Skip to content

Commit

Permalink
Switch to new sdr-client interface
Browse files Browse the repository at this point in the history
  • Loading branch information
mjgiarlo committed Aug 19, 2024
1 parent cf54c59 commit bc8273f
Show file tree
Hide file tree
Showing 16 changed files with 145 additions and 274 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ gem 'dor-workflow-client'
gem 'reform', '~> 2.5.0'
gem 'reform-rails'
gem 'rubyzip', '~> 2.3'
gem 'sdr-client', '~> 2.14'
gem 'sdr-client', github: 'sul-dlss/sdr-client', branch: 'allow-collection-deposits' # '~> 2.14'
gem 'sidekiq', '~> 7.0'
gem 'sneakers', '~> 2.11' # rabbitMQ background processing
gem 'state_machines-activerecord'
Expand Down
24 changes: 15 additions & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
GIT
remote: https://github.com/sul-dlss/sdr-client.git
revision: 9ab9f873a70ad8d0a423a3a00e1e7ac3ed9c5282
branch: allow-collection-deposits
specs:
sdr-client (2.17.0)
activesupport
cocina-models (~> 0.99.0)
config
dry-monads
faraday (>= 0.16)
launchy
zeitwerk

GEM
remote: https://rubygems.org/
specs:
Expand Down Expand Up @@ -546,14 +560,6 @@ GEM
ruby-next-core (1.0.3)
ruby-progressbar (1.13.0)
rubyzip (2.3.2)
sdr-client (2.17.0)
activesupport
cocina-models (~> 0.99.0)
config
dry-monads
faraday (>= 0.16)
launchy
zeitwerk
selenium-webdriver (4.23.0)
base64 (~> 0.2)
logger (~> 1.4)
Expand Down Expand Up @@ -736,7 +742,7 @@ DEPENDENCIES
rubocop-rspec
rubocop-rspec_rails
rubyzip (~> 2.3)
sdr-client (~> 2.14)
sdr-client!
selenium-webdriver
sidekiq (~> 7.0)
simplecov
Expand Down
10 changes: 0 additions & 10 deletions app/jobs/base_deposit_job.rb

This file was deleted.

44 changes: 14 additions & 30 deletions app/jobs/deposit_collection_job.rb
Original file line number Diff line number Diff line change
@@ -1,42 +1,26 @@
# frozen_string_literal: true

# Deposits a Collection into SDR API.
class DepositCollectionJob < BaseDepositJob
class DepositCollectionJob < ApplicationJob
queue_as :default

def perform(collection_version)
deposit(request_dro: CocinaGenerator::CollectionGenerator.generate_model(collection_version:),
version_description: collection_version.version_description.presence)
rescue StandardError => e
Honeybadger.notify(e)
end

private

def deposit(request_dro:, version_description:)
login_result = login

raise login_result.failure unless login_result.success?
collection_model = CocinaGenerator::CollectionGenerator.generate_model(collection_version:)
version_description = collection_version.version_description.presence

create_or_update(request_dro, version_description)
end

def create_or_update(request_dro, version_description)
case request_dro
case collection_model
when Cocina::Models::RequestCollection
SdrClient::Deposit::CreateResource.run(accession: true,
metadata: request_dro,
logger: Rails.logger,
connection:)
# TODO: Consider removing `basepath` as a required arg in sdr-client since it's useless without files
SdrClient::RedesignedClient.deposit_model(
model: collection_model,
accession: true,
basepath: '.'
)
when Cocina::Models::Collection
SdrClient::Deposit::UpdateResource.run(metadata: request_dro,
logger: Rails.logger,
connection:,
version_description:)
SdrClient::RedesignedClient.update_model(model: collection_model,
version_description:)
end
end

def connection
@connection ||= SdrClient::Connection.new(url: Settings.sdr_api.url)
rescue StandardError => e
Honeybadger.notify(e)
end
end
119 changes: 37 additions & 82 deletions app/jobs/deposit_job.rb
Original file line number Diff line number Diff line change
@@ -1,114 +1,69 @@
# frozen_string_literal: true

# Deposits a Work into SDR API.
class DepositJob < BaseDepositJob
class DepositJob < ApplicationJob
queue_as :default

