aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2019-12-09 16:19:41 +0200
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2019-12-09 16:19:41 +0200
commitc7fa53084c674586ceee773ccbdc6b4c0a2ec7d4 (patch)
tree1642092f35d6e02de502909c3db97131e66bfaca /Software/Visual_Studio
parentaeabb681d16451e191a1620d4eebf40549771491 (diff)
downloadTango-c7fa53084c674586ceee773ccbdc6b4c0a2ec7d4.tar.gz
Tango-c7fa53084c674586ceee773ccbdc6b4c0a2ec7d4.zip
Implemented full TUP package update !!!
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj8
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs8
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs129
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml3
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml60
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs28
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj17
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs285
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs16
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs14
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs21
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs9
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config1
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj6
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs7
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs468
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs13
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs13
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs6
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj1
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml12
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs30
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml5
-rw-r--r--Software/Visual_Studio/Tango.Core/DB/DbManager.cs33
-rw-r--r--Software/Visual_Studio/Tango.PMR/FirmwareUpgrade/VersionFileDescriptor.cs37
-rw-r--r--Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs9
-rw-r--r--Software/Visual_Studio/Tango.SQLExaminer/ExtensionMethods.cs21
-rw-r--r--Software/Visual_Studio/Tango.SQLExaminer/Helper.cs2
-rw-r--r--Software/Visual_Studio/Tango.SQLExaminer/Tango.SQLExaminer.csproj1
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/SQLExaminer/SQLExaminer_TST.cs71
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs65
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs2
32 files changed, 1257 insertions, 144 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj
index 6225bd7ad..69cc75461 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj
@@ -93,6 +93,7 @@
<Compile Include="ViewModels\MachineUpdatesViewVM.cs" />
<Compile Include="ViewModels\MachineVersionDialogVM.cs" />
<Compile Include="ViewModels\MainViewVM.cs" />
+ <Compile Include="ViewModels\TupViewVM.cs" />
<Compile Include="Views\ColorCalibrationView.xaml.cs">
<DependentUpon>ColorCalibrationView.xaml</DependentUpon>
</Compile>
@@ -130,6 +131,9 @@
<Compile Include="Views\MachineUpdatesView.xaml.cs">
<DependentUpon>MachineUpdatesView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Views\TupView.xaml.cs">
+ <DependentUpon>TupView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\SpoolsView.xaml.cs">
<DependentUpon>SpoolsView.xaml</DependentUpon>
</Compile>
@@ -185,6 +189,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
+ <Page Include="Views\TupView.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
<Page Include="Views\SpoolsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs
index 820950290..768f93de1 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs
@@ -140,6 +140,12 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels
set { _machineUpdatesViewVM = value; RaisePropertyChangedAuto(); }
}
+ private TupViewVM _tupViewVM;
+ public TupViewVM TupViewVM
+ {
+ get { return _tupViewVM; }
+ set { _tupViewVM = value; RaisePropertyChangedAuto(); }
+ }
#endregion
@@ -233,6 +239,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels
ResetDeviceRegistrationCommand = new RelayCommand(ResetDeviceRegistration);
MachineUpdatesViewVM = new MachineUpdatesViewVM(_notification);
+ TupViewVM = new TupViewVM(_notification);
}
#endregion
@@ -478,6 +485,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels
HardwareConfigurationViewVM.Init(ActiveMachine.Configuration);
await MachineUpdatesViewVM.Init(ActiveMachine, ActiveMachineAdapter.Context);
+ TupViewVM.Init(ActiveMachine);
ActiveMachine.Configuration.HardwareVersionChanged += Configuration_HardwareVersionChanged;
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs
new file mode 100644
index 000000000..12ed09c75
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs
@@ -0,0 +1,129 @@
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.BL.Entities;
+using Tango.Core.Commands;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.Common.Tup;
+using Tango.SharedUI;
+
+namespace Tango.MachineStudio.MachineDesigner.ViewModels
+{
+ public class TupViewVM : ViewModel
+ {
+ private INotificationProvider _notification;
+
+ private String _latestVersion;
+ public String LatestVersion
+ {
+ get { return _latestVersion; }
+ set { _latestVersion = value; RaisePropertyChangedAuto(); }
+ }
+
+ private Machine _machine;
+ public Machine Machine
+ {
+ get { return _machine; }
+ set { _machine = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _filePath;
+ public String FilePath
+ {
+ get { return _filePath; }
+ set { _filePath = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
+ }
+
+ private TupFileBuilderProgressEventArgs _progress;
+ public TupFileBuilderProgressEventArgs Progress
+ {
+ get { return _progress; }
+ set { _progress = value; RaisePropertyChangedAuto(); }
+ }
+
+ public RelayCommand CreateTupFileCommand { get; set; }
+
+ public RelayCommand SelectFileCommand { get; set; }
+
+ public TupViewVM()
+ {
+
+ }
+
+ public TupViewVM(INotificationProvider notification) : this()
+ {
+ _notification = notification;
+ CreateTupFileCommand = new RelayCommand(CreateTupFile, () => FilePath != null && IsFree);
+ SelectFileCommand = new RelayCommand(SelectFile);
+ }
+
+ public void Init(Machine machine)
+ {
+ Machine = machine;
+ DisplayLatestPPCVersion();
+ }
+
+ private async void DisplayLatestPPCVersion()
+ {
+ TupFileBuilder builder = new TupFileBuilder();
+
+ try
+ {
+ LatestVersion = await builder.GetLatestPPCVersion(Machine.SerialNumber);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error retrieving latest PPC version.");
+ await Task.Delay(5000);
+ DisplayLatestPPCVersion();
+ }
+ }
+
+ private void SelectFile()
+ {
+ SaveFileDialog dlg = new SaveFileDialog();
+ dlg.Title = "Select package location";
+ dlg.Filter = "Tango Update Package Files|*.tup";
+ dlg.DefaultExt = ".tup";
+ dlg.FileName = LatestVersion == null ? $"{Machine.SerialNumber}_Update.tup" : $"{Machine.SerialNumber}_Update_v{LatestVersion}.tup";
+
+ if (dlg.ShowDialog().Value)
+ {
+ FilePath = dlg.FileName;
+ }
+ }
+
+ private async void CreateTupFile()
+ {
+ try
+ {
+ LogManager.Log($"Generating TUP file to '{FilePath}'...");
+
+ IsFree = false;
+ TupFileBuilder builder = new TupFileBuilder();
+ builder.Progress += Builder_Progress;
+ await builder.Build(Machine.SerialNumber, FilePath);
+
+ LogManager.Log("TUP file generated successfully.");
+ _notification.ShowInfo("Tango update package created successfuly.");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error generating tup file.");
+ _notification.ShowError($"An error occurred while generating the .tup file.\n{ex.FlattenMessage()}");
+ }
+ finally
+ {
+ IsFree = true;
+ }
+ }
+
+ private void Builder_Progress(object sender, TupFileBuilderProgressEventArgs e)
+ {
+ Progress = e;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml
index 666a4ee4a..bcca83ca5 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml
@@ -64,6 +64,9 @@
<TabItem Header="UPDATES">
<local:MachineUpdatesView/>
</TabItem>
+ <TabItem Header="TUP">
+ <local:TupView/>
+ </TabItem>
</TabControl>
</Grid>
</DockPanel>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml
new file mode 100644
index 000000000..895a26ca0
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml
@@ -0,0 +1,60 @@
+<UserControl x:Class="Tango.MachineStudio.MachineDesigner.Views.TupView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:vm="clr-namespace:Tango.MachineStudio.MachineDesigner.ViewModels"
+ xmlns:global="clr-namespace:Tango.MachineStudio.MachineDesigner"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}" Background="Transparent">
+
+ <Grid Margin="20" DataContext="{Binding TupViewVM}">
+ <DockPanel IsEnabled="{Binding IsFree}">
+ <Grid DockPanel.Dock="Bottom">
+
+ </Grid>
+
+ <Grid Margin="0 20">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="38*"/>
+ <ColumnDefinition Width="117*"/>
+ </Grid.ColumnDefinitions>
+
+ <local:MachineView Margin="30 80 0 0" DataContext="{Binding Machine}" IsHitTestVisible="False" VerticalAlignment="Top" Height="241" />
+
+ <DockPanel Grid.Column="1" Margin="50 100 300 100">
+ <TextBlock DockPanel.Dock="Top">
+ <Run>Create a complete update package (.tup) in order to update this machine offline using a removable storage device.</Run>
+ <LineBreak/>
+ <Run>The latest PPC version is </Run>
+ <Run Foreground="{StaticResource AccentColorBrush}" FontWeight="SemiBold" Text="{Binding LatestVersion,FallbackValue='loading...',TargetNullValue='loading...'}"></Run>
+ </TextBlock>
+ <Grid Margin="0 20 0 0">
+ <Border Background="{StaticResource Transparent200}" CornerRadius="5" Padding="60" BorderThickness="1" BorderBrush="Silver">
+ <DockPanel>
+ <DockPanel DockPanel.Dock="Top" Height="40">
+ <Button Command="{Binding SelectFileCommand}" DockPanel.Dock="Right" BorderBrush="Silver" BorderThickness="1" Padding="0" Height="Auto" Width="40" Margin="5 0 0 0" Style="{StaticResource MaterialDesignFlatButton}">
+ <material:PackIcon Kind="Folder" />
+ </Button>
+ <TextBox materialDesign:HintAssist.Hint="Select package location" BorderBrush="Silver" BorderThickness="1" Text="{Binding FilePath}" IsReadOnly="True" VerticalContentAlignment="Center" Padding="10 0 0 0"></TextBox>
+ </DockPanel>
+ <StackPanel DockPanel.Dock="Bottom">
+ <TextBlock HorizontalAlignment="Center" Text="{Binding Progress.Message,FallbackValue='Ready',TargetNullValue='Ready'}"></TextBlock>
+ <ProgressBar Margin="0 10 0 0" Height="15" IsIndeterminate="{Binding Progress.IsIntermediate}" Value="{Binding Progress.Progress}" Maximum="{Binding Progress.Total}"></ProgressBar>
+ </StackPanel>
+ <Grid>
+ <Button Command="{Binding CreateTupFileCommand}" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="20 10" Height="60" Width="300">GENERATE UPDATE PACKAGE</Button>
+ </Grid>
+ </DockPanel>
+ </Border>
+ </Grid>
+ </DockPanel>
+ </Grid>
+ </DockPanel>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs
new file mode 100644
index 000000000..fe01296d8
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Tango.MachineStudio.MachineDesigner.Views
+{
+ /// <summary>
+ /// Interaction logic for SpoolsView.xaml
+ /// </summary>
+ public partial class TupView : UserControl
+ {
+ public TupView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
index 7c0851d01..3ce667afe 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
@@ -59,6 +59,9 @@
<HintPath>..\..\Referenced Assemblies\SMO\Microsoft.SqlServer.AzureStorageEnum.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=4.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
@@ -83,6 +86,9 @@
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="..\..\PPC\Tango.PPC.Common\Publish\PublishInfo.cs">
+ <Link>Tup\PublishInfo.cs</Link>
+ </Compile>
<Compile Include="..\..\Versioning\GlobalVersionInfo.cs">
<Link>GlobalVersionInfo.cs</Link>
</Compile>
@@ -95,6 +101,10 @@
<Compile Include="Converters\UserRoleToVisibilityConverter.cs" />
<Compile Include="MachineStudioTheme.cs" />
<Compile Include="Resources\SharedResourceDictionary.cs" />
+ <Compile Include="Tup\TupFileBuilder.cs" />
+ <Compile Include="Tup\TupFileBuilderProgressEventArgs.cs" />
+ <Compile Include="Web\DownloadLatestPPCVersionRequest.cs" />
+ <Compile Include="Web\DownloadLatestPPCVersionResponse.cs" />
<Compile Include="Web\LoginRequest.cs" />
<Compile Include="Web\LoginResponse.cs" />
<Compile Include="AutoComplete\MachinesProvider.cs" />
@@ -291,6 +301,10 @@
<Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
<Name>Tango.SharedUI</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.SQLExaminer\Tango.SQLExaminer.csproj">
+ <Project>{e1e66ed9-597d-45fa-8048-de90a6930484}</Project>
+ <Name>Tango.SQLExaminer</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.Transport\Tango.Transport.csproj">
<Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
<Name>Tango.Transport</Name>
@@ -387,10 +401,11 @@
<ItemGroup>
<Resource Include="Images\ti-tm4c129x.png" />
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs
new file mode 100644
index 000000000..6dd8b82f7
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs
@@ -0,0 +1,285 @@
+using Ionic.Zip;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.BL;
+using Tango.Core;
+using Tango.Core.DB;
+using Tango.Core.DI;
+using Tango.MachineStudio.Common.Web;
+using Tango.SQLExaminer;
+using Tango.Transport.Web;
+using Tango.Core.ExtensionMethods;
+using Tango.PPC.Common.Publish;
+using Tango.Settings;
+using Tango.Core.Components;
+using System.Text.RegularExpressions;
+
+namespace Tango.MachineStudio.Common.Tup
+{
+ public class TupFileBuilder : ExtendedObject
+ {
+ public event EventHandler<TupFileBuilderProgressEventArgs> Progress;
+
+ public Task Build(String serialNumber, String filePath)
+ {
+ return Task.Factory.StartNew(() =>
+ {
+ String tempDbName = "Tango_TUP";
+ var tempPackageFolder = TemporaryManager.CreateFolder();
+ String tempBackupFolder = "C:\\MachineStudioTUP";
+ String tempBackupFile = Path.Combine(tempBackupFolder, tempDbName + ".bak");
+ var tempZipFile = TemporaryManager.CreateImaginaryFile();
+ DbManager dbManager = null;
+
+ LogManager.Log("Generating tup file...");
+ LogManager.Log($"Tup file: '{filePath}.'");
+ LogManager.Log($"Temporary db name: '{tempDbName}'.");
+ LogManager.Log($"Temporary package folder: '{tempPackageFolder}'.");
+ LogManager.Log($"Temporary db backup folder: '{tempBackupFolder}'.");
+ LogManager.Log($"Temporary db backup file: '{tempBackupFile}'.");
+ LogManager.Log($"Temporary zip file: '{tempZipFile}'.");
+
+ try
+ {
+ LogManager.Log("Initializing...");
+
+ OnProgress("Initializing...");
+
+ Core.DataSource localDataSource = new Core.DataSource()
+ {
+ Address = "localhost\\SQLEXPRESS",
+ IntegratedSecurity = true,
+ Type = DataSourceType.SQLServer,
+ Catalog = null,
+ };
+
+ try
+ {
+ LogManager.Log($"Trying to connect via SQLEXPRESS:\n{localDataSource.ToJsonString()}");
+ dbManager = DbManager.FromDataSource(localDataSource);
+ }
+ catch (Exception ex)
+ {
+ try
+ {
+ LogManager.Log(ex, "Could not connect using SQLEXPRESS. Trying local DB...");
+
+ CmdCommand command = new CmdCommand("sqllocaldb", "info \"MSSQLLocalDB\"");
+ var result = command.Run().Result;
+
+ String pattern = "np:.+";
+ Regex reg = new Regex(pattern);
+ var match = reg.Match(result.StandardOutput);
+ String address = match.ToString();
+ if (address.Contains("np:"))
+ {
+ localDataSource.Address = address;
+ address = address.Trim().Replace("\r", "");
+ }
+ else
+ {
+ throw new ArgumentException("Could not parse LocalDB address string.");
+ }
+
+ LogManager.Log($"Trying to connect via LocalDB:\n{localDataSource.ToJsonString()}");
+ dbManager = DbManager.FromDataSource(localDataSource);
+ }
+ catch (Exception x)
+ {
+ LogManager.Log(x, "Could not find any database service for this operation.");
+ throw x;
+ }
+ }
+
+
+
+ OnProgress("Downloading latest PPC version...");
+
+ LogManager.Log("Connecting to machine service...");
+ MachineStudioWebClient client = TangoIOC.Default.GetInstance<MachineStudioWebClient>();
+
+ LogManager.Log("Requesting latest PPC version from machine service...");
+ var response = client.DownloadLatestPPCVersion(new DownloadLatestPPCVersionRequest() { SerialNumber = serialNumber }).Result;
+
+ LogManager.Log($"Machine service response:\n{response.ToJsonString()}");
+
+ var remoteDataSource = response.DataSource;
+
+ using (AutoFileDownloader downloader = new AutoFileDownloader(response.BlobAddress, response.CdnAddress, tempZipFile))
+ {
+ downloader.Progress += (x, e) =>
+ {
+ OnProgress($"Downloading latest PPC version '{response.Version}'...", false, e.Current, e.Total);
+ };
+
+ downloader.ResolveMode().GetAwaiter().GetResult();
+
+ LogManager.Log($"Downloading latest PPC version from: '{downloader.Address}'");
+
+ downloader.Download().Wait();
+ }
+
+ LogManager.Log("Extracting PPC version package...");
+
+ OnProgress("Extracting PPC package...");
+
+ using (ZipFile zip = new ZipFile(tempZipFile))
+ {
+ int currentEntry = 0;
+
+ zip.ExtractProgress += (x, args) =>
+ {
+ if (args.EventType == ZipProgressEventType.Extracting_AfterExtractEntry)
+ {
+ OnProgress("Extracting PPC package...", false, currentEntry++, zip.Entries.Count);
+ }
+ };
+
+ zip.ExtractAll(tempPackageFolder);
+ }
+
+ OnProgress("Extracting version information...");
+ LogManager.Log("Extracting publish information...");
+ PublishInfo publishInfo = PublishInfo.FromJson(File.ReadAllText(Path.Combine(tempPackageFolder, "version.json")));
+ LogManager.Log($"Publish Information:\n{publishInfo}");
+
+ LogManager.Log("Modifying publish information to custom tup file...");
+ publishInfo.IsMachineTupPackage = true;
+ publishInfo.MachineSerialNumber = serialNumber;
+ publishInfo.MachineDeploymentSlot = SettingsManager.Default.GetOrCreate<MachineStudioSettings>().DeploymentSlot;
+
+ OnProgress("Creating temporary database...");
+
+ LogManager.Log($"Creating temporary db backup directory '{tempBackupFolder}'");
+
+ Directory.CreateDirectory(tempBackupFolder);
+
+ LogManager.Log($"Creating new database: '{tempDbName}'");
+
+ //Create temp db
+ dbManager.Create(tempDbName, Path.Combine(tempBackupFolder, tempDbName + ".mdf"));
+
+ OnProgress("Generating database snapshot...");
+
+ LogManager.Log("Starting database synchronization...");
+
+ Thread.Sleep(2000);
+
+ localDataSource.Catalog = tempDbName;
+
+ ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner(
+ Path.Combine(tempPackageFolder, "Provision Scripts", "config.xml"),
+ Path.Combine(tempPackageFolder, "Provision Scripts"),
+ remoteDataSource,
+ localDataSource,
+ serialNumber);
+
+ runner.ScriptExecuting += (x, item) =>
+ {
+ LogManager.Log($"Executing script '{item.FileName}'...");
+ OnProgress($"{item.Name}...");
+ };
+
+ runner.Log += (x, log) =>
+ {
+ LogManager.Log(log);
+ };
+
+ runner.Run().GetAwaiter().GetResult();
+
+ OnProgress("Generating database snapshot...");
+
+ if (File.Exists(tempBackupFile))
+ {
+ LogManager.Log($"Deleting file '{tempBackupFile}'");
+ File.Delete(tempBackupFile);
+ }
+
+ LogManager.Log($"Generating backup for '{tempDbName}' to '{tempBackupFile}'...");
+
+ dbManager.Backup(tempDbName, tempBackupFile);
+
+ OnProgress("Injecting database snapshot to PPC package...");
+
+ using (ZipFile zip = new ZipFile(tempZipFile))
+ {
+ LogManager.Log($"Injecting file '{tempBackupFile}' to original package at '{tempZipFile}'...");
+ zip.AddFile(tempBackupFile, "/");
+
+ LogManager.Log($"Injecting modified publish information...");
+ zip.UpdateEntry("version.json", publishInfo.ToJson());
+
+ zip.Save();
+ }
+
+ LogManager.Log($"Copying '{tempZipFile}' to '{filePath}'...");
+
+ File.Copy(tempZipFile, filePath, true);
+
+ OnProgress("Completed", false, 100, 100);
+
+ LogManager.Log("TUP file generation completed successfully.");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "TUP file generation failed.");
+ OnProgress("Failed", false, 0, 100);
+ throw ex;
+ }
+ finally
+ {
+ LogManager.Log($"Removing '{tempZipFile}'.");
+ tempZipFile.Delete();
+ LogManager.Log($"Removing '{tempPackageFolder}'.");
+ tempPackageFolder.Delete();
+
+ try
+ {
+ LogManager.Log($"Removing database '{tempDbName}'.");
+ dbManager.SetOffline(tempDbName);
+ dbManager.SetOnline(tempDbName);
+ dbManager.Delete(tempDbName);
+ dbManager.Dispose();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error removing temp database '{tempDbName}'.");
+ }
+
+ try
+ {
+ LogManager.Log($"Removing '{tempBackupFolder}'.");
+ Directory.Delete(tempBackupFolder, true);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error removing folder '{tempBackupFolder}'.");
+ }
+ }
+ });
+ }
+
+ public async Task<String> GetLatestPPCVersion(String serialNumber)
+ {
+ MachineStudioWebClient client = TangoIOC.Default.GetInstance<MachineStudioWebClient>();
+ var response = await client.DownloadLatestPPCVersion(new DownloadLatestPPCVersionRequest() { SerialNumber = serialNumber });
+ return response.Version;
+ }
+
+ private void OnProgress(String message, bool isIntermediate = true, double progress = 0, double total = 100)
+ {
+ Progress?.Invoke(this, new TupFileBuilderProgressEventArgs()
+ {
+ Message = message,
+ IsIntermediate = isIntermediate,
+ Progress = progress,
+ Total = total,
+ });
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs
new file mode 100644
index 000000000..ada69dd40
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.MachineStudio.Common.Tup
+{
+ public class TupFileBuilderProgressEventArgs
+ {
+ public double Progress { get; set; }
+ public double Total { get; set; }
+ public bool IsIntermediate { get; set; }
+ public String Message { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs
new file mode 100644
index 000000000..24d465e69
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Transport.Web;
+
+namespace Tango.MachineStudio.Common.Web
+{
+ public class DownloadLatestPPCVersionRequest : WebRequestMessage
+ {
+ public String SerialNumber { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs
new file mode 100644
index 000000000..2cc6b731a
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Transport.Web;
+
+namespace Tango.MachineStudio.Common.Web
+{
+ public class DownloadLatestPPCVersionResponse : WebResponseMessage
+ {
+ public String Version { get; set; }
+
+ public String BlobAddress { get; set; }
+
+ public String CdnAddress { get; set; }
+
+ public DataSource DataSource { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs
index 131f89515..c2d0dd3e6 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs
@@ -94,5 +94,14 @@ namespace Tango.MachineStudio.Common.Web
return Post<Tango.MachineStudio.Common.Web.RefreshTokenRequest, Tango.MachineStudio.Common.Web.RefreshTokenResponse>("RefreshToken", request);
}
+ /// <summary>
+ /// Executes the DownloadLatestPPCVersion action and returns Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionResponse.
+ /// </summary>
+ /// <returns></returns>
+ public Task<Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionResponse> DownloadLatestPPCVersion(Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionRequest request)
+ {
+ return Post<Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionRequest, Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionResponse>("DownloadLatestPPCVersion", request);
+ }
+
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config
index f871776f5..6fd5091a8 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config
@@ -9,4 +9,5 @@
<package id="MahApps.Metro" version="1.5.0" targetFramework="net46" />
<package id="MaterialDesignColors" version="1.1.2" targetFramework="net46" />
<package id="MaterialDesignThemes" version="2.3.1.953" targetFramework="net46" />
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj
index 991eb9da6..c6cf624b3 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj
@@ -448,6 +448,10 @@
<Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
<Name>Tango.SharedUI</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.SQLExaminer\Tango.SQLExaminer.csproj">
+ <Project>{e1e66ed9-597d-45fa-8048-de90a6930484}</Project>
+ <Name>Tango.SQLExaminer</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.TFS\Tango.TFS.csproj">
<Project>{998f8471-dc1b-41b6-9d96-354e1b4e7a32}</Project>
<Name>Tango.TFS</Name>
@@ -661,7 +665,7 @@ if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)ProtoCompilers\"</PostB
</Target>
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_UseGlobalSettings="False" BuildVersion_DetectChanges="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.DeltaBaseYearDayOfYear" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_StartDate="2000/1/1" />
+ <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_BuildVersioningStyle="None.None.Increment.DeltaBaseYearDayOfYear" BuildVersion_UpdateFileVersion="True" BuildVersion_DetectChanges="True" BuildVersion_UseGlobalSettings="False" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs
index 3655aa462..e11eab3a5 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.PMR.Synchronization;
+using Tango.PPC.Common.Publish;
using Tango.PPC.Common.UpdatePackages;
using Tango.PPC.Common.Web;
@@ -43,14 +44,14 @@ namespace Tango.PPC.Common.MachineUpdate
/// <param name="setupFirmware">if set to <c>true</c> updates the embedded device firmware.</param>
/// <param name="setupFPGA">if set to <c>true</c> updates the embedded device FPGA version and other parameters.</param>
/// <returns></returns>
- Task<MachineUpdateResult> Update(String serialNumber, bool setupFirmware, bool setupFPGA);
+ Task<MachineUpdateResult> Update(bool setupFirmware, bool setupFPGA);
/// <summary>
/// Performs a machine update using the specified software update package path.
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <returns></returns>
- Task<MachineUpdateResult> UpdateFromTUP(String fileName);
+ Task<MachineUpdateResult> UpdateFromTUP(String fileName, bool setupFirmware, bool setupFPGA);
/// <summary>
/// Checks if any update are available for the specified machine serial number.
@@ -77,7 +78,7 @@ namespace Tango.PPC.Common.MachineUpdate
/// </summary>
/// <param name="filePath">The file path.</param>
/// <returns></returns>
- Task<UpdatePackageFile> GetUpdatePackageFileInfo(String filePath);
+ Task<PublishInfo> GetUpdatePackageFileInfo(String filePath);
/// <summary>
/// Checks whether any post update packages needs to be installed.
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs
index 5296a9f34..7e742ceb6 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs
@@ -22,6 +22,7 @@ using Tango.PMR.Synchronization;
using Tango.PPC.Common.Application;
using Tango.PPC.Common.Connection;
using Tango.PPC.Common.Navigation;
+using Tango.PPC.Common.Publish;
using Tango.PPC.Common.UpdatePackages;
using Tango.PPC.Common.Web;
using Tango.Settings;
@@ -117,7 +118,10 @@ namespace Tango.PPC.Common.MachineUpdate
private void LogManager_NewLog(object sender, LogItemBase e)
{
- _logs.Add(e);
+ if (_isUpdating)
+ {
+ _logs.Add(e);
+ }
}
#endregion
@@ -133,37 +137,80 @@ namespace Tango.PPC.Common.MachineUpdate
});
}
- private async void OnFailed(Exception ex, TaskCompletionSource<MachineUpdateResult> completionSource, DownloadUpdateResponse response, bool performDatabaseRollback, String dbBackupFile, Tango.Core.DataSource localDataSource)
+ private async void OnFailed(Exception ex, TaskCompletionSource<MachineUpdateResult> completionSource, DownloadUpdateResponse response, bool performDatabaseRollback, String dbBackupFile, String backupsFolder, String tempDbName, Tango.Core.DataSource localDataSource, String tempUpdatePackageFolder = null)
{
LogManager.Log(ex, "An error occurred in machine update.");
- if (performDatabaseRollback)
+ await Task.Factory.StartNew(() =>
{
- LogManager.Log("Rolling back database changes...");
- using (DbManager db = DbManager.FromDataSource(localDataSource))
+ if (performDatabaseRollback)
+ {
+ LogManager.Log("Rolling back database changes...");
+
+ using (DbManager db = DbManager.FromDataSource(localDataSource))
+ {
+ try
+ {
+ UpdateProgress("Rollback", "Rolling back database changes...");
+ db.Restore(localDataSource.Catalog, dbBackupFile);
+ LogManager.Log("Database restored successfully.");
+ }
+ catch (Exception e)
+ {
+ LogManager.Log(e, "Could not rollback the database.");
+ }
+ finally
+ {
+ try
+ {
+ File.Delete(dbBackupFile);
+ }
+ catch { }
+ }
+ }
+ }
+
+ if (tempDbName != null)
{
try
{
- UpdateProgress("Rollback", "Rolling back database changes...");
- await Task.Factory.StartNew(() => db.Restore(localDataSource.Catalog, dbBackupFile));
- LogManager.Log("Database restored successfully.");
+ LogManager.Log($"Removing temporary database '{tempDbName}'...");
+ using (DbManager dbManager = DbManager.FromDataSource(localDataSource))
+ {
+ dbManager.SetOffline(tempDbName);
+ dbManager.SetOnline(tempDbName);
+ dbManager.Delete(tempDbName);
+ }
}
- catch (Exception e)
+ catch (Exception exx)
{
- LogManager.Log(e, "Could not rollback the database.");
- throw ex;
+ LogManager.Log(exx, "Error removing temporary database.");
}
- finally
+ }
+
+ try
+ {
+ Directory.Delete(backupsFolder, true);
+ }
+ catch (Exception ee)
+ {
+ LogManager.Log(ee, $"Error deleting backups folder '{backupsFolder}'.");
+ }
+
+ if (tempUpdatePackageFolder != null)
+ {
+ try
{
- try
- {
- File.Delete(dbBackupFile);
- }
- catch { }
+ Directory.Delete(tempUpdatePackageFolder, true);
+ }
+ catch (Exception eee)
+ {
+ LogManager.Log(eee, "Error removing temporary package folder.");
}
}
- }
+
+ });
completionSource.SetException(ex);
@@ -188,13 +235,50 @@ namespace Tango.PPC.Common.MachineUpdate
_isUpdating = false;
}
- private async void OnCompleted(MachineUpdateResult result, TaskCompletionSource<MachineUpdateResult> completionSource, DownloadUpdateResponse response, String dbBackupFile)
+ private async void OnCompleted(MachineUpdateResult result, TaskCompletionSource<MachineUpdateResult> completionSource, DownloadUpdateResponse response, String tempDbName, String backupsFolder, Core.DataSource localDataSource)
{
- try
+ await Task.Factory.StartNew(() =>
{
- File.Delete(dbBackupFile);
- }
- catch { }
+ if (tempDbName != null)
+ {
+ try
+ {
+ LogManager.Log($"Removing temporary database '{tempDbName}'...");
+ using (DbManager dbManager = DbManager.FromDataSource(localDataSource))
+ {
+ dbManager.SetOffline(tempDbName);
+ dbManager.SetOnline(tempDbName);
+ dbManager.Delete(tempDbName);
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error removing temporary database.");
+ }
+ }
+
+ try
+ {
+ Directory.Delete(backupsFolder, true);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error deleting backups folder '{backupsFolder}'.");
+ }
+
+ if (!result.RequiresBinariesUpdate)
+ {
+ try
+ {
+ Directory.Delete(result.UpdatePackagePath, true);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error removing temporary package folder.");
+ }
+ }
+
+ });
completionSource.SetResult(result);
@@ -315,7 +399,7 @@ namespace Tango.PPC.Common.MachineUpdate
/// or
/// </exception>
/// <exception cref="System.InvalidProgramException">Database tango does not exists.</exception>
- public async Task<MachineUpdateResult> Update(String serialNumber, bool setupFirmware, bool setupFPGA)
+ public async Task<MachineUpdateResult> Update(bool setupFirmware, bool setupFPGA)
{
_logs.Clear();
@@ -325,6 +409,13 @@ namespace Tango.PPC.Common.MachineUpdate
bool performDatabaseRollback = false;
String dbBackupFile = null;
DownloadUpdateResponse update_response = null;
+ String backupsFolder = "C:\\Backups";
+
+ //Create temporary folders for packages.
+ var _newPackageTempFolder = TemporaryManager.CreateFolder();
+ _newPackageTempFolder.Persist = true;
+
+ String serialNumber = _machineProvider.Machine.SerialNumber;
try
{
@@ -371,10 +462,6 @@ namespace Tango.PPC.Common.MachineUpdate
LogManager.Log($"Machine update response received: {Environment.NewLine}{update_response.ToJsonString()}");
- //Create temporary folders for packages.
- var _newPackageTempFolder = TemporaryManager.CreateFolder();
- _newPackageTempFolder.Persist = true;
-
LogManager.Log($"Temporary package folder created: {_newPackageTempFolder}.");
//Download software package.
@@ -413,8 +500,12 @@ namespace Tango.PPC.Common.MachineUpdate
UpdateProgress("Downloading software package", "Extracting package...");
LogManager.Log("Extracting downloaded zip file...");
- //Extract software package.
- ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder);
+
+ await Task.Factory.StartNew(() =>
+ {
+ //Extract software package.
+ ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder);
+ });
LogManager.Log("Copying latest updater utility to application path...");
//Copy new updater utility to app path.
@@ -464,8 +555,8 @@ namespace Tango.PPC.Common.MachineUpdate
//Create Database Backup
try
{
- Directory.CreateDirectory("C:\\Backups");
- dbBackupFile = $"C:\\Backups\\{Path.GetRandomFileName()}.bak";
+ Directory.CreateDirectory(backupsFolder);
+ dbBackupFile = $"{backupsFolder}\\{Path.GetRandomFileName()}.bak";
LogManager.Log($"Creating database backup to '{dbBackupFile}'...");
await Task.Factory.StartNew(() => db.Backup(localDataSource.Catalog, dbBackupFile));
performDatabaseRollback = true;
@@ -548,7 +639,7 @@ namespace Tango.PPC.Common.MachineUpdate
handler.Failed += (_, ex) =>
{
stream.Dispose();
- OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, localDataSource);
+ OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, backupsFolder, null, localDataSource, _newPackageTempFolder);
};
handler.Completed += (_, __) =>
{
@@ -557,12 +648,12 @@ namespace Tango.PPC.Common.MachineUpdate
OnCompleted(new MachineUpdateResult()
{
UpdatePackagePath = _newPackageTempFolder,
- }, result, update_response, dbBackupFile);
+ }, result, update_response, null, backupsFolder, localDataSource);
};
handler.Canceled += (_, __) =>
{
stream.Dispose();
- OnFailed(new Exception("The operation has been canceled."), result, update_response, performDatabaseRollback, dbBackupFile, localDataSource);
+ OnFailed(new Exception("The operation has been canceled."), result, update_response, performDatabaseRollback, dbBackupFile, backupsFolder, null, localDataSource, _newPackageTempFolder);
};
handler.Progress += (_, e) =>
{
@@ -574,12 +665,12 @@ namespace Tango.PPC.Common.MachineUpdate
OnCompleted(new MachineUpdateResult()
{
UpdatePackagePath = _newPackageTempFolder,
- }, result, update_response, dbBackupFile);
+ }, result, update_response, null, backupsFolder, localDataSource);
}
}
catch (Exception ex)
{
- OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, localDataSource);
+ OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, backupsFolder, null, localDataSource, _newPackageTempFolder);
}
return await result.Task;
@@ -875,31 +966,284 @@ namespace Tango.PPC.Common.MachineUpdate
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <returns></returns>
- public Task<MachineUpdateResult> UpdateFromTUP(string fileName)
+ public async Task<MachineUpdateResult> UpdateFromTUP(string fileName, bool setupFirmware, bool setupFPGA)
{
- return Task.Factory.StartNew<MachineUpdateResult>(() =>
+ _logs.Clear();
+
+ TaskCompletionSource<MachineUpdateResult> result = new TaskCompletionSource<MachineUpdateResult>();
+
+ var localDataSource = SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource;
+ bool performDatabaseRollback = false;
+ String dbBackupFile = null;
+ String tempDbName = "Tango_TUP";
+ String tempDbFileName = tempDbName + ".bak";
+ String backupsFolder = "C:\\Backups";
+ bool replaceBinaries = false;
+
+ String serialNumber = _machineProvider.Machine.SerialNumber;
+
+ //Create temporary folders for packages.
+ var _newPackageTempFolder = TemporaryManager.CreateFolder();
+ _newPackageTempFolder.Persist = true;
+
+ try
{
- LogManager.Log($"Starting machine update from update package '{fileName}'...");
+ _isUpdating = true;
+
+ LogManager.Log($"Starting machine update for serial number {serialNumber}...");
- //Create temporary folders for packages.
- var _newPackageTempFolder = TemporaryManager.CreateFolder();
- _newPackageTempFolder.Persist = true;
+ //Connecting to machine...
+ LogManager.Log("Verifying machine connection and state...");
- LogManager.Log("Extracting downloaded zip file...");
- //Extract software package.
- ZipFile.ExtractToDirectory(fileName, _newPackageTempFolder);
+ UpdateProgress("Verifying machine state", "Initializing...");
+
+ await Task.Delay(1000);
+
+ IMachineOperator op = _machineProvider.MachineOperator;
+
+ if (setupFirmware)
+ {
+ LogManager.Log("Machine is configured to update firmware...");
+
+ if (op.State != Transport.TransportComponentState.Connected)
+ {
+ throw LogManager.Log(new InvalidOperationException("Could not perform an update while the machine is not connected."));
+ }
+ if (op.Status != MachineStatuses.ReadyToDye)
+ {
+ throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {op.Status} status."));
+ }
+ }
+
+ UpdateProgress("Exploring package", "Extracting...");
+ LogManager.Log("Extracting package...");
+
+ LogManager.Log($"Temporary package folder created: {_newPackageTempFolder}.");
+
+ await Task.Factory.StartNew(() =>
+ {
+ //Extract software package.
+ ZipFile.ExtractToDirectory(fileName, _newPackageTempFolder);
+ });
+
+ //Extracting publish info
+ UpdateProgress("Exploring package", "Verifying...");
+ PublishInfo publishInfo = PublishInfo.FromJson(File.ReadAllText(Path.Combine(_newPackageTempFolder, "version.json")));
+
+ if (!publishInfo.IsMachineTupPackage)
+ {
+ throw new InvalidOperationException("The specified tup file is invalid. Updating a machine from a tup file requires a custom generated package.");
+ }
+
+ if (publishInfo.MachineSerialNumber != serialNumber)
+ {
+ throw new InvalidOperationException("The specified tup file is invalid. The package was generated for a different machine.");
+ }
+
+ if (publishInfo.MachineDeploymentSlot != SettingsManager.Default.GetOrCreate<PPCSettings>().DeploymentSlot)
+ {
+ throw new InvalidOperationException("The specified tup file is invalid. The package was generated on a different environment.");
+ }
+
+ replaceBinaries = _app_manager.Version.ToString() != publishInfo.ApplicationVersion;
LogManager.Log("Copying latest updater utility to application path...");
+
//Copy new updater utility to app path.
File.Copy(Path.Combine(_newPackageTempFolder, "Tango.PPC.Updater.exe"), Path.Combine(PathHelper.GetStartupPath(), "Tango.PPC.Updater.exe"), true);
- LogManager.Log("Update operation completed!");
+ //Run pre-update packages.
+ try
+ {
+ UpdateProgress("Preparing", "Running update packages...");
+ LogManager.Log("Running pre-update packages...");
+ var packagesFolder = Path.Combine(_newPackageTempFolder, "Packages");
- return new MachineUpdateResult()
+ Version updateVersion = new Version(1, 0, 0, 0);
+ try
+ {
+ updateVersion = Version.Parse(publishInfo.ApplicationVersion);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error parsing new version string for package runner.");
+ }
+
+ await _packageRunner.Run(PackageType.Pre, updateVersion, packagesFolder);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error running pre-update packages...");
+ }
+
+ //Synchronize database
+ UpdateProgress("Updating Database", "Initializing...");
+
+ UpdateProgress("Updating Database", "Connecting to local database...");
+ LogManager.Log("Initializing database manager...");
+ DbManager db = DbManager.FromDataSource(localDataSource);
+
+ LogManager.Log("Checking Tango database exists on the local machine...");
+ if (!db.Exists(localDataSource.Catalog))
+ {
+ throw new InvalidProgramException("Database tango does not exists.");
+ }
+
+ UpdateProgress("Updating Database", "Creating database backup...");
+
+ //Create Database Backup
+ try
+ {
+ Directory.CreateDirectory(backupsFolder);
+ dbBackupFile = $"{backupsFolder}\\{Path.GetRandomFileName()}.bak";
+ LogManager.Log($"Creating database backup to '{dbBackupFile}'...");
+ await Task.Factory.StartNew(() => db.Backup(localDataSource.Catalog, dbBackupFile));
+ performDatabaseRollback = true;
+ LogManager.Log("Database backup created successfully.");
+ }
+ catch (Exception ex)
+ {
+ throw LogManager.Log(ex, "Update manager error while trying to create a database backup.");
+ }
+
+ LogManager.Log("Extracting database file from package...");
+ File.Copy(Path.Combine(_newPackageTempFolder, tempDbFileName), Path.Combine(backupsFolder, tempDbFileName));
+
+ LogManager.Log("Restoring package database as a new database...");
+ db.RestoreAsNew(tempDbName, Path.Combine(backupsFolder, tempDbFileName), backupsFolder);
+
+ Core.DataSource tempDbDataSource = new Core.DataSource();
+ tempDbDataSource.Address = localDataSource.Address;
+ tempDbDataSource.IntegratedSecurity = localDataSource.IntegratedSecurity;
+ tempDbDataSource.Type = localDataSource.Type;
+ tempDbDataSource.Catalog = tempDbName;
+
+ LogManager.Log("Disposing database manager.");
+ db.Dispose();
+
+ LogManager.Log($"Initializing {nameof(ExaminerSequenceConfigurationRunner)}...");
+
+ UpdateProgress("Updating Database", "Initializing update sequence...");
+
+ ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner(
+ Path.Combine(_newPackageTempFolder, "Update Scripts", "config.xml"),
+ Path.Combine(_newPackageTempFolder, "Update Scripts"),
+ tempDbDataSource,
+ localDataSource,
+ serialNumber);
+
+ runner.Log += (x, msg) =>
{
- UpdatePackagePath = _newPackageTempFolder,
+ LogManager.Log(msg);
+ ProgressLog?.Invoke(this, msg);
};
- });
+
+ runner.ScriptExecuting += (x, item) =>
+ {
+ LogManager.Log($"Executing script {item.ToString()}...");
+ UpdateProgress("Updating Database", item.Name + "...");
+ };
+
+ LogManager.Log("Starting synchronization process...");
+
+ try
+ {
+ await runner.Run();
+ LogManager.Log("Synchronization completed successfully!");
+ UpdateProgress("Updating Database", "Database synchronization completed successfully.");
+ }
+ catch (Exception ex)
+ {
+ throw LogManager.Log(ex, "Update manager error while trying to synchronize database.");
+ }
+
+ LogManager.Log("Getting setup firmware/fpga directly from db..");
+
+ using (var dbManager = DbManager.FromDataSource(localDataSource))
+ {
+ try
+ {
+ String firmware = dbManager.GetValue($"SELECT TOP 1 * FROM MACHINES WHERE SERIAL_NUMBER = '{serialNumber}'", "SETUP_FIRMWARE");
+ String fpga = dbManager.GetValue($"SELECT TOP 1 * FROM MACHINES WHERE SERIAL_NUMBER = '{serialNumber}'", "SETUP_FPGA");
+
+ setupFirmware = bool.Parse(firmware);
+ setupFPGA = bool.Parse(fpga);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error getting new values of SETUP_FIRMWARE and SETUP_FPGA.");
+ }
+ }
+
+ //Updating firmware
+ if (setupFirmware)
+ {
+ UpdateProgress("Updating Firmware", "Connecting to firmware device...");
+ LogManager.Log("");
+ LogManager.Log("-------------------------------------------------------------------------");
+ LogManager.Log("Updating Firmware...");
+
+ UpdateProgress("Updating Firmware", "Loading firmware package...");
+ var tfpPath = Path.Combine(_newPackageTempFolder, "firmware_package.tfp");
+ var stream = new FileStream(tfpPath, FileMode.Open);
+
+ if (!_machineProvider.Machine.IsDemo)
+ {
+ if (setupFPGA)
+ {
+ op.FirmwareUpgradeMode = FirmwareUpgradeModes.DFU | FirmwareUpgradeModes.TFP_PACKAGE;
+ }
+ else
+ {
+ op.FirmwareUpgradeMode = FirmwareUpgradeModes.DFU;
+ }
+ }
+ else
+ {
+ op.FirmwareUpgradeMode = FirmwareUpgradeModes.TFP_PACKAGE;
+ }
+
+ var handler = await op.UpgradeFirmware(stream);
+ handler.Failed += (_, ex) =>
+ {
+ stream.Dispose();
+ OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder);
+ };
+ handler.Completed += (_, __) =>
+ {
+ UpdateProgress("Updating Firmware", "Firmware update completed successfully.");
+ stream.Dispose();
+ OnCompleted(new MachineUpdateResult()
+ {
+ UpdatePackagePath = _newPackageTempFolder,
+ RequiresBinariesUpdate = replaceBinaries,
+ }, result, null, tempDbName, backupsFolder, localDataSource);
+ };
+ handler.Canceled += (_, __) =>
+ {
+ stream.Dispose();
+ OnFailed(new Exception("The operation has been canceled."), result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder);
+ };
+ handler.Progress += (_, e) =>
+ {
+ UpdateProgress("Updating Firmware", e.Message, false, e.Current, e.Total);
+ };
+ }
+ else
+ {
+ OnCompleted(new MachineUpdateResult()
+ {
+ UpdatePackagePath = _newPackageTempFolder,
+ RequiresBinariesUpdate = replaceBinaries,
+ }, result, null, tempDbName, backupsFolder, localDataSource);
+ }
+ }
+ catch (Exception ex)
+ {
+ OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder);
+ }
+
+ return await result.Task;
}
/// <summary>
@@ -907,25 +1251,23 @@ namespace Tango.PPC.Common.MachineUpdate
/// </summary>
/// <param name="filePath">The file path.</param>
/// <returns></returns>
- public Task<UpdatePackageFile> GetUpdatePackageFileInfo(string filePath)
+ public Task<PublishInfo> GetUpdatePackageFileInfo(string filePath)
{
- return Task.Factory.StartNew<UpdatePackageFile>(() =>
+ return Task.Factory.StartNew<PublishInfo>(() =>
{
- UpdatePackageFile file = new UpdatePackageFile();
- var tempFolder = TemporaryManager.CreateFolder();
-
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile(filePath))
{
- var appEntry = zip.Entries.SingleOrDefault(x => x.FileName == "Tango.PPC.UI.exe");
- appEntry.Extract(tempFolder);
- }
+ var appEntry = zip.Entries.SingleOrDefault(x => x.FileName == "version.json");
+ var reader = appEntry.OpenReader();
- FileVersionInfo info = FileVersionInfo.GetVersionInfo(Path.Combine(tempFolder, "Tango.PPC.UI.exe"));
- file.Version = Version.Parse(info.ProductVersion);
-
- tempFolder.Delete();
+ using (StreamReader stReader = new StreamReader(reader))
+ {
+ String json = stReader.ReadToEnd();
+ reader.Dispose();
- return file;
+ return PublishInfo.FromJson(json);
+ }
+ }
});
}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs
index 17ae394ee..85dd5b7d2 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs
@@ -12,5 +12,18 @@ namespace Tango.PPC.Common.MachineUpdate
/// Gets or sets the temporary update package path from which to get the last downloaded software version.
/// </summary>
public String UpdatePackagePath { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the application should replace it's binaries.
+ /// </summary>
+ public bool RequiresBinariesUpdate { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MachineUpdateResult"/> class.
+ /// </summary>
+ public MachineUpdateResult()
+ {
+ RequiresBinariesUpdate = true;
+ }
}
}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs
deleted file mode 100644
index df496c3be..000000000
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Tango.PPC.Common.MachineUpdate
-{
- public class UpdatePackageFile
- {
- public Version Version { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs
index 77717254e..df5690a05 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.PMR.FirmwareUpgrade;
+using Tango.Web;
namespace Tango.PPC.Common.Publish
{
@@ -13,6 +14,9 @@ namespace Tango.PPC.Common.Publish
public String ApplicationVersion { get; set; }
public VersionPackageDescriptor Firmware { get; set; }
public String Comments { get; set; }
+ public bool IsMachineTupPackage { get; set; }
+ public String MachineSerialNumber { get; set; }
+ public DeploymentSlot MachineDeploymentSlot { get; set; }
public PublishInfo()
{
@@ -24,7 +28,7 @@ namespace Tango.PPC.Common.Publish
return JsonConvert.SerializeObject(this);
}
- public PublishInfo FromJson(String json)
+ public static PublishInfo FromJson(String json)
{
return JsonConvert.DeserializeObject<PublishInfo>(json);
}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
index e3a23903e..d38b9c8e9 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
@@ -194,7 +194,6 @@
<Compile Include="Web\PPCWebClientBase.cs" />
<Compile Include="Web\UpdateDBRequest.cs" />
<Compile Include="Web\UpdateDBResponse.cs" />
- <Compile Include="MachineUpdate\UpdatePackageFile.cs" />
<Compile Include="Messages\JobRemovedMessage.cs" />
<Compile Include="Messages\JobSavedMessage.cs" />
<Compile Include="Messages\MachineSettingsSavedMessage.cs" />
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml
index 231f5dabb..a175b655e 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml
@@ -6,16 +6,16 @@
xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs"
xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch"
mc:Ignorable="d"
- Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="550" Height="450" d:DataContext="{d:DesignInstance Type=local:UpdateFromFileViewVM, IsDesignTimeCreatable=False}">
+ Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="570" Height="700" d:DataContext="{d:DesignInstance Type=local:UpdateFromFileViewVM, IsDesignTimeCreatable=False}">
<Grid Margin="20">
<DockPanel>
- <StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Right" Orientation="Horizontal">
- <touch:TouchButton Command="{Binding CloseCommand}" CornerRadius="25" Style="{StaticResource TangoMessageBoxButton}" HorizontalContentAlignment="Center" DockPanel.Dock="Right" Width="120" Height="50" VerticalAlignment="Bottom">CANCEL</touch:TouchButton>
- <touch:TouchButton Command="{Binding OKCommand}" CornerRadius="25" Style="{StaticResource TangoMessageBoxButton}" Foreground="{StaticResource TangoPrimaryAccentBrush}" HorizontalContentAlignment="Center" DockPanel.Dock="Right" Width="120" Height="50" VerticalAlignment="Bottom">UPDATE</touch:TouchButton>
- </StackPanel>
+ <Grid DockPanel.Dock="Bottom">
+ <touch:TouchButton HorizontalAlignment="Left" CornerRadius="25" Command="{Binding CloseCommand}" Style="{StaticResource TangoHollowButton}" Width="150" Height="50" VerticalAlignment="Bottom">CANCEL</touch:TouchButton>
+ <touch:TouchButton HorizontalAlignment="Right" CornerRadius="25" Command="{Binding OKCommand}" Style="{StaticResource TangoHollowButton}" Width="150" Height="50" VerticalAlignment="Bottom">UPDATE</touch:TouchButton>
+ </Grid>
<StackPanel>
<Image Source="../Images/update.png" Stretch="Uniform" Height="120"></Image>
- <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" FontSize="{StaticResource TangoHeaderFontSize}">UPDATE PACKAGE</TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" FontSize="{StaticResource TangoHeaderFontSize}">Tango Update Package</TextBlock>
<TextBlock Margin="20 10" HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center">The selected file contains a software update package. Press 'UPDATE' to start updating your system.</TextBlock>
<TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoGrayTextBrush}">
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs
index 0371e94da..c0654f643 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs
@@ -10,6 +10,7 @@ using Tango.Core.Helpers;
using Tango.Explorer;
using Tango.PPC.Common;
using Tango.PPC.Common.MachineUpdate;
+using Tango.PPC.Common.Publish;
using Tango.PPC.Common.Web;
using Tango.PPC.UI.Dialogs;
using Tango.PPC.UI.Notifications.NotificationItems;
@@ -209,7 +210,7 @@ namespace Tango.PPC.UI.ViewModels
try
{
- _update_result = await MachineUpdateManager.Update(MachineProvider.Machine.SerialNumber, _checkUpdateResponse.SetupFirmware, _checkUpdateResponse.SetupFPGA);
+ _update_result = await MachineUpdateManager.Update(_checkUpdateResponse.SetupFirmware, _checkUpdateResponse.SetupFPGA);
LogManager.Log("Machine update completed.");
await NavigateTo(MachineUpdateView.UpdateCompletedView);
}
@@ -248,15 +249,15 @@ namespace Tango.PPC.UI.ViewModels
{
LogManager.Log("Completing machine update...");
- if (!IsDbUpdate)
+ if (IsDbUpdate || !_update_result.RequiresBinariesUpdate)
{
- String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe");
- ApplicationManager.UpdateApplication(updater_exe, PathHelper.GetStartupPath());
+ LogManager.Log("Restarting Application...");
+ ApplicationManager.Restart();
}
else
{
- LogManager.Log("Restarting Application...");
- ApplicationManager.Restart();
+ String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe");
+ ApplicationManager.UpdateApplication(updater_exe, PathHelper.GetStartupPath());
}
}
@@ -375,7 +376,7 @@ namespace Tango.PPC.UI.ViewModels
private async void HandleSoftwareUpdatePackageLoaded(ExplorerFileItem fileItem)
{
- UpdatePackageFile packageFile = null;
+ PublishInfo packageFile = null;
try
{
@@ -383,38 +384,33 @@ namespace Tango.PPC.UI.ViewModels
}
catch (Exception ex)
{
- LogManager.Log(ex, $"Error loading update package file from {fileItem.Path}.");
+ LogManager.Log(ex, $"Error loading publish info from {fileItem.Path}.");
await NotificationProvider.ShowError("An error occurred while trying to load the selected software update package. Please make sure the package is valid.");
return;
}
- if (ApplicationManager.Version <= packageFile.Version)
- {
- await NotificationProvider.ShowError($"The selected update package (v{packageFile.Version.ToString()}) contains an older software version.");
- return;
- }
-
UpdateFromFileViewVM vm = new UpdateFromFileViewVM();
- vm.Version = packageFile.Version.ToString();
+ vm.Version = packageFile.ApplicationVersion;
await NotificationProvider.ShowDialog(vm);
if (vm.DialogResult)
{
await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView);
- await NavigateTo(MachineUpdateView.UpdateFromPackageView);
+ await NavigateTo(MachineUpdateView.UpdateProgressView);
LogManager.Log("Starting machine update from package...");
try
{
- _update_result = await MachineUpdateManager.UpdateFromTUP(fileItem.Path);
+ _update_result = await MachineUpdateManager.UpdateFromTUP(fileItem.Path, MachineProvider.Machine.SetupFirmware, MachineProvider.Machine.SetupFpga);
LogManager.Log("Machine update from package completed.");
await NavigateTo(MachineUpdateView.UpdateCompletedView);
}
catch (Exception ex)
{
LogManager.Log(ex, "Machine update from package failed.");
+ FailedError = ex.FlattenMessage();
await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView);
}
}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml
index fba8a599d..beb09be0d 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml
@@ -194,8 +194,9 @@
<touch:TouchButton Padding="20" Width="300" Margin="0 0 0 130" CornerRadius="35" Command="{Binding CloseCommand}">CLOSE</touch:TouchButton>
</StackPanel>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0 50 0 0">
- <touch:TouchIcon Icon="AlertOctagon" Foreground="{StaticResource TangoErrorBrush}" Width="70" Height="70" />
- <TextBlock VerticalAlignment="Center" Margin="0 10 0 0" Foreground="{StaticResource TangoErrorBrush}" FontSize="{StaticResource TangoTitleFontSize}">An error occurred while trying to update the machine.</TextBlock>
+ <touch:TouchIcon Icon="AlertOutline" Foreground="{StaticResource TangoErrorBrush}" Width="70" Height="70" />
+ <TextBlock HorizontalAlignment="Center" Margin="0 10 0 0" FontSize="{StaticResource TangoTitleFontSize}">Update Failed</TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 5 0 0" Foreground="{StaticResource TangoErrorBrush}" TextAlignment="Center" Text="{Binding FailedError,FallbackValue='Unexpected error'}"></TextBlock>
</StackPanel>
</DockPanel>
</Grid>
diff --git a/Software/Visual_Studio/Tango.Core/DB/DbManager.cs b/Software/Visual_Studio/Tango.Core/DB/DbManager.cs
index 1d415fdb1..8601d67a0 100644
--- a/Software/Visual_Studio/Tango.Core/DB/DbManager.cs
+++ b/Software/Visual_Studio/Tango.Core/DB/DbManager.cs
@@ -65,9 +65,15 @@ namespace Tango.Core.DB
#region Public Methods
- public void Create(String name)
+ public void Create(String name, String filePath = null)
{
String command = String.Format("CREATE DATABASE {0}", name);
+
+ if (filePath != null)
+ {
+ command = $"CREATE DATABASE {name} ON (name='{name}', filename='{filePath}')";
+ }
+
SqlCommand cmd = new SqlCommand(command, _connection);
cmd.ExecuteNonQuery();
}
@@ -160,6 +166,13 @@ namespace Tango.Core.DB
SetOnline(name);
}
+ public void RestoreAsNew(String name, String file, String dbFolder)
+ {
+ String command = $"RESTORE DATABASE {name} FROM DISK='{file}' WITH MOVE '{name}' TO '{Path.Combine(dbFolder, name)}.mdf', MOVE '{name}_log' TO '{Path.Combine(dbFolder, name)}.ldf'";
+ SqlCommand cmd = new SqlCommand(command, _connection);
+ cmd.ExecuteNonQuery();
+ }
+
public void ClearDb()
{
if (!_connection.ConnectionString.ToLower().Contains("initial catalog"))
@@ -265,6 +278,24 @@ EXEC sp_executesql @statement
return cred;
}
+ public String GetValue(String query, String columnName)
+ {
+ string sql = query;
+ var cm = new SqlCommand(sql, _connection);
+ var dr = cm.ExecuteReader();
+ if (dr.Read())
+ {
+ var value = dr[columnName];
+
+ if (value != null)
+ {
+ return value.ToString();
+ }
+ }
+
+ return null;
+ }
+
#endregion
#region IDisposable
diff --git a/Software/Visual_Studio/Tango.PMR/FirmwareUpgrade/VersionFileDescriptor.cs b/Software/Visual_Studio/Tango.PMR/FirmwareUpgrade/VersionFileDescriptor.cs
index 98a6c2efc..96b0a8525 100644
--- a/Software/Visual_Studio/Tango.PMR/FirmwareUpgrade/VersionFileDescriptor.cs
+++ b/Software/Visual_Studio/Tango.PMR/FirmwareUpgrade/VersionFileDescriptor.cs
@@ -23,16 +23,15 @@ namespace Tango.PMR.FirmwareUpgrade {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChtWZXJzaW9uRmlsZURlc2NyaXB0b3IucHJvdG8SGVRhbmdvLlBNUi5GaXJt",
- "d2FyZVVwZ3JhZGUaHFZlcnNpb25GaWxlRGVzdGluYXRpb24ucHJvdG8ilAEK",
+ "d2FyZVVwZ3JhZGUaHFZlcnNpb25GaWxlRGVzdGluYXRpb24ucHJvdG8iggEK",
"FVZlcnNpb25GaWxlRGVzY3JpcHRvchIQCghGaWxlTmFtZRgBIAEoCRIPCgdW",
"ZXJzaW9uGAIgASgJEkYKC0Rlc3RpbmF0aW9uGAMgASgOMjEuVGFuZ28uUE1S",
- "LkZpcm13YXJlVXBncmFkZS5WZXJzaW9uRmlsZURlc3RpbmF0aW9uEhAKCENo",
- "ZWNrU3VtGAQgASgMQiUKI2NvbS50d2luZS50YW5nby5wbXIuZmlybXdhcmV1",
- "cGdyYWRlYgZwcm90bzM="));
+ "LkZpcm13YXJlVXBncmFkZS5WZXJzaW9uRmlsZURlc3RpbmF0aW9uQiUKI2Nv",
+ "bS50d2luZS50YW5nby5wbXIuZmlybXdhcmV1cGdyYWRlYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Tango.PMR.FirmwareUpgrade.VersionFileDestinationReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.FirmwareUpgrade.VersionFileDescriptor), global::Tango.PMR.FirmwareUpgrade.VersionFileDescriptor.Parser, new[]{ "FileName", "Version", "Destination", "CheckSum" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.FirmwareUpgrade.VersionFileDescriptor), global::Tango.PMR.FirmwareUpgrade.VersionFileDescriptor.Parser, new[]{ "FileName", "Version", "Destination" }, null, null, null)
}));
}
#endregion
@@ -66,7 +65,6 @@ namespace Tango.PMR.FirmwareUpgrade {
fileName_ = other.fileName_;
version_ = other.version_;
destination_ = other.destination_;
- checkSum_ = other.checkSum_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -107,17 +105,6 @@ namespace Tango.PMR.FirmwareUpgrade {
}
}
- /// <summary>Field number for the "CheckSum" field.</summary>
- public const int CheckSumFieldNumber = 4;
- private pb::ByteString checkSum_ = pb::ByteString.Empty;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public pb::ByteString CheckSum {
- get { return checkSum_; }
- set {
- checkSum_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as VersionFileDescriptor);
@@ -134,7 +121,6 @@ namespace Tango.PMR.FirmwareUpgrade {
if (FileName != other.FileName) return false;
if (Version != other.Version) return false;
if (Destination != other.Destination) return false;
- if (CheckSum != other.CheckSum) return false;
return true;
}
@@ -144,7 +130,6 @@ namespace Tango.PMR.FirmwareUpgrade {
if (FileName.Length != 0) hash ^= FileName.GetHashCode();
if (Version.Length != 0) hash ^= Version.GetHashCode();
if (Destination != 0) hash ^= Destination.GetHashCode();
- if (CheckSum.Length != 0) hash ^= CheckSum.GetHashCode();
return hash;
}
@@ -167,10 +152,6 @@ namespace Tango.PMR.FirmwareUpgrade {
output.WriteRawTag(24);
output.WriteEnum((int) Destination);
}
- if (CheckSum.Length != 0) {
- output.WriteRawTag(34);
- output.WriteBytes(CheckSum);
- }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -185,9 +166,6 @@ namespace Tango.PMR.FirmwareUpgrade {
if (Destination != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Destination);
}
- if (CheckSum.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeBytesSize(CheckSum);
- }
return size;
}
@@ -205,9 +183,6 @@ namespace Tango.PMR.FirmwareUpgrade {
if (other.Destination != 0) {
Destination = other.Destination;
}
- if (other.CheckSum.Length != 0) {
- CheckSum = other.CheckSum;
- }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -230,10 +205,6 @@ namespace Tango.PMR.FirmwareUpgrade {
destination_ = (global::Tango.PMR.FirmwareUpgrade.VersionFileDestination) input.ReadEnum();
break;
}
- case 34: {
- CheckSum = input.ReadBytes();
- break;
- }
}
}
}
diff --git a/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs b/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs
index de146ead3..b9ee0cf7a 100644
--- a/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs
+++ b/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs
@@ -24,6 +24,15 @@ namespace Tango.SQLExaminer
public ExaminerSequenceConfiguration Configuration { get; private set; }
+ public ExaminerSequenceConfigurationRunner(ExaminerSequenceConfiguration sequenceConfiguration, String scriptsFolder, Core.DataSource source, Core.DataSource target, String machineSerialNumber)
+ {
+ ScriptsFolder = scriptsFolder;
+ Source = source;
+ Target = target;
+ MachineSerialNumber = machineSerialNumber;
+ Configuration = sequenceConfiguration;
+ }
+
public ExaminerSequenceConfigurationRunner(String sequenceFile, String scriptsFolder, Core.DataSource source, Core.DataSource target, String machineSerialNumber)
{
SequenceFile = sequenceFile;
diff --git a/Software/Visual_Studio/Tango.SQLExaminer/ExtensionMethods.cs b/Software/Visual_Studio/Tango.SQLExaminer/ExtensionMethods.cs
new file mode 100644
index 000000000..09a830ab3
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SQLExaminer/ExtensionMethods.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.SQLExaminer;
+
+public static class ExtensionMethods
+{
+ public static String GetFilePath(this ExaminerConfigurationType type)
+ {
+ return Path.Combine(Helper.SQL_EXAMINER_CONFIG_FOLDER, type.ToString() + ".xml");
+ }
+
+ public static String GetFileName(this ExaminerConfigurationType type)
+ {
+ return type.ToString() + ".xml";
+ }
+}
+
diff --git a/Software/Visual_Studio/Tango.SQLExaminer/Helper.cs b/Software/Visual_Studio/Tango.SQLExaminer/Helper.cs
index 5eb09b98c..3b4e238a7 100644
--- a/Software/Visual_Studio/Tango.SQLExaminer/Helper.cs
+++ b/Software/Visual_Studio/Tango.SQLExaminer/Helper.cs
@@ -8,7 +8,7 @@ using Tango.Core.Helpers;
namespace Tango.SQLExaminer
{
- internal static class Helper
+ public static class Helper
{
public static String SQL_EXAMINER_FOLDER = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "SQLExaminer");
public static String SQL_EXAMINER_CONFIG_FOLDER = Path.Combine(SQL_EXAMINER_FOLDER, "Configurations");
diff --git a/Software/Visual_Studio/Tango.SQLExaminer/Tango.SQLExaminer.csproj b/Software/Visual_Studio/Tango.SQLExaminer/Tango.SQLExaminer.csproj
index b71a30dc0..17dcb1b22 100644
--- a/Software/Visual_Studio/Tango.SQLExaminer/Tango.SQLExaminer.csproj
+++ b/Software/Visual_Studio/Tango.SQLExaminer/Tango.SQLExaminer.csproj
@@ -69,6 +69,7 @@
<Compile Include="ExaminerSequenceItemDirection.cs" />
<Compile Include="ExaminerSequenceItemType.cs" />
<Compile Include="ExaminerSerializedObject.cs" />
+ <Compile Include="ExtensionMethods.cs" />
<Compile Include="Filter.cs" />
<Compile Include="Helper.cs" />
<Compile Include="IncludeItem.cs" />
diff --git a/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer/SQLExaminer_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer/SQLExaminer_TST.cs
index 9b0385c23..e3e49ac5e 100644
--- a/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer/SQLExaminer_TST.cs
+++ b/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer/SQLExaminer_TST.cs
@@ -391,5 +391,76 @@ namespace Tango.UnitTesting.SQLExaminer
//Should have no differences!
Assert.IsFalse(data_report.HasDifferences);
}
+
+ [TestMethod]
+ public void Perform_Machine_Update_From_Backup()
+ {
+ String tempDbName = "Tango_TUP";
+
+ var source_db = GetSource("Tango");
+ var target_db = GetSource(tempDbName);
+
+ DbManager dbManager = DbManager.FromDataSource(source_db);
+
+ //Create the backup for the tup file.
+ dbManager.Create(tempDbName);
+
+ var configuration = GetFullConfiguration();
+
+ ExaminerSequenceConfigurationRunner runner =
+ new ExaminerSequenceConfigurationRunner(
+ configuration,
+ Tango.SQLExaminer.Helper.SQL_EXAMINER_CONFIG_FOLDER,
+ source_db,
+ target_db,
+ "1111");
+
+ runner.Run().GetAwaiter().GetResult();
+
+ String backupFile = "C:\\DB_Backups\\Tango_TEMP.bak";
+
+ dbManager.Backup(tempDbName, backupFile);
+ dbManager.SetOffline(tempDbName);
+ dbManager.SetOnline(tempDbName);
+ dbManager.Delete(tempDbName);
+
+ //Now restore as different name
+ dbManager.RestoreAsNew(tempDbName, backupFile, "C:\\DB_Backups");
+ }
+
+ private ExaminerSequenceConfiguration GetFullConfiguration()
+ {
+ ExaminerSequenceConfiguration configuration = new ExaminerSequenceConfiguration();
+
+ configuration.Items.Add(new ExaminerSequenceItem()
+ {
+ Type = ExaminerSequenceItemType.Schema,
+ Direction = ExaminerSequenceItemDirection.SourceToTarget,
+ FileName = ExaminerConfigurationType.Schema.GetFileName(),
+ Index = 0,
+ Name = "Updating Schema",
+ });
+
+ configuration.Items.Add(new ExaminerSequenceItem()
+ {
+ Type = ExaminerSequenceItemType.Data,
+ Direction = ExaminerSequenceItemDirection.SourceToTarget,
+ FileName = ExaminerConfigurationType.OverrideData.GetFileName(),
+ Index = 1,
+ Name = "Updating Collections",
+ });
+
+ configuration.Items.Add(new ExaminerSequenceItem()
+ {
+ Type = ExaminerSequenceItemType.Data,
+ Direction = ExaminerSequenceItemDirection.SourceToTarget,
+ FileName = ExaminerConfigurationType.ProvisionMachine.GetFileName(),
+ Index = 2,
+ Name = "Configuring Machine",
+ RequiresSerialNumber = true,
+ });
+
+ return configuration;
+ }
}
}
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs
index 2eeaa6e0e..378fc3eea 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs
@@ -23,6 +23,10 @@ using Tango.Web.ActiveDirectory;
using Tango.MachineService.Filters;
using Tango.MachineService.Security;
using Tango.Web.SQLServer;
+using Tango.Core;
+using Tango.Web.SMO;
+using Tango.Core.DB;
+using System.Threading.Tasks;
namespace Tango.MachineService.Controllers
{
@@ -425,6 +429,67 @@ namespace Tango.MachineService.Controllers
};
}
+ [HttpPost]
+ [JwtTokenFilter]
+ public DownloadLatestPPCVersionResponse DownloadLatestPPCVersion(DownloadLatestPPCVersionRequest request)
+ {
+ DownloadLatestPPCVersionResponse response = new DownloadLatestPPCVersionResponse();
+
+ using (ObservablesContext db = ObservablesContextHelper.CreateContext())
+ {
+ var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == request.SerialNumber);
+
+ if (machine == null)
+ {
+ throw new AuthenticationException("The specified serial number could not be found.");
+ }
+
+ var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid);
+
+ var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
+
+ response.Version = latest_machine_version.Version;
+
+ var manager = new BlobStorageManager();
+ var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER);
+ var blob = container.GetBlockBlobReference(latest_machine_version.BlobName);
+
+ response.BlobAddress = blob.GenerateReadSignature(TimeSpan.FromMinutes(60));
+
+ if (!String.IsNullOrWhiteSpace(MachineServiceConfig.CDN_ENDPOINT))
+ {
+ response.CdnAddress = MachineServiceConfig.CDN_ENDPOINT + blob.Uri.AbsolutePath;
+ }
+
+ DbCredentials credentials = new DbCredentials();
+
+ using (SmoManager smo = new SmoManager())
+ {
+ credentials = smo.CreateRandomLoginAndUser();
+
+ Task.Delay(TimeSpan.FromMinutes(PPCController.SQL_TEMP_CREDENTIALS_EXP_MINUTS)).ContinueWith((x) =>
+ {
+ using (SmoManager m = new SmoManager())
+ {
+ m.DeleteLoginAndUser(credentials.UserName);
+ }
+ });
+ }
+
+ response.DataSource = new DataSource()
+ {
+ Address = MachineServiceConfig.DB_ADDRESS,
+ Catalog = MachineServiceConfig.DB_CATALOG,
+ UserName = credentials.UserName,
+ Password = credentials.Password,
+ IntegratedSecurity = false,
+ Type = DataSourceType.SQLServer,
+ };
+ }
+
+ return response;
+ }
+
#endregion
}
}
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
index 2dee09e69..0d9a2993b 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
@@ -32,7 +32,7 @@ namespace Tango.MachineService.Controllers
private static List<PPCPendingUpload> _pendingUploads;
private static List<PPCPendingUpdate> _pendingUpdates;
private ActiveDirectoryManager _ad_manager;
- private const int SQL_TEMP_CREDENTIALS_EXP_MINUTS = 20;
+ public const int SQL_TEMP_CREDENTIALS_EXP_MINUTS = 20;
public class TokenObject
{