From 94b3eab8e566f16a9b20cc655615b5bc128c8cca Mon Sep 17 00:00:00 2001 From: jazairi <16103405+jazairi@users.noreply.github.com> Date: Thu, 9 Nov 2023 13:19:47 -0500 Subject: [PATCH] Add report emails to preservation workflow Why these changes are being introduced: We found a bug in the preservation workflow last month that we might have identified sooner if the preservation submission job triggered a report email. Relevant ticket(s): https://mitlibraries.atlassian.net/browse/ETD-651 How this addresses that need: * Removes the Preservation Submission Prep Job * Updates the Preservation Submission Job to accept an array of theses * Adds a preservation results email to the Report Mailer that is enqueued on completion of the Preservation Submission Job * Updates the preservation rake task to convert the input thesis into an array, so it will continue to work Side effects of this change: We not sure why we implemented the 'prep' job pattern: passing in an array of theses so the actual job takes a single thesis as a parameter. There is some risk in removing this job, since we don't remember why it exists in the first place. --- app/jobs/dspace_publication_results_job.rb | 2 +- app/jobs/preservation_submission_job.rb | 26 +++++++++++------ app/jobs/preservation_submission_prep_job.rb | 11 -------- app/mailers/report_mailer.rb | 10 +++++++ .../preservation_results_email.html.erb | 21 ++++++++++++++ lib/tasks/preservation.rake | 2 +- .../dspace_publication_results_job_test.rb | 2 +- .../preservation_submission_job_prep_test.rb | 28 ------------------- test/jobs/preservation_submission_job_test.rb | 22 +++++++++++---- test/mailers/report_mailer_test.rb | 19 +++++++++++++ 10 files changed, 87 insertions(+), 56 deletions(-) delete mode 100644 app/jobs/preservation_submission_prep_job.rb create mode 100644 app/views/report_mailer/preservation_results_email.html.erb delete mode 100644 test/jobs/preservation_submission_job_prep_test.rb diff --git a/app/jobs/dspace_publication_results_job.rb b/app/jobs/dspace_publication_results_job.rb index 91a09cee..d4dbee7f 100644 --- a/app/jobs/dspace_publication_results_job.rb +++ b/app/jobs/dspace_publication_results_job.rb @@ -19,7 +19,7 @@ def perform results[:errors] << "Error reading from SQS queue: #{e}" end - PreservationSubmissionPrepJob.perform_later(results[:preservation_ready]) if results[:preservation_ready].any? + PreservationSubmissionJob.perform_later(results[:preservation_ready]) if results[:preservation_ready].any? MarcExportJob.perform_later(results[:marc_exports]) if results[:marc_exports].any? ReportMailer.publication_results_email(results).deliver_now if results[:total].positive? || results[:errors].any? diff --git a/app/jobs/preservation_submission_job.rb b/app/jobs/preservation_submission_job.rb index 4c615ec5..053a1575 100644 --- a/app/jobs/preservation_submission_job.rb +++ b/app/jobs/preservation_submission_job.rb @@ -1,15 +1,23 @@ class PreservationSubmissionJob < ActiveJob::Base queue_as :default - def perform(thesis) - Rails.logger.info("Thesis #{thesis.id} is now being prepared for preservation") - sip = thesis.submission_information_packages.create - preserve_sip(sip) - Rails.logger.info("Thesis #{thesis.id} has been sent to preservation") - rescue StandardError, Aws::Errors => e - Rails.logger.info("Thesis #{thesis.id} could not be preserved: #{e}") - sip.preservation_status = 'error' - sip.save + def perform(theses) + Rails.logger.info("Preparing to send #{theses.count} theses to preservation") + results = { total: theses.count, processed: 0, errors: [] } + theses.each do |thesis| + Rails.logger.info("Thesis #{thesis.id} is now being prepared for preservation") + sip = thesis.submission_information_packages.create + preserve_sip(sip) + Rails.logger.info("Thesis #{thesis.id} has been sent to preservation") + results[:processed] += 1 + rescue StandardError, Aws::Errors => e + preservation_error = "Thesis #{thesis.id} could not be preserved: #{e}" + Rails.logger.info(preservation_error) + sip.preservation_status = 'error' + sip.save + results[:errors] << preservation_error + end + ReportMailer.preservation_results_email(results).deliver_now if results[:total].positive? end private diff --git a/app/jobs/preservation_submission_prep_job.rb b/app/jobs/preservation_submission_prep_job.rb deleted file mode 100644 index da9a2da4..00000000 --- a/app/jobs/preservation_submission_prep_job.rb +++ /dev/null @@ -1,11 +0,0 @@ -class PreservationSubmissionPrepJob < ActiveJob::Base - queue_as :default - - def perform(theses) - Rails.logger.info("Preparing to send #{theses.count} theses to preservation") - - theses.each do |thesis| - PreservationSubmissionJob.perform_later(thesis) - end - end -end diff --git a/app/mailers/report_mailer.rb b/app/mailers/report_mailer.rb index 8b12b7ce..9b15344f 100644 --- a/app/mailers/report_mailer.rb +++ b/app/mailers/report_mailer.rb @@ -19,4 +19,14 @@ def publication_results_email(results) cc: ENV['MAINTAINER_EMAIL'], subject: 'DSpace publication results summary') end + + def preservation_results_email(results) + return unless ENV.fetch('DISABLE_ALL_EMAIL', 'true') == 'false' # allows PR builds to disable emails + + @results = results + mail(from: "MIT Libraries <#{ENV['ETD_APP_EMAIL']}>", + to: ENV['THESIS_ADMIN_EMAIL'], + cc: ENV['MAINTAINER_EMAIL'], + subject: 'Archivematica preservation submission results summary') + end end diff --git a/app/views/report_mailer/preservation_results_email.html.erb b/app/views/report_mailer/preservation_results_email.html.erb new file mode 100644 index 00000000..17107077 --- /dev/null +++ b/app/views/report_mailer/preservation_results_email.html.erb @@ -0,0 +1,21 @@ +

