1515 */
1616
1717using Ardalis . GuardClauses ;
18+ using Microsoft . Extensions . DependencyInjection ;
1819using Microsoft . Extensions . Logging ;
1920using Monai . Deploy . Messaging . Events ;
21+ using Monai . Deploy . Storage . API ;
22+ using Monai . Deploy . WorkflowManager . Common . Exceptions ;
2023using Monai . Deploy . WorkflowManager . Common . Interfaces ;
2124using Monai . Deploy . WorkflowManager . Contracts . Models ;
2225using Monai . Deploy . WorkflowManager . Database . Interfaces ;
@@ -27,17 +30,28 @@ namespace Monai.Deploy.WorkflowManager.Common.Services
2730{
2831 public class PayloadService : IPayloadService
2932 {
30- private readonly IPayloadRepsitory _payloadRepsitory ;
33+ private readonly IPayloadRepsitory _payloadRepository ;
3134
3235 private readonly IDicomService _dicomService ;
3336
37+ private readonly IStorageService _storageService ;
38+
3439 private readonly ILogger < PayloadService > _logger ;
3540
36- public PayloadService ( IPayloadRepsitory payloadRepsitory , IDicomService dicomService , ILogger < PayloadService > logger )
41+ public PayloadService (
42+ IPayloadRepsitory payloadRepsitory ,
43+ IDicomService dicomService ,
44+ IServiceScopeFactory serviceScopeFactory ,
45+ ILogger < PayloadService > logger )
3746 {
38- _payloadRepsitory = payloadRepsitory ?? throw new ArgumentNullException ( nameof ( payloadRepsitory ) ) ;
47+ _payloadRepository = payloadRepsitory ?? throw new ArgumentNullException ( nameof ( payloadRepsitory ) ) ;
3948 _dicomService = dicomService ?? throw new ArgumentNullException ( nameof ( dicomService ) ) ;
4049 _logger = logger ?? throw new ArgumentNullException ( nameof ( logger ) ) ;
50+
51+ var _serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException ( nameof ( serviceScopeFactory ) ) ;
52+ var scope = _serviceScopeFactory . CreateScope ( ) ;
53+
54+ _storageService = scope . ServiceProvider . GetService < IStorageService > ( ) ?? throw new ArgumentNullException ( nameof ( IStorageService ) ) ;
4155 }
4256
4357 public async Task < Payload ? > CreateAsync ( WorkflowRequestEvent eventPayload )
@@ -70,7 +84,7 @@ public PayloadService(IPayloadRepsitory payloadRepsitory, IDicomService dicomSer
7084 PatientDetails = patientDetails
7185 } ;
7286
73- if ( await _payloadRepsitory . CreateAsync ( payload ) )
87+ if ( await _payloadRepository . CreateAsync ( payload ) )
7488 {
7589 _logger . PayloadCreated ( payload . Id ) ;
7690 return payload ;
@@ -92,23 +106,67 @@ public async Task<Payload> GetByIdAsync(string payloadId)
92106 {
93107 Guard . Against . NullOrWhiteSpace ( payloadId ) ;
94108
95- return await _payloadRepsitory . GetByIdAsync ( payloadId ) ;
109+ return await _payloadRepository . GetByIdAsync ( payloadId ) ;
96110 }
97111
98112 public async Task < IList < Payload > > GetAllAsync ( int ? skip = null ,
99113 int ? limit = null ,
100114 string ? patientId = "" ,
101115 string ? patientName = "" )
102- => await _payloadRepsitory . GetAllAsync ( skip , limit , patientId , patientName ) ;
116+ => await _payloadRepository . GetAllAsync ( skip , limit , patientId , patientName ) ;
103117
104118 public async Task < IList < Payload > > GetAllAsync ( int ? skip = null , int ? limit = null )
105- => await _payloadRepsitory . GetAllAsync ( skip , limit ) ;
119+ => await _payloadRepository . GetAllAsync ( skip , limit ) ;
120+
121+ public async Task < long > CountAsync ( ) => await _payloadRepository . CountAsync ( ) ;
122+
123+ public async Task < bool > DeletePayloadFromStorageAsync ( string payloadId )
124+ {
125+ Guard . Against . NullOrWhiteSpace ( payloadId ) ;
126+
127+ var payload = await GetByIdAsync ( payloadId ) ;
128+
129+ if ( payload is null )
130+ {
131+ throw new MonaiNotFoundException ( $ "Payload with ID: { payloadId } not found") ;
132+ }
133+
134+ if ( payload . PayloadDeleted == PayloadDeleted . InProgress )
135+ {
136+ throw new MonaiBadRequestException ( $ "Deletion of files for payload ID: { payloadId } already in progress") ;
137+ }
138+
139+ // update the payload to in progress before we request deletion form MinIO
140+ payload . PayloadDeleted = PayloadDeleted . InProgress ;
141+ await _payloadRepository . UpdateAsync ( payload ) ;
142+
143+ // run deletion in alternative thread so the user isn't held up
144+ #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
145+ Task . Run ( async ( ) =>
146+ {
147+ try
148+ {
149+ await _storageService . RemoveObjectsAsync ( payload . Bucket , payload . Files . Select ( f => f . Path ) ) ;
150+ payload . PayloadDeleted = PayloadDeleted . Yes ;
151+ }
152+ catch
153+ {
154+ _logger . PayloadUpdateFailed ( payloadId ) ;
155+ payload . PayloadDeleted = PayloadDeleted . Failed ;
156+ }
157+ finally
158+ {
159+ await _payloadRepository . UpdateAsync ( payload ) ;
160+ }
161+ } ) ;
162+ #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
106163
107- public async Task < long > CountAsync ( ) => await _payloadRepsitory . CountAsync ( ) ;
164+ return true ;
165+ }
108166
109167 public async Task < bool > UpdateWorkflowInstanceIdsAsync ( string payloadId , IEnumerable < string > workflowInstances )
110168 {
111- if ( await _payloadRepsitory . UpdateAssociatedWorkflowInstancesAsync ( payloadId , workflowInstances ) )
169+ if ( await _payloadRepository . UpdateAssociatedWorkflowInstancesAsync ( payloadId , workflowInstances ) )
112170 {
113171 _logger . PayloadUpdated ( payloadId ) ;
114172 return true ;
0 commit comments