# @raise [SdrClient::Find::Failed] if the (non-nil) druid cannot be found in SDR
# @raise [RuntimeError] if the (non-nil) druid cannot be found in SDR
# rubocop:disable Metrics/AbcSize
def perform(work_version)
druid = work_version.work.druid # may be nil
Honeybadger.context({ work_version_id: work_version.id, druid:,
work_id: work_version.work.id, depositor_sunet: work_version.work.depositor.sunetid })

# NOTE: this login ensures `Repository.find` and various SdrClient::* calls below all have a valid token
perform_login

disallow_writes(work_version) if work_version.globus_endpoint.present?
disallow_writes!(work_version)

cocina_obj = Repository.find(druid) if druid
request_dro = CocinaGenerator::DROGenerator.generate_model(work_version:, cocina_obj:)
new_request_dro = update_dro_with_file_identifiers(request_dro, work_version)

case new_request_dro
case request_dro
when Cocina::Models::RequestDRO
create(new_request_dro, work_version)
Rails.logger.info("logging files: work version #{work_version.id}")
Rails.logger.info("files: #{work_version.staged_local_files.map(&:path)}")
Rails.logger.info("basepath for files: #{basepath_for(work_version.attached_files.first.file.blob)}")
Rails.logger.info("filepath_map for files: #{filepath_map_for(work_version)}")
SdrClient::RedesignedClient.deposit_model(
accession: true,
assign_doi: work_version.work.assign_doi?,
model: request_dro,
basepath: basepath_for(work_version.attached_files.first.file.blob),
files: work_version.staged_local_files.map(&:path),
filepath_map: filepath_map_for(work_version),
user_versions: user_versions_param(work_version)
)
when Cocina::Models::DRO
update(new_request_dro, work_version)
# basepath: basepath_for(work_version.attached_files.first.file.blob),
# files: work_version.staged_local_files.map(&:path),
# filepath_map: filepath_map_for(work_version),
SdrClient::RedesignedClient.update_model(
model: request_dro,
version_description: work_version.version_description.presence,
user_versions: user_versions_param(work_version)
)
end
end
# rubocop:enable Metrics/AbcSize

private

def perform_login
login_result = login
raise login_result.failure unless login_result.success?
end

def disallow_writes(work_version)
return true if test_mode?
return true if integration_test_mode? && work_version.globus_endpoint == integration_endpoint

# user_id nil because unneeded for permission update operations
GlobusClient.disallow_writes(path: work_version.globus_endpoint, user_id: nil)
end

def update_dro_with_file_identifiers(request_dro, work_version)
# Only uploading new or changed files.
# blobs_map is a map of relative filepath to blob
blobs_map = staged_blobs(work_version)
filepath_map = filepath_map_for(work_version)
upload_responses = perform_upload(blobs_map, filepath_map)
# Update with any new externalIdentifiers assigned by SDR API during upload.
SdrClient::Deposit::UpdateDroWithFileIdentifiers.update(request_dro:,
upload_responses:)
end

def create(new_request_dro, work_version)
SdrClient::Deposit::CreateResource.run(accession: true,
assign_doi: work_version.work.assign_doi?,
metadata: new_request_dro,
logger: Rails.logger,
connection:,
user_versions: user_versions_param(work_version))
end

def update(new_request_dro, work_version)
SdrClient::Deposit::UpdateResource.run(metadata: new_request_dro,
logger: Rails.logger,
connection:,
version_description: work_version.version_description.presence,
user_versions: user_versions_param(work_version))
end

def perform_upload(blobs_map, filepath_map)
SdrClient::Deposit::UploadFiles.upload(file_metadata: build_file_metadata(blobs_map),
filepath_map:,
logger: Rails.logger,
connection:)
end

def connection
@connection ||= SdrClient::Connection.new(url: Settings.sdr_api.url, read_timeout: 1800)
end

def build_file_metadata(blobs_map)
blobs_map.transform_values do |blob|
SdrClient::Deposit::Files::DirectUploadRequest.new(
checksum: blob.checksum,
byte_size: blob.byte_size,
content_type: blob.content_type,
filename: blob.filename.to_s
)
def filepath_map_for(work_version)
# attached_file.path contains the cocina filename (e.g. 'dir1/file1.txt')
work_version.staged_local_files.to_h do |attached_file|
[attached_file.path, basepath_for(attached_file.file.blob)]
end
end

