Skip to content

Commit 498c6fd

Browse files
add update workflow endpoint
Signed-off-by: Jack Schofield <[email protected]>
1 parent 5152136 commit 498c6fd

File tree

9 files changed

+428
-0
lines changed

9 files changed

+428
-0
lines changed

src/Common/Interfaces/IWorkflowService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,12 @@ public interface IWorkflowService
1818
/// </summary>
1919
/// <param name="workflow">Workflow to create.</param>
2020
Task<string> CreateAsync(Workflow workflow);
21+
22+
/// <summary>
23+
/// Updates a workflow within the workflow repository.
24+
/// </summary>
25+
/// <param name="workflow">Workflow to Update.</param>
26+
/// <param name="id">Id of the workflow to Update.</param>
27+
Task<string> UpdateAsync(Workflow workflow, string id);
2128
}
2229
}

src/Common/Services/WorkflowService.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,20 @@ public async Task<string> CreateAsync(Workflow workflow)
3232

3333
return await _workflowRepository.CreateAsync(workflow);
3434
}
35+
36+
public async Task<string> UpdateAsync(Workflow workflow, string id)
37+
{
38+
Guard.Against.Null(workflow);
39+
Guard.Against.NullOrWhiteSpace(id);
40+
41+
var existingWorkflow = await _workflowRepository.GetByWorkflowIdAsync(id);
42+
43+
if (existingWorkflow is null)
44+
{
45+
return null;
46+
}
47+
48+
return await _workflowRepository.UpdateAsync(workflow, existingWorkflow);
49+
}
3550
}
3651
}

src/Database/Interfaces/IWorkflowRepository.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,12 @@ public interface IWorkflowRepository
3838
/// </summary>
3939
/// <param name="workflow">Workflow object to create.</param>
4040
Task<string> CreateAsync(Workflow workflow);
41+
42+
/// <summary>
43+
/// Updates a workflow object and creates a new revision.
44+
/// </summary>
45+
/// <param name="workflow">Workflow object to create.</param>
46+
/// <param name="existingWorkflow">Existing Workflow object to update.</param>
47+
Task<string> UpdateAsync(Workflow workflow, WorkflowRevision existingWorkflow);
4148
}
4249
}

src/Database/WorkflowRepository.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,23 @@ public async Task<string> CreateAsync(Workflow workflow)
107107

108108
return workflowRevision.WorkflowId;
109109
}
110+
111+
public async Task<string> UpdateAsync(Workflow workflow, WorkflowRevision existingWorkflow)
112+
{
113+
Guard.Against.Null(workflow, nameof(workflow));
114+
Guard.Against.Null(existingWorkflow, nameof(existingWorkflow));
115+
116+
var workflowRevision = new WorkflowRevision
117+
{
118+
Id = Guid.NewGuid().ToString(),
119+
WorkflowId = existingWorkflow.WorkflowId,
120+
Revision = existingWorkflow.Revision++,
121+
Workflow = workflow
122+
};
123+
124+
await _workflowCollection.InsertOneAsync(workflowRevision);
125+
126+
return workflowRevision.WorkflowId;
127+
}
110128
}
111129
}