Hello,

+ +

Below is a report of the Archivematica preservation submission job.

+ +

Summary of results:

+ + + +<% if @results[:errors].any? %> +

The following errors require processor attention:

+ + +<% end %> diff --git a/lib/tasks/preservation.rake b/lib/tasks/preservation.rake index 1edb8cf6..7a256cbc 100644 --- a/lib/tasks/preservation.rake +++ b/lib/tasks/preservation.rake @@ -8,7 +8,7 @@ namespace :preservation do # Only published theses may be sent to preservation. We already check for this in SubmissionInformationPackage # validations, but double-checking here to save potential confusion. if thesis.publication_status == 'Published' - PreservationSubmissionJob.perform_now(thesis) + PreservationSubmissionJob.perform_now([thesis]) else Rails.logger.info("Thesis status of #{thesis.publication_status} cannot be preserved.") end diff --git a/test/jobs/dspace_publication_results_job_test.rb b/test/jobs/dspace_publication_results_job_test.rb index 6e1627f7..ed735ac8 100644 --- a/test/jobs/dspace_publication_results_job_test.rb +++ b/test/jobs/dspace_publication_results_job_test.rb @@ -182,7 +182,7 @@ def teardown end test 'enqueues preservation submission prep job' do - assert_enqueued_with(job: PreservationSubmissionPrepJob) do + assert_enqueued_with(job: PreservationSubmissionJob) do DspacePublicationResultsJob.perform_now end end diff --git a/test/jobs/preservation_submission_job_prep_test.rb b/test/jobs/preservation_submission_job_prep_test.rb deleted file mode 100644 index 3ed7e553..00000000 --- a/test/jobs/preservation_submission_job_prep_test.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'test_helper' - -class PreservationSubmissionPrepJobTest < ActiveJob::TestCase - - test 'queues 1 job for 1 thesis' do - theses = [theses(:one)].to_a - - assert_enqueued_jobs 1 do - PreservationSubmissionPrepJob.perform_now(theses) - end - end - - test 'queues 2 jobs for 2 theses' do - theses = [theses(:one), theses(:two)].to_a - - assert_enqueued_jobs 2 do - PreservationSubmissionPrepJob.perform_now(theses) - end - end - - test 'queues same number of theses it receives' do - theses = Thesis.in_review.to_a - - assert_enqueued_jobs theses.count do - PreservationSubmissionPrepJob.perform_now(theses) - end - end -end diff --git a/test/jobs/preservation_submission_job_test.rb b/test/jobs/preservation_submission_job_test.rb index 315d7f04..5da19745 100644 --- a/test/jobs/preservation_submission_job_test.rb +++ b/test/jobs/preservation_submission_job_test.rb @@ -16,17 +16,29 @@ def setup_thesis thesis end + test 'sends report emails' do + ClimateControl.modify DISABLE_ALL_EMAIL: 'false' do + assert_difference('ActionMailer::Base.deliveries.size', 1) do + PreservationSubmissionJob.perform_now([setup_thesis]) + end + end + end + test 'creates a SIP' do thesis = setup_thesis assert_equal 0, thesis.submission_information_packages.count - PreservationSubmissionJob.perform_now(thesis) + PreservationSubmissionJob.perform_now([thesis]) assert_equal 1, thesis.submission_information_packages.count end + test 'creates multiple SIPs' do + theses = [setup_thesis, theses(:published)] + end + test 'updates preservation_status to "preserved" after successfully processing a thesis' do thesis = setup_thesis - PreservationSubmissionJob.perform_now(thesis) + PreservationSubmissionJob.perform_now([thesis]) assert_equal 'preserved', thesis.submission_information_packages.last.preservation_status end @@ -34,20 +46,20 @@ def setup_thesis time = DateTime.new.getutc Timecop.freeze(time) do thesis = setup_thesis - PreservationSubmissionJob.perform_now(thesis) + PreservationSubmissionJob.perform_now([thesis]) assert_equal time, thesis.submission_information_packages.last.preserved_at end end test 'rescues exceptions by updating preservation_status to "error"' do thesis = theses(:one) - PreservationSubmissionJob.perform_now(thesis) + PreservationSubmissionJob.perform_now([thesis]) assert_equal 'error', thesis.submission_information_packages.last.preservation_status end test 'does not update preserved_at if the job enters an error state' do thesis = theses(:one) - PreservationSubmissionJob.perform_now(thesis) + PreservationSubmissionJob.perform_now([thesis]) assert_nil thesis.submission_information_packages.last.preserved_at end end diff --git a/test/mailers/report_mailer_test.rb b/test/mailers/report_mailer_test.rb index 5759055f..e0ab2370 100644 --- a/test/mailers/report_mailer_test.rb +++ b/test/mailers/report_mailer_test.rb @@ -43,4 +43,23 @@ class ReportMailerTest < ActionMailer::TestCase assert_match 'Couldn't find Thesis with 'id'=9999999999999', email.body.to_s end end + + test 'sends reports for preservation submission results' do + ClimateControl.modify DISABLE_ALL_EMAIL: 'false' do + results = { total: 2, processed: 1, errors: ["Couldn't find Thesis with 'id'=9999999999999"] } + email = ReportMailer.preservation_results_email(results) + + assert_emails 1 do + email.deliver_now + end + + assert_equal ['app@example.com'], email.from + assert_equal ['test@example.com'], email.to + assert_equal 'Archivematica preservation submission results summary', email.subject.to_s + assert_match 'Total theses queued for preservation: 2', email.body.to_s + assert_match 'Total theses sent to preservation: 1', email.body.to_s + assert_match 'Errors found: 1', email.body.to_s + assert_match 'Couldn't find Thesis with 'id'=9999999999999', email.body.to_s + end + end end