Skip to content

Commit e9e4eca

Browse files
JaymeeHbesscarolyncoleleefaisonrjrgriffiniii
authored
Tigerdata Refactor: User Requests (#780)
* New Model for UserRequests * refactoring the job id on a user request to be a uuid instead of an integer * creating file inventory request and activate project requests as child classes of user request * Rename job to FileInventoryJob to match FileInventoryRequest * Delete unused rake tasks and refactor the job scheduler to run the inventory cleanup daily Co-authored-by: Bess Sadler <[email protected]> Co-authored-by: Carolyn Cole <[email protected]> Co-authored-by: Jaymee Hyppolite <[email protected]> Co-authored-by: Robert-Anthony Lee-Faison <[email protected]> Co-authored-by: James R. Griffin III <[email protected]>
1 parent 12c4376 commit e9e4eca

21 files changed

+301
-207
lines changed

app/jobs/activate_project_job.rb

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ class ActivateProjectJob < ApplicationJob
44
def perform(user:, project_id:)
55
project = Project.find(project_id)
66
raise "Invalid project id #{project_id} for job #{job_id}" if project.nil?
7-
collection_id = project.metadata_json["project_id"]
7+
#The id of the project in mediaflux is the collection id, and mediaflux id is what we refer to the collection id in rails
8+
collection_id = project.mediaflux_id
89
project_metadata = project.metadata_model
910

1011
# ACTIVATE THE PROJECT IF THE DOI IN RAILS AND MF MATCH
@@ -25,20 +26,11 @@ def perform(user:, project_id:)
2526
project_metadata: project.metadata
2627
}
2728
Honeybadger.notify(activation_failure_msg, context: honeybadger_context)
28-
29-
mark_user_job_as_complete(project: project, user: user)
3029
end
3130

3231
private
3332
def mediaflux_session
3433
logon_request = Mediaflux::Http::LogonRequest.new
3534
logon_request.session_token
3635
end
37-
38-
def mark_user_job_as_complete(project:, user:)
39-
user_job = UserJob.create_and_link_to_user(job_id: job_id, user: user, job_title: "Project Activation for #{project.title}")
40-
user_job.completed_at = Time.current.in_time_zone("America/New_York").iso8601
41-
user_job.save!
42-
user_job.reload
43-
end
4436
end

app/jobs/delete_user_job.rb

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# frozen_string_literal: true
2+
class FileInventoryCleanupJob < ApplicationJob
3+
queue_as :default
4+
5+
def perform
6+
FileInventoryRequest.where(["completion_time < ?", 7.days.ago]).each do |req|
7+
File.delete(req.output_file) if File.exist?(req.output_file)
8+
req.state = UserRequest::STALE
9+
req.save
10+
end
11+
end
12+
end
Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
# frozen_string_literal: true
2-
class ListProjectContentsJob < ApplicationJob
3-
after_perform do |job|
4-
uid = job.arguments.first[:user_id]
5-
DeleteUserJob.set(wait: 1.week).perform_later(job_id: job_id, user_id: uid)
6-
end
7-
2+
class FileInventoryJob < ApplicationJob
83
def perform(user_id:, project_id:)
94
project = Project.find(project_id)
105
raise "Invalid project id #{project_id} for job #{job_id}" if project.nil?
116
user = User.find(user_id)
127
raise "Invalid user id #{user_id} for job #{job_id}" if user.nil?
8+
Rails.logger.debug inspect
139

1410
# Queries Mediaflux for the file list and saves it to a CSV file.
1511
filename = filename_for_export
1612
Rails.logger.info "Exporting file list to #{filename} for project #{project_id}"
1713
project.file_list_to_file(session_id: mediaflux_session, filename: filename)
1814
Rails.logger.info "Export file generated #{filename} for project #{project_id}"
1915

20-
mark_user_job_as_complete(project: project, user: user)
16+
# Make the FileInventoryRequest object
17+
# TODO: Figure out what request_details should have.
18+
FileInventoryRequest.create(user_id: user.id, project_id: project.id, job_id: @job_id, state: UserRequest::PENDING, request_details: { output_file: filename, project_title: project.title },
19+
completion_time: Time.current.in_time_zone("America/New_York"))
2120
end
2221

2322
private
@@ -32,11 +31,4 @@ def filename_for_export
3231
pathname = Pathname.new(Rails.configuration.mediaflux["shared_files_location"])
3332
pathname.join("#{job_id}.csv").to_s
3433
end
35-
36-
def mark_user_job_as_complete(project:, user:)
37-
user_job = UserJob.create_and_link_to_user(job_id: job_id, user: user, job_title: "File list for #{project.title}")
38-
user_job.completed_at = Time.current.in_time_zone("America/New_York").iso8601
39-
user_job.save!
40-
user_job.reload
41-
end
4234
end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# frozen_string_literal: true
2+
class ActivateProjectRequest < UserRequest
3+
end

app/models/file_inventory_request.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# frozen_string_literal: true
2+
class FileInventoryRequest < UserRequest
3+
def output_file
4+
request_details["output_file"]
5+
end
6+
end

app/models/project.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ def file_list_to_file(session_id:, filename:)
204204
query_req = Mediaflux::Http::QueryRequest.new(session_token: session_id, collection: mediaflux_id, deep_search: true)
205205
iterator_id = query_req.result
206206

