From f00233f493b38f1a8eb9422f3c9ac4193f264486 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 20 May 2020 18:22:29 +0300 Subject: Fixed issue with machine virtual user when synchronizing jobs from PPC. --- .../Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 28acb3647..10af2f725 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -589,6 +589,7 @@ namespace Tango.MachineService.Controllers { var run = dto.ToObservable(); run.ID = 0; + run.UserGuid = machineUser.Guid; run.IsSynchronized = true; if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) -- cgit v1.3.1 From 7c7aba43ab895d02e0209861550fed3bc12f3904 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Tue, 28 Jul 2020 15:27:05 +0300 Subject: Implemented Tango FSE Publish Utils. Added FSE to AzureUtils on environment upgrade. --- .../Advanced Installer Projects/FSE Installer.aip | 515 ++++++++++++++++++++- .../Controls/WebAppPropertiesControl.xaml | 3 + .../Controls/WebAppPropertiesControl.xaml.cs | 9 + .../Azure/Tango.AzureUtils.UI/MainWindow.xaml | 2 +- .../Views/EnvironmentUpgradeView.xaml | 4 +- .../Tango.AzureUtils/Database/DatabaseManager.cs | 77 ++- .../Environment/EnvironmentManager.cs | 40 ++ .../Environment/EnvironmentSettings.cs | 2 + .../Environment/UpgradeEnvironmentConfiguration.cs | 2 + .../Tango.AzureUtils/MachineServiceSettings.cs | 1 + .../Tango.AzureUtils/Storage/StorageManager.cs | 65 ++- .../FSE/Tango.FSE.BL/Web/FSEWebClientBase.cs | 27 ++ .../FSE/Tango.FSE.Publisher.UI/App.config | 9 + .../FSE/Tango.FSE.Publisher.UI/App.xaml | 9 + .../FSE/Tango.FSE.Publisher.UI/App.xaml.cs | 17 + .../FSE/Tango.FSE.Publisher.UI/MainWindow.xaml | 66 +++ .../FSE/Tango.FSE.Publisher.UI/MainWindow.xaml.cs | 34 ++ .../FSE/Tango.FSE.Publisher.UI/MainWindowVM.cs | 316 +++++++++++++ .../Properties/AssemblyInfo.cs | 55 +++ .../Properties/Resources.Designer.cs | 71 +++ .../Properties/Resources.resx | 117 +++++ .../Properties/Settings.Designer.cs | 30 ++ .../Properties/Settings.settings | 7 + .../Tango.FSE.Publisher.UI/PublisherSettings.cs | 15 + .../Tango.FSE.Publisher.UI.csproj | 141 ++++++ .../FSE/Tango.FSE.UI/Properties/AssemblyInfo.cs | 2 +- .../Tango.FSE.Web/Messages/LatestVersionRequest.cs | 15 + .../Messages/LatestVersionResponse.cs | 15 + .../Messages/UploadCompletedRequest.cs | 15 + .../Messages/UploadCompletedResponse.cs | 14 + .../Tango.FSE.Web/Messages/UploadVersionRequest.cs | 19 + .../Messages/UploadVersionResponse.cs | 19 + .../FSE/Tango.FSE.Web/Tango.FSE.Web.csproj | 6 + Software/Visual_Studio/Tango.sln | 23 + .../Controllers/FSEController.cs | 104 +++++ .../Models/FSEPendingUpload.cs | 22 + .../Tango.MachineService.csproj | 3 +- 37 files changed, 1862 insertions(+), 29 deletions(-) create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.config create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.xaml.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindow.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindow.xaml.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindowVM.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Resources.Designer.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Resources.resx create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Settings.Designer.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Settings.settings create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/PublisherSettings.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Tango.FSE.Publisher.UI.csproj create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LatestVersionRequest.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LatestVersionResponse.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadCompletedRequest.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadCompletedResponse.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadVersionRequest.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadVersionResponse.cs create mode 100644 Software/Visual_Studio/Web/Tango.MachineService/Models/FSEPendingUpload.cs (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip b/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip index bd71ea0a1..eec051e8e 100644 --- a/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip +++ b/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip @@ -24,10 +24,10 @@ - + - + @@ -51,8 +51,21 @@ + + + + + + + + + + + + + @@ -84,10 +97,14 @@ + + + + @@ -100,19 +117,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -232,6 +379,7 @@ + @@ -272,6 +420,7 @@ + @@ -310,11 +459,13 @@ + + + + - - @@ -636,14 +787,109 @@ + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -651,21 +897,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -677,7 +1014,7 @@ - + @@ -764,8 +1101,6 @@ - - @@ -1069,8 +1404,146 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml index fe8b4bdef..aadfb7918 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml @@ -61,6 +61,9 @@ Tango Firmware Version:: + + Tango FSE Version: + diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs index ea7475fb1..8888dfc02 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs @@ -47,6 +47,14 @@ namespace Tango.AzureUtils.UI.Controls public static readonly DependencyProperty TangoVersionProperty = DependencyProperty.Register("TangoVersion", typeof(TangoVersion), typeof(WebAppPropertiesControl), new PropertyMetadata(null)); + public FseVersion FseVersion + { + get { return (FseVersion)GetValue(FseVersionProperty); } + set { SetValue(FseVersionProperty, value); } + } + public static readonly DependencyProperty FseVersionProperty = + DependencyProperty.Register("FseVersion", typeof(FseVersion), typeof(WebAppPropertiesControl), new PropertyMetadata(null)); + public MachineStudioVersion MachineStudioVersion { get { return (MachineStudioVersion)GetValue(MachineStudioVersionProperty); } @@ -88,6 +96,7 @@ namespace Tango.AzureUtils.UI.Controls var databaseManager = new DatabaseManager(azure); TangoVersion = await databaseManager.GetLatestPPCVersion(app); MachineStudioVersion = await databaseManager.GetLatestMachineStudioVersion(app); + FseVersion = await databaseManager.GetLatestFSEVersion(app); } catch { } finally diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/MainWindow.xaml b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/MainWindow.xaml index 7985f7985..6eaedea2a 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/MainWindow.xaml +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/MainWindow.xaml @@ -6,7 +6,7 @@ xmlns:views="clr-namespace:Tango.AzureUtils.UI.Views" xmlns:local="clr-namespace:Tango.AzureUtils.UI" mc:Ignorable="d" - Title="Azure Utils" Height="900" Width="1280"> + Title="Azure Utils" Height="920" Width="1280"> diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentUpgradeView.xaml b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentUpgradeView.xaml index b82be1e67..0bc763c35 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentUpgradeView.xaml +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Views/EnvironmentUpgradeView.xaml @@ -44,9 +44,11 @@ Upgrade Database Schema Upgrade Database Static Collections Upgrade Machine Studio Blob Storage - Upgrade PPC Blob Storage Upgrade Machine Studio Database Version + Upgrade PPC Blob Storage Upgrade PPC Database Version + Upgrade FSE Blob Storage + Upgrade FSE Database Version Upgrade Machine Service diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Database/DatabaseManager.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Database/DatabaseManager.cs index 75a7f321b..2a94e95b0 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Database/DatabaseManager.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Database/DatabaseManager.cs @@ -234,7 +234,7 @@ namespace Tango.AzureUtils.Database var targetDataSource = (await targetApp.GetMachineServiceSettingsAsync()).ToDataSource(); - OnProgress(AzureUtilsStage.Database, $"Adding machine studio database entry for version '{latestPPCVersion.Version}'..."); + OnProgress(AzureUtilsStage.Database, $"Adding PPC database entry for version '{latestPPCVersion.Version}'..."); using (var db = ObservablesContext.CreateDefault(targetDataSource)) { @@ -243,6 +243,21 @@ namespace Tango.AzureUtils.Database } } + public async Task UpgradeFSEVersion(IWebAppBase sourceApp, IWebAppBase targetApp) + { + var latestFSEVersion = await GetLatestFSEVersion(sourceApp); + + var targetDataSource = (await targetApp.GetMachineServiceSettingsAsync()).ToDataSource(); + + OnProgress(AzureUtilsStage.Database, $"Adding FSE database entry for version '{latestFSEVersion.Version}'..."); + + using (var db = ObservablesContext.CreateDefault(targetDataSource)) + { + db.FseVersions.Add(latestFSEVersion); + await db.SaveChangesAsync(); + } + } + public async Task DowngradeMachineStudioVersion(IWebAppBase app) { var latestMachineStudioVersion = await GetLatestMachineStudioVersion(app); @@ -327,8 +342,8 @@ namespace Tango.AzureUtils.Database using (var db = ObservablesContext.CreateDefault(dataSource)) { var versions = await db.TangoVersions.ToListAsync(); - var latest_machine_version = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); - return latest_machine_version; + var latest_version = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + return latest_version; } } catch (Exception ex) @@ -337,6 +352,38 @@ namespace Tango.AzureUtils.Database } } + public async Task GetLatestFSEVersion(IWebAppBase app) + { + OnProgress(AzureUtilsStage.Database, $"Getting latest FSE version on '{app.Name}'..."); + + MachineServiceSettings settings = null; + + try + { + settings = await app.GetMachineServiceSettingsAsync(); + } + catch (Exception ex) + { + throw new ArgumentException("Could not fetch machine service settings. Please check that all settings are available.", ex); + } + + try + { + DataSource dataSource = settings.ToDataSource(); + + using (var db = ObservablesContext.CreateDefault(dataSource)) + { + var versions = await db.FseVersions.ToListAsync(); + var latest_version = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + return latest_version; + } + } + catch (Exception ex) + { + throw new InvalidDataException($"Could not retrieve '{app.Name}' latest FSE version from database.", ex); + } + } + public async Task ValidateMachineStudioDatabaseUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp) { OnProgress(AzureUtilsStage.Validating, "Validating machine studio database upgrade..."); @@ -385,6 +432,30 @@ namespace Tango.AzureUtils.Database } } + public async Task ValidateFSEDatabaseUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp) + { + OnProgress(AzureUtilsStage.Validating, "Validating FSE database upgrade..."); + + var sourceSettings = await sourceApp.GetMachineServiceSettingsAsync(); + var targetSettings = await targetApp.GetMachineServiceSettingsAsync(); + + var latestSourceFSEVersion = await GetLatestFSEVersion(sourceApp); + + //Check if there is any source FSE version. + if (latestSourceFSEVersion == null) + { + throw new ValidationException("Could not locate a FSE version entry on the source database."); + } + + var latestTargetFSEVersion = await GetLatestFSEVersion(targetApp); + + //Check target latest FSE version is older if there is any. + if (latestTargetFSEVersion != null && Version.Parse(latestSourceFSEVersion.Version) <= Version.Parse(latestTargetFSEVersion.Version)) + { + throw new ValidationException($"FSE source version is '{latestSourceFSEVersion.Version}' while target version is '{latestTargetFSEVersion.Version}'."); + } + } + #endregion } } diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs index 19ccb8f92..123c94f7d 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentManager.cs @@ -327,6 +327,20 @@ namespace Tango.AzureUtils.Environment } } + //Add FSE storage versions. + if (config.CopyFSEStorageBlobs) + { + try + { + await _storageManager.ValidateFSEStorageUpgrade(sourceApp, targetApp); + await _storageManager.UpgradeFSEStorage(sourceApp, targetApp); + } + catch (Exception ex) + { + await RequestConfirmation($"Issues encountered with upgrading FSE storage versions.\n{ex.FlattenMessage()}\nDo you wish to continue?"); + } + } + //Upgrade machine studio database version. if (config.UpgradeMachineStudioDatabaseVersion) { @@ -355,6 +369,20 @@ namespace Tango.AzureUtils.Environment } } + //Upgrade FSE database version. + if (config.UpgradeFSEDatabaseVersion) + { + try + { + await _databaseManager.ValidateFSEDatabaseUpgrade(sourceApp, targetApp); + await _databaseManager.UpgradeFSEVersion(sourceApp, targetApp); + } + catch (Exception ex) + { + await RequestConfirmation($"Issues encountered with upgrading FSE database versions.\n{ex.FlattenMessage()}\nDo you wish to continue?"); + } + } + //Copy Website files. if (config.CopyMachineServiceFiles) @@ -388,6 +416,12 @@ namespace Tango.AzureUtils.Environment await _storageManager.ValidatePPCStorageUpgrade(sourceApp, targetApp); } + //Add FSE storage versions. + if (config.CopyFSEStorageBlobs) + { + await _storageManager.ValidateFSEStorageUpgrade(sourceApp, targetApp); + } + //Upgrade machine studio database version. if (config.UpgradeMachineStudioDatabaseVersion) { @@ -399,6 +433,12 @@ namespace Tango.AzureUtils.Environment { await _databaseManager.ValidatePPCDatabaseUpgrade(sourceApp, targetApp); } + + //Upgrade FSE database version. + if (config.UpgradeFSEDatabaseVersion) + { + await _databaseManager.ValidateFSEDatabaseUpgrade(sourceApp, targetApp); + } } #endregion diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentSettings.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentSettings.cs index 8b8e3a757..8eefc4bc5 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentSettings.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/EnvironmentSettings.cs @@ -12,6 +12,7 @@ namespace Tango.AzureUtils.Environment public String DB_CATALOG { get; set; } public String MACHINE_STUDIO_VERSIONS_CONTAINER { get; set; } public String TANGO_VERSIONS_CONTAINER { get; set; } + public String FSE_VERSIONS_CONTAINER { get; set; } public String MACHINE_SERVICE_BACKUPS_CONTAINER { get; set; } public String MACHINE_SERVICE_LOGS_CONTAINER { get; set; } public String ENVIRONMENT_GROUP { get; set; } @@ -24,6 +25,7 @@ namespace Tango.AzureUtils.Environment settings.DB_CATALOG = $"Tango_{name}"; settings.MACHINE_STUDIO_VERSIONS_CONTAINER = $"machine-studio-versions-{name.ToLower()}"; settings.TANGO_VERSIONS_CONTAINER = $"tango-versions-{name.ToLower()}"; + settings.FSE_VERSIONS_CONTAINER = $"fse-versions-{name.ToLower()}"; settings.MACHINE_SERVICE_BACKUPS_CONTAINER = $"machine-service-backups-{name.ToLower()}"; settings.MACHINE_SERVICE_LOGS_CONTAINER = $"machine-service-logs-{name.ToLower()}"; settings.ENVIRONMENT_GROUP = $"Tango {name}"; diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/UpgradeEnvironmentConfiguration.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/UpgradeEnvironmentConfiguration.cs index 537056701..1d7b9de16 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/UpgradeEnvironmentConfiguration.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Environment/UpgradeEnvironmentConfiguration.cs @@ -14,6 +14,8 @@ namespace Tango.AzureUtils.Environment public bool UpgradeMachineStudioDatabaseVersion { get; set; } = true; public bool CopyPPCStorageBlobs { get; set; } = true; public bool UpgradePPCDatabaseVersion { get; set; } = true; + public bool CopyFSEStorageBlobs { get; set; } = true; + public bool UpgradeFSEDatabaseVersion { get; set; } = true; public bool CopyMachineServiceFiles { get; set; } = true; } } diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/MachineServiceSettings.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/MachineServiceSettings.cs index 93065c50d..4f8742083 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/MachineServiceSettings.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/MachineServiceSettings.cs @@ -18,5 +18,6 @@ namespace Tango.AzureUtils public String MACHINE_STUDIO_VERSIONS_CONTAINER { get; set; } public String STORAGE_ACCOUNT { get; set; } public String TANGO_VERSIONS_CONTAINER { get; set; } + public String FSE_VERSIONS_CONTAINER { get; set; } } } diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils/Storage/StorageManager.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils/Storage/StorageManager.cs index 77a0aaf6d..db4403cc9 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils/Storage/StorageManager.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils/Storage/StorageManager.cs @@ -109,6 +109,39 @@ namespace Tango.AzureUtils.Storage }); } + public async Task UpgradeFSEStorage(IWebAppBase sourceApp, IWebAppBase targetApp) + { + OnProgress(AzureUtilsStage.Storage, $"Retrieving source and target settings..."); + + var sourceSettings = await sourceApp.GetMachineServiceSettingsAsync(); + var targetSettings = await targetApp.GetMachineServiceSettingsAsync(); + + var latestFSEVersion = await _databaseManager.GetLatestFSEVersion(sourceApp); + + OnProgress(AzureUtilsStage.Storage, $"Upgrading FSE version storage..."); + + var sourceAccount = CloudStorageAccount.Parse(sourceSettings.STORAGE_ACCOUNT); + var sourceClient = sourceAccount.CreateCloudBlobClient(); + + var targetAccount = CloudStorageAccount.Parse(targetSettings.STORAGE_ACCOUNT); + var targetClient = targetAccount.CreateCloudBlobClient(); + + var sourceFSEContainer = sourceClient.GetContainerReference(sourceSettings.FSE_VERSIONS_CONTAINER); + var targetFSEContainer = targetClient.GetContainerReference(targetSettings.FSE_VERSIONS_CONTAINER); + + //var sourceFSEBlob = sourceFSEContainer.GetBlockBlobReference(latestPPCVersion.BlobName); + var sourceFSEInstallerBlob = sourceFSEContainer.GetBlockBlobReference(latestFSEVersion.InstallerBlobName); + + //var targetFSEBlob = await CreateEmptyBlob(targetFSEContainer, sourceFSEBlob.Name); + var targetFSEInstallerBlob = await CreateEmptyBlob(targetFSEContainer, sourceFSEInstallerBlob.Name); + + await Task.Factory.StartNew(() => + { + //targetFSEBlob.StartCopy(sourceFSEBlob); + targetFSEInstallerBlob.StartCopy(sourceFSEInstallerBlob); + }); + } + public async Task UpgradeMachineStudioStorage(IWebAppBase sourceApp, IWebAppBase targetApp) { OnProgress(AzureUtilsStage.Storage, $"Retrieving source and target settings..."); @@ -170,7 +203,7 @@ namespace Tango.AzureUtils.Storage public async Task ValidatePPCStorageUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp) { - OnProgress(AzureUtilsStage.Validating, "Validating PPC database upgrade..."); + OnProgress(AzureUtilsStage.Validating, "Validating PPC storage upgrade..."); var sourceSettings = await sourceApp.GetMachineServiceSettingsAsync(); var targetSettings = await targetApp.GetMachineServiceSettingsAsync(); @@ -198,6 +231,36 @@ namespace Tango.AzureUtils.Storage } } + public async Task ValidateFSEStorageUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp) + { + OnProgress(AzureUtilsStage.Validating, "Validating FSE storage upgrade..."); + + var sourceSettings = await sourceApp.GetMachineServiceSettingsAsync(); + var targetSettings = await targetApp.GetMachineServiceSettingsAsync(); + + var latestSourceFSEVersion = await _databaseManager.GetLatestFSEVersion(sourceApp); + var latestTargetFSEVersion = await _databaseManager.GetLatestFSEVersion(targetApp); + + var targetAccount = CloudStorageAccount.Parse(targetSettings.STORAGE_ACCOUNT); + var targetClient = targetAccount.CreateCloudBlobClient(); + + var targetFSEContainer = targetClient.GetContainerReference(targetSettings.FSE_VERSIONS_CONTAINER); + + //Check FSE binaries blob not exists on the target. + var targetFSEBlob = targetFSEContainer.GetBlockBlobReference(latestSourceFSEVersion.BlobName); + if (await targetFSEBlob.ExistsAsync()) + { + throw new ValidationException($"FSE Block blob '{latestSourceFSEVersion.BlobName}' already exists on the target storage."); + } + + //Check FSE installer blob not exists on the target. + var targetFSEInstallerBlob = targetFSEContainer.GetBlockBlobReference(latestSourceFSEVersion.InstallerBlobName); + if (await targetFSEInstallerBlob.ExistsAsync()) + { + throw new ValidationException($"FSE Block blob '{latestSourceFSEVersion.InstallerBlobName}' already exists on the target storage."); + } + } + public async Task ValidateMachineStudioStorageUpgrade(IWebAppBase sourceApp, IWebAppBase targetApp) { OnProgress(AzureUtilsStage.Validating, "Validating machine studio storage upgrade..."); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Web/FSEWebClientBase.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/Web/FSEWebClientBase.cs index 68420ea67..2151f03d1 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/Web/FSEWebClientBase.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Web/FSEWebClientBase.cs @@ -93,5 +93,32 @@ namespace Tango.FSE.BL.Web return Post("SendForgotPasswordEmail", request); } + /// + /// Executes the GetLatestVersion action and returns Tango.FSE.Web.Messages.LatestVersionResponse. + /// + /// + public Task GetLatestVersion(Tango.FSE.Web.Messages.LatestVersionRequest request) + { + return Post("GetLatestVersion", request); + } + + /// + /// Executes the UploadVersion action and returns Tango.FSE.Web.Messages.UploadVersionResponse. + /// + /// + public Task UploadVersion(Tango.FSE.Web.Messages.UploadVersionRequest request) + { + return Post("UploadVersion", request); + } + + /// + /// Executes the NotifyVersionUploadCompleted action and returns Tango.FSE.Web.Messages.UploadCompletedResponse. + /// + /// + public Task NotifyVersionUploadCompleted(Tango.FSE.Web.Messages.UploadCompletedRequest request) + { + return Post("NotifyVersionUploadCompleted", request); + } + } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.config b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.config new file mode 100644 index 000000000..3c53533de --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.xaml new file mode 100644 index 000000000..ccf0edb6b --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.xaml.cs new file mode 100644 index 000000000..3a9bfe8d8 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace Tango.FSE.Publisher.UI +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindow.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindow.xaml new file mode 100644 index 000000000..143113bf1 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindow.xaml @@ -0,0 +1,66 @@ + + + + + + + + Tango FSE Publish Utility + + + + + + + + + Environment: + + + + + Build Configuration: + + Release + Debug + + + + + Remote Version: + + + + + Local Version: + + + + Comments + + + Email + + + Password + + + + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindow.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindow.xaml.cs new file mode 100644 index 000000000..7a4ddc19f --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindow.xaml.cs @@ -0,0 +1,34 @@ +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.FSE.Publisher.UI +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + var vm = new MainWindowVM(); + DataContext = vm; + ContentRendered += (_, __) => + { + vm.Init(); + }; + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindowVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindowVM.cs new file mode 100644 index 000000000..148ee37f6 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/MainWindowVM.cs @@ -0,0 +1,316 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Tango.AdvancedInstaller; +using Tango.Core; +using Tango.Core.Commands; +using Tango.FSE.BL.Web; +using Tango.FSE.Web.Messages; +using Tango.MachineService.Gateway; +using Tango.Settings; +using Tango.SharedUI; +using Tango.Transport.Web; + +namespace Tango.FSE.Publisher.UI +{ + public class MainWindowVM : ViewModel + { + private FSEWebClient _client; + private String _buildFolder; + private const String APP_EXE_NAME = "Tango.FSE.UI.exe"; + + private List _environments; + public List Environments + { + get { return _environments; } + set { _environments = value; RaisePropertyChangedAuto(); } + } + + private EnvironmentConfiguration _selectedEnvironment; + public EnvironmentConfiguration SelectedEnvironment + { + get { return _selectedEnvironment; } + set { _selectedEnvironment = value; RaisePropertyChangedAuto(); OnSelectedEnvironmentChanged(); InvalidateRelayCommands(); } + } + + private String _localVersion; + public String LocalVersion + { + get { return _localVersion; } + set { _localVersion = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _remoteVersion; + public String RemoteVersion + { + get { return _remoteVersion; } + set { _remoteVersion = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _buidConfig; + public String BuildConfig + { + get { return _buidConfig; } + set { _buidConfig = value; RaisePropertyChangedAuto(); OnBuildConfigChanged(); InvalidateRelayCommands(); } + } + + private String _email; + public String Email + { + get { return _email; } + set { _email = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _password; + public String Password + { + get { return _password; } + set { _password = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _comments; + public String Comments + { + get { return _comments; } + set { _comments = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private TangoProgress _progress; + public TangoProgress Progress + { + get { return _progress; } + set { _progress = value; RaisePropertyChangedAuto(); } + } + + + public RelayCommand PublishCommand { get; set; } + + public MainWindowVM() + { + PublishCommand = new RelayCommand(Publish, CanPublish); + + var settings = SettingsManager.Default.GetOrCreate(); + Email = settings.Email; + Password = settings.Password; + } + + private bool CanPublish() + { + try + { + return + SelectedEnvironment != null && + Email.IsNotNullOrEmpty() && + Password.IsNotNullOrEmpty() && + Comments.IsNotNullOrEmpty() && + System.Version.Parse(LocalVersion) > System.Version.Parse(RemoteVersion) && + IsFree; + } + catch (Exception ex) + { + Debug.WriteLine(ex); + return false; + } + } + + public async void Init() + { + try + { + IsFree = false; + UpdateProgress("Retrieving environments..."); + using (HttpClient http = new HttpClient()) + { + GatewayClient client = new GatewayClient(ConfigurationManager.AppSettings.Get("GatewayUrl"), http); + Environments = (await client.GetEnvironmentsAsync(new EnvironmentsRequest())).Environments.OrderBy(x => x.DisplayIndex).ToList(); + } + + SelectedEnvironment = Environments.SingleOrDefault(x => x.Name == "TEST"); + + BuildConfig = "Release"; + + ProgressReady(); + } + catch (Exception ex) + { + ShowError($"Error retrieving environments from gateway service.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private void OnBuildConfigChanged() + { + UpdateProgress("Searching build path..."); + + String path = Path.GetFullPath($@"../../../../Build\FSE\{BuildConfig}"); + if (!Directory.Exists(path)) + { + ShowError($"Could not locate FSE build folder at '{path}'."); + } + + _buildFolder = path; + + try + { + String appExe = Path.Combine(path, APP_EXE_NAME); + LocalVersion = FileVersionInfo.GetVersionInfo(appExe).ProductVersion; + ProgressReady(); + } + catch (Exception ex) + { + ShowError($"Could not determine the local application version.\n{ex.FlattenMessage()}"); + } + } + + private async Task OnSelectedEnvironmentChanged() + { + if (SelectedEnvironment != null) + { + try + { + IsFree = false; + UpdateProgress("Getting remote version..."); + _client = new FSEWebClient(SelectedEnvironment.MachineServiceAddress); + RemoteVersion = (await _client.GetLatestVersion(new Web.Messages.LatestVersionRequest())).Version; + ProgressReady(); + } + catch (Exception ex) + { + ShowError($"Error retrieving the remote version.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + } + + private async void Publish() + { + try + { + IsFree = false; + UpdateProgress("Publishing Tango FSE..."); + + var settings = SettingsManager.Default.GetOrCreate(); + settings.Email = Email; + settings.Password = Password; + settings.Save(); + + UpdateProgress("Validating Tango FSE installer...."); + + String projectPath = Path.GetFullPath(@"../../../../Advanced Installer Projects\FSE Installer.aip"); + + if (!File.Exists(projectPath)) + { + throw new FileNotFoundException($"Could not locate advanced installer project at '{projectPath}'."); + } + + String installerName = $"Tango FSE v{System.Version.Parse(LocalVersion).ToString(3)}.exe"; + String installerPath = Path.GetFullPath($@"../../../../Build\Installers\FSE\Release\{installerName}"); + + if (!Directory.Exists(Path.GetDirectoryName(installerPath))) + { + throw new DirectoryNotFoundException($"Could not locate installer output directory '{Path.GetDirectoryName(installerPath)}'."); + } + + UpdateProgress("Authenticating with machine service..."); + await _client.Login(new LoginRequest() + { + Email = Email, + Password = Password, + Version = LocalVersion + }); + + UpdateProgress("Requesting version upload..."); + var uploadResponse = await _client.UploadVersion(new UploadVersionRequest() + { + Comments = Comments, + InstallerBlobName = installerName, + Version = LocalVersion + }); + + UpdateProgress("Building Tango FSE installer..."); + + InstallerBuilder builder = new InstallerBuilder(projectPath); + await builder.Build(LocalVersion, installerPath); + + if (!File.Exists(installerPath)) + { + throw new FileNotFoundException($"Installer build was successful but the output installer could not be located at the specified path '{installerPath}'."); + } + + UpdateProgress("Uploading Tango FSE installer..."); + + using (StorageBlobUploader uploader = new StorageBlobUploader(uploadResponse.InstallerBlobAddress, installerPath)) + { + uploader.Progress += (x, e) => + { + UpdateProgress("Uploading Tango FSE installer...", false, e.Current, e.Total); + }; + + await uploader.Upload(); + } + + UpdateProgress("Finalizing version publishing..."); + + await _client.NotifyVersionUploadCompleted(new UploadCompletedRequest() + { + Token = uploadResponse.Token + }); + + UpdateProgress("Validating..."); + await OnSelectedEnvironmentChanged(); + + if (LocalVersion != RemoteVersion) + { + throw new InvalidDataException("Publishing completed but the local and remote versions are different?!"); + } + + Process.Start(SelectedEnvironment.MachineServiceAddress + "/fse"); + + UpdateProgress("Version published successfully!", false, 100, 100); + ShowInfo("Tango FSE published successfully!"); + } + catch (Exception ex) + { + ShowError($"Error while trying to publish Tango FSE\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private void ShowError(String error) + { + UpdateProgress("Error!", false, 0, 100); + MessageBox.Show(error, "FSE Publisher", MessageBoxButton.OK, MessageBoxImage.Error); + } + + private void ShowInfo(String message) + { + MessageBox.Show(message, "FSE Publisher", MessageBoxButton.OK, MessageBoxImage.Information); + } + + private void UpdateProgress(String message, bool isIndeterminate = true, double value = 0, double max = 100) + { + Progress = new TangoProgress(message, isIndeterminate, value, max); + } + + private void ProgressReady() + { + UpdateProgress("Ready", false, 0, 100); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..970139e8e --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +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.FSE.Publisher.UI")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tango.FSE.Publisher.UI")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Resources.Designer.cs b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Resources.Designer.cs new file mode 100644 index 000000000..48dfa2514 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Tango.FSE.Publisher.UI.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tango.FSE.Publisher.UI.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Resources.resx b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Settings.Designer.cs b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Settings.Designer.cs new file mode 100644 index 000000000..05f0c70e0 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Tango.FSE.Publisher.UI.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Settings.settings b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/PublisherSettings.cs b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/PublisherSettings.cs new file mode 100644 index 000000000..f2fd98b9c --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/PublisherSettings.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Settings; + +namespace Tango.FSE.Publisher.UI +{ + public class PublisherSettings : SettingsBase + { + public String Email { get; set; } + public String Password { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Tango.FSE.Publisher.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Tango.FSE.Publisher.UI.csproj new file mode 100644 index 000000000..26a0ee007 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Publisher.UI/Tango.FSE.Publisher.UI.csproj @@ -0,0 +1,141 @@ + + + + + Debug + AnyCPU + {4C045668-9E5A-447A-A3B8-106C872C1039} + WinExe + Tango.FSE.Publisher.UI + Tango.FSE.Publisher.UI + v4.6.1 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + MainWindow.xaml + Code + + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + {c5df1816-34e5-4700-824c-29623a1baa22} + Tango.AdvancedInstaller + + + {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} + Tango.Core + + + {d8f1ad85-526a-4f50-b6dc-d437af63d8d8} + Tango.Settings + + + {8491d07b-c1f6-4b62-a412-41b9fd2d6538} + Tango.SharedUI + + + {74e700b0-1156-4126-be40-ee450d3c3026} + Tango.Transport + + + {5001990f-977b-48ff-b217-0236a5022ad8} + Tango.Web + + + {834c81c3-09b5-45d7-be12-e7d1e6655a7c} + Tango.FSE.BL + + + {bc37cccb-7392-4f78-8d1c-e9629e6e046e} + Tango.FSE.Common + + + {d6f7d31d-7f8c-45e2-ae0a-fbbd1f5f9d5f} + Tango.FSE.Web + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/AssemblyInfo.cs index 9121fb2f1..4a0bc1496 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Properties/AssemblyInfo.cs @@ -8,5 +8,5 @@ using System.Windows; // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Tango FSE")] -[assembly: AssemblyVersion("1.0.2.0")] +[assembly: AssemblyVersion("1.0.3.0")] diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LatestVersionRequest.cs b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LatestVersionRequest.cs new file mode 100644 index 000000000..8f6117241 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LatestVersionRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using Tango.Transport.Web; + +namespace Tango.FSE.Web.Messages +{ + public class LatestVersionRequest : WebRequestMessage + { + + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LatestVersionResponse.cs b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LatestVersionResponse.cs new file mode 100644 index 000000000..3b239567c --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/LatestVersionResponse.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using Tango.Transport.Web; + +namespace Tango.FSE.Web.Messages +{ + public class LatestVersionResponse : WebResponseMessage + { + public String Version { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadCompletedRequest.cs b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadCompletedRequest.cs new file mode 100644 index 000000000..a82ac0083 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadCompletedRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using Tango.Transport.Web; + +namespace Tango.FSE.Web.Messages +{ + public class UploadCompletedRequest : WebRequestMessage + { + public String Token { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadCompletedResponse.cs b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadCompletedResponse.cs new file mode 100644 index 000000000..065ccc3ce --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadCompletedResponse.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.FSE.Web.Messages +{ + public class UploadCompletedResponse : WebResponseMessage + { + + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadVersionRequest.cs b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadVersionRequest.cs new file mode 100644 index 000000000..01968d249 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadVersionRequest.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using Tango.Transport.Web; + +namespace Tango.FSE.Web.Messages +{ + public class UploadVersionRequest : WebRequestMessage + { + public String Version { get; set; } + + public String Comments { get; set; } + + public String InstallerBlobName { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadVersionResponse.cs b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadVersionResponse.cs new file mode 100644 index 000000000..1ea801b63 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Messages/UploadVersionResponse.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using Tango.Transport.Web; + +namespace Tango.FSE.Web.Messages +{ + public class UploadVersionResponse : WebResponseMessage + { + public String Token { get; set; } + + public String BlobAddress { get; set; } + + public String InstallerBlobAddress { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Web/Tango.FSE.Web.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Web/Tango.FSE.Web.csproj index 4c9f769c4..7c6e70919 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Web/Tango.FSE.Web.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.Web/Tango.FSE.Web.csproj @@ -49,10 +49,16 @@ + + + + + + diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln index 51788b0d2..c28ad8850 100644 --- a/Software/Visual_Studio/Tango.sln +++ b/Software/Visual_Studio/Tango.sln @@ -401,6 +401,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.ColorLib.GradientTest EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.FSE.Procedures", "FSE\Modules\Tango.FSE.Procedures\Tango.FSE.Procedures.csproj", "{1754F846-4763-4000-807F-C7BFAA145DB2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.FSE.Publisher.UI", "FSE\Tango.FSE.Publisher.UI\Tango.FSE.Publisher.UI.csproj", "{4C045668-9E5A-447A-A3B8-106C872C1039}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -3748,6 +3750,26 @@ Global {1754F846-4763-4000-807F-C7BFAA145DB2}.Release|x64.Build.0 = Release|Any CPU {1754F846-4763-4000-807F-C7BFAA145DB2}.Release|x86.ActiveCfg = Release|Any CPU {1754F846-4763-4000-807F-C7BFAA145DB2}.Release|x86.Build.0 = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|ARM.ActiveCfg = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|ARM.Build.0 = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|ARM64.Build.0 = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|x64.ActiveCfg = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|x64.Build.0 = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|x86.ActiveCfg = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Debug|x86.Build.0 = Debug|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|Any CPU.Build.0 = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|ARM.ActiveCfg = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|ARM.Build.0 = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|ARM64.ActiveCfg = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|ARM64.Build.0 = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|x64.ActiveCfg = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|x64.Build.0 = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|x86.ActiveCfg = Release|Any CPU + {4C045668-9E5A-447A-A3B8-106C872C1039}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -3884,6 +3906,7 @@ Global {8336A702-9C49-4C9E-ADCC-1886A666D3BD} = {7181F9DE-0760-46B7-AD8F-BDBCAEDEF1B7} {982C6FAC-2864-484E-82AE-5A36658C4DB1} = {8336A702-9C49-4C9E-ADCC-1886A666D3BD} {1754F846-4763-4000-807F-C7BFAA145DB2} = {4EE6DBA1-71BC-49E2-8DC7-266487E61050} + {4C045668-9E5A-447A-A3B8-106C872C1039} = {004337EB-0761-4D30-B9F5-AE6E1CFC6013} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution BuildVersion_UseGlobalSettings = False diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs index e471ed20c..387430f89 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs @@ -25,11 +25,15 @@ using Tango.Web.SQLServer; using Tango.Web.Storage; using System.Data.Entity; using static Tango.MachineService.Controllers.FSEController; +using Tango.MachineService.Models; +using Tango.BL.Enumerations; namespace Tango.MachineService.Controllers { public class FSEController : TangoController { + private static List _pendingUploads; + public class TokenObject { public String UserGuid { get; set; } @@ -46,6 +50,7 @@ namespace Tango.MachineService.Controllers static FSEController() { + _pendingUploads = new List(); PendingPasswordResets = new List(); } @@ -323,5 +328,104 @@ namespace Tango.MachineService.Controllers return new ForgotPasswordResponse(); } + + #region Version Upload + + [HttpPost] + public LatestVersionResponse GetLatestVersion(LatestVersionRequest request) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + var version = db.FseVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + return new LatestVersionResponse() { Version = version != null ? version.Version : "0.0.0.0" }; + } + } + + [HttpPost] + [JwtTokenFilter] + public UploadVersionResponse UploadVersion(UploadVersionRequest request) + { + UploadVersionResponse response = new UploadVersionResponse(); + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + String userID = RequestToken.Object.UserGuid; + + var user = new UserBuilder(db).Set(userID).WithRolesAndPermissions().Build(); + + if (user != null && user.HasPermission(Permissions.PublishMachineStudioVersions)) + +{ + var latestVersion = db.FseVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + Version local_version = Version.Parse(request.Version); + + if (latestVersion == null || local_version > Version.Parse(latestVersion.Version)) + { + var manager = new BlobStorageManager(); + var container = manager.GetContainer(MachineServiceConfig.FSE_VERSIONS_CONTAINER); + var installerBlob = container.CreateEmptyBlob(request.InstallerBlobName); + + response.Token = Guid.NewGuid().ToString(); + response.InstallerBlobAddress = installerBlob.GenerateWriteSignature(TimeSpan.FromMinutes(30)); + + FSEPendingUpload pending_upload = new FSEPendingUpload() + { + UserGuid = user.Guid, + Comments = request.Comments, + Token = response.Token, + Version = request.Version, + BlobName = "BLOB", + InstallerBlobName = installerBlob.Name + }; + + _pendingUploads.Add(pending_upload); + } + else + { + throw new ArgumentException("New version must be greater than latest version."); + } + } + else + { + throw new AuthenticationException("Invalid user credentials."); + } + } + + return response; + } + + [HttpPost] + [JwtTokenFilter] + public UploadCompletedResponse NotifyVersionUploadCompleted(UploadCompletedRequest request) + { + FSEPendingUpload upload = _pendingUploads.FirstOrDefault(x => x.Token == request.Token); + + if (upload != null) + { + _pendingUploads.RemoveAll(x => x.Token == upload.Token); + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + db.FseVersions.Add(new FseVersion() + { + Comments = upload.Comments, + BlobName = upload.BlobName, + InstallerBlobName = upload.InstallerBlobName, + UserGuid = upload.UserGuid, + Version = upload.Version, + }); + + db.SaveChanges(); + } + + return new UploadCompletedResponse(); + } + else + { + throw new ArgumentException("Invalid Token."); + } + } + + #endregion } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Models/FSEPendingUpload.cs b/Software/Visual_Studio/Web/Tango.MachineService/Models/FSEPendingUpload.cs new file mode 100644 index 000000000..7bb74d045 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Models/FSEPendingUpload.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Tango.MachineService.Models +{ + public class FSEPendingUpload + { + public String Token { get; set; } + + public String Version { get; set; } + + public String UserGuid { get; set; } + + public String Comments { get; set; } + + public String BlobName { get; set; } + + public String InstallerBlobName { get; set; } + } +} \ 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 9b25a25a8..c662b1e87 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj +++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj @@ -327,6 +327,7 @@ + @@ -489,7 +490,7 @@ False - + -- cgit v1.3.1 From 03bc9bd370929884f98ee9488146646d44911efd Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 5 Aug 2020 22:18:14 +0300 Subject: Improved PPC Publisher for Firmware version display and validation. --- .../PPC/Tango.PPC.Common/Publish/PPCPublisher.cs | 32 ++++++++++++++++------ .../PPC/Tango.PPC.Common/Publish/PublishOptions.cs | 3 +- .../Tango.PPC.Common/Web/LatestVersionResponse.cs | 1 + .../PPC/Tango.PPC.Publisher.UI/MainWindow.xaml | 10 ++++--- .../PPC/Tango.PPC.Publisher.UI/MainWindowVM.cs | 26 +++++++++++++++++- .../Controllers/PPCController.cs | 5 +++- .../Properties/AssemblyInfo.cs | 2 +- 7 files changed, 63 insertions(+), 16 deletions(-) (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PPCPublisher.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PPCPublisher.cs index 2fc2ca507..a28cc747a 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PPCPublisher.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PPCPublisher.cs @@ -59,14 +59,11 @@ namespace Tango.PPC.Common.Publish /// Gets the latest version. /// /// - public async Task GetRemoteVersion(String machineVersionGuid) + public async Task GetRemoteVersion(String machineVersionGuid) { _client.Environment = Options.Environment; - var response = await _client.GetLatestVersion(new LatestVersionRequest() - { - MachineVersionGuid = machineVersionGuid, - }); - return response.Version; + var response = await _client.GetLatestVersion(new LatestVersionRequest() { MachineVersionGuid = machineVersionGuid } ); + return response; } /// @@ -163,8 +160,12 @@ namespace Tango.PPC.Common.Publish OnPublishProgress(0, 100, $"Fetching remote version from {Options.Environment.ToAddress()}..."); - String remote_version = GetRemoteVersion(Options.MachineVersionGuid).Result; + var r = GetRemoteVersion(Options.MachineVersionGuid).Result; + String remote_version = r.Version; + String remote_firmware_version = r.FirmwareVersion; + String local_version = GetLocalVersion(); + String local_firmware_version = GetLocalFirmwareVersion(Options.TfpPath); OnPublishProgress(0, 100, $"Remote version: {remote_version}"); OnPublishProgress(0, 100, $"Local version: {local_version}"); @@ -174,6 +175,11 @@ namespace Tango.PPC.Common.Publish throw new InvalidOperationException($"The local version '{local_version}' is not greater than the remote version '{remote_version}'."); } + if (Version.Parse(local_firmware_version) <= Version.Parse(remote_firmware_version)) + { + throw new InvalidOperationException($"The local firmware version '{local_firmware_version}' is not greater than the remote version '{remote_firmware_version}'."); + } + OnPublishProgress(0, 100, $"Requesting version upload..."); var response = _client.UploadVersion(new UploadVersionRequest() @@ -233,7 +239,7 @@ namespace Tango.PPC.Common.Publish Token = response.Token, }).Wait(); - remote_version = GetRemoteVersion(Options.MachineVersionGuid).Result; + remote_version = GetRemoteVersion(Options.MachineVersionGuid).Result.Version; local_version = GetLocalVersion(); OnPublishProgress(0, 0, $"Remote version: {remote_version}"); @@ -412,6 +418,16 @@ namespace Tango.PPC.Common.Publish } } + /// + /// Gets the MCU version from the specified TFP file. + /// + /// The TFP file. + /// + public String GetLocalFirmwareVersion(String tfpFile) + { + return GetVersionInfoFromTFP(tfpFile).GetMcuVersion().ToString(); + } + /// /// Raises the publish progress event. /// diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishOptions.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishOptions.cs index 4c40acb44..9b8613cfb 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishOptions.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishOptions.cs @@ -17,6 +17,7 @@ namespace Tango.PPC.Common.Publish public event EventHandler BuidConfigChanged; public event EventHandler BasicInfoChanged; public event EventHandler MachineVersionGuidChanged; + public event EventHandler TfpPathChanged; private String basePath; [Option("path", HelpText = "Specifies the application base path.", Required = false)] @@ -79,7 +80,7 @@ namespace Tango.PPC.Common.Publish public String TfpPath { get { return _tfpPath; } - set { _tfpPath = value; RaisePropertyChangedAuto(); } + set { _tfpPath = value; RaisePropertyChangedAuto(); TfpPathChanged?.Invoke(this, new EventArgs()); } } private String _installerProject; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LatestVersionResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LatestVersionResponse.cs index d2ed08f7d..eb5ef7f5a 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LatestVersionResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LatestVersionResponse.cs @@ -11,5 +11,6 @@ namespace Tango.PPC.Common.Web public class LatestVersionResponse : WebResponseMessage { public String Version { get; set; } + public String FirmwareVersion { get; set; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Publisher.UI/MainWindow.xaml b/Software/Visual_Studio/PPC/Tango.PPC.Publisher.UI/MainWindow.xaml index f74194222..1d60a70be 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Publisher.UI/MainWindow.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.Publisher.UI/MainWindow.xaml @@ -67,15 +67,17 @@ - Remote Version: - + Remote Versions: + , + - Local Version: - + Local Versions: + , + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Publisher.UI/MainWindowVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.Publisher.UI/MainWindowVM.cs index 98b35ed3f..d935c44d2 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Publisher.UI/MainWindowVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Publisher.UI/MainWindowVM.cs @@ -67,6 +67,13 @@ namespace Tango.PPC.Publisher.UI set { _localVersion = value; RaisePropertyChangedAuto(); } } + private String _localFirmwareVersion; + public String LocalFirmwareVersion + { + get { return _localFirmwareVersion; } + set { _localFirmwareVersion = value; RaisePropertyChangedAuto(); } + } + private String _remoteVersion; public String RemoteVersion { @@ -74,6 +81,13 @@ namespace Tango.PPC.Publisher.UI set { _remoteVersion = value; RaisePropertyChangedAuto(); } } + private String _remoteFirmwareVersion; + public String RemoteFirmwareVersion + { + get { return _remoteFirmwareVersion; } + set { _remoteFirmwareVersion = value; RaisePropertyChangedAuto(); } + } + private ICollectionView _provisionSequenceItemsView; public ICollectionView ProvisionSequenceItemsView { @@ -127,6 +141,7 @@ namespace Tango.PPC.Publisher.UI Options.BasicInfoChanged += (_, __) => InvalidateRelayCommands(); Options.EnvironmentChanged += async (_, __) => await OnEnvironmentChanged(); Options.BuidConfigChanged += async (_, __) => await UpdateVersions(); + Options.TfpPathChanged += async (_, __) => await UpdateVersions(); Init(); } @@ -165,9 +180,18 @@ namespace Tango.PPC.Publisher.UI { IsFree = false; LocalVersion = _publisher.GetLocalVersion(); + + try + { + LocalFirmwareVersion = _publisher.GetLocalFirmwareVersion(Options.TfpPath); + } + catch {} + if (SelectedMachineVersion != null) { - RemoteVersion = await _publisher.GetRemoteVersion(SelectedMachineVersion.Guid); + var latestVersion = await _publisher.GetRemoteVersion(SelectedMachineVersion.Guid); + RemoteVersion = latestVersion.Version; + RemoteFirmwareVersion = latestVersion.FirmwareVersion; } InvalidateRelayCommands(); IsFree = true; diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 10af2f725..22feb29c1 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -788,10 +788,13 @@ namespace Tango.MachineService.Controllers return new LatestVersionResponse() { Version = "0.0.0.0", + FirmwareVersion = "0.0.0.0" }; } - response.Version = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault().Version; + var latestTangoVersion = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + response.Version = latestTangoVersion.Version; + response.FirmwareVersion = latestTangoVersion.FirmwareVersion; } return response; diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs index 386a7c4b8..a6aa93dee 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.0.0")] +[assembly: AssemblyVersion("3.0.1.0")] -- cgit v1.3.1 From f809df07060dc3a27167f68027eb03bdbc89221a Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sat, 15 Aug 2020 19:13:10 +0300 Subject: File Associations DDE!! --- .../FSE/File Associations/procedure_dde.ico | Bin 0 -> 107997 bytes .../FSE/File Associations/procedure_dde.png | Bin 0 -> 6350 bytes .../Graphics/FSE/File Associations/tdp_dde.ico | Bin 0 -> 109508 bytes .../Graphics/FSE/File Associations/tdp_dde.png | Bin 0 -> 7337 bytes .../Graphics/FSE/File Associations/tfp_dde.ico | Bin 0 -> 105372 bytes .../Graphics/FSE/File Associations/tfp_dde.png | Bin 0 -> 4111 bytes .../Graphics/FSE/File Associations/tup_dde.ico | Bin 0 -> 106375 bytes .../Graphics/FSE/File Associations/tup_dde.png | Bin 0 -> 5048 bytes .../Advanced Installer Projects/FSE Installer.aip | 20 ++- .../ViewModels/DiagnosticsViewVM.cs | 35 ++++++ .../Help/proc-doc.chm | Bin 206257 -> 212099 bytes .../Tango.FSE.Procedures.Documentation.shfbproj | 1 + .../Navigation/RunProcedureNavigationObject.cs | 1 + .../ViewModels/ProcedureDesignerViewVM.cs | 39 +++++- .../ViewModels/ProcedureRunnerViewVM.cs | 60 ++++++--- .../ViewModels/FirmwareUpgradeGeneratedViewVM.cs | 40 +++++- .../Views/FirmwareUpgradeView.xaml | 2 +- .../FSEApplication/IFSEApplicationManager.cs | 5 + .../FSE/Tango.FSE.Common/FSESettings.cs | 6 + .../FSE/Tango.FSE.Common/FSEViewModel.cs | 7 ++ .../FileAssociation/FileAssociationPackage.cs | 1 + .../FileAssociation/IFileAssociationProvider.cs | 3 +- .../Navigation/INavigationManager.cs | 5 +- .../Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs | 46 +++++-- .../FSEApplication/DefaultFSEApplicationManager.cs | 11 ++ .../DefaultFileAssociationHandler.cs | 24 ---- .../DefaultFileAssociationProvider.cs | 136 +++++++++++++++++++++ .../Navigation/DefaultNavigationManager.cs | 10 +- .../FSE/Tango.FSE.UI/Tango.FSE.UI.csproj | 5 +- .../FSE/Tango.FSE.UI/ViewModelLocator.cs | 4 + .../FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs | 8 ++ .../Visual_Studio/FSE/Tango.FSE.UI/packages.config | 1 + .../Controllers/FSEController.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- 34 files changed, 406 insertions(+), 68 deletions(-) create mode 100644 Software/Graphics/FSE/File Associations/procedure_dde.ico create mode 100644 Software/Graphics/FSE/File Associations/procedure_dde.png create mode 100644 Software/Graphics/FSE/File Associations/tdp_dde.ico create mode 100644 Software/Graphics/FSE/File Associations/tdp_dde.png create mode 100644 Software/Graphics/FSE/File Associations/tfp_dde.ico create mode 100644 Software/Graphics/FSE/File Associations/tfp_dde.png create mode 100644 Software/Graphics/FSE/File Associations/tup_dde.ico create mode 100644 Software/Graphics/FSE/File Associations/tup_dde.png delete mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationHandler.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Graphics/FSE/File Associations/procedure_dde.ico b/Software/Graphics/FSE/File Associations/procedure_dde.ico new file mode 100644 index 000000000..7df42ce47 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/procedure_dde.ico differ diff --git a/Software/Graphics/FSE/File Associations/procedure_dde.png b/Software/Graphics/FSE/File Associations/procedure_dde.png new file mode 100644 index 000000000..1e92440d6 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/procedure_dde.png differ diff --git a/Software/Graphics/FSE/File Associations/tdp_dde.ico b/Software/Graphics/FSE/File Associations/tdp_dde.ico new file mode 100644 index 000000000..a81e68d65 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tdp_dde.ico differ diff --git a/Software/Graphics/FSE/File Associations/tdp_dde.png b/Software/Graphics/FSE/File Associations/tdp_dde.png new file mode 100644 index 000000000..9ba449028 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tdp_dde.png differ diff --git a/Software/Graphics/FSE/File Associations/tfp_dde.ico b/Software/Graphics/FSE/File Associations/tfp_dde.ico new file mode 100644 index 000000000..27ce70914 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tfp_dde.ico differ diff --git a/Software/Graphics/FSE/File Associations/tfp_dde.png b/Software/Graphics/FSE/File Associations/tfp_dde.png new file mode 100644 index 000000000..0577cfb13 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tfp_dde.png differ diff --git a/Software/Graphics/FSE/File Associations/tup_dde.ico b/Software/Graphics/FSE/File Associations/tup_dde.ico new file mode 100644 index 000000000..013e33ba5 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tup_dde.ico differ diff --git a/Software/Graphics/FSE/File Associations/tup_dde.png b/Software/Graphics/FSE/File Associations/tup_dde.png new file mode 100644 index 000000000..9c6374f87 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tup_dde.png differ diff --git a/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip b/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip index 4d7250d8e..901fd1a05 100644 --- a/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip +++ b/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip @@ -310,6 +310,7 @@ + @@ -666,6 +667,7 @@ + @@ -810,6 +812,9 @@ + + + @@ -1078,11 +1083,15 @@ + - + + + + @@ -1139,7 +1148,10 @@ - + + + + @@ -1166,6 +1178,10 @@ + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs index ac9279ab8..8a89fbc8f 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs @@ -15,8 +15,10 @@ using Tango.BL.Enumerations; using Tango.Core.Commands; using Tango.FSE.Common; using Tango.FSE.Common.Diagnostics; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Notifications; using Tango.FSE.Diagnostics.Project; +using Tango.FSE.Diagnostics.Views; using Tango.PMR.Diagnostics; namespace Tango.FSE.Diagnostics.ViewModels @@ -403,6 +405,8 @@ namespace Tango.FSE.Diagnostics.ViewModels { base.OnApplicationStarted(); DiagnosticsProvider.FrameReceived += DiagnosticsProvider_FrameReceived; + + FileAssociationProvider.RegisterFileAssociationHandler("diagnostics", HandleDiagnosticsFileAssociation); } public async override void OnApplicationReady() @@ -781,5 +785,36 @@ namespace Tango.FSE.Diagnostics.ViewModels } #endregion + + #region File Association + + private async void HandleDiagnosticsFileAssociation(FileAssociationPackage package) + { + if (!CurrentUser.HasPermission(Permissions.FSE_EditDiagnosticsProject)) + { + await NotificationProvider.ShowError("Current user profile does not allow loading custom diagnostics projects."); + return; + } + + if (File.Exists(package.File)) + { + try + { + LogManager.Log("Opening diagnostics project from file association..."); + await NavigationManager.NavigateTo(true, nameof(DiagnosticsView)); + using (NotificationProvider.PushTaskItem("Loading diagnostics project...")) + { + await Task.Delay(2000); + await LoadProject(package.File); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to handle the diagnostics file association."); + } + } + } + + #endregion } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Help/proc-doc.chm b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Help/proc-doc.chm index 861555098..1fb821112 100644 Binary files a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Help/proc-doc.chm and b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Help/proc-doc.chm differ diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Tango.FSE.Procedures.Documentation.shfbproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Tango.FSE.Procedures.Documentation.shfbproj index 7a0935061..abb8a83f9 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Tango.FSE.Procedures.Documentation.shfbproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Tango.FSE.Procedures.Documentation.shfbproj @@ -80,6 +80,7 @@ + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Navigation/RunProcedureNavigationObject.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Navigation/RunProcedureNavigationObject.cs index b91d6ca03..c19857c21 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Navigation/RunProcedureNavigationObject.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Navigation/RunProcedureNavigationObject.cs @@ -9,5 +9,6 @@ namespace Tango.FSE.Procedures.Navigation public class RunProcedureNavigationObject { public ProcedureProject Project { get; set; } + public bool StartProcedure { get; set; } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs index 34510e54c..e9c476a20 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs @@ -21,6 +21,7 @@ using Tango.Core.Commands; using Tango.Core.ExtensionMethods; using Tango.Core.Helpers; using Tango.FSE.Common; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.Notifications; using Tango.FSE.Procedures.Contracts; @@ -454,6 +455,8 @@ namespace Tango.FSE.Procedures.ViewModels LogManager.Log(ex, "Error generating procedure designer auto creation groups."); } }); + + FileAssociationProvider.RegisterFileAssociationHandler("designer", HandlerProcedureFileAssociation); } public override void OnNavigatedTo() @@ -658,7 +661,8 @@ namespace Tango.FSE.Procedures.ViewModels { await NavigationManager.NavigateWithObject(new RunProcedureNavigationObject() { - Project = Project + Project = Project, + StartProcedure = true }); } } @@ -907,6 +911,12 @@ namespace Tango.FSE.Procedures.ViewModels private void OpenProject(String file) { + if (Project != null && Project.IsRunning) + { + NotificationProvider.ShowError("Cannot load a project while another project is running."); + return; + } + try { Project = ProcedureProject.FromJson(File.ReadAllText(file)); @@ -1517,5 +1527,32 @@ namespace Tango.FSE.Procedures.ViewModels } #endregion + + #region File Association + + private void HandlerProcedureFileAssociation(FileAssociationPackage package) + { + if (!CurrentUser.HasPermission(Permissions.FSE_RunProcedureDesigner)) + { + NotificationProvider.ShowError("Current user profile does not allow running the procedure designer."); + return; + } + + if (File.Exists(package.File)) + { + try + { + LogManager.Log("Opening procedure project from file association..."); + NavigationManager.NavigateTo(true, nameof(ProcedureDesignerView)); + OpenProject(package.File); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to handle the procedure file association."); + } + } + } + + #endregion } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureRunnerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureRunnerViewVM.cs index d69ba63f8..6ccc77669 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureRunnerViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureRunnerViewVM.cs @@ -1,19 +1,14 @@ using System; -using System.Collections; using System.Collections.Generic; -using System.ComponentModel; +using System.IO; using System.Linq; -using System.Reflection; -using System.Text; using System.Threading.Tasks; using Tango.BL.Entities; using Tango.Core; using Tango.Core.Commands; -using Tango.CSV; using Tango.FSE.Common; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Navigation; -using Tango.FSE.Procedures.CSV; -using Tango.FSE.Procedures.Dialogs; using Tango.FSE.Procedures.Messages; using Tango.FSE.Procedures.Navigation; using Tango.FSE.Procedures.Views; @@ -29,8 +24,8 @@ namespace Tango.FSE.Procedures.ViewModels } private bool _requiresReloadingOfProjects; - private bool _isFromDesigner; - private ProcedureProject _designerProject; + private bool _isFromNavigation; + private RunProcedureNavigationObject _navigationObject; private RunnerView _selectedView; public RunnerView SelectedView @@ -121,6 +116,13 @@ namespace Tango.FSE.Procedures.ViewModels RegisterForMessage((x) => _requiresReloadingOfProjects = true); } + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + + FileAssociationProvider.RegisterFileAssociationHandler("procedure", HandlerProcedureFileAssociation); + } + private async void StartProject() { try @@ -192,18 +194,22 @@ namespace Tango.FSE.Procedures.ViewModels LoadPublishedProcedureProjects(); } - if (_isFromDesigner) + if (_isFromNavigation) { if (!IsRunning) { - RunningProcedureProject = _designerProject; + RunningProcedureProject = _navigationObject.Project; RaisePropertyChanged(nameof(HasProcedureInputs)); ProjectRunner = new ProjectRunner(RunningProcedureProject); ProjectRunner.StateChanged += (x, e) => InvalidateRelayCommands(); Status = "Ready"; InvalidateRelayCommands(); SelectedView = RunnerView.ProcedureRunnerExecutionView; - StartProject(); + + if (_navigationObject.StartProcedure) + { + StartProject(); + } } else { @@ -252,16 +258,16 @@ namespace Tango.FSE.Procedures.ViewModels { SelectedView = RunnerView.ProcedureRunnerCatalogView; - if (_isFromDesigner) + if (_isFromNavigation) { - _isFromDesigner = false; + _isFromNavigation = false; return Task.FromResult(true); } return Task.FromResult(false); } - _isFromDesigner = false; + _isFromNavigation = false; return base.OnNavigateBackRequest(); } @@ -283,8 +289,28 @@ namespace Tango.FSE.Procedures.ViewModels public void OnNavigatedToWithObject(RunProcedureNavigationObject obj) { - _isFromDesigner = true; - _designerProject = obj.Project; + _isFromNavigation = true; + _navigationObject = obj; + } + + private async void HandlerProcedureFileAssociation(FileAssociationPackage package) + { + if (File.Exists(package.File)) + { + try + { + ProcedureProject project = ProcedureProject.FromJson(File.ReadAllText(package.File)); + LogManager.Log("Loading procedure from file association..."); + await NavigationManager.NavigateWithObject(new RunProcedureNavigationObject() + { + Project = project + }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to handler the procedure file association."); + } + } } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs index accc8d111..ce01b5804 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs @@ -5,10 +5,13 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL.Entities; +using Tango.BL.Enumerations; using Tango.Core.Commands; using Tango.FSE.Common; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.RemoteUpgrade; +using Tango.FSE.Upgrade.Views; using static Tango.FSE.Upgrade.ViewModels.FirmwareUpgradeGeneratedViewVM; namespace Tango.FSE.Upgrade.ViewModels @@ -102,6 +105,8 @@ namespace Tango.FSE.Upgrade.ViewModels base.OnApplicationStarted(); MachineProvider.MachineConnected += (_, __) => InvalidateCanUpgradeNow(); MachineProvider.MachineDisconnected += (_, __) => InvalidateCanUpgradeNow(); + + FileAssociationProvider.RegisterFileAssociationHandler("tfp", HandleTfpFileAssociation); } private void InvalidateCanUpgradeNow() @@ -199,7 +204,6 @@ namespace Tango.FSE.Upgrade.ViewModels IsCompleted = false; SelectedVersion = null; IsUpgradeNowSelected = true; - TfpFileLocation = null; InvalidateRelayCommands(); } @@ -235,5 +239,39 @@ namespace Tango.FSE.Upgrade.ViewModels return true; } + + private void HandleTfpFileAssociation(FileAssociationPackage package) + { + if (!IsFree) + { + NotificationProvider.ShowError("Cannot perform firmware upgrade while another upgrade is running."); + return; + } + + if (!CurrentUser.HasPermission(Permissions.FSE_RemoteUpgradeOnline)) + { + NotificationProvider.ShowError("Current user profile does not allow online remote upgrade."); + return; + } + + if (File.Exists(package.File)) + { + try + { + LogManager.Log("Performing remote firmware upgrade from file association..."); + Handler = new RemoteUpgradeHandler("Ready"); + IsCompleted = false; + TfpFileLocation = package.File; + IsUsingExistingTfp = true; + InvalidateCanUpgradeNow(); + NavigationManager.NavigateTo(true); + ModularNavigationManager.NavigateTo(Navigation.RemoteUpgradeView.FirmwareUpgradeGeneratedView); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to handle the tfp file association."); + } + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml index 6aeb0fcb1..3e93300c0 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml @@ -60,7 +60,7 @@ - + I already have the .tfp file and just want to upgrade the currently connected machine. (requires an active machine connection) diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs index c3f54d0e2..5f72fbd29 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs @@ -63,6 +63,11 @@ namespace Tango.FSE.Common.FSEApplication /// void Restart(); + /// + /// Activates the main window if it's not in focus. + /// + void ActivateMainWindow(); + /// /// Gets the application version. /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs index 352294e0a..c85a5fd35 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs @@ -141,6 +141,11 @@ namespace Tango.FSE.Common /// public bool TerminatedExpectedly { get; set; } + /// + /// Gets or sets the file association service port. + /// + public int FileAssociationServicePort { get; set; } + /// /// Initializes a new instance of the class. /// @@ -158,6 +163,7 @@ namespace Tango.FSE.Common AutoCheckForUpdates = true; EnableAdaptiveScaling = true; TerminatedExpectedly = true; + FileAssociationServicePort = 1800; } } } \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs index d6e3a5b52..07d2a7a5b 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs @@ -43,6 +43,7 @@ using Tango.FSE.Common.Tiles; using Tango.FSE.Common.RemoteJob; using Tango.FSE.Common.WindowsManager; using Tango.FSE.Common.DemoMode; +using Tango.FSE.Common.FileAssociation; namespace Tango.FSE.Common { @@ -228,6 +229,12 @@ namespace Tango.FSE.Common [TangoInject] public IDemoModeManager DemoModeManager { get; set; } + /// + /// Gets or sets the file association provider. + /// + [TangoInject] + public IFileAssociationProvider FileAssociationProvider { get; set; } + /// /// Gets or sets the FSE service. /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/FileAssociationPackage.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/FileAssociationPackage.cs index 106c37f16..ec072e7b1 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/FileAssociationPackage.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/FileAssociationPackage.cs @@ -8,6 +8,7 @@ namespace Tango.FSE.Common.FileAssociation { public class FileAssociationPackage { + public String TargetName { get; set; } public String File { get; set; } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/IFileAssociationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/IFileAssociationProvider.cs index 6b4440f41..2517ba82c 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/IFileAssociationProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/IFileAssociationProvider.cs @@ -6,8 +6,9 @@ using System.Threading.Tasks; namespace Tango.FSE.Common.FileAssociation { - public interface IFileAssociationProvider + public interface IFileAssociationProvider : INotifyApplicationStarted, INotifyApplicationReady { + bool HasStartArgsPackage { get; } void RegisterFileAssociationHandler(String targetName, Action handler); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs index ddcc5dc8f..2efd3c75d 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs @@ -106,9 +106,10 @@ namespace Tango.FSE.Common.Navigation /// The type of the view. /// The type of the pass. /// The object. - /// if set to true [push to history]. + /// Push the current view to history ?. + /// Force the navigation even if we are on the same view. /// - Task NavigateWithObject(TPass obj, bool pushToHistory = true) + Task NavigateWithObject(TPass obj, bool pushToHistory = true, bool force = false) where TModule : IFSEModule; /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs index 196978f69..de0594703 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Configuration; using System.Data; @@ -14,11 +15,14 @@ using Tango.Core.DI; using Tango.Core.Helpers; using Tango.FSE.Common; using Tango.FSE.Common.BugReporting; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Helpers; using Tango.FSE.Common.Notifications; +using Tango.FSE.UI.FileAssociation; using Tango.Integration.Operation; using Tango.Logging; using Tango.Settings; +using ZetaIpc.Runtime.Client; namespace Tango.FSE.UI { @@ -51,26 +55,42 @@ namespace Tango.FSE.UI protected override void OnStartup(StartupEventArgs e) { - if (e.Args != null) + try { - if (e.Args.Length == 3) + if (e.Args != null) { - if (e.Args[0] == "-file") + if (e.Args.Length == DefaultFileAssociationProvider.FILE_ASSOCIATION_ARGS_COUNT) { - if (mutex.WaitOne(TimeSpan.Zero, true)) - { - mutex.ReleaseMutex(); - MessageBox.Show($"Run Procedure {e.Args[2]} on this instance."); - } - else + if (e.Args[0] == DefaultFileAssociationProvider.FILE_ASSOCIATION_PREFIX) { - MessageBox.Show($"Run Procedure {e.Args[2]} on another instance."); - Environment.Exit(0); - return; + if (mutex.WaitOne(TimeSpan.Zero, true)) + { + //This is the first instance. Do nothing... + mutex.ReleaseMutex(); + } + else + { + //MessageBox.Show($"Run Procedure {e.Args[2]} on another instance."); + var settings = SettingsManager.Default.GetOrCreate(); + var ipcClient = new IpcClient(); + ipcClient.Initialize(settings.FileAssociationServicePort); + ipcClient.Send(JsonConvert.SerializeObject(new FileAssociationPackage() + { + TargetName = e.Args[1], + File = e.Args[2] + })); + Thread.Sleep(1000); + Environment.Exit(0); + return; + } } } } } + catch (Exception ex) + { + Debug.WriteLine(ex); + } //Set culture info. var enUSCulture = new CultureInfo("en-US"); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs index 48087bff9..aa5d4a629 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs @@ -457,5 +457,16 @@ namespace Tango.FSE.UI.FSEApplication return StartupArgs.Contains("-demo"); } } + + /// + /// Activates the main window if it's not in focus. + /// + public void ActivateMainWindow() + { + MainWindow.Instance.Dispatcher.BeginInvoke(new Action(() => + { + MainWindow.Instance.Activate(); + })); + } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationHandler.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationHandler.cs deleted file mode 100644 index 88f4fff05..000000000 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationHandler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.FSE.Common.FileAssociation; - -namespace Tango.FSE.UI.FileAssociation -{ - public class DefaultFileAssociationHandler : IFileAssociationProvider - { - private Dictionary> _handlers; - - public DefaultFileAssociationHandler() - { - _handlers = new Dictionary>(); - } - - public void RegisterFileAssociationHandler(string targetName, Action handler) - { - _handlers.Add(targetName.ToLower(), handler); - } - } -} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs new file mode 100644 index 000000000..9e2997e92 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs @@ -0,0 +1,136 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.FSE.Common; +using Tango.FSE.Common.FileAssociation; +using Tango.FSE.Common.FSEApplication; +using Tango.FSE.Common.Threading; +using Tango.Logging; +using ZetaIpc.Runtime.Server; + +namespace Tango.FSE.UI.FileAssociation +{ + [TangoCreateWhenRegistered] + public class DefaultFileAssociationProvider : FSEExtendedObject, IFileAssociationProvider + { + private Dictionary> _handlers; + private IpcServer _ipcServer; + + public const string FILE_ASSOCIATION_PREFIX = "-file"; + public const int FILE_ASSOCIATION_ARGS_COUNT = 3; + + public bool HasStartArgsPackage { get; private set; } + + [TangoInject] + private IDispatcherProvider DispatcherProvider { get; set; } + + [TangoInject] + private IFSEApplicationManager ApplicationManager { get; set; } + + public DefaultFileAssociationProvider() + { + _handlers = new Dictionary>(); + _ipcServer = new IpcServer(); + } + + public void RegisterFileAssociationHandler(string targetName, Action handler) + { + _handlers.Add(targetName.ToLower(), handler); + } + + public async void OnApplicationReady(IFSEApplicationManager applicationManager) + { + try + { + LogManager.Log("Starting file association IPC service..."); + _ipcServer.Start(Settings.FileAssociationServicePort); + _ipcServer.ReceivedRequest += _ipcServer_ReceivedRequest; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error starting file association IPC service. Another instance of the application might already be running..."); + } + + var args = applicationManager.StartupArgs; + + LogManager.Log("Processing file association if any..."); + + if (args.Count == FILE_ASSOCIATION_ARGS_COUNT) + { + if (args[0] == FILE_ASSOCIATION_PREFIX) + { + + //This delay is a workaround for when the invoked handler navigates to some module. + //The navigation system does not catches the navigation request properly... :/ + await Task.Delay(500); + + LogManager.Log($"File association package found: '{String.Join(" ", args)}'. Invoking handler..."); + + try + { + String targetName = args[1].ToLower(); + + if (_handlers.ContainsKey(targetName)) + { + var package = new FileAssociationPackage() + { + TargetName = targetName, + File = args[2] + }; + + _handlers[targetName].Invoke(package); + } + else + { + LogManager.Log("File association handler not found.", LogCategory.Warning); + } + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error invoking file association handler for package '{String.Join(" ", args)}'."); + } + } + } + } + + private void _ipcServer_ReceivedRequest(object sender, ReceivedRequestEventArgs e) + { + try + { + e.Handled = true; + LogManager.Log($"File association package received through IPC server.\n{e.Request}\nInvoking handler..."); + + var package = JsonConvert.DeserializeObject(e.Request); + + if (_handlers.ContainsKey(package.TargetName.ToLower())) + { + DispatcherProvider.Invoke(() => + { + ApplicationManager.ActivateMainWindow(); + _handlers[package.TargetName.ToLower()].Invoke(package); + }); + } + else + { + LogManager.Log($"Handler not found for target '{package.TargetName}'.", LogCategory.Warning); + } + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error invoking file association handler."); + } + } + + public void OnApplicationStarted(IFSEApplicationManager applicationManager) + { + HasStartArgsPackage = + applicationManager.StartupArgs.Count == FILE_ASSOCIATION_ARGS_COUNT + && + applicationManager.StartupArgs[0] == FILE_ASSOCIATION_PREFIX; + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs index 9de496793..7a55b085a 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs @@ -44,6 +44,7 @@ namespace Tango.FSE.UI.Navigation private Object _currentVM; private String _lastFullPath; private bool _preventHistory; + private bool _force; private Stack _navigationHistory; @@ -242,7 +243,7 @@ namespace Tango.FSE.UI.Navigation { try { - if (_lastFullPath == fullPath) + if (_lastFullPath == fullPath && !_force) { return true; } @@ -450,12 +451,15 @@ namespace Tango.FSE.UI.Navigation /// The type of the view. /// The type of the pass. /// The object. - /// if set to true [push to history]. + /// Push the current view to history ?. + /// Force the navigation even if we are on the same view. /// - public Task NavigateWithObject(TPass obj, bool pushToHistory = true) where TModule : IFSEModule + public Task NavigateWithObject(TPass obj, bool pushToHistory = true, bool force = false) where TModule : IFSEModule { + _force = true; return NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (fromVM, toVM) => { + _force = false; if (toVM is INavigationObjectReceiver) { (toVM as INavigationObjectReceiver).OnNavigatedToWithObject(obj); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj index 44a163326..3d5fa6db1 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj @@ -200,6 +200,9 @@ + + ..\..\packages\ZetaIpc.1.0.0.9\lib\netstandard2.0\ZetaIpc.dll + @@ -271,7 +274,7 @@ - + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs index 13520ec7e..25d0b45c9 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs @@ -64,6 +64,8 @@ using Tango.FSE.Common.DemoMode; using Tango.FSE.UI.DemoMode; using Tango.FSE.Common.SQL; using Tango.FSE.UI.SQL; +using Tango.FSE.Common.FileAssociation; +using Tango.FSE.UI.FileAssociation; namespace Tango.FSE.UI { @@ -101,6 +103,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); @@ -138,6 +141,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs index 5c4f1b11a..9a5433f82 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs @@ -232,6 +232,14 @@ namespace Tango.FSE.UI.ViewModels { this.SetFocus(() => Password); } + + if (RememberMe) + { + if (FileAssociationProvider.HasStartArgsPackage) + { + Login(); + } + } } /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config b/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config index d0abb0ebf..4fda0a885 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config @@ -68,4 +68,5 @@ + \ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs index 387430f89..b9dacfcf9 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs @@ -200,7 +200,7 @@ namespace Tango.MachineService.Controllers String comments = String.Join(Environment.NewLine, versions.OrderBy(x => Version.Parse(x.Version)).Where(x => Version.Parse(x.Version) > currentVersion).Select(x => x.Comments)); - if (latestVersion != null && Version.Parse(latestVersion.Version) != currentVersion) + if (latestVersion != null && Version.Parse(latestVersion.Version) > currentVersion) { var manager = new BlobStorageManager(); var container = manager.GetContainer(MachineServiceConfig.FSE_VERSIONS_CONTAINER); diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs index a6aa93dee..704da0c08 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyVersion("3.0.2.0")] -- cgit v1.3.1 From 09b1dd03e5d67453e673789fe0826e7a25d881ab Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Thu, 24 Sep 2020 22:28:15 +0300 Subject: Allow null user on jobs. Dropped use of any user on PPC. --- Software/DB/PPC/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/PPC/Tango_log.ldf | Bin 53673984 -> 53673984 bytes Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../ViewModels/MainViewVM.cs | 2 +- .../Views/MachineJobSelectionView.xaml | 2 +- .../Views/JobRunsView.xaml | 2 +- .../Tango.PPC.Jobs/ViewModels/JobsViewVM.cs | 4 +- .../Authentication/IAuthenticationProvider.cs | 11 ++++ .../BackupRestore/DefaultBackupManager.cs | 4 +- .../EventLogging/DefaultEventLogger.cs | 6 +- .../DefaultMachineDataSynchronizer.cs | 4 +- .../PPC/Tango.PPC.Common/Tango.PPC.Common.csproj | 2 +- .../DefaultAuthenticationProvider.cs | 18 ++++++ .../Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs | 6 +- .../PPC/Tango.PPC.UI/Tango.PPC.UI.csproj | 2 +- .../PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs | 67 ++++++++++++--------- .../PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs | 8 ++- .../Controllers/PPCController.cs | 28 +-------- 19 files changed, 95 insertions(+), 71 deletions(-) (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/DB/PPC/Tango.mdf b/Software/DB/PPC/Tango.mdf index 15c3bd9ca..9f7d93dfe 100644 Binary files a/Software/DB/PPC/Tango.mdf and b/Software/DB/PPC/Tango.mdf differ diff --git a/Software/DB/PPC/Tango_log.ldf b/Software/DB/PPC/Tango_log.ldf index 65758d2f1..084f08847 100644 Binary files a/Software/DB/PPC/Tango_log.ldf and b/Software/DB/PPC/Tango_log.ldf differ diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 008504c5b..f8c0132fb 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 a5ccf997d..5cc378c9f 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index 8f02749da..fc0680d9c 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -1257,7 +1257,7 @@ namespace Tango.MachineStudio.Developer.ViewModels || j.Name.ToLower().Contains(filter) //Job name || - j.User.Contact.FirstName.ToLower().Contains(filter) // User first name + (j.User != null && j.User.Contact.FirstName.ToLower().Contains(filter)) // User first name || j.Length.ToString().Contains(filter); //Job length }; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml index 78a7551c0..c7e1d4130 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml @@ -193,7 +193,7 @@ - + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml index de506bab8..862f48793 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml @@ -493,7 +493,7 @@ - + diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs index c41a9ef5d..164867afe 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Jobs/ViewModels/JobsViewVM.cs @@ -518,7 +518,7 @@ namespace Tango.PPC.Jobs.ViewModels job.ColorSpaceGuid = Adapter.ColorSpaces.FirstOrDefault(x => x.Code == vm.SelectedColorSpace.ToInt32()).Guid; job.ColorSpace = _colorSpaces.SingleOrDefault(x => x.Guid == job.ColorSpaceGuid); job.MachineGuid = MachineProvider.Machine.Guid; - job.UserGuid = AuthenticationProvider.CurrentUser.Guid; + job.UserGuid = null; job.RmlGuid = Settings.DefaultRmlGuid != null ? Settings.DefaultRmlGuid : _rmls.FirstOrDefault().Guid; job.WindingMethodGuid = Adapter.WindingMethods.FirstOrDefault().Guid; job.SpoolTypeGuid = Settings.DefaultSpoolTypeGuid != null ? Settings.DefaultSpoolTypeGuid : Adapter.SpoolTypes.FirstOrDefault().Guid; @@ -843,7 +843,7 @@ namespace Tango.PPC.Jobs.ViewModels try { JobFile jFile = JobFile.Parser.ParseFrom(File.ReadAllBytes(jobFile.Path)); - var job = await Job.FromJobFile(jFile, MachineProvider.Machine.Guid, AuthenticationProvider.CurrentUser.Guid); + var job = await Job.FromJobFile(jFile, MachineProvider.Machine.Guid, null); job.JobSource = JobSource.Local; jobContext.Jobs.Add(job); await jobContext.SaveChangesAsync(); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Authentication/IAuthenticationProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Authentication/IAuthenticationProvider.cs index 33761c8d6..ca927e6df 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Authentication/IAuthenticationProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Authentication/IAuthenticationProvider.cs @@ -22,6 +22,11 @@ namespace Tango.PPC.Common.Authentication /// User CurrentUser { get; } + /// + /// Gets a value indicating whether the authentication provider is using a null user. + /// + bool AuthenticationRequired { get; } + /// /// Performs a user login by the specified email and password. /// @@ -31,6 +36,12 @@ namespace Tango.PPC.Common.Authentication /// Task Login(String email, String password, bool encrypt = true); + /// + /// Performs a fake login when no authentication is used. + /// + /// + Task Login(); + /// /// Logs-out the current logged-in user. /// diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/DefaultBackupManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/DefaultBackupManager.cs index 087534d48..d32df734d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/DefaultBackupManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/DefaultBackupManager.cs @@ -368,7 +368,7 @@ namespace Tango.PPC.Common.BackupRestore { LogManager.Log("Job already exist, overwriting..."); - var newJob = Job.FromJobFile(jobFile, _machineProvider.Machine.Guid, _authenticationProvider.CurrentUser.Guid).Result; + var newJob = Job.FromJobFile(jobFile, _machineProvider.Machine.Guid, null).Result; newJob.Guid = existingJob.Guid; existingJob.Delete(db); @@ -386,7 +386,7 @@ namespace Tango.PPC.Common.BackupRestore } else { - var newJob = Job.FromJobFile(jobFile, _machineProvider.Machine.Guid, _authenticationProvider.CurrentUser.Guid).Result; + var newJob = Job.FromJobFile(jobFile, _machineProvider.Machine.Guid, null).Result; db.Jobs.Add(newJob); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/DefaultEventLogger.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/DefaultEventLogger.cs index 970532d43..e9bcd4246 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/DefaultEventLogger.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/EventLogging/DefaultEventLogger.cs @@ -261,7 +261,7 @@ namespace Tango.PPC.Common.EventLogging machineEvent.HostName = _hostName; machineEvent.EventType = _eventTypesGuids[machineEvent.Type]; - if (_machine == null || _authentication.CurrentUser == null) + if (_machine == null) { _pendingEvents.Add(machineEvent); } @@ -280,8 +280,8 @@ namespace Tango.PPC.Common.EventLogging LogManager.Log("Logging event " + machineEvent.EventType.Name); machineEvent.MachineGuid = _machine.Guid; - machineEvent.UserGuid = _authentication.CurrentUser.Guid; - machineEvent.User = _authentication.CurrentUser; + machineEvent.UserGuid = null; + machineEvent.User = null; _events.Enqueue(machineEvent); if (!_currentEvents.Exists(x => x.Type == machineEvent.Type)) diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs index 53e41062f..ab1f8e890 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs @@ -315,7 +315,7 @@ namespace Tango.PPC.Common.Synchronization var job = dto.ToObservable(); job.ID = 0; - job.UserGuid = _authenticationProvider.CurrentUser.Guid; + job.UserGuid = null; job.CustomerGuid = null; job.IsSynchronized = true; @@ -385,7 +385,7 @@ namespace Tango.PPC.Common.Synchronization { var ev = dto.ToObservable(); ev.ID = 0; - ev.UserGuid = _authenticationProvider.CurrentUser.Guid; + ev.UserGuid = null; ev.IsSynchronized = true; if (await db.MachinesEvents.SingleOrDefaultAsync(x => x.Guid == ev.Guid) == null) 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 14666f16a..87b322f04 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 @@ -489,7 +489,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs index 04e968da2..e7be61b0a 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs @@ -45,6 +45,11 @@ namespace Tango.PPC.UI.Authentication } } + /// + /// Gets a value indicating whether the authentication provider is using a null user. + /// + public bool AuthenticationRequired { get; private set; } + /// /// Performs a user login by the specified email and password. /// @@ -56,6 +61,9 @@ namespace Tango.PPC.UI.Authentication { return Task.Factory.StartNew(() => { + + AuthenticationRequired = true; + String hash = encrypt ? User.GetPasswordHash(password) : password; LogManager.Log($"Logging in user {email}..."); @@ -82,6 +90,16 @@ namespace Tango.PPC.UI.Authentication }); } + public Task Login() + { + return Task.Factory.StartNew(() => + { + AuthenticationRequired = false; + CurrentUser = null; + CurrentUserChanged?.Invoke(this, CurrentUser); + }); + } + /// /// Logs-out the current logged-in user. /// diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs index 375b648d0..bbabed225 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs @@ -131,10 +131,14 @@ namespace Tango.PPC.UI.Modules UserModules.Clear(); - if (_authenticationProvider.CurrentUser != null) + if (_authenticationProvider.AuthenticationRequired && _authenticationProvider.CurrentUser != null) { UserModules = AllModules.Where(x => _authenticationProvider.CurrentUser.HasPermission(x.Permission)).ToObservableCollection(); } + else if (!_authenticationProvider.AuthenticationRequired) + { + UserModules = AllModules.ToObservableCollection(); + } ModulesLoaded?.Invoke(this, new EventArgs()); } 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 6b6934ce5..c214d73ae 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 @@ -725,7 +725,7 @@ if $(ConfigurationName) == Debug copy /Y "$(TargetDir)Packages" "$(TargetDir)" - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs index e280d5f9d..38dd569e1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs @@ -74,39 +74,46 @@ namespace Tango.PPC.UI.ViewModels /// public async override void OnApplicationStarted() { - using (ObservablesContext db = ObservablesContext.CreateDefault()) - { - var machine = await db.Machines.FirstAsync(); + //We don't use authentication! - if (db.Users.Count() == 1 || machine.AutoLogin) - { - var user = await new UserBuilder(db).SetFirst().WithRolesAndPermissions().BuildAsync(); + //using (ObservablesContext db = ObservablesContext.CreateDefault()) + //{ + // var machine = await db.Machines.FirstAsync(); - if (!user.HasRole(Roles.PPCUser)) - { - var role = db.Roles.Single(x => x.Code == (int)Roles.PPCUser); - user.Roles.Add(role); - db.UsersRoles.Add(new BL.Entities.UsersRole() - { - User = user, - Role = role, - }); - await db.SaveChangesAsync(); - } + // if (db.Users.Count() == 1 || machine.AutoLogin) + // { + // var user = await new UserBuilder(db).SetFirst().WithRolesAndPermissions().BuildAsync(); - LogManager.Log($"Application started. Single user/Auto login detected ({user.Email}). Skipping LoginView..."); - await AuthenticationProvider.Login(user.Email, user.Password, false); - await Task.Delay(1000); - IsLoading = false; - } - else - { - LogManager.Log("Application started. Navigating to LoginView..."); - await NavigationManager.NavigateTo(NavigationView.LoginView); - await Task.Delay(1000); - IsLoading = false; - } - } + // if (!user.HasRole(Roles.PPCUser)) + // { + // var role = db.Roles.Single(x => x.Code == (int)Roles.PPCUser); + // user.Roles.Add(role); + // db.UsersRoles.Add(new BL.Entities.UsersRole() + // { + // User = user, + // Role = role, + // }); + // await db.SaveChangesAsync(); + // } + + // LogManager.Log($"Application started. Single user/Auto login detected ({user.Email}). Skipping LoginView..."); + // await AuthenticationProvider.Login(user.Email, user.Password, false); + // await Task.Delay(1000); + // IsLoading = false; + // } + // else + // { + // LogManager.Log("Application started. Navigating to LoginView..."); + // await NavigationManager.NavigateTo(NavigationView.LoginView); + // await Task.Delay(1000); + // IsLoading = false; + // } + //} + + LogManager.Log($"Application started with no authentication mode..."); + await AuthenticationProvider.Login(); + await Task.Delay(1000); + IsLoading = false; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs index aa9689ef3..ec316989f 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs @@ -92,7 +92,13 @@ namespace Tango.PPC.UI.ViewModels await Task.Delay(500); - if (AuthenticationProvider.CurrentUser != null && AuthenticationProvider.CurrentUser.HasPermission(Permissions.RunPPC)) + if (!AuthenticationProvider.AuthenticationRequired) + { + LogManager.Log("Application is ready! Navigating to home module..."); + await NavigationManager.NavigateTo(NavigationView.HomeModule); + IsLoading = false; + } + else if (AuthenticationProvider.CurrentUser != null && AuthenticationProvider.CurrentUser.HasPermission(Permissions.RunPPC)) { LogManager.Log("Application is ready! Navigating to home module..."); await NavigationManager.NavigateTo(NavigationView.HomeModule); diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 22feb29c1..4215cd175 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -507,8 +507,6 @@ namespace Tango.MachineService.Controllers }); } - User machineUser = null; - try { using (ObservablesContext db = ObservablesContextHelper.CreateContext()) @@ -519,26 +517,6 @@ namespace Tango.MachineService.Controllers { throw new AuthenticationException("The specified machine could not be found."); } - - machineUser = db.Users.Include(x => x.Contact).SingleOrDefault(x => x.Contact.FirstName == machine.Name); - - if (machineUser == null) - { - //No machine user then create one. - machineUser = new User(); - machineUser.Email = machine.SerialNumber + "@twine-s.com"; - machineUser.Password = machine.SerialNumber; - machineUser.OrganizationGuid = machine.OrganizationGuid; - machineUser.Contact = new Contact(); - machineUser.Contact.Email = machineUser.Email; - machineUser.Contact.FirstName = machine.Name; - machineUser.Contact.LastName = machine.Name; - machineUser.Contact.FullName = machine.Name; - machineUser.Address = new Address(); - - db.Users.Add(machineUser); - db.SaveChanges(); - } } //Insert/Replace Jobs. @@ -551,7 +529,7 @@ namespace Tango.MachineService.Controllers var job = dto.ToObservable(); job.ID = 0; - job.UserGuid = machineUser.Guid; + job.UserGuid = dto.UserGuid; job.CustomerGuid = null; job.IsSynchronized = true; @@ -589,7 +567,7 @@ namespace Tango.MachineService.Controllers { var run = dto.ToObservable(); run.ID = 0; - run.UserGuid = machineUser.Guid; + run.UserGuid = dto.UserGuid; run.IsSynchronized = true; if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) @@ -618,7 +596,7 @@ namespace Tango.MachineService.Controllers { var ev = dto.ToObservable(); ev.ID = 0; - ev.UserGuid = machineUser.Guid; + ev.UserGuid = dto.UserGuid; ev.IsSynchronized = true; if (db.MachinesEvents.SingleOrDefault(x => x.Guid == ev.Guid) == null) -- cgit v1.3.1 From 17a624c8ddacc1dac4904793645d6c893f7ced77 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Thu, 24 Sep 2020 23:20:25 +0300 Subject: Changed all PPC updated to based on GUID ! --- Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../MachineSetup/MachineSetupManager.cs | 1 - .../MachineUpdate/IMachineUpdateManager.cs | 13 +++--- .../MachineUpdate/MachineUpdateManager.cs | 47 +++++++++------------ .../DefaultMachineDataSynchronizer.cs | 2 +- .../Tango.PPC.Common/Web/CheckForUpdateRequest.cs | 1 - .../Tango.PPC.Common/Web/DownloadUpdateRequest.cs | 2 +- .../PPC/Tango.PPC.Common/Web/LoginRequest.cs | 1 + .../Tango.PPC.Common/Web/MachineSetupRequest.cs | 1 - .../PPC/Tango.PPC.Common/Web/UpdateDBRequest.cs | 1 - .../Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs | 6 +-- .../Configurations/ProvisionMachine.xml | Bin 88354 -> 76348 bytes .../SQLExaminer/Configurations/UpdateMachine.xml | Bin 55424 -> 72920 bytes .../Controllers/PPCController.cs | 10 +++-- 15 files changed, 39 insertions(+), 46 deletions(-) (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index f8c0132fb..aeb06fad3 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 5cc378c9f..52724650c 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ 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 a2a750805..15902f629 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs @@ -247,7 +247,6 @@ namespace Tango.PPC.Common.MachineSetup } MachineSetupRequest request = new MachineSetupRequest(); - request.SerialNumber = serialNumber; request.DeviceID = await _windows_manager.GetDeviceId(); request.DeviceName = deviceName; 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 3e3fbcc27..77646da40 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs @@ -38,9 +38,8 @@ namespace Tango.PPC.Common.MachineUpdate event EventHandler Progress; /// - /// Performs a machine update using the specified serial number and machine service address. + /// Performs a machine update. /// - /// The serial number. /// if set to true updates the embedded device firmware. /// if set to true updates the embedded device FPGA version and other parameters. /// @@ -61,24 +60,22 @@ namespace Tango.PPC.Common.MachineUpdate Task UpdateFromTFP(String fileName); /// - /// Checks if any update are available for the specified machine serial number. + /// Checks if any update are available. /// - /// The serial number. /// - Task CheckForUpdate(String serialNumber); + Task CheckForUpdate(); /// /// Checks whether it is necessary to updates all the "overwrite-able" database tables. /// - /// The serial number. /// - Task UpdateDBCheck(String serialNumber); + Task UpdateDBCheck(); /// /// Updates all the "overwrite-able" database tables. /// /// - Task UpdateDB(DbCompareResult dbCompareResult, String serialNumber); + Task UpdateDB(DbCompareResult dbCompareResult); /// /// Gets the update package file information. 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 4f8be0a6e..9b4462a70 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs @@ -148,12 +148,12 @@ namespace Tango.PPC.Common.MachineUpdate #region Private Methods - private Task Login(String serialNumber) + private Task Login(String machineGuid) { return _client.Login(new LoginRequest() { Mode = LoginMode.Machine, - SerialNumber = serialNumber, + MachineGuid = machineGuid, }); } @@ -609,9 +609,8 @@ namespace Tango.PPC.Common.MachineUpdate #region Public Methods /// - /// Performs a machine update using the specified serial number and machine service address. + /// Performs a machine update. /// - /// The serial number. /// if set to true updates the embedded device firmware. /// if set to true updates the embedded device FPGA version and other parameters. /// @@ -638,7 +637,7 @@ namespace Tango.PPC.Common.MachineUpdate var _newPackageTempFolder = TemporaryManager.CreateFolder(); _newPackageTempFolder.Persist = true; - String serialNumber = _machineProvider.Machine.SerialNumber; + String machineGuid = _machineProvider.Machine.Guid; try { @@ -646,7 +645,7 @@ namespace Tango.PPC.Common.MachineUpdate var machineServiceAddress = _settings.GetMachineServiceAddress(); - LogManager.Log($"Starting machine update for serial number {serialNumber}..."); + LogManager.Log($"Starting machine update..."); //Connecting to machine... LogManager.Log("Verifying machine connection and state..."); @@ -677,10 +676,9 @@ namespace Tango.PPC.Common.MachineUpdate LogManager.Log($"Connecting to machine service on {machineServiceAddress}..."); - await Login(serialNumber); + await Login(machineGuid); DownloadUpdateRequest request = new DownloadUpdateRequest(); - request.SerialNumber = serialNumber; update_response = await _client.MachineUpdate(request); @@ -804,7 +802,7 @@ namespace Tango.PPC.Common.MachineUpdate Path.Combine(_newPackageTempFolder, "Update Scripts"), update_response.DataSource, localDataSource, - serialNumber); + machineGuid); runner.Log += (x, msg) => { @@ -894,12 +892,11 @@ namespace Tango.PPC.Common.MachineUpdate } /// - /// Checks if any update are available for the specified machine serial number. + /// Checks if any update are available for the specified machine. /// - /// The serial number. /// The machine service address. /// - public Task CheckForUpdate(string serialNumber) + public Task CheckForUpdate() { return Task.Factory.StartNew(() => { @@ -909,12 +906,13 @@ namespace Tango.PPC.Common.MachineUpdate LogManager.Log($"Connecting to machine service on {machineServiceAddress}..."); - Login(serialNumber).GetAwaiter().GetResult(); + String machineGuid = _machineProvider.Machine.Guid; + + Login(machineGuid).GetAwaiter().GetResult(); LogManager.Log($"Checking if updates available..."); CheckForUpdateRequest request = new CheckForUpdateRequest(); - request.SerialNumber = serialNumber; request.Version = _app_manager.Version.ToString(); request.FirmwareVersion = _app_manager.FirmwareVersion?.ToString(); @@ -950,10 +948,9 @@ namespace Tango.PPC.Common.MachineUpdate /// /// Updates all the "overwrite-able" database tables. /// - /// The serial number. /// The machine service address. /// - public Task UpdateDB(DbCompareResult dbCompareResult, String serialNumber) + public Task UpdateDB(DbCompareResult dbCompareResult) { _updateStartDate = DateTime.UtcNow; _logs.Clear(); @@ -1034,7 +1031,7 @@ namespace Tango.PPC.Common.MachineUpdate if (item.RequiresSerialNumber) { - builder.SetMachineSerialNumber(serialNumber); + builder.SetMachineSerialNumber(_machineProvider.Machine.Guid); } builder.Synchronize(); @@ -1081,16 +1078,15 @@ namespace Tango.PPC.Common.MachineUpdate /// /// Checks whether it is necessary to updates all the "overwrite-able" database tables. /// - /// The serial number. /// The machine service address. /// - public Task UpdateDBCheck(string serialNumber) + public Task UpdateDBCheck() { return Task.Factory.StartNew(() => { var machineServiceAddress = _settings.GetMachineServiceAddress(); - LogManager.Log($"Checking if database update is required for serial number {serialNumber}..."); + LogManager.Log($"Checking if database update is required..."); LogManager.Log("Looking for update scripts configuration on application path..."); @@ -1103,10 +1099,9 @@ namespace Tango.PPC.Common.MachineUpdate LogManager.Log($"Connecting to machine service on {machineServiceAddress}..."); - Login(serialNumber).Wait(); + Login(_machineProvider.Machine.Guid).Wait(); UpdateDBRequest request = new UpdateDBRequest(); - request.SerialNumber = serialNumber; request.ApplicationVersion = _app_manager.Version.ToString(); request.FirmwareVersion = _app_manager.FirmwareVersion.ToString(); @@ -1137,7 +1132,7 @@ namespace Tango.PPC.Common.MachineUpdate if (item.RequiresSerialNumber) { - builder.SetMachineSerialNumber(serialNumber); + builder.SetMachineSerialNumber(_machineProvider.Machine.Guid); } var config = builder.Build(); @@ -1227,7 +1222,7 @@ namespace Tango.PPC.Common.MachineUpdate { _isUpdating = true; - LogManager.Log($"Starting machine update for serial number {serialNumber}..."); + LogManager.Log($"Starting machine update (TUP) for serial number {serialNumber}..."); //Connecting to machine... LogManager.Log("Verifying machine connection and state..."); @@ -1368,7 +1363,7 @@ namespace Tango.PPC.Common.MachineUpdate Path.Combine(_newPackageTempFolder, "Update Scripts"), tempDbDataSource, localDataSource, - serialNumber); + _machineProvider.Machine.Guid); runner.Log += (x, msg) => { @@ -1661,7 +1656,7 @@ namespace Tango.PPC.Common.MachineUpdate try { - var response = await CheckForUpdate(_machineProvider.Machine.SerialNumber); + var response = await CheckForUpdate(); if (response.IsUpdateAvailable || response.IsDatabaseUpdateAvailable) { LogManager.Log($"New {(response.IsDatabaseUpdateAvailable ? "database updates" : "application version")} detected ({response.Version}). Raising event..."); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs index ab1f8e890..645ddbdf5 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs @@ -452,7 +452,7 @@ namespace Tango.PPC.Common.Synchronization await this.client.Login(new LoginRequest() { Mode = LoginMode.Machine, - SerialNumber = _machineProvider.Machine.SerialNumber, + MachineGuid = _machineProvider.Machine.Guid, }); } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/CheckForUpdateRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/CheckForUpdateRequest.cs index a93b30a59..8e13ea7c4 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/CheckForUpdateRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/CheckForUpdateRequest.cs @@ -9,7 +9,6 @@ namespace Tango.PPC.Common.Web { public class CheckForUpdateRequest : WebRequestMessage { - public String SerialNumber { get; set; } public String Version { get; set; } public String FirmwareVersion { get; set; } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadUpdateRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadUpdateRequest.cs index a32d3d497..db4080dff 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadUpdateRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadUpdateRequest.cs @@ -9,6 +9,6 @@ namespace Tango.PPC.Common.Web { public class DownloadUpdateRequest : WebRequestMessage { - public String SerialNumber { get; set; } + } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LoginRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LoginRequest.cs index f8588f6b0..9ae0d65ae 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LoginRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/LoginRequest.cs @@ -11,6 +11,7 @@ namespace Tango.PPC.Common.Web { public LoginMode Mode { get; set; } public String SerialNumber { get; set; } + public String MachineGuid { get; set; } public String Email { get; set; } public String Password { get; set; } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupRequest.cs index 821828a48..a9e68df36 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupRequest.cs @@ -9,7 +9,6 @@ namespace Tango.PPC.Common.Web { public class MachineSetupRequest : WebRequestMessage { - public String SerialNumber { get; set; } public String DeviceID { get; set; } public String DeviceName { get; set; } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UpdateDBRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UpdateDBRequest.cs index c78f6199e..4d8433a56 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UpdateDBRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UpdateDBRequest.cs @@ -9,7 +9,6 @@ namespace Tango.PPC.Common.Web { public class UpdateDBRequest : WebRequestMessage { - public String SerialNumber { get; set; } public String ApplicationVersion { get; set; } public String FirmwareVersion { get; set; } } 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 d4d78dac6..23ec956a0 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs @@ -167,7 +167,7 @@ namespace Tango.PPC.UI.ViewModels return; } - var response = await MachineUpdateManager.CheckForUpdate(MachineProvider.Machine.SerialNumber); + var response = await MachineUpdateManager.CheckForUpdate(); try { @@ -208,7 +208,7 @@ namespace Tango.PPC.UI.ViewModels } else { - _db_compare_result = await MachineUpdateManager.UpdateDBCheck(MachineProvider.Machine.SerialNumber); + _db_compare_result = await MachineUpdateManager.UpdateDBCheck(); if (_db_compare_result.RequiresUpdate) { @@ -261,7 +261,7 @@ namespace Tango.PPC.UI.ViewModels try { - await MachineUpdateManager.UpdateDB(_db_compare_result, MachineProvider.Machine.SerialNumber); + await MachineUpdateManager.UpdateDB(_db_compare_result); LogManager.Log("Database update completed."); await NavigateTo(MachineUpdateView.UpdateCompletedView); } diff --git a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/ProvisionMachine.xml b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/ProvisionMachine.xml index 8f60372b0..f3b845010 100644 Binary files a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/ProvisionMachine.xml and b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/ProvisionMachine.xml differ diff --git a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/UpdateMachine.xml b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/UpdateMachine.xml index 540b4cad9..260448394 100644 Binary files a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/UpdateMachine.xml and b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/UpdateMachine.xml differ diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 4215cd175..601438d67 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -390,7 +390,11 @@ namespace Tango.MachineService.Controllers if (hasDatabaseUpdates) { response.IsDatabaseUpdateAvailable = true; - response.UpdateDBResponse = UpdateDB(new UpdateDBRequest() { SerialNumber = request.SerialNumber }); + response.UpdateDBResponse = UpdateDB(new UpdateDBRequest() + { + ApplicationVersion = request.Version, + FirmwareVersion = request.FirmwareVersion + }); } //Compare database @@ -937,11 +941,11 @@ namespace Tango.MachineService.Controllers } else if (request.Mode == LoginMode.Machine) { - var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == request.SerialNumber); + var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == request.SerialNumber || x.Guid == request.MachineGuid); if (machine == null) { - throw new AuthenticationException("Invalid serial number."); + throw new AuthenticationException("Invalid machine serial number or id."); } response.AccessToken = WebToken.CreateNew(MachineServiceConfig.JWT_TOKEN_SECRET, new TokenObject() -- cgit v1.3.1 From 73d68112321587add7e22d89175fd1f12c34c6d1 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Fri, 25 Sep 2020 04:04:52 +0300 Subject: Improved Auth2 package and tested. Dropped "Stack trace not provided" message from TangoController. Retained job user round-trip from MS. --- .../PPC Installer-cache/cacheIndex.txt | Bin 52 -> 52 bytes .../Advanced Installer Projects/PPC Installer.aip | 125 +++++++++++++-------- .../Views/MachineJobSelectionView.xaml | 2 +- .../PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs | 2 +- .../Visual_Studio/PPC/Tango.PPC.UI/app.manifest | 2 +- .../Tango.PPC.Packages.Auth2/Auth2.cs | 37 +++++- .../Tango.PPC.Packages.Auth2.csproj | 4 + .../SQLExaminer/Configurations/UpdateMachine.xml | Bin 72920 -> 77930 bytes .../Tango.Web/Controllers/TangoController.cs | 2 +- .../Controllers/PPCController.cs | 4 +- .../Properties/AssemblyInfo.cs | 2 +- 11 files changed, 119 insertions(+), 61 deletions(-) (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer-cache/cacheIndex.txt b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer-cache/cacheIndex.txt index a603ff06b..5fe5afe5a 100644 Binary files a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer-cache/cacheIndex.txt and b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer-cache/cacheIndex.txt differ diff --git a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip index d1e783e61..7cd6c02b1 100644 --- a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip +++ b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip @@ -18,10 +18,10 @@ - + - + @@ -73,7 +73,9 @@ + + @@ -156,7 +158,6 @@ - @@ -164,6 +165,7 @@ + @@ -194,12 +196,14 @@ + + @@ -221,26 +225,28 @@ - - - - - - + + + + + + + + + + + + - - - - + + + + - - - - @@ -312,7 +318,6 @@ - @@ -502,6 +507,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -511,7 +548,7 @@ - + @@ -579,20 +616,6 @@ - - - - - - - - - - - - - - @@ -707,7 +730,6 @@ - @@ -791,20 +813,27 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml index c7e1d4130..a3d2dbd68 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml @@ -193,7 +193,7 @@ - + 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 de58aa679..b95219ad0 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs @@ -8,4 +8,4 @@ using System.Windows; // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Tango PPC Application")] -[assembly: AssemblyVersion("1.1.28.0")] +[assembly: AssemblyVersion("1.2.3.0")] diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest index efc5f8179..d72e75011 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest @@ -16,7 +16,7 @@ Remove this element if your application requires this virtualization for backwards compatibility. --> - + diff --git a/Software/Visual_Studio/PPC/UpdatePackages/Tango.PPC.Packages.Auth2/Auth2.cs b/Software/Visual_Studio/PPC/UpdatePackages/Tango.PPC.Packages.Auth2/Auth2.cs index c27391d90..6ba278511 100644 --- a/Software/Visual_Studio/PPC/UpdatePackages/Tango.PPC.Packages.Auth2/Auth2.cs +++ b/Software/Visual_Studio/PPC/UpdatePackages/Tango.PPC.Packages.Auth2/Auth2.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Tango.BL; using Tango.Core; @@ -10,7 +11,7 @@ using Tango.PPC.Shared.Updates; namespace Tango.PPC.Packages.Auth2 { - [PPCPackage(PackageType.Pre, "Auth 2", false)] + [PPCPackage(PackageType.Pre, "Applying Auth2 Patch", false)] public class Auth2 : ExtendedObject, IPPCPackage { public Task Run(PackageContext context) @@ -23,23 +24,49 @@ namespace Tango.PPC.Packages.Auth2 { using (var transaction = db.Database.BeginTransaction()) { - LogManager.Log("Removing all users..."); - context.ReportProgress("Modifying users..."); - db.Database.ExecuteSqlCommand("DELETE FROM USERS"); - LogManager.Log("Setting all jobs users to null..."); context.ReportProgress("Modifying jobs..."); db.Database.ExecuteSqlCommand("ALTER TABLE JOBS ALTER COLUMN USER_GUID VARCHAR(36) NULL"); db.Database.ExecuteSqlCommand("UPDATE JOBS SET USER_GUID = NULL"); + Thread.Sleep(1000); + LogManager.Log("Setting all job runs users to null..."); context.ReportProgress("Modifying job runs..."); db.Database.ExecuteSqlCommand("UPDATE JOB_RUNS SET USER_GUID = NULL"); + Thread.Sleep(1000); + LogManager.Log("Setting all events users to null..."); context.ReportProgress("Modifying events..."); db.Database.ExecuteSqlCommand("UPDATE MACHINES_EVENTS SET USER_GUID = NULL"); + Thread.Sleep(1000); + + LogManager.Log("Removing all users..."); + context.ReportProgress("Modifying users..."); + db.Database.ExecuteSqlCommand("DELETE FROM USERS"); + + Thread.Sleep(1000); + + LogManager.Log("Removing redundant addresses..."); + context.ReportProgress("Modifying addresses..."); + db.Database.ExecuteSqlCommand(@" +DELETE ADDRESSES FROM ADDRESSES +FULL JOIN ORGANIZATIONS ON ORGANIZATIONS.ADDRESS_GUID = ADDRESSES.GUID +WHERE ORGANIZATIONS.ADDRESS_GUID IS NULL"); + + Thread.Sleep(1000); + + LogManager.Log("Removing redundant contacts..."); + context.ReportProgress("Modifying contacts..."); + db.Database.ExecuteSqlCommand(@" +DELETE CONTACTS FROM CONTACTS +FULL JOIN ORGANIZATIONS ON ORGANIZATIONS.CONTACT_GUID = CONTACTS.GUID +WHERE ORGANIZATIONS.CONTACT_GUID IS NULL"); + + Thread.Sleep(1000); + LogManager.Log("Committing transaction..."); context.ReportProgress("Committing transaction..."); transaction.Commit(); diff --git a/Software/Visual_Studio/PPC/UpdatePackages/Tango.PPC.Packages.Auth2/Tango.PPC.Packages.Auth2.csproj b/Software/Visual_Studio/PPC/UpdatePackages/Tango.PPC.Packages.Auth2/Tango.PPC.Packages.Auth2.csproj index 721c61654..bd91c2b60 100644 --- a/Software/Visual_Studio/PPC/UpdatePackages/Tango.PPC.Packages.Auth2/Tango.PPC.Packages.Auth2.csproj +++ b/Software/Visual_Studio/PPC/UpdatePackages/Tango.PPC.Packages.Auth2/Tango.PPC.Packages.Auth2.csproj @@ -33,9 +33,11 @@ ..\..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + False ..\..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + False @@ -55,6 +57,7 @@ {F441FEEE-322A-4943-B566-110E12FD3B72} Tango.BL + False {A34EE0F0-649D-41C8-8489-B6F1CC6924EE} @@ -74,6 +77,7 @@ {208c8bd8-72c6-4e3c-acaa-351091a2acc7} Tango.PPC.Shared + False diff --git a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/UpdateMachine.xml b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/UpdateMachine.xml index 260448394..b70bc1ff4 100644 Binary files a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/UpdateMachine.xml and b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/UpdateMachine.xml differ diff --git a/Software/Visual_Studio/Tango.Web/Controllers/TangoController.cs b/Software/Visual_Studio/Tango.Web/Controllers/TangoController.cs index 3fd3d469e..b3df0373e 100644 --- a/Software/Visual_Studio/Tango.Web/Controllers/TangoController.cs +++ b/Software/Visual_Studio/Tango.Web/Controllers/TangoController.cs @@ -84,7 +84,7 @@ namespace Tango.Web.Controllers if (expandedExceptionValues != null) { - expandedExceptionValues["StackTrace"] = "StackTrace not provided."; + expandedExceptionValues["StackTrace"] = ""; } } #endif diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 601438d67..2c1c27f52 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -533,7 +533,6 @@ namespace Tango.MachineService.Controllers var job = dto.ToObservable(); job.ID = 0; - job.UserGuid = dto.UserGuid; job.CustomerGuid = null; job.IsSynchronized = true; @@ -546,6 +545,7 @@ namespace Tango.MachineService.Controllers } else if (job.LastUpdated > existingJob.LastUpdated) { + job.UserGuid = existingJob.UserGuid; existingJob.Delete(db); db.Jobs.Add(job); db.SaveChanges(); @@ -571,7 +571,6 @@ namespace Tango.MachineService.Controllers { var run = dto.ToObservable(); run.ID = 0; - run.UserGuid = dto.UserGuid; run.IsSynchronized = true; if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) @@ -600,7 +599,6 @@ namespace Tango.MachineService.Controllers { var ev = dto.ToObservable(); ev.ID = 0; - ev.UserGuid = dto.UserGuid; ev.IsSynchronized = true; if (db.MachinesEvents.SingleOrDefault(x => x.Guid == ev.Guid) == null) diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs index efa53fcdd..11c9ee72a 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.4.0")] +[assembly: AssemblyVersion("3.0.5.0")] -- cgit v1.3.1 From e8cec64cf5c35b17fed6a1f8f4ea0665d4ddf39b Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 21 Oct 2020 04:06:23 +0300 Subject: DataStore EF ! --- Software/DB/PPC/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/PPC/Tango_log.ldf | Bin 53673984 -> 53673984 bytes Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../DataStore/RemoteDataStoreCollection.cs | 38 ++++++- .../DataStore/DefaultDataStoreService.cs | 3 +- .../PPC/Tango.PPC.Common/Tango.PPC.Common.csproj | 6 +- .../Web/DownloadMachineDataRequest.cs | 2 + .../Web/DownloadMachineDataResponse.cs | 2 + .../NotifyMachineDataDownloadCompletedRequest.cs | 2 + .../Web/UploadMachineDataRequest.cs | 2 + .../Web/UploadMachineDataResponse.cs | 3 + .../Tango.DataStore.EF/EFDataStoreCollection.cs | 117 +++++++++++++++++++++ .../Tango.DataStore.EF/EFDataStoreHelper.cs | 80 ++++++++++++++ .../Tango.DataStore.EF/EFDataStoreItem.cs | 28 +++++ .../Tango.DataStore.EF/EFDataStoreManager.cs | 33 ++++++ .../Tango.DataStore.EF/ExtensionMethods.cs | 22 ++++ .../Tango.DataStore.EF/Properties/AssemblyInfo.cs | 7 ++ .../Tango.DataStore.EF/Tango.DataStore.EF.csproj | 82 +++++++++++++++ .../Tango.DataStore.EF/packages.config | 5 + .../LiteDBDataStoreCollection.cs | 8 +- .../Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs | 7 ++ .../Tango.DataStore/IDataStoreCollection.cs | 5 + .../Tango.DataStore/IDataStoreItem.cs | 10 ++ .../Tango.Emulations/Emulators/MachineEmulator.cs | 12 +-- .../Tango.UnitTesting/Tango.UnitTesting.csproj | 6 +- Software/Visual_Studio/Tango.sln | 34 ++++-- .../Controllers/PPCController.cs | 89 +++++++++++++--- .../Properties/AssemblyInfo.cs | 2 +- 29 files changed, 567 insertions(+), 38 deletions(-) create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj create mode 100644 Software/Visual_Studio/Tango.DataStore.EF/packages.config (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/DB/PPC/Tango.mdf b/Software/DB/PPC/Tango.mdf index 04e72ca45..77b6f4120 100644 Binary files a/Software/DB/PPC/Tango.mdf and b/Software/DB/PPC/Tango.mdf differ diff --git a/Software/DB/PPC/Tango_log.ldf b/Software/DB/PPC/Tango_log.ldf index e8aac16f8..4cfc85ea4 100644 Binary files a/Software/DB/PPC/Tango_log.ldf and b/Software/DB/PPC/Tango_log.ldf differ diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 47b8e26d2..4e178ad92 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 88b1f2c1d..6e0fefa06 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs index 323a1b550..b7325cd48 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/DataStore/RemoteDataStoreCollection.cs @@ -60,27 +60,55 @@ namespace Tango.FSE.UI.DataStore public List GetAll() { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreGetAllRequest() + { + Collection = Name + }).Result; + + return result.Items; } public void Delete(string key) { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreDeleteRequest() + { + Collection = Name, + Key = key + }).Result; } public void DeleteAll() { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreDeleteAllRequest() + { + Collection = Name, + }).Result; } public int Count() { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreCountRequest() + { + Collection = Name + }).Result; + + return result.Count; } public IDataStoreItem GetItem(string key) { - throw new NotImplementedException(); + var result = _machineProvider.MachineOperator.SendGenericRequest(new RemoteDataStoreGetItemRequest() + { + Collection = Name, + Key = key + }).Result; + + return result.Item; + } + + public List GetUnsynchronized() + { + return GetAll().Where(x => !x.IsSynchronized).ToList(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs index 02d8e1858..e5bec90f2 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/DataStore/DefaultDataStoreService.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading.Tasks; using Tango.Core.DI; using Tango.DataStore; +using Tango.DataStore.EF; using Tango.DataStore.Lite; using Tango.DataStore.Remote; using Tango.Integration.ExternalBridge; @@ -34,7 +35,7 @@ namespace Tango.PPC.Common.DataStore { if (_manager == null) { - _manager = new LiteDBDataStoreManager(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "DataStore", Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName) + ".db")); + _manager = new EFDataStoreManager(); } return _manager; 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 fec0dfd1a..0a6e57f5d 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 @@ -383,6 +383,10 @@ {58e8825f-0c96-449c-b320-1e82b0aa876b} Tango.CSV + + {88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4} + Tango.DataStore.EF + {fa96bc0c-4055-475c-9dcc-70a5a9436b10} Tango.DataStore.Lite @@ -507,7 +511,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs index 66fca8e36..bbb0e883b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataRequest.cs @@ -14,9 +14,11 @@ namespace Tango.PPC.Common.Web public bool RequestJobs { get; set; } public bool RequestJobRuns { get; set; } public bool RequestMachineEvents { get; set; } + public bool RequestDataStoreItems { get; set; } public int MaxJobs { get; set; } public int MaxJobRuns { get; set; } public int MaxMachinesEvents { get; set; } + public int MaxDataStoreItems { get; set; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs index 5c3f7ba78..e90c7c2ac 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/DownloadMachineDataResponse.cs @@ -14,12 +14,14 @@ namespace Tango.PPC.Common.Web public List Jobs { get; set; } public List JobRuns { get; set; } public List MachineEvents { get; set; } + public List DataStoreItems { get; set; } public DownloadMachineDataResponse() { Jobs = new List(); JobRuns = new List(); MachineEvents = new List(); + DataStoreItems = new List(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs index fc135c234..fda7a4666 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/NotifyMachineDataDownloadCompletedRequest.cs @@ -14,12 +14,14 @@ namespace Tango.PPC.Common.Web public List SynchronizedJobs { get; set; } public List SynchronizedJobRuns { get; set; } public List SynchronizedMachineEvents { get; set; } + public List SynchronizedDataStoreItems { get; set; } public NotifyMachineDataDownloadCompletedRequest() { SynchronizedJobs = new List(); SynchronizedJobRuns = new List(); SynchronizedMachineEvents = new List(); + SynchronizedDataStoreItems = new List(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs index d7475819c..8eee667cd 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataRequest.cs @@ -15,6 +15,7 @@ namespace Tango.PPC.Common.Web public List JobRuns { get; set; } public List MachineEvents { get; set; } public List OfflineUpdates { get; set; } + public List DataStoreItems { get; set; } public String ApplicationVersion { get; set; } public String FirmwareVersion { get; set; } @@ -24,6 +25,7 @@ namespace Tango.PPC.Common.Web JobRuns = new List(); MachineEvents = new List(); OfflineUpdates = new List(); + DataStoreItems = new List(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs index 0119c07b6..ba0b4089b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/UploadMachineDataResponse.cs @@ -15,6 +15,8 @@ namespace Tango.PPC.Common.Web public List FailedJobRuns { get; set; } public List FailedMachineEvents { get; set; } public List FailedOfflineUpdates { get; set; } + public List FailedDataStoreItems { get; set; } + public String NotifyCompletedToken { get; set; } public UploadMachineDataResponse() @@ -23,6 +25,7 @@ namespace Tango.PPC.Common.Web FailedJobRuns = new List(); FailedMachineEvents = new List(); FailedOfflineUpdates = new List(); + FailedDataStoreItems = new List(); } } } diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs new file mode 100644 index 000000000..769533445 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs @@ -0,0 +1,117 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; + +namespace Tango.DataStore.EF +{ + public class EFDataStoreCollection : IDataStoreCollection + { + public string Name { get; } + + public EFDataStoreCollection(String name) + { + Name = name; + } + + public void Put(string key, T value) + { + Put(key, (object)value); + } + + public void Put(string key, object value) + { + Put(key, DataStoreHelper.GetDataType(value), value); + } + + public void Put(string key, DataType type, object value) + { + using (var db = ObservablesContext.CreateDefault()) + { + DataStoreItem item = db.DataStoreItems.SingleOrDefault(x => x.CollectionName == Name && x.Key == key); + + if (item == null) + { + item = new DataStoreItem(); + db.DataStoreItems.Add(item); + } + + item.CollectionName = Name; + item.Key = key; + item.DataType = (int)type; + item.Value = EFDataStoreHelper.CreateBytes(type, value); + + db.SaveChanges(); + } + } + + public T Get(string key) + { + return (T)Get(key); + } + + public object Get(string key) + { + return GetItem(key).Value; + } + + public IDataStoreItem GetItem(string key) + { + using (var db = ObservablesContext.CreateDefault()) + { + var item = db.DataStoreItems.SingleOrDefault(x => x.CollectionName == Name && x.Key == key); + + if (item == null) + { + throw new KeyNotFoundException("The specified data store key was not found."); + } + + return item.ToDataStoreItem(); + } + } + + public List GetAll() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Where(x => x.CollectionName == Name).ToList().Select(x => x.ToDataStoreItem()).ToList(); + } + } + + public List GetUnsynchronized() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Where(x => x.CollectionName == Name && !x.IsSynchronized).ToList().Select(x => x.ToDataStoreItem()).ToList(); + } + } + + public void Delete(string key) + { + using (var db = ObservablesContext.CreateDefault()) + { + db.Database.ExecuteSqlCommand($"DELETE FROM DATA_STORE_ITEMS WHERE COLLECTION_NAME = '{Name}' AND KEY = '{key}'"); + } + } + + public void DeleteAll() + { + using (var db = ObservablesContext.CreateDefault()) + { + db.Database.ExecuteSqlCommand($"DELETE FROM DATA_STORE_ITEMS WHERE COLLECTION_NAME = '{Name}'"); + } + } + + public int Count() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Count(x => x.CollectionName == Name); + } + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs new file mode 100644 index 000000000..c51c54b7c --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreHelper.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; + +namespace Tango.DataStore.EF +{ + public static class EFDataStoreHelper + { + public static byte[] CreateBytes(DataType type, Object obj) + { + switch (type) + { + case DataType.Int32: + return BitConverter.GetBytes((int)obj); + case DataType.Float: + return BitConverter.GetBytes((float)obj); + case DataType.Double: + return BitConverter.GetBytes((double)obj); + case DataType.Boolean: + return BitConverter.GetBytes((bool)obj); + case DataType.String: + return Encoding.Default.GetBytes(obj.ToString()); + case DataType.Bytes: + return (byte[])obj; + } + + throw new NotSupportedException("The specified type is not supported."); + } + + public static Object CreateObject(DataType type, byte[] bytes) + { + switch (type) + { + case DataType.Int32: + return BitConverter.ToInt32(bytes, 0); + case DataType.Float: + return BitConverter.ToSingle(bytes, 0); + case DataType.Double: + return BitConverter.ToDouble(bytes, 0); + case DataType.Boolean: + return BitConverter.ToBoolean(bytes, 0); + case DataType.String: + return Encoding.Default.GetString(bytes); + case DataType.Bytes: + return bytes; + } + + throw new NotSupportedException("The specified type is not supported."); + } + + public static IDataStoreItem CreateDataStoreItem(DataStoreItem item) + { + return new EFDataStoreItem() + { + Guid = item.Guid, + Date = item.LastUpdated, + IsSynchronized = item.IsSynchronized, + Key = item.Key, + Type = (DataType)item.DataType, + Value = CreateObject((DataType)item.DataType, item.Value) + }; + } + + public static DataStoreItem CreateDbDataStoreItem(IDataStoreItem item) + { + return new DataStoreItem() + { + Guid = item.Guid, + LastUpdated = item.Date, + IsSynchronized = item.IsSynchronized, + Key = item.Key, + DataType = (int)item.Type, + Value = CreateBytes(item.Type, item.Value) + }; + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs new file mode 100644 index 000000000..45061c7ef --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreItem.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.DataStore.EF +{ + public class EFDataStoreItem : IDataStoreItem + { + public string Guid { get; set; } + public string Key { get; set; } + public DataType Type { get; set; } + public object Value { get; set; } + public DateTime Date { get; set; } + public bool IsSynchronized { get; set; } + + public EFDataStoreItem() + { + Guid = System.Guid.NewGuid().ToString(); + } + + public override string ToString() + { + return $"{Key}: {Value}"; + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs new file mode 100644 index 000000000..4314a25f9 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreManager.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; + +namespace Tango.DataStore.EF +{ + public class EFDataStoreManager : IDataStoreManager + { + public IDataStoreCollection GetCollection(string name) + { + using (var db = ObservablesContext.CreateDefault()) + { + return new EFDataStoreCollection(name); + } + } + + public List GetCollectionNames() + { + using (var db = ObservablesContext.CreateDefault()) + { + return db.DataStoreItems.Select(x => x.CollectionName).Distinct().ToList(); + } + } + + public void Dispose() + { + //DO Nothing. + } + } +} diff --git a/Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs b/Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs new file mode 100644 index 000000000..361a37a7c --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/ExtensionMethods.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.DataStore; +using Tango.DataStore.EF; + +public static class ExtensionMethods +{ + public static IDataStoreItem ToDataStoreItem(this DataStoreItem item) + { + return EFDataStoreHelper.CreateDataStoreItem(item); + } + + public static DataStoreItem ToDbDataStoreItem(this IDataStoreItem item) + { + return EFDataStoreHelper.CreateDbDataStoreItem(item); + } +} + diff --git a/Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..c59e45461 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Tango - Data Store Entity Framework Implementation")] +[assembly: AssemblyVersion("2.0.4.1608")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj b/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj new file mode 100644 index 000000000..53e288584 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/Tango.DataStore.EF.csproj @@ -0,0 +1,82 @@ + + + + + Debug + AnyCPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4} + Library + Properties + Tango.DataStore.EF + Tango.DataStore.EF + v4.6.1 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + + GlobalVersionInfo.cs + + + + + + + + + + + + + + {f441feee-322a-4943-b566-110e12fd3b72} + Tango.BL + + + {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} + Tango.Core + + + {e0364dfa-0721-4637-9d32-9d22aac109d6} + Tango.DataStore + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.EF/packages.config b/Software/Visual_Studio/Tango.DataStore.EF/packages.config new file mode 100644 index 000000000..1127d4e32 --- /dev/null +++ b/Software/Visual_Studio/Tango.DataStore.EF/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs index 9c939797a..e61385ab8 100644 --- a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs +++ b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreCollection.cs @@ -35,7 +35,8 @@ namespace Tango.DataStore.Lite Key = key, Date = DateTime.UtcNow, Type = type, - Value = value + Value = value, + IsSynchronized = false, }); } @@ -80,5 +81,10 @@ namespace Tango.DataStore.Lite { return _collection.FindById(key); } + + public List GetUnsynchronized() + { + return _collection.Find(x => !x.IsSynchronized).ToList(); + } } } diff --git a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs index 6a5a44462..544a15b61 100644 --- a/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs +++ b/Software/Visual_Studio/Tango.DataStore.LiteDB/LiteDBDataStoreItem.cs @@ -9,11 +9,18 @@ namespace Tango.DataStore.Lite { public class LiteDBDataStoreItem : IDataStoreItem { + public String Guid { get; set; } [BsonId] public string Key { get; set; } public DataType Type { get; set; } public object Value { get; set; } public DateTime Date { get; set; } + public bool IsSynchronized { get; set; } + + public LiteDBDataStoreItem() + { + Guid = System.Guid.NewGuid().ToString(); + } public override string ToString() { diff --git a/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs index 45f5d3406..e73d02328 100644 --- a/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs +++ b/Software/Visual_Studio/Tango.DataStore/IDataStoreCollection.cs @@ -61,6 +61,11 @@ namespace Tango.DataStore /// List GetAll(); /// + /// Gets all the data store unsynchronized items in the collection. + /// + /// + List GetUnsynchronized(); + /// /// Deleted an item by the specified key. /// /// The key. diff --git a/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs b/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs index 1e58518ff..9c03f40ee 100644 --- a/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs +++ b/Software/Visual_Studio/Tango.DataStore/IDataStoreItem.cs @@ -11,6 +11,11 @@ namespace Tango.DataStore /// public interface IDataStoreItem { + /// + /// Gets or sets the unique identifier (Use only for synchronization). + /// + String Guid { get; set; } + /// /// Gets or sets item id. /// @@ -30,5 +35,10 @@ namespace Tango.DataStore /// Gets or sets the item update UTC date. /// DateTime Date { get; set; } + + /// + /// Gets or sets a value indicating whether this item is synchronized with the remote service. + /// + bool IsSynchronized { get; set; } } } diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs index 0c47f5e34..f8682dd18 100644 --- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs +++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs @@ -1786,7 +1786,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "int", DataType = DataType.Int32, @@ -1826,7 +1826,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "float", DataType = DataType.Float, @@ -1866,7 +1866,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "double", DataType = DataType.Double, @@ -1906,7 +1906,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "bool", DataType = DataType.Boolean, @@ -1946,7 +1946,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "string", DataType = DataType.String, @@ -1986,7 +1986,7 @@ namespace Tango.Emulations.Emulators var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", - Item = new DataStoreItem() + Item = new PMR.DataStore.DataStoreItem() { Key = "bytes", DataType = DataType.Bytes, diff --git a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj index 218652c1b..0371c1cca 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj +++ b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj @@ -213,6 +213,10 @@ {38197109-8610-4d3f-92b9-16d48df94d7c} Tango.DAL.Remote + + {88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4} + Tango.DataStore.EF + {fa96bc0c-4055-475c-9dcc-70a5a9436b10} Tango.DataStore.Lite @@ -315,7 +319,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln index c77985b68..615dc2154 100644 --- a/Software/Visual_Studio/Tango.sln +++ b/Software/Visual_Studio/Tango.sln @@ -425,6 +425,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.Lite", "Tan EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.Remote", "Tango.DataStore.Remote\Tango.DataStore.Remote.csproj", "{29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.DataStore.EF", "Tango.DataStore.EF\Tango.DataStore.EF.csproj", "{88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -4012,6 +4014,26 @@ Global {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}.Release|x64.Build.0 = Release|Any CPU {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}.Release|x86.ActiveCfg = Release|Any CPU {29448F3C-9B3E-4DA6-8555-46A8B9A6B3AA}.Release|x86.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|ARM64.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x64.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x64.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x86.ActiveCfg = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Debug|x86.Build.0 = Debug|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|Any CPU.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM64.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|ARM64.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x64.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x64.Build.0 = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x86.ActiveCfg = Release|Any CPU + {88D9906B-8FC4-4FE0-B7EB-127A0A8FCEE4}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -4157,12 +4179,12 @@ Global {EA4233F1-4B7B-4CCF-A6DE-2D17612EBA90} = {E728CBD9-1AF4-4814-A218-E4BD26E7EDEA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} - BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear - BuildVersion_UpdateAssemblyVersion = True - BuildVersion_UpdateFileVersion = False - BuildVersion_StartDate = 2000/1/1 - BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs BuildVersion_UseGlobalSettings = False + BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs + BuildVersion_StartDate = 2000/1/1 + BuildVersion_UpdateFileVersion = False + BuildVersion_UpdateAssemblyVersion = True + BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear + SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} EndGlobalSection EndGlobal diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 2c1c27f52..2eb2b01c4 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -562,26 +562,38 @@ namespace Tango.MachineService.Controllers } } - //Insert JobRuns. - foreach (var dto in request.JobRuns) + //Insert Update DataStore Items + foreach (var dto in request.DataStoreItems) { using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { try { - var run = dto.ToObservable(); - run.ID = 0; - run.IsSynchronized = true; + var dataStoreItem = dto.ToObservable(); + dataStoreItem.MachineGuid = RequestToken.Object.MachineGuid; - if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) + dataStoreItem.ID = 0; + dataStoreItem.IsSynchronized = true; + + var existingItem = db.DataStoreItems.SingleOrDefault(x => x.Guid == dataStoreItem.Guid); + + if (existingItem == null) { - db.JobRuns.Add(run); + db.DataStoreItems.Add(dataStoreItem); + db.SaveChanges(); + } + else if (dataStoreItem.LastUpdated > existingItem.LastUpdated) + { + existingItem.DataType = dataStoreItem.DataType; + existingItem.Value = dataStoreItem.Value; + existingItem.IsSynchronized = true; + existingItem.LastUpdated = dataStoreItem.LastUpdated; db.SaveChanges(); } } catch (Exception ex) { - response.FailedJobRuns.Add(new SynchronizationFailedEntity() + response.FailedDataStoreItems.Add(new SynchronizationFailedEntity() { Guid = dto.Guid, Reason = ex.FlattenMessage(), @@ -590,26 +602,26 @@ namespace Tango.MachineService.Controllers } } - //Insert MachineEvents. - foreach (var dto in request.MachineEvents) + //Insert JobRuns. + foreach (var dto in request.JobRuns) { using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { try { - var ev = dto.ToObservable(); - ev.ID = 0; - ev.IsSynchronized = true; + var run = dto.ToObservable(); + run.ID = 0; + run.IsSynchronized = true; - if (db.MachinesEvents.SingleOrDefault(x => x.Guid == ev.Guid) == null) + if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) { - db.MachinesEvents.Add(ev); + db.JobRuns.Add(run); db.SaveChanges(); } } catch (Exception ex) { - response.FailedMachineEvents.Add(new SynchronizationFailedEntity() + response.FailedJobRuns.Add(new SynchronizationFailedEntity() { Guid = dto.Guid, Reason = ex.FlattenMessage(), @@ -645,6 +657,34 @@ namespace Tango.MachineService.Controllers } } } + + //Insert MachineEvents. + foreach (var dto in request.MachineEvents) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + try + { + var ev = dto.ToObservable(); + ev.ID = 0; + ev.IsSynchronized = true; + + if (db.MachinesEvents.SingleOrDefault(x => x.Guid == ev.Guid) == null) + { + db.MachinesEvents.Add(ev); + db.SaveChanges(); + } + } + catch (Exception ex) + { + response.FailedMachineEvents.Add(new SynchronizationFailedEntity() + { + Guid = dto.Guid, + Reason = ex.FlattenMessage(), + }); + } + } + } } catch (Exception ex) { @@ -711,6 +751,18 @@ namespace Tango.MachineService.Controllers response.MachineEvents.Add(dto); } } + + //Send DataStore Items + if (request.RequestDataStoreItems) + { + var dataStoreItems = db.DataStoreItems.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxDataStoreItems).OrderByDescending(x => x.LastUpdated).ToList(); + + foreach (var item in dataStoreItems) + { + DataStoreItemDTO dto = DataStoreItemDTO.FromObservable(item); + response.DataStoreItems.Add(dto); + } + } } return response; @@ -745,6 +797,11 @@ namespace Tango.MachineService.Controllers { db.Database.ExecuteSqlCommand($"UPDATE MACHINES_EVENTS SET IS_SYNCHRONIZED = 1 WHERE GUID IN ({String.Join(",", request.SynchronizedMachineEvents.Select(x => "'" + x + "'"))});"); } + + if (request.SynchronizedDataStoreItems.Count > 0) + { + db.Database.ExecuteSqlCommand($"UPDATE DATA_STORE_ITEMS SET IS_SYNCHRONIZED = 1 WHERE GUID IN ({String.Join(",", request.SynchronizedDataStoreItems.Select(x => "'" + x + "'"))});"); + } } return response; diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs index 11c9ee72a..41fa77771 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.5.0")] +[assembly: AssemblyVersion("3.0.6.0")] -- cgit v1.3.1 From 573eed2d8575a29d09c9602acf1f2765adc9abcb Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 21 Oct 2020 05:10:59 +0300 Subject: DataStore Synchronization ! --- .../DefaultMachineDataSynchronizer.cs | 77 ++++++++++++++++++++++ .../Tango.DataStore.EF/EFDataStoreCollection.cs | 2 + .../Controllers/PPCController.cs | 2 +- 3 files changed, 80 insertions(+), 1 deletion(-) (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs index 645ddbdf5..4ffb6b751 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Synchronization/DefaultMachineDataSynchronizer.cs @@ -41,6 +41,7 @@ namespace Tango.PPC.Common.Synchronization public int MaxJobRuns { get; set; } public int MaxMachinesEvents { get; set; } public int MaxOfflineUpdates { get; set; } + public int MaxDataStoreItems { get; set; } private SynchronizationStatus _currentStatus; public SynchronizationStatus CurrentStatus @@ -82,6 +83,7 @@ namespace Tango.PPC.Common.Synchronization MaxJobRuns = 10; MaxMachinesEvents = 10; MaxOfflineUpdates = 10; + MaxDataStoreItems = 100; var settings = SettingsManager.Default.GetOrCreate(); Interval = settings.SynchronizationInterval; @@ -207,6 +209,21 @@ namespace Tango.PPC.Common.Synchronization request.OfflineUpdates.Add(dto); } } + + { //Always synchronize data store items + LogManager.Log("Checking Data Store Items..."); + + var dataStoreItems = await db.DataStoreItems.Where(x => !x.IsSynchronized).Take(MaxDataStoreItems).ToListAsync(); + List dtos = new List(); + + foreach (var item in dataStoreItems) + { + item.IsSynchronized = true; + var dto = DataStoreItemDTO.FromObservable(item); + dto.MachineGuid = null; + request.DataStoreItems.Add(dto); + } + } } return request; @@ -280,6 +297,22 @@ namespace Tango.PPC.Common.Synchronization } } + //Finalize data store items + foreach (var dataStoreItem in request.DataStoreItems) + { + var failedDataStoreItem = response.FailedDataStoreItems.SingleOrDefault(x => x.Guid == dataStoreItem.Guid); + + if (failedDataStoreItem == null) + { + var dbDataStoreItem = await db.DataStoreItems.SingleOrDefaultAsync(x => x.Guid == dataStoreItem.Guid); + dbDataStoreItem.IsSynchronized = true; + } + else + { + LogManager.Log($"Synchronization Error - DataStoreItem '{dataStoreItem.Key}' cannot be stored on the server due to the following reason:\n{failedDataStoreItem.Reason}", LogCategory.Error); + } + } + await db.SaveChangesAsync(); } } @@ -291,9 +324,11 @@ namespace Tango.PPC.Common.Synchronization RequestJobs = syncJobs, RequestJobRuns = syncDiagnostics, RequestMachineEvents = syncDiagnostics, + RequestDataStoreItems = true, MaxJobs = MaxJobs, MaxJobRuns = MaxJobRuns, MaxMachinesEvents = MaxMachinesEvents, + MaxDataStoreItems = MaxDataStoreItems, }); } @@ -342,6 +377,48 @@ namespace Tango.PPC.Common.Synchronization } } + //Insert/Update Data Store Items. + if (response.DataStoreItems.Count > 0) + { + LogManager.Log("Inserting/Updating Data Store Items..."); + } + foreach (var dto in response.DataStoreItems) + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + try + { + var dataStoreItem = dto.ToObservable(); + + dataStoreItem.ID = 0; + dataStoreItem.MachineGuid = null; + dataStoreItem.IsSynchronized = true; + + var existingItem = db.DataStoreItems.SingleOrDefault(x => x.Guid == dataStoreItem.Guid); + + if (existingItem == null) + { + db.DataStoreItems.Add(dataStoreItem); + db.SaveChanges(); + } + else if (dataStoreItem.LastUpdated >= existingItem.LastUpdated) + { + existingItem.DataType = dataStoreItem.DataType; + existingItem.Value = dataStoreItem.Value; + existingItem.IsSynchronized = true; + existingItem.LastUpdated = dataStoreItem.LastUpdated; + db.SaveChanges(); + } + + request.SynchronizedDataStoreItems.Add(dataStoreItem.Guid); + } + catch (Exception ex) + { + LogManager.Log($"Synchronization Error - DataStoreItem '{dto.Key}' cannot be stored locally due to the following reason:\n{ex.FlattenMessage()}", LogCategory.Error); + } + } + } + //Insert JobRuns. if (response.JobRuns.Count > 0) { diff --git a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs index 2a02bbd5b..eab6ef377 100644 --- a/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs +++ b/Software/Visual_Studio/Tango.DataStore.EF/EFDataStoreCollection.cs @@ -44,6 +44,8 @@ namespace Tango.DataStore.EF item.Key = key; item.DataType = (int)type; item.Value = EFDataStoreHelper.CreateBytes(type, value); + item.IsSynchronized = false; + item.LastUpdated = DateTime.UtcNow; db.SaveChanges(); } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 2eb2b01c4..fbc4f8a0a 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -582,7 +582,7 @@ namespace Tango.MachineService.Controllers db.DataStoreItems.Add(dataStoreItem); db.SaveChanges(); } - else if (dataStoreItem.LastUpdated > existingItem.LastUpdated) + else if (dataStoreItem.LastUpdated >= existingItem.LastUpdated) { existingItem.DataType = dataStoreItem.DataType; existingItem.Value = dataStoreItem.Value; -- cgit v1.3.1