src/Monai.Deploy.WorkflowManager.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Monai.Deploy.WorkflowManage
5555
EndProject
5656
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Monai.Deploy.WorkflowManager.ConditionsResolver.Tests", "..\tests\UnitTests\ConditionsResolver.Tests\Monai.Deploy.WorkflowManager.ConditionsResolver.Tests.csproj", "{918E4DE3-A7BF-4B7F-9B5A-5C36FEFA3C30}"
5757
EndProject
58+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monai.Deploy.WorkflowManger.Common.Tests", "..\tests\UnitTests\Common.Tests\Monai.Deploy.WorkflowManger.Common.Tests.csproj", "{94CF906E-35A1-4C68-8346-01BC7FE9470A}"
59+
EndProject
5860
Global
5961
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6062
Debug|Any CPU = Debug|Any CPU
@@ -157,6 +159,10 @@ Global
157159
{918E4DE3-A7BF-4B7F-9B5A-5C36FEFA3C30}.Debug|Any CPU.Build.0 = Debug|Any CPU
158160
{918E4DE3-A7BF-4B7F-9B5A-5C36FEFA3C30}.Release|Any CPU.ActiveCfg = Release|Any CPU
159161
{918E4DE3-A7BF-4B7F-9B5A-5C36FEFA3C30}.Release|Any CPU.Build.0 = Release|Any CPU
162+
{94CF906E-35A1-4C68-8346-01BC7FE9470A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
163+
{94CF906E-35A1-4C68-8346-01BC7FE9470A}.Debug|Any CPU.Build.0 = Debug|Any CPU
164+
{94CF906E-35A1-4C68-8346-01BC7FE9470A}.Release|Any CPU.ActiveCfg = Release|Any CPU
165+
{94CF906E-35A1-4C68-8346-01BC7FE9470A}.Release|Any CPU.Build.0 = Release|Any CPU
160166
EndGlobalSection
161167
GlobalSection(SolutionProperties) = preSolution
162168
HideSolutionNode = FALSE
@@ -176,6 +182,7 @@ Global
176182
{2DA40575-4748-4198-BE57-F4AF070DE8E3} = {71DDEE7B-E213-4E39-A7F4-4646783A27F7}
177183
{89D3D817-CCFE-4933-9089-D1283F2EA1B5} = {71DDEE7B-E213-4E39-A7F4-4646783A27F7}
178184
{918E4DE3-A7BF-4B7F-9B5A-5C36FEFA3C30} = {71DDEE7B-E213-4E39-A7F4-4646783A27F7}
185+
{94CF906E-35A1-4C68-8346-01BC7FE9470A} = {71DDEE7B-E213-4E39-A7F4-4646783A27F7}
179186
EndGlobalSection
180187
GlobalSection(ExtensibilityGlobals) = postSolution
181188
SolutionGuid = {DC0D56C8-D8CB-45CE-B528-F3DCF86D63ED}

src/WorkflowManager/Controllers/WorkflowsController.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,46 @@ public async Task<IActionResult> CreateAsync([FromBody] Workflow workflow)
8888
return Problem($"Unexpected error occured: {e.Message}", $"/workflows", 500);
8989
}
9090
}
91+
92+
/// <summary>
93+
/// Updates a workflow and creates a new revision
94+
/// </summary>
95+
/// <param name="workflow">The Workflow.</param>
96+
/// <returns>The ID of the created Workflow.</returns>
97+
[Route("{id}")]
98+
[HttpPut]
99+
public async Task<IActionResult> UpdateAsync([FromBody] Workflow workflow, [FromRoute] string id)
100+
{
101+
if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out _))
102+
{
103+
this._logger.LogDebug($"{nameof(UpdateAsync)} - Failed to validate {nameof(id)}");
104+
105+
return Problem($"Failed to validate {nameof(id)}, not a valid guid", $"/workflows/{id}", 400);
106+
}
107+
108+
if (!workflow.IsValid(out var validationErrors))
109+
{
110+
this._logger.LogDebug($"{nameof(UpdateAsync)} - Failed to validate {nameof(workflow)}: {validationErrors}");
111+
112+
return Problem($"Failed to validate {nameof(workflow)}: {string.Join(", ", validationErrors)}", $"/workflows/{id}", 400);
113+
}
114+
115+
try
116+
{
117+
var workflowId = await _workflowService.UpdateAsync(workflow, id);
118+
119+
if (workflowId == null)
120+
{
121+
this._logger.LogDebug($"{nameof(UpdateAsync)} - Failed to find workflow with Id: {id}");
122+
123+
return NotFound($"Faild to find workflow with Id: {id}");
124+
}
125+
126+
return StatusCode(StatusCodes.Status201Created, new CreateWorkflowResponse(workflowId));
127+
}
128+
catch (Exception e)
129+
{
130+
return Problem($"Unexpected error occured: {e.Message}", $"/workflows", 500);
131+
}
132+
}
91133
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
13+
<PackageReference Include="Moq" Version="4.17.2" />
14+
<PackageReference Include="xunit" Version="2.4.1" />
15+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
16+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
17+
<PrivateAssets>all</PrivateAssets>
18+
</PackageReference>
19+
<PackageReference Include="coverlet.collector" Version="3.1.2">
20+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
21+
<PrivateAssets>all</PrivateAssets>
22+
</PackageReference>
23+
</ItemGroup>
24+
25+
<ItemGroup>
26+
<ProjectReference Include="..\..\..\src\Common\Monai.Deploy.WorkflowManager.Common.csproj" />
27+
</ItemGroup>
28+
29+
</Project>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// SPDX-FileCopyrightText: © 2021-2022 MONAI Consortium
2+
// SPDX-License-Identifier: Apache License 2.0
3+
4+
using Monai.Deploy.WorkflowManager.Common.Interfaces;
5+
using Monai.Deploy.WorkflowManager.Common.Services;
6+
using Monai.Deploy.WorkflowManager.Contracts.Models;
7+
using Monai.Deploy.WorkflowManager.Database.Interfaces;
8+
using Moq;
9+
using Xunit;
10+
11+
namespace Monai.Deploy.WorkflowManger.Common.Tests.Services
12+
{
13+
public class WorkflowServiceTests
14+
{
15+
private IWorkflowService WorkflowService { get; set; }
16+
17+
private readonly Mock<IWorkflowRepository> _workflowRepository;
18+
19+
public WorkflowServiceTests()
20+
{
21+
_workflowRepository = new Mock<IWorkflowRepository>();
22+
23+
WorkflowService = new WorkflowService(_workflowRepository.Object);
24+
}
25+
26+
[Fact]
27+
public async Task WorkflowService_NullWorkflow_ThrowsException()
28+
{
29+
await Assert.ThrowsAsync<ArgumentNullException>(() => WorkflowService.UpdateAsync(null, null));
30+
}
31+
32+
[Fact]
33+
public async Task WorkflowService_NoExistingWorkflow_ReturnsNull()
34+
{
35+
var result = await WorkflowService.UpdateAsync(new Workflow(), Guid.NewGuid().ToString());
36+
37+
Assert.Null(result);
38+
}
39+
40+
[Fact]
41+
public async Task WorkflowService_WorkflowExists_ReturnsWorkflowId()
42+
{
43+
var workflowRevision = new WorkflowRevision
44+
{
45+
Id = Guid.NewGuid().ToString(),
46+
WorkflowId = Guid.NewGuid().ToString(),
47+
Revision = 1,
48+
Workflow = new Workflow
49+
{
50+
Name = "Workflowname1",
51+
Description = "Workflowdesc1",
52+
Version = "1",
53+
InformaticsGateway = new InformaticsGateway
54+
{
55+
AeTitle = "aetitle"
56+
},
57+
Tasks = new TaskObject[]
58+
{
59+
new TaskObject {
60+
Id = Guid.NewGuid().ToString(),
61+
Type = "type",
62+
Description = "taskdesc"
63+
}
64+
}
65+
}
66+
};
67+
68+
_workflowRepository.Setup(w => w.GetByWorkflowIdAsync(workflowRevision.WorkflowId)).ReturnsAsync(workflowRevision);
69+
_workflowRepository.Setup(w => w.UpdateAsync(It.IsAny<Workflow>(), workflowRevision)).ReturnsAsync(workflowRevision.WorkflowId);
70+
71+
var result = await WorkflowService.UpdateAsync(new Workflow(), workflowRevision.WorkflowId);
72+
73+
Assert.Equal(workflowRevision.WorkflowId, result);
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)