From 7e20e91f1082f3f97c83e5446e371393fe407a76 Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Tue, 2 Aug 2022 11:20:18 +0100 Subject: [PATCH 1/6] use task level export destinations Signed-off-by: Jack Schofield --- src/Contracts/Models/ExportDestination.cs | 6 ------ src/Contracts/Models/TaskObject.cs | 2 +- src/WorkflowExecuter/Common/EventMapper.cs | 4 ++-- .../Services/WorkflowExecuterService.cs | 20 +++++++++++-------- .../Common/EventMapperTests.cs | 4 ++-- .../Services/WorkflowExecuterServiceTests.cs | 18 +++++++++++++++-- .../Controllers/WorkflowsControllerTests.cs | 14 ++++++------- 7 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/Contracts/Models/ExportDestination.cs b/src/Contracts/Models/ExportDestination.cs index 3258acb26..c7f87de09 100644 --- a/src/Contracts/Models/ExportDestination.cs +++ b/src/Contracts/Models/ExportDestination.cs @@ -22,11 +22,5 @@ public class ExportDestination { [JsonProperty(PropertyName = "name")] public string Name { get; set; } - - [JsonProperty(PropertyName = "conditions")] - public Evaluator[] Conditions { get; set; } - - [JsonProperty(PropertyName = "artifacts")] - public Artifact[] Artifacts { get; set; } } } diff --git a/src/Contracts/Models/TaskObject.cs b/src/Contracts/Models/TaskObject.cs index d72ef677b..5ce7ae4e2 100644 --- a/src/Contracts/Models/TaskObject.cs +++ b/src/Contracts/Models/TaskObject.cs @@ -39,7 +39,7 @@ public class TaskObject public TaskDestination[] TaskDestinations { get; set; } = System.Array.Empty(); [JsonProperty(PropertyName = "export_destinations")] - public TaskDestination[] ExportDestinations { get; set; } = System.Array.Empty(); + public ExportDestination[] ExportDestinations { get; set; } = System.Array.Empty(); [JsonProperty(PropertyName = "artifacts")] public ArtifactMap Artifacts { get; set; } = new ArtifactMap(); diff --git a/src/WorkflowExecuter/Common/EventMapper.cs b/src/WorkflowExecuter/Common/EventMapper.cs index 89c8dfdab..1e689f542 100644 --- a/src/WorkflowExecuter/Common/EventMapper.cs +++ b/src/WorkflowExecuter/Common/EventMapper.cs @@ -91,7 +91,7 @@ public static TaskDispatchEvent ToTaskDispatchEvent(TaskExecution task, Workflow }; } - public static ExportRequestEvent ToExportRequestEvent(IList dicomImages, string[] exportDestinations, string taskId, string workflowInstanceId, string correlationId) + public static ExportRequestEvent ToExportRequestEvent(IList dicomImages, ExportDestination[] exportDestinations, string taskId, string workflowInstanceId, string correlationId) { Guard.Against.NullOrWhiteSpace(taskId, nameof(taskId)); Guard.Against.NullOrWhiteSpace(workflowInstanceId, nameof(workflowInstanceId)); @@ -105,7 +105,7 @@ public static ExportRequestEvent ToExportRequestEvent(IList dicomImages, ExportTaskId = taskId, CorrelationId = correlationId, Files = dicomImages, - Destinations = exportDestinations + Destinations = exportDestinations.Select(e => e.Name).ToArray() }; } } diff --git a/src/WorkflowExecuter/Services/WorkflowExecuterService.cs b/src/WorkflowExecuter/Services/WorkflowExecuterService.cs index 05335a1f5..460b3492c 100644 --- a/src/WorkflowExecuter/Services/WorkflowExecuterService.cs +++ b/src/WorkflowExecuter/Services/WorkflowExecuterService.cs @@ -14,7 +14,6 @@ * limitations under the License. */ -using System.Diagnostics; using Ardalis.GuardClauses; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -319,21 +318,26 @@ private async Task UpdateWorkflowInstanceStatus(WorkflowInstance workflowI private async Task HandleDicomExport(WorkflowRevision workflow, WorkflowInstance workflowInstance, TaskExecution task, string correlationId) { - var artifactValues = GetDicomExports(workflow, workflowInstance, task); + var exportDestinations = workflow.Workflow?.Tasks?.FirstOrDefault(t => t.Id == task.TaskId)?.ExportDestinations; + + var exportList = workflow.Workflow?.Tasks?.FirstOrDefault(t => t.Id == task.TaskId)?.ExportDestinations; + + var artifactValues = GetDicomExports(workflow, workflowInstance, task, exportList); if (artifactValues.Any() is false) { await HandleTaskDestinations(workflowInstance, workflow, task, correlationId); } - await DispatchDicomExport(workflowInstance, task, workflow.Workflow?.InformaticsGateway?.ExportDestinations, artifactValues, correlationId); + await DispatchDicomExport(workflowInstance, task, exportList, artifactValues, correlationId); } - private string[] GetDicomExports(WorkflowRevision workflow, WorkflowInstance workflowInstance, TaskExecution task) + private string[] GetDicomExports(WorkflowRevision workflow, WorkflowInstance workflowInstance, TaskExecution task, ExportDestination[] exportDestinations) { - var exportDestinations = workflow.Workflow?.InformaticsGateway?.ExportDestinations; + var validExportDestinations = workflow.Workflow?.InformaticsGateway?.ExportDestinations; - if (exportDestinations is null || !exportDestinations.Any()) + if (validExportDestinations is null || !validExportDestinations.Any() + || exportDestinations is null || !exportDestinations.Any()) { return Array.Empty(); } @@ -348,7 +352,7 @@ private string[] GetDicomExports(WorkflowRevision workflow, WorkflowInstance wor return new List(task.InputArtifacts.Values).ToArray(); } - private async Task DispatchDicomExport(WorkflowInstance workflowInstance, TaskExecution task, string[] exportDestinations, string[] artifactValues, string correlationId) + private async Task DispatchDicomExport(WorkflowInstance workflowInstance, TaskExecution task, ExportDestination[] exportDestinations, string[] artifactValues, string correlationId) { if (exportDestinations is null || !exportDestinations.Any()) { @@ -496,7 +500,7 @@ private async Task DispatchTask(WorkflowInstance workflowInstance, Workflo return await _workflowInstanceRepository.UpdateTaskStatusAsync(workflowInstance.Id, taskExec.TaskId, TaskExecutionStatus.Dispatched); } - private async Task ExportRequest(WorkflowInstance workflowInstance, TaskExecution taskExec, string[] exportDestinations, IList dicomImages, string correlationId) + private async Task ExportRequest(WorkflowInstance workflowInstance, TaskExecution taskExec, ExportDestination[] exportDestinations, IList dicomImages, string correlationId) { var exportRequestEvent = EventMapper.ToExportRequestEvent(dicomImages, exportDestinations, taskExec.TaskId, workflowInstance.Id, correlationId); var jsonMesssage = new JsonMessage(exportRequestEvent, MessageBrokerConfiguration.WorkflowManagerApplicationId, exportRequestEvent.CorrelationId, Guid.NewGuid().ToString()); diff --git a/tests/UnitTests/WorkflowExecuter.Tests/Common/EventMapperTests.cs b/tests/UnitTests/WorkflowExecuter.Tests/Common/EventMapperTests.cs index cba78a7be..e07426e22 100644 --- a/tests/UnitTests/WorkflowExecuter.Tests/Common/EventMapperTests.cs +++ b/tests/UnitTests/WorkflowExecuter.Tests/Common/EventMapperTests.cs @@ -144,7 +144,7 @@ public void ToExportRequestEvent_ValidOutputArtifacts_ReturnsExportRequest() OutputDirectory = "minio/workflowid/taskid" }; - var exportDestinations = new string[] { "test" }; + var exportDestinations = new ExportDestination[] { new ExportDestination { Name = "test" } }; var dicomImages = new List { "dicom" }; @@ -157,7 +157,7 @@ public void ToExportRequestEvent_ValidOutputArtifacts_ReturnsExportRequest() ExportTaskId = task.TaskId, CorrelationId = correlationId, Files = dicomImages, - Destinations = exportDestinations + Destinations = new string[] { exportDestinations[0].Name } }; var exportRequest = EventMapper.ToExportRequestEvent(dicomImages, exportDestinations, task.TaskId, workflowInstanceId, correlationId); diff --git a/tests/UnitTests/WorkflowExecuter.Tests/Services/WorkflowExecuterServiceTests.cs b/tests/UnitTests/WorkflowExecuter.Tests/Services/WorkflowExecuterServiceTests.cs index f5a1dc50f..95f4bcef3 100644 --- a/tests/UnitTests/WorkflowExecuter.Tests/Services/WorkflowExecuterServiceTests.cs +++ b/tests/UnitTests/WorkflowExecuter.Tests/Services/WorkflowExecuterServiceTests.cs @@ -358,7 +358,14 @@ public async Task ProcessPayload_WithExportTask_DispatchesExport() { Input = new Artifact[] { new Artifact { Name = "dicomexport", Value = "{{ context.input }}" } } }, - TaskDestinations = Array.Empty() + TaskDestinations = Array.Empty(), + ExportDestinations = new ExportDestination[] + { + new ExportDestination + { + Name = "PROD_PACS" + } + } } } } @@ -922,7 +929,14 @@ public async Task ProcessTaskUpdate_ValidTaskUpdateEventWithExportTaskDestinatio { Input = new Artifact[] { new Artifact { Name = "dicomexport", Value = "{{ context.input }}" } } }, - TaskDestinations = Array.Empty() + TaskDestinations = Array.Empty(), + ExportDestinations = new ExportDestination[] + { + new ExportDestination + { + Name = "PROD_PACS" + } + } } } } diff --git a/tests/UnitTests/WorkflowManager.Tests/Controllers/WorkflowsControllerTests.cs b/tests/UnitTests/WorkflowManager.Tests/Controllers/WorkflowsControllerTests.cs index a851f62f3..cdaf99b05 100644 --- a/tests/UnitTests/WorkflowManager.Tests/Controllers/WorkflowsControllerTests.cs +++ b/tests/UnitTests/WorkflowManager.Tests/Controllers/WorkflowsControllerTests.cs @@ -522,10 +522,10 @@ public void ValidateWorkflow_ValidatesAWorkflow_ReturnsTrueAndHasCorrectValidati Name = "taskLoopdesc1" } }, - ExportDestinations = new TaskDestination[] + ExportDestinations = new ExportDestination[] { - new TaskDestination { Name = "oneDestination" }, - new TaskDestination { Name = "twoDestination" }, + new ExportDestination { Name = "oneDestination" }, + new ExportDestination { Name = "twoDestination" }, } }, #region LoopingTasks @@ -539,11 +539,11 @@ public void ValidateWorkflow_ValidatesAWorkflow_ReturnsTrueAndHasCorrectValidati Name = "taskLoopdesc2" } }, - ExportDestinations = new TaskDestination[] + ExportDestinations = new ExportDestination[] { - new TaskDestination { Name = "threeDestination" }, - new TaskDestination { Name = "twoDestination" }, - new TaskDestination { Name = "DoesNotExistDestination" }, + new ExportDestination { Name = "threeDestination" }, + new ExportDestination { Name = "twoDestination" }, + new ExportDestination { Name = "DoesNotExistDestination" }, } }, new TaskObject { From a7a26d491b368dad75889dcd3b4f3e16f245a67d Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Tue, 2 Aug 2022 12:12:20 +0100 Subject: [PATCH 2/6] fix Signed-off-by: Jack Schofield --- src/WorkflowExecuter/Common/EventMapper.cs | 4 +- .../Services/WorkflowExecuterService.cs | 18 ++++- .../Common/EventMapperTests.cs | 4 +- .../Services/WorkflowExecuterServiceTests.cs | 73 +++++++++++++++++++ 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/src/WorkflowExecuter/Common/EventMapper.cs b/src/WorkflowExecuter/Common/EventMapper.cs index 1e689f542..89c8dfdab 100644 --- a/src/WorkflowExecuter/Common/EventMapper.cs +++ b/src/WorkflowExecuter/Common/EventMapper.cs @@ -91,7 +91,7 @@ public static TaskDispatchEvent ToTaskDispatchEvent(TaskExecution task, Workflow }; } - public static ExportRequestEvent ToExportRequestEvent(IList dicomImages, ExportDestination[] exportDestinations, string taskId, string workflowInstanceId, string correlationId) + public static ExportRequestEvent ToExportRequestEvent(IList dicomImages, string[] exportDestinations, string taskId, string workflowInstanceId, string correlationId) { Guard.Against.NullOrWhiteSpace(taskId, nameof(taskId)); Guard.Against.NullOrWhiteSpace(workflowInstanceId, nameof(workflowInstanceId)); @@ -105,7 +105,7 @@ public static ExportRequestEvent ToExportRequestEvent(IList dicomImages, ExportTaskId = taskId, CorrelationId = correlationId, Files = dicomImages, - Destinations = exportDestinations.Select(e => e.Name).ToArray() + Destinations = exportDestinations }; } } diff --git a/src/WorkflowExecuter/Services/WorkflowExecuterService.cs b/src/WorkflowExecuter/Services/WorkflowExecuterService.cs index 460b3492c..e93a322a9 100644 --- a/src/WorkflowExecuter/Services/WorkflowExecuterService.cs +++ b/src/WorkflowExecuter/Services/WorkflowExecuterService.cs @@ -320,19 +320,21 @@ private async Task HandleDicomExport(WorkflowRevision workflow, WorkflowInstance { var exportDestinations = workflow.Workflow?.Tasks?.FirstOrDefault(t => t.Id == task.TaskId)?.ExportDestinations; - var exportList = workflow.Workflow?.Tasks?.FirstOrDefault(t => t.Id == task.TaskId)?.ExportDestinations; + var exportList = workflow.Workflow?.Tasks?.FirstOrDefault(t => t.Id == task.TaskId)?.ExportDestinations.Select(e => e.Name).ToArray(); var artifactValues = GetDicomExports(workflow, workflowInstance, task, exportList); if (artifactValues.Any() is false) { await HandleTaskDestinations(workflowInstance, workflow, task, correlationId); + + return; } await DispatchDicomExport(workflowInstance, task, exportList, artifactValues, correlationId); } - private string[] GetDicomExports(WorkflowRevision workflow, WorkflowInstance workflowInstance, TaskExecution task, ExportDestination[] exportDestinations) + private string[] GetDicomExports(WorkflowRevision workflow, WorkflowInstance workflowInstance, TaskExecution task, string[] exportDestinations) { var validExportDestinations = workflow.Workflow?.InformaticsGateway?.ExportDestinations; @@ -342,6 +344,14 @@ private string[] GetDicomExports(WorkflowRevision workflow, WorkflowInstance wor return Array.Empty(); } + foreach (var exportDestination in exportDestinations) + { + if (validExportDestinations.Contains(exportDestination) is false) + { + return Array.Empty(); + } + } + if (!task.InputArtifacts.Any()) { _logger.ExportFilesNotFound(task.TaskId, workflowInstance.Id); @@ -352,7 +362,7 @@ private string[] GetDicomExports(WorkflowRevision workflow, WorkflowInstance wor return new List(task.InputArtifacts.Values).ToArray(); } - private async Task DispatchDicomExport(WorkflowInstance workflowInstance, TaskExecution task, ExportDestination[] exportDestinations, string[] artifactValues, string correlationId) + private async Task DispatchDicomExport(WorkflowInstance workflowInstance, TaskExecution task, string[] exportDestinations, string[] artifactValues, string correlationId) { if (exportDestinations is null || !exportDestinations.Any()) { @@ -500,7 +510,7 @@ private async Task DispatchTask(WorkflowInstance workflowInstance, Workflo return await _workflowInstanceRepository.UpdateTaskStatusAsync(workflowInstance.Id, taskExec.TaskId, TaskExecutionStatus.Dispatched); } - private async Task ExportRequest(WorkflowInstance workflowInstance, TaskExecution taskExec, ExportDestination[] exportDestinations, IList dicomImages, string correlationId) + private async Task ExportRequest(WorkflowInstance workflowInstance, TaskExecution taskExec, string[] exportDestinations, IList dicomImages, string correlationId) { var exportRequestEvent = EventMapper.ToExportRequestEvent(dicomImages, exportDestinations, taskExec.TaskId, workflowInstance.Id, correlationId); var jsonMesssage = new JsonMessage(exportRequestEvent, MessageBrokerConfiguration.WorkflowManagerApplicationId, exportRequestEvent.CorrelationId, Guid.NewGuid().ToString()); diff --git a/tests/UnitTests/WorkflowExecuter.Tests/Common/EventMapperTests.cs b/tests/UnitTests/WorkflowExecuter.Tests/Common/EventMapperTests.cs index e07426e22..cba78a7be 100644 --- a/tests/UnitTests/WorkflowExecuter.Tests/Common/EventMapperTests.cs +++ b/tests/UnitTests/WorkflowExecuter.Tests/Common/EventMapperTests.cs @@ -144,7 +144,7 @@ public void ToExportRequestEvent_ValidOutputArtifacts_ReturnsExportRequest() OutputDirectory = "minio/workflowid/taskid" }; - var exportDestinations = new ExportDestination[] { new ExportDestination { Name = "test" } }; + var exportDestinations = new string[] { "test" }; var dicomImages = new List { "dicom" }; @@ -157,7 +157,7 @@ public void ToExportRequestEvent_ValidOutputArtifacts_ReturnsExportRequest() ExportTaskId = task.TaskId, CorrelationId = correlationId, Files = dicomImages, - Destinations = new string[] { exportDestinations[0].Name } + Destinations = exportDestinations }; var exportRequest = EventMapper.ToExportRequestEvent(dicomImages, exportDestinations, task.TaskId, workflowInstanceId, correlationId); diff --git a/tests/UnitTests/WorkflowExecuter.Tests/Services/WorkflowExecuterServiceTests.cs b/tests/UnitTests/WorkflowExecuter.Tests/Services/WorkflowExecuterServiceTests.cs index 95f4bcef3..aafc594ea 100644 --- a/tests/UnitTests/WorkflowExecuter.Tests/Services/WorkflowExecuterServiceTests.cs +++ b/tests/UnitTests/WorkflowExecuter.Tests/Services/WorkflowExecuterServiceTests.cs @@ -387,6 +387,79 @@ public async Task ProcessPayload_WithExportTask_DispatchesExport() Assert.True(result); } + [Fact] + public async Task ProcessPayload_WithInvalidExportTask_DoesNotDispatchExport() + { + var workflowId1 = Guid.NewGuid().ToString(); + var workflowId2 = Guid.NewGuid().ToString(); + var workflowRequest = new WorkflowRequestEvent + { + Bucket = "testbucket", + CalledAeTitle = "aetitle", + CallingAeTitle = "aetitle", + CorrelationId = Guid.NewGuid().ToString(), + Timestamp = DateTime.UtcNow, + Workflows = new List + { + workflowId1.ToString() + } + }; + + var workflows = new List + { + new WorkflowRevision + { + Id = Guid.NewGuid().ToString(), + WorkflowId = workflowId1, + Revision = 1, + Workflow = new Workflow + { + Name = "Workflowname1", + Description = "Workflowdesc1", + Version = "1", + InformaticsGateway = new InformaticsGateway + { + AeTitle = "aetitle", + ExportDestinations = new string[] { "PROD_PACS" } + }, + Tasks = new TaskObject[] + { + new TaskObject { + Id = Guid.NewGuid().ToString(), + Type = "export", + Description = "taskdesc", + Artifacts = new ArtifactMap + { + Input = new Artifact[] { new Artifact { Name = "dicomexport", Value = "{{ context.input }}" } } + }, + TaskDestinations = Array.Empty(), + ExportDestinations = new ExportDestination[] + { + new ExportDestination + { + Name = "PROD_PINS" + } + } + } + } + } + } + }; + + _workflowRepository.Setup(w => w.GetByWorkflowsIdsAsync(new List { workflowId1.ToString() })).ReturnsAsync(workflows); + _workflowRepository.Setup(w => w.GetByWorkflowIdAsync(workflowId1.ToString())).ReturnsAsync(workflows[0]); + _workflowInstanceRepository.Setup(w => w.CreateAsync(It.IsAny>())).ReturnsAsync(true); + _workflowInstanceRepository.Setup(w => w.UpdateTasksAsync(It.IsAny(), It.IsAny>())).ReturnsAsync(true); + _workflowInstanceRepository.Setup(w => w.GetByWorkflowsIdsAsync(It.IsAny>())).ReturnsAsync(new List()); + _workflowInstanceRepository.Setup(w => w.UpdateTaskStatusAsync(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(true); + _artifactMapper.Setup(a => a.ConvertArtifactVariablesToPath(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(new Dictionary() { { "dicomexport", "/dcm" } }); + + var result = await WorkflowExecuterService.ProcessPayload(workflowRequest, new Payload() { Id = Guid.NewGuid().ToString() }); + + _messageBrokerPublisherService.Verify(w => w.Publish($"{_configuration.Value.Messaging.Topics.ExportRequestPrefix}.{_configuration.Value.Messaging.DicomAgents.DicomWebAgentName}", It.IsAny()), Times.Exactly(0)); + Assert.True(result); + } + [Fact] public async Task ProcessPayload_FileNotFound_FailsWorkflow() { From 398ca48ed287ef4dcfd6ad717bd66b99ac2bd662 Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Tue, 2 Aug 2022 12:19:10 +0100 Subject: [PATCH 3/6] update docs Signed-off-by: Jack Schofield --- guidelines/mwm-workflow-spec.md | 53 ++++++++++++++------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/guidelines/mwm-workflow-spec.md b/guidelines/mwm-workflow-spec.md index a5a9214c1..ec897e1a0 100644 --- a/guidelines/mwm-workflow-spec.md +++ b/guidelines/mwm-workflow-spec.md @@ -141,8 +141,29 @@ The task also requires these extra attributes:- | Property | Type | Description | |------|------|------| -|export_destinations|Optional[list[[ExportDestination](#export-destinations)]]|An optional lists of possible export destinations to which the output of this task can be sent.| -|artifacts|[ArtifactMap](#artifacts)| Only Input artifacts of this task. +|export_destinations|Optional[list[[ExportDestination](#export-destinations)]]|An optional lists of possible export destinations to which the output of this task can be sent. This must be an export destinations already defined within the [Informatics Gateway](#informatics-gateway) section of the workflow configuration.|| +|artifacts|[ArtifactMap](#artifacts)| Only Input artifacts of this task that should be sent to this export destination.. + +Example (output sent to another task if the patient is female, otherwise to PACS): +```json +{ + ...task... + "export_destinations": [ + { + "name": "PROD_PACS" + } + ], + "task_destinations": [ + { + "name": "my-task-id", + "conditions": ["{{context.input.dicom.series.all('0010','0040')}} == 'F'"] + } + ], + ... +} +``` + +Export destinations define an external location to which the output of the task can be sent. This will take the form of an event published to a pub/sub service notifying of an available export to a specific destination reference. Most commonly, the export location will be a PACs system and the notification will be picked up by the Monai Informatics Gateway. #### Plugin These are tasks are Named the same as the installed Pluging. @@ -337,34 +358,6 @@ Example (run my-task-id when the patient is female): } ``` - -#### Export Destinations -Export destinations define an external location to which the output of the task can be sent. This will take the form of an event published to a pub/sub service notifying of an available export to a specific destination reference. Most commonly, the export location will be a PACs system and the notification will be picked up by the Monai Informatics Gateway. - -| Property | Type | Description | -|------|------|------| -|name|str|The name of the destination. This can either be an export destinations already defined within the [Informatics Gateway](#informatics-gateway) section of the workflow configuration.| -|artifacts|list[Artifact]|An array of [Artifacts](#artifacts) that should be sent to this export destination.| - -Example (output sent to another task if the patient is female, otherwise to PACS): -```json -{ - ...task... - "export_destinations": [ - { - "name": "PROD_PACS" - } - ], - "task_destinations": [ - { - "name": "my-task-id", - "conditions": ["{{context.input.dicom.series.all('0010','0040')}} == 'F'"] - } - ], - ... -} -``` - ### Retention Policies _Future version: TBD_ From 9f84cc026a0f0a0429f76942900b6a3713a8e70e Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Tue, 2 Aug 2022 14:34:05 +0100 Subject: [PATCH 4/6] address comments Signed-off-by: Jack Schofield --- src/Common/Extensions/ArrayExtensions.cs | 10 ++++++++++ src/Contracts/Models/TaskObject.cs | 5 +++-- .../Services/WorkflowExecuterService.cs | 10 +++++----- 3 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 src/Common/Extensions/ArrayExtensions.cs diff --git a/src/Common/Extensions/ArrayExtensions.cs b/src/Common/Extensions/ArrayExtensions.cs new file mode 100644 index 000000000..f7bfd18b0 --- /dev/null +++ b/src/Common/Extensions/ArrayExtensions.cs @@ -0,0 +1,10 @@ +namespace Monai.Deploy.WorkflowManager.Common.Extensions +{ + public static class ArrayExtensions + { + public static bool IsNullOrEmpty(this T[] array) + { + return array == null || array.Length == 0; + } + } +} diff --git a/src/Contracts/Models/TaskObject.cs b/src/Contracts/Models/TaskObject.cs index 5ce7ae4e2..47dde7079 100644 --- a/src/Contracts/Models/TaskObject.cs +++ b/src/Contracts/Models/TaskObject.cs @@ -35,11 +35,12 @@ public class TaskObject [JsonProperty(PropertyName = "ref")] public string Ref { get; set; } = string.Empty; + [JsonProperty(PropertyName = "task_destinations")] - public TaskDestination[] TaskDestinations { get; set; } = System.Array.Empty(); + public TaskDestination[] TaskDestinations { get; set; } = Array.Empty(); [JsonProperty(PropertyName = "export_destinations")] - public ExportDestination[] ExportDestinations { get; set; } = System.Array.Empty(); + public ExportDestination[] ExportDestinations { get; set; } = Array.Empty(); [JsonProperty(PropertyName = "artifacts")] public ArtifactMap Artifacts { get; set; } = new ArtifactMap(); diff --git a/src/WorkflowExecuter/Services/WorkflowExecuterService.cs b/src/WorkflowExecuter/Services/WorkflowExecuterService.cs index e93a322a9..38f3564f6 100644 --- a/src/WorkflowExecuter/Services/WorkflowExecuterService.cs +++ b/src/WorkflowExecuter/Services/WorkflowExecuterService.cs @@ -160,7 +160,7 @@ public async Task ProcessFirstWorkflowTask(WorkflowInstance workflowInstance, st if (string.Equals(task.TaskType, TaskTypeConstants.ExportTask, StringComparison.InvariantCultureIgnoreCase)) { - await HandleDicomExport(workflow, workflowInstance, task, correlationId); + await HandleDicomExportAsync(workflow, workflowInstance, task, correlationId); return; } @@ -316,7 +316,7 @@ private async Task UpdateWorkflowInstanceStatus(WorkflowInstance workflowI return true; } - private async Task HandleDicomExport(WorkflowRevision workflow, WorkflowInstance workflowInstance, TaskExecution task, string correlationId) + private async Task HandleDicomExportAsync(WorkflowRevision workflow, WorkflowInstance workflowInstance, TaskExecution task, string correlationId) { var exportDestinations = workflow.Workflow?.Tasks?.FirstOrDefault(t => t.Id == task.TaskId)?.ExportDestinations; @@ -338,8 +338,8 @@ private string[] GetDicomExports(WorkflowRevision workflow, WorkflowInstance wor { var validExportDestinations = workflow.Workflow?.InformaticsGateway?.ExportDestinations; - if (validExportDestinations is null || !validExportDestinations.Any() - || exportDestinations is null || !exportDestinations.Any()) + if (exportDestinations.IsNullOrEmpty() + || validExportDestinations.IsNullOrEmpty()) { return Array.Empty(); } @@ -417,7 +417,7 @@ private async Task DispatchTaskDestinations(WorkflowInstance workflowInsta if (string.Equals(taskExec.TaskType, TaskTypeConstants.ExportTask, StringComparison.InvariantCultureIgnoreCase)) { - await HandleDicomExport(workflow, workflowInstance, taskExec, correlationId); + await HandleDicomExportAsync(workflow, workflowInstance, taskExec, correlationId); continue; } From 4a6033eb7a93f14e65f376eb79ecfe4089a12adb Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Tue, 2 Aug 2022 14:54:20 +0100 Subject: [PATCH 5/6] fix system Signed-off-by: Jack Schofield --- src/Contracts/Models/TaskObject.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Contracts/Models/TaskObject.cs b/src/Contracts/Models/TaskObject.cs index 47dde7079..14f6bd887 100644 --- a/src/Contracts/Models/TaskObject.cs +++ b/src/Contracts/Models/TaskObject.cs @@ -14,6 +14,7 @@ * limitations under the License. */ +using System; using System.Collections.Generic; using Newtonsoft.Json; From da51eba1a10cd67fe0c37bc75dd27ee17e0a9d9b Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Tue, 2 Aug 2022 15:00:43 +0100 Subject: [PATCH 6/6] license Signed-off-by: Jack Schofield --- src/Common/Extensions/ArrayExtensions.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Common/Extensions/ArrayExtensions.cs b/src/Common/Extensions/ArrayExtensions.cs index f7bfd18b0..862457a31 100644 --- a/src/Common/Extensions/ArrayExtensions.cs +++ b/src/Common/Extensions/ArrayExtensions.cs @@ -1,4 +1,20 @@ -namespace Monai.Deploy.WorkflowManager.Common.Extensions +/* + * Copyright 2021-2022 MONAI Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Monai.Deploy.WorkflowManager.Common.Extensions { public static class ArrayExtensions {