protected override bool OnExecute(ServerActionContext context) { DateTime scheduledTime = Platform.Time; if (_exprScheduledTime != null) { scheduledTime = Evaluate(_exprScheduledTime, context, scheduledTime); } scheduledTime = CalculateOffsetTime(scheduledTime, _offsetTime, _units); XmlDocument doc = new XmlDocument(); XmlElement element = doc.CreateElement("compress"); doc.AppendChild(element); XmlAttribute syntaxAttribute = doc.CreateAttribute("syntax"); syntaxAttribute.Value = TransferSyntax.Jpeg2000ImageCompressionUid; element.Attributes.Append(syntaxAttribute); syntaxAttribute = doc.CreateAttribute("ratio"); syntaxAttribute.Value = _ratio.ToString(); element.Attributes.Append(syntaxAttribute); Platform.Log(LogLevel.Debug, "Jpeg 2000 Lossy Compression Scheduling: This study will be compressed on {0}", scheduledTime); context.CommandProcessor.AddCommand( new InsertFilesystemQueueCommand(_queueType, context.FilesystemKey, context.StudyLocationKey, scheduledTime, doc)); return(true); }
/// <summary> /// Creates an instance of <see cref="UpdateSeriesCommand"/> to update the existing Series record in the database /// </summary> public UpdateSeriesCommand(StudyStorageLocation storageLocation, ServerActionContext sopContext) : base(String.Concat("Update Series Command")) { _storageLocation = storageLocation; _data = sopContext.Message.DataSet; _context = sopContext; }
/// <summary> /// Constructor. /// </summary> /// <param name="context">A contentxt in which to apply the AutoRoute request.</param> /// <param name="device">The AE Title of the device to AutoRoute to.</param> public InsertAutoRouteCommand(ServerActionContext context, string device) : base("Update/Insert an AutoRoute WorkQueue Entry") { Platform.CheckForNullReference(context, "ServerActionContext"); _context = context; _deviceAe = device; }
/// <summary> /// Constructor. /// </summary> /// <param name="context">A contentxt in which to apply the GrantAccess request.</param> /// <param name="authorityGroupOid">The OID of the Authority Group to grant access to the Study.</param> public InsertStudyDataAccessCommand(ServerActionContext context, Guid authorityGroupOid) : base("Update/Insert a StudyDataAccess Entry") { Platform.CheckForNullReference(context, "ServerActionContext"); _context = context; _authorityGroupOid = authorityGroupOid; }
public ApplyRulesCommand(string directory, string studyInstanceUid, ServerActionContext context) : base("Apply Server Rules", true) { _directory = directory; _studyInstanceUid = studyInstanceUid; _context = context; _engine = new ServerRulesEngine(ServerRuleApplyTimeEnum.StudyRestored, _context.ServerPartitionKey); _engine.Load(); }
/// <summary> /// Constructor. /// </summary> /// <param name="context">A contentxt in which to apply the AutoRoute request.</param> /// <param name="device">The AE Title of the device to AutoRoute to.</param> public InsertAutoRouteCommand(ServerActionContext context, string device) : base("Update/Insert an AutoRoute WorkQueue Entry") { Platform.CheckForNullReference(context, "ServerActionContext"); _context = context; _deviceAe = device; }
/// <summary> /// Constructor. /// </summary> /// <param name="context">A contentxt in which to apply the GrantAccess request.</param> /// <param name="authorityGroupOid">The OID of the Authority Group to grant access to the Study.</param> public InsertStudyDataAccessCommand(ServerActionContext context, Guid authorityGroupOid) : base("Update/Insert a StudyDataAccess Entry") { Platform.CheckForNullReference(context, "ServerActionContext"); _context = context; _authorityGroupOid = authorityGroupOid; }
/// <summary> /// Constructor. /// </summary> /// <param name="context">A contentxt in which to apply the AutoRoute request.</param> /// <param name="device">The AE Title of the device to AutoRoute to.</param> /// <param name="scheduledTime">The scheduled time for the AutoRoute.</param> /// <param name="e">An option required QC StatusEnum value</param> public InsertStudyAutoRouteCommand(ServerActionContext context, string device, DateTime scheduledTime, QCStatusEnum e) : base("Update/Insert an AutoRoute WorkQueue Entry") { Platform.CheckForNullReference(context, "ServerActionContext"); _context = context; _deviceAe = device; _scheduledTime = scheduledTime; _qcStatus = e; }
/// <summary> /// Constructor. /// </summary> /// <param name="context">A contentxt in which to apply the AutoRoute request.</param> /// <param name="device">The AE Title of the device to AutoRoute to.</param> /// <param name="scheduledTime">The scheduled time for the AutoRoute.</param> /// <param name="e">An option required QC StatusEnum value</param> public InsertStudyAutoRouteCommand(ServerActionContext context, string device, DateTime scheduledTime, QCStatusEnum e) : base("Update/Insert an AutoRoute WorkQueue Entry") { Platform.CheckForNullReference(context, "ServerActionContext"); _context = context; _deviceAe = device; _scheduledTime = scheduledTime; _qcStatus = e; }
public ReleaseInstanceWithExistingSession() { _context = CreateContext(InitSessionAction); _instance = new InstanceObject(); Mock.Setup(o => o.CreateInstance(It.IsAny <ServerActionContext>(), typeof(IMockContract))).Returns(_instance).Verifiable(); Mock.Setup(o => o.GenerateSessionid()).Returns(SessionHeaderValue); Subject.GetInstanceAsync(_context, typeof(IMockContract)).GetAwaiter().GetResult(); _session = _context.HttpContext.Features.Get <IContractSession>(); }
protected override object CreateInstance(ServerActionContext context, Type type) { var factory = _factory; if (factory == null) { factory = ActivatorUtilities.CreateFactory(_type, Array.Empty <Type>()); _factory = factory; } return(factory(context.HttpContext.RequestServices, null)); }
private RawContractMetadata CrateContractMetadata(ServerActionContext context) { var feature = context.HttpContext.Features.Get <IBoltFeature>(); var m = new RawContractMetadata { Actions = context.Contract.Actions.ToArray().Select(a => a.Name).ToList(), ErrorHeader = feature.ActionContext.Configuration.Options.ServerErrorHeader, ContentTypes = feature.ActionContext.Configuration.AvailableSerializers.Select(s => s.MediaType).ToArray() }; return(m); }
public virtual async Task HandleContractMetadataAsync(ServerActionContext context) { try { string result; string actionName = context.HttpContext.Request.Query["action"]; Bolt.Metadata.ActionMetadata action = null; if (!string.IsNullOrEmpty(actionName)) { action = _actionResolver.Resolve(context.Contract, actionName.AsReadOnlySpan()); } if (action == null) { var contractMetadata = CrateContractMetadata(context); result = JsonConvert.SerializeObject(contractMetadata, Formatting.Indented, CreateSettings()); } else { context.Action = action; ActionMetadata actionMetadata = new ActionMetadata(); if (context.Action.HasSerializableParameters) { actionMetadata.Parameters = context.Action.Parameters.Where(p => p.IsSerializable).Select(p => p.Name).ToArray(); } if (context.Action.HasResult) { actionMetadata.Response = context.Action.ResultType.Name; } result = JsonConvert.SerializeObject(actionMetadata, Formatting.Indented, CreateSettings()); } context.HttpContext.Response.ContentType = "application/json"; context.HttpContext.Response.StatusCode = 200; await context.HttpContext.Response.WriteAsync(result); } catch (Exception e) { Logger.LogWarning( BoltLogId.HandleContractMetadataError, "Failed to generate Bolt metadata for contract '{0}'. Error: {1}", context.Contract.Name, e); } }
/// <summary> /// Overwrites existing copy with the received duplicate. Update the database, study xml and applies any SOP rules. /// </summary> /// <param name="dupFile"></param> /// <param name="uid"></param> /// <param name="studyXml"></param> /// <returns></returns> private ProcessDuplicateResult OverwriteAndUpdateDuplicate(DicomFile dupFile, WorkQueueUid uid, StudyXml studyXml) { Platform.Log(LogLevel.Info, "Overwriting duplicate SOP {0}", uid.SopInstanceUid); var result = new ProcessDuplicateResult(); result.ActionTaken = DuplicateProcessResultAction.Accept; using (var processor = new ServerCommandProcessor("Overwrite duplicate instance")) { var sopContext = new ServerActionContext(dupFile, Context.StorageLocation.FilesystemKey, Context.StorageLocation.ServerPartition, Context.StorageLocation.Key, processor); var destination = Context.StorageLocation.GetSopInstancePath(uid.SeriesInstanceUid, uid.SopInstanceUid); processor.AddCommand(new RenameFileCommand(dupFile.Filename, destination, false)); // Do so that the FileSize calculation inInsertStudyXmlCommand works dupFile.Filename = destination; // Update the StudyStream object var insertStudyXmlCommand = new InsertStudyXmlCommand(dupFile, studyXml, Context.StorageLocation); processor.AddCommand(insertStudyXmlCommand); // Ideally we don't need to insert the instance into the database since it's a duplicate. // However, we need to do so to ensure the Study record is recreated if we are dealing with an orphan study. // For other cases, this will cause the instance count in the DB to be out of sync with the filesystem. // But it will be corrected at the end of the processing when the study verification is executed. processor.AddCommand(new UpdateInstanceCommand(Context.StorageLocation.ServerPartition, Context.StorageLocation, dupFile)); processor.AddCommand(new DeleteWorkQueueUidCommand(uid)); processor.AddCommand(new ApplySopRulesCommand(sopContext, Context.SopProcessedRulesEngine)); if (!processor.Execute()) { EventManager.FireEvent(this, new FailedUpdateSopEventArgs { File = dupFile, ServerPartitionEntry = Context.StorageLocation.ServerPartition, WorkQueueUidEntry = uid, WorkQueueEntry = WorkQueueItem, FileLength = (ulong)insertStudyXmlCommand.FileSize, FailureMessage = processor.FailureReason }); // cause the item to fail throw new Exception(string.Format("Error occurred when trying to overwrite duplicate in the filesystem."), processor.FailureException); } EventManager.FireEvent(this, new UpdateSopEventArgs { File = dupFile, ServerPartitionEntry = Context.StorageLocation.ServerPartition, WorkQueueUidEntry = uid, WorkQueueEntry = WorkQueueItem, FileLength = (ulong)insertStudyXmlCommand.FileSize }); } return(result); }
protected override bool OnExecute(ServerActionContext context) { XmlDocument doc = new XmlDocument(); XmlElement element = doc.CreateElement("compress"); doc.AppendChild(element); XmlAttribute syntaxAttribute = doc.CreateAttribute("syntax"); syntaxAttribute.Value = TransferSyntax.Jpeg2000ImageCompressionLosslessOnlyUid; element.Attributes.Append(syntaxAttribute); context.CommandProcessor.AddCommand( new DicomCompressCommand(context.Message, doc)); return true; }
public async Task ExecuteAsync(ServerActionContext context) { var result = _compiledLambda(context.ContractInstance, context.Parameters); if (_isTaskResult) { await(Task) result; if (_taskResultProvider != null) { context.ActionResult = _taskResultProvider((Task)result); } } else { context.ActionResult = result; } }
protected override bool OnExecute(ServerActionContext context) { XmlDocument doc = new XmlDocument(); XmlElement element = doc.CreateElement("compress"); doc.AppendChild(element); XmlAttribute syntaxAttribute = doc.CreateAttribute("syntax"); syntaxAttribute.Value = TransferSyntax.Jpeg2000ImageCompressionLosslessOnlyUid; element.Attributes.Append(syntaxAttribute); context.CommandProcessor.AddCommand( new DicomCompressCommand(context.Message, doc)); return(true); }
private void SaveFile(DicomFile file) { String seriesInstanceUid = file.DataSet[DicomTags.SeriesInstanceUid].GetString(0, String.Empty); String sopInstanceUid = file.DataSet[DicomTags.SopInstanceUid].GetString(0, String.Empty); String destPath = _oldStudyLocation.FilesystemPath; using (ServerCommandProcessor filesystemUpdateProcessor = new ServerCommandProcessor("Update Study")) { filesystemUpdateProcessor.AddCommand(new CreateDirectoryCommand(destPath)); destPath = Path.Combine(destPath, _partition.PartitionFolder); filesystemUpdateProcessor.AddCommand(new CreateDirectoryCommand(destPath)); destPath = Path.Combine(destPath, _oldStudyFolder); filesystemUpdateProcessor.AddCommand(new CreateDirectoryCommand(destPath)); destPath = Path.Combine(destPath, _newStudyInstanceUid); filesystemUpdateProcessor.AddCommand(new CreateDirectoryCommand(destPath)); destPath = Path.Combine(destPath, seriesInstanceUid); filesystemUpdateProcessor.AddCommand(new CreateDirectoryCommand(destPath)); destPath = Path.Combine(destPath, sopInstanceUid); destPath += ServerPlatform.DicomFileExtension; // Overwrite the prior file SaveDicomFileCommand saveCommand = new SaveDicomFileCommand(destPath, file, false); filesystemUpdateProcessor.AddCommand(saveCommand); if (_rulesEngine != null) { ServerActionContext context = new ServerActionContext(file, _oldStudyLocation.FilesystemKey, _partition, _oldStudyLocation.Key) { CommandProcessor = filesystemUpdateProcessor }; _rulesEngine.Execute(context); } if (!filesystemUpdateProcessor.Execute()) { throw new ApplicationException(String.Format("Unable to update image {0} : {1}", file.Filename, filesystemUpdateProcessor.FailureReason)); } } }
public virtual async Task<bool> HandleBoltMetadataAsync(ServerActionContext context, IEnumerable<IContractInvoker> contracts) { try { string result = JsonConvert.SerializeObject( contracts.Select(c => BoltFramework.GetContractName(c.Contract)).ToList(), Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); await context.HttpContext.Response.WriteAsync(result); return true; } catch (Exception e) { Logger.LogWarning(BoltLogId.HandleBoltRootError, "Failed to generate Bolt root metadata. Error: {0}", e); return false; } }
public virtual async Task HandleBoltMetadataAsync(ServerActionContext context, IEnumerable <IContractInvoker> contracts) { try { string result = JsonConvert.SerializeObject( contracts.Select(c => c.Contract.NormalizedName).ToList(), Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); await context.HttpContext.Response.WriteAsync(result); } catch (Exception e) { Logger.LogWarning(BoltLogId.HandleBoltRootError, "Failed to generate Bolt root metadata. Error: {0}", e); } }
public sealed override async Task<object> GetInstanceAsync(ServerActionContext context, Type type) { IContractSession contractSession; if (context.Action == context.SessionContract.InitSession) { contractSession = await _sessionFactory.CreateAsync(context.HttpContext, await base.GetInstanceAsync(context, type)); context.ContractInstance = contractSession.Instance; context.HttpContext.SetFeature(contractSession); await OnInstanceCreatedAsync(context, contractSession.SessionId); return contractSession.Instance; } contractSession = await _sessionFactory.GetExistingAsync(context.HttpContext, () => base.GetInstanceAsync(context, type)); context.HttpContext.SetFeature(contractSession); return contractSession.Instance; }
public sealed override async Task <object> GetInstanceAsync(ServerActionContext context, Type type) { IContractSession contractSession; if (context.Action == context.Contract.Session.InitSession) { contractSession = await _sessionFactory.CreateAsync(context.HttpContext, () => CreateInstance(context, type)); context.ContractInstance = contractSession.Instance; context.HttpContext.Features.Set <IContractSession>(contractSession); await OnInstanceCreatedAsync(context, contractSession.SessionId); return(contractSession.Instance); } contractSession = await _sessionFactory.GetExistingAsync(context.HttpContext, () => CreateInstance(context, type)); context.HttpContext.Features.Set <IContractSession>(contractSession); return(contractSession.Instance); }
void SaveDuplicateReport(WorkQueueUid uid, string sourceFile, string destinationFile, DicomFile dupFile, StudyXml studyXml) { using (var processor = new ServerCommandProcessor("Save duplicate report")) { var sopContext = new ServerActionContext(dupFile, Context.StorageLocation.FilesystemKey, Context.StorageLocation.ServerPartition, Context.StorageLocation.Key, processor); processor.AddCommand(new RenameFileCommand(sourceFile, destinationFile, false)); // Update the StudyStream object processor.AddCommand(new InsertStudyXmlCommand(dupFile, studyXml, Context.StorageLocation)); // Update the series processor.AddCommand(new UpdateSeriesCommand(Context.StorageLocation, sopContext)); processor.AddCommand(new DeleteWorkQueueUidCommand(uid)); processor.AddCommand(new ApplySopRulesCommand(sopContext, Context.SopProcessedRulesEngine)); processor.Execute(); } }
public sealed override async Task ReleaseInstanceAsync(ServerActionContext context, object obj, Exception error) { var session = context.HttpContext.Features.Get <IContractSession>(); if (session == null) { return; } if (context.Action == context.Contract.Session.InitSession) { if (error != null) { try { await session.DestroyAsync(); await OnInstanceReleasedAsync(context, session.SessionId); } catch (Exception e) { Debug.Assert( false, "Instance release failed after the session initialization error. This exception will be supressed and the session initialization error will be propagated to client.", e.ToString()); } } } else if (context.Action == context.Contract.Session.DestroySession) { await session.DestroyAsync(); await OnInstanceReleasedAsync(context, session.SessionId); } else { await session.CommitAsync(); } }
public sealed override async Task ReleaseInstanceAsync(ServerActionContext context, object obj, Exception error) { var session = context.HttpContext.GetFeature<IContractSession>(); if (session == null) { return; } if (context.Action == context.SessionContract.InitSession) { if (error != null) { try { await session.DestroyAsync(); await OnInstanceReleasedAsync(context, session.SessionId); } catch (Exception e) { Debug.Assert( false, "Instance release failed after the session initialization error. This exception will be supressed and the session initialization error will be propagated to client.", e.ToString()); } } } else if (context.Action == context.SessionContract.DestroySession) { await session.DestroyAsync(); await OnInstanceReleasedAsync(context, session.SessionId); } else { await session.CommitAsync(); } }
public Task ReleaseInstanceAsync(ServerActionContext context, object obj, Exception error) { return(Task.FromResult(true)); }
private void RestoreOnlineStudy(RestoreQueue queueItem, string zipFile, string destinationFolder) { try { using (var processor = new ServerCommandProcessor("HSM Restore Online Study")) { var zipService = Platform.GetService <IZipService>(); using (var zipWriter = zipService.OpenWrite(zipFile)) { foreach (string file in zipWriter.EntryFileNames) { processor.AddCommand(new ExtractZipFileAndReplaceCommand(zipFile, file, destinationFolder)); } } // We rebuild the StudyXml, in case any settings or issues have happened since archival processor.AddCommand(new RebuildStudyXmlCommand(_location.StudyInstanceUid, destinationFolder)); StudyStatusEnum status; if (_syntax.Encapsulated && _syntax.LosslessCompressed) { status = StudyStatusEnum.OnlineLossless; } else if (_syntax.Encapsulated && _syntax.LossyCompressed) { status = StudyStatusEnum.OnlineLossy; } else { status = StudyStatusEnum.Online; } processor.AddCommand(new UpdateStudyStateCommand(_location, status, _serverSyntax)); // Apply the rules engine. var context = new ServerActionContext(null, _location.FilesystemKey, _hsmArchive.ServerPartition, queueItem.StudyStorageKey) { CommandProcessor = processor }; processor.AddCommand( new ApplyRulesCommand(destinationFolder, _location.StudyInstanceUid, context)); if (!processor.Execute()) { Platform.Log(LogLevel.Error, "Unexpected error processing restore request for {0} on archive {1}", _location.StudyInstanceUid, _hsmArchive.PartitionArchive.Description); queueItem.FailureDescription = processor.FailureReason; _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time); } else { // Unlock the Queue Entry and set to complete using (IUpdateContext update = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush)) { _hsmArchive.UpdateRestoreQueue(update, queueItem, RestoreQueueStatusEnum.Completed, Platform.Time.AddSeconds(60)); var studyLock = update.GetBroker <ILockStudy>(); var parms = new LockStudyParameters { StudyStorageKey = queueItem.StudyStorageKey, QueueStudyStateEnum = QueueStudyStateEnum.Idle }; bool retVal = studyLock.Execute(parms); if (!parms.Successful || !retVal) { Platform.Log(LogLevel.Info, "Study {0} on partition {1} failed to unlock.", _location.StudyInstanceUid, _hsmArchive.ServerPartition.Description); } update.Commit(); Platform.Log(LogLevel.Info, "Successfully restored study: {0} on archive {1}", _location.StudyInstanceUid, _hsmArchive.PartitionArchive.Description); _location = ReloadStorageLocation(); OnStudyRestored(_location); } } } } catch (StudyIntegrityValidationFailure ex) { // study has been restored but it seems corrupted. Need to reprocess it. ReprocessStudy(_location, ex.Message); } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception processing restore request for {0} on archive {1}", _location.StudyInstanceUid, _hsmArchive.PartitionArchive.Description); queueItem.FailureDescription = e.Message; _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time); } }
public Task ReleaseInstanceAsync(ServerActionContext context, object obj, Exception error) { return Task.FromResult(true); }
private void SetupRelease(ServerActionContext ctxt = null) { Mock.Setup(o => o.OnInstanceReleased(ctxt ?? _context, SessionHeaderValue)).Verifiable(); }
private ContractMetadata CrateContractMetadata(ServerActionContext context) { var feature = context.HttpContext.GetFeature<IBoltFeature>(); var m = new ContractMetadata { Actions = BoltFramework.GetContractActions(context.Contract).Select(a => a.Name).ToList(), ErrorHeader = feature.ActionContext.Configuration.Options.ServerErrorHeader, ContentType = feature.ActionContext.Configuration.Serializer.ContentType }; return m; }
public BoltFeature(ServerActionContext actionContext) { ActionContext = actionContext; }
protected virtual Task OnInstanceReleasedAsync(ServerActionContext context, string sessionId) { return CompletedTask.Done; }
/// <summary> /// Reprocess a specific study. /// </summary> /// <param name="partition">The ServerPartition the study is on.</param> /// <param name="location">The storage location of the study to process.</param> /// <param name="engine">The rules engine to use when processing the study.</param> /// <param name="postArchivalEngine">The rules engine used for studies that have been archived.</param> /// <param name="dataAccessEngine">The rules engine strictly used for setting data acess.</param> protected static void ProcessStudy(ServerPartition partition, StudyStorageLocation location, ServerRulesEngine engine, ServerRulesEngine postArchivalEngine, ServerRulesEngine dataAccessEngine) { if (!location.QueueStudyStateEnum.Equals(QueueStudyStateEnum.Idle) || !location.AcquireWriteLock()) { Platform.Log(LogLevel.Error, "Unable to lock study {0}. The study is being processed. (Queue State: {1})", location.StudyInstanceUid, location.QueueStudyStateEnum.Description); } else { try { DicomFile msg = LoadInstance(location); if (msg == null) { Platform.Log(LogLevel.Error, "Unable to load file for study {0}", location.StudyInstanceUid); return; } bool archiveQueueExists; bool archiveStudyStorageExists; bool filesystemDeleteExists; using (IReadContext read = PersistentStoreRegistry.GetDefaultStore().OpenReadContext()) { // Check for existing archive queue entries var archiveQueueBroker = read.GetBroker <IArchiveQueueEntityBroker>(); var archiveQueueCriteria = new ArchiveQueueSelectCriteria(); archiveQueueCriteria.StudyStorageKey.EqualTo(location.Key); archiveQueueExists = archiveQueueBroker.Count(archiveQueueCriteria) > 0; var archiveStorageBroker = read.GetBroker <IArchiveStudyStorageEntityBroker>(); var archiveStudyStorageCriteria = new ArchiveStudyStorageSelectCriteria(); archiveStudyStorageCriteria.StudyStorageKey.EqualTo(location.Key); archiveStudyStorageExists = archiveStorageBroker.Count(archiveStudyStorageCriteria) > 0; var filesystemQueueBroker = read.GetBroker <IFilesystemQueueEntityBroker>(); var filesystemQueueCriteria = new FilesystemQueueSelectCriteria(); filesystemQueueCriteria.StudyStorageKey.EqualTo(location.Key); filesystemQueueCriteria.FilesystemQueueTypeEnum.EqualTo(FilesystemQueueTypeEnum.DeleteStudy); filesystemDeleteExists = filesystemQueueBroker.Count(filesystemQueueCriteria) > 0; } using (var commandProcessor = new ServerCommandProcessor("Study Rule Processor") { PrimaryServerPartitionKey = partition.GetKey(), PrimaryStudyKey = location.Study.GetKey() }) { var context = new ServerActionContext(msg, location.FilesystemKey, partition, location.Key, commandProcessor); // Check if the Study has been archived if (archiveStudyStorageExists && !archiveQueueExists && !filesystemDeleteExists) { // Add a command to delete the current filesystemQueue entries, so that they can // be reinserted by the rules engine. context.CommandProcessor.AddCommand(new DeleteFilesystemQueueCommand(location.Key, ServerRuleApplyTimeEnum.StudyArchived)); // How to deal with exiting FilesystemQueue entries is problematic here. If the study // has been migrated off tier 1, we probably don't want to modify the tier migration // entries. Compression entries may have been entered when the Study was initially // processed, we don't want to delete them, because they might still be valid. // We just re-run the rules engine at this point, and delete only the StudyPurge entries, // since those we know at least would only be applied for archived studies. var studyRulesEngine = new StudyRulesEngine(postArchivalEngine, location, location.ServerPartition, location.LoadStudyXml()); studyRulesEngine.Apply(ServerRuleApplyTimeEnum.StudyArchived, commandProcessor); // Post Archive doesn't allow data access rules. Force Data Access rules to be reapplied // to these studies also. dataAccessEngine.Execute(context); } else { // Add a command to delete the current filesystemQueue entries, so that they can // be reinserted by the rules engine. context.CommandProcessor.AddCommand(new DeleteFilesystemQueueCommand(location.Key, ServerRuleApplyTimeEnum.StudyProcessed)); // Execute the rules engine, insert commands to update the database into the command processor. // Due to ticket #11673, we create a new rules engine instance for each study, since the Study QC rules // don't work right now with a single rules engine. //TODO CR (Jan 2014) - Check if we can go back to caching the rules engine to reduce database hits on the rules var studyRulesEngine = new StudyRulesEngine(location, location.ServerPartition, location.LoadStudyXml()); studyRulesEngine.Apply(ServerRuleApplyTimeEnum.StudyProcessed, commandProcessor); } // Do the actual database updates. if (false == context.CommandProcessor.Execute()) { Platform.Log(LogLevel.Error, "Unexpected failure processing Study level rules for study {0}", location.StudyInstanceUid); } // Log the FilesystemQueue related entries location.LogFilesystemQueue(); } } finally { location.ReleaseWriteLock(); } } }
Task <object> IInstanceProvider.GetInstanceAsync(ServerActionContext context, Type type) { return(Task.FromResult(CurrentInstance)); }
public virtual async Task<bool> HandleContractMetadataAsync(ServerActionContext context) { try { string result = string.Empty; string actionName = context.HttpContext.Request.Query["action"]?.Trim(); MethodInfo action = null; if (!string.IsNullOrEmpty(actionName)) { action = _actionResolver.Resolve(context.Contract, actionName); } if (action == null) { var contractMetadata = CrateContractMetadata(context); result = JsonConvert.SerializeObject( contractMetadata, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } else { context.Action = action; JsonSchema actionSchema = new JsonSchema { Properties = new Dictionary<string, JsonSchema>(), Description = $"Request and response parameters for action '{actionName}'." }; List<ParameterInfo> actionParameters = BoltFramework.GetSerializableParameters(action).ToList(); if (actionParameters.Any()) { JsonSchemaGenerator generator = new JsonSchemaGenerator(); JsonSchema arguments = new JsonSchema { Properties = actionParameters.ToDictionary( p => p.Name, p => generator.Generate(p.ParameterType)), Required = true, Type = JsonSchemaType.Object, }; actionSchema.Properties.Add("request", arguments); } if (context.ResponseType != typeof(void)) { JsonSchemaGenerator generator = new JsonSchemaGenerator(); actionSchema.Properties.Add("response", generator.Generate(context.ResponseType)); } using (var sw = new StringWriter()) { using (JsonTextWriter jw = new JsonTextWriter(sw)) { jw.Formatting = Formatting.Indented; actionSchema.WriteTo(jw); } result = sw.GetStringBuilder().ToString(); } } context.HttpContext.Response.ContentType = "application/json"; context.HttpContext.Response.StatusCode = 200; await context.HttpContext.Response.WriteAsync(result); return true; } catch (Exception e) { Logger.LogWarning( BoltLogId.HandleContractMetadataError, "Failed to generate Bolt metadata for contract '{0}'. Error: {1}", context.Contract.Name, e); return false; } }
public ApplySopRulesCommand(ServerActionContext context, ServerRulesEngine engine) : base("Apply SOP Rules Engine and insert Archival Request", false) { _context = context; _engine = engine; }
protected virtual object CreateInstance(ServerActionContext context, Type type) { var createFactory = _typeActivatorCache.GetOrAdd(type, t => ActivatorUtilities.CreateFactory(type, new Type[] { })); return createFactory(context.HttpContext.ApplicationServices, null); }
private void SetupInit(ServerActionContext ctxt, string session = "testsession", object instance = null) { Mock.Setup(o => o.CreateInstance(ctxt, typeof(IMockContract))).Returns(instance ?? new object()).Verifiable(); Mock.Setup(o => o.GenerateSessionid()).Returns(session ?? Guid.NewGuid().ToString()).Verifiable(); }
public Task ReleaseInstanceAsync(ServerActionContext context, object obj, Exception error) { return CompletedTask.Done; }
protected override Task OnInstanceReleasedAsync(ServerActionContext context, string sessionId) { _actions.Object.OnInstanceReleased(context, sessionId); return(Task.FromResult(true)); }
public Task <object> GetInstanceAsync(ServerActionContext context, Type type) { return(Task.FromResult(_instance)); }
public Task ReleaseInstanceAsync(ServerActionContext context, object obj, Exception error) { return(CompletedTask.Done); }
public virtual Task ReleaseInstanceAsync(ServerActionContext context, object obj, Exception error) { (obj as IDisposable)?.Dispose(); return CompletedTask.Done; }
public Task<object> GetInstanceAsync(ServerActionContext context, Type type) { return Task.FromResult(_instance); }
public virtual Task<object> GetInstanceAsync(ServerActionContext context, Type type) { return Task.FromResult(CreateInstance(context, type)); }
public void RestoreNearlineStudy(RestoreQueue queueItem, string zipFile, string studyFolder) { ServerFilesystemInfo fs = _hsmArchive.Selector.SelectFilesystem(); if (fs == null) { DateTime scheduleTime = Platform.Time.AddMinutes(5); Platform.Log(LogLevel.Error, "No writeable filesystem for restore, rescheduling restore request to {0}", scheduleTime); queueItem.FailureDescription = "No writeable filesystem for restore, rescheduling restore request"; _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Pending, scheduleTime); return; } string destinationFolder = Path.Combine(fs.Filesystem.FilesystemPath, _hsmArchive.ServerPartition.PartitionFolder); StudyStorageLocation restoredLocation = null; try { using (var processor = new ServerCommandProcessor("HSM Restore Offline Study")) { processor.AddCommand(new CreateDirectoryCommand(destinationFolder)); destinationFolder = Path.Combine(destinationFolder, studyFolder); processor.AddCommand(new CreateDirectoryCommand(destinationFolder)); destinationFolder = Path.Combine(destinationFolder, _studyStorage.StudyInstanceUid); processor.AddCommand(new CreateDirectoryCommand(destinationFolder)); processor.AddCommand(new ExtractZipCommand(zipFile, destinationFolder)); // We rebuild the StudyXml, in case any settings or issues have happened since archival processor.AddCommand(new RebuildStudyXmlCommand(_studyStorage.StudyInstanceUid, destinationFolder)); // Apply the rules engine. var context = new ServerActionContext(null, fs.Filesystem.GetKey(), _hsmArchive.ServerPartition, queueItem.StudyStorageKey) { CommandProcessor = processor }; processor.AddCommand( new ApplyRulesCommand(destinationFolder, _studyStorage.StudyInstanceUid, context)); // Do the actual insert into the DB var insertStorageCommand = new InsertFilesystemStudyStorageCommand( _hsmArchive.PartitionArchive.ServerPartitionKey, _studyStorage.StudyInstanceUid, studyFolder, fs.Filesystem.GetKey(), _syntax); processor.AddCommand(insertStorageCommand); if (!processor.Execute()) { Platform.Log(LogLevel.Error, "Unexpected error processing restore request for {0} on archive {1}", _studyStorage.StudyInstanceUid, _hsmArchive.PartitionArchive.Description); queueItem.FailureDescription = processor.FailureReason; _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time); } else { restoredLocation = insertStorageCommand.Location; // Unlock the Queue Entry using ( IUpdateContext update = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush)) { bool retVal = _hsmArchive.UpdateRestoreQueue(update, queueItem, RestoreQueueStatusEnum.Completed, Platform.Time.AddSeconds(60)); var studyLock = update.GetBroker <ILockStudy>(); var parms = new LockStudyParameters { StudyStorageKey = queueItem.StudyStorageKey, QueueStudyStateEnum = QueueStudyStateEnum.Idle }; retVal = retVal && studyLock.Execute(parms); if (!parms.Successful || !retVal) { string message = String.Format("Study {0} on partition {1} failed to unlock.", _studyStorage.StudyInstanceUid, _hsmArchive.ServerPartition.Description); Platform.Log(LogLevel.Info, message); throw new ApplicationException(message); } update.Commit(); Platform.Log(LogLevel.Info, "Successfully restored study: {0} on archive {1}", _studyStorage.StudyInstanceUid, _hsmArchive.PartitionArchive.Description); OnStudyRestored(restoredLocation); } } } } catch (StudyIntegrityValidationFailure ex) { Debug.Assert(restoredLocation != null); // study has been restored but it seems corrupted. Need to reprocess it. ReprocessStudy(restoredLocation, ex.Message); } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception processing restore request for {0} on archive {1}", _studyStorage.StudyInstanceUid, _hsmArchive.PartitionArchive.Description); _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time); } }
private void InsertInstance(DicomFile file, StudyXml stream, WorkQueueUid uid, string deleteFile) { using (ServerCommandProcessor processor = new ServerCommandProcessor("Processing WorkQueue DICOM file")) { EventsHelper.Fire(OnInsertingSop, this, new SopInsertingEventArgs { Processor = processor }); InsertInstanceCommand insertInstanceCommand = null; InsertStudyXmlCommand insertStudyXmlCommand = null; String patientsName = file.DataSet[DicomTags.PatientsName].GetString(0, String.Empty); _modality = file.DataSet[DicomTags.Modality].GetString(0, String.Empty); if (_context.UpdateCommands.Count > 0) { foreach (BaseImageLevelUpdateCommand command in _context.UpdateCommands) { command.File = file; processor.AddCommand(command); } } try { // Create a context for applying actions from the rules engine ServerActionContext context = new ServerActionContext(file, _context.StorageLocation.FilesystemKey, _context.Partition, _context.StorageLocation.Key); context.CommandProcessor = processor; _context.SopCompressionRulesEngine.Execute(context); String seriesUid = file.DataSet[DicomTags.SeriesInstanceUid].GetString(0, String.Empty); String sopUid = file.DataSet[DicomTags.SopInstanceUid].GetString(0, String.Empty); String finalDest = _context.StorageLocation.GetSopInstancePath(seriesUid, sopUid); if (_context.UpdateCommands.Count > 0) { processor.AddCommand(new SaveDicomFileCommand(_context.StorageLocation, file, file.Filename != finalDest)); } else if (file.Filename != finalDest || processor.CommandCount > 0) { // Have to be careful here about failure on exists vs. not failing on exists // because of the different use cases of the importer. // save the file in the study folder, or if its been compressed processor.AddCommand(new SaveDicomFileCommand(finalDest, file, file.Filename != finalDest)); } // Update the StudyStream object insertStudyXmlCommand = new InsertStudyXmlCommand(file, stream, _context.StorageLocation); processor.AddCommand(insertStudyXmlCommand); // Have the rules applied during the command processor, and add the objects. processor.AddCommand(new ApplySopRulesCommand(context, _context.SopProcessedRulesEngine)); // If specified, delete the file if (deleteFile != null) { processor.AddCommand(new FileDeleteCommand(deleteFile, true)); } // Insert into the database, but only if its not a duplicate so the counts don't get off insertInstanceCommand = new InsertInstanceCommand(file, _context.StorageLocation); processor.AddCommand(insertInstanceCommand); // Do a check if the StudyStatus value should be changed in the StorageLocation. This // should only occur if the object has been compressed in the previous steps. processor.AddCommand(new UpdateStudyStatusCommand(_context.StorageLocation, file)); if (uid != null) { processor.AddCommand(new DeleteWorkQueueUidCommand(uid)); } // Do the actual processing if (!processor.Execute()) { Platform.Log(LogLevel.Error, "Failure processing command {0} for SOP: {1}", processor.Description, file.MediaStorageSopInstanceUid); Platform.Log(LogLevel.Error, "File that failed processing: {0}", file.Filename); throw new ApplicationException("Unexpected failure (" + processor.FailureReason + ") executing command for SOP: " + file.MediaStorageSopInstanceUid, processor.FailureException); } Platform.Log(ServerPlatform.InstanceLogLevel, "Processed SOP: {0} for Patient {1}", file.MediaStorageSopInstanceUid, patientsName); } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception when {0}. Rolling back operation.", processor.Description); processor.Rollback(); throw new ApplicationException("Unexpected exception when processing file.", e); } finally { if (insertInstanceCommand != null && insertInstanceCommand.Statistics.IsSet) { _instanceStats.InsertDBTime.Add(insertInstanceCommand.Statistics); } if (insertStudyXmlCommand != null && insertStudyXmlCommand.Statistics.IsSet) { _instanceStats.InsertStreamTime.Add(insertStudyXmlCommand.Statistics); } } } }
Task<object> IInstanceProvider.GetInstanceAsync(ServerActionContext context, Type type) { return Task.FromResult(CurrentInstance); }