/// <summary> /// Processes the request asynchronously. /// </summary> protected override async Task <ContractExecutionResult> ProcessAsyncEx <T>(T item) { var request = CastRequestObjectTo <TRexEditDataRequest>(item); var result = new ContractExecutionResult(); try { log.LogInformation($"#In# RemoveEditDataExecutor. Remove data edit {JsonConvert.SerializeObject(request)}"); var overrideRequest = new OverrideEventRequest(); var arg = new OverrideEventRequestArgument(true, request.ProjectUid, request.AssetUid, request.StartUtc, request.EndUtc, request.MachineDesignName, (ushort?)request.LiftNumber); var overrideResult = await overrideRequest.ExecuteAsync(arg); if (!overrideResult.Success) { log.LogInformation($"Failed to remove data edit: {overrideResult.Message}"); result = new ContractExecutionResult(ContractExecutionStatesEnum.InternalProcessingError, overrideResult.Message); } } finally { log.LogInformation($"#Out# RemoveEditDataExecutor. Add data edit {JsonConvert.SerializeObject(request)}"); } return(result); }
public void Test_OverrideEventRequestArgument() { var argument = new OverrideEventRequestArgument { Undo = true, ProjectID = Guid.NewGuid(), AssetID = Guid.NewGuid(), StartUTC = DateTime.UtcNow.AddMinutes(-2), EndUTC = DateTime.UtcNow, MachineDesignName = "some design", LayerID = 2 }; SimpleBinarizableInstanceTester.TestClass(argument, "Custom OverrideEventRequestArgument not same after round trip serialisation"); }
public void Test_OverrideEventRequestArgument_CreationWithArgs() { var undo = false; var siteModelID = Guid.NewGuid(); var assetID = Guid.NewGuid(); var startUTC = DateTime.UtcNow.AddMinutes(-10); var endUTC = DateTime.UtcNow.AddMinutes(-1); var machineDesignName = "Southern Motorway 1.4"; var layerID = (ushort)2; var arg = new OverrideEventRequestArgument(undo, siteModelID, assetID, startUTC, endUTC, machineDesignName, layerID); Assert.NotNull(arg); Assert.Equal(undo, arg.Undo); Assert.Equal(siteModelID, arg.ProjectID); Assert.Equal(assetID, arg.AssetID); Assert.Equal(startUTC, arg.StartUTC); Assert.Equal(endUTC, arg.EndUTC); Assert.Equal(machineDesignName, arg.MachineDesignName); Assert.Equal(layerID, arg.LayerID); }
/// <summary> /// Removes the override event from the site model. /// </summary> public async Task <OverrideEventResponse> ExecuteAsync(OverrideEventRequestArgument arg) { Log.LogInformation($"START Remove Override Event Executor: Project={arg.ProjectID}, Asset={arg.AssetID}, Date Range={arg.StartUTC}-{arg.EndUTC}"); var result = new OverrideEventResponse { Success = false }; var siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(arg.ProjectID); if (siteModel == null) { result.Message = $"Failed to locate site model {arg.ProjectID}"; Log.LogError(result.Message); return(result); } bool changed = false; lock (siteModel) { if (arg.AssetID == Guid.Empty) { //If AssetID not provided, remove all override events for project Log.LogDebug($"Removing override events for all assets in project {arg.ProjectID}"); foreach (var machine in siteModel.Machines) { if (RemoveOverrideEventsForMachine(siteModel, machine, arg)) { changed = true; } } } else { var machine = siteModel.Machines.Locate(arg.AssetID); if (machine == null) { result.Message = $"Failed to locate machine {arg.AssetID}"; Log.LogError(result.Message); return(result); } Log.LogDebug($"Removing override events for asset {arg.AssetID}"); changed = RemoveOverrideEventsForMachine(siteModel, machine, arg); } if (changed) { Log.LogDebug($"Notifying grid of changes to project {arg.ProjectID}"); // Notify the immutable grid listeners that attributes of this site model have changed. var sender = DIContext.Obtain <ISiteModelAttributesChangedEventSender>(); sender.ModelAttributesChanged(SiteModelNotificationEventGridMutability.NotifyImmutable, siteModel.ID, machineTargetValuesChanged: true); } } if (!changed) { result.Message = "No override event(s) found to remove"; } result.Success = changed; Log.LogInformation($"END Remove Override Event Executor: Project={arg.ProjectID}, Asset={arg.AssetID}, Date Range={arg.StartUTC}-{arg.EndUTC}"); return(result); }
/// <summary> /// Remove requested machine design and layer override events for given machine /// </summary> private bool RemoveOverrideEventsForMachine(ISiteModel siteModel, IMachine machine, OverrideEventRequestArgument arg) { var changed = false; var machineTargetValues = siteModel.MachinesTargetValues[machine.InternalSiteModelMachineIndex]; //Remove design overrides if (!string.IsNullOrEmpty(arg.MachineDesignName)) { var overrideDesignEvents = machineTargetValues.DesignOverrideEvents; if (RemoveOverrideEventsForMachine(arg.StartUTC, arg.EndUTC, overrideDesignEvents)) { changed = true; } } //Remove layer overrides if (arg.LayerID.HasValue) { var overrideLayerEvents = machineTargetValues.LayerOverrideEvents; if (RemoveOverrideEventsForMachine(arg.StartUTC, arg.EndUTC, overrideLayerEvents)) { changed = true; } } if (changed) { Log.LogDebug($"Saving override events: Project={arg.ProjectID}, Asset={machine.ID}, Date Range={arg.StartUTC}-{arg.EndUTC}"); // Use the synchronous command to save the machine events to the persistent store into the deferred (asynchronous model) machineTargetValues.SaveMachineEventsToPersistentStore(storageProxy_Mutable); } return(changed); }
/// <summary> /// Inserts the override event into the site model. /// </summary> public async Task <OverrideEventResponse> ExecuteAsync(OverrideEventRequestArgument arg) { Log.LogInformation($"START Add Override Event Executor: Project={arg.ProjectID}, Asset={arg.AssetID}, Date Range={arg.StartUTC}-{arg.EndUTC}"); var result = new OverrideEventResponse { Success = false }; if (arg.StartUTC >= arg.EndUTC) { result.Message = $"Invalid date range. Start:{arg.StartUTC} End:{arg.EndUTC}"; return(result); } if (string.IsNullOrEmpty(arg.MachineDesignName) && !arg.LayerID.HasValue) { result.Message = "Missing override values"; Log.LogError(result.Message); return(result); } var siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(arg.ProjectID); if (siteModel == null) { result.Message = $"Failed to locate site model {arg.ProjectID}"; Log.LogError(result.Message); return(result); } lock (siteModel) { var machine = siteModel.Machines.Locate(arg.AssetID); if (machine == null) { result.Message = $"Failed to locate machine {arg.AssetID}"; Log.LogError(result.Message); return(result); } //Test targets exist i.e. we have some machine events to override var machineTargetValues = siteModel.MachinesTargetValues[machine.InternalSiteModelMachineIndex]; if (arg.LayerID.HasValue && machineTargetValues.LayerIDStateEvents.Count() == 0 || !string.IsNullOrEmpty(arg.MachineDesignName) && machineTargetValues.MachineDesignNameIDStateEvents.Count() == 0) { result.Message = "No target values found to override"; Log.LogError(result.Message); return(result); } // Now we should check there are no overlapping override events for a new event in this list if (arg.LayerID.HasValue && !ValidateNewOverrideEventAgainstExistingOverridingEvents(machineTargetValues.LayerOverrideEvents, arg)) { //We are not able to override event as there is already overridden event result.Message = $"Layer override failed event date validation {arg.StartUTC}-{arg.EndUTC}"; Log.LogError(result.Message); return(result); } if (!string.IsNullOrEmpty(arg.MachineDesignName) && !ValidateNewOverrideEventAgainstExistingOverridingEvents(machineTargetValues.DesignOverrideEvents, arg)) { result.Message = $"Design override failed event date validation {arg.StartUTC}-{arg.EndUTC}"; Log.LogError(result.Message); return(result); } Log.LogDebug($"Override event passed validation checks, about to add to list: Project={arg.ProjectID}, Asset={arg.AssetID}, Date Range={arg.StartUTC}-{arg.EndUTC}"); //Override lift if (arg.LayerID.HasValue) { machineTargetValues.LayerOverrideEvents.PutValueAtDate(arg.StartUTC, new OverrideEvent <ushort>(arg.EndUTC, arg.LayerID.Value)); } //Override machine design if (!string.IsNullOrEmpty(arg.MachineDesignName)) { //Try to find corresponding designId var siteModelMachineDesign = siteModel.SiteModelMachineDesigns.Locate(arg.MachineDesignName); if (siteModelMachineDesign == null) { siteModelMachineDesign = siteModel.SiteModelMachineDesigns.CreateNew(arg.MachineDesignName); } machineTargetValues.DesignOverrideEvents.PutValueAtDate(arg.StartUTC, new OverrideEvent <int>(arg.EndUTC, siteModelMachineDesign.Id)); } Log.LogDebug($"Saving override events: Project={arg.ProjectID}, Asset={arg.AssetID}, Date Range={arg.StartUTC}-{arg.EndUTC}"); machineTargetValues.SaveMachineEventsToPersistentStore(storageProxy_Mutable); // Notify the immutable grid listeners that attributes of this site model have changed. Log.LogDebug($"Notifying grid of changes to project {arg.ProjectID}"); var sender = DIContext.Obtain <ISiteModelAttributesChangedEventSender>(); sender.ModelAttributesChanged(SiteModelNotificationEventGridMutability.NotifyImmutable, siteModel.ID, machineTargetValuesChanged: true); result.Success = true; } Log.LogInformation($"END Add Override Event Executor: Project={arg.ProjectID}, Asset={arg.AssetID}, Date Range={arg.StartUTC}-{arg.EndUTC}"); return(result); }
/// <summary> /// Checks the new override event has a valid date range. It cannot overlap existing override events. /// </summary> private bool ValidateNewOverrideEventAgainstExistingOverridingEvents <T>(IProductionEvents <OverrideEvent <T> > existingList, OverrideEventRequestArgument arg) { //Test if we override event within the range or we have overlapping overriding bool noOverlap = true; //Test if we have overlapping for the start date of the event //Note closest prior and closest subsequent include event at date itself var index = existingList.IndexOfClosestEventPriorToDate(arg.EndUTC); if (index >= 0) { existingList.GetStateAtIndex(index, out var startDate, out var evt); if (startDate != arg.EndUTC) //Ignore exact event time matches { noOverlap = arg.StartUTC >= evt.EndDate; } } //Test if we have overlapping for the end date of the event index = existingList.IndexOfClosestEventSubsequentToDate(arg.StartUTC); if (index >= 0) { existingList.GetStateAtIndex(index, out var startDate, out _); if (startDate != arg.StartUTC) { noOverlap = noOverlap && arg.EndUTC <= startDate; } } return(noOverlap); }
public void Test_OverrideEventRequestArgument_Creation() { var arg = new OverrideEventRequestArgument(); Assert.NotNull(arg); }