diff options
| author | Victoria Plitt <Victoria.Plitt@twine-s.com> | 2019-12-18 13:27:02 +0200 |
|---|---|---|
| committer | Victoria Plitt <Victoria.Plitt@twine-s.com> | 2019-12-18 13:27:02 +0200 |
| commit | 41129873d38034c5679eeaf46f48e4f67fd38ba2 (patch) | |
| tree | 94109a9602e91bcf7f114e3491bc8018e60bef4c /Software/Visual_Studio/Web/Tango.MachineService/Controllers | |
| parent | 70e3f2699a500666d1ca4e4d5db2dbaafb339e80 (diff) | |
| parent | a61a911d1ebde107ba7bf210af7e753e692d93e2 (diff) | |
| download | Tango-41129873d38034c5679eeaf46f48e4f67fd38ba2.tar.gz Tango-41129873d38034c5679eeaf46f48e4f67fd38ba2.zip | |
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers')
| -rw-r--r-- | Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs | 76 | ||||
| -rw-r--r-- | Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs | 322 |
2 files changed, 390 insertions, 8 deletions
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs index 2eeaa6e0e..da5ce16f7 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs @@ -23,6 +23,10 @@ using Tango.Web.ActiveDirectory; using Tango.MachineService.Filters; using Tango.MachineService.Security; using Tango.Web.SQLServer; +using Tango.Core; +using Tango.Web.SMO; +using Tango.Core.DB; +using System.Threading.Tasks; namespace Tango.MachineService.Controllers { @@ -281,7 +285,16 @@ namespace Tango.MachineService.Controllers [HttpPost] public LoginResponse Login(LoginRequest request) { - var authResult = _ad_manager.ValidateUserCredentials(request.Email, request.Password); + AuthenticationResult authResult = null; + + try + { + authResult = _ad_manager.ValidateUserCredentials(request.Email, request.Password); + } + catch (Exception ex) + { + throw new AuthenticationException(ex.FlattenMessage()); + } if (!_ad_manager.CanUserAccessCurrentEnvironment(request.Email)) { @@ -425,6 +438,67 @@ namespace Tango.MachineService.Controllers }; } + [HttpPost] + [JwtTokenFilter] + public DownloadLatestPPCVersionResponse DownloadLatestPPCVersion(DownloadLatestPPCVersionRequest request) + { + DownloadLatestPPCVersionResponse response = new DownloadLatestPPCVersionResponse(); + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == request.SerialNumber); + + if (machine == null) + { + throw new AuthenticationException("The specified serial number could not be found."); + } + + var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid); + + var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + + response.Version = latest_machine_version.Version; + + var manager = new BlobStorageManager(); + var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER); + var blob = container.GetBlockBlobReference(latest_machine_version.BlobName); + + response.BlobAddress = blob.GenerateReadSignature(TimeSpan.FromMinutes(60)); + + if (!String.IsNullOrWhiteSpace(MachineServiceConfig.CDN_ENDPOINT)) + { + response.CdnAddress = MachineServiceConfig.CDN_ENDPOINT + blob.Uri.AbsolutePath; + } + + DbCredentials credentials = new DbCredentials(); + + using (SmoManager smo = new SmoManager()) + { + credentials = smo.CreateRandomLoginAndUser(); + + Task.Delay(TimeSpan.FromMinutes(PPCController.SQL_TEMP_CREDENTIALS_EXP_MINUTS)).ContinueWith((x) => + { + using (SmoManager m = new SmoManager()) + { + m.DeleteLoginAndUser(credentials.UserName); + } + }); + } + + response.DataSource = new DataSource() + { + Address = MachineServiceConfig.DB_ADDRESS, + Catalog = MachineServiceConfig.DB_CATALOG, + UserName = credentials.UserName, + Password = credentials.Password, + IntegratedSecurity = false, + Type = DataSourceType.SQLServer, + }; + } + + return response; + } + #endregion } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 2dee09e69..10a732221 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -32,7 +32,7 @@ namespace Tango.MachineService.Controllers private static List<PPCPendingUpload> _pendingUploads; private static List<PPCPendingUpdate> _pendingUpdates; private ActiveDirectoryManager _ad_manager; - private const int SQL_TEMP_CREDENTIALS_EXP_MINUTS = 20; + public const int SQL_TEMP_CREDENTIALS_EXP_MINUTS = 20; public class TokenObject { @@ -107,6 +107,7 @@ namespace Tango.MachineService.Controllers var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); response.Version = latest_machine_version.Version; + response.FirmwareVersion = latest_machine_version.FirmwareVersion; var manager = new BlobStorageManager(); var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER); @@ -195,6 +196,7 @@ namespace Tango.MachineService.Controllers var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); response.Version = latest_machine_version.Version; + response.FirmwareVersion = latest_machine_version.FirmwareVersion; var manager = new BlobStorageManager(); var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER); @@ -273,6 +275,11 @@ namespace Tango.MachineService.Controllers tangoUpdate.FailedReason = request.FailedReason; tangoUpdate.FailedLog = request.FailedLog; + if (request.ReportsAboutDbCheckNoDifferences) + { + db.TangoUpdates.Remove(tangoUpdate); + } + db.SaveChanges(); } } @@ -313,6 +320,7 @@ namespace Tango.MachineService.Controllers } response.Version = latest_machine_version.Version; + response.FirmwareVersion = latest_machine_version.FirmwareVersion; //Compare database @@ -322,7 +330,12 @@ namespace Tango.MachineService.Controllers bool hasDatabaseUpdates = false; - hasDatabaseUpdates = rmls.Exists(x => request.Rmls.Exists(y => x.Guid == y.Guid && x.LastUpdated > y.LastUpdated) || !request.Rmls.Exists(y => x.Guid == y.Guid)); + hasDatabaseUpdates = machine.LastUpdated > request.MachineLastUpdated; + + if (!hasDatabaseUpdates) + { + hasDatabaseUpdates = rmls.Exists(x => request.Rmls.Exists(y => x.Guid == y.Guid && x.LastUpdated > y.LastUpdated) || !request.Rmls.Exists(y => x.Guid == y.Guid)); + } if (!hasDatabaseUpdates) { @@ -398,12 +411,9 @@ namespace Tango.MachineService.Controllers Type = DataSourceType.SQLServer, }; - var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid); - var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); - TangoUpdate tangoUpdate = new TangoUpdate(); - tangoUpdate.ApplicationVersion = latest_machine_version.Version; - tangoUpdate.FirmwareVersion = latest_machine_version.FirmwareVersion; + tangoUpdate.ApplicationVersion = request.ApplicationVersion; + tangoUpdate.FirmwareVersion = request.FirmwareVersion; tangoUpdate.MachineGuid = machine.Guid; tangoUpdate.StartDate = DateTime.UtcNow; tangoUpdate.UpdateStatus = TangoUpdateStatuses.DatabaseStarted; @@ -423,6 +433,304 @@ namespace Tango.MachineService.Controllers #endregion + #region Synchronization + + [HttpPost] + [JwtTokenFilter] + public UploadMachineDataResponse UploadMachineData(UploadMachineDataRequest request) + { + UploadMachineDataResponse response = new UploadMachineDataResponse(); + response.NotifyCompletedToken = Guid.NewGuid().ToString(); + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + var machine = db.Machines.SingleOrDefault(x => x.Guid == RequestToken.Object.MachineGuid); + + if (machine == null) + { + throw new AuthenticationException("The specified machine could not be found."); + } + + TangoUpdate tangoUpdate = new TangoUpdate(); + tangoUpdate.ApplicationVersion = request.ApplicationVersion; + tangoUpdate.FirmwareVersion = request.FirmwareVersion; + tangoUpdate.MachineGuid = machine.Guid; + tangoUpdate.StartDate = DateTime.UtcNow; + tangoUpdate.UpdateStatus = TangoUpdateStatuses.SynchronizationStarted; + db.TangoUpdates.Add(tangoUpdate); + db.SaveChanges(); + + _pendingUpdates.Add(new PPCPendingUpdate() + { + Token = response.NotifyCompletedToken, + TangoUpdateGuid = tangoUpdate.Guid, + }); + } + + User machineUser = null; + + try + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + var machine = db.Machines.SingleOrDefault(x => x.Guid == RequestToken.Object.MachineGuid); + + if (machine == null) + { + 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. + foreach (var dto in request.Jobs) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + try + { + var job = dto.ToObservable(); + + job.ID = 0; + job.UserGuid = machineUser.Guid; + job.CustomerGuid = null; + job.IsSynchronized = true; + + var existingJob = db.Jobs.SingleOrDefault(x => x.Guid == job.Guid); + + if (existingJob == null) + { + db.Jobs.Add(job); + db.SaveChanges(); + } + else if (job.LastUpdated > existingJob.LastUpdated) + { + existingJob.Delete(db); + db.Jobs.Add(job); + db.SaveChanges(); + } + } + catch (Exception ex) + { + response.FailedJobs.Add(new SynchronizationFailedEntity() + { + Guid = dto.Guid, + Reason = ex.FlattenMessage(), + }); + } + } + } + + //Insert JobRuns. + foreach (var dto in request.JobRuns) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + try + { + var run = dto.ToObservable(); + run.ID = 0; + run.IsSynchronized = true; + + if (db.JobRuns.SingleOrDefault(x => x.Guid == run.Guid) == null) + { + db.JobRuns.Add(run); + db.SaveChanges(); + } + } + catch (Exception ex) + { + response.FailedJobRuns.Add(new SynchronizationFailedEntity() + { + Guid = dto.Guid, + Reason = ex.FlattenMessage(), + }); + } + } + } + + //Insert MachineEvents. + foreach (var dto in request.MachineEvents) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + try + { + var ev = dto.ToObservable(); + ev.ID = 0; + ev.UserGuid = machineUser.Guid; + 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(), + }); + } + } + } + + //Insert TangoUpdates. + foreach (var dto in request.OfflineUpdates) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + try + { + var update = dto.ToObservable(); + update.ID = 0; + update.IsSynchronized = true; + + if (db.TangoUpdates.SingleOrDefault(x => x.Guid == update.Guid) == null) + { + db.TangoUpdates.Add(update); + db.SaveChanges(); + } + } + catch (Exception ex) + { + response.FailedOfflineUpdates.Add(new SynchronizationFailedEntity() + { + Guid = dto.Guid, + Reason = ex.FlattenMessage(), + }); + } + } + } + } + catch (Exception ex) + { + NotifyUpdateCompleted(new MachineUpdateCompletedRequest() + { + Status = TangoUpdateStatuses.SynchronizationFailed, + FailedReason = ex.FlattenMessage(), + FailedLog = ex.FlattenException(), + Token = response.NotifyCompletedToken, + }); + throw ex; + } + + return response; + } + + [HttpPost] + [JwtTokenFilter] + public DownloadMachineDataResponse DownloadMachineData(DownloadMachineDataRequest request) + { + DownloadMachineDataResponse response = new DownloadMachineDataResponse(); + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + var machine = db.Machines.SingleOrDefault(x => x.Guid == RequestToken.Object.MachineGuid); + + if (machine == null) + { + throw new AuthenticationException("The specified machine could not be found."); + } + + //Send Jobs + if (request.RequestJobs) + { + var jobs = new JobsCollectionBuilder(db).Set(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).WithSegments().WithBrushStops().Query(x => x.Take(request.MaxJobs).OrderByDescending(z => z.LastUpdated)).BuildList(); + + foreach (var job in jobs) + { + JobDTO dto = JobDTO.FromObservable(job); + response.Jobs.Add(dto); + } + } + + //Send Job Runs + if (request.RequestJobRuns) + { + var jobRuns = db.JobRuns.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxJobRuns).OrderByDescending(x => x.LastUpdated).ToList(); + + foreach (var jobRun in jobRuns) + { + JobRunDTO dto = JobRunDTO.FromObservable(jobRun); + response.JobRuns.Add(dto); + } + } + + //Send Machine Events + if (request.RequestMachineEvents) + { + var machineEvents = db.MachinesEvents.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxMachinesEvents).OrderByDescending(x => x.LastUpdated).ToList(); + + foreach (var machineEvent in machineEvents) + { + MachinesEventDTO dto = MachinesEventDTO.FromObservable(machineEvent); + response.MachineEvents.Add(dto); + } + } + } + + return response; + } + + [HttpPost] + [JwtTokenFilter] + public NotifyMachineDataDownloadCompletedResponse NotifyMachineDataDownloadCompleted(NotifyMachineDataDownloadCompletedRequest request) + { + var response = new NotifyMachineDataDownloadCompletedResponse(); + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + var machine = db.Machines.SingleOrDefault(x => x.Guid == RequestToken.Object.MachineGuid); + + if (machine == null) + { + throw new AuthenticationException("The specified machine could not be found."); + } + + if (request.SynchronizedJobs.Count > 0) + { + db.Database.ExecuteSqlCommand($"UPDATE JOBS SET IS_SYNCHRONIZED = 1 WHERE GUID IN ({String.Join(",", request.SynchronizedJobs.Select(x => "'" + x + "'"))});"); + } + + if (request.SynchronizedJobRuns.Count > 0) + { + db.Database.ExecuteSqlCommand($"UPDATE JOB_RUNS SET IS_SYNCHRONIZED = 1 WHERE GUID IN ({String.Join(",", request.SynchronizedJobRuns.Select(x => "'" + x + "'"))});"); + } + + if (request.SynchronizedMachineEvents.Count > 0) + { + db.Database.ExecuteSqlCommand($"UPDATE MACHINES_EVENTS SET IS_SYNCHRONIZED = 1 WHERE GUID IN ({String.Join(",", request.SynchronizedMachineEvents.Select(x => "'" + x + "'"))});"); + } + } + + return response; + } + + #endregion + #region Version Upload [HttpPost] |
