private static void RenameAndArchive(ref string filePath, string prefix, string suffix, string extension, BulkActionUploadDto bulkActionUpload) { try { if (prefix.EndsWith(BulkActionConstants.Working, StringComparison.InvariantCultureIgnoreCase)) { var idx = prefix.LastIndexOf(BulkActionConstants.Working); prefix = prefix.Substring(0, idx); } RenameFile(ref filePath, prefix, suffix, extension); } catch (Exception ex) { logger.BulkActionError($"Upload succeeded, but failed to rename file: {ex.Message}"); } try { ArchiveFile(filePath, bulkActionUpload.FileArchiveDirectory, logger); } catch (Exception ex) { logger.BulkActionError($"Upload succeeded, but failed to archive file: {ex.Message}"); } }
public static void ProcessBulkAction(BulkActionUploadDto bulkActionUpload) { try { logger.BulkActionInfo("ProcessBulkAction enter"); DocumentManager manager = new DocumentManager(); // Check read/write permissions. if (!manager.ValidateDirectory(bulkActionUpload.FileUploadDirectory) || !manager.ValidateDirectory(bulkActionUpload.FileArchiveDirectory)) { NotificationService.ErrorNotification("Bulk Action", $"{bulkActionUpload.FileUploadDirectory} does not authorize read and write updates"); logger.BulkActionError($"{bulkActionUpload.FileUploadDirectory} does not authorize read and write updates"); throw new Exception($"{bulkActionUpload.FileUploadDirectory} does not authorize read and write updates"); } logger.BulkActionInfo($"Loading files from \"{bulkActionUpload.FileUploadDirectory}\"");// Get all files to process. string[] filesToProcess = Directory.GetFiles(bulkActionUpload.FileUploadDirectory) .Select(fileName => Path.Combine(bulkActionUpload.FileUploadDirectory, fileName)) .ToArray(); foreach (string f in filesToProcess) { var filePath = f; logger.BulkActionInfo($"Processing file \"{filePath}\""); try { var directory = Path.GetDirectoryName(filePath); var prefix = Path.Combine(directory, Path.GetFileNameWithoutExtension(filePath)); var extension = Path.GetExtension(filePath); //Note that while processing a file in the Upload directory, we rename it to provide for status //indication and also to help handle situations where archiving fails, or when the server resets. //1234.csv --> not yet processed. //1234.working.csv --> currently being processed, but not yet uploaded to student forms. //1234.complete.csv --> successfully uploaded to student forms //1234.failed.csv --> rejected by student forms if (prefix.EndsWith(BulkActionConstants.Working, StringComparison.InvariantCultureIgnoreCase)) { //This can happen if the server reset before we had an opportunity to fully upload the file. //Let's just reprocess. logger.Info($"Encountered a working file. Reprocessing: \"{filePath}\""); } else if (prefix.EndsWith(BulkActionConstants.Complete, StringComparison.InvariantCultureIgnoreCase) || prefix.EndsWith(BulkActionConstants.Failed, StringComparison.InvariantCultureIgnoreCase)) { try { logger.BulkActionInfo($"Encountered an already-processed file \"{filePath}\", attempting to archive"); ArchiveFile(filePath, bulkActionUpload.FileArchiveDirectory, logger); } catch (Exception ex) { logger.BulkActionError(ex); } //At this point, we're done processing the completed file - either with success or failure. Let's //continue on to the next file. continue; } else { //We've encountered a file that's ready for processing. We first rename it to .working to indicate that //the file is currently being processed. RenameFile(ref filePath, prefix, BulkActionConstants.Working, extension); } HttpResponseMessage result = Task.Run(() => manager.UploadBulkAction(bulkActionUpload, filePath)).Result; logger.BulkActionInfo($"Bulk action upload completed with {result.StatusCode}"); if (result.IsSuccessStatusCode) { //Rename the file to .complete and then attempt to archive it. RenameAndArchive(ref filePath, prefix, BulkActionConstants.Complete, extension, bulkActionUpload); } else { if (result.Content == null) { // Never hit the API...failed validation. throw new Exception(result.ReasonPhrase); } else { // Build error message to send to notitification service var importResult = Task.Run(() => result.Content.ReadAsAsync <ImportResult>()).Result; //Rename the file to .failed and then attempt to archive it. RenameAndArchive(ref filePath, prefix, BulkActionConstants.Failed, extension, bulkActionUpload); throw new Exception(FormatImportResultMessage(importResult, filePath)); } } } catch (Exception ex) { logger.BulkActionError(ex); try { logger.BulkActionInfo($"Attempting to send notification email to: \"{bulkActionUpload.NotificationEmail}\""); // what to do if a file fails... var response = Task.Run(() => notificationManager.SendErrorNotification("ProcessBulkAction", ex.Message, bulkActionUpload.NotificationEmail)).Result; if (response.SendCompleted.HasValue) { logger.BulkActionInfo("Send notification email completed without error"); } else { logger.BulkActionInfo("Send notification email failed"); } } catch (Exception ex2) { logger.BulkActionError($"Send notification email failed with error: \"{ex2.Message}\""); } } } } finally { logger.BulkActionInfo("ProcessBulkAction exit"); } }