From 3d9beda13daccac78fb05dc94d1430a0a47e9db6 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Thu, 30 Aug 2018 14:30:37 +0300 Subject: Some work.. --- .../Publish Machine Service via FTP.pubxml | 21 +++++ .../Tango.MachineService.csproj | 7 +- .../Web/Tango.MachineService/Web.config | 97 +++++++++++----------- 3 files changed, 74 insertions(+), 51 deletions(-) create mode 100644 Software/Visual_Studio/Web/Tango.MachineService/Properties/PublishProfiles/Publish Machine Service via FTP.pubxml (limited to 'Software/Visual_Studio/Web/Tango.MachineService') diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/PublishProfiles/Publish Machine Service via FTP.pubxml b/Software/Visual_Studio/Web/Tango.MachineService/Properties/PublishProfiles/Publish Machine Service via FTP.pubxml new file mode 100644 index 000000000..bd9a693e0 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/PublishProfiles/Publish Machine Service via FTP.pubxml @@ -0,0 +1,21 @@ + + + + + FTP + Release + Any CPU + + True + False + twine01 + True + True + MachineService + PublishFTP|Roy + <_SavePWD>False + + \ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj index bc05f04bc..3f54c8568 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj +++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj @@ -83,9 +83,9 @@ - + @@ -222,6 +222,9 @@ + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) @@ -248,7 +251,7 @@ False - + diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Web.config b/Software/Visual_Studio/Web/Tango.MachineService/Web.config index d116dc437..281fdadeb 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Web.config +++ b/Software/Visual_Studio/Web/Tango.MachineService/Web.config @@ -1,4 +1,4 @@ - + -
+
- - - - - - - - - - - - + + + + + + + + + - - + + - + - - - - + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + - - - - \ No newline at end of file + + + + + + + \ No newline at end of file -- cgit v1.3.1 From 37e5138e6acac4a9b93e018087fe9c50d36c4b34 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Thu, 30 Aug 2018 19:04:18 +0300 Subject: Implemented machine update on PPC !!! Need to verify update scripts... --- Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 15400960 -> 15400960 bytes Software/Graphics/machine-update.png | Bin 0 -> 54914 bytes .../Synchronization/CheckForUpdateRequest.proto | 10 + .../Synchronization/CheckForUpdateResponse.proto | 10 + .../Synchronization/DownloadUpdateRequest.proto | 9 + .../Synchronization/DownloadUpdateResponse.proto | 18 ++ .../MachineSetup/MachineSetupManager.cs | 4 +- .../MachineUpdate/IMachineUpdateManager.cs | 53 +++ .../MachineUpdate/MachineUpdateManager.cs | 287 ++++++++++++++++ .../MachineUpdate/MachineUpdateResult.cs | 16 + .../MachineUpdate/MachineUpdateSteps.cs | 21 ++ .../Tango.PPC.Common/Navigation/NavigationView.cs | 1 + .../PPC/Tango.PPC.Common/Tango.PPC.Common.csproj | 6 +- .../PPC/Tango.PPC.Publisher/MainWindow.xaml | 19 +- .../PPC/Tango.PPC.Publisher/MainWindow.xaml.cs | 51 ++- .../PPC/Tango.PPC.Publisher/MainWindowVM.cs | 90 ++++-- .../PPC/Tango.PPC.UI/Images/machine-update.png | Bin 0 -> 54914 bytes .../PPC/Tango.PPC.UI/Images/right-arrow-64.png | Bin 0 -> 690 bytes .../PPCApplication/DefaultPPCApplicationManager.cs | 1 - .../PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs | 2 +- .../PPC/Tango.PPC.UI/Tango.PPC.UI.csproj | 13 +- .../PPC/Tango.PPC.UI/ViewModelLocator.cs | 13 + .../PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs | 9 + .../Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs | 7 +- .../Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs | 170 ++++++++++ .../PPC/Tango.PPC.UI/Views/LayoutView.xaml | 9 + .../PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml | 129 ++++++++ .../Tango.PPC.UI/Views/MachineUpdateView.xaml.cs | 46 +++ .../PPC/Tango.PPC.UI/Views/MainView.xaml | 1 + .../ViewsContracts/IMachineUpdateView.cs | 19 ++ .../PPC/Tango.PPC.Updater/MainWindow.xaml.cs | 50 ++- .../Visual_Studio/Tango.Logging/ConsoleWindow.xaml | 2 +- .../Tango.Logging/ConsoleWindow.xaml.cs | 2 +- .../Synchronization/CheckForUpdateRequest.cs | 188 +++++++++++ .../Synchronization/CheckForUpdateResponse.cs | 188 +++++++++++ .../Synchronization/DownloadUpdateRequest.cs | 160 +++++++++ .../Synchronization/DownloadUpdateResponse.cs | 359 +++++++++++++++++++++ Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj | 11 +- .../Tango.SharedUI/Controls/NavigationControl.cs | 15 +- .../Controllers/SynchronizationController.cs | 96 ++++++ 41 files changed, 2028 insertions(+), 57 deletions(-) create mode 100644 Software/Graphics/machine-update.png create mode 100644 Software/PMR/Messages/Synchronization/CheckForUpdateRequest.proto create mode 100644 Software/PMR/Messages/Synchronization/CheckForUpdateResponse.proto create mode 100644 Software/PMR/Messages/Synchronization/DownloadUpdateRequest.proto create mode 100644 Software/PMR/Messages/Synchronization/DownloadUpdateResponse.proto create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateSteps.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-update.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/right-arrow-64.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/ViewsContracts/IMachineUpdateView.cs create mode 100644 Software/Visual_Studio/Tango.PMR/Synchronization/CheckForUpdateRequest.cs create mode 100644 Software/Visual_Studio/Tango.PMR/Synchronization/CheckForUpdateResponse.cs create mode 100644 Software/Visual_Studio/Tango.PMR/Synchronization/DownloadUpdateRequest.cs create mode 100644 Software/Visual_Studio/Tango.PMR/Synchronization/DownloadUpdateResponse.cs (limited to 'Software/Visual_Studio/Web/Tango.MachineService') diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 9d864e6a7..3e25b6208 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 1e080784d..a4d8c33d4 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Graphics/machine-update.png b/Software/Graphics/machine-update.png new file mode 100644 index 000000000..3e49520dd Binary files /dev/null and b/Software/Graphics/machine-update.png differ diff --git a/Software/PMR/Messages/Synchronization/CheckForUpdateRequest.proto b/Software/PMR/Messages/Synchronization/CheckForUpdateRequest.proto new file mode 100644 index 000000000..4b1da8764 --- /dev/null +++ b/Software/PMR/Messages/Synchronization/CheckForUpdateRequest.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package Tango.PMR.Synchronization; +option java_package = "com.twine.tango.pmr.synchronization"; + +message CheckForUpdateRequest +{ + string SerialNumber = 1; + string Version = 2; +} \ No newline at end of file diff --git a/Software/PMR/Messages/Synchronization/CheckForUpdateResponse.proto b/Software/PMR/Messages/Synchronization/CheckForUpdateResponse.proto new file mode 100644 index 000000000..30e2b6fbb --- /dev/null +++ b/Software/PMR/Messages/Synchronization/CheckForUpdateResponse.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package Tango.PMR.Synchronization; +option java_package = "com.twine.tango.pmr.synchronization"; + +message CheckForUpdateResponse +{ + bool IsUpdateAvailable = 1; + string Version = 2; +} \ No newline at end of file diff --git a/Software/PMR/Messages/Synchronization/DownloadUpdateRequest.proto b/Software/PMR/Messages/Synchronization/DownloadUpdateRequest.proto new file mode 100644 index 000000000..98b302f85 --- /dev/null +++ b/Software/PMR/Messages/Synchronization/DownloadUpdateRequest.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package Tango.PMR.Synchronization; +option java_package = "com.twine.tango.pmr.synchronization"; + +message DownloadUpdateRequest +{ + string SerialNumber = 1; +} \ No newline at end of file diff --git a/Software/PMR/Messages/Synchronization/DownloadUpdateResponse.proto b/Software/PMR/Messages/Synchronization/DownloadUpdateResponse.proto new file mode 100644 index 000000000..db70e7d92 --- /dev/null +++ b/Software/PMR/Messages/Synchronization/DownloadUpdateResponse.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package Tango.PMR.Synchronization; +option java_package = "com.twine.tango.pmr.synchronization"; + +message DownloadUpdateResponse +{ + string Version = 1; + + string FtpAddress = 2; + string FtpFilePath = 3; + string FtpUserName = 4; + string FtpPassword = 5; + + string DbAddress = 6; + string DbUserName = 7; + string DbPassword = 8; +} \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs index 8d4d5fa0a..252491669 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs @@ -196,8 +196,8 @@ namespace Tango.PPC.Common.MachineSetup LogManager.Log($"Initializing {nameof(ExaminerSequenceConfigurationRunner)}..."); ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner( - Path.Combine(_newPackageTempFolder, "Synchronization Scripts", "config.xml"), - Path.Combine(_newPackageTempFolder, "Synchronization Scripts"), + Path.Combine(_newPackageTempFolder, "Provision Scripts", "config.xml"), + Path.Combine(_newPackageTempFolder, "Provision Scripts"), new ExaminerSequenceDataSource() { Address = remote_address, diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs new file mode 100644 index 000000000..fd565b84a --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR.Synchronization; + +namespace Tango.PPC.Common.MachineUpdate +{ + public interface IMachineUpdateManager + { + /// + /// Gets the current setup step. + /// + MachineUpdateSteps CurrentStep { get; } + + /// + /// Occurs when there is a text log message available. + /// + event EventHandler ProgressLog; + + /// + /// Gets the downloading packages step progress. + /// + double DownloadingPackagesProgress { get; } + + /// + /// Gets the downloading packages step status. + /// + String DownloadingPackagesStatus { get; } + + /// + /// Occurs when the has changed. + /// + event EventHandler ProgressStep; + + /// + /// Performs a machine update using the specified serial number and machine service address. + /// + /// The serial number. + /// The machine service address. + /// + Task Update(String serialNumber, String machineServiceAddress); + + /// + /// Checks if any update are available for the specified machine serial number. + /// + /// The serial number. + /// The machine service address. + /// + Task CheckForUpdate(String serialNumber, String machineServiceAddress); + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs new file mode 100644 index 000000000..b86fb88d4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs @@ -0,0 +1,287 @@ +using FluentFTP; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.Core; +using Tango.Core.DB; +using Tango.Core.Helpers; +using Tango.Core.IO; +using Tango.PMR.Synchronization; +using Tango.PPC.Common.Application; +using Tango.Settings; +using Tango.SQLExaminer; +using Tango.Transport.Web; + +namespace Tango.PPC.Common.MachineUpdate +{ + public class MachineUpdateManager : ExtendedObject, IMachineUpdateManager + { + private IPPCApplicationManager _app_manager; + + #region Events + + /// + /// Occurs when there is a text log message available. + /// + public event EventHandler ProgressLog; + + /// + /// Occurs when the has changed. + /// + public event EventHandler ProgressStep; + + #endregion + + #region Properties + + private MachineUpdateSteps _currentStep; + /// + /// Gets the current setup step. + /// + public MachineUpdateSteps CurrentStep + { + get { return _currentStep; } + set + { + if (_currentStep != value) + { + _currentStep = value; + RaisePropertyChangedAuto(); + ProgressStep?.Invoke(this, _currentStep); + LogManager.Log("Machine Setup Manager Step: " + value.ToString()); + } + } + } + + private double _downloadProgress; + /// + /// Gets the downloading packages step progress. + /// + public double DownloadingPackagesProgress + { + get { return _downloadProgress; } + private set { _downloadProgress = value; RaisePropertyChangedAuto(); } + } + + private String _updatingPackagesStatus; + /// + /// Gets the downloading packages step status. + /// + public String DownloadingPackagesStatus + { + get { return _updatingPackagesStatus; } + set { _updatingPackagesStatus = value; RaisePropertyChangedAuto(); } + } + + #endregion + + /// + /// Initializes a new instance of the class. + /// + /// The application manager. + public MachineUpdateManager(IPPCApplicationManager applicationManager) + { + _app_manager = applicationManager; + } + + #region Public Methods + + /// + /// Performs a machine setup using the specified serial number and machine service address. + /// + /// The serial number. + /// The machine service address. + /// + public Task Update(string serialNumber, string machineServiceAddress) + { + return Task.Factory.StartNew(() => + { + + LogManager.Log($"Starting machine update for serial number {serialNumber}..."); + + //Connect to machine service and get matching packages for this machine. + CurrentStep = MachineUpdateSteps.DownloadingPackage; + DownloadingPackagesProgress = 0; + DownloadingPackagesStatus = "Connecting to machine service..."; + + LogManager.Log($"Connecting to machine service on {machineServiceAddress}..."); + + DownloadUpdateRequest request = new DownloadUpdateRequest(); + request.SerialNumber = serialNumber; + + DownloadUpdateResponse update_response = null; + + using (var http = new ProtoWebClient()) + { + update_response = http.Post(machineServiceAddress + "/api/Synchronization/MachineUpdate", request).Result; + } + + 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. + var tempFile = TemporaryManager.CreateFile(".zip"); + + LogManager.Log($"Temporary package zip file created: {tempFile}."); + + DownloadingPackagesStatus = "Downloading software package..."; + + LogManager.Log("Downloading software package..."); + + int fileSize = 0; + DownloadingPackagesProgress = 0; + + using (FileStreamWrapper fs = new FileStreamWrapper(tempFile.Path, FileMode.Create, (current) => + { + InvokeUINow(() => + { + Thread.Sleep(2); //TODO: this is necessary only for visibility... + DownloadingPackagesProgress = ((double)current / (double)fileSize) * 100d; + }); + })) + { + using (FtpClient ftp = new FtpClient(update_response.FtpAddress, update_response.FtpUserName, update_response.FtpPassword)) + { + LogManager.Log("FTP: Connecting to site: " + update_response.FtpAddress); + ftp.ConnectAsync().Wait(); + LogManager.Log("FTP: Retrieving download size..."); + fileSize = (int)ftp.GetFileSize(update_response.FtpFilePath); + LogManager.Log("FTP: Download size: " + fileSize + " bytes."); + LogManager.Log("FTP: Starting download..."); + ftp.DownloadAsync(fs, update_response.FtpFilePath).Wait(); + } + } + + LogManager.Log("Extracting downloaded zip file..."); + //Extract software package. + ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder); + + + 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); + + + //Synchronize database + CurrentStep = MachineUpdateSteps.SynchronizingSchema; + + String db_name = "Tango"; + String localAddress = SettingsManager.Default.GetOrCreate().DataSource.Address; + String remote_address = update_response.DbAddress; + + LogManager.Log($"Synchronizing database '{remote_address}\\{db_name}' => '{localAddress}\\{db_name}'..."); + + LogManager.Log("Initializing database manager..."); + DbManager db = DbManager.FromAddressAndName(localAddress, db_name); + + LogManager.Log("Checking Tango database exists on the local machine..."); + if (!db.Exists(db_name)) + { + throw new InvalidProgramException("Database tango does not exists."); + } + + LogManager.Log("Disposing database manager."); + db.Dispose(); + + LogManager.Log($"Initializing {nameof(ExaminerSequenceConfigurationRunner)}..."); + + ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner( + Path.Combine(_newPackageTempFolder, "Update Scripts", "config.xml"), + Path.Combine(_newPackageTempFolder, "Update Scripts"), + new ExaminerSequenceDataSource() + { + Address = remote_address, + DataBaseName = db_name, + IntegratedSecurity = false, + UserName = update_response.DbUserName, + Password = update_response.DbPassword, + }, + new ExaminerSequenceDataSource() + { + Address = localAddress, + DataBaseName = db_name, + IntegratedSecurity = true, + }, serialNumber); + + runner.Log += (x, msg) => + { + LogManager.Log(msg); + ProgressLog?.Invoke(this, msg); + }; + + runner.ScriptExecuting += (x, item) => + { + LogManager.Log($"Executing script {item.ToString()}..."); + + if (item.Type == ExaminerSequenceItemType.Data && item.RequiresSerialNumber) + { + CurrentStep = MachineUpdateSteps.SynchronizingMachineConfiguration; + } + else if (item.Type == ExaminerSequenceItemType.Data) + { + CurrentStep = MachineUpdateSteps.SynchronizingData; + } + }; + + LogManager.Log("Starting synchronization process..."); + + try + { + runner.Run().Wait(); + LogManager.Log("Synchronization completed successfully!"); + } + catch (Exception ex) + { + throw LogManager.Log(ex, "Setup manager error while trying to synchronize database."); + } + + return new MachineUpdateResult() + { + UpdatePackagePath = _newPackageTempFolder, + }; + }); + } + + /// + /// Checks if any update are available for the specified machine serial number. + /// + /// The serial number. + /// The machine service address. + /// + public Task CheckForUpdate(string serialNumber, string machineServiceAddress) + { + return Task.Factory.StartNew(() => + { + LogManager.Log($"Connecting to machine service on {machineServiceAddress}..."); + LogManager.Log($"Checking if updates available..."); + + CheckForUpdateRequest request = new CheckForUpdateRequest(); + request.SerialNumber = serialNumber; + request.Version = _app_manager.Version.ToString(); + + CheckForUpdateResponse update_response = null; + + using (var http = new ProtoWebClient()) + { + update_response = http.Post(machineServiceAddress + "/api/Synchronization/CheckForUpdate", request).Result; + } + + LogManager.Log($"Check for update response received: {Environment.NewLine}{update_response.ToJsonString()}"); + + return update_response; + }); + } + + #endregion + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs new file mode 100644 index 000000000..17ae394ee --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.MachineUpdate +{ + public class MachineUpdateResult + { + /// + /// Gets or sets the temporary update package path from which to get the last downloaded software version. + /// + public String UpdatePackagePath { get; set; } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateSteps.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateSteps.cs new file mode 100644 index 000000000..3d8208e4b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateSteps.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.MachineUpdate +{ + public enum MachineUpdateSteps + { + [Description("Downloading Package")] + DownloadingPackage, + [Description("Synchronizing Schema")] + SynchronizingSchema, + [Description("Synchronizing Data")] + SynchronizingData, + [Description("Updating Configuration")] + SynchronizingMachineConfiguration + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs index 3c6d91502..ef8f1c2ad 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs @@ -15,6 +15,7 @@ namespace Tango.PPC.Common.Navigation LayoutView, LoginView, MachineSetupView, + MachineUpdateView, ExternalBridgeView, HomeModule, ShutdownView, 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 0fbfb635e..35a79d497 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 @@ -126,6 +126,10 @@ + + + + @@ -299,7 +303,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml index d1921b0a8..8e9b31dff 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml @@ -8,7 +8,7 @@ xmlns:examiner="clr-namespace:Tango.SQLExaminer;assembly=Tango.SQLExaminer" xmlns:local="clr-namespace:Tango.PPC.Publisher" mc:Ignorable="d" - Title="Tango PPC Publisher" Height="800" Width="500" d:DataContext="{d:DesignInstance Type=local:MainWindowVM, IsDesignTimeCreatable=False}"> + Title="Tango PPC Publisher" Height="980" Width="500" d:DataContext="{d:DesignInstance Type=local:MainWindowVM, IsDesignTimeCreatable=False}"> @@ -53,9 +53,22 @@ - Examiner Sequence Items + Examiner Provision Sequence Items - + + + + + + + + + + + + Examiner Update Sequence Items + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml.cs index 64e7e8740..610eb40a8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml.cs @@ -1,6 +1,7 @@ using Microsoft.Win32; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -13,6 +14,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.SQLExaminer; namespace Tango.PPC.Publisher { @@ -35,9 +37,54 @@ namespace Tango.PPC.Publisher { SequenceItem item = new SequenceItem(); - if ((DataContext as MainWindowVM).SequenceItems.Count > 0) + var config = ExaminerConfiguration.FromFile(dlg.FileName); + + if (config.Maker == "SQL Examiner") + { + item.Type = ExaminerSequenceItemType.Schema; + } + else + { + item.Type = ExaminerSequenceItemType.Data; + } + + item.RequiresSerialNumber = File.ReadAllText(dlg.FileName).Contains("'@'"); + + if ((DataContext as MainWindowVM).ProvisionSequenceItems.Count > 0) + { + item.Index = (DataContext as MainWindowVM).ProvisionSequenceItems.Max(x => x.Index + 1); + } + item.FilePath = dlg.FileName; + item.Name = System.IO.Path.GetFileNameWithoutExtension(dlg.FileName); + + e.NewItem = item; + } + } + + private void DataGrid_AddingNewItem_1(object sender, AddingNewItemEventArgs e) + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Filter = "SQL Examiner Configuration|*.xml"; + if (dlg.ShowDialog().Value) + { + SequenceItem item = new SequenceItem(); + + var config = ExaminerConfiguration.FromFile(dlg.FileName); + + if (config.Maker == "SQL Examiner") + { + item.Type = ExaminerSequenceItemType.Schema; + } + else + { + item.Type = ExaminerSequenceItemType.Data; + } + + item.RequiresSerialNumber = File.ReadAllText(dlg.FileName).Contains("'@'"); + + if ((DataContext as MainWindowVM).UpdateSequenceItems.Count > 0) { - item.Index = (DataContext as MainWindowVM).SequenceItems.Max(x => x.Index + 1); + item.Index = (DataContext as MainWindowVM).UpdateSequenceItems.Max(x => x.Index + 1); } item.FilePath = dlg.FileName; item.Name = System.IO.Path.GetFileNameWithoutExtension(dlg.FileName); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindowVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindowVM.cs index 48e4fdf01..4828879e1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindowVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindowVM.cs @@ -66,27 +66,35 @@ namespace Tango.PPC.Publisher set { _currentVersion = value; RaisePropertyChangedAuto(); } } - private ObservableCollection _sequenceItems; - public ObservableCollection SequenceItems + private ObservableCollection _provisionSequenceItems; + public ObservableCollection ProvisionSequenceItems { - get { return _sequenceItems; } - set { _sequenceItems = value; RaisePropertyChangedAuto(); } + get { return _provisionSequenceItems; } + set { _provisionSequenceItems = value; RaisePropertyChangedAuto(); } } - private ICollectionView _sequenceItemsView; - public ICollectionView SequenceItemsView + private ICollectionView _provisionSequenceItemsView; + public ICollectionView ProvisionSequenceItemsView { - get { return _sequenceItemsView; } - set { _sequenceItemsView = value; RaisePropertyChangedAuto(); } + get { return _provisionSequenceItemsView; } + set { _provisionSequenceItemsView = value; RaisePropertyChangedAuto(); } } - private SequenceItem _selectedSequenceItem; - public SequenceItem SelectedSequenceItem + private ObservableCollection _updateSequenceItems; + public ObservableCollection UpdateSequenceItems { - get { return _selectedSequenceItem; } - set { _selectedSequenceItem = value; RaisePropertyChangedAuto(); } + get { return _updateSequenceItems; } + set { _updateSequenceItems = value; RaisePropertyChangedAuto(); } } + private ICollectionView _updateSequenceItemsView; + public ICollectionView UpdateSequenceItemsView + { + get { return _updateSequenceItemsView; } + set { _updateSequenceItemsView = value; RaisePropertyChangedAuto(); } + } + + private String _email; public String Email { @@ -137,10 +145,13 @@ namespace Tango.PPC.Publisher _hashGenerator = new BasicHashGenerator(); - SequenceItems = new ObservableCollection(); - SequenceItemsView = CollectionViewSource.GetDefaultView(SequenceItems); + ProvisionSequenceItems = new ObservableCollection(); + ProvisionSequenceItemsView = CollectionViewSource.GetDefaultView(ProvisionSequenceItems); + ProvisionSequenceItemsView.SortDescriptions.Add(new SortDescription(nameof(SequenceItem.Index), ListSortDirection.Ascending)); - SequenceItemsView.SortDescriptions.Add(new SortDescription(nameof(SequenceItem.Index), ListSortDirection.Ascending)); + UpdateSequenceItems = new ObservableCollection(); + UpdateSequenceItemsView = CollectionViewSource.GetDefaultView(UpdateSequenceItems); + UpdateSequenceItemsView.SortDescriptions.Add(new SortDescription(nameof(SequenceItem.Index), ListSortDirection.Ascending)); using (ObservablesContext db = ObservablesContext.CreateDefault("twine01\\SQLTWINE_TEST")) { @@ -196,15 +207,44 @@ namespace Tango.PPC.Publisher using (ZipFile zip = new ZipFile()) { - String sync_dir = "Synchronization Scripts"; + String provision_dir = "Provision Scripts"; + + zip.AddDirectoryByName(provision_dir); + + ExaminerSequenceConfiguration provision_config = new ExaminerSequenceConfiguration(); + + foreach (var item in ProvisionSequenceItems) + { + provision_config.Items.Add(new ExaminerSequenceItem() + { + Direction = item.Direction, + FileName = item.FileName, + Index = item.Index, + Name = item.Name, + Type = item.Type, + RequiresSerialNumber = item.RequiresSerialNumber + }); + + zip.AddFile(item.FilePath, provision_dir); + } + + String provision_config_file = TemporaryManager.Default.CreateFile(".zip"); + provision_config.ToFile(provision_config_file); + + var cf = zip.AddFile(provision_config_file, provision_dir); + cf.FileName = provision_dir + "\\config.xml"; + + + + String update_dir = "Update Scripts"; - zip.AddDirectoryByName(sync_dir); + zip.AddDirectoryByName(update_dir); - ExaminerSequenceConfiguration config = new ExaminerSequenceConfiguration(); + ExaminerSequenceConfiguration update_config = new ExaminerSequenceConfiguration(); - foreach (var item in SequenceItems) + foreach (var item in UpdateSequenceItems) { - config.Items.Add(new ExaminerSequenceItem() + update_config.Items.Add(new ExaminerSequenceItem() { Direction = item.Direction, FileName = item.FileName, @@ -214,14 +254,14 @@ namespace Tango.PPC.Publisher RequiresSerialNumber = item.RequiresSerialNumber }); - zip.AddFile(item.FilePath, sync_dir); + zip.AddFile(item.FilePath, update_dir); } - String config_file = TemporaryManager.Default.CreateFile(".zip"); - config.ToFile(config_file); + String update_config_file = TemporaryManager.Default.CreateFile(".zip"); + update_config.ToFile(update_config_file); - var cf = zip.AddFile(config_file, sync_dir); - cf.FileName = sync_dir + "\\config.xml"; + var cuf = zip.AddFile(update_config_file, update_dir); + cuf.FileName = update_dir + "\\config.xml"; foreach (var file in Directory.GetFiles(_appPath, "*.*", SearchOption.TopDirectoryOnly)) { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-update.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-update.png new file mode 100644 index 000000000..3e49520dd Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-update.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/right-arrow-64.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/right-arrow-64.png new file mode 100644 index 000000000..b23d81f3c Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/right-arrow-64.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs index e43f37e5f..714b83dfa 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs @@ -71,7 +71,6 @@ namespace Tango.PPC.UI.PPCApplication /// /// Gets the application version. /// - /// public Version Version { get diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs index 648ddbb59..a4ffefec8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs @@ -7,5 +7,5 @@ using System.Windows; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Tango Panel PC Application")] +[assembly: AssemblyTitle("Tango PPC Application")] [assembly: AssemblyVersion("2.0.7.1119")] diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj index 2b2752a24..fc4c94eb0 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj @@ -134,8 +134,10 @@ + + ExternalBridgeView.xaml @@ -154,6 +156,9 @@ MainView.xaml + + MachineUpdateView.xaml + Designer MSBuild:Compile @@ -206,6 +211,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + @@ -356,6 +365,8 @@ Tango.ColorLib.dll PreserveNewest + + @@ -421,7 +432,7 @@ copy /Y "$(SolutionDir)Referenced Assemblies\vcruntime140d.dll" "$(TargetDir)" - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs index bec1d2b48..57fae7791 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs @@ -11,6 +11,7 @@ using Tango.PPC.Common.Diagnostics; using Tango.PPC.Common.EventLogging; using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Common.MachineSetup; +using Tango.PPC.Common.MachineUpdate; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; using Tango.PPC.Common.Notifications; @@ -55,6 +56,7 @@ namespace Tango.PPC.UI TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); @@ -70,6 +72,7 @@ namespace Tango.PPC.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); @@ -81,12 +84,14 @@ namespace Tango.PPC.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.GetInstance().ContentRendered += (_, __) => { TangoIOC.Default.Register(LayoutView.Instance); TangoIOC.Default.Register(MachineSetupView.Instance); + TangoIOC.Default.Register(MachineUpdateView.Instance); }; //TangoIOC.Default.Register(); @@ -145,5 +150,13 @@ namespace Tango.PPC.UI return TangoIOC.Default.GetInstance(); } } + + public static MachineUpdateViewVM MachineUpdateViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } } } \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs index 28692cdfa..fd36d0d13 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs @@ -84,6 +84,10 @@ namespace Tango.PPC.UI.ViewModels /// public RelayCommand SignOutCommand { get; set; } + /// + /// Gets or sets the update command. + /// + public RelayCommand UpdateCommand { get; set; } #endregion #region Constructors @@ -100,6 +104,11 @@ namespace Tango.PPC.UI.ViewModels StopPrintingCommand = new RelayCommand(StopPrinting); SignOutCommand = new RelayCommand(SignOut); + UpdateCommand = new RelayCommand(() => + { + NavigationManager.NavigateTo(NavigationView.MachineUpdateView); + TangoIOC.Default.GetInstance().CheckForUpdates(); + }); } #endregion diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs index 0f66b6fc8..f3cb83ffe 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Data.SqlClient; using System.Diagnostics; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -227,11 +228,11 @@ namespace Tango.PPC.UI.ViewModels /// private void CompleteSetup() { - String updater_exe = AssemblyHelper.GetCurrentAssemblyFolder() + "\\Tango.PPC.Updater.exe"; + String updater_exe = Path.Combine(_setup_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); LogManager.Log("Completing machine setup..."); - LogManager.Log($"Executing '{updater_exe}' with arguments '{_setup_result.UpdatePackagePath}'..."); - Process.Start(updater_exe, _setup_result.UpdatePackagePath); + LogManager.Log($"Executing '{updater_exe}' with arguments '{PathHelper.GetStartupPath()}'..."); + Process.Start(updater_exe, PathHelper.GetStartupPath()); LogManager.Log("Terminating application process!"); Environment.Exit(0); } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs new file mode 100644 index 000000000..84e65e516 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Core.Helpers; +using Tango.PPC.Common; +using Tango.PPC.Common.MachineUpdate; +using Tango.PPC.UI.ViewsContracts; + +namespace Tango.PPC.UI.ViewModels +{ + public class MachineUpdateViewVM : PPCViewModel + { + public enum MachineUpdateView + { + + UpdateCheckView, + UpdateCheckErrorView, + UpdateAvailableView, + UpToDateView, + UpdateProgressView, + UpdateCompletedView, + UpdateFailedView, + } + + private MachineUpdateResult _update_result; + + #region Properties + + /// + /// Gets or sets the machine update manager. + /// + public IMachineUpdateManager MachineUpdateManager { get; set; } + + private String _latestVersion; + /// + /// Gets or sets the latest version. + /// + public String LatestVersion + { + get { return _latestVersion; } + set { _latestVersion = value; RaisePropertyChangedAuto(); } + } + + #endregion + + #region Commands + + /// + /// Gets or sets the complete command. + /// + public RelayCommand CompleteCommand { get; set; } + + /// + /// Gets or sets the install command. + /// + public RelayCommand UpdateCommand { get; set; } + + /// + /// Gets or sets the restart command. + /// + public RelayCommand RestartCommand { get; set; } + + /// + /// Gets or sets the close command. + /// + public RelayCommand CloseCommand { get; set; } + + #endregion + + #region Constructors + + public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager) + { + MachineUpdateManager = machineUpdateManager; + + CompleteCommand = new RelayCommand(CompleteUpdate); + UpdateCommand = new RelayCommand(Update); + RestartCommand = new RelayCommand(CheckForUpdates); + CloseCommand = new RelayCommand(() => + { + NavigationManager.NavigateTo(Common.Navigation.NavigationView.HomeModule); + NavigateTo(MachineUpdateView.UpdateCheckView); + }); + } + + #endregion + + #region Update + + public async void CheckForUpdates() + { + await NavigateTo(MachineUpdateView.UpdateCheckView); + + try + { + var response = await MachineUpdateManager.CheckForUpdate(MachineProvider.Machine.SerialNumber, "http://localhost:51581/"); + + if (response.IsUpdateAvailable) + { + LatestVersion = response.Version; + await NavigateTo(MachineUpdateView.UpdateAvailableView); + } + else + { + await NavigateTo(MachineUpdateView.UpToDateView); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error while trying to check for updates."); + await NavigateTo(MachineUpdateView.UpdateFailedView); + } + } + + private async void Update() + { + await NavigateTo(MachineUpdateView.UpdateProgressView); + + LogManager.Log("Starting machine update..."); + + try + { + _update_result = await MachineUpdateManager.Update(MachineProvider.Machine.SerialNumber, "http://localhost:51581/"); + LogManager.Log("Machine update completed."); + await NavigateTo(MachineUpdateView.UpdateCompletedView); + } + catch (Exception ex) + { + LogManager.Log(ex, "Machine update failed."); + await NavigateTo(MachineUpdateView.UpdateFailedView); + } + } + + #endregion + + #region Complete + + private void CompleteUpdate() + { + String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); + + LogManager.Log("Completing machine setup..."); + LogManager.Log($"Executing '{updater_exe}' with arguments '{PathHelper.GetStartupPath()}'..."); + Process.Start(updater_exe, PathHelper.GetStartupPath()); + LogManager.Log("Terminating application process!"); + Environment.Exit(0); + } + + #endregion + + public override void OnApplicationStarted() + { + + } + + /// + /// Navigates to the specified view. + /// + /// The view. + private Task NavigateTo(MachineUpdateView view) + { + return View.NavigateTo(view); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml index 19f2caa59..2db5f12b6 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml @@ -60,6 +60,15 @@ + + + + + + Update + + +