public DeleteServiceTests() { _indexDataStore = Substitute.For <IIndexDataStore>(); _metadataStore = Substitute.For <IMetadataStore>(); _fileDataStore = Substitute.For <IFileStore>(); _deleteConfiguration = new DeletedInstanceCleanupConfiguration { DeleteDelay = TimeSpan.FromDays(1), BatchSize = 10, MaxRetries = 5, PollingInterval = TimeSpan.FromSeconds(1), RetryBackOff = TimeSpan.FromDays(4), }; IOptions <DeletedInstanceCleanupConfiguration> deletedInstanceCleanupConfigurationOptions = Substitute.For <IOptions <DeletedInstanceCleanupConfiguration> >(); deletedInstanceCleanupConfigurationOptions.Value.Returns(_deleteConfiguration); ITransactionHandler transactionHandler = Substitute.For <ITransactionHandler>(); _transactionScope = Substitute.For <ITransactionScope>(); transactionHandler.BeginTransaction().Returns(_transactionScope); _dicomRequestContextAccessor = Substitute.For <IDicomRequestContextAccessor>(); _dicomRequestContextAccessor.RequestContext.DataPartitionEntry = new PartitionEntry(DefaultPartition.Key, DefaultPartition.Name); _deleteService = new DeleteService(_indexDataStore, _metadataStore, _fileDataStore, deletedInstanceCleanupConfigurationOptions, transactionHandler, NullLogger <DeleteService> .Instance, _dicomRequestContextAccessor); }
public DeleteServiceTests() { _indexDataStore = Substitute.For <IIndexDataStore>(); _metadataStore = Substitute.For <IMetadataStore>(); _fileDataStore = Substitute.For <IFileStore>(); _indexDataStoreFactory = Substitute.For <IIndexDataStoreFactory>(); _deleteConfiguration = new DeletedInstanceCleanupConfiguration { DeleteDelay = TimeSpan.FromDays(1), BatchSize = 10, MaxRetries = 5, PollingInterval = TimeSpan.FromSeconds(1), RetryBackOff = TimeSpan.FromDays(4), }; IOptions <DeletedInstanceCleanupConfiguration> deletedInstanceCleanupConfigurationOptions = Substitute.For <IOptions <DeletedInstanceCleanupConfiguration> >(); deletedInstanceCleanupConfigurationOptions.Value.Returns(_deleteConfiguration); ITransactionHandler transactionHandler = Substitute.For <ITransactionHandler>(); _transactionScope = Substitute.For <ITransactionScope>(); transactionHandler.BeginTransaction().Returns(_transactionScope); _indexDataStoreFactory.GetInstance().Returns(_indexDataStore); _deleteService = new DeleteService(_indexDataStoreFactory, _metadataStore, _fileDataStore, deletedInstanceCleanupConfigurationOptions, transactionHandler, NullLogger <DeleteService> .Instance); }
private async Task <BundleResponse> ExecuteTransactionForAllRequests(Hl7.Fhir.Model.Bundle responseBundle) { try { using (var transaction = _transactionHandler.BeginTransaction()) { await ExecuteAllRequests(responseBundle); transaction.Complete(); } } catch (TransactionAbortedException) { _logger.LogError("Failed to commit a transaction. Throwing BadRequest as a default exception."); throw new TransactionFailedException(Api.Resources.GeneralTransactionFailedError, HttpStatusCode.BadRequest); } return(new BundleResponse(responseBundle.ToResourceElement())); }
public async Task <(bool success, int retrievedInstanceCount)> CleanupDeletedInstancesAsync(CancellationToken cancellationToken) { bool success = true; int retrievedInstanceCount = 0; using (ITransactionScope transactionScope = _transactionHandler.BeginTransaction()) { try { var deletedInstanceIdentifiers = (await _indexDataStore .RetrieveDeletedInstancesAsync( _deletedInstanceCleanupConfiguration.BatchSize, _deletedInstanceCleanupConfiguration.MaxRetries, cancellationToken)) .ToList(); retrievedInstanceCount = deletedInstanceIdentifiers.Count; foreach (VersionedInstanceIdentifier deletedInstanceIdentifier in deletedInstanceIdentifiers) { try { Task[] tasks = new[] { _fileStore.DeleteFileIfExistsAsync(deletedInstanceIdentifier, cancellationToken), _metadataStore.DeleteInstanceMetadataIfExistsAsync(deletedInstanceIdentifier, cancellationToken), }; await Task.WhenAll(tasks); await _indexDataStore.DeleteDeletedInstanceAsync(deletedInstanceIdentifier, cancellationToken); } catch (Exception cleanupException) { try { int newRetryCount = await _indexDataStore.IncrementDeletedInstanceRetryAsync(deletedInstanceIdentifier, GenerateCleanupAfter(_deletedInstanceCleanupConfiguration.RetryBackOff), cancellationToken); if (newRetryCount > _deletedInstanceCleanupConfiguration.MaxRetries) { _logger.LogCritical(cleanupException, "Failed to cleanup instance {deletedInstanceIdentifier}. Retry count is now {newRetryCount} and retry will not be re-attempted.", deletedInstanceIdentifier, newRetryCount); } else { _logger.LogError(cleanupException, "Failed to cleanup instance {deletedInstanceIdentifier}. Retry count is now {newRetryCount}.", deletedInstanceIdentifier, newRetryCount); } } catch (Exception incrementException) { _logger.LogCritical(incrementException, "Failed to increment cleanup retry for instance {deletedInstanceIdentifier}.", deletedInstanceIdentifier); success = false; } } } transactionScope.Complete(); } catch (Exception retrieveException) { _logger.LogCritical(retrieveException, "Failed to retrieve instances to cleanup."); success = false; } } return(success, retrievedInstanceCount); }