From 8e16d73ad560bdb51d900298869730b7e9798320 Mon Sep 17 00:00:00 2001 From: Sam Rooke Date: Fri, 12 May 2023 10:32:58 +0100 Subject: [PATCH 1/3] fix data origin check in workflow validator Signed-off-by: Sam Rooke --- .../InformaticsGatewayConfiguration.cs | 6 + .../Exceptions/InternalServerException.cs | 35 ++ .../InformaticsGatewayService.cs | 20 +- ...nai.Deploy.WorkflowManager.Services.csproj | 1 + .../packages.lock.json | 571 ++++++++++++++++++ .../Controllers/WorkflowsController.cs | 59 +- .../appsettings.Development.json | 4 +- .../WorkflowManager/appsettings.Local.json | 4 +- .../WorkflowManager/appsettings.json | 4 +- .../WorkflowManager/packages.lock.json | 1 + .../Features/WorkflowApi.feature | 17 + .../TestData/WorkflowObjectTestData.cs | 32 + .../Controllers/WorkflowsControllerTests.cs | 120 ++++ .../WorkflowManager.Tests/packages.lock.json | 1 + 14 files changed, 853 insertions(+), 22 deletions(-) create mode 100644 src/WorkflowManager/Common/Exceptions/InternalServerException.cs diff --git a/src/Shared/Configuration/InformaticsGatewayConfiguration.cs b/src/Shared/Configuration/InformaticsGatewayConfiguration.cs index 4499f502a..b2c316846 100644 --- a/src/Shared/Configuration/InformaticsGatewayConfiguration.cs +++ b/src/Shared/Configuration/InformaticsGatewayConfiguration.cs @@ -22,5 +22,11 @@ public class InformaticsGatewayConfiguration { [ConfigurationKeyName("apiHost")] public string ApiHost { get; set; } + + [ConfigurationKeyName("username")] + public string Username { get; set; } + + [ConfigurationKeyName("password")] + public string Password { get; set; } } } diff --git a/src/WorkflowManager/Common/Exceptions/InternalServerException.cs b/src/WorkflowManager/Common/Exceptions/InternalServerException.cs new file mode 100644 index 000000000..4557c83b1 --- /dev/null +++ b/src/WorkflowManager/Common/Exceptions/InternalServerException.cs @@ -0,0 +1,35 @@ +/* + * 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. + */ + +namespace Monai.Deploy.WorkflowManager.Common.Exceptions +{ + public class MonaiInternalServerException : Exception + { + public MonaiInternalServerException() + { + } + + public MonaiInternalServerException(string message) + : base(message) + { + } + + public MonaiInternalServerException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/InformaticsGateway/InformaticsGatewayService.cs b/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/InformaticsGateway/InformaticsGatewayService.cs index dcb81fb9e..0c9da2d29 100644 --- a/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/InformaticsGateway/InformaticsGatewayService.cs +++ b/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/InformaticsGateway/InformaticsGatewayService.cs @@ -15,7 +15,9 @@ */ using System.Net; +using System.Net.Http.Headers; using Microsoft.Extensions.Options; +using Monai.Deploy.WorkflowManager.Common.Exceptions; using Monai.Deploy.WorkflowManager.Configuration; namespace Monai.Deploy.WorkflowManager.Services.InformaticsGateway @@ -31,17 +33,29 @@ IOptions options _options = options ?? throw new ArgumentNullException(nameof(options)); _httpClient.BaseAddress = new Uri(_options.Value.ApiHost); + + var authenticationString = $"{_options.Value.Username}:{_options.Value.Password}"; + var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(authenticationString)); + + _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString); } private readonly HttpClient _httpClient; private readonly IOptions _options; - public async Task OriginExists(string name) + public async Task OriginExists(string aetitle) { - var response = await _httpClient.GetAsync($"/config/source/{name}"); + try + { + var response = await _httpClient.GetAsync($"/config/source/aetitle/{aetitle}"); - return response.StatusCode == HttpStatusCode.OK; + return response.StatusCode == HttpStatusCode.OK; + } + catch (Exception ex) + { + throw new MonaiInternalServerException($"An error occured when cheking if the origin '{aetitle}' existed.", ex); + } } } } diff --git a/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/Monai.Deploy.WorkflowManager.Services.csproj b/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/Monai.Deploy.WorkflowManager.Services.csproj index d0491abe4..477269c41 100644 --- a/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/Monai.Deploy.WorkflowManager.Services.csproj +++ b/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/Monai.Deploy.WorkflowManager.Services.csproj @@ -41,6 +41,7 @@ + diff --git a/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/packages.lock.json b/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/packages.lock.json index d34fecf72..649c90706 100644 --- a/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/packages.lock.json +++ b/src/WorkflowManager/Monai.Deploy.WorkflowManager.Services/packages.lock.json @@ -34,11 +34,63 @@ "AWSSDK.Core": "[3.7.105.20, 4.0.0)" } }, + "DnsClient": { + "type": "Transitive", + "resolved": "1.6.1", + "contentHash": "4H/f2uYJOZ+YObZjpY9ABrKZI+JNw3uizp6oMzTXwDw6F+2qIPhpRl/1t68O/6e98+vqNiYGu+lswmwdYUy3gg==", + "dependencies": { + "Microsoft.Win32.Registry": "5.0.0" + } + }, "JetBrains.Annotations": { "type": "Transitive", "resolved": "2021.3.0", "contentHash": "Ddxjs5RRjf+c8m9m++WvhW1lz1bqNhsTjWvCLbQN9bvKbkJeR9MhtfNwKgBRRdG2yLHcXFr5Lf7fsvvkiPaDRg==" }, + "LightInject": { + "type": "Transitive", + "resolved": "5.4.0", + "contentHash": "w4EjEhNqtzFb0qlScmpjA84Nuv4+OITNGfYCjDhJoLYyw+uagkrrth+e9Hgidv4bMzuNSlJpHPGTHx6DtE4Ixg==", + "dependencies": { + "System.ValueTuple": "4.5.0" + } + }, + "Microsoft.AspNetCore.Hosting.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "ubycklv+ZY7Kutdwuy1W4upWcZ6VFR8WUXU7l7B2+mvbDBBPAcfpi+E+Y5GFe+Q157YfA3C49D2GCjAZc7Mobw==", + "dependencies": { + "Microsoft.AspNetCore.Hosting.Server.Abstractions": "2.2.0", + "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", + "Microsoft.Extensions.Hosting.Abstractions": "2.2.0" + } + }, + "Microsoft.AspNetCore.Hosting.Server.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "1PMijw8RMtuQF60SsD/JlKtVfvh4NORAhF4wjysdABhlhTrYmtgssqyncR0Stq5vqtjplZcj6kbT4LRTglt9IQ==", + "dependencies": { + "Microsoft.AspNetCore.Http.Features": "2.2.0", + "Microsoft.Extensions.Configuration.Abstractions": "2.2.0" + } + }, + "Microsoft.AspNetCore.Http.Abstractions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "Nxs7Z1q3f1STfLYKJSVXCs1iBl+Ya6E8o4Oy1bCxJ/rNI44E/0f6tbsrVqAWfB7jlnJfyaAtIalBVxPKUPQb4Q==", + "dependencies": { + "Microsoft.AspNetCore.Http.Features": "2.2.0", + "System.Text.Encodings.Web": "4.5.0" + } + }, + "Microsoft.AspNetCore.Http.Features": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "ziFz5zH8f33En4dX81LW84I6XrYXKf9jg6aM39cM+LffN9KJahViKZ61dGMSO2gd3e+qe5yBRwsesvyqlZaSMg==", + "dependencies": { + "Microsoft.Extensions.Primitives": "2.2.0" + } + }, "Microsoft.Extensions.Configuration": { "type": "Transitive", "resolved": "6.0.1", @@ -56,6 +108,14 @@ "Microsoft.Extensions.Primitives": "6.0.0" } }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "2.2.0" + } + }, "Microsoft.Extensions.DependencyInjection": { "type": "Transitive", "resolved": "6.0.0", @@ -121,6 +181,33 @@ "resolved": "6.0.3", "contentHash": "SUpStcdjeBbdKjPKe53hVVLkFjylX0yIXY8K+xWa47+o1d+REDyOMZjHZa+chsQI1K9qZeiHWk9jos0TFU7vGg==" }, + "Microsoft.Extensions.Logging.Configuration": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "ukU1mQGX9+xBsEzpNd13yl4deFVYI+fxxnmKpOhvNZsF+/trCrAUQh+9QM5pPGHbfYkz3lLQ4BXfKCP0502dLw==", + "dependencies": { + "Microsoft.Extensions.Logging": "2.2.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "2.2.0" + } + }, + "Microsoft.Extensions.Logging.Console": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "1eGgcOJ++PMxW6sn++j6U7wsWvhEBm/5ScqBUUBGLRE8M7AHahi9tsxivDMqEXVM3F0/pshHl3kEpMXtw4BeFg==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging": "2.2.0", + "Microsoft.Extensions.Logging.Configuration": "2.2.0" + } + }, + "Microsoft.Extensions.Logging.Debug": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "JjqWtshxUujSnxslFccCRAaH8uFOciqXkYdRw+h5MwpC4sUc+ju9yZzvVi6PA5vW09ckv26EkasEvXrofGiaJg==", + "dependencies": { + "Microsoft.Extensions.Logging": "2.2.0" + } + }, "Microsoft.Extensions.Options": { "type": "Transitive", "resolved": "6.0.0", @@ -130,6 +217,17 @@ "Microsoft.Extensions.Primitives": "6.0.0" } }, + "Microsoft.Extensions.Options.ConfigurationExtensions": { + "type": "Transitive", + "resolved": "2.2.0", + "contentHash": "d4WS6yVXaw43ffiUnHj8oG1t2B6RbDDiQcgdA+Eq//NlPa3Wd+GTJFKj4OM4eDF3GjVumGr/CEVRS/jcYoF5LA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "2.2.0", + "Microsoft.Extensions.Configuration.Binder": "2.2.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0", + "Microsoft.Extensions.Options": "2.2.0" + } + }, "Microsoft.Extensions.Primitives": { "type": "Transitive", "resolved": "6.0.0", @@ -138,6 +236,25 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, "Monai.Deploy.Messaging": { "type": "Transitive", "resolved": "0.1.22", @@ -175,16 +292,221 @@ "Newtonsoft.Json": "13.0.3" } }, + "Mongo.Migration": { + "type": "Transitive", + "resolved": "3.1.4", + "contentHash": "iA13H1tFH7x3eeKhBAYdgFxzK4gj78hY2pc5yiB08zX3kmhxGT/hp5k+iTDlSlCCyl+pMNpitTUiKiqOI6L6Gg==", + "dependencies": { + "LightInject": "5.4.0", + "Microsoft.AspNetCore.Hosting.Abstractions": "2.2.0", + "Microsoft.AspNetCore.Http.Abstractions": "2.2.0", + "Microsoft.Extensions.DependencyInjection": "2.2.0", + "Microsoft.Extensions.Logging.Abstractions": "2.2.0", + "Microsoft.Extensions.Logging.Console": "2.2.0", + "Microsoft.Extensions.Logging.Debug": "2.2.0", + "Microsoft.Extensions.Options": "2.2.0", + "MongoDB.Driver": "2.13.1", + "NLog": "4.7.11", + "Serilog": "2.8.0", + "Serilog.Extensions.Logging": "2.0.4", + "Serilog.Extensions.Logging.File": "2.0.0", + "System.ValueTuple": "4.5.0" + } + }, + "MongoDB.Bson": { + "type": "Transitive", + "resolved": "2.19.0", + "contentHash": "pGp9F2PWU3Dj54PiXKibuaQ5rphWkfp8/Nsy5jLp2dWZGRGlr3r/Lfwnr0PvfihFfxieUcJZ2z3VeO8RctXcvA==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "5.0.0" + } + }, + "MongoDB.Driver": { + "type": "Transitive", + "resolved": "2.19.0", + "contentHash": "W/1YByn5gNGfHBe8AyDURXWKn1Z9xJ9IUjplFcvk8B/jlTlDOkmXgmwjlToIdqr0l8rX594kksjGx3a9if3dsg==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "2.0.0", + "MongoDB.Bson": "2.19.0", + "MongoDB.Driver.Core": "2.19.0", + "MongoDB.Libmongocrypt": "1.7.0" + } + }, + "MongoDB.Driver.Core": { + "type": "Transitive", + "resolved": "2.19.0", + "contentHash": "KbzJJJc4EsUZ+YQoe7zZL1OxHVC9RjgQMso2LjhZWnlP+IHSON63vKNt7jGarXrOVXK0DqIUrRwQyXMgmqTX5g==", + "dependencies": { + "AWSSDK.SecurityToken": "3.7.100.14", + "DnsClient": "1.6.1", + "Microsoft.Extensions.Logging.Abstractions": "2.0.0", + "MongoDB.Bson": "2.19.0", + "MongoDB.Libmongocrypt": "1.7.0", + "SharpCompress": "0.30.1", + "Snappier": "1.0.0", + "System.Buffers": "4.5.1", + "ZstdSharp.Port": "0.6.2" + } + }, + "MongoDB.Libmongocrypt": { + "type": "Transitive", + "resolved": "1.7.0", + "contentHash": "p9+peTZX63nGHskOLhvhfBtrknxNg1RzXepE07rPozuCGz27bMjCcQyvn2YByg0L3YEcNWdTmI4BlnG/5RF+5Q==" + }, "Newtonsoft.Json": { "type": "Transitive", "resolved": "13.0.3", "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" }, + "NLog": { + "type": "Transitive", + "resolved": "4.7.11", + "contentHash": "A7EpoOjWesV5BPx1cOiBndazZq1VGdagIs6oK8ttcRDl5adCMtHiTqnsD5yYaOrMxOQeCjHBf/w3nKzCmhGbgw==" + }, + "Serilog": { + "type": "Transitive", + "resolved": "2.8.0", + "contentHash": "zjuKXW5IQws43IHX7VY9nURsaCiBYh2kyJCWLJRSWrTsx/syBKHV8MibWe2A+QH3Er0AiwA+OJmO3DhFJDY1+A==", + "dependencies": { + "System.Collections.NonGeneric": "4.3.0" + } + }, + "Serilog.Extensions.Logging": { + "type": "Transitive", + "resolved": "2.0.4", + "contentHash": "C8Vf9Wj1M+wGilChTV+OhE4v5ZCDzQfHjLKj2yNDMkXf/zgUKeAUZfbrVrt/c+flXP8M7/SHWBOXTkuPgubFsA==", + "dependencies": { + "Microsoft.Extensions.Logging": "2.0.0", + "Serilog": "2.3.0" + } + }, + "Serilog.Extensions.Logging.File": { + "type": "Transitive", + "resolved": "2.0.0", + "contentHash": "usO0qr4v9VCMBWiTJ1nQmAbPNCt40FrkDol6CpfCXbsxGZS/hH+YCueF7vvPQ32ATI0GWcMWiKRdjXEE7/HxTQ==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "2.0.0", + "Microsoft.Extensions.Configuration.Binder": "2.0.0", + "Serilog": "2.5.0", + "Serilog.Extensions.Logging": "2.0.2", + "Serilog.Formatting.Compact": "1.0.0", + "Serilog.Sinks.Async": "1.1.0", + "Serilog.Sinks.RollingFile": "3.3.0" + } + }, + "Serilog.Formatting.Compact": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "r3QYz02y7+B7Ng30hyJM929OJhem7SsJ4XDUE0Zfptj2MRiQfpPUb5f58juAFjp/TnNeSX2QNzZEnHwLeoJfHQ==", + "dependencies": { + "Serilog": "2.0.0" + } + }, + "Serilog.Sinks.Async": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "xll0Kanz2BkCxuv+F3p1WXr47jdsVM0GU1n1LZvK+18QiRZ/WGFNxSNw9EMKFV5ED5gr7MUpAe6PCMNL1HGUMA==", + "dependencies": { + "Serilog": "2.1.0", + "System.Collections.Concurrent": "4.0.12" + } + }, + "Serilog.Sinks.File": { + "type": "Transitive", + "resolved": "3.2.0", + "contentHash": "VHbo68pMg5hwSWrzLEdZv5b/rYmIgHIRhd4d5rl8GnC5/a8Fr+RShT5kWyeJOXax1el6mNJ+dmHDOVgnNUQxaw==", + "dependencies": { + "Serilog": "2.3.0", + "System.IO": "4.1.0", + "System.IO.FileSystem": "4.0.1", + "System.IO.FileSystem.Primitives": "4.0.1", + "System.Text.Encoding.Extensions": "4.0.11", + "System.Threading": "4.0.11", + "System.Threading.Timer": "4.0.1" + } + }, + "Serilog.Sinks.RollingFile": { + "type": "Transitive", + "resolved": "3.3.0", + "contentHash": "2lT5X1r3GH4P0bRWJfhA7etGl8Q2Ipw9AACvtAHWRUSpYZ42NGVyHoVs2ALBZ/cAkkS+tA4jl80Zie144eLQPg==", + "dependencies": { + "Serilog.Sinks.File": "3.2.0", + "System.IO": "4.1.0", + "System.IO.FileSystem.Primitives": "4.0.1", + "System.Runtime.InteropServices": "4.1.0", + "System.Text.Encoding.Extensions": "4.0.11" + } + }, + "SharpCompress": { + "type": "Transitive", + "resolved": "0.30.1", + "contentHash": "XqD4TpfyYGa7QTPzaGlMVbcecKnXy4YmYLDWrU+JIj7IuRNl7DH2END+Ll7ekWIY8o3dAMWLFDE1xdhfIWD1nw==" + }, + "Snappier": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "rFtK2KEI9hIe8gtx3a0YDXdHOpedIf9wYCEYtBEmtlyiWVX3XlCNV03JrmmAi/Cdfn7dxK+k0sjjcLv4fpHnqA==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.0.11", + "contentHash": "YUJGz6eFKqS0V//mLt25vFGrrCvOnsXjlvFQs+KimpwNxug9x0Pzy4PlFMU3Q2IzqAa9G2L4LsK3+9vCBK7oTg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Collections.Concurrent": { + "type": "Transitive", + "resolved": "4.0.12", + "contentHash": "2gBcbb3drMLgxlI0fBfxMA31ec6AEyYCHygGse4vxceJan8mRIWeKJ24BFzN7+bi/NFTgdIgufzb94LWO5EERQ==", + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Diagnostics.Tracing": "4.1.0", + "System.Globalization": "4.0.11", + "System.Reflection": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Threading": "4.0.11", + "System.Threading.Tasks": "4.0.11" + } + }, + "System.Collections.NonGeneric": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "prtjIEMhGUnQq6RnPEYLpFt8AtLbp9yq2zxOSrY7KJJZrw25Fi97IzBqY7iqssbM61Ek5b8f3MG/sG1N2sN5KA==", + "dependencies": { + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0" + } + }, "System.ComponentModel.Annotations": { "type": "Transitive", "resolved": "5.0.0", "contentHash": "dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==" }, + "System.Diagnostics.Debug": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", "resolved": "6.0.0", @@ -193,22 +515,271 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "System.Diagnostics.Tracing": { + "type": "Transitive", + "resolved": "4.1.0", + "contentHash": "vDN1PoMZCkkdNjvZLql592oYJZgS7URcJzJ7bxeBgGtx5UtR5leNm49VmfHGqIffX4FKacHbI3H6UyNSHQknBg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Globalization": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.IO": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, "System.IO.Abstractions": { "type": "Transitive", "resolved": "17.2.3", "contentHash": "VcozGeE4SxIo0cnXrDHhbrh/Gb8KQnZ3BvMelvh+iw0PrIKtuuA46U2Xm4e4pgnaWFgT4RdZfTpWl/WPRdw0WQ==" }, + "System.IO.FileSystem": { + "type": "Transitive", + "resolved": "4.0.1", + "contentHash": "IBErlVq5jOggAD69bg1t0pJcHaDbJbWNUZTPI96fkYWzwYbN6D9wRHMULLDd9dHsl7C2YsxXL31LMfPI1SWt8w==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1", + "Microsoft.NETCore.Targets": "1.0.1", + "System.IO": "4.1.0", + "System.IO.FileSystem.Primitives": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Handles": "4.0.1", + "System.Text.Encoding": "4.0.11", + "System.Threading.Tasks": "4.0.11" + } + }, + "System.IO.FileSystem.Primitives": { + "type": "Transitive", + "resolved": "4.0.1", + "contentHash": "kWkKD203JJKxJeE74p8aF8y4Qc9r9WQx4C0cHzHPrY3fv/L/IhWnyCHaFJ3H1QPOH6A93whlQ2vG5nHlBDvzWQ==", + "dependencies": { + "System.Runtime": "4.1.0" + } + }, + "System.Reflection": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Resources.ResourceManager": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Globalization": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", "resolved": "6.0.0", "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" }, + "System.Runtime.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime.Handles": { + "type": "Transitive", + "resolved": "4.0.1", + "contentHash": "nCJvEKguXEvk2ymk1gqj625vVnlK3/xdGzx0vOKicQkoquaTBJTP13AIYkocSUwHCLNBwUbXTqTWGDxBTWpt7g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Runtime.InteropServices": { + "type": "Transitive", + "resolved": "4.1.0", + "contentHash": "16eu3kjHS633yYdkjwShDHZLRNMKVi/s0bY8ODiqJ2RfMhDMAwxZaUaWVnZ2P71kr/or+X9o/xFWtNqz8ivieQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Reflection": "4.1.0", + "System.Reflection.Primitives": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Handles": "4.0.1" + } + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Text.Encoding.Extensions": { + "type": "Transitive", + "resolved": "4.0.11", + "contentHash": "jtbiTDtvfLYgXn8PTfWI+SiBs51rrmO4AAckx4KR6vFK9Wzf6tI8kcRdsYQNwriUeQ1+CtQbM1W4cMbLXnj/OQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0", + "System.Text.Encoding": "4.0.11" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "Xg4G4Indi4dqP1iuAiMSwpiWS54ZghzR644OtsRCm/m/lBMG8dUBhLVN7hLm8NNrNTR+iGbshCPTwrvxZPlm4g==" + }, + "System.Threading": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==", + "dependencies": { + "System.Runtime": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Threading.Tasks": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Threading.Timer": { + "type": "Transitive", + "resolved": "4.0.1", + "contentHash": "saGfUV8uqVW6LeURiqxcGhZ24PzuRNaUBtbhVeuUAvky1naH395A/1nY0P2bWvrw/BreRtIB/EzTDkGBpqCwEw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1", + "Microsoft.NETCore.Targets": "1.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.ValueTuple": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, + "ZstdSharp.Port": { + "type": "Transitive", + "resolved": "0.6.2", + "contentHash": "jPao/LdUNLUz8rn3H1D8W7wQbZsRZM0iayvWI4xGejJg3XJHT56gcmYdgmCGPdJF1UEBqUjucCRrFB+4HbJsbw==" + }, + "monai.deploy.workflowmanager.common": { + "type": "Project", + "dependencies": { + "Monai.Deploy.WorkflowManager.Contracts": "1.0.0", + "Monai.Deploy.WorkflowManager.Database": "1.0.0", + "Monai.Deploy.WorkflowManager.Storage": "1.0.0" + } + }, "monai.deploy.workflowmanager.configuration": { "type": "Project", "dependencies": { "Monai.Deploy.Messaging": "0.1.22", "Monai.Deploy.Storage": "0.2.15" } + }, + "monai.deploy.workflowmanager.contracts": { + "type": "Project", + "dependencies": { + "Monai.Deploy.Messaging": "0.1.22", + "Mongo.Migration": "3.1.4", + "MongoDB.Bson": "2.19.0" + } + }, + "monai.deploy.workflowmanager.database": { + "type": "Project", + "dependencies": { + "Monai.Deploy.WorkflowManager.Contracts": "1.0.0", + "Monai.Deploy.WorkflowManager.Logging": "1.0.0", + "Mongo.Migration": "3.1.4", + "MongoDB.Driver": "2.19.0" + } + }, + "monai.deploy.workflowmanager.logging": { + "type": "Project", + "dependencies": { + "Monai.Deploy.WorkflowManager.Contracts": "1.0.0" + } + }, + "monai.deploy.workflowmanager.storage": { + "type": "Project", + "dependencies": { + "Monai.Deploy.Storage": "0.2.15", + "Monai.Deploy.WorkflowManager.Contracts": "1.0.0", + "Monai.Deploy.WorkflowManager.Logging": "1.0.0" + } } } } diff --git a/src/WorkflowManager/WorkflowManager/Controllers/WorkflowsController.cs b/src/WorkflowManager/WorkflowManager/Controllers/WorkflowsController.cs index e9134aa98..6aa6a8bd9 100644 --- a/src/WorkflowManager/WorkflowManager/Controllers/WorkflowsController.cs +++ b/src/WorkflowManager/WorkflowManager/Controllers/WorkflowsController.cs @@ -22,6 +22,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using Monai.Deploy.WorkflowManager.Common.Exceptions; using Monai.Deploy.WorkflowManager.Common.Interfaces; using Monai.Deploy.WorkflowManager.Configuration; using Monai.Deploy.WorkflowManager.Contracts.Models; @@ -152,14 +153,23 @@ public async Task ValidateAsync([FromBody] WorkflowUpdateRequest { var workflow = request.Workflow; _workflowValidator.OrignalName = request.OriginalWorkflowName; - var errors = await _workflowValidator.ValidateWorkflow(workflow); - if (errors.Count > 0) + try { - var validationErrors = WorkflowValidator.ErrorsToString(errors); - _logger.LogDebug($"{nameof(CreateAsync)} - Failed to validate {nameof(workflow)}: {validationErrors}"); + var errors = await _workflowValidator.ValidateWorkflow(workflow); + + if (errors.Count > 0) + { + var validationErrors = WorkflowValidator.ErrorsToString(errors); + _logger.LogDebug($"{nameof(ValidateAsync)} - Failed to validate {nameof(workflow)}: {validationErrors}"); - return Problem($"Failed to validate {nameof(workflow)}: {string.Join(", ", validationErrors)}", $"/workflows", BadRequest); + return Problem($"Failed to validate {nameof(workflow)}: {string.Join(", ", validationErrors)}", $"/workflows/validate", BadRequest); + } + } + catch (MonaiInternalServerException ex) + { + _logger.LogDebug($"{nameof(ValidateAsync)} - Internal server error while validating {nameof(workflow)}: {ex.InnerException}"); + return Problem($"Internal server error while validating {nameof(workflow)}", $"/workflows/validate", InternalServerError); } return StatusCode(StatusCodes.Status204NoContent); @@ -176,14 +186,22 @@ public async Task ValidateAsync([FromBody] WorkflowUpdateRequest [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)] public async Task CreateAsync([FromBody] Workflow workflow) { - var errors = await _workflowValidator.ValidateWorkflow(workflow); - - if (errors.Count > 0) + try { - var validationErrors = WorkflowValidator.ErrorsToString(errors); - _logger.LogDebug($"{nameof(CreateAsync)} - Failed to validate {nameof(workflow)}: {validationErrors}"); + var errors = await _workflowValidator.ValidateWorkflow(workflow); + + if (errors.Count > 0) + { + var validationErrors = WorkflowValidator.ErrorsToString(errors); + _logger.LogDebug($"{nameof(CreateAsync)} - Failed to validate {nameof(workflow)}: {validationErrors}"); - return Problem($"Failed to validate {nameof(workflow)}: {string.Join(", ", validationErrors)}", $"/workflows", BadRequest); + return Problem($"Failed to validate {nameof(workflow)}: {string.Join(", ", validationErrors)}", $"/workflows", BadRequest); + } + } + catch (MonaiInternalServerException ex) + { + _logger.LogDebug($"{nameof(CreateAsync)} - Internal server error while validating {nameof(workflow)}: {ex.InnerException}"); + return Problem($"Internal server error while validating {nameof(workflow)}", $"/workflows", InternalServerError); } try @@ -222,14 +240,23 @@ public async Task UpdateAsync([FromBody] WorkflowUpdateRequest re } _workflowValidator.OrignalName = originalName; - var errors = await _workflowValidator.ValidateWorkflow(workflow); - if (errors.Count > 0) + try { - var validationErrors = WorkflowValidator.ErrorsToString(errors); - _logger.LogDebug($"{nameof(UpdateAsync)} - Failed to validate {nameof(workflow)}: {validationErrors}"); + var errors = await _workflowValidator.ValidateWorkflow(workflow); - return Problem($"Failed to validate {nameof(workflow)}: {string.Join(", ", validationErrors)}", $"/workflows/{id}", BadRequest); + if (errors.Count > 0) + { + var validationErrors = WorkflowValidator.ErrorsToString(errors); + _logger.LogDebug($"{nameof(UpdateAsync)} - Failed to validate {nameof(workflow)}: {validationErrors}"); + + return Problem($"Failed to validate {nameof(workflow)}: {string.Join(", ", validationErrors)}", $"/workflows/{id}", BadRequest); + } + } + catch (MonaiInternalServerException ex) + { + _logger.LogDebug($"{nameof(UpdateAsync)} - Internal server error while validating {nameof(workflow)}: {ex.InnerException}"); + return Problem($"Internal server error while validating {nameof(workflow)}", $"/workflows/{id}", InternalServerError); } try diff --git a/src/WorkflowManager/WorkflowManager/appsettings.Development.json b/src/WorkflowManager/WorkflowManager/appsettings.Development.json index 650f4c17b..c08a019bd 100755 --- a/src/WorkflowManager/WorkflowManager/appsettings.Development.json +++ b/src/WorkflowManager/WorkflowManager/appsettings.Development.json @@ -96,7 +96,9 @@ } }, "InformaticsGateway": { - "apiHost": "http://localhost:5010" + "apiHost": "http://localhost:5010", + "username": "aide", + "password": "example" }, "Kestrel": { "EndPoints": { diff --git a/src/WorkflowManager/WorkflowManager/appsettings.Local.json b/src/WorkflowManager/WorkflowManager/appsettings.Local.json index 5fc5ae9f0..f81670e63 100755 --- a/src/WorkflowManager/WorkflowManager/appsettings.Local.json +++ b/src/WorkflowManager/WorkflowManager/appsettings.Local.json @@ -98,7 +98,9 @@ } }, "InformaticsGateway": { - "apiHost": "http://localhost:5010" + "apiHost": "http://localhost:5010", + "username": "aide", + "password": "example" }, "Kestrel": { "EndPoints": { diff --git a/src/WorkflowManager/WorkflowManager/appsettings.json b/src/WorkflowManager/WorkflowManager/appsettings.json index c129f2d19..484e2a87f 100755 --- a/src/WorkflowManager/WorkflowManager/appsettings.json +++ b/src/WorkflowManager/WorkflowManager/appsettings.json @@ -103,7 +103,9 @@ } }, "InformaticsGateway": { - "apiHost": "http://localhost:5010" + "apiHost": "http://localhost:5010", + "username": "", + "password": "" }, "Kestrel": { "EndPoints": { diff --git a/src/WorkflowManager/WorkflowManager/packages.lock.json b/src/WorkflowManager/WorkflowManager/packages.lock.json index 6d6f16250..32a402789 100755 --- a/src/WorkflowManager/WorkflowManager/packages.lock.json +++ b/src/WorkflowManager/WorkflowManager/packages.lock.json @@ -1566,6 +1566,7 @@ "type": "Project", "dependencies": { "Microsoft.Extensions.Http": "3.1.0", + "Monai.Deploy.WorkflowManager.Common": "1.0.0", "Monai.Deploy.WorkflowManager.Configuration": "1.0.0" } }, diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Features/WorkflowApi.feature b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Features/WorkflowApi.feature index 5e3643cca..03d41a0f1 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Features/WorkflowApi.feature +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Features/WorkflowApi.feature @@ -145,6 +145,15 @@ Scenario: Update workflow where workflow ID does not exist Then I will get a 404 response And I will receive the error message Failed to find workflow with Id: 52b87b54-a728-4796-9a79-d30867da2a6e +@UpdateWorkflows +Scenario Outline: Update workflow with invalid data origin + Given I have a clinical workflow Basic_Workflow_1 + And I have an endpoint /workflows/c86a437d-d026-4bdf-b1df-c7a6372b89e3 + And I have a body Invalid_Data_Origin + When I send a PUT request + Then I will get a 500 response + And I will receive the error message Internal server error while validating workflow + @AddWorkflows Scenario: Add workflow with valid details Given I have an endpoint /workflows @@ -250,6 +259,14 @@ Scenario Outline: Validate workflow with invalid details | Invalid_Clinical_Review_Missing_Notifications | notifications must be specified | | Invalid_Clinical_Review_Invalid_Notifications | notifications is incorrectly specified | +@ValidateWorkflows +Scenario: Validate workflow with invalid data origin + Given I have an endpoint /workflows/validate + And I have a body Invalid_Data_Origin + When I send a POST request + Then I will get a 500 response + And I will receive the error message Internal server error while validating workflow + @DeleteWorkflows Scenario: Delete a workflow with one revision Given I have a clinical workflow Basic_Workflow_1_static diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowObjectTestData.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowObjectTestData.cs index 75c53e355..f7ffbbedc 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowObjectTestData.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowObjectTestData.cs @@ -1552,6 +1552,38 @@ public static class WorkflowObjectsTestData AeTitle = "Update", ExportDestinations = new string[]{"test"} } + }, + }, + new WorkflowObjectTestData() + { + Name = "Invalid_Data_Origin", + Workflow = new Workflow() + { + Name = "Basic workflow", + Description = "Basic workflow update", + Version = "1", + Tasks = new TaskObject[] + { + new TaskObject + { + Id = "basic_id_with-legal-chars", + Type = "router", + Description = "Basic Workflow update Task update", + Args = new Dictionary { { "test", "test" } }, + Artifacts = new ArtifactMap() + { + Input = new Artifact[] {}, + Output = new Artifact[] {} + }, + TaskDestinations = new TaskDestination[] {} + } + }, + InformaticsGateway = new InformaticsGateway() + { + AeTitle = "Update", + ExportDestinations = new string[]{"test"}, + DataOrigins = new string[] { "invalid_source" } + } } }, }; diff --git a/tests/UnitTests/WorkflowManager.Tests/Controllers/WorkflowsControllerTests.cs b/tests/UnitTests/WorkflowManager.Tests/Controllers/WorkflowsControllerTests.cs index 563ea54f8..7c525962d 100644 --- a/tests/UnitTests/WorkflowManager.Tests/Controllers/WorkflowsControllerTests.cs +++ b/tests/UnitTests/WorkflowManager.Tests/Controllers/WorkflowsControllerTests.cs @@ -33,6 +33,7 @@ using Xunit; using Monai.Deploy.WorkflowManager.Shared.Filter; using Monai.Deploy.WorkflowManager.Services.InformaticsGateway; +using Monai.Deploy.WorkflowManager.Common.Exceptions; namespace Monai.Deploy.WorkflowManager.Test.Controllers { @@ -468,6 +469,52 @@ public async Task ValidateAsync_InvalidWorkflowWithClinicalReviewInvalidNotifica Assert.StartsWith(expectedInstance, ((ProblemDetails)objectResult.Value).Instance); } + [Fact] + public async Task ValidateAsync_InvalidWorkflow_ReturnsInternalServerError() + { + var newWorkflow = new Workflow + { + Name = "Workflowname", + Description = "Workflowdesc", + Version = "1", + InformaticsGateway = new InformaticsGateway + { + AeTitle = "aetitle", + DataOrigins = new string[] { "test" }, + }, + Tasks = new TaskObject[] + { + new TaskObject { + Id = Guid.NewGuid().ToString(), + Type = "export", + Description = "taskdesc", + Args = new Dictionary + { + { "test", "test" } + } + } + } + }; + var request = new WorkflowUpdateRequest(); + request.Workflow = newWorkflow; + request.OriginalWorkflowName = newWorkflow.Name + "1"; + + _informaticsGatewayService.Setup(x => x.OriginExists(It.IsAny())) + .ThrowsAsync(new MonaiInternalServerException( + $"An error occured when cheking if the origin '{newWorkflow.InformaticsGateway.DataOrigins[0]}' existed.", + new Exception() + )); + + var result = await WorkflowsController.ValidateAsync(request); + + var objectResult = Assert.IsType(result); + + Assert.Equal(500, objectResult.StatusCode); + + const string expectedInstance = "/workflows"; + Assert.StartsWith(expectedInstance, ((ProblemDetails)objectResult.Value).Instance); + } + [Fact] public async Task UpdateAsync_InvalidWorkflow_ReturnsBadRequest() { @@ -703,6 +750,79 @@ public async Task UpdateAsync_WorkflowsExist_ReturnsWorkflowId() objectResult.Value.Should().BeEquivalentTo(response); } + [Fact] + public async Task UpdateAsync_InvalidWorkflow_ReturnsInternalServerException() + { + var newWorkflow = new Workflow + { + Name = "Workflowname", + Description = "Workflowdesc", + Version = "1", + InformaticsGateway = new InformaticsGateway + { + AeTitle = "aetitle", + DataOrigins = new string[] { "test" } + }, + Tasks = new TaskObject[] + { + new TaskObject { + Id = Guid.NewGuid().ToString(), + Type = "type", + Description = "taskdesc", + Args = new Dictionary + { + { "test", "test" } + } + } + } + }; + + var workflowRevision = new WorkflowRevision + { + Id = Guid.NewGuid().ToString(), + WorkflowId = Guid.NewGuid().ToString(), + Revision = 1, + Workflow = new Workflow + { + Name = "Workflowname", + Description = "Workflowdesc", + Version = "2", + InformaticsGateway = new InformaticsGateway + { + AeTitle = "aetitle", + DataOrigins = new[] { "test" }, + ExportDestinations = new[] { "test" } + }, + Tasks = new TaskObject[] + { + new TaskObject { + Id = Guid.NewGuid().ToString(), + Type = "type", + Description = "taskdesc" + } + } + } + }; + var request = new WorkflowUpdateRequest(); + request.Workflow = newWorkflow; + request.OriginalWorkflowName = newWorkflow.Name + "1"; + + _informaticsGatewayService.Setup(x => x.OriginExists(It.IsAny())) + .ThrowsAsync(new MonaiInternalServerException( + $"An error occured when cheking if the origin '{newWorkflow.InformaticsGateway.DataOrigins[0]}' existed.", + new Exception() + )); + + var result = await WorkflowsController.UpdateAsync(request, workflowRevision.WorkflowId); + + var objectResult = Assert.IsType(result); + + Assert.Equal(500, objectResult.StatusCode); + + const string expectedInstance = "/workflows"; + Assert.StartsWith(expectedInstance, ((ProblemDetails)objectResult.Value).Instance); + } + [Fact] public async Task DeleteAsync_WorkflowsExist_SoftDeltesWorkflow() { diff --git a/tests/UnitTests/WorkflowManager.Tests/packages.lock.json b/tests/UnitTests/WorkflowManager.Tests/packages.lock.json index f4a1c885a..fe785abe2 100755 --- a/tests/UnitTests/WorkflowManager.Tests/packages.lock.json +++ b/tests/UnitTests/WorkflowManager.Tests/packages.lock.json @@ -1751,6 +1751,7 @@ "type": "Project", "dependencies": { "Microsoft.Extensions.Http": "3.1.0", + "Monai.Deploy.WorkflowManager.Common": "1.0.0", "Monai.Deploy.WorkflowManager.Configuration": "1.0.0" } }, From 9b0fee7a0e49171806ee07fdc266961db95773a3 Mon Sep 17 00:00:00 2001 From: Sam Rooke Date: Fri, 12 May 2023 10:39:19 +0100 Subject: [PATCH 2/3] update informatics gateway configurations Signed-off-by: Sam Rooke --- .../WorkflowExecutor.IntegrationTests/appsettings.Test.json | 4 +++- .../InformaticsGateway/InformaticsGatewayServiceTests.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/appsettings.Test.json b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/appsettings.Test.json index 15b33bc43..ff6c1a87c 100755 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/appsettings.Test.json +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/appsettings.Test.json @@ -70,7 +70,9 @@ } }, "InformaticsGateway": { - "apiHost": "http://localhost:5010" + "apiHost": "http://localhost:5010", + "username": "username", + "password": "password" }, "Kestrel": { "EndPoints": { diff --git a/tests/UnitTests/WorkflowManager.Services.Tests/InformaticsGateway/InformaticsGatewayServiceTests.cs b/tests/UnitTests/WorkflowManager.Services.Tests/InformaticsGateway/InformaticsGatewayServiceTests.cs index 5a69c8926..91d9b32d3 100644 --- a/tests/UnitTests/WorkflowManager.Services.Tests/InformaticsGateway/InformaticsGatewayServiceTests.cs +++ b/tests/UnitTests/WorkflowManager.Services.Tests/InformaticsGateway/InformaticsGatewayServiceTests.cs @@ -42,7 +42,7 @@ public InformaticsGatewayServiceTests() httpClientFactory.Setup(w => w.CreateClient(It.IsAny())).Returns(httpClient.Object); - _options = Options.Create(new InformaticsGatewayConfiguration() { ApiHost = "https://localhost:5010" }); + _options = Options.Create(new InformaticsGatewayConfiguration() { ApiHost = "https://localhost:5010", Username = "username", Password = "password" }); InformaticsGatewayService = new InformaticsGatewayService(httpClientFactory.Object, _options); } From 7bb453ffbc0eda841f6a73368f51c4668dd7aea5 Mon Sep 17 00:00:00 2001 From: Alex Woodhead <11213454+woodheadio@users.noreply.github.com> Date: Fri, 12 May 2023 11:06:03 +0100 Subject: [PATCH 3/3] Bumped version of error handling library referenced by callback app. Signed-off-by: Alex Woodhead <11213454+woodheadio@users.noreply.github.com> --- CallbackApp.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CallbackApp.Dockerfile b/CallbackApp.Dockerfile index 12d1c0f81..f3b74d216 100644 --- a/CallbackApp.Dockerfile +++ b/CallbackApp.Dockerfile @@ -12,7 +12,7 @@ FROM python:3.10-alpine RUN apk update && apk upgrade -RUN apk add libcom_err=1.46.6-r0 +RUN apk add libcom_err=1.47.0-r2 WORKDIR /app COPY src/TaskManager/CallbackApp/app.py ./ COPY src/TaskManager/CallbackApp/requirements.txt ./