207+
207208
File.open(filename, "w") do |file|
208209
# file header
209210
file.write("ID, PATH, NAME, COLLECTION?, LAST_MODIFIED, SIZE\r\n")

app/models/user_request.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
class UserRequest < ApplicationRecord
3+
belongs_to :user
4+
belongs_to :project
5+
6+
PENDING = "pending"
7+
COMPLETED = "completed"
8+
STALE = "stale"
9+
10+
validates :state, inclusion: { in: [PENDING, COMPLETED, STALE] }
11+
end

app/services/project_job_service.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def initialize(project:)
66
end
77

88
def list_contents_job(user:)
9-
job = ListProjectContentsJob.perform_later(user_id: user.id, project_id: @project.id)
9+
job = FileInventoryJob.perform_later(user_id: user.id, project_id: @project.id)
1010
# Log the job id and the Sidekiq JID in case we need to troubleshoot the job
1111
# https://github.com/sidekiq/sidekiq/wiki/Active-Job#job-id
1212
Rails.logger.info("Job scheduled, job id: #{job.job_id}, (Sidekiq JID: #{job.provider_job_id || 'nil'})")

config/schedule.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@
2121
# Learn more: http://github.com/javan/whenever
2222

2323
every 1.day do
24-
rake "exports:delete_old"
24+
FileInventoryCleanupJob.perform_later
2525
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class CreateUserRequests < ActiveRecord::Migration[7.0]
2+
def change
3+
create_table :user_requests do |t|
4+
t.integer :user_id
5+
t.integer :project_id
6+
t.uuid :job_id
7+
t.datetime :completion_time
8+
t.string :state
9+
t.string :type
10+
t.jsonb :request_details
11+
12+
t.timestamps
13+
end
14+
end
15+
end

db/schema.rb

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/tasks/exports.rake

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,20 @@
11
# frozen_string_literal: true
22
require "rails_helper"
33

4-
RSpec.describe ActivateProjectJob, type: :job do
4+
RSpec.describe ActivateProjectJob, connect_to_mediaflux: true, type: :job do
55
let(:user) { FactoryBot.create(:user) }
6-
let(:sponsor_user) { FactoryBot.create(:project_sponsor, uid: "pul123") }
7-
let(:collection_id) { 1170 }
8-
let(:approved_project) { FactoryBot.create :project }
9-
let(:metadata) do
10-
{
11-
data_sponsor: sponsor_user.uid,
12-
data_manager: sponsor_user.uid,
13-
directory: "project-123",
14-
title: "project 123",
15-
departments: ["RDSS"],
16-
description: "hello world",
17-
status: ::Project::PENDING_STATUS
18-
}
19-
end
20-
let(:project_in_mediaflux) { FactoryBot.create(:project, mediaflux_id: 8888, metadata: metadata) }
6+
let(:project_in_mediaflux) { FactoryBot.create(:project_with_doi, status: Project::APPROVED_STATUS) }
217

8+
before do
9+
ProjectMediaflux.create!(session_id: user.mediaflux_session, project: project_in_mediaflux)
10+
end
2211

23-
describe "#perform_now", connect_to_mediaflux: true do
24-
it "updates the UserJob#completed_at attribute" do
25-
job = described_class.perform_now(user:, project_id: project_in_mediaflux.id)
26-
user_job = UserJob.where(job_id: job.job_id).first
27-
expect(user_job.completed_at).to_not be nil
12+
describe "#perform_now" do
13+
it "marks the state as active" do
14+
expect(project_in_mediaflux.status).to eq(Project::APPROVED_STATUS)
15+
described_class.perform_now(user: user, project_id: project_in_mediaflux.id)
16+
project_in_mediaflux.reload
17+
expect(project_in_mediaflux.status).to eq(Project::ACTIVE_STATUS)
2818
end
29-
3019
end
3120
end

spec/jobs/delete_user_job_spec.rb

Lines changed: 0 additions & 46 deletions
This file was deleted.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# frozen_string_literal: true
2+
require "rails_helper"
3+
4+
RSpec.describe FileInventoryCleanupJob, connect_to_mediaflux: true, type: :job do
5+
let(:user) { FactoryBot.create(:user) }
6+
let(:project_in_mediaflux) { FactoryBot.create(:project_with_doi) }
7+
let(:eight_days_ago) { Time.current.in_time_zone("America/New_York") - 8.days }
8+
9+
before do
10+
ProjectMediaflux.create!(session_id: user.mediaflux_session, project: project_in_mediaflux)
11+
end
12+
13+
describe "#perform_now" do
14+
it "deletes any files older than 7 days" do
15+
req = FileInventoryJob.perform_now(user_id: user.id, project_id: project_in_mediaflux.id)
16+
req.completion_time = eight_days_ago
17+
req.save
18+
19+
expect(File.exist?(req.output_file)).to be_truthy
20+
described_class.perform_now
21+
expect(File.exist?(req.output_file)).to be_falsey
22+
end
23+
24+
it "marks the file inventory request stale" do
25+
req = FileInventoryJob.perform_now(user_id: user.id, project_id: project_in_mediaflux.id)
26+
req.completion_time = eight_days_ago
27+
req.save
28+
29+
expect(req.state).to eq(UserRequest::PENDING)
30+
described_class.perform_now
31+
req.reload
32+
expect(req.state).to eq(UserRequest::STALE)
33+
end
34+
end
35+
end

0 commit comments

Comments
 (0)