From 487e68f5c6f7434c34696d84ef5f5d89b1ba2ce6 Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Fri, 29 Jul 2022 10:51:41 +0100 Subject: [PATCH 1/9] fix warnings Signed-off-by: Jack Schofield --- StyleCop.Analyzers.ruleset | 1 + ...onai-deploy-workflow-managercsharp.ruleset | 3 + .../Extensions/TaskDispatchEventExtension.cs | 6 +- src/Contracts/Models/Artifact.cs | 4 +- src/Contracts/Models/ArtifactMap.cs | 4 +- src/Contracts/Models/DicomTags.cs | 33 - src/Contracts/Models/DicomValue.cs | 4 +- src/Contracts/Models/Evaluator.cs | 35 - src/Contracts/Models/ExecutionContext.cs | 54 -- src/Contracts/Models/InformaticsGateway.cs | 6 +- src/Contracts/Models/PatientDetails.cs | 10 +- src/Contracts/Models/TaskDestination.cs | 6 +- src/Contracts/Models/TaskExecution.cs | 22 +- src/Contracts/Models/TaskPluginArguments.cs | 29 - src/Contracts/Models/Workflow.cs | 10 +- src/Contracts/Models/WorkflowInstance.cs | 14 +- src/Contracts/Models/WorkflowRevision.cs | 6 +- src/Database/Interfaces/IPayloadRepsitory.cs | 2 +- .../Interfaces/IWorkflowInstanceRepository.cs | 2 +- .../WorkflowInstanceRepository.cs | 2 +- .../Repositories/WorkflowRepository.cs | 4 +- .../AideClinicalReviewPlugin.cs | 10 +- .../Repositories/ArgoMetadataRepository.cs | 10 +- ...aRepository.cs => TestPluginRepository.cs} | 10 +- src/TaskManager/TaskManager.cs | 2 +- src/WorkflowExecuter/Common/ArtifactMapper.cs | 5 + .../Services/WorkflowExecuterService.cs | 6 +- .../Controllers/ApiControllerBase.cs | 2 +- .../Controllers/PayloadController.cs | 163 ++-- .../Controllers/WorkflowInstanceController.cs | 168 ++-- .../Controllers/WorkflowsController.cs | 331 ++++---- .../Extentions/TaskManagerExtensions.cs | 1 - .../Extentions/WorkflowExecutorExtensions.cs | 2 + .../Monai.Deploy.WorkflowManager.csproj | 5 - src/WorkflowManager/Program.cs | 8 +- src/WorkflowManager/Services/UriService.cs | 2 +- src/WorkflowManager/stylecop.json | 14 + .../WorkflowRequestMessage.cs | 2 +- .../POCO/TestExecutionConfig.cs | 46 +- .../PayloadApiStepDefinitions.cs | 10 +- .../PayloadCollectionStepDefinitions.cs | 2 + .../TaskStatusUpdateStepDefinitions.cs | 1 + .../Support/Assertions.cs | 60 +- .../Support/DataHelper.cs | 753 +++++++++--------- .../Support/MinioClientUtil.cs | 3 +- .../Support/WorkflowExecutorStartup.cs | 6 +- .../TestData/PayloadTestData.cs | 6 +- .../TestData/TaskUpdateTestData.cs | 3 +- .../TestData/WorkflowInstanceTestData.cs | 171 ++-- .../TestData/WorkflowRequestTestData.cs | 4 +- .../ConditionalParameterParserTests.cs | 26 +- 51 files changed, 986 insertions(+), 1103 deletions(-) delete mode 100644 src/Contracts/Models/DicomTags.cs delete mode 100644 src/Contracts/Models/Evaluator.cs delete mode 100644 src/Contracts/Models/ExecutionContext.cs delete mode 100644 src/Contracts/Models/TaskPluginArguments.cs rename src/TaskManager/Plug-ins/TestPlugin/Repositories/{ArgoMetadataRepository.cs => TestPluginRepository.cs} (89%) create mode 100644 src/WorkflowManager/stylecop.json diff --git a/StyleCop.Analyzers.ruleset b/StyleCop.Analyzers.ruleset index 2ecbda9cb..27d439a0f 100644 --- a/StyleCop.Analyzers.ruleset +++ b/StyleCop.Analyzers.ruleset @@ -95,6 +95,7 @@ + diff --git a/src/.sonarlint/project-monai_monai-deploy-workflow-managercsharp.ruleset b/src/.sonarlint/project-monai_monai-deploy-workflow-managercsharp.ruleset index af7ee0d2e..9189ba28c 100644 --- a/src/.sonarlint/project-monai_monai-deploy-workflow-managercsharp.ruleset +++ b/src/.sonarlint/project-monai_monai-deploy-workflow-managercsharp.ruleset @@ -373,5 +373,8 @@ + + + \ No newline at end of file diff --git a/src/Common/Extensions/TaskDispatchEventExtension.cs b/src/Common/Extensions/TaskDispatchEventExtension.cs index 9f597069f..fe280552a 100644 --- a/src/Common/Extensions/TaskDispatchEventExtension.cs +++ b/src/Common/Extensions/TaskDispatchEventExtension.cs @@ -23,7 +23,7 @@ public static class TaskDispatchEventExtension { public static string? GetTaskPluginArgumentsParameter(this TaskDispatchEvent taskDispatchEvent, string key) { - if (!taskDispatchEvent.TaskPluginArguments.TryGetValue(key, out string? value)) + if (!taskDispatchEvent.TaskPluginArguments.TryGetValue(key, out var value)) { return null; } @@ -33,10 +33,10 @@ public static class TaskDispatchEventExtension public static T? GetTaskPluginArgumentsParameter(this TaskDispatchEvent taskDispatchEvent, string key) { - taskDispatchEvent.TaskPluginArguments.TryGetValue(key, out string? value); + taskDispatchEvent.TaskPluginArguments.TryGetValue(key, out var value); if (string.IsNullOrWhiteSpace(value)) { - return default(T); + return default; } return JsonConvert.DeserializeObject(value); } diff --git a/src/Contracts/Models/Artifact.cs b/src/Contracts/Models/Artifact.cs index 18bf80121..417f5a6d8 100644 --- a/src/Contracts/Models/Artifact.cs +++ b/src/Contracts/Models/Artifact.cs @@ -21,10 +21,10 @@ namespace Monai.Deploy.WorkflowManager.Contracts.Models public class Artifact { [JsonProperty(PropertyName = "name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; [JsonProperty(PropertyName = "value")] - public string Value { get; set; } + public string Value { get; set; } = string.Empty; [JsonProperty(PropertyName = "mandatory")] public bool Mandatory { get; set; } = true; diff --git a/src/Contracts/Models/ArtifactMap.cs b/src/Contracts/Models/ArtifactMap.cs index 7a4ecce0a..a23efe6e8 100644 --- a/src/Contracts/Models/ArtifactMap.cs +++ b/src/Contracts/Models/ArtifactMap.cs @@ -21,9 +21,9 @@ namespace Monai.Deploy.WorkflowManager.Contracts.Models public class ArtifactMap { [JsonProperty(PropertyName = "input")] - public Artifact[] Input { get; set; } + public Artifact[] Input { get; set; } = System.Array.Empty(); [JsonProperty(PropertyName = "output")] - public Artifact[] Output { get; set; } + public Artifact[] Output { get; set; } = System.Array.Empty(); } } diff --git a/src/Contracts/Models/DicomTags.cs b/src/Contracts/Models/DicomTags.cs deleted file mode 100644 index 9786fdf08..000000000 --- a/src/Contracts/Models/DicomTags.cs +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - */ - -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Monai.Deploy.WorkflowManager.Contracts.Models -{ - public class DicomTags - { - [JsonProperty(PropertyName = "study_id")] - public string StudyId { get; set; } - - [JsonProperty(PropertyName = "tags")] - public Dictionary Tags { get; set; } - - [JsonProperty(PropertyName = "series")] - public List Series { get; set; } - } -} diff --git a/src/Contracts/Models/DicomValue.cs b/src/Contracts/Models/DicomValue.cs index 23123f025..73f383f42 100644 --- a/src/Contracts/Models/DicomValue.cs +++ b/src/Contracts/Models/DicomValue.cs @@ -21,9 +21,9 @@ namespace Monai.Deploy.WorkflowManager.Contracts.Models public class DicomValue { [JsonProperty(PropertyName = "vr")] - public string Vr { get; set; } + public string Vr { get; set; } = string.Empty; [JsonProperty(PropertyName = "Value")] - public object[] Value { get; set; } + public object[] Value { get; set; } = System.Array.Empty(); } } diff --git a/src/Contracts/Models/Evaluator.cs b/src/Contracts/Models/Evaluator.cs deleted file mode 100644 index 6c59dcd61..000000000 --- a/src/Contracts/Models/Evaluator.cs +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - */ - -using Newtonsoft.Json; - -namespace Monai.Deploy.WorkflowManager.Contracts.Models -{ - public class Evaluator - { - [JsonProperty(PropertyName = "correlation_id")] - public string CorrelationId { get; set; } - - [JsonProperty(PropertyName = "input")] - public Artifact Input { get; set; } - - [JsonProperty(PropertyName = "executions")] - public ExecutionContext Executions { get; set; } - - [JsonProperty(PropertyName = "dicom")] - public ExecutionContext Dicom { get; set; } - } -} diff --git a/src/Contracts/Models/ExecutionContext.cs b/src/Contracts/Models/ExecutionContext.cs deleted file mode 100644 index cca46e36f..000000000 --- a/src/Contracts/Models/ExecutionContext.cs +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Monai.Deploy.WorkflowManager.Contracts.Models -{ - public class ExecutionContext - { - [JsonProperty(PropertyName = "execution_id")] - public string ExecutionId { get; set; } - - [JsonProperty(PropertyName = "task_id")] - public string TaskId { get; set; } - - [JsonProperty(PropertyName = "input_dir")] - public string InputDir { get; set; } - - [JsonProperty(PropertyName = "output_dir")] - public string OutputDir { get; set; } - - [JsonProperty(PropertyName = "task")] - public Dictionary Task { get; set; } - - [JsonProperty(PropertyName = "start_time")] - public decimal StartTime { get; set; } - - [JsonProperty(PropertyName = "end_time")] - public decimal EndTime { get; set; } - - [JsonProperty(PropertyName = "status")] - public string Status { get; set; } - - [JsonProperty(PropertyName = "error_msg")] - public string ErrorMsg { get; set; } - - [JsonProperty(PropertyName = "result")] - public Dictionary Result { get; set; } - } -} diff --git a/src/Contracts/Models/InformaticsGateway.cs b/src/Contracts/Models/InformaticsGateway.cs index 9764f4df1..c93af196b 100644 --- a/src/Contracts/Models/InformaticsGateway.cs +++ b/src/Contracts/Models/InformaticsGateway.cs @@ -21,12 +21,12 @@ namespace Monai.Deploy.WorkflowManager.Contracts.Models public class InformaticsGateway { [JsonProperty(PropertyName = "ae_title")] - public string AeTitle { get; set; } + public string AeTitle { get; set; } = string.Empty; [JsonProperty(PropertyName = "data_origins")] - public string[] DataOrigins { get; set; } + public string[] DataOrigins { get; set; } = System.Array.Empty(); [JsonProperty(PropertyName = "export_destinations")] - public string[] ExportDestinations { get; set; } + public string[] ExportDestinations { get; set; } = System.Array.Empty(); } } diff --git a/src/Contracts/Models/PatientDetails.cs b/src/Contracts/Models/PatientDetails.cs index 3accd68b5..4985cdf9f 100644 --- a/src/Contracts/Models/PatientDetails.cs +++ b/src/Contracts/Models/PatientDetails.cs @@ -22,21 +22,21 @@ namespace Monai.Deploy.WorkflowManager.Contracts.Models public class PatientDetails { [JsonProperty(PropertyName = "patient_id")] - public string PatientId { get; set; } + public string PatientId { get; set; } = string.Empty; [JsonProperty(PropertyName = "patient_name")] - public string PatientName { get; set; } + public string PatientName { get; set; } = string.Empty; [JsonProperty(PropertyName = "patient_sex")] - public string PatientSex { get; set; } + public string PatientSex { get; set; } = string.Empty; [JsonProperty(PropertyName = "patient_dob")] public DateTime? PatientDob { get; set; } [JsonProperty(PropertyName = "patient_age")] - public string PatientAge { get; set; } + public string PatientAge { get; set; } = string.Empty; [JsonProperty(PropertyName = "patient_hospital_id")] - public string PatientHospitalId { get; set; } + public string PatientHospitalId { get; set; } = string.Empty; } } diff --git a/src/Contracts/Models/TaskDestination.cs b/src/Contracts/Models/TaskDestination.cs index f38c154f7..19cc916ef 100644 --- a/src/Contracts/Models/TaskDestination.cs +++ b/src/Contracts/Models/TaskDestination.cs @@ -21,11 +21,9 @@ namespace Monai.Deploy.WorkflowManager.Contracts.Models public class TaskDestination { [JsonProperty(PropertyName = "name")] -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public string Name { get; set; } -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public string Name { get; set; } = string.Empty; [JsonProperty(PropertyName = "conditions")] - public string Conditions { get; set; } = ""; + public string Conditions { get; set; } = string.Empty; } } diff --git a/src/Contracts/Models/TaskExecution.cs b/src/Contracts/Models/TaskExecution.cs index 2de4f5506..ac7709ec5 100644 --- a/src/Contracts/Models/TaskExecution.cs +++ b/src/Contracts/Models/TaskExecution.cs @@ -24,25 +24,25 @@ namespace Monai.Deploy.WorkflowManager.Contracts.Models public class TaskExecution { [JsonProperty(PropertyName = "execution_id")] - public string ExecutionId { get; set; } + public string ExecutionId { get; set; } = string.Empty; [JsonProperty(PropertyName = "task_type")] - public string TaskType { get; set; } + public string TaskType { get; set; } = string.Empty; [JsonProperty(PropertyName = "task_start_time")] public DateTime? TaskStartTime { get; set; } [JsonProperty(PropertyName = "execution_stats")] - public Dictionary ExecutionStats { get; set; } + public Dictionary ExecutionStats { get; set; } = new Dictionary(); [JsonProperty(PropertyName = "task_plugin_arguments")] - public Dictionary TaskPluginArguments { get; set; } + public Dictionary TaskPluginArguments { get; set; } = new Dictionary(); [JsonProperty(PropertyName = "task_id")] - public string TaskId { get; set; } + public string TaskId { get; set; } = string.Empty; [JsonProperty(PropertyName = "previous_task_id")] - public string PreviousTaskId { get; set; } + public string PreviousTaskId { get; set; } = string.Empty; [JsonProperty(PropertyName = "status")] public TaskExecutionStatus Status { get; set; } @@ -51,18 +51,18 @@ public class TaskExecution public FailureReason Reason { get; set; } [JsonProperty(PropertyName = "input_artifacts")] - public Dictionary InputArtifacts { get; set; } + public Dictionary InputArtifacts { get; set; } = new Dictionary(); [JsonProperty(PropertyName = "output_artifacts")] - public Dictionary OutputArtifacts { get; set; } + public Dictionary OutputArtifacts { get; set; } = new Dictionary(); [JsonProperty(PropertyName = "output_directory")] - public string OutputDirectory { get; set; } + public string OutputDirectory { get; set; } = string.Empty; [JsonProperty(PropertyName = "result")] - public Dictionary ResultMetadata { get; set; } + public Dictionary ResultMetadata { get; set; } = new Dictionary(); [JsonProperty(PropertyName = "input_parameters")] - public Dictionary InputParameters { get; set; } + public Dictionary InputParameters { get; set; } = new Dictionary(); } } diff --git a/src/Contracts/Models/TaskPluginArguments.cs b/src/Contracts/Models/TaskPluginArguments.cs deleted file mode 100644 index 24acbc511..000000000 --- a/src/Contracts/Models/TaskPluginArguments.cs +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ - -using Microsoft.Extensions.Configuration; - -namespace Monai.Deploy.WorkflowManager.Contracts.Models -{ - public class TaskPluginArguments - { - [ConfigurationKeyName("workflow_id")] - public string WorkflowId { get; set; } - - [ConfigurationKeyName("server_url")] - public string ServerUrl { get; set; } - } -} diff --git a/src/Contracts/Models/Workflow.cs b/src/Contracts/Models/Workflow.cs index 19ca0823d..cce7332b1 100644 --- a/src/Contracts/Models/Workflow.cs +++ b/src/Contracts/Models/Workflow.cs @@ -21,18 +21,18 @@ namespace Monai.Deploy.WorkflowManager.Contracts.Models public class Workflow { [JsonProperty(PropertyName = "name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; [JsonProperty(PropertyName = "version")] - public string Version { get; set; } + public string Version { get; set; } = string.Empty; [JsonProperty(PropertyName = "description")] - public string Description { get; set; } + public string Description { get; set; } = string.Empty; [JsonProperty(PropertyName = "informatics_gateway")] - public InformaticsGateway InformaticsGateway { get; set; } + public InformaticsGateway? InformaticsGateway { get; set; } [JsonProperty(PropertyName = "tasks")] - public TaskObject[] Tasks { get; set; } + public TaskObject[] Tasks { get; set; } = System.Array.Empty(); } } diff --git a/src/Contracts/Models/WorkflowInstance.cs b/src/Contracts/Models/WorkflowInstance.cs index 328ca26f9..631a6328f 100644 --- a/src/Contracts/Models/WorkflowInstance.cs +++ b/src/Contracts/Models/WorkflowInstance.cs @@ -23,16 +23,16 @@ namespace Monai.Deploy.WorkflowManager.Contracts.Models public class WorkflowInstance { [JsonProperty(PropertyName = "id")] - public string Id { get; set; } + public string Id { get; set; } = string.Empty; [JsonProperty(PropertyName = "ae_title")] - public string AeTitle { get; set; } + public string? AeTitle { get; set; } = string.Empty; [JsonProperty(PropertyName = "workflow_id")] - public string WorkflowId { get; set; } + public string WorkflowId { get; set; } = string.Empty; [JsonProperty(PropertyName = "payload_id")] - public string PayloadId { get; set; } + public string PayloadId { get; set; } = string.Empty; [JsonProperty(PropertyName = "start_time")] public DateTime StartTime { get; set; } @@ -41,12 +41,12 @@ public class WorkflowInstance public Status Status { get; set; } [JsonProperty(PropertyName = "bucket_id")] - public string BucketId { get; set; } + public string BucketId { get; set; } = string.Empty; [JsonProperty(PropertyName = "input_metadata")] - public Dictionary InputMetaData { get; set; } + public Dictionary InputMetaData { get; set; } = new Dictionary(); [JsonProperty(PropertyName = "tasks")] - public List Tasks { get; set; } + public List Tasks { get; set; } = new List(); } } diff --git a/src/Contracts/Models/WorkflowRevision.cs b/src/Contracts/Models/WorkflowRevision.cs index 0db35ff4a..d3b776de0 100644 --- a/src/Contracts/Models/WorkflowRevision.cs +++ b/src/Contracts/Models/WorkflowRevision.cs @@ -24,16 +24,16 @@ public class WorkflowRevision : ISoftDeleteable { [BsonId] [JsonProperty(PropertyName = "id")] - public string Id { get; set; } + public string? Id { get; set; } [JsonProperty(PropertyName = "workflow_id")] - public string WorkflowId { get; set; } + public string WorkflowId { get; set; } = string.Empty; [JsonProperty(PropertyName = "revision")] public int Revision { get; set; } [JsonProperty(PropertyName = "workflow")] - public Workflow Workflow { get; set; } + public Workflow? Workflow { get; set; } [JsonIgnore] public DateTime? Deleted { get; set; } = null; diff --git a/src/Database/Interfaces/IPayloadRepsitory.cs b/src/Database/Interfaces/IPayloadRepsitory.cs index 1ce1b59d3..bb991874a 100644 --- a/src/Database/Interfaces/IPayloadRepsitory.cs +++ b/src/Database/Interfaces/IPayloadRepsitory.cs @@ -31,7 +31,7 @@ public interface IPayloadRepsitory /// /// Retrieves a list of payloads in the database. /// - Task> GetAllAsync(int? skip = null, int? limit = null, string patientId = "", string patientName = ""); + Task> GetAllAsync(int? skip = null, int? limit = null, string? patientId = "", string? patientName = ""); /// /// Retrieves a payload by id in the database. diff --git a/src/Database/Interfaces/IWorkflowInstanceRepository.cs b/src/Database/Interfaces/IWorkflowInstanceRepository.cs index 8166cfeb9..484c4769f 100644 --- a/src/Database/Interfaces/IWorkflowInstanceRepository.cs +++ b/src/Database/Interfaces/IWorkflowInstanceRepository.cs @@ -81,7 +81,7 @@ public interface IWorkflowInstanceRepository /// /// A Workflow Instance Id to retrieve a task from. /// A Task Id to retrieve. - Task GetTaskByIdAsync(string workflowInstanceId, string taskId); + Task GetTaskByIdAsync(string workflowInstanceId, string taskId); /// /// Updates the Task list for a given workflow instance. diff --git a/src/Database/Repositories/WorkflowInstanceRepository.cs b/src/Database/Repositories/WorkflowInstanceRepository.cs index 8ae04416b..11e52f45a 100644 --- a/src/Database/Repositories/WorkflowInstanceRepository.cs +++ b/src/Database/Repositories/WorkflowInstanceRepository.cs @@ -182,7 +182,7 @@ await _workflowInstanceCollection.FindOneAndUpdateAsync( } } - public async Task GetTaskByIdAsync(string workflowInstanceId, string taskId) + public async Task GetTaskByIdAsync(string workflowInstanceId, string taskId) { Guard.Against.NullOrWhiteSpace(workflowInstanceId, nameof(workflowInstanceId)); Guard.Against.NullOrWhiteSpace(taskId, nameof(taskId)); diff --git a/src/Database/Repositories/WorkflowRepository.cs b/src/Database/Repositories/WorkflowRepository.cs index 3f8b6b705..146ae729c 100644 --- a/src/Database/Repositories/WorkflowRepository.cs +++ b/src/Database/Repositories/WorkflowRepository.cs @@ -102,7 +102,7 @@ public async Task> GetByWorkflowsIdsAsync(IEnumerable GetByAeTitleAsync(string aeTitle) { Guard.Against.NullOrWhiteSpace(aeTitle, nameof(aeTitle)); - +#pragma warning disable CS8602 // Dereference of a possibly null reference. var workflow = await _workflowCollection .Find(x => x.Workflow.InformaticsGateway.AeTitle == aeTitle && x.Deleted == null) .Sort(Builders.Sort.Descending("Revision")) @@ -117,10 +117,12 @@ public async Task> GetWorkflowsByAeTitleAsync(string aeT var workflows = new List(); + workflows = await _workflowCollection .Find(x => x.Workflow.InformaticsGateway.AeTitle == aeTitle) .Sort(Builders.Sort.Descending("Revision")) .ToListAsync(); +#pragma warning restore CS8602 // Dereference of a possibly null reference. workflows = workflows.GroupBy(w => w.WorkflowId).Select(g => g.First()).ToList(); diff --git a/src/TaskManager/Plug-ins/AideClinicalReview/AideClinicalReviewPlugin.cs b/src/TaskManager/Plug-ins/AideClinicalReview/AideClinicalReviewPlugin.cs index d9cc42ad2..e08263f06 100644 --- a/src/TaskManager/Plug-ins/AideClinicalReview/AideClinicalReviewPlugin.cs +++ b/src/TaskManager/Plug-ins/AideClinicalReview/AideClinicalReviewPlugin.cs @@ -27,7 +27,7 @@ namespace Monai.Deploy.WorkflowManager.TaskManager.AideClinicalReview { - public class AideClinicalReviewPlugin : TaskPluginBase, IAsyncDisposable + public class AideClinicalReviewPlugin : TaskPluginBase, IDisposable { private const string TaskManagerApplicationId = "4c9072a1-35f5-4d85-847d-dafca22244a8"; private readonly IServiceScope _scope; @@ -197,13 +197,5 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - -#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously - public async ValueTask DisposeAsync() -#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously - { - Dispose(disposing: false); - GC.SuppressFinalize(this); - } } } diff --git a/src/TaskManager/Plug-ins/Argo/Repositories/ArgoMetadataRepository.cs b/src/TaskManager/Plug-ins/Argo/Repositories/ArgoMetadataRepository.cs index e4ec7c3f6..0431c0cf8 100644 --- a/src/TaskManager/Plug-ins/Argo/Repositories/ArgoMetadataRepository.cs +++ b/src/TaskManager/Plug-ins/Argo/Repositories/ArgoMetadataRepository.cs @@ -26,7 +26,7 @@ namespace Monai.Deploy.WorkflowManager.TaskManager.Argo.Repositories { - public sealed class ArgoMetadataRepository : MetadataRepositoryBase, IAsyncDisposable + public sealed class ArgoMetadataRepository : MetadataRepositoryBase, IDisposable { private readonly IStorageService _storageService; private readonly IServiceScope _scope; @@ -71,7 +71,7 @@ public override async Task> RetrieveMetadata(Cancella return new Dictionary(); } - return JsonConvert.DeserializeObject>(jsonStr); + return JsonConvert.DeserializeObject>(jsonStr) ?? new Dictionary(); } private async Task RetrieveJsonFromFile(string bucketName, string path) @@ -103,11 +103,5 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - - public async ValueTask DisposeAsync() - { - Dispose(disposing: false); - GC.SuppressFinalize(this); - } } } diff --git a/src/TaskManager/Plug-ins/TestPlugin/Repositories/ArgoMetadataRepository.cs b/src/TaskManager/Plug-ins/TestPlugin/Repositories/TestPluginRepository.cs similarity index 89% rename from src/TaskManager/Plug-ins/TestPlugin/Repositories/ArgoMetadataRepository.cs rename to src/TaskManager/Plug-ins/TestPlugin/Repositories/TestPluginRepository.cs index 8fec10682..378e2fa2a 100644 --- a/src/TaskManager/Plug-ins/TestPlugin/Repositories/ArgoMetadataRepository.cs +++ b/src/TaskManager/Plug-ins/TestPlugin/Repositories/TestPluginRepository.cs @@ -21,7 +21,7 @@ namespace Monai.Deploy.WorkflowManager.TaskManager.TestPlugin.Repositories { - public sealed class TestPluginRepository : MetadataRepositoryBase, IAsyncDisposable + public sealed class TestPluginRepository : MetadataRepositoryBase, IDisposable { private readonly IServiceScope _scope; @@ -50,7 +50,7 @@ private void Validate() public override async Task> RetrieveMetadata(CancellationToken cancellationToken = default) { - return await Task.FromResult(new Dictionary()); + return await Task.Run(() => new Dictionary()).ConfigureAwait(false); } ~TestPluginRepository() => Dispose(disposing: false); @@ -64,11 +64,5 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - - public async ValueTask DisposeAsync() - { - Dispose(disposing: false); - GC.SuppressFinalize(this); - } } } diff --git a/src/TaskManager/TaskManager.cs b/src/TaskManager/TaskManager.cs index 50fde3644..b8fd31494 100644 --- a/src/TaskManager/TaskManager.cs +++ b/src/TaskManager/TaskManager.cs @@ -370,7 +370,7 @@ await Task.WhenAll( } } - private async Task?> RetrievePluginMetadata(JsonMessage message, TaskDispatchEvent dispatchEvent, string metadataAssembly) + private async Task?> RetrievePluginMetadata(JsonMessage message, TaskDispatchEvent dispatchEvent, string? metadataAssembly) { if (string.IsNullOrWhiteSpace(metadataAssembly)) { diff --git a/src/WorkflowExecuter/Common/ArtifactMapper.cs b/src/WorkflowExecuter/Common/ArtifactMapper.cs index 84614bcdc..db389dc75 100644 --- a/src/WorkflowExecuter/Common/ArtifactMapper.cs +++ b/src/WorkflowExecuter/Common/ArtifactMapper.cs @@ -108,6 +108,11 @@ private async Task> ConvertVariableStringToPath(Art var task = await _workflowInstanceRepository.GetTaskByIdAsync(workflowInstanceId, variableTaskId); + if (task is null) + { + return default; + } + if (string.Equals(variableLocation, "output_dir", StringComparison.InvariantCultureIgnoreCase)) { return await VerifyExists(new KeyValuePair(artifact.Name, task.OutputDirectory), bucketId, shouldExistYet); diff --git a/src/WorkflowExecuter/Services/WorkflowExecuterService.cs b/src/WorkflowExecuter/Services/WorkflowExecuterService.cs index 055c0071e..b7c7e8207 100644 --- a/src/WorkflowExecuter/Services/WorkflowExecuterService.cs +++ b/src/WorkflowExecuter/Services/WorkflowExecuterService.cs @@ -363,7 +363,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, string[]? exportDestinations, string[] artifactValues, string correlationId) { if (exportDestinations is null || !exportDestinations.Any()) { @@ -398,7 +398,7 @@ private async Task HandleOutputArtifacts(WorkflowInstance workflowInstance private async Task DispatchTaskDestinations(WorkflowInstance workflowInstance, WorkflowRevision workflow, string correlationId, IList taskExecutions) { - workflowInstance.Tasks?.AddRange(taskExecutions); + workflowInstance.Tasks.AddRange(taskExecutions); if (!await _workflowInstanceRepository.UpdateTasksAsync(workflowInstance.Id, workflowInstance.Tasks)) { @@ -611,7 +611,7 @@ private async Task CreateTaskExecutionAsync(TaskObject task, OutputDirectory = $"{payloadId}/workflows/{workflowInstanceId}/{executionId}", ResultMetadata = { }, InputParameters = newInputParameters, - PreviousTaskId = previousTaskId + PreviousTaskId = previousTaskId is not null ? previousTaskId : string.Empty }; } diff --git a/src/WorkflowManager/Controllers/ApiControllerBase.cs b/src/WorkflowManager/Controllers/ApiControllerBase.cs index 953d82db9..75ea72589 100644 --- a/src/WorkflowManager/Controllers/ApiControllerBase.cs +++ b/src/WorkflowManager/Controllers/ApiControllerBase.cs @@ -38,7 +38,7 @@ public class ApiControllerBase : ControllerBase /// /// Initializes a new instance of the class. /// - /// + /// Workflow manager options. public ApiControllerBase(IOptions options) { _options = options ?? throw new ArgumentNullException(nameof(options)); diff --git a/src/WorkflowManager/Controllers/PayloadController.cs b/src/WorkflowManager/Controllers/PayloadController.cs index ada50af65..ff11e1477 100644 --- a/src/WorkflowManager/Controllers/PayloadController.cs +++ b/src/WorkflowManager/Controllers/PayloadController.cs @@ -25,104 +25,107 @@ using Monai.Deploy.WorkflowManager.Filter; using Monai.Deploy.WorkflowManager.Services; -namespace Monai.Deploy.WorkflowManager.Controllers; - -/// -/// Payloads Controller. -/// -[ApiController] -[Route("payload")] -public class PayloadController : ApiControllerBase +namespace Monai.Deploy.WorkflowManager.Controllers { - private readonly IOptions _options; - private readonly IPayloadService _payloadService; - - private readonly ILogger _logger; - private readonly IUriService _uriService; - - /// - /// Initializes a new instance of the class. - /// - /// paylod service to retrieve payloads. - /// logger. - /// Uri Service. - public PayloadController(IPayloadService payloadService, - ILogger logger, - IUriService uriService, - IOptions options) - : base(options) - { - _options = options ?? throw new ArgumentNullException(nameof(options)); - _payloadService = payloadService ?? throw new ArgumentNullException(nameof(payloadService)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _uriService = uriService ?? throw new ArgumentNullException(nameof(uriService)); - } - /// - /// Gets a paged response list of all workflows. + /// Payloads Controller. /// - /// Filters. - /// Optional paient Id. - /// Optional patient name. - /// paged response of subset of all workflows. - [HttpGet] - public async Task GetAllAsync([FromQuery] PaginationFilter filter, [FromQuery] string patientId = "", [FromQuery] string patientName = "") + [ApiController] + [Route("payload")] + public class PayloadController : ApiControllerBase { - try - { - var route = Request?.Path.Value ?? string.Empty; - var pageSize = filter.PageSize ?? _options.Value.EndpointSettings.DefaultPageSize; - var validFilter = new PaginationFilter(filter.PageNumber, pageSize, _options.Value.EndpointSettings.MaxPageSize); - - var pagedData = await _payloadService.GetAllAsync( - (validFilter.PageNumber - 1) * validFilter.PageSize, - validFilter.PageSize, - patientId, - patientName); + private readonly IOptions _options; + private readonly IPayloadService _payloadService; - var dataTotal = await _payloadService.CountAsync(); - var pagedReponse = CreatePagedReponse(pagedData.ToList(), validFilter, dataTotal, _uriService, route); + private readonly ILogger _logger; + private readonly IUriService _uriService; - return Ok(pagedReponse); - } - catch (Exception e) + /// + /// Initializes a new instance of the class. + /// + /// paylod service to retrieve payloads. + /// logger. + /// Uri Service. + /// Workflow Manager options. + public PayloadController( + IPayloadService payloadService, + ILogger logger, + IUriService uriService, + IOptions options) + : base(options) { - return Problem($"Unexpected error occured: {e.Message}", $"/payload", InternalServerError); + _options = options ?? throw new ArgumentNullException(nameof(options)); + _payloadService = payloadService ?? throw new ArgumentNullException(nameof(payloadService)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _uriService = uriService ?? throw new ArgumentNullException(nameof(uriService)); } - } - /// - /// Get a workflow by the ID. - /// - /// The Workflow Id - /// The specified workflow for a given Id. - [Route("{id}")] - [HttpGet] - public async Task GetAsync([FromRoute] string id) - { - if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) + /// + /// Gets a paged response list of all workflows. + /// + /// Filters. + /// Optional paient Id. + /// Optional patient name. + /// paged response of subset of all workflows. + [HttpGet] + public async Task GetAllAsync([FromQuery] PaginationFilter filter, [FromQuery] string patientId = "", [FromQuery] string patientName = "") { - _logger.LogDebug($"{nameof(GetAsync)} - Failed to validate {nameof(id)}"); + try + { + var route = Request?.Path.Value ?? string.Empty; + var pageSize = filter.PageSize ?? _options.Value.EndpointSettings.DefaultPageSize; + var validFilter = new PaginationFilter(filter.PageNumber, pageSize, _options.Value.EndpointSettings.MaxPageSize); - return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/payload/{id}", BadRequest); + var pagedData = await _payloadService.GetAllAsync( + (validFilter.PageNumber - 1) * validFilter.PageSize, + validFilter.PageSize, + patientId, + patientName); + + var dataTotal = await _payloadService.CountAsync(); + var pagedReponse = CreatePagedReponse(pagedData.ToList(), validFilter, dataTotal, _uriService, route); + + return Ok(pagedReponse); + } + catch (Exception e) + { + return Problem($"Unexpected error occured: {e.Message}", $"/payload", InternalServerError); + } } - try + /// + /// Get a workflow by the ID. + /// + /// The Workflow Id. + /// The specified workflow for a given Id. + [Route("{id}")] + [HttpGet] + public async Task GetAsync([FromRoute] string id) { - var payload = await _payloadService.GetByIdAsync(id); - - if (payload is null) + if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) { - _logger.LogDebug($"{nameof(GetAsync)} - Failed to find payload with payload id: {id}"); + _logger.LogDebug($"{nameof(GetAsync)} - Failed to validate {nameof(id)}"); - return NotFound($"Faild to find payload with payload id: {id}"); + return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/payload/{id}", BadRequest); } - return Ok(payload); - } - catch (Exception e) - { - return Problem($"Unexpected error occured: {e.Message}", $"/payload/{nameof(id)}", InternalServerError); + try + { + var payload = await _payloadService.GetByIdAsync(id); + + if (payload is null) + { + _logger.LogDebug($"{nameof(GetAsync)} - Failed to find payload with payload id: {id}"); + + return NotFound($"Faild to find payload with payload id: {id}"); + } + + return Ok(payload); + } + catch (Exception e) + { + return Problem($"Unexpected error occured: {e.Message}", $"/payload/{nameof(id)}", InternalServerError); + } } } } diff --git a/src/WorkflowManager/Controllers/WorkflowInstanceController.cs b/src/WorkflowManager/Controllers/WorkflowInstanceController.cs index f29d96cbf..6f2f6cb0c 100644 --- a/src/WorkflowManager/Controllers/WorkflowInstanceController.cs +++ b/src/WorkflowManager/Controllers/WorkflowInstanceController.cs @@ -23,110 +23,112 @@ using Microsoft.Extensions.Options; using Monai.Deploy.WorkflowManager.Common.Interfaces; using Monai.Deploy.WorkflowManager.Configuration; +using Monai.Deploy.WorkflowManager.Contracts.Models; using Monai.Deploy.WorkflowManager.Filter; using Monai.Deploy.WorkflowManager.Services; -using Monai.Deploy.WorkflowManager.Contracts.Models; - -namespace Monai.Deploy.WorkflowManager.Controllers; -/// -/// Workflow Instances Controller. -/// -[ApiController] -[Route("workflowinstances")] -public class WorkflowInstanceController : ApiControllerBase +namespace Monai.Deploy.WorkflowManager.Controllers { - private readonly IOptions _options; - private readonly IWorkflowInstanceService _workflowInstanceService; - - private readonly ILogger _logger; - private readonly IUriService _uriService; - /// - /// Initializes a new instance of the class. + /// Workflow Instances Controller. /// - /// Workflow Instance Service. - /// Logger. - /// Uri Service. - public WorkflowInstanceController( - IWorkflowInstanceService workflowInstanceService, - ILogger logger, - IUriService uriService, - IOptions options) - : base(options) + [ApiController] + [Route("workflowinstances")] + public class WorkflowInstanceController : ApiControllerBase { - _options = options ?? throw new ArgumentNullException(nameof(options)); - _workflowInstanceService = workflowInstanceService ?? throw new ArgumentNullException(nameof(workflowInstanceService)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _uriService = uriService ?? throw new ArgumentNullException(nameof(uriService)); - } + private readonly IOptions _options; + private readonly IWorkflowInstanceService _workflowInstanceService; + + private readonly ILogger _logger; + private readonly IUriService _uriService; + + /// + /// Initializes a new instance of the class. + /// + /// Workflow Instance Service. + /// Logger. + /// Uri Service. + /// Workflow Manager options. + public WorkflowInstanceController( + IWorkflowInstanceService workflowInstanceService, + ILogger logger, + IUriService uriService, + IOptions options) + : base(options) + { + _options = options ?? throw new ArgumentNullException(nameof(options)); + _workflowInstanceService = workflowInstanceService ?? throw new ArgumentNullException(nameof(workflowInstanceService)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _uriService = uriService ?? throw new ArgumentNullException(nameof(uriService)); + } - /// - /// Get a list of workflowInstances. - /// - /// Filters. - /// Workflow instance status filter. - /// A list of workflow instances. - [HttpGet] - public async Task GetListAsync([FromQuery] PaginationFilter filter, [FromQuery] string? status = null) - { - try + /// + /// Get a list of workflowInstances. + /// + /// Filters. + /// Workflow instance status filter. + /// A list of workflow instances. + [HttpGet] + public async Task GetListAsync([FromQuery] PaginationFilter filter, [FromQuery] string? status = null) { - var route = Request?.Path.Value ?? string.Empty; - var pageSize = filter.PageSize ?? _options.Value.EndpointSettings.DefaultPageSize; - Status? parsedStatus = status == null ? null : Enum.Parse(status, true); - var validFilter = new PaginationFilter(filter.PageNumber, pageSize, _options.Value.EndpointSettings.MaxPageSize); + try + { + var route = Request?.Path.Value ?? string.Empty; + var pageSize = filter.PageSize ?? _options.Value.EndpointSettings.DefaultPageSize; + Status? parsedStatus = status == null ? null : Enum.Parse(status, true); + var validFilter = new PaginationFilter(filter.PageNumber, pageSize, _options.Value.EndpointSettings.MaxPageSize); - var pagedData = await _workflowInstanceService.GetAllAsync( - (validFilter.PageNumber - 1) * validFilter.PageSize, - validFilter.PageSize, - parsedStatus); + var pagedData = await _workflowInstanceService.GetAllAsync( + (validFilter.PageNumber - 1) * validFilter.PageSize, + validFilter.PageSize, + parsedStatus); - var dataTotal = await _workflowInstanceService.CountAsync(); - var pagedReponse = CreatePagedReponse(pagedData.ToList(), validFilter, dataTotal, _uriService, route); + var dataTotal = await _workflowInstanceService.CountAsync(); + var pagedReponse = CreatePagedReponse(pagedData.ToList(), validFilter, dataTotal, _uriService, route); - return Ok(pagedReponse); - } - catch (Exception e) - { - _logger.LogError($"{nameof(GetListAsync)} - Failed to get workflowInstances", e); + return Ok(pagedReponse); + } + catch (Exception e) + { + _logger.LogError($"{nameof(GetListAsync)} - Failed to get workflowInstances", e); - return Problem($"Unexpected error occured: {e.Message}", $"/workflowinstances", (int)HttpStatusCode.InternalServerError); + return Problem($"Unexpected error occured: {e.Message}", $"/workflowinstances", (int)HttpStatusCode.InternalServerError); + } } - } - /// - /// Get a list of workflowInstances. - /// - /// The Workflow Instance Id. - /// A list of workflow instances. - [Route("{id}")] - [HttpGet] - public async Task GetByIdAsync([FromRoute] string id) - { - if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) + /// + /// Get a list of workflowInstances. + /// + /// The Workflow Instance Id. + /// A list of workflow instances. + [Route("{id}")] + [HttpGet] + public async Task GetByIdAsync([FromRoute] string id) { - _logger.LogDebug($"{nameof(GetByIdAsync)} - Failed to validate {nameof(id)}"); - - return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/workflows/{id}", (int)HttpStatusCode.BadRequest); - } + if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) + { + _logger.LogDebug($"{nameof(GetByIdAsync)} - Failed to validate {nameof(id)}"); - try - { - var workflowInstance = await _workflowInstanceService.GetByIdAsync(id); + return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/workflows/{id}", (int)HttpStatusCode.BadRequest); + } - if (workflowInstance is null) + try { - _logger.LogDebug($"{nameof(GetByIdAsync)} - Failed to find workflow instance with Id: {id}"); + var workflowInstance = await _workflowInstanceService.GetByIdAsync(id); - return NotFound($"Faild to find workflow instance with Id: {id}"); - } + if (workflowInstance is null) + { + _logger.LogDebug($"{nameof(GetByIdAsync)} - Failed to find workflow instance with Id: {id}"); - return Ok(workflowInstance); - } - catch (Exception e) - { - return Problem($"Unexpected error occured: {e.Message}", $"/workflowinstances/{nameof(id)}", (int)HttpStatusCode.InternalServerError); + return NotFound($"Faild to find workflow instance with Id: {id}"); + } + + return Ok(workflowInstance); + } + catch (Exception e) + { + return Problem($"Unexpected error occured: {e.Message}", $"/workflowinstances/{nameof(id)}", (int)HttpStatusCode.InternalServerError); + } } } } diff --git a/src/WorkflowManager/Controllers/WorkflowsController.cs b/src/WorkflowManager/Controllers/WorkflowsController.cs index c44473fa1..7e935d273 100644 --- a/src/WorkflowManager/Controllers/WorkflowsController.cs +++ b/src/WorkflowManager/Controllers/WorkflowsController.cs @@ -26,216 +26,215 @@ using Monai.Deploy.WorkflowManager.Contracts.Models; using Monai.Deploy.WorkflowManager.Contracts.Responses; using Monai.Deploy.WorkflowManager.Filter; +using Monai.Deploy.WorkflowManager.PayloadListener.Extensions; using Monai.Deploy.WorkflowManager.Services; -using Monai.Deploy.WorkflowManager.Validators; -namespace Monai.Deploy.WorkflowManager.Controllers; - -/// -/// Workflows Controller. -/// -[ApiController] -[Route("workflows")] -public class WorkflowsController : ApiControllerBase +namespace Monai.Deploy.WorkflowManager.Controllers { - private readonly IOptions _options; - private readonly IWorkflowService _workflowService; - - private readonly ILogger _logger; - private readonly IUriService _uriService; - - /// - /// Initializes a new instance of the class. - /// - /// IWorkflowService. - /// ILogger. - /// Uri Service. - /// IOptions. - /// ArgumentNullException - public WorkflowsController( - IWorkflowService workflowService, - ILogger logger, - IUriService uriService, - IOptions options) - : base(options) - { - _options = options ?? throw new ArgumentNullException(nameof(options)); - _workflowService = workflowService ?? throw new ArgumentNullException(nameof(workflowService)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _uriService = uriService ?? throw new ArgumentNullException(nameof(uriService)); - } - /// - /// Gets a list of all workflows. + /// Workflows Controller. /// - /// The ID of the created Workflow. - [HttpGet] - public async Task GetList([FromQuery] PaginationFilter filter) + [ApiController] + [Route("workflows")] + public class WorkflowsController : ApiControllerBase { - try + private readonly IOptions _options; + private readonly IWorkflowService _workflowService; + + private readonly ILogger _logger; + private readonly IUriService _uriService; + + /// + /// Initializes a new instance of the class. + /// + /// IWorkflowService. + /// ILogger. + /// Uri Service. + /// Workflow Manager options. + /// ArgumentNullException + public WorkflowsController( + IWorkflowService workflowService, + ILogger logger, + IUriService uriService, + IOptions options) + : base(options) { - var route = Request?.Path.Value ?? string.Empty; - var pageSize = filter.PageSize ?? _options.Value.EndpointSettings.DefaultPageSize; - var validFilter = new PaginationFilter(filter.PageNumber, pageSize, _options.Value.EndpointSettings.MaxPageSize); - - var pagedData = await _workflowService.GetAllAsync( - (validFilter.PageNumber - 1) * validFilter.PageSize, - validFilter.PageSize); - - var dataTotal = await _workflowService.CountAsync(); - var pagedReponse = CreatePagedReponse(pagedData.ToList(), validFilter, dataTotal, _uriService, route); - - return Ok(pagedReponse); - } - catch (Exception e) - { - return Problem($"Unexpected error occured: {e.Message}", $"/workflows", InternalServerError); + _options = options ?? throw new ArgumentNullException(nameof(options)); + _workflowService = workflowService ?? throw new ArgumentNullException(nameof(workflowService)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _uriService = uriService ?? throw new ArgumentNullException(nameof(uriService)); } - } - /// - /// Get a workflow by the ID. - /// - /// The Workflow Id - /// The specified workflow for a given Id. - [Route("{id}")] - [HttpGet] - public async Task GetAsync([FromRoute] string id) - { - if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) + /// + /// Gets a list of all workflows. + /// + /// Pagination filter. + /// The ID of the created Workflow. + [HttpGet] + public async Task GetList([FromQuery] PaginationFilter filter) { - _logger.LogDebug($"{nameof(GetAsync)} - Failed to validate {nameof(id)}"); + try + { + var route = Request?.Path.Value ?? string.Empty; + var pageSize = filter.PageSize ?? _options.Value.EndpointSettings.DefaultPageSize; + var validFilter = new PaginationFilter(filter.PageNumber, pageSize, _options.Value.EndpointSettings.MaxPageSize); - return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/workflows/{id}", BadRequest); - } + var pagedData = await _workflowService.GetAllAsync( + (validFilter.PageNumber - 1) * validFilter.PageSize, + validFilter.PageSize); - try - { - var workflow = await _workflowService.GetAsync(id); - if (workflow is null) + var dataTotal = await _workflowService.CountAsync(); + var pagedReponse = CreatePagedReponse(pagedData.ToList(), validFilter, dataTotal, _uriService, route); + + return Ok(pagedReponse); + } + catch (Exception e) { - return Problem($"Failed to validate {nameof(id)}, workflow not found", $"/workflows/{id}", NotFound); + return Problem($"Unexpected error occured: {e.Message}", $"/workflows", InternalServerError); } - - return Ok(workflow); - } - catch (Exception e) - { - return Problem($"Unexpected error occured: {e.Message}", $"/workflows/{nameof(id)}", InternalServerError); } - } - /// - /// Create a workflow. - /// - /// The Workflow. - /// The ID of the created Workflow. - [HttpPost] - public async Task CreateAsync([FromBody] Workflow workflow) - { - var workflowHasErrors = WorkflowValidator.ValidateWorkflow(workflow, out var results); - if (workflowHasErrors) + /// + /// Get a workflow by the ID. + /// + /// The Workflow Id. + /// The specified workflow for a given Id. + [Route("{id}")] + [HttpGet] + public async Task GetAsync([FromRoute] string id) { - var errors = string.Join(", ", results.Errors); - _logger.LogDebug($"{nameof(CreateAsync)} - Failed to validate {nameof(workflow)}: {errors}"); + if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) + { + _logger.LogDebug($"{nameof(GetAsync)} - Failed to validate {nameof(id)}"); - return Problem($"Failed to validate {nameof(workflow)}: {errors}", $"/workflows", BadRequest); - } + return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/workflows/{id}", BadRequest); + } - try - { - var workflowId = await _workflowService.CreateAsync(workflow); + try + { + var workflow = await _workflowService.GetAsync(id); + if (workflow is null) + { + return Problem($"Failed to validate {nameof(id)}, workflow not found", $"/workflows/{id}", NotFound); + } - return StatusCode(StatusCodes.Status201Created, new CreateWorkflowResponse(workflowId)); - } - catch (Exception e) - { - return Problem($"Unexpected error occured: {e.Message}", $"/workflows", InternalServerError); + return Ok(workflow); + } + catch (Exception e) + { + return Problem($"Unexpected error occured: {e.Message}", $"/workflows/{nameof(id)}", InternalServerError); + } } - } - /// - /// Updates a workflow and creates a new revision. - /// - /// The Workflow. - /// The ID of the created Workflow. - [HttpPut("{id}")] - [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(CreateWorkflowResponse))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task UpdateAsync([FromBody] Workflow workflow, [FromRoute] string id) - { - if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) + /// + /// Create a workflow. + /// + /// The Workflow. + /// The ID of the created Workflow. + [HttpPost] + public async Task CreateAsync([FromBody] Workflow workflow) { - _logger.LogDebug($"{nameof(UpdateAsync)} - Failed to validate {nameof(id)}"); + if (!workflow.IsValid(out var validationErrors)) + { + _logger.LogDebug($"{nameof(CreateAsync)} - Failed to validate {nameof(workflow)}: {validationErrors}"); - return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/workflows/{id}", BadRequest); - } + return Problem($"Failed to validate {nameof(workflow)}: {string.Join(", ", validationErrors)}", $"/workflows", BadRequest); + } - var workflowHasErrors = WorkflowValidator.ValidateWorkflow(workflow, out var results); - if (workflowHasErrors) - { - var errors = string.Join(", ", results.Errors); - _logger.LogDebug($"{nameof(UpdateAsync)} - Failed to validate {nameof(workflow)}: {errors}"); + try + { + var workflowId = await _workflowService.CreateAsync(workflow); - return Problem($"Failed to validate {nameof(workflow)}: {errors}", $"/workflows/{id}", BadRequest); + return StatusCode(StatusCodes.Status201Created, new CreateWorkflowResponse(workflowId)); + } + catch (Exception e) + { + return Problem($"Unexpected error occured: {e.Message}", $"/workflows", InternalServerError); + } } - try + /// + /// Updates a workflow and creates a new revision. + /// + /// The Workflow. + /// The id of the workflow. + /// The ID of the created Workflow. + [HttpPut("{id}")] + [ProducesResponseType(StatusCodes.Status201Created, Type = typeof(CreateWorkflowResponse))] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task UpdateAsync([FromBody] Workflow workflow, [FromRoute] string id) { - var workflowId = await _workflowService.UpdateAsync(workflow, id); + if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) + { + _logger.LogDebug($"{nameof(UpdateAsync)} - Failed to validate {nameof(id)}"); - if (workflowId == null) + return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/workflows/{id}", BadRequest); + } + + if (!workflow.IsValid(out var validationErrors)) { - _logger.LogDebug($"{nameof(UpdateAsync)} - Failed to find workflow with Id: {id}"); + _logger.LogDebug($"{nameof(UpdateAsync)} - Failed to validate {nameof(workflow)}: {validationErrors}"); - return NotFound($"Failed to find workflow with Id: {id}"); + return Problem($"Failed to validate {nameof(workflow)}: {string.Join(", ", validationErrors)}", $"/workflows/{id}", BadRequest); } - return StatusCode(StatusCodes.Status201Created, new CreateWorkflowResponse(workflowId)); - } - catch (Exception e) - { - return Problem($"Unexpected error occured: {e.Message}", $"/workflows", InternalServerError); - } - } + try + { + var workflowId = await _workflowService.UpdateAsync(workflow, id); - /// - /// Soft deletes a workflow by the ID. - /// - /// The Workflow Id - /// The specified workflow for a given Id. - [Route("{id}")] - [HttpDelete] - public async Task DeleteAsync([FromRoute] string id) - { - if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) - { - _logger.LogDebug($"{nameof(GetAsync)} - Failed to validate {nameof(id)}"); + if (workflowId == null) + { + _logger.LogDebug($"{nameof(UpdateAsync)} - Failed to find workflow with Id: {id}"); + + return NotFound($"Failed to find workflow with Id: {id}"); + } - return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/workflows/{id}", BadRequest); + return StatusCode(StatusCodes.Status201Created, new CreateWorkflowResponse(workflowId)); + } + catch (Exception e) + { + return Problem($"Unexpected error occured: {e.Message}", $"/workflows", InternalServerError); + } } - try + /// + /// Soft deletes a workflow by the ID. + /// + /// The Workflow Id. + /// The specified workflow for a given Id. + [Route("{id}")] + [HttpDelete] + public async Task DeleteAsync([FromRoute] string id) { - var workflow = await _workflowService.GetAsync(id); - if (workflow == null || workflow.IsDeleted) + if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _)) { - return Problem($"Failed to validate {nameof(id)}, workflow not found", $"/workflows/{id}", NotFound); + _logger.LogDebug($"{nameof(GetAsync)} - Failed to validate {nameof(id)}"); + + return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/workflows/{id}", BadRequest); } - workflow.Deleted = DateTime.UtcNow; + try + { + var workflow = await _workflowService.GetAsync(id); + if (workflow == null || workflow.IsDeleted) + { + return Problem($"Failed to validate {nameof(id)}, workflow not found", $"/workflows/{id}", NotFound); + } - var workflowId = await _workflowService.DeleteWorkflowAsync(workflow); + workflow.Deleted = DateTime.UtcNow; - return Ok(workflow); - } - catch (Exception e) - { - return Problem( - $"Unexpected error occured: {e.Message}", - $"/workflows/{nameof(id)}", - InternalServerError); + var workflowId = await _workflowService.DeleteWorkflowAsync(workflow); + + return Ok(workflow); + } + catch (Exception e) + { + return Problem( + $"Unexpected error occured: {e.Message}", + $"/workflows/{nameof(id)}", + InternalServerError); + } } } } diff --git a/src/WorkflowManager/Extentions/TaskManagerExtensions.cs b/src/WorkflowManager/Extentions/TaskManagerExtensions.cs index 5508be939..5d48dfeb2 100644 --- a/src/WorkflowManager/Extentions/TaskManagerExtensions.cs +++ b/src/WorkflowManager/Extentions/TaskManagerExtensions.cs @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - using System.Net.Http; using Ardalis.GuardClauses; using Microsoft.Extensions.DependencyInjection; diff --git a/src/WorkflowManager/Extentions/WorkflowExecutorExtensions.cs b/src/WorkflowManager/Extentions/WorkflowExecutorExtensions.cs index b9de26514..2c8f7de89 100644 --- a/src/WorkflowManager/Extentions/WorkflowExecutorExtensions.cs +++ b/src/WorkflowManager/Extentions/WorkflowExecutorExtensions.cs @@ -54,7 +54,9 @@ public static IServiceCollection AddWorkflowExecutor(this IServiceCollection ser var dicomStore = s.GetService(); var workflowInstanceService = s.GetService(); +#pragma warning disable CS8604 // Possible null reference argument. return new ConditionalParameterParser(logger, dicomStore, workflowInstanceService, payloadService, workflowService); +#pragma warning restore CS8604 // Possible null reference argument. }); services.AddSingleton(); diff --git a/src/WorkflowManager/Monai.Deploy.WorkflowManager.csproj b/src/WorkflowManager/Monai.Deploy.WorkflowManager.csproj index 78af26477..a0ef3ef0b 100644 --- a/src/WorkflowManager/Monai.Deploy.WorkflowManager.csproj +++ b/src/WorkflowManager/Monai.Deploy.WorkflowManager.csproj @@ -28,11 +28,6 @@ - - - - - diff --git a/src/WorkflowManager/Program.cs b/src/WorkflowManager/Program.cs index a2d8cbd77..e0af30296 100644 --- a/src/WorkflowManager/Program.cs +++ b/src/WorkflowManager/Program.cs @@ -107,7 +107,9 @@ private static void ConfigureServices(HostBuilderContext hostContext, IServiceCo services.AddSingleton(); - services.AddHostedService(p => p.GetService()); +#pragma warning disable CS8603 // Possible null reference return. + services.AddHostedService(p => p.GetService()); +#pragma warning restore CS8603 // Possible null reference return. // Services services.AddTransient(); @@ -139,8 +141,8 @@ private static void ConfigureServices(HostBuilderContext hostContext, IServiceCo services.AddSingleton(p => { var accessor = p.GetRequiredService(); - var request = accessor.HttpContext.Request; - var uri = string.Concat(request.Scheme, "://", request.Host.ToUriComponent()); + var request = accessor?.HttpContext?.Request; + var uri = string.Concat(request?.Scheme, "://", request?.Host.ToUriComponent()); var newUri = new Uri(uri); return new UriService(newUri); }); diff --git a/src/WorkflowManager/Services/UriService.cs b/src/WorkflowManager/Services/UriService.cs index 7365f24a8..be29c6b7b 100644 --- a/src/WorkflowManager/Services/UriService.cs +++ b/src/WorkflowManager/Services/UriService.cs @@ -46,7 +46,7 @@ public string GetPageUriString(PaginationFilter filter, string route) { var endpointUri = new Uri(string.Concat(_baseUri, route)); var modifiedUri = QueryHelpers.AddQueryString(endpointUri.ToString(), "pageNumber", filter.PageNumber.ToString()); - modifiedUri = QueryHelpers.AddQueryString(modifiedUri, "pageSize", filter.PageSize.ToString()); + modifiedUri = QueryHelpers.AddQueryString(modifiedUri, "pageSize", filter?.PageSize?.ToString() ?? string.Empty); var uri = new Uri(modifiedUri); return uri.IsAbsoluteUri ? uri.PathAndQuery : uri.OriginalString; } diff --git a/src/WorkflowManager/stylecop.json b/src/WorkflowManager/stylecop.json new file mode 100644 index 000000000..42fb1f8ea --- /dev/null +++ b/src/WorkflowManager/stylecop.json @@ -0,0 +1,14 @@ +{ + // ACTION REQUIRED: This file was automatically added to your project, but it + // will not take effect until additional steps are taken to enable it. See the + // following page for additional information: + // + // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md + + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "PlaceholderCompany" + } + } +} diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Models/InformaticsGateway/WorkflowRequestMessage.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Models/InformaticsGateway/WorkflowRequestMessage.cs index 978505ac8..75b7b3108 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Models/InformaticsGateway/WorkflowRequestMessage.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Models/InformaticsGateway/WorkflowRequestMessage.cs @@ -24,7 +24,7 @@ public class WorkflowRequestMessage public Guid PayloadId { get; set; } [JsonProperty(PropertyName = "workflows")] - public IEnumerable Workflows { get; set; } + public IEnumerable Workflows { get; set; } = new List(); [JsonProperty(PropertyName = "file_count")] public int FileCount { get; set; } diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/POCO/TestExecutionConfig.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/POCO/TestExecutionConfig.cs index 8294c7aa3..cdbe02c17 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/POCO/TestExecutionConfig.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/POCO/TestExecutionConfig.cs @@ -20,64 +20,64 @@ static class TestExecutionConfig { public static class RabbitConfig { - public static string Host { get; set; } + public static string Host { get; set; } = string.Empty; public static int Port { get; set; } - public static string User { get; set; } + public static string User { get; set; } = string.Empty; - public static string Password { get; set; } + public static string Password { get; set; } = string.Empty; - public static string Exchange { get; set; } + public static string Exchange { get; set; } = string.Empty; - public static string VirtualHost { get; set; } + public static string VirtualHost { get; set; } = string.Empty; - public static string WorkflowRequestQueue { get; set; } + public static string WorkflowRequestQueue { get; set; } = string.Empty; - public static string TaskDispatchQueue { get; set; } + public static string TaskDispatchQueue { get; set; } = string.Empty; - public static string TaskCallbackQueue { get; set; } + public static string TaskCallbackQueue { get; set; } = string.Empty; - public static string WorkflowCompleteQueue { get; set; } + public static string WorkflowCompleteQueue { get; set; } = string.Empty; - public static string TaskUpdateQueue { get; set; } + public static string TaskUpdateQueue { get; set; } = string.Empty; } public static class MongoConfig { - public static string ConnectionString { get; set; } + public static string ConnectionString { get; set; } = string.Empty; public static int Port { get; set; } - public static string User { get; set; } + public static string User { get; set; } = string.Empty; - public static string Password { get; set; } + public static string Password { get; set; } = string.Empty; - public static string Database { get; set; } + public static string Database { get; set; } = string.Empty; - public static string WorkflowCollection { get; set; } + public static string WorkflowCollection { get; set; } = string.Empty; - public static string WorkflowInstanceCollection { get; set; } + public static string WorkflowInstanceCollection { get; set; } = string.Empty; - public static string PayloadCollection { get; set; } + public static string PayloadCollection { get; set; } = string.Empty; } public static class MinioConfig { - public static string Endpoint { get; set; } + public static string Endpoint { get; set; } = string.Empty; - public static string AccessKey { get; set; } + public static string AccessKey { get; set; } = string.Empty; - public static string AccessToken { get; set; } + public static string AccessToken { get; set; } = string.Empty; - public static string Bucket { get; set; } + public static string Bucket { get; set; } = string.Empty; - public static string Region { get; set; } + public static string Region { get; set; } = string.Empty; } public static class ApiConfig { - public static string BaseUrl { get; set; } + public static string BaseUrl { get; set; } = string.Empty; } } } diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/PayloadApiStepDefinitions.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/PayloadApiStepDefinitions.cs index 7d49cfacd..66c37c5c4 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/PayloadApiStepDefinitions.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/PayloadApiStepDefinitions.cs @@ -71,17 +71,22 @@ public void ThenICanSeeExpectedPayloadsAreReturned() var result = ApiHelper.Response.Content.ReadAsStringAsync().Result; var actualPayloads = JsonConvert.DeserializeObject>>(result); - Assertions.AssertPayloadList(DataHelper.Payload, actualPayloads.Data); + actualPayloads.Should().NotBeNull(); + Assertions.AssertPayloadList(DataHelper.Payload, actualPayloads?.Data); } [Then(@"Pagination is working correctly for the (.*) payload")] [Then(@"Pagination is working correctly for the (.*) payloads")] public void ThenPaginationIsWorkingCorrectlyForTheWorkflow(int count) { +#pragma warning disable CS8602 // Dereference of a possibly null reference. var request = ApiHelper.Request.RequestUri.Query; +#pragma warning restore CS8602 // Dereference of a possibly null reference. var result = ApiHelper.Response.Content.ReadAsStringAsync().Result; var deserializedResult = JsonConvert.DeserializeObject>>(result); + deserializedResult.Should().NotBeNull(); Assertions.AssertPagination>>(count, request, deserializedResult); + } [Then(@"I can see expected Payload is returned")] @@ -98,7 +103,8 @@ public void ThenICanSeeNoPayloadsAreReturned() var result = ApiHelper.Response.Content.ReadAsStringAsync().Result; var payloads = JsonConvert.DeserializeObject>>(result); - payloads.Data.Should().BeNullOrEmpty(); + payloads.Should().NotBeNull(); + payloads?.Data.Should().BeNullOrEmpty(); } } diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/PayloadCollectionStepDefinitions.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/PayloadCollectionStepDefinitions.cs index 69fe69ee2..b6dc79914 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/PayloadCollectionStepDefinitions.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/PayloadCollectionStepDefinitions.cs @@ -30,7 +30,9 @@ public class PayloadCollectionStepDefinitions private DataHelper DataHelper { get; set; } private readonly ISpecFlowOutputHelper _outputHelper; +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. public PayloadCollectionStepDefinitions(ObjectContainer objectContainer, ISpecFlowOutputHelper outputHelper) +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { _outputHelper = outputHelper; Assertions = new Assertions(objectContainer); diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/TaskStatusUpdateStepDefinitions.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/TaskStatusUpdateStepDefinitions.cs index 1ca800b0a..d7c371d01 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/TaskStatusUpdateStepDefinitions.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/StepDefinitions/TaskStatusUpdateStepDefinitions.cs @@ -94,6 +94,7 @@ public void ThenICanSeeTheStatusOfTheTaskIsUpdated() var taskUpdated = workflowInstance.Tasks.FirstOrDefault(x => x.TaskId.Equals(DataHelper.TaskUpdateEvent.TaskId)); + taskUpdated.Should().NotBeNull(); taskUpdated?.Status.Should().Be(DataHelper.TaskUpdateEvent.Status); if (DataHelper.TaskDispatchEvents.Count > 0) diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/Assertions.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/Assertions.cs index 111c02016..f729af4cd 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/Assertions.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/Assertions.cs @@ -37,11 +37,11 @@ public void AssertWorkflowInstanceMatchesExpectedWorkflow(WorkflowInstance workf { workflowInstance.PayloadId.Should().Match(workflowRequestMessage.PayloadId.ToString()); workflowInstance.WorkflowId.Should().Match(workflowRevision.WorkflowId); - workflowInstance.AeTitle.Should().Match(workflowRevision.Workflow.InformaticsGateway.AeTitle); + workflowInstance.AeTitle.Should().Match(workflowRevision?.Workflow?.InformaticsGateway?.AeTitle); foreach (var task in workflowInstance.Tasks) { - var workflowTask = workflowRevision.Workflow.Tasks.FirstOrDefault(x => x.Id.Equals(task.TaskId)); + var workflowTask = workflowRevision?.Workflow?.Tasks.FirstOrDefault(x => x.Id.Equals(task.TaskId)); if (workflowTask != null) { task.TaskId.Should().Match(workflowTask.Id); @@ -110,7 +110,7 @@ public void AssertOutputArtifactsForTaskDispatch(List } } - public void AssertTaskDispatchEvent(TaskDispatchEvent taskDispatchEvent, WorkflowInstance workflowInstance, WorkflowRevision workflowRevision, WorkflowRequestMessage workflowRequestMessage = null, TaskUpdateEvent taskUpdateEvent = null) + public void AssertTaskDispatchEvent(TaskDispatchEvent taskDispatchEvent, WorkflowInstance workflowInstance, WorkflowRevision workflowRevision, WorkflowRequestMessage? workflowRequestMessage = null, TaskUpdateEvent? taskUpdateEvent = null) { var workflowInstanceTask = workflowInstance.Tasks.FirstOrDefault(x => x.TaskId.Equals(taskDispatchEvent.TaskId, StringComparison.OrdinalIgnoreCase)); @@ -122,7 +122,7 @@ public void AssertTaskDispatchEvent(TaskDispatchEvent taskDispatchEvent, Workflo } else { - taskDispatchEvent.CorrelationId.Should().Match(taskUpdateEvent.CorrelationId); + taskDispatchEvent.CorrelationId.Should().Match(taskUpdateEvent?.CorrelationId); } taskDispatchEvent.WorkflowInstanceId.Should().Match(workflowInstance.Id); @@ -145,17 +145,19 @@ public void AssertTaskDispatchEvent(TaskDispatchEvent taskDispatchEvent, Workflo public void AssertPayload(Payload payload, Payload? actualPayload) { - actualPayload.Should().BeEquivalentTo(payload, options => options.Excluding(x => x.Timestamp)); - actualPayload.Timestamp.ToString(format: "yyyy-MM-dd hh:mm:ss").Should().Be(payload.Timestamp.ToString(format: "yyyy-MM-dd hh:mm:ss")); + actualPayload.Should().NotBeNull(); + actualPayload?.Should().BeEquivalentTo(payload, options => options.Excluding(x => x.Timestamp)); + actualPayload?.Timestamp.ToString(format: "yyyy-MM-dd hh:mm:ss").Should().Be(payload.Timestamp.ToString(format: "yyyy-MM-dd hh:mm:ss")); } public void AssertPayloadList(List payload, List? actualPayloads) { - actualPayloads.Count.Should().Be(payload.Count); + actualPayloads.Should().NotBeNull(); + actualPayloads?.Count.Should().Be(payload.Count); foreach (var p in payload) { - var actualPayload = actualPayloads.FirstOrDefault(x => x.PayloadId.Equals(p.PayloadId)); + var actualPayload = actualPayloads?.FirstOrDefault(x => x.PayloadId.Equals(p.PayloadId)); AssertPayload(p, actualPayload); } @@ -177,13 +179,13 @@ public void AssertWorkflowIstanceMatchesExpectedTaskStatusUpdate(WorkflowInstanc updatedWorkflowInstance.Tasks[0].Status.Should().Be(taskExecutionStatus); } - public void AssertPagination(int count, string queries, T Response) + public void AssertPagination(int count, string queries, T? Response) { - var data = Response.GetType().GetProperty("Data").GetValue(Response, null) as ICollection; - var totalPages = Response.GetType().GetProperty("TotalPages").GetValue(Response, null); - var pageSize = Response.GetType().GetProperty("PageSize").GetValue(Response, null); - var totalRecords = Response.GetType().GetProperty("TotalRecords").GetValue(Response, null); - var pageNumber = Response.GetType().GetProperty("PageNumber").GetValue(Response, null); + var data = Response?.GetType()?.GetProperty("Data")?.GetValue(Response, null) as ICollection; + var totalPages = Response?.GetType()?.GetProperty("TotalPages")?.GetValue(Response, null); + var pageSize = Response?.GetType()?.GetProperty("PageSize")?.GetValue(Response, null); + var totalRecords = Response?.GetType()?.GetProperty("TotalRecords")?.GetValue(Response, null); + var pageNumber = Response?.GetType()?.GetProperty("PageNumber")?.GetValue(Response, null); int pageNumberQuery = 1; int pageSizeQuery = 10; List splitQuery = queries.Split("&").ToList(); @@ -217,10 +219,12 @@ public void WorkflowInstanceIncludesTaskDetails(List taskDisp foreach (var taskDispatchEvent in taskDispatchEvents) { var workflowInstanceTaskDetails = workflowInstance.Tasks.FirstOrDefault(c => c.TaskId.Equals(taskDispatchEvent.TaskId)); - var workflowTaskDetails = workflowRevision.Workflow.Tasks.FirstOrDefault(c => c.Id.Equals(taskDispatchEvent.TaskId)); - workflowInstanceTaskDetails.ExecutionId.Should().Be(taskDispatchEvent.ExecutionId); - workflowInstanceTaskDetails.Status.Should().Be(TaskExecutionStatus.Dispatched); - workflowInstanceTaskDetails.TaskType.Should().Be(workflowTaskDetails.Type); + var workflowTaskDetails = workflowRevision?.Workflow?.Tasks.FirstOrDefault(c => c.Id.Equals(taskDispatchEvent.TaskId)); + workflowInstanceTaskDetails.Should().NotBeNull(); + workflowTaskDetails.Should().NotBeNull(); + workflowInstanceTaskDetails?.ExecutionId.Should().Be(taskDispatchEvent.ExecutionId); + workflowInstanceTaskDetails?.Status.Should().Be(TaskExecutionStatus.Dispatched); + workflowInstanceTaskDetails?.TaskType.Should().Be(workflowTaskDetails?.Type); } } @@ -266,7 +270,7 @@ public void AssertWorkflowInstanceList(List expectedWorkflowIn foreach (var actualWorkflowInstance in actualWorkflowInstances) { var expectedWorkflowInstance = expectedWorkflowInstances.FirstOrDefault(x => x.Id.Equals(actualWorkflowInstance.Id)); - actualWorkflowInstance.StartTime.ToString(format: "yyyy-MM-dd hh:mm:ss").Should().Be(expectedWorkflowInstance.StartTime.ToString(format: "yyyy-MM-dd hh:mm:ss")); + actualWorkflowInstance.StartTime.ToString(format: "yyyy-MM-dd hh:mm:ss").Should().Be(expectedWorkflowInstance?.StartTime.ToString(format: "yyyy-MM-dd hh:mm:ss")); } actualWorkflowInstances.OrderBy(x => x.Id).Should().BeEquivalentTo(expectedWorkflowInstances.OrderBy(x => x.Id), options => options.Excluding(x => x.StartTime)); @@ -274,32 +278,34 @@ public void AssertWorkflowInstanceList(List expectedWorkflowIn public void AssertWorkflowInstance(List expectedWorkflowInstances, WorkflowInstance? actualWorkflowInstance) { - var expectedWorkflowInstance = expectedWorkflowInstances.FirstOrDefault(x => x.Id.Equals(actualWorkflowInstance.Id)); - actualWorkflowInstance.StartTime.ToString(format: "yyyy-MM-dd hh:mm:ss").Should().Be(expectedWorkflowInstance.StartTime.ToString(format: "yyyy-MM-dd hh:mm:ss")); + var expectedWorkflowInstance = expectedWorkflowInstances.FirstOrDefault(x => x.Id.Equals(actualWorkflowInstance?.Id)); + actualWorkflowInstance?.StartTime.ToString(format: "yyyy-MM-dd hh:mm:ss").Should().Be(expectedWorkflowInstance?.StartTime.ToString(format: "yyyy-MM-dd hh:mm:ss")); +#pragma warning disable CS8602 // Dereference of a possibly null reference. actualWorkflowInstance.Should().BeEquivalentTo(expectedWorkflowInstance, options => options.Excluding(x => x.StartTime)); +#pragma warning restore CS8602 // Dereference of a possibly null reference. } - private static void AssertDataCount(ICollection Data, int pageNumberQuery, int pageSizeQuery, int count) + private static void AssertDataCount(ICollection? Data, int pageNumberQuery, int pageSizeQuery, int count) { if ((pageNumberQuery * pageSizeQuery) > count) { - Data.Count.Should().Be(Math.Max(count - ((pageNumberQuery - 1) * pageSizeQuery), 0)); + Data?.Count.Should().Be(Math.Max(count - ((pageNumberQuery - 1) * pageSizeQuery), 0)); } else if ((pageNumberQuery * pageSizeQuery) < count) { - Data.Count.Should().Be(pageSizeQuery); + Data?.Count.Should().Be(pageSizeQuery); } else if (pageNumberQuery > 1) { - Data.Count.Should().Be(Math.Max(count - (pageSizeQuery * (pageNumberQuery - 1)), 0)); + Data?.Count.Should().Be(Math.Max(count - (pageSizeQuery * (pageNumberQuery - 1)), 0)); } else { - Data.Count.Should().Be(count); + Data?.Count.Should().Be(count); } } - private static void AssertTotalPages(object TotalPages, int count, int pageSizeQuery) + private static void AssertTotalPages(object? TotalPages, int count, int pageSizeQuery) { int remainder; int quotient = Math.DivRem(count, pageSizeQuery, out remainder); diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/DataHelper.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/DataHelper.cs index db59c1730..135555168 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/DataHelper.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/DataHelper.cs @@ -1,383 +1,384 @@ -/* - * Copyright 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. - */ - -using Monai.Deploy.Messaging.Events; -using Monai.Deploy.WorkflowManager.Contracts.Models; -using Monai.Deploy.WorkflowManager.IntegrationTests.Models; -using Monai.Deploy.WorkflowManager.WorkflowExecutor.IntegrationTests.TestData; -using Polly; -using Polly.Retry; - -namespace Monai.Deploy.WorkflowManager.IntegrationTests.Support -{ - public class DataHelper - { - public WorkflowRequestMessage WorkflowRequestMessage = new WorkflowRequestMessage(); - public List WorkflowInstances = new List(); - public PatientDetails PatientDetails { get; set; } - public TaskUpdateEvent TaskUpdateEvent = new TaskUpdateEvent(); - public List TaskDispatchEvents = new List(); - public List WorkflowRevisions = new List(); - public List Workflows = new List(); - public List Payload = new List(); - private RetryPolicy> RetryWorkflowInstances { get; set; } - private RetryPolicy> RetryTaskDispatches { get; set; } - private RetryPolicy> RetryPayloadCollections { get; set; } - private RabbitConsumer TaskDispatchConsumer { get; set; } - private MongoClientUtil MongoClient { get; set; } +/* + * Copyright 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. + */ + +using Monai.Deploy.Messaging.Events; +using Monai.Deploy.WorkflowManager.Contracts.Models; +using Monai.Deploy.WorkflowManager.IntegrationTests.Models; +using Monai.Deploy.WorkflowManager.WorkflowExecutor.IntegrationTests.TestData; +using Polly; +using Polly.Retry; +#pragma warning disable CS8602 // Dereference of a possibly null reference. +namespace Monai.Deploy.WorkflowManager.IntegrationTests.Support +{ + public class DataHelper + { + public WorkflowRequestMessage WorkflowRequestMessage = new WorkflowRequestMessage(); + public List WorkflowInstances = new List(); + public PatientDetails PatientDetails { get; set; } = new PatientDetails(); + public TaskUpdateEvent TaskUpdateEvent = new TaskUpdateEvent(); + public List TaskDispatchEvents = new List(); + public List WorkflowRevisions = new List(); + public List Workflows = new List(); + public List Payload = new List(); + private RetryPolicy> RetryWorkflowInstances { get; set; } + private RetryPolicy> RetryTaskDispatches { get; set; } + private RetryPolicy> RetryPayloadCollections { get; set; } + private RabbitConsumer TaskDispatchConsumer { get; set; } + private MongoClientUtil MongoClient { get; set; } public string PayloadId { get; private set; } public string BucketId { get; internal set; } public List SeededWorkflowInstances { get; internal set; } - public DataHelper(RabbitConsumer taskDispatchConsumer, MongoClientUtil mongoClient) - { - TaskDispatchConsumer = taskDispatchConsumer; - MongoClient = mongoClient; + public DataHelper(RabbitConsumer taskDispatchConsumer, MongoClientUtil mongoClient) + { + TaskDispatchConsumer = taskDispatchConsumer; + MongoClient = mongoClient; RetryWorkflowInstances = Policy>.Handle().WaitAndRetry(retryCount: 20, sleepDurationProvider: _ => TimeSpan.FromMilliseconds(500)); RetryTaskDispatches = Policy>.Handle().WaitAndRetry(retryCount: 20, sleepDurationProvider: _ => TimeSpan.FromMilliseconds(500)); RetryPayloadCollections = Policy>.Handle().WaitAndRetry(retryCount: 20, sleepDurationProvider: _ => TimeSpan.FromMilliseconds(500)); - } - - public WorkflowRevision GetWorkflowRevisionTestData(string name) - { - var workflowRevision = WorkflowRevisionsTestData.TestData.FirstOrDefault(c => c.Name.Equals(name)); - - if (workflowRevision != null) - { - if (workflowRevision.WorkflowRevision != null) - { - WorkflowRevisions.Add(workflowRevision.WorkflowRevision); - return workflowRevision.WorkflowRevision; - } - else - { - throw new Exception($"Workflow {name} does not have any applicable test data, please check and try again!"); - } - } - else - { - throw new Exception($"Workflow {name} does not have any applicable test data, please check and try again!"); - } - } - - public WorkflowRevision GetWorkflowRevisionTestDataByIndex(int index) - { - var workflowRevision = WorkflowRevisionsTestData.TestData[index]; - - if (workflowRevision != null) - { - if (workflowRevision.WorkflowRevision != null) - { - WorkflowRevisions.Add(workflowRevision.WorkflowRevision); - return workflowRevision.WorkflowRevision; - } - else - { - throw new Exception($"Workflow at index {index} does not have any applicable test data, please check and try again!"); - } - } - else - { - throw new Exception($"Workflow at index {index} does not have any applicable test data, please check and try again!"); - } - } - - public Workflow GetWorkflowObjectTestData(string name) - { - var workflow = WorkflowObjectsTestData.TestData.FirstOrDefault(c => c.Name.Equals(name)); - - if (workflow != null) - { - if (workflow.Workflow != null) - { - Workflows.Add(workflow.Workflow); - return workflow.Workflow; - } - else - { - throw new Exception($"Workflow object {name} does not have any applicable test data, please check and try again!"); - } - } - else - { - throw new Exception($"Workflow object {name} does not have any applicable test data, please check and try again!"); - } - } - - public WorkflowInstance GetWorkflowInstanceTestData(string name) - { - var workflowInstance = WorkflowInstancesTestData.TestData.FirstOrDefault(c => c.Name.Contains(name)); - - if (workflowInstance != null) - { - if (workflowInstance.WorkflowInstance != null) - { - WorkflowInstances.Add(workflowInstance.WorkflowInstance); - - return workflowInstance.WorkflowInstance; - } - else - { - throw new Exception($"Workflow Intance {name} does not have any applicable test data, please check and try again!"); - } - } - else - { - throw new Exception($"Workflow Intance {name} does not have any applicable test data, please check and try again!"); - } - } - - public WorkflowInstance GetWorkflowInstanceTestDataByIndex(int index) - { - var workflowInstance = WorkflowInstancesTestData.TestData[index]; - - if (workflowInstance != null) - { - if (workflowInstance.WorkflowInstance != null) - { - WorkflowInstances.Add(workflowInstance.WorkflowInstance); - return workflowInstance.WorkflowInstance; - } - else - { - throw new Exception($"Workflow at index {index} does not have any applicable test data, please check and try again!"); - } - } - else - { - throw new Exception($"Workflow at index {index} does not have any applicable test data, please check and try again!"); - } - } - - public PatientDetails GetPatientDetailsTestData(string name) - { - var patientTestData = PatientsTestData.TestData.FirstOrDefault(c => c.Name.Contains(name)); - - if (patientTestData != null) - { - if (patientTestData.Patient != null) - { - PatientDetails = patientTestData.Patient; - return patientTestData.Patient; - } - else - { - throw new Exception($"Patient Details {name} does not have any applicable test data, please check and try again!"); - } - } - else - { - throw new Exception($"Patient Details {name} does not have any applicable test data, please check and try again!"); - } - } - - public WorkflowRequestMessage GetWorkflowRequestTestData(string name) - { - var workflowRequest = WorkflowRequestsTestData.TestData.FirstOrDefault(c => c.Name.Contains(name)); - - if (workflowRequest != null) - { - if (workflowRequest.WorkflowRequestMessage != null) - { - WorkflowRequestMessage = workflowRequest.WorkflowRequestMessage; - - return workflowRequest.WorkflowRequestMessage; - } - else - { - throw new Exception($"Workflow request {name} does not have any applicable test data, please check and try again!"); - } - } - else - { - throw new Exception($"Workflow request {name} does not have any applicable test data, please check and try again!"); - } - } - - public TaskUpdateEvent GetTaskUpdateTestData(string name, string updateStatus) - { - var taskUpdateTestData = TaskUpdatesTestData.TestData.FirstOrDefault(c => c.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); - - if (taskUpdateTestData != null && taskUpdateTestData.TaskUpdateEvent != null) - { - if (!taskUpdateTestData.Name.Contains("Missing_Status")) - { - taskUpdateTestData.TaskUpdateEvent.Status = updateStatus.ToLower() switch - { - "accepted" => TaskExecutionStatus.Accepted, - "succeeded" => TaskExecutionStatus.Succeeded, - "failed" => TaskExecutionStatus.Failed, - "canceled" => TaskExecutionStatus.Canceled, - _ => throw new Exception($"updateStatus {updateStatus} is not recognised. Please check and try again."), - }; - } - - TaskUpdateEvent = taskUpdateTestData.TaskUpdateEvent; - - return taskUpdateTestData.TaskUpdateEvent; - } - - throw new Exception($"Task update message not found for {name}"); - } - - public List GetWorkflowInstances(int count, string payloadId) - { - var res = RetryWorkflowInstances.Execute(() => - { - WorkflowInstances = MongoClient.GetWorkflowInstancesByPayloadId(payloadId); - - if (WorkflowInstances.Count == count) - { - return WorkflowInstances; - } - else - { - throw new Exception($"{count} workflow instances could not be found for payloadId {payloadId}. Actual count is {WorkflowInstances.Count}"); - } - }); - - return res; - } - - public List GetPayloadCollections(string payloadId) - { - var res = RetryPayloadCollections.Execute(() => - { - Payload = MongoClient.GetPayloadCollectionByPayloadId(payloadId); - - if (Payload != null) - { - return Payload; - } - else - { - throw new Exception($"Payload collection could not be found for payloadId {payloadId}"); - } - }); - - return res; - } - - public List GetTaskDispatchEvents(int count, List workflowInstances) - { - var res = RetryTaskDispatches.Execute(() => - { - var message = TaskDispatchConsumer.GetMessage(); - - if (message != null) - { - foreach (var workflowInstance in workflowInstances) - { - if (message.WorkflowInstanceId == workflowInstance.Id) - { - TaskDispatchEvents.Add(message); - } - } - } - - if (TaskDispatchEvents.Count == count) - { - return TaskDispatchEvents; - } - else - { - throw new Exception($"{count} task dispatch events could not be found"); - } - }); - - return res; - } - - public List GetTaskDispatchEventByTaskId(List taskIds) - { - var res = RetryTaskDispatches.Execute(() => - { - var message = TaskDispatchConsumer.GetMessage(); - - if (message != null) - { - foreach (var taskId in taskIds) - { - if (message.TaskId == taskId) - { - TaskDispatchEvents.Add(message); - } - } - } - - if (TaskDispatchEvents.Count == taskIds.Count) - { - return TaskDispatchEvents; - } - else - { - throw new Exception($"{taskIds.Count} task dispatch events could not be found"); - } - }); - - return res; - } - - public Payload GetPayloadTestData(string name) - { - var payload = PayloadsTestData.TestData.FirstOrDefault(c => c.Name.Contains(name)); - - if (payload != null) - { - if (payload.Payload != null) - { - Payload.Add(payload.Payload); - return payload.Payload; - } - else - { - throw new Exception($"Payload {name} does not have any applicable test data, please check and try again!"); - } - } - else - { - throw new Exception($"Payload {name} does not have any applicable test data, please check and try again!"); - } - } - - public Payload GetPayloadsTestDataByIndex(int index) - { - var payload = PayloadsTestData.TestData[index]; - - if (payload != null) - { - if (payload.Payload != null) - { - Payload.Add(payload.Payload); - return payload.Payload; - } - else - { - throw new Exception($"Payload at index {index} does not have any applicable test data, please check and try again!"); - } - } - else - { - throw new Exception($"Payload at index {index} does not have any applicable test data, please check and try again!"); - } - } - - public string GetPayloadId(string? payloadId = null) - { - return PayloadId = payloadId ?? Guid.NewGuid().ToString(); - } - } -} + } + + public WorkflowRevision GetWorkflowRevisionTestData(string name) + { + var workflowRevision = WorkflowRevisionsTestData.TestData.FirstOrDefault(c => c.Name.Equals(name)); + + if (workflowRevision != null) + { + if (workflowRevision.WorkflowRevision != null) + { + WorkflowRevisions.Add(workflowRevision.WorkflowRevision); + return workflowRevision.WorkflowRevision; + } + else + { + throw new Exception($"Workflow {name} does not have any applicable test data, please check and try again!"); + } + } + else + { + throw new Exception($"Workflow {name} does not have any applicable test data, please check and try again!"); + } + } + + public WorkflowRevision GetWorkflowRevisionTestDataByIndex(int index) + { + var workflowRevision = WorkflowRevisionsTestData.TestData[index]; + + if (workflowRevision != null) + { + if (workflowRevision.WorkflowRevision != null) + { + WorkflowRevisions.Add(workflowRevision.WorkflowRevision); + return workflowRevision.WorkflowRevision; + } + else + { + throw new Exception($"Workflow at index {index} does not have any applicable test data, please check and try again!"); + } + } + else + { + throw new Exception($"Workflow at index {index} does not have any applicable test data, please check and try again!"); + } + } + + public Workflow GetWorkflowObjectTestData(string name) + { + var workflow = WorkflowObjectsTestData.TestData.FirstOrDefault(c => c.Name.Equals(name)); + + if (workflow != null) + { + if (workflow.Workflow != null) + { + Workflows.Add(workflow.Workflow); + return workflow.Workflow; + } + else + { + throw new Exception($"Workflow object {name} does not have any applicable test data, please check and try again!"); + } + } + else + { + throw new Exception($"Workflow object {name} does not have any applicable test data, please check and try again!"); + } + } + + public WorkflowInstance GetWorkflowInstanceTestData(string name) + { + var workflowInstance = WorkflowInstancesTestData.TestData.FirstOrDefault(c => c.Name.Contains(name)); + + if (workflowInstance != null) + { + if (workflowInstance.WorkflowInstance != null) + { + WorkflowInstances.Add(workflowInstance.WorkflowInstance); + + return workflowInstance.WorkflowInstance; + } + else + { + throw new Exception($"Workflow Intance {name} does not have any applicable test data, please check and try again!"); + } + } + else + { + throw new Exception($"Workflow Intance {name} does not have any applicable test data, please check and try again!"); + } + } + + public WorkflowInstance GetWorkflowInstanceTestDataByIndex(int index) + { + var workflowInstance = WorkflowInstancesTestData.TestData[index]; + + if (workflowInstance != null) + { + if (workflowInstance.WorkflowInstance != null) + { + WorkflowInstances.Add(workflowInstance.WorkflowInstance); + return workflowInstance.WorkflowInstance; + } + else + { + throw new Exception($"Workflow at index {index} does not have any applicable test data, please check and try again!"); + } + } + else + { + throw new Exception($"Workflow at index {index} does not have any applicable test data, please check and try again!"); + } + } + + public PatientDetails GetPatientDetailsTestData(string name) + { + var patientTestData = PatientsTestData.TestData.FirstOrDefault(c => c.Name.Contains(name)); + + if (patientTestData != null) + { + if (patientTestData.Patient != null) + { + PatientDetails = patientTestData.Patient; + return patientTestData.Patient; + } + else + { + throw new Exception($"Patient Details {name} does not have any applicable test data, please check and try again!"); + } + } + else + { + throw new Exception($"Patient Details {name} does not have any applicable test data, please check and try again!"); + } + } + + public WorkflowRequestMessage GetWorkflowRequestTestData(string name) + { + var workflowRequest = WorkflowRequestsTestData.TestData.FirstOrDefault(c => c.Name.Contains(name)); + + if (workflowRequest != null) + { + if (workflowRequest.WorkflowRequestMessage != null) + { + WorkflowRequestMessage = workflowRequest.WorkflowRequestMessage; + + return workflowRequest.WorkflowRequestMessage; + } + else + { + throw new Exception($"Workflow request {name} does not have any applicable test data, please check and try again!"); + } + } + else + { + throw new Exception($"Workflow request {name} does not have any applicable test data, please check and try again!"); + } + } + + public TaskUpdateEvent GetTaskUpdateTestData(string name, string updateStatus) + { + var taskUpdateTestData = TaskUpdatesTestData.TestData.FirstOrDefault(c => c.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + + if (taskUpdateTestData != null && taskUpdateTestData.TaskUpdateEvent != null) + { + if (!taskUpdateTestData.Name.Contains("Missing_Status")) + { + taskUpdateTestData.TaskUpdateEvent.Status = updateStatus.ToLower() switch + { + "accepted" => TaskExecutionStatus.Accepted, + "succeeded" => TaskExecutionStatus.Succeeded, + "failed" => TaskExecutionStatus.Failed, + "canceled" => TaskExecutionStatus.Canceled, + _ => throw new Exception($"updateStatus {updateStatus} is not recognised. Please check and try again."), + }; + } + + TaskUpdateEvent = taskUpdateTestData.TaskUpdateEvent; + + return taskUpdateTestData.TaskUpdateEvent; + } + + throw new Exception($"Task update message not found for {name}"); + } + + public List GetWorkflowInstances(int count, string payloadId) + { + var res = RetryWorkflowInstances.Execute(() => + { + WorkflowInstances = MongoClient.GetWorkflowInstancesByPayloadId(payloadId); + + if (WorkflowInstances.Count == count) + { + return WorkflowInstances; + } + else + { + throw new Exception($"{count} workflow instances could not be found for payloadId {payloadId}. Actual count is {WorkflowInstances.Count}"); + } + }); + + return res; + } + + public List GetPayloadCollections(string payloadId) + { + var res = RetryPayloadCollections.Execute(() => + { + Payload = MongoClient.GetPayloadCollectionByPayloadId(payloadId); + + if (Payload != null) + { + return Payload; + } + else + { + throw new Exception($"Payload collection could not be found for payloadId {payloadId}"); + } + }); + + return res; + } + + public List GetTaskDispatchEvents(int count, List workflowInstances) + { + var res = RetryTaskDispatches.Execute(() => + { + var message = TaskDispatchConsumer.GetMessage(); + + if (message != null) + { + foreach (var workflowInstance in workflowInstances) + { + if (message.WorkflowInstanceId == workflowInstance.Id) + { + TaskDispatchEvents.Add(message); + } + } + } + + if (TaskDispatchEvents.Count == count) + { + return TaskDispatchEvents; + } + else + { + throw new Exception($"{count} task dispatch events could not be found"); + } + }); + + return res; + } + + public List GetTaskDispatchEventByTaskId(List taskIds) + { + var res = RetryTaskDispatches.Execute(() => + { + var message = TaskDispatchConsumer.GetMessage(); + + if (message != null) + { + foreach (var taskId in taskIds) + { + if (message.TaskId == taskId) + { + TaskDispatchEvents.Add(message); + } + } + } + + if (TaskDispatchEvents.Count == taskIds.Count) + { + return TaskDispatchEvents; + } + else + { + throw new Exception($"{taskIds.Count} task dispatch events could not be found"); + } + }); + + return res; + } + + public Payload GetPayloadTestData(string name) + { + var payload = PayloadsTestData.TestData.FirstOrDefault(c => c.Name.Contains(name)); + + if (payload != null) + { + if (payload.Payload != null) + { + Payload.Add(payload.Payload); + return payload.Payload; + } + else + { + throw new Exception($"Payload {name} does not have any applicable test data, please check and try again!"); + } + } + else + { + throw new Exception($"Payload {name} does not have any applicable test data, please check and try again!"); + } + } + + public Payload GetPayloadsTestDataByIndex(int index) + { + var payload = PayloadsTestData.TestData[index]; + + if (payload != null) + { + if (payload.Payload != null) + { + Payload.Add(payload.Payload); + return payload.Payload; + } + else + { + throw new Exception($"Payload at index {index} does not have any applicable test data, please check and try again!"); + } + } + else + { + throw new Exception($"Payload at index {index} does not have any applicable test data, please check and try again!"); + } + } + + public string GetPayloadId(string? payloadId = null) + { + return PayloadId = payloadId ?? Guid.NewGuid().ToString(); + } + } +} +#pragma warning restore CS8602 // Dereference of a possibly null reference. diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/MinioClientUtil.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/MinioClientUtil.cs index 39c85c62c..3272f4a21 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/MinioClientUtil.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/MinioClientUtil.cs @@ -51,7 +51,6 @@ await RetryPolicy.ExecuteAsync(async () => try { var listOfKeys = new List(); - var count = 0; var listArgs = new ListObjectsArgs() .WithBucket(bucketName) .WithPrefix("") @@ -63,7 +62,7 @@ await RetryPolicy.ExecuteAsync(async () => await Client.RemoveObjectAsync(bucketName, obj.Key); } } - catch (Exception e) + catch (Exception) { } diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/WorkflowExecutorStartup.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/WorkflowExecutorStartup.cs index d2bdf51b1..826941d0f 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/WorkflowExecutorStartup.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/WorkflowExecutorStartup.cs @@ -83,7 +83,9 @@ private static IHostBuilder CreateHostBuilder() => services.AddSingleton(); +#pragma warning disable CS8603 // Possible null reference return. services.AddHostedService(p => p.GetService()); +#pragma warning restore CS8603 // Possible null reference return. // Services services.AddTransient(); @@ -111,8 +113,8 @@ private static IHostBuilder CreateHostBuilder() => services.AddSingleton(p => { var accessor = p.GetRequiredService(); - var request = accessor.HttpContext.Request; - var uri = string.Concat(request.Scheme, "://", request.Host.ToUriComponent()); + var request = accessor?.HttpContext?.Request; + var uri = string.Concat(request?.Scheme, "://", request?.Host.ToUriComponent()); var newUri = new Uri(uri); return new UriService(newUri); }); diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/PayloadTestData.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/PayloadTestData.cs index 8b6886c52..80e751993 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/PayloadTestData.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/PayloadTestData.cs @@ -92,9 +92,9 @@ public static class PayloadsTestData PatientDetails = new PatientDetails() { PatientDob = null, - PatientId = null, - PatientName = null, - PatientSex = null + PatientId = String.Empty, + PatientName = String.Empty, + PatientSex = String.Empty } } }, diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/TaskUpdateTestData.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/TaskUpdateTestData.cs index ed6c86337..a25efb601 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/TaskUpdateTestData.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/TaskUpdateTestData.cs @@ -15,7 +15,7 @@ */ using Monai.Deploy.Messaging.Events; - +#pragma warning disable CS8602 // Dereference of a possibly null reference. namespace Monai.Deploy.WorkflowManager.WorkflowExecutor.IntegrationTests.TestData { public class TaskUpdateTestData @@ -550,3 +550,4 @@ public static string GetRelativePathForOutputArtifacts(string name) }; } } +#pragma warning restore CS8602 // Dereference of a possibly null reference. diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowInstanceTestData.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowInstanceTestData.cs index 66322594e..62b620866 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowInstanceTestData.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowInstanceTestData.cs @@ -17,6 +17,8 @@ using Monai.Deploy.Messaging.Events; using Monai.Deploy.WorkflowManager.Contracts.Models; using Monai.Deploy.WorkflowManager.IntegrationTests.POCO; +#pragma warning disable CS8602 // Dereference of a possibly null reference. +#pragma warning disable CS8601 // Possible null reference assignment. namespace Monai.Deploy.WorkflowManager.WorkflowExecutor.IntegrationTests.TestData { @@ -38,7 +40,7 @@ public static class WorkflowInstancesTestData { Id = Guid.NewGuid().ToString(), AeTitle = "Multi_Req", - WorkflowId = Helper.GetWorkflowByName("Workflow_Revision_for_bucket_minio").WorkflowRevision.WorkflowId, + WorkflowId = Helper.GetWorkflowByName("Workflow_Revision_for_bucket_minio")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = "5450c3a9-2b19-45b0-8b17-fb10f89d1b2d", BucketId = "bucket1", StartTime = DateTime.UtcNow, @@ -67,7 +69,7 @@ public static class WorkflowInstancesTestData { Id = Guid.NewGuid().ToString(), AeTitle = "Multi_Req", - WorkflowId = Helper.GetWorkflowByName("Multi_Request_Workflow_Created").WorkflowRevision.WorkflowId, + WorkflowId = Helper.GetWorkflowByName("Multi_Request_Workflow_Created")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Helper.GetWorkflowRequestByName("Multi_WF_Created").WorkflowRequestMessage.PayloadId.ToString(), BucketId = "bucket1", StartTime = DateTime.UtcNow, @@ -96,7 +98,7 @@ public static class WorkflowInstancesTestData { Id = Guid.NewGuid().ToString(), AeTitle = "Multi_Req", - WorkflowId = Helper.GetWorkflowByName("Multi_Request_Workflow_Dispatched").WorkflowRevision.WorkflowId, + WorkflowId = Helper.GetWorkflowByName("Multi_Request_Workflow_Dispatched")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Helper.GetWorkflowRequestByName("Multi_WF_Dispatched").WorkflowRequestMessage.PayloadId.ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -123,8 +125,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Task_Status_Update_Workflow").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Task_Status_Update_Workflow").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Task_Status_Update_Workflow")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Task_Status_Update_Workflow")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.UtcNow, BucketId = "monai", @@ -138,8 +140,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Task_Status_Update_Workflow").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Task_Status_Update_Workflow").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Task_Status_Update_Workflow")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Task_Status_Update_Workflow")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched } @@ -236,8 +238,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -251,8 +253,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched } @@ -265,8 +267,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_2").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_2").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_2")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_2")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -280,8 +282,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_2").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_2").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_2")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_2")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched } @@ -294,8 +296,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_3").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_3").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_3")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_3")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -309,8 +311,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_3").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_3").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_3")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id ?? "", + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_3")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type ?? "", OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched } @@ -323,8 +325,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -338,16 +340,16 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched }, new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[1].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[1].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks[1].Id ?? "", + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks[1].Type ?? "", OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched } @@ -360,8 +362,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -375,16 +377,16 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched }, new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[1].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[1].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks[1].Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks[1].Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Accepted } @@ -397,8 +399,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -412,16 +414,16 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched }, new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[1].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1").WorkflowRevision.Workflow.Tasks[1].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks[1].Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_1")?.WorkflowRevision?.Workflow?.Tasks[1].Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Succeeded } @@ -434,8 +436,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Independent_Task_Workflow").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Independent_Task_Workflow").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Independent_Task_Workflow")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Independent_Task_Workflow")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -449,8 +451,9 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Independent_Task_Workflow").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Independent_Task_Workflow").WorkflowRevision.Workflow.Tasks[0].Type, + + TaskId = Helper.GetWorkflowByName("Multi_Independent_Task_Workflow")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Independent_Task_Workflow")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched } @@ -463,8 +466,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -478,8 +481,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, OutputDirectory = "payloadId/workflows/workflowInstanceId/executionId/", Status = TaskExecutionStatus.Dispatched } @@ -493,7 +496,7 @@ public static class WorkflowInstancesTestData { Id = "bff4cfd0-3af3-4e2b-9f3c-de2a6f2b9569", AeTitle = "Multi_Req", - WorkflowId = Helper.GetWorkflowByName("Multi_Request_Workflow_Created").WorkflowRevision.WorkflowId, + WorkflowId = Helper.GetWorkflowByName("Multi_Request_Workflow_Created")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Helper.GetWorkflowRequestByName("Multi_WF_Created").WorkflowRequestMessage.PayloadId.ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -521,7 +524,7 @@ public static class WorkflowInstancesTestData { Id = "97749d29-8f75-4169-8cf4-1093a1f38c07", AeTitle = "Multi_Req", - WorkflowId = Helper.GetWorkflowByName("Multi_Request_Workflow_Dispatched").WorkflowRevision.WorkflowId, + WorkflowId = Helper.GetWorkflowByName("Multi_Request_Workflow_Dispatched")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Helper.GetWorkflowRequestByName("Multi_WF_Dispatched").WorkflowRequestMessage.PayloadId.ToString(), StartTime = DateTime.UtcNow, Status = Status.Created, @@ -548,8 +551,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.Now, Status = Status.Created, @@ -563,16 +566,16 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault().Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault().Type, Status = TaskExecutionStatus.Dispatched, // OutputArtifacts = "" // Need to add artifacts }, new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault().Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault().Type, Status = TaskExecutionStatus.Accepted // InputArtifacts = "" // Need to add artifacts } @@ -585,8 +588,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_True").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_True").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_True")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_True")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.Now, Status = Status.Created, @@ -600,8 +603,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_True").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_True").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_True")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_True")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, Status = TaskExecutionStatus.Dispatched } } @@ -613,8 +616,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_False").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_False").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_False")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_False")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.Now, Status = Status.Created, @@ -628,8 +631,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_False").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_False").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_False")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Single_Condition_False")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, Status = TaskExecutionStatus.Dispatched } } @@ -641,8 +644,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_True").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_True").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_True")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_True")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.Now, Status = Status.Created, @@ -656,8 +659,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_True").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_True").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_True")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_True")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, Status = TaskExecutionStatus.Dispatched } } @@ -669,8 +672,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_False").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_False").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_False")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_False")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.Now, Status = Status.Created, @@ -684,8 +687,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_False").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_False").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_False")?.WorkflowRevision?.Workflow?.Tasks?.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Multiple_Destination_Single_Condition_False")?.WorkflowRevision?.Workflow?.Tasks?.FirstOrDefault()?.Type, Status = TaskExecutionStatus.Dispatched } } @@ -697,8 +700,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.Now, Status = Status.Created, @@ -712,16 +715,16 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, Status = TaskExecutionStatus.Dispatched, // OutputArtifacts = "" // Need to add artifacts }, new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Invalid_Task_Destination")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, Status = TaskExecutionStatus.Accepted // InputArtifacts = "" // Need to add artifacts } @@ -734,8 +737,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Multiple_Condition_True_And_False").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Multiple_Condition_True_And_False").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Multiple_Condition_True_And_False")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Multiple_Condition_True_And_False")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.Now, Status = Status.Created, @@ -749,8 +752,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Multiple_Condition_True_And_False").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Multiple_Condition_True_And_False").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Multiple_Condition_True_And_False")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Destination_Multiple_Condition_True_And_False")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, Status = TaskExecutionStatus.Dispatched } } @@ -762,8 +765,8 @@ public static class WorkflowInstancesTestData WorkflowInstance = new WorkflowInstance() { Id = Guid.NewGuid().ToString(), - AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Task_Destination_Invalid_Condition").WorkflowRevision.Workflow.InformaticsGateway.AeTitle, - WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Task_Destination_Invalid_Condition").WorkflowRevision.WorkflowId, + AeTitle = Helper.GetWorkflowByName("Multi_Task_Workflow_Task_Destination_Invalid_Condition")?.WorkflowRevision?.Workflow?.InformaticsGateway?.AeTitle, + WorkflowId = Helper.GetWorkflowByName("Multi_Task_Workflow_Task_Destination_Invalid_Condition")?.WorkflowRevision?.WorkflowId ?? "", PayloadId = Guid.NewGuid().ToString(), StartTime = DateTime.Now, Status = Status.Created, @@ -777,8 +780,8 @@ public static class WorkflowInstancesTestData new TaskExecution() { ExecutionId = Guid.NewGuid().ToString(), - TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Task_Destination_Invalid_Condition").WorkflowRevision.Workflow.Tasks[0].Id, - TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Task_Destination_Invalid_Condition").WorkflowRevision.Workflow.Tasks[0].Type, + TaskId = Helper.GetWorkflowByName("Multi_Task_Workflow_Task_Destination_Invalid_Condition")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Id, + TaskType = Helper.GetWorkflowByName("Multi_Task_Workflow_Task_Destination_Invalid_Condition")?.WorkflowRevision?.Workflow?.Tasks.FirstOrDefault()?.Type, Status = TaskExecutionStatus.Dispatched } } @@ -878,3 +881,5 @@ public static class WorkflowInstancesTestData }; } } +#pragma warning restore CS8601 // Possible null reference assignment. +#pragma warning restore CS8602 // Dereference of a possibly null reference. diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowRequestTestData.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowRequestTestData.cs index 0458e45ec..090c4ff42 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowRequestTestData.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowRequestTestData.cs @@ -15,7 +15,7 @@ */ using Monai.Deploy.WorkflowManager.IntegrationTests.Models; - +#pragma warning disable CS8602 // Dereference of a possibly null reference. namespace Monai.Deploy.WorkflowManager.WorkflowExecutor.IntegrationTests.TestData { public class WorkflowRequestTestData @@ -50,6 +50,7 @@ public static class WorkflowRequestsTestData { Bucket = "bucket1", PayloadId = Guid.NewGuid(), + Workflows = new List() { Helper.GetWorkflowByName("Basic_Workflow_1").WorkflowRevision.WorkflowId }, CorrelationId = Guid.NewGuid().ToString(), Timestamp = DateTime.Now, @@ -320,3 +321,4 @@ public static class WorkflowRequestsTestData }; } } +#pragma warning restore CS8602 // Dereference of a possibly null reference. diff --git a/tests/UnitTests/WorkflowExecuter.Tests/Services/ConditionalParameterParserTests.cs b/tests/UnitTests/WorkflowExecuter.Tests/Services/ConditionalParameterParserTests.cs index 29aad4c91..492051ec0 100644 --- a/tests/UnitTests/WorkflowExecuter.Tests/Services/ConditionalParameterParserTests.cs +++ b/tests/UnitTests/WorkflowExecuter.Tests/Services/ConditionalParameterParserTests.cs @@ -58,11 +58,13 @@ public ConditionalParameterParserTests() "{{ context.executions.other_task.result.'Derick' }} == 'lordge'", true)] public void ConditionalParameterParser_WhenGivenCorrectResultMetadataString_ShouldEvaluate(string input, bool expectedResult, string? expectedDicomReturn = null) { - _dicom.Setup(w => w.GetAnyValueAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .ReturnsAsync(() => expectedDicomReturn); - _dicom.Setup(w => w.GetAllValueAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .ReturnsAsync(() => expectedDicomReturn); - + if (expectedDicomReturn is not null) + { + _dicom.Setup(w => w.GetAnyValueAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(() => expectedDicomReturn); + _dicom.Setup(w => w.GetAllValueAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(() => expectedDicomReturn); + } var testData = CreateTestData(); var workflow = testData.First(); @@ -81,11 +83,13 @@ public void ConditionalParameterParser_WhenGivenCorrectResultMetadataString_Shou [InlineData("'invalid' > 'false'", false)] public void ConditionalParameterParser_WhenGivenCorrectDicomString_ShouldEvaluate(string input, bool expectedResult, string? expectedDicomReturn = null) { - _dicom.Setup(w => w.GetAnyValueAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .ReturnsAsync(() => expectedDicomReturn); - _dicom.Setup(w => w.GetAllValueAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .ReturnsAsync(() => expectedDicomReturn); - + if (expectedDicomReturn is not null) + { + _dicom.Setup(w => w.GetAnyValueAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(() => expectedDicomReturn); + _dicom.Setup(w => w.GetAllValueAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(() => expectedDicomReturn); + } var testData = CreateTestData(); var workflow = testData.First(); @@ -104,7 +108,7 @@ public void ConditionalParameterParser_WhenGivenCorrectDicomString_ShouldEvaluat "{{ context.executions.2dbd1af7-b699-4467-8e99-05a0c22422b4.status }} == 'Succeeded' AND " + "{{ context.executions.2dbd1af7-b699-4467-8e99-05a0c22422b4.start_time }} == '25/12/2022 00:00:00' AND " + "{{ context.executions.2dbd1af7-b699-4467-8e99-05a0c22422b4.execution_id }} == '3c4484bd-e1a4-4347-902e-31a6503edd5f'", true)] - public void ConditionalParameterParser_WhenGivenCorrectExecutionString_ShouldEvaluate(string input, bool expectedResult, string? expectedDicomReturn = null) + public void ConditionalParameterParser_WhenGivenCorrectExecutionString_ShouldEvaluate(string input, bool expectedResult) { var testData = CreateTestData(); var workflow = testData.First(); From 52d898d34cca058b934bfd9cdaf7fe2f5a66c077 Mon Sep 17 00:00:00 2001 From: Jack Schofield Date: Mon, 1 Aug 2022 14:22:03 +0100 Subject: [PATCH 2/9] fix headers Signed-off-by: Jack Schofield --- .../Common/ServiceProviderExtensions.cs | 28 +- .../Controllers/WorkflowInstanceController.cs | 2 +- .../Controllers/WorkflowsController.cs | 5 +- .../Extentions/TaskManagerExtensions.cs | 9 + .../Extentions/WorkflowExecutorExtensions.cs | 13 + .../Logging/FileLoggingTextFormatter.cs | 28 +- .../Monai.Deploy.WorkflowManager.csproj | 10 +- .../DataRetentionService.cs | 28 +- src/WorkflowManager/Wrappers/Response.cs | 28 +- src/WorkflowManager/stylecop.json | 13 +- stylecop.json | 5 +- .../Support/MinioClientUtil.cs | 319 +++++++++--------- .../TestData/Helper.cs | 3 +- 13 files changed, 256 insertions(+), 235 deletions(-) diff --git a/src/WorkflowManager/Common/ServiceProviderExtensions.cs b/src/WorkflowManager/Common/ServiceProviderExtensions.cs index 0daf8639d..d0bfc0070 100644 --- a/src/WorkflowManager/Common/ServiceProviderExtensions.cs +++ b/src/WorkflowManager/Common/ServiceProviderExtensions.cs @@ -1,18 +1,16 @@ -/* - * 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. - */ +// Copyright 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 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. using System; using Microsoft.Extensions.Logging; diff --git a/src/WorkflowManager/Controllers/WorkflowInstanceController.cs b/src/WorkflowManager/Controllers/WorkflowInstanceController.cs index 6f2f6cb0c..79ff0535a 100644 --- a/src/WorkflowManager/Controllers/WorkflowInstanceController.cs +++ b/src/WorkflowManager/Controllers/WorkflowInstanceController.cs @@ -69,7 +69,7 @@ public WorkflowInstanceController( /// Workflow instance status filter. /// A list of workflow instances. [HttpGet] - public async Task GetListAsync([FromQuery] PaginationFilter filter, [FromQuery] string? status = null) + public async Task GetListAsync([FromQuery] PaginationFilter filter, [FromQuery] string status = null) { try { diff --git a/src/WorkflowManager/Controllers/WorkflowsController.cs b/src/WorkflowManager/Controllers/WorkflowsController.cs index 7e935d273..95aeafd5b 100644 --- a/src/WorkflowManager/Controllers/WorkflowsController.cs +++ b/src/WorkflowManager/Controllers/WorkflowsController.cs @@ -40,7 +40,6 @@ public class WorkflowsController : ApiControllerBase { private readonly IOptions _options; private readonly IWorkflowService _workflowService; - private readonly ILogger _logger; private readonly IUriService _uriService; @@ -48,10 +47,10 @@ public class WorkflowsController : ApiControllerBase /// Initializes a new instance of the class. /// /// IWorkflowService. - /// ILogger. + /// ILogger.WorkflowsController. /// Uri Service. /// Workflow Manager options. - /// ArgumentNullException + /// ArgumentNullException. public WorkflowsController( IWorkflowService workflowService, ILogger logger, diff --git a/src/WorkflowManager/Extentions/TaskManagerExtensions.cs b/src/WorkflowManager/Extentions/TaskManagerExtensions.cs index 5d48dfeb2..c7b5db3bd 100644 --- a/src/WorkflowManager/Extentions/TaskManagerExtensions.cs +++ b/src/WorkflowManager/Extentions/TaskManagerExtensions.cs @@ -23,8 +23,17 @@ namespace Monai.Deploy.WorkflowManager.Services { + /// + /// Sets up task manager service collection. + /// public static class TaskManagerExtensions { + /// + /// Adds task manager and dependencies to service collection. + /// + /// Service collection to add task manager to. + /// Hostcontext object. + /// Updated IServiceCollection. public static IServiceCollection AddTaskManager(this IServiceCollection services, HostBuilderContext hostContext) { Guard.Against.Null(hostContext, nameof(hostContext)); diff --git a/src/WorkflowManager/Extentions/WorkflowExecutorExtensions.cs b/src/WorkflowManager/Extentions/WorkflowExecutorExtensions.cs index 2c8f7de89..1f736c48a 100644 --- a/src/WorkflowManager/Extentions/WorkflowExecutorExtensions.cs +++ b/src/WorkflowManager/Extentions/WorkflowExecutorExtensions.cs @@ -1,3 +1,7 @@ +// Copyright 2021-2022 MONAI Consortium +// +// Licensed under the Apache License, Version 2.0 (the "License");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + /* * Copyright 2022 MONAI Consortium * @@ -29,8 +33,17 @@ namespace Monai.Deploy.WorkflowManager.Services { + /// + /// Sets up workflow executor service collection. + /// public static class WorkflowExecutorExtensions { + /// + /// Adds workflow executor and dependencies to service collection. + /// + /// Service collection to add workflow executor to. + /// Hostcontext object. + /// Updated IServiceCollection. public static IServiceCollection AddWorkflowExecutor(this IServiceCollection services, HostBuilderContext hostContext) { Guard.Against.Null(hostContext, nameof(hostContext)); diff --git a/src/WorkflowManager/Logging/FileLoggingTextFormatter.cs b/src/WorkflowManager/Logging/FileLoggingTextFormatter.cs index c6e6371ea..878dc6673 100644 --- a/src/WorkflowManager/Logging/FileLoggingTextFormatter.cs +++ b/src/WorkflowManager/Logging/FileLoggingTextFormatter.cs @@ -1,18 +1,16 @@ -/* - * 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. - */ +// Copyright 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 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. using System; using System.Globalization; diff --git a/src/WorkflowManager/Monai.Deploy.WorkflowManager.csproj b/src/WorkflowManager/Monai.Deploy.WorkflowManager.csproj index a0ef3ef0b..ae3860eae 100644 --- a/src/WorkflowManager/Monai.Deploy.WorkflowManager.csproj +++ b/src/WorkflowManager/Monai.Deploy.WorkflowManager.csproj @@ -1,4 +1,4 @@ -