public override async Task Execute(CommandModel commandModel) { try { if (!(commandModel is CommandPurgePreservation)) { _logger.Error($"Command is not of type {nameof(CommandPurgePreservation)}"); await SendNotification(commandModel.ReferenceId, "E' avvenuto un errore durante la gestione del comando di pulizia storage", NotifyLevel.Error, true); return; } CommandPurgePreservation @command = commandModel as CommandPurgePreservation; _logger.Info($"Process command {command.Id} with preservation id {command.IdPreservation}"); await SendNotification(command.ReferenceId, "Inizio attività di pulizia archivio corrente degli elementi conservati", NotifyLevel.Info); if (command.IdPreservation == Guid.Empty) { _logger.Error($"Preservation reference not setted for command {command.Id}"); await SendNotification(command.ReferenceId, "E' avvenuto un errore durante la gestione del comando di pulizia archivio corrente", NotifyLevel.Error, true); return; } if (string.IsNullOrEmpty(command.Executor)) { _logger.Error($"Process executor not setted for command {command.Id}"); await SendNotification(command.ReferenceId, "E' avvenuto un errore durante la gestione del comando di pulizia archivio corrente", NotifyLevel.Error, true); return; } Preservation preservation = _preservationService.GetPreservation(command.IdPreservation, false); if (preservation == null) { _logger.Error($"Preservation {command.IdPreservation} not found"); await SendNotification(command.ReferenceId, $"Nessuna conservazione trovata con id {command.IdPreservation}", NotifyLevel.Error, true); return; } if (!preservation.CloseDate.HasValue) { _logger.Error($"Preservation {command.IdPreservation} is not closed. Please close preservation before execute this task."); await SendNotification(command.ReferenceId, $"Non è possibile procedere alla pulizia dell'archivio corrente di una conservazione non chiusa", NotifyLevel.Error, true); return; } Logging.AddLog(LoggingOperationType.BiblosDS_General, preservation.IdArchive, Guid.Empty, preservation.IdPreservation, $"Attività di pulizia storage per la conservazione {preservation.IdPreservation} richiesta dall'utente {command.Executor}", command.Executor); int preservedDocumentsCount = _preservationService.CountPreservationDocumentsToPurge(command.IdPreservation); _logger.Info($"Found {preservedDocumentsCount} to process"); if (preservedDocumentsCount == 0) { await SendNotification(command.ReferenceId, $"Nessun documento trovato per la conservazione {command.IdPreservation}", NotifyLevel.Info, true); return; } await SendNotification(command.ReferenceId, $"Trovati {preservedDocumentsCount} documenti da eliminare dall'archivio corrente", NotifyLevel.Info); int processedItems = 0; decimal pulsePercentageLimit = 20; decimal percentage; EntityProvider entityProvider; await SendNotification(command.ReferenceId, $"Inizio cancellazione documenti, l'attività può richiedere alcuni minuti", NotifyLevel.Info); Status statusToChange = new Status(DocumentStatus.MovedToPreservation); ICollection <Document> preservedDocuments = _preservationService.GetPreservationDocumentsToPurge(command.IdPreservation); string documentPath = string.Empty; bool hasMoveErrors = false; foreach (Document document in preservedDocuments) { processedItems++; _logger.Info($"Process document {document.IdDocument}"); documentPath = DocumentService.GetPreservationDocumentPath(document); _logger.Info($"Document {document.IdDocument} with preservation path: {documentPath}"); if (string.IsNullOrEmpty(documentPath)) { _logger.Info($"Document {document.IdDocument} hasn't preservation path defined. Document skipped"); await SendNotification(command.ReferenceId, $"Il documento {document.IdDocument} non ha l'indicazione del percorso di conservazione e pertanto non può essere eliminato dall'archivio corrente", NotifyLevel.Error); continue; } if (!File.Exists(documentPath)) { _logger.Info($"File {documentPath} not found on disk for document {document.IdDocument}"); await SendNotification(command.ReferenceId, $"Il documento {document.IdDocument} non esiste nel percorso di conservazione {documentPath}", NotifyLevel.Error); continue; } entityProvider = new EntityProvider(); using (IDbTransaction transaction = entityProvider.BeginNoSave()) { try { _logger.Info($"Document {document.IdDocument} -> change document state to {DocumentStatus.MovedToPreservation.ToString()}"); entityProvider.UpdateDocumentStatus(document, statusToChange); entityProvider.SaveChanges(); _logger.Info($"Document {document.IdDocument} -> delete document from storage"); _storageService.DeleteDocument(document, false); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); _logger.Info($"Error on delete document {document.IdDocument} from storage. Document skipped.", ex); hasMoveErrors = true; } } percentage = ((decimal)processedItems / preservedDocumentsCount) * 100.0m; if (Math.Ceiling(percentage) > pulsePercentageLimit) { await SendNotification(command.ReferenceId, $"Pulizia documenti nell'archivio corrente ({pulsePercentageLimit}%).", NotifyLevel.Info); pulsePercentageLimit += 20; } } string completeMessage = $"Il processo di pulizia archivio corrente per la conservazione {command.IdPreservation} è terminato correttamente."; if (hasMoveErrors) { completeMessage = $"Il processo di pulizia archivio corrente per la conservazione {command.IdPreservation} è terminato con errori. Verificare il file di log per ulteriori dettagli."; } await SendNotification(command.ReferenceId, completeMessage, hasMoveErrors?NotifyLevel.Error : NotifyLevel.Info, true); } catch (Exception ex) { _logger.Error($"Error on purge preservation", ex); await SendNotification(commandModel.ReferenceId, $"E' avvenuto un errore durante l'esecuzione dell'attività corrente", NotifyLevel.Error, true); } }