Beispiel #1
0
        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);
        }
Beispiel #2
0
        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()));
        }
Beispiel #4
0
        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);
        }