def blob_filepath_for(blob)
ActiveStorage::Blob.service.path_for(blob.key)
def basepath_for(blob)
File.dirname(ActiveStorage::Blob.service.path_for(blob.key))
end

def staged_blobs(work_version)
work_version.staged_local_files.to_h do |attached_file|
[attached_file.path, attached_file.blob]
end
end
def disallow_writes!(work_version)
return if work_version.globus_endpoint.blank? ||
test_mode? ||
(integration_test_mode? && work_version.globus_endpoint == integration_endpoint)

def filepath_map_for(work_version)
# attached_file.path contains the cocina filename (e.g. 'dir1/file1.txt')
work_version.staged_local_files.to_h do |attached_file|
[attached_file.path, blob_filepath_for(attached_file.file.blob)]
end
# user_id nil because unneeded for permission update operations
GlobusClient.disallow_writes(path: work_version.globus_endpoint, user_id: nil)
end

# simulate globus calls in development if settings indicate we should for testing
Expand Down
2 changes: 1 addition & 1 deletion app/jobs/fetch_globus_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Change work version from a globus type to a browser type by fetching file names
# from Globus and creating Attached Files.
class FetchGlobusJob < BaseDepositJob
class FetchGlobusJob < ApplicationJob
queue_as :default

def perform(work_version)
Expand Down
18 changes: 7 additions & 11 deletions app/jobs/reserve_job.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
# frozen_string_literal: true

# Register a DRUID in the SDR API.
class ReserveJob < BaseDepositJob
class ReserveJob < ApplicationJob
queue_as :default

def perform(work_version)
login_result = login
raise login_result.failure unless login_result.success?

request_dro = CocinaGenerator::DROGenerator.generate_model(work_version:)
SdrClient::Deposit::CreateResource.run(accession: false,
metadata: request_dro,
logger: Rails.logger,
connection:)
end

def connection
@connection ||= SdrClient::Connection.new(url: Settings.sdr_api.url)
# TODO: Consider removing `basepath` as a required arg in sdr-client since it's useless without files
SdrClient::RedesignedClient.deposit_model(
model: request_dro,
accession: false,
basepath: '.'
)
end
end
2 changes: 1 addition & 1 deletion app/jobs/unzip_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require 'zip'

# Change work version from a zipfile type to a browser type by unzipping the attached zip file.
class UnzipJob < BaseDepositJob
class UnzipJob < ApplicationJob
queue_as :default

def perform(work_version)
Expand Down
11 changes: 2 additions & 9 deletions app/services/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
class Repository
# @return [Cocina::Models::DRO]
def self.find(druid)
ensure_logged_in!
cocina_str = SdrClient::Find.run(druid, url: Settings.sdr_api.url, logger: Rails.logger)
cocina_json = JSON.parse(cocina_str)
Cocina::Models.build(cocina_json)
cocina_hash = SdrClient::RedesignedClient.find(object_id: druid)
Cocina::Models.build(cocina_hash)
end

# @return [boolean] true if H2 version is one greater than SDR version.
Expand All @@ -18,9 +16,4 @@ def self.valid_version?(druid:, h2_version:)
allowed_versions = [cocina_obj.version, cocina_obj.version + 1]
allowed_versions.include?(h2_version)
end

def self.ensure_logged_in!
SdrClientAuthenticator.login
end
private_class_method :ensure_logged_in!
end
15 changes: 0 additions & 15 deletions app/services/sdr_client_authenticator.rb

This file was deleted.

12 changes: 12 additions & 0 deletions config/initializers/sdr_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

require 'sdr_client'
require 'sdr_client/redesigned_client' # TODO: Remove this when the redesigned client is promoted

# Configure SDR client
SdrClient::RedesignedClient.configure(
url: Settings.sdr_api.url,
email: Settings.sdr_api.email,
password: Settings.sdr_api.password,
logger: Rails.logger
)
Loading

0 comments on commit bc8273f

Please sign in to comment.