aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate')
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs59
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs1451
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs13
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs13
4 files changed, 210 insertions, 1326 deletions
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 7c835165f..85d61d4cc 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs
@@ -4,27 +4,12 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.PMR.Synchronization;
-using Tango.PPC.Common.Publish;
-using Tango.PPC.Common.UpdatePackages;
using Tango.PPC.Common.Web;
namespace Tango.PPC.Common.MachineUpdate
{
public interface IMachineUpdateManager
{
- /// <summary>
- /// Occurs when an application update is available.
- /// </summary>
- event EventHandler<CheckForUpdateResponse> UpdateAvailable;
-
- /// <summary>
- /// Gets or sets a value indicating whether to automatically check for new application updates.
- /// </summary>
- bool EnableAutoCheckForUpdates { get; set; }
-
- /// <summary>
- /// Gets the current machine update progress status.
- /// </summary>
MachineUpdateProgress Status { get; }
/// <summary>
@@ -38,68 +23,46 @@ namespace Tango.PPC.Common.MachineUpdate
event EventHandler<MachineUpdateProgress> Progress;
/// <summary>
- /// Performs a machine update.
+ /// Performs a machine update using the specified serial number and machine service address.
/// </summary>
+ /// <param name="serialNumber">The serial number.</param>
/// <param name="setupFirmware">if set to <c>true</c> updates the embedded device firmware.</param>
/// <param name="setupFPGA">if set to <c>true</c> updates the embedded device FPGA version and other parameters.</param>
/// <returns></returns>
- Task<MachineUpdateResult> Update(bool setupFirmware, bool setupFPGA);
+ Task<MachineUpdateResult> Update(String serialNumber, bool setupFirmware, bool setupFPGA);
/// <summary>
/// Performs a machine update using the specified software update package path.
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <returns></returns>
- Task<MachineUpdateResult> UpdateFromTUP(String fileName, bool setupFirmware, bool setupFPGA);
-
- /// <summary>
- /// Performs a firmware upgrade from the specified TFP file.
- /// </summary>
- /// <param name="fileName">Name of the file.</param>
- /// <returns></returns>
- Task UpdateFromTFP(String fileName);
+ Task<MachineUpdateResult> UpdateFromTUP(String fileName);
/// <summary>
- /// Checks if any update are available.
+ /// Checks if any update are available for the specified machine serial number.
/// </summary>
+ /// <param name="serialNumber">The serial number.</param>
/// <returns></returns>
- Task<CheckForUpdateResponse> CheckForUpdate();
+ Task<CheckForUpdateResponse> CheckForUpdate(String serialNumber);
/// <summary>
/// Checks whether it is necessary to updates all the "overwrite-able" database tables.
/// </summary>
+ /// <param name="serialNumber">The serial number.</param>
/// <returns></returns>
- Task<DbCompareResult> UpdateDBCheck();
+ Task<DbCompareResult> UpdateDBCheck(String serialNumber);
/// <summary>
/// Updates all the "overwrite-able" database tables.
/// </summary>
/// <returns></returns>
- Task UpdateDB(DbCompareResult dbCompareResult);
+ Task UpdateDB(DbCompareResult dbCompareResult, String serialNumber);
/// <summary>
/// Gets the update package file information.
/// </summary>
/// <param name="filePath">The file path.</param>
/// <returns></returns>
- Task<PublishInfo> GetUpdatePackageFileInfo(String filePath);
-
- /// <summary>
- /// Checks whether any post update packages needs to be installed.
- /// </summary>
- /// <returns></returns>
- Task<bool> PostUpdatePackagesRequired();
-
- /// <summary>
- /// Runs all post update packages.
- /// </summary>
- /// <returns></returns>
- Task<PackageRunnerResult> RunPostUpdatePackages();
-
- /// <summary>
- /// Restores the last database backup.
- /// </summary>
- /// <returns></returns>
- Task RestoreLastDatabaseBackup();
+ Task<UpdatePackageFile> GetUpdatePackageFileInfo(String filePath);
}
}
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 c115f4f5b..b7573ec60 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs
@@ -9,8 +9,6 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using Tango.BL;
-using Tango.BL.Entities;
using Tango.Core;
using Tango.Core.DB;
using Tango.Core.ExtensionMethods;
@@ -18,48 +16,26 @@ using Tango.Core.Helpers;
using Tango.Core.IO;
using Tango.Integration.Operation;
using Tango.Integration.Upgrade;
-using Tango.Logging;
using Tango.PMR.Synchronization;
using Tango.PPC.Common.Application;
using Tango.PPC.Common.Connection;
-using Tango.PPC.Common.Navigation;
-using Tango.PPC.Common.Publish;
-using Tango.PPC.Common.UpdatePackages;
using Tango.PPC.Common.Web;
using Tango.Settings;
using Tango.SharedUI.Helpers;
using Tango.SQLExaminer;
using Tango.Transport.Web;
-using System.Data.Entity;
-using Tango.PPC.Common.ExternalBridge;
-using Tango.Integration.ExternalBridge;
-using Tango.BL.DTO;
-using Tango.PPC.Shared.Updates;
-using Tango.PPC.Shared.RemoteUpgrade;
-using Tango.Core.Threading;
namespace Tango.PPC.Common.MachineUpdate
{
- public class MachineUpdateManager : ExtendedObject, IMachineUpdateManager, IExternalBridgeRequestHandler
+ public class MachineUpdateManager : ExtendedObject, IMachineUpdateManager
{
private IPPCApplicationManager _app_manager;
private IMachineProvider _machineProvider;
- private IPackageRunner _packageRunner;
private PPCWebClient _client;
- private List<LogItemBase> _logs;
- private System.Timers.Timer _checkForUpdateTimer;
- private bool _isUpdating;
- private PPCSettings _settings;
- private DateTime _updateStartDate;
#region Events
/// <summary>
- /// Occurs when an application update is available.
- /// </summary>
- public event EventHandler<CheckForUpdateResponse> UpdateAvailable;
-
- /// <summary>
/// Occurs when there is a text log message available.
/// </summary>
public event EventHandler<string> ProgressLog;
@@ -74,25 +50,12 @@ namespace Tango.PPC.Common.MachineUpdate
#region Properties
private MachineUpdateProgress _status;
- /// <summary>
- /// Gets the current machine update progress status.
- /// </summary>
public MachineUpdateProgress Status
{
get { return _status; }
private set { _status = value; RaisePropertyChangedAuto(); }
}
- private bool _autoCheckForUpdates;
- /// <summary>
- /// Gets or sets a value indicating whether to automatically check for new application updates.
- /// </summary>
- public bool EnableAutoCheckForUpdates
- {
- get { return _autoCheckForUpdates; }
- set { _autoCheckForUpdates = value; RaisePropertyChangedAuto(); }
- }
-
#endregion
#region Constructors
@@ -101,531 +64,23 @@ namespace Tango.PPC.Common.MachineUpdate
/// Initializes a new instance of the <see cref="MachineUpdateManager"/> class.
/// </summary>
/// <param name="applicationManager">The application manager.</param>
- public MachineUpdateManager(PPCWebClient ppcWebClient, IPPCApplicationManager applicationManager, IMachineProvider machineProvider, IPackageRunner packageRunner, IPPCExternalBridgeService externalBridge)
+ public MachineUpdateManager(PPCWebClient ppcWebClient, IPPCApplicationManager applicationManager, IMachineProvider machineProvider)
{
_client = ppcWebClient;
_machineProvider = machineProvider;
_app_manager = applicationManager;
- _app_manager.ApplicationReady += _app_manager_ApplicationReady;
- _packageRunner = packageRunner;
- _packageRunner.PackageProgress += _packageRunner_PackageProgress;
-
- _logs = new List<LogItemBase>();
- LogManager.NewLog += LogManager_NewLog;
-
- _settings = SettingsManager.Default.GetOrCreate<PPCSettings>();
-
- _checkForUpdateTimer = new System.Timers.Timer(_settings.AutoUpdateCheckInterval.TotalMilliseconds);
- _checkForUpdateTimer.Elapsed += _checkForUpdateTimer_Elapsed;
- _checkForUpdateTimer.Stop();
-
- externalBridge.RegisterRequestHandler(this);
- }
-
- #endregion
-
- #region Event Handlers
-
- private void _app_manager_ApplicationReady(object sender, EventArgs e)
- {
- _checkForUpdateTimer.Start();
-
- if (!_app_manager.IsUpdateFailed)
- {
- ClearLastDatabaseBackup();
- }
- }
-
- private void _packageRunner_PackageProgress(object sender, PackageProgressEventArgs e)
- {
- UpdateProgress(e.PackageName, e.Message, e.IsIntermediate, e.Progress, e.Total);
- }
-
- private void LogManager_NewLog(object sender, LogItemBase e)
- {
- if (_isUpdating)
- {
- _logs.Add(e);
- }
}
#endregion
#region Private Methods
- private Task Login(String machineGuid)
+ private Task Login(String serialNumber)
{
return _client.Login(new LoginRequest()
{
Mode = LoginMode.Machine,
- MachineGuid = machineGuid,
- });
- }
-
- private async void OnFailed(Exception ex, TaskCompletionSource<MachineUpdateResult> completionSource, DownloadUpdateResponse response, bool performDatabaseRollback, String dbBackupFile, String backupsFolder, String tempDbName, Tango.Core.DataSource localDataSource, String tempUpdatePackageFolder = null, PublishInfo tupPublishInfo = null)
- {
- LogManager.Log(ex, "An error occurred in machine update.");
-
- await Task.Factory.StartNew(() =>
- {
-
- if (performDatabaseRollback)
- {
- LogManager.Log("Rolling back database changes...");
-
- using (DbManager db = DbManager.FromDataSource(localDataSource))
- {
- try
- {
- UpdateProgress("Rollback", "Rolling back database changes...");
- db.Restore(localDataSource.Catalog, dbBackupFile);
- LogManager.Log("Database restored successfully.");
- }
- catch (Exception e)
- {
- LogManager.Log(e, "Could not rollback the database.");
- }
- finally
- {
- try
- {
- File.Delete(dbBackupFile);
- }
- catch { }
- }
- }
- }
-
- if (tempDbName != null)
- {
- try
- {
- LogManager.Log($"Removing temporary database '{tempDbName}'...");
- using (DbManager dbManager = DbManager.FromDataSource(localDataSource))
- {
- dbManager.SetOffline(tempDbName);
- dbManager.SetOnline(tempDbName);
- dbManager.Delete(tempDbName);
- }
- }
- catch (Exception exx)
- {
- LogManager.Log(exx, "Error removing temporary database.");
- }
- }
-
- try
- {
- Directory.Delete(backupsFolder, true);
- }
- catch (Exception ee)
- {
- LogManager.Log(ee, $"Error deleting backups folder '{backupsFolder}'.");
- }
-
- if (tempUpdatePackageFolder != null)
- {
- try
- {
- Directory.Delete(tempUpdatePackageFolder, true);
- }
- catch (Exception eee)
- {
- LogManager.Log(eee, "Error removing temporary package folder.");
- }
- }
-
- });
-
- completionSource.SetException(ex);
-
- String logs = GetLogsStringAndClear();
-
- if (response != null)
- {
- try
- {
- var result = await _client.NotifyUpdateCompleted(new MachineUpdateCompletedRequest()
- {
- Token = response.NotifyCompletedToken,
- Status = BL.Enumerations.TangoUpdateStatuses.UpdateFailed,
- FailedReason = ex.FlattenMessage(),
- FailedLog = logs,
- });
- }
- catch (Exception xx)
- {
- LogManager.Log(xx, "Error notifying update failed.");
- }
-
- try
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- TangoUpdate update = new TangoUpdate();
- update.ApplicationVersion = response.Version;
- update.FirmwareVersion = response.FirmwareVersion;
- update.MachineGuid = _machineProvider.Machine.Guid;
- update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.UpdateFailed;
- update.StartDate = _updateStartDate;
- update.EndDate = DateTime.UtcNow;
- update.FailedReason = ex.FlattenMessage();
- update.FailedLog = logs;
- db.TangoUpdates.Add(update);
- await db.SaveChangesAsync();
- }
- }
- catch (Exception xxx)
- {
- LogManager.Log(xxx, "Error saving tango update information to database.");
- }
- }
-
-
- if (tupPublishInfo != null)
- {
- try
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- TangoUpdate update = new TangoUpdate();
- update.ApplicationVersion = tupPublishInfo.ApplicationVersion;
- update.FirmwareVersion = tupPublishInfo.GetFirmwareVersion();
- update.MachineGuid = _machineProvider.Machine.Guid;
- update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.OfflineUpdateFailed;
- update.StartDate = _updateStartDate;
- update.EndDate = DateTime.UtcNow;
- update.FailedReason = ex.FlattenMessage();
- update.FailedLog = logs;
- db.TangoUpdates.Add(update);
- await db.SaveChangesAsync();
- }
- }
- catch (Exception xxx)
- {
- LogManager.Log(xxx, "Error saving tango offline update information to database.");
- }
- }
-
- _isUpdating = false;
- }
-
- private async void OnCompleted(MachineUpdateResult result, TaskCompletionSource<MachineUpdateResult> completionSource, DownloadUpdateResponse response, String tempDbName, String backupsFolder, Core.DataSource localDataSource, PublishInfo tupPublishInfo = null)
- {
- await Task.Factory.StartNew(() =>
- {
- if (tempDbName != null)
- {
- try
- {
- LogManager.Log($"Removing temporary database '{tempDbName}'...");
- using (DbManager dbManager = DbManager.FromDataSource(localDataSource))
- {
- dbManager.SetOffline(tempDbName);
- dbManager.SetOnline(tempDbName);
- dbManager.Delete(tempDbName);
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error removing temporary database.");
- }
- }
-
- //try
- //{
- // Directory.Delete(backupsFolder, true);
- //}
- //catch (Exception ex)
- //{
- // LogManager.Log(ex, $"Error deleting backups folder '{backupsFolder}'.");
- //}
-
- if (!result.RequiresBinariesUpdate)
- {
- try
- {
- Directory.Delete(result.UpdatePackagePath, true);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error removing temporary package folder.");
- }
- }
-
- });
-
- completionSource.SetResult(result);
-
- if (response != null)
- {
- try
- {
- var r = await _client.NotifyUpdateCompleted(new MachineUpdateCompletedRequest()
- {
- Token = response.NotifyCompletedToken,
- Status = BL.Enumerations.TangoUpdateStatuses.UpdateCompleted,
- });
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error notifying update completed.");
- }
-
- try
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- TangoUpdate update = new TangoUpdate();
- update.ApplicationVersion = response.Version;
- update.FirmwareVersion = response.FirmwareVersion;
- update.MachineGuid = (await db.Machines.FirstAsync()).Guid;
- update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.UpdateCompleted;
- update.StartDate = _updateStartDate;
- update.EndDate = DateTime.UtcNow;
- db.TangoUpdates.Add(update);
- await db.SaveChangesAsync();
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error saving tango update information to database.");
- }
- }
-
-
- if (tupPublishInfo != null)
- {
- try
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- TangoUpdate update = new TangoUpdate();
- update.ApplicationVersion = tupPublishInfo.ApplicationVersion;
- update.FirmwareVersion = tupPublishInfo.GetFirmwareVersion();
- update.MachineGuid = _machineProvider.Machine.Guid;
- update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.OfflineUpdateCompleted;
- update.StartDate = _updateStartDate;
- update.EndDate = DateTime.UtcNow;
- db.TangoUpdates.Add(update);
- await db.SaveChangesAsync();
- }
- }
- catch (Exception xxx)
- {
- LogManager.Log(xxx, "Error saving tango offline update information to database.");
- }
- }
-
- _isUpdating = false;
- }
-
- private void OnFailed(Exception ex, UpdateDBResponse response, bool performDatabaseRollback, String dbBackupFile, Tango.Core.DataSource localDataSource)
- {
- LogManager.Log(ex, "An error occurred in database update.");
-
- if (performDatabaseRollback)
- {
- LogManager.Log("Rolling back database changes...");
-
- using (DbManager db = DbManager.FromDataSource(localDataSource))
- {
- try
- {
- UpdateProgress("Rollback", "Rolling back database changes...");
- db.Restore(localDataSource.Catalog, dbBackupFile);
- LogManager.Log("Database restored successfully.");
- }
- catch (Exception e)
- {
- LogManager.Log(e, "Could not rollback the database.");
- throw ex;
- }
- finally
- {
- try
- {
- File.Delete(dbBackupFile);
- }
- catch { }
- }
- }
- }
-
- String logs = GetLogsStringAndClear();
-
- if (response != null)
- {
- try
- {
- var r = _client.NotifyUpdateCompleted(new MachineUpdateCompletedRequest()
- {
- Token = response.NotifyCompletedToken,
- Status = BL.Enumerations.TangoUpdateStatuses.DatabaseFailed,
- FailedReason = ex.FlattenMessage(),
- FailedLog = logs,
- }).Result;
- }
- catch (Exception xx)
- {
- LogManager.Log(xx, "Error notifying database failed.");
- }
-
- try
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- TangoUpdate update = new TangoUpdate();
- update.ApplicationVersion = _app_manager.Version.ToString();
- update.FirmwareVersion = _app_manager.FirmwareVersion.ToString();
- update.MachineGuid = _machineProvider.Machine.Guid;
- update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.DatabaseFailed;
- update.StartDate = _updateStartDate;
- update.EndDate = DateTime.UtcNow;
- update.FailedReason = ex.FlattenMessage();
- update.FailedLog = logs;
- db.TangoUpdates.Add(update);
- db.SaveChanges();
- }
- }
- catch (Exception exx)
- {
- LogManager.Log(exx, "Error saving database update information to database.");
- }
- }
-
- _isUpdating = false;
- }
-
- private void OnCompleted(UpdateDBResponse response, bool completedWithNoDifferences = false)
- {
- if (response != null)
- {
- try
- {
- var r = _client.NotifyUpdateCompleted(new MachineUpdateCompletedRequest()
- {
- Token = response.NotifyCompletedToken,
- Status = BL.Enumerations.TangoUpdateStatuses.DatabaseCompleted,
- ReportsAboutDbCheckNoDifferences = completedWithNoDifferences,
- }).Result;
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error notifying database completed.");
- }
-
- if (!completedWithNoDifferences)
- {
- try
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- TangoUpdate update = new TangoUpdate();
- update.ApplicationVersion = _app_manager.Version.ToString();
- update.FirmwareVersion = _app_manager.FirmwareVersion.ToString();
- update.MachineGuid = _machineProvider.Machine.Guid;
- update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.DatabaseCompleted;
- update.StartDate = _updateStartDate;
- update.EndDate = DateTime.UtcNow;
- db.TangoUpdates.Add(update);
- db.SaveChanges();
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error saving database update information to database.");
- }
- }
- }
-
- _isUpdating = false;
- }
-
- private void OnFailed(Exception ex, TaskCompletionSource<object> completionSource, String firmwareVersion)
- {
- LogManager.Log(ex, "An error occurred in firmware upgrade.");
-
- completionSource.SetException(ex);
- String logs = GetLogsStringAndClear();
-
- try
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- TangoUpdate update = new TangoUpdate();
- update.ApplicationVersion = _app_manager.Version.ToString();
- update.FirmwareVersion = firmwareVersion;
- update.MachineGuid = _machineProvider.Machine.Guid;
- update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.OfflineFirmwareUpgradeFailed;
- update.StartDate = _updateStartDate;
- update.EndDate = DateTime.UtcNow;
- update.FailedReason = ex.FlattenMessage();
- update.FailedLog = logs;
- db.TangoUpdates.Add(update);
- db.SaveChanges();
- }
- }
- catch (Exception exx)
- {
- LogManager.Log(exx, "Error saving firmware upgrade information to database.");
- }
-
- _isUpdating = false;
- }
-
- private void OnCompleted(TaskCompletionSource<object> completionSource, String firmwareVersion)
- {
- LogManager.Log("Firmware upgrade completed successfully.");
- completionSource.SetResult(true);
-
- try
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- TangoUpdate update = new TangoUpdate();
- update.ApplicationVersion = _app_manager.Version.ToString();
- update.FirmwareVersion = firmwareVersion;
- update.MachineGuid = _machineProvider.Machine.Guid;
- update.UpdateStatus = BL.Enumerations.TangoUpdateStatuses.OfflineFirmwareUpgradeCompleted;
- update.StartDate = _updateStartDate;
- update.EndDate = DateTime.UtcNow;
- db.TangoUpdates.Add(update);
- db.SaveChanges();
- }
- }
- catch (Exception exx)
- {
- LogManager.Log(exx, "Error saving firmware upgrade information to database.");
- }
-
- _isUpdating = false;
- }
-
- private String GetLogsStringAndClear()
- {
- String logsString = String.Join(Environment.NewLine, _logs.ToList().Select(x => x.ToString()));
- _logs.Clear();
- return logsString;
- }
-
- private void ClearLastDatabaseBackup()
- {
- Task.Factory.StartNew(() =>
- {
- try
- {
- var lastBackupFile = SettingsManager.Default.GetOrCreate<PPCSettings>().LastDatabaseBackupFile;
-
- if (File.Exists(lastBackupFile))
- {
- File.Delete(lastBackupFile);
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error removing last database backup file.");
- }
+ SerialNumber = serialNumber,
});
}
@@ -634,8 +89,9 @@ namespace Tango.PPC.Common.MachineUpdate
#region Public Methods
/// <summary>
- /// Performs a machine update.
+ /// Performs a machine update using the specified serial number and machine service address.
/// </summary>
+ /// <param name="serialNumber">The serial number.</param>
/// <param name="setupFirmware">if set to <c>true</c> updates the embedded device firmware.</param>
/// <param name="setupFPGA">if set to <c>true</c> updates the embedded device FPGA version and other parameters.</param>
/// <returns></returns>
@@ -645,32 +101,19 @@ namespace Tango.PPC.Common.MachineUpdate
/// or
/// </exception>
/// <exception cref="System.InvalidProgramException">Database tango does not exists.</exception>
- public async Task<MachineUpdateResult> Update(bool setupFirmware, bool setupFPGA)
+ public async Task<MachineUpdateResult> Update(String serialNumber, bool setupFirmware, bool setupFPGA)
{
- _updateStartDate = DateTime.UtcNow;
- _logs.Clear();
-
TaskCompletionSource<MachineUpdateResult> result = new TaskCompletionSource<MachineUpdateResult>();
var localDataSource = SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource;
bool performDatabaseRollback = false;
String dbBackupFile = null;
- DownloadUpdateResponse update_response = null;
- String backupsFolder = "C:\\Backups";
-
- //Create temporary folders for packages.
- var _newPackageTempFolder = TemporaryManager.CreateFolder();
- _newPackageTempFolder.Persist = true;
-
- String machineGuid = _machineProvider.Machine.Guid;
try
{
- _isUpdating = true;
-
- var machineServiceAddress = _settings.GetMachineServiceAddress();
+ var machineServiceAddress = SettingsManager.Default.GetOrCreate<PPCSettings>().GetMachineServiceAddress();
- LogManager.Log($"Starting machine update...");
+ LogManager.Log($"Starting machine update for serial number {serialNumber}...");
//Connecting to machine...
LogManager.Log("Verifying machine connection and state...");
@@ -689,11 +132,10 @@ namespace Tango.PPC.Common.MachineUpdate
{
throw LogManager.Log(new InvalidOperationException("Could not perform an update while the machine is not connected."));
}
- }
-
- if (!op.CanPrint)
- {
- throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {op.Status} status."));
+ if (op.IsPrinting)
+ {
+ throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {op.Status} status."));
+ }
}
//Connect to machine service and get matching packages for this machine.
@@ -701,14 +143,21 @@ namespace Tango.PPC.Common.MachineUpdate
LogManager.Log($"Connecting to machine service on {machineServiceAddress}...");
- await Login(machineGuid);
+ await Login(serialNumber);
DownloadUpdateRequest request = new DownloadUpdateRequest();
+ request.SerialNumber = serialNumber;
+
+ DownloadUpdateResponse update_response = null;
update_response = await _client.MachineUpdate(request);
LogManager.Log($"Machine update response received: {Environment.NewLine}{update_response.ToJsonString()}");
+ //Create temporary folders for packages.
+ var _newPackageTempFolder = TemporaryManager.CreateFolder();
+ _newPackageTempFolder.Persist = true;
+
LogManager.Log($"Temporary package folder created: {_newPackageTempFolder}.");
//Download software package.
@@ -718,102 +167,68 @@ namespace Tango.PPC.Common.MachineUpdate
LogManager.Log("Downloading software package...");
+ long fileSize = 0;
UpdateProgress("Downloading software package", "Downloading...", false);
- using (AutoFileDownloader downloader = new AutoFileDownloader(update_response.BlobAddress, update_response.CdnAddress, tempFile))
+ using (FileStreamWrapper fs = new FileStreamWrapper(tempFile.Path, FileMode.Create, (current) =>
{
- await downloader.ResolveMode();
-
- if (downloader.Mode == AutoFileDownloader.DownloadMode.Standard)
- {
- LogManager.Log($"Connecting to storage CDN with address {downloader.Address}");
- }
- else
- {
- LogManager.Log($"Connecting to storage blob with address {downloader.Address}");
- }
-
- downloader.Progress += (x, e) =>
- {
- UpdateProgress("Downloading software package", "Downloading...", false, e.Current, e.Total);
- };
-
- var size = await downloader.GetFileSize();
- LogManager.Log("Download size: " + size + " bytes.");
- LogManager.Log("Starting file download...");
- await downloader.Download();
+ UpdateProgress("Downloading software package", "Downloading...", false, current, fileSize);
+ }))
+ {
+ LogManager.Log($"Connecting to storage blob with address {update_response.BlobAddress}");
+ CloudBlockBlob blob = new CloudBlockBlob(new Uri(update_response.BlobAddress));
+ LogManager.Log("Fetching blob attributes...");
+ blob.FetchAttributes();
+ fileSize = blob.Properties.Length;
+ LogManager.Log("Download size: " + fileSize + " bytes.");
+ LogManager.Log("Starting blob download...");
+ blob.DownloadToStream(fs);
}
UpdateProgress("Downloading software package", "Extracting package...");
LogManager.Log("Extracting downloaded zip file...");
+ //Extract software package.
+ ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder);
- await Task.Factory.StartNew(() =>
- {
- //Extract software package.
- ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder);
- });
LogManager.Log("Copying latest updater utility to application path...");
//Copy new updater utility to app path.
File.Copy(Path.Combine(_newPackageTempFolder, "Tango.PPC.Updater.exe"), Path.Combine(PathHelper.GetStartupPath(), "Tango.PPC.Updater.exe"), true);
+
+ //Synchronize database
+ UpdateProgress("Updating Database", "Initializing...");
+
+ LogManager.Log($"Synchronizing database '{update_response.DataSource.ToString()}' => '{localDataSource.ToString()}'...");
+
+ UpdateProgress("Updating Database", "Connecting to local database...");
LogManager.Log("Initializing database manager...");
DbManager db = DbManager.FromDataSource(localDataSource);
- //Create Database Backup
- UpdateProgress("Updating Database", "Creating database backup...");
- try
- {
- Directory.CreateDirectory(backupsFolder);
- dbBackupFile = $"{backupsFolder}\\{Path.GetRandomFileName()}.bak";
- _settings.LastDatabaseBackupFile = dbBackupFile;
- _settings.Save();
- LogManager.Log($"Creating database backup to '{dbBackupFile}'...");
- await Task.Factory.StartNew(() => db.Backup(localDataSource.Catalog, dbBackupFile));
- performDatabaseRollback = true;
- LogManager.Log("Database backup created successfully.");
- }
- catch (Exception ex)
+ LogManager.Log("Checking Tango database exists on the local machine...");
+ if (!db.Exists(localDataSource.Catalog))
{
- throw LogManager.Log(ex, "Update manager error while trying to create a database backup.");
+ throw new InvalidProgramException("Database tango does not exists.");
}
- //Run pre-update packages.
- try
+ if (setupFirmware)
{
- UpdateProgress("Preparing", "Running update packages...");
- LogManager.Log("Running pre-update packages...");
- var packagesFolder = Path.Combine(_newPackageTempFolder, "Packages");
+ LogManager.Log("Setup firmware is active so a database rollback procedure should be configured.");
+ UpdateProgress("Updating Database", "Creating database backup...");
- Version updateVersion = new Version(1, 0, 0, 0);
try
{
- updateVersion = Version.Parse(update_response.Version);
+ Directory.CreateDirectory("C:\\Backups");
+ dbBackupFile = $"C:\\Backups\\{Path.GetRandomFileName()}.bak";
+ LogManager.Log($"Creating database backup to '{dbBackupFile}'...");
+ await Task.Factory.StartNew(() => db.Backup(localDataSource.Catalog, dbBackupFile));
+ LogManager.Log("Database backup created successfully.");
}
catch (Exception ex)
{
- LogManager.Log(ex, "Error parsing new version string for package runner.");
+ throw LogManager.Log(ex, "Setup manager error while trying to create a database backup.");
}
-
- await _packageRunner.Run(PackageType.Pre, updateVersion, packagesFolder);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error running pre-update packages...");
- }
-
- //Synchronize database
- UpdateProgress("Updating Database", "Initializing...");
-
- LogManager.Log($"Synchronizing database '{update_response.DataSource.ToString()}' => '{localDataSource.ToString()}'...");
-
- UpdateProgress("Updating Database", "Connecting to local database...");
-
- LogManager.Log("Checking Tango database exists on the local machine...");
- if (!db.Exists(localDataSource.Catalog))
- {
- throw new InvalidProgramException("Database tango does not exists.");
}
LogManager.Log("Disposing database manager.");
@@ -828,7 +243,7 @@ namespace Tango.PPC.Common.MachineUpdate
Path.Combine(_newPackageTempFolder, "Update Scripts"),
update_response.DataSource,
localDataSource,
- machineGuid);
+ serialNumber);
runner.Log += (x, msg) =>
{
@@ -852,12 +267,14 @@ namespace Tango.PPC.Common.MachineUpdate
}
catch (Exception ex)
{
- throw LogManager.Log(ex, "Update manager error while trying to synchronize database.");
+ throw LogManager.Log(ex, "Setup manager error while trying to synchronize database.");
}
//Updating firmware
if (setupFirmware)
{
+ performDatabaseRollback = true;
+
UpdateProgress("Updating Firmware", "Connecting to firmware device...");
LogManager.Log("");
LogManager.Log("-------------------------------------------------------------------------");
@@ -876,88 +293,106 @@ namespace Tango.PPC.Common.MachineUpdate
op.FirmwareUpgradeMode = FirmwareUpgradeModes.DFU;
}
- var handler = await op.UpgradeFirmware(stream, _machineProvider.Machine.IsDemo);
+ var handler = await op.UpgradeFirmware(stream);
handler.Failed += (_, ex) =>
{
stream.Dispose();
- OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, backupsFolder, null, localDataSource, _newPackageTempFolder);
+ throw ex;
};
handler.Completed += (_, __) =>
{
UpdateProgress("Updating Firmware", "Firmware update completed successfully.");
stream.Dispose();
- OnCompleted(new MachineUpdateResult()
+ result.SetResult(new MachineUpdateResult()
{
UpdatePackagePath = _newPackageTempFolder,
- }, result, update_response, null, backupsFolder, localDataSource);
+ });
};
handler.Canceled += (_, __) =>
{
stream.Dispose();
- OnFailed(new Exception("The operation has been canceled."), result, update_response, performDatabaseRollback, dbBackupFile, backupsFolder, null, localDataSource, _newPackageTempFolder);
+ throw new Exception("The operation has been canceled.");
};
handler.Progress += (_, e) =>
{
- UpdateProgress("Updating Firmware", e.Message, e.IsIndeterminate, e.Current, e.Total);
+ UpdateProgress("Updating Firmware", e.Message, false, e.Current, e.Total);
};
}
else
{
- OnCompleted(new MachineUpdateResult()
+ result.SetResult(new MachineUpdateResult()
{
UpdatePackagePath = _newPackageTempFolder,
- }, result, update_response, null, backupsFolder, localDataSource);
+ });
}
}
catch (Exception ex)
{
- OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, backupsFolder, null, localDataSource, _newPackageTempFolder);
+ LogManager.Log(ex, "An error occurred in machine update.");
+
+ if (performDatabaseRollback)
+ {
+ LogManager.Log("Rolling back database changes...");
+
+ using (DbManager db = DbManager.FromDataSource(localDataSource))
+ {
+ try
+ {
+ UpdateProgress("Rollback", "Rolling back database changes...");
+ await Task.Factory.StartNew(() => db.Restore(localDataSource.Catalog, dbBackupFile));
+ LogManager.Log("Database restored successfully.");
+ }
+ catch (Exception e)
+ {
+ LogManager.Log(e, "Could not rollback the database.");
+ throw ex;
+ }
+ finally
+ {
+ try
+ {
+ File.Delete(dbBackupFile);
+ }
+ catch { }
+ }
+ }
+ }
+
+ result.SetException(ex);
+ }
+ finally
+ {
+ try
+ {
+ File.Delete(dbBackupFile);
+ }
+ catch { }
}
return await result.Task;
}
/// <summary>
- /// Checks if any update are available for the specified machine.
+ /// Checks if any update are available for the specified machine serial number.
/// </summary>
+ /// <param name="serialNumber">The serial number.</param>
/// <param name="machineServiceAddress">The machine service address.</param>
/// <returns></returns>
- public Task<CheckForUpdateResponse> CheckForUpdate()
+ public Task<CheckForUpdateResponse> CheckForUpdate(string serialNumber)
{
return Task.Factory.StartNew<CheckForUpdateResponse>(() =>
{
- _isUpdating = true;
-
- var machineServiceAddress = _settings.GetMachineServiceAddress();
+ var machineServiceAddress = SettingsManager.Default.GetOrCreate<PPCSettings>().GetMachineServiceAddress();
LogManager.Log($"Connecting to machine service on {machineServiceAddress}...");
- String machineGuid = _machineProvider.Machine.Guid;
-
- Login(machineGuid).GetAwaiter().GetResult();
+ Login(serialNumber).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();
-
- try
- {
- request.MachineLastUpdated = _machineProvider.Machine.LastUpdated;
-
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- request.Rmls = db.Rmls.ToList().Select(x => new UpdatedEntity(x)).ToList();
- request.HardwareVersions = db.HardwareVersions.ToList().Select(x => new UpdatedEntity(x)).ToList();
- request.Catalogs = db.ColorCatalogs.ToList().Select(x => new UpdatedEntity(x)).ToList();
- request.UsedRmlsGuids = db.Jobs.Select(x => x.RmlGuid).Distinct().ToList();
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "An error occurred while trying to fill the existing database entities before checking for updates.");
- }
CheckForUpdateResponse update_response = null;
@@ -965,8 +400,6 @@ namespace Tango.PPC.Common.MachineUpdate
LogManager.Log($"Check for update response received: {Environment.NewLine}{update_response.ToJsonString()}");
- _isUpdating = false;
-
return update_response;
});
}
@@ -974,145 +407,96 @@ namespace Tango.PPC.Common.MachineUpdate
/// <summary>
/// Updates all the "overwrite-able" database tables.
/// </summary>
+ /// <param name="serialNumber">The serial number.</param>
/// <param name="machineServiceAddress">The machine service address.</param>
/// <returns></returns>
- public Task UpdateDB(DbCompareResult dbCompareResult)
+ public Task UpdateDB(DbCompareResult dbCompareResult, String serialNumber)
{
- _updateStartDate = DateTime.UtcNow;
- _logs.Clear();
-
return Task.Factory.StartNew(() =>
{
- _isUpdating = true;
- UpdateDBResponse update_response = null;
- var localDataSource = SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource;
- bool performDatabaseRollback = false;
- String dbBackupFile = null;
+ LogManager.Log("Starting database update...");
- try
- {
- LogManager.Log("Starting database update...");
+ UpdateProgress("Updating Database", "Initializing...");
- if (_machineProvider.MachineOperator.IsPrinting)
- {
- throw LogManager.Log(new InvalidOperationException($"Could not perform a database update while the machine is dyeing."));
- }
+ LogManager.Log("Looking for update scripts configuration on application path...");
- UpdateProgress("Updating Database", "Initializing...");
+ String config_file = Path.Combine(PathHelper.GetStartupPath(), "Update Scripts", "config.xml");
- LogManager.Log("Looking for update scripts configuration on application path...");
+ if (!File.Exists(config_file))
+ {
+ throw LogManager.Log(new FileNotFoundException($"Could not locate '{config_file}' file on application folder."));
+ }
- String config_file = Path.Combine(PathHelper.GetStartupPath(), "Update Scripts", "config.xml");
+ UpdateDBResponse update_response = dbCompareResult.UpdateDBResponse;
- if (!File.Exists(config_file))
- {
- throw LogManager.Log(new FileNotFoundException($"Could not locate '{config_file}' file on application folder."));
- }
+ var localDataSource = SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource;
- update_response = dbCompareResult.UpdateDBResponse;
+ LogManager.Log($"Updating database '{update_response.DataSource.ToString()}' => '{localDataSource.ToString()}'...");
- LogManager.Log($"Updating database '{update_response.DataSource.ToString()}' => '{localDataSource.ToString()}'...");
+ UpdateProgress("Updating Database", "Initializing update sequence...");
- UpdateProgress("Updating Database", "Initializing update sequence...");
+ ExaminerSequenceConfiguration config_sequence = ExaminerSequenceConfiguration.FromFile(config_file);
- ExaminerSequenceConfiguration config_sequence = ExaminerSequenceConfiguration.FromFile(config_file);
+ foreach (var item in config_sequence.Items.Where(x => x.Type == ExaminerSequenceItemType.Data || update_response.PerformSchemaUpdate).OrderBy(x => x.Index))
+ {
+ LogManager.Log($"Executing update script '{item.FileName}...'");
- UpdateProgress("Updating Database", "Connecting to local database...");
- LogManager.Log("Initializing database manager...");
- DbManager db = DbManager.FromDataSource(localDataSource);
+ ExaminerConfigurationBuilder builder = new ExaminerConfigurationBuilder(Path.Combine(Path.GetDirectoryName(config_file), item.FileName));
+ builder.SetSource(update_response.DataSource);
+ builder.SetTarget(localDataSource);
- LogManager.Log("Checking Tango database exists on the local machine...");
- if (!db.Exists(localDataSource.Catalog))
+ if (item.RequiresSerialNumber)
{
- throw new InvalidProgramException("Database tango does not exists.");
+ builder.SetMachineSerialNumber(serialNumber);
}
- UpdateProgress("Updating Database", "Creating database backup...");
+ builder.Synchronize();
- //Create Database Backup
- try
- {
- Directory.CreateDirectory("C:\\Backups");
- dbBackupFile = $"C:\\Backups\\{Path.GetRandomFileName()}.bak";
- LogManager.Log($"Creating database backup to '{dbBackupFile}'...");
- db.Backup(localDataSource.Catalog, dbBackupFile);
- performDatabaseRollback = true;
- LogManager.Log("Database backup created successfully.");
- }
- catch (Exception ex)
- {
- throw LogManager.Log(ex, "Update manager error while trying to create a database backup.");
- }
+ var config = builder.Build();
- LogManager.Log("Disposing database manager.");
- db.Dispose();
+ ExaminerProcess process = new ExaminerProcess(config, item.Type == ExaminerSequenceItemType.Data ? ExaminerProcessType.Data : ExaminerProcessType.Schema);
+ process.Progress += (x, msg) =>
+ {
+ LogManager.Log(msg);
+ };
- foreach (var item in config_sequence.Items.Where(x => x.Type == ExaminerSequenceItemType.Data || update_response.PerformSchemaUpdate).OrderBy(x => x.Index))
+ try
{
- LogManager.Log($"Executing update script '{item.FileName}...'");
+ UpdateProgress("Updating Database", item.Name + "...");
- ExaminerConfigurationBuilder builder = new ExaminerConfigurationBuilder(Path.Combine(Path.GetDirectoryName(config_file), item.FileName));
- builder.SetSource(update_response.DataSource);
- builder.SetTarget(localDataSource);
+ var result = process.Execute().Result;
- if (item.RequiresSerialNumber)
+ if (result.ExitCode != ExaminerProcessExitCode.Success)
{
- builder.SetMachineSerialNumber(_machineProvider.Machine.Guid);
+ throw LogManager.Log(new InvalidDataException($"{item.FileName} script has terminated with exit code '{result.ExitCode}'."));
}
- builder.Synchronize();
-
- var config = builder.Build();
-
- ExaminerProcess process = new ExaminerProcess(config, item.Type == ExaminerSequenceItemType.Data ? ExaminerProcessType.Data : ExaminerProcessType.Schema);
- process.Progress += (x, msg) =>
- {
- LogManager.Log(msg);
- };
-
- try
- {
- UpdateProgress("Updating Database", item.Name + "...");
-
- var result = process.Execute().Result;
-
- if (result.ExitCode != ExaminerProcessExitCode.Success)
- {
- throw LogManager.Log(new InvalidDataException($"{item.FileName} script has terminated with exit code '{result.ExitCode}'."));
- }
-
- LogManager.Log("Script executed successfully.");
- }
- catch (Exception ex)
- {
- throw LogManager.Log(ex, "Upudate manager error while trying to update the database.");
- }
+ LogManager.Log("Script executed successfully.");
+ }
+ catch (Exception ex)
+ {
+ throw LogManager.Log(ex, "Setup manager error while trying to update the database.");
}
-
- UpdateProgress("Updating Database", "Database synchronization completed successfully.");
- LogManager.Log("Update completed successfully.");
- OnCompleted(update_response);
- }
- catch (Exception ex)
- {
- OnFailed(ex, update_response, performDatabaseRollback, dbBackupFile, localDataSource);
- throw ex;
}
+
+ UpdateProgress("Updating Database", "Database synchronization completed successfully.");
+ LogManager.Log("Update completed successfully.");
});
}
/// <summary>
/// Checks whether it is necessary to updates all the "overwrite-able" database tables.
/// </summary>
+ /// <param name="serialNumber">The serial number.</param>
/// <param name="machineServiceAddress">The machine service address.</param>
/// <returns></returns>
- public Task<DbCompareResult> UpdateDBCheck()
+ public Task<DbCompareResult> UpdateDBCheck(string serialNumber)
{
return Task.Factory.StartNew<DbCompareResult>(() =>
{
- var machineServiceAddress = _settings.GetMachineServiceAddress();
+ var machineServiceAddress = SettingsManager.Default.GetOrCreate<PPCSettings>().GetMachineServiceAddress();
- LogManager.Log($"Checking if database update is required...");
+ LogManager.Log($"Checking if database update is required for serial number {serialNumber}...");
LogManager.Log("Looking for update scripts configuration on application path...");
@@ -1125,11 +509,10 @@ namespace Tango.PPC.Common.MachineUpdate
LogManager.Log($"Connecting to machine service on {machineServiceAddress}...");
- Login(_machineProvider.Machine.Guid).Wait();
+ Login(serialNumber).Wait();
UpdateDBRequest request = new UpdateDBRequest();
- request.ApplicationVersion = _app_manager.Version.ToString();
- request.FirmwareVersion = _app_manager.FirmwareVersion.ToString();
+ request.SerialNumber = serialNumber;
UpdateDBResponse update_response = null;
@@ -1158,7 +541,7 @@ namespace Tango.PPC.Common.MachineUpdate
if (item.RequiresSerialNumber)
{
- builder.SetMachineSerialNumber(_machineProvider.Machine.Guid);
+ builder.SetMachineSerialNumber(serialNumber);
}
var config = builder.Build();
@@ -1197,18 +580,12 @@ namespace Tango.PPC.Common.MachineUpdate
}
catch (Exception ex)
{
- OnFailed(ex, update_response, false, null, null);
throw LogManager.Log(ex, "Update manager error while trying to compare the database.");
}
}
LogManager.Log("Comparison completed successfully.");
- if (!has_differences)
- {
- OnCompleted(update_response, true);
- }
-
return new DbCompareResult()
{
RequiresUpdate = has_differences,
@@ -1222,373 +599,31 @@ namespace Tango.PPC.Common.MachineUpdate
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <returns></returns>
- public async Task<MachineUpdateResult> UpdateFromTUP(string fileName, bool setupFirmware, bool setupFPGA)
+ public Task<MachineUpdateResult> UpdateFromTUP(string fileName)
{
- _updateStartDate = DateTime.UtcNow;
- _logs.Clear();
-
- TaskCompletionSource<MachineUpdateResult> result = new TaskCompletionSource<MachineUpdateResult>();
-
- var localDataSource = SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource;
- bool performDatabaseRollback = false;
- String dbBackupFile = null;
- String tempDbName = "Tango_TUP";
- String tempDbFileName = tempDbName + ".bak";
- String backupsFolder = "C:\\Backups";
- bool replaceBinaries = false;
- PublishInfo publishInfo = null;
-
- String serialNumber = _machineProvider.Machine.SerialNumber;
-
- //Create temporary folders for packages.
- var _newPackageTempFolder = TemporaryManager.CreateFolder();
- _newPackageTempFolder.Persist = true;
-
- try
+ return Task.Factory.StartNew<MachineUpdateResult>(() =>
{
- _isUpdating = true;
-
- LogManager.Log($"Starting machine update (TUP) for serial number {serialNumber}...");
-
- //Connecting to machine...
- LogManager.Log("Verifying machine connection and state...");
-
- UpdateProgress("Verifying machine state", "Initializing...");
-
- await Task.Delay(1000);
-
- IMachineOperator op = _machineProvider.MachineOperator;
+ LogManager.Log($"Starting machine update from update package '{fileName}'...");
- if (setupFirmware)
- {
- LogManager.Log("Machine is configured to update firmware...");
-
- if (op.State != Transport.TransportComponentState.Connected)
- {
- throw LogManager.Log(new InvalidOperationException("Could not perform an update while the machine is not connected."));
- }
- }
-
- if (!op.CanPrint)
- {
- throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {op.Status} status."));
- }
-
- UpdateProgress("Exploring package", "Extracting...");
- LogManager.Log("Extracting package...");
-
- LogManager.Log($"Temporary package folder created: {_newPackageTempFolder}.");
-
- await Task.Factory.StartNew(() =>
- {
- //Extract software package.
- ZipFile.ExtractToDirectory(fileName, _newPackageTempFolder);
- });
-
- //Extracting publish info
- UpdateProgress("Exploring package", "Verifying...");
- publishInfo = PublishInfo.FromJson(File.ReadAllText(Path.Combine(_newPackageTempFolder, "version.json")));
-
- if (!publishInfo.IsMachineTupPackage)
- {
- throw new InvalidOperationException("The specified tup file is invalid. Updating a machine from a tup file requires a custom generated package.");
- }
-
- if (publishInfo.MachineSerialNumber != serialNumber)
- {
- throw new InvalidOperationException("The specified tup file is invalid. The package was generated for a different machine.");
- }
+ //Create temporary folders for packages.
+ var _newPackageTempFolder = TemporaryManager.CreateFolder();
+ _newPackageTempFolder.Persist = true;
- if (publishInfo.MachineDeploymentSlot != _settings.DeploymentSlot)
- {
- throw new InvalidOperationException("The specified tup file is invalid. The package was generated on a different environment.");
- }
-
- replaceBinaries = _app_manager.Version.ToString() != publishInfo.ApplicationVersion;
+ LogManager.Log("Extracting downloaded zip file...");
+ //Extract software package.
+ ZipFile.ExtractToDirectory(fileName, _newPackageTempFolder);
LogManager.Log("Copying latest updater utility to application path...");
-
//Copy new updater utility to app path.
File.Copy(Path.Combine(_newPackageTempFolder, "Tango.PPC.Updater.exe"), Path.Combine(PathHelper.GetStartupPath(), "Tango.PPC.Updater.exe"), true);
- //Run pre-update packages.
- try
- {
- UpdateProgress("Preparing", "Running update packages...");
- LogManager.Log("Running pre-update packages...");
- var packagesFolder = Path.Combine(_newPackageTempFolder, "Packages");
-
- Version updateVersion = new Version(1, 0, 0, 0);
- try
- {
- updateVersion = Version.Parse(publishInfo.ApplicationVersion);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error parsing new version string for package runner.");
- }
-
- await _packageRunner.Run(PackageType.Pre, updateVersion, packagesFolder);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error running pre-update packages...");
- }
-
- //Synchronize database
- UpdateProgress("Updating Database", "Initializing...");
-
- UpdateProgress("Updating Database", "Connecting to local database...");
- LogManager.Log("Initializing database manager...");
- DbManager db = DbManager.FromDataSource(localDataSource);
-
- LogManager.Log("Checking Tango database exists on the local machine...");
- if (!db.Exists(localDataSource.Catalog))
- {
- throw new InvalidProgramException("Database tango does not exists.");
- }
-
- UpdateProgress("Updating Database", "Creating database backup...");
-
- //Create Database Backup
- try
- {
- Directory.CreateDirectory(backupsFolder);
- dbBackupFile = $"{backupsFolder}\\{Path.GetRandomFileName()}.bak";
- LogManager.Log($"Creating database backup to '{dbBackupFile}'...");
- await Task.Factory.StartNew(() => db.Backup(localDataSource.Catalog, dbBackupFile));
- performDatabaseRollback = true;
- LogManager.Log("Database backup created successfully.");
- }
- catch (Exception ex)
- {
- throw LogManager.Log(ex, "Update manager error while trying to create a database backup.");
- }
-
- LogManager.Log("Extracting database file from package...");
- File.Copy(Path.Combine(_newPackageTempFolder, tempDbFileName), Path.Combine(backupsFolder, tempDbFileName));
-
- LogManager.Log("Restoring package database as a new database...");
- db.RestoreAsNew(tempDbName, Path.Combine(backupsFolder, tempDbFileName), backupsFolder);
-
- Core.DataSource tempDbDataSource = new Core.DataSource();
- tempDbDataSource.Address = localDataSource.Address;
- tempDbDataSource.IntegratedSecurity = localDataSource.IntegratedSecurity;
- tempDbDataSource.Type = localDataSource.Type;
- tempDbDataSource.Catalog = tempDbName;
-
- LogManager.Log("Disposing database manager.");
- db.Dispose();
-
- LogManager.Log($"Initializing {nameof(ExaminerSequenceConfigurationRunner)}...");
-
- UpdateProgress("Updating Database", "Initializing update sequence...");
-
- ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner(
- Path.Combine(_newPackageTempFolder, "Update Scripts", "config.xml"),
- Path.Combine(_newPackageTempFolder, "Update Scripts"),
- tempDbDataSource,
- localDataSource,
- _machineProvider.Machine.Guid);
-
- runner.Log += (x, msg) =>
- {
- LogManager.Log(msg);
- ProgressLog?.Invoke(this, msg);
- };
-
- runner.ScriptExecuting += (x, item) =>
- {
- LogManager.Log($"Executing script {item.ToString()}...");
- UpdateProgress("Updating Database", item.Name + "...");
- };
-
- LogManager.Log("Starting synchronization process...");
-
- try
- {
- await runner.Run();
- LogManager.Log("Synchronization completed successfully!");
- UpdateProgress("Updating Database", "Database synchronization completed successfully.");
- }
- catch (Exception ex)
- {
- throw LogManager.Log(ex, "Update manager error while trying to synchronize database.");
- }
-
- LogManager.Log("Getting setup firmware/fpga directly from db..");
-
- using (var dbManager = DbManager.FromDataSource(localDataSource))
- {
- try
- {
- String firmware = dbManager.GetValue($"SELECT TOP 1 * FROM MACHINES WHERE SERIAL_NUMBER = '{serialNumber}'", "SETUP_FIRMWARE");
- String fpga = dbManager.GetValue($"SELECT TOP 1 * FROM MACHINES WHERE SERIAL_NUMBER = '{serialNumber}'", "SETUP_FPGA");
-
- setupFirmware = bool.Parse(firmware);
- setupFPGA = bool.Parse(fpga);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error getting new values of SETUP_FIRMWARE and SETUP_FPGA.");
- }
- }
-
- //Updating firmware
- if (setupFirmware)
- {
- UpdateProgress("Updating Firmware", "Connecting to firmware device...");
- LogManager.Log("");
- LogManager.Log("-------------------------------------------------------------------------");
- LogManager.Log("Updating Firmware...");
-
- UpdateProgress("Updating Firmware", "Loading firmware package...");
- var tfpPath = Path.Combine(_newPackageTempFolder, "firmware_package.tfp");
- var stream = new FileStream(tfpPath, FileMode.Open);
-
- if (setupFPGA)
- {
- op.FirmwareUpgradeMode = FirmwareUpgradeModes.DFU | FirmwareUpgradeModes.TFP_PACKAGE;
- }
- else
- {
- op.FirmwareUpgradeMode = FirmwareUpgradeModes.DFU;
- }
-
- var handler = await op.UpgradeFirmware(stream, _machineProvider.Machine.IsDemo);
- handler.Failed += (_, ex) =>
- {
- stream.Dispose();
- OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder, publishInfo);
- };
- handler.Completed += (_, __) =>
- {
- UpdateProgress("Updating Firmware", "Firmware update completed successfully.");
- stream.Dispose();
- OnCompleted(new MachineUpdateResult()
- {
- UpdatePackagePath = _newPackageTempFolder,
- RequiresBinariesUpdate = replaceBinaries,
- }, result, null, tempDbName, backupsFolder, localDataSource, publishInfo);
- };
- handler.Canceled += (_, __) =>
- {
- stream.Dispose();
- OnFailed(new Exception("The operation has been canceled."), result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder, publishInfo);
- };
- handler.Progress += (_, e) =>
- {
- UpdateProgress("Updating Firmware", e.Message, e.IsIndeterminate, e.Current, e.Total);
- };
- }
- else
- {
- OnCompleted(new MachineUpdateResult()
- {
- UpdatePackagePath = _newPackageTempFolder,
- RequiresBinariesUpdate = replaceBinaries,
- }, result, null, tempDbName, backupsFolder, localDataSource, publishInfo);
- }
- }
- catch (Exception ex)
- {
- OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder, publishInfo);
- }
-
- return await result.Task;
- }
-
- /// <summary>
- /// Performs a firmware upgrade from the specified TFP file.
- /// </summary>
- /// <param name="fileName">Name of the file.</param>
- /// <returns></returns>
- /// <exception cref="InvalidOperationException">
- /// Could not perform a firmware upgrade while the machine is not connected.
- /// or
- /// </exception>
- public async Task UpdateFromTFP(String fileName)
- {
- _updateStartDate = DateTime.UtcNow;
- _logs.Clear();
-
- TaskCompletionSource<object> result = new TaskCompletionSource<object>();
-
- String version = String.Empty;
- Stream stream = null;
-
- try
- {
- _isUpdating = true;
-
- IMachineOperator op = _machineProvider.MachineOperator;
-
- UpdateProgress("Updating Firmware", "Loading firmware package...");
- stream = new FileStream(fileName, FileMode.Open);
-
- var packageInfo = await op.GetFirmwarePackageInfo(stream);
- stream.Position = 0;
- version = packageInfo.FileDescriptors.FirstOrDefault(x => x.Destination == PMR.FirmwareUpgrade.VersionFileDestination.Mcu)?.Version;
-
- LogManager.Log("Verifying machine connection and state...");
-
- UpdateProgress("Verifying machine state", "Initializing...");
-
- await Task.Delay(1000);
-
- if (op.State != Transport.TransportComponentState.Connected)
- {
- throw LogManager.Log(new InvalidOperationException("Could not perform a firmware upgrade while the machine is not connected."));
- }
- if (!op.CanPrint)
- {
- throw LogManager.Log(new InvalidOperationException($"Could not perform a firmware upgrade while the machine is in {op.Status} status."));
- }
-
- UpdateProgress("Updating Firmware", "Connecting to firmware device...");
- LogManager.Log("");
- LogManager.Log("-------------------------------------------------------------------------");
- LogManager.Log("Updating Firmware...");
+ LogManager.Log("Update operation completed!");
- op.FirmwareUpgradeMode = FirmwareUpgradeModes.DFU | FirmwareUpgradeModes.TFP_PACKAGE;
-
- var handler = await op.UpgradeFirmware(stream, _machineProvider.Machine.IsDemo);
- handler.Failed += (_, ex) =>
- {
- stream.Dispose();
- OnFailed(ex, result, version);
- };
- handler.Completed += (_, __) =>
+ return new MachineUpdateResult()
{
- UpdateProgress("Updating Firmware", "Firmware update completed successfully.");
- stream.Dispose();
- OnCompleted(result, version);
+ UpdatePackagePath = _newPackageTempFolder,
};
- handler.Canceled += (_, __) =>
- {
- stream.Dispose();
- OnFailed(new Exception("The operation has been canceled."), result, version);
- };
- handler.Progress += (_, e) =>
- {
- UpdateProgress("Updating Firmware", e.Message, e.IsIndeterminate, e.Current, e.Total);
- };
- }
- catch (Exception ex)
- {
- try
- {
- if (stream != null)
- {
- stream.Dispose();
- }
- }
- catch { }
-
- OnFailed(ex, result, version);
- }
-
- await result.Task;
+ });
}
/// <summary>
@@ -1596,88 +631,25 @@ namespace Tango.PPC.Common.MachineUpdate
/// </summary>
/// <param name="filePath">The file path.</param>
/// <returns></returns>
- public Task<PublishInfo> GetUpdatePackageFileInfo(string filePath)
+ public Task<UpdatePackageFile> GetUpdatePackageFileInfo(string filePath)
{
- return Task.Factory.StartNew<PublishInfo>(() =>
+ return Task.Factory.StartNew<UpdatePackageFile>(() =>
{
+ UpdatePackageFile file = new UpdatePackageFile();
+ var tempFolder = TemporaryManager.CreateFolder();
+
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile(filePath))
{
- var appEntry = zip.Entries.SingleOrDefault(x => x.FileName == "version.json");
- var reader = appEntry.OpenReader();
-
- using (StreamReader stReader = new StreamReader(reader))
- {
- String json = stReader.ReadToEnd();
- reader.Dispose();
-
- return PublishInfo.FromJson(json);
- }
+ var appEntry = zip.Entries.SingleOrDefault(x => x.FileName == "Tango.PPC.UI.exe");
+ appEntry.Extract(tempFolder);
}
- });
- }
-
- /// <summary>
- /// Checks whether any post update packages needs to be installed.
- /// </summary>
- /// <returns></returns>
- public Task<bool> PostUpdatePackagesRequired()
- {
- String packagesFolder = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "packages");
- return _packageRunner.IsPackageInstallationRequired(PackageType.Post, packagesFolder);
- }
-
- /// <summary>
- /// Runs all post update packages.
- /// </summary>
- /// <returns></returns>
- public Task<PackageRunnerResult> RunPostUpdatePackages()
- {
- String packagesFolder = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "packages");
- Version previousVersion = null;
- String str = _settings.PreviousApplicationVersion;
+ FileVersionInfo info = FileVersionInfo.GetVersionInfo(Path.Combine(tempFolder, "Tango.PPC.UI.exe"));
+ file.Version = Version.Parse(info.ProductVersion);
- if (Version.TryParse(str, out previousVersion))
- {
- return _packageRunner.Run(PackageType.Post, previousVersion, packagesFolder);
- }
- else
- {
- throw new InvalidCastException($"Error parsing the previous version string '{str}'.");
- }
- }
+ tempFolder.Delete();
- public Task RestoreLastDatabaseBackup()
- {
- return Task.Factory.StartNew(() =>
- {
- LogManager.Log("Rolling back database changes...");
- UpdateProgress("Rollback", "Rolling back database changes...");
-
- var localDataSource = SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource;
- var lastBackupFile = SettingsManager.Default.GetOrCreate<PPCSettings>().LastDatabaseBackupFile;
-
- using (DbManager db = DbManager.FromDataSource(localDataSource))
- {
- try
- {
- db.Restore(localDataSource.Catalog, lastBackupFile);
- LogManager.Log("Database restored successfully.");
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Could not rollback the database after a failed updater.");
- throw ex;
- }
- finally
- {
- try
- {
- File.Delete(lastBackupFile);
- }
- catch { }
- }
- }
+ return file;
});
}
@@ -1705,56 +677,5 @@ namespace Tango.PPC.Common.MachineUpdate
}
#endregion
-
- #region Auto Check For Update
-
- private async void _checkForUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
- {
- if (EnableAutoCheckForUpdates && _settings.AutoCheckForUpdates && !_isUpdating)
- {
- _checkForUpdateTimer.Stop();
-
- try
- {
- var response = await CheckForUpdate();
- if (response.IsUpdateAvailable || response.IsDatabaseUpdateAvailable)
- {
- LogManager.Log($"New {(response.IsDatabaseUpdateAvailable ? "database updates" : "application version")} detected ({response.Version}). Raising event...");
- UpdateAvailable?.Invoke(this, response);
- }
- }
- catch { }
-
- _checkForUpdateTimer.Start();
- }
- }
-
- #endregion
-
- #region External Bridge
-
- public void OnReceiverDisconnected(ExternalBridgeReceiver receiver)
- {
- //Do nothing.
- }
-
- [ExternalBridgeRequestHandlerMethod(typeof(GetUpdatesAndPackagesRequest), RequestHandlerLoggingMode.LogRequestName)]
- public async Task OnGetUpdatesAndPackagesRequest(GetUpdatesAndPackagesRequest request, String token, ExternalBridgeReceiver receiver)
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
- {
- var updates = await db.TangoUpdates.OrderByDescending(x => x.StartDate).ToListAsync();
- var updatesDTO = updates.Select(x => TangoUpdateDTO.FromObservable(x)).ToList();
- var packages = (await _packageRunner.GetPackagesFile()).PackageInstallations;
-
- var response = new GetUpdatesAndPackagesResponse();
- response.Updates.AddRange(updatesDTO);
- response.Packages.AddRange(packages);
-
- await receiver.SendGenericResponse(response, token);
- }
- }
-
- #endregion
}
}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs
index 85dd5b7d2..17ae394ee 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs
@@ -12,18 +12,5 @@ namespace Tango.PPC.Common.MachineUpdate
/// Gets or sets the temporary update package path from which to get the last downloaded software version.
/// </summary>
public String UpdatePackagePath { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether the application should replace it's binaries.
- /// </summary>
- public bool RequiresBinariesUpdate { get; set; }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="MachineUpdateResult"/> class.
- /// </summary>
- public MachineUpdateResult()
- {
- RequiresBinariesUpdate = true;
- }
}
}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs
new file mode 100644
index 000000000..df496c3be
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Common.MachineUpdate
+{
+ public class UpdatePackageFile
+ {
+ public Version Version { get; set; }
+ }
+}