Skip to content

Commit

Permalink
Merge pull request #5216 from sul-dlss/t5215-orcid_robot
Browse files Browse the repository at this point in the history
  • Loading branch information
mjgiarlo authored Oct 31, 2024
2 parents 25d830b + 7fa21a6 commit 3c6f617
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 168 deletions.
11 changes: 1 addition & 10 deletions app/controllers/objects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# rubocop:disable Metrics/ClassLength
class ObjectsController < ApplicationController
before_action :load_cocina_object, only: %i[update_marc_record notify_goobi accession destroy show update_orcid_work reindex]
before_action :load_cocina_object, only: %i[update_marc_record notify_goobi accession destroy show reindex]
before_action :check_cocina_object_exists, only: :publish

rescue_from(CocinaObjectStore::CocinaObjectNotFoundError) do |e|
Expand Down Expand Up @@ -118,15 +118,6 @@ def update_marc_record
head :accepted
end

# Called by the robots.
def update_orcid_work
return head :no_content unless Settings.enabled_features.orcid_update

UpdateOrcidWorkJob.perform_later(Cocina::Models.without_metadata(@cocina_object).to_json)

head :accepted
end

def destroy
DeleteService.destroy(@cocina_object, user_name: params[:user_name])
head :no_content
Expand Down
111 changes: 111 additions & 0 deletions app/jobs/robots/dor_repo/accession/update_orcid_work.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# frozen_string_literal: true

module Robots
module DorRepo
module Accession
# Requests that Orcid works be created / updated for the object
class UpdateOrcidWork < Robots::Robot
def initialize
super('accessionWF', 'update-orcid-work')
end

def perform_work
return LyberCore::ReturnState.new(status: :skipped, note: 'Orcid works are not supported on non-Item objects') unless cocina_object.dro?
return LyberCore::ReturnState.new(status: :skipped, note: 'Object belongs to the SDR graveyard APO') if cocina_object.administrative.hasAdminPolicy == Settings.graveyard_admin_policy.druid

create_or_update_orcid_works
delete_orcid_works
end

private

def create_or_update_orcid_works
orcid_users.each do |orcid_user|
ar_orcid_work = OrcidWork.find_by(orcidid: orcid_user.orcidid, druid:)
if ar_orcid_work.nil?
create(orcid_user)
elsif ar_orcid_work.md5 != md5
update(orcid_user, ar_orcid_work)
else
Rails.logger.info("Orcid work for #{druid} / #{orcid_user.orcidid} has not changed")
end
end
end

def delete_orcid_works
delete_orcid_users.each do |orcid_user|
ar_orcid_work = OrcidWork.find_by(orcidid: orcid_user.orcidid, druid:)

Rails.logger.info("Deleting Orcid work for #{druid} / #{orcid_user.orcidid}")
orcid_client.delete_work(orcidid: orcid_user.orcidid, token: orcid_user.access_token, put_code: ar_orcid_work.put_code)
ar_orcid_work.destroy
end
end

def orcid_client
@orcid_client ||= SulOrcidClient.configure(
client_id: Settings.orcid.client_id,
client_secret: Settings.orcid.client_secret,
base_url: Settings.orcid.base_url,
base_public_url: Settings.orcid.base_public_url,
base_auth_url: Settings.orcid.base_auth_url
)
end

def mais_orcid_client
@mais_orcid_client = MaisOrcidClient.configure(
client_id: Settings.mais_orcid.client_id,
client_secret: Settings.mais_orcid.client_secret,
base_url: Settings.mais_orcid.base_url
)
end

def orcid_users
@orcid_users ||= begin
cited_orcid_ids = SulOrcidClient::CocinaSupport.cited_orcidids(cocina_object.description)

all_orcid_users = cited_orcid_ids.filter_map do |orcid_id|
mais_orcid_client.fetch_orcid_user(orcidid: orcid_id)
end

all_orcid_users.select(&:update?)
end
end

def delete_orcid_users
@delete_orcid_users ||= begin
delete_ar_orcid_works = OrcidWork.where(druid:)
orcid_ids = orcid_users.map(&:orcidid)
delete_ar_orcid_works = delete_ar_orcid_works.where.not(orcidid: orcid_ids) if orcid_ids.present?

delete_orcid_users = delete_ar_orcid_works.filter_map do |ar_orcid_work|
mais_orcid_client.fetch_orcid_user(orcidid: ar_orcid_work.orcidid)
end

delete_orcid_users.select(&:update?)
end
end

def work
@work ||= SulOrcidClient::WorkMapper.map(description: cocina_object.description, doi: cocina_object.identification.doi)
end

def md5
@md5 ||= Digest::MD5.hexdigest(work.to_json)
end

def create(orcid_user)
Rails.logger.info("Creating new Orcid work for #{druid} / #{orcid_user.orcidid}")
put_code = orcid_client.add_work(orcidid: orcid_user.orcidid, work:, token: orcid_user.access_token)
OrcidWork.create(orcidid: orcid_user.orcidid, druid:, put_code:, md5:)
end

def update(orcid_user, ar_orcid_work)
Rails.logger.info("Updating Orcid work for #{druid} / #{orcid_user.orcidid}")
orcid_client.update_work(orcidid: orcid_user.orcidid, work:, token: orcid_user.access_token, put_code: ar_orcid_work.put_code)
ar_orcid_work.update(md5:)
end
end
end
end
end
102 changes: 0 additions & 102 deletions app/jobs/update_orcid_work_job.rb

This file was deleted.

17 changes: 0 additions & 17 deletions openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,23 +197,6 @@ paths:
required: true
schema:
$ref: "#/components/schemas/Druid"
"/v1/objects/{id}/update_orcid_work":
post:
tags:
- integrations
summary: Update Orcid Work
description: "Starts a background job to do this, from metadata in the repository"
operationId: "objects#update_orcid_work"
responses:
"202":
description: Accepted
parameters:
- name: id
in: path
description: ID of object
required: true
schema:
$ref: "#/components/schemas/Druid"
"/v1/objects/{id}/notify_goobi":
post:
tags:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

require 'rails_helper'

RSpec.describe UpdateOrcidWorkJob do
subject(:perform) do
described_class.perform_now(cocina_item.to_json)
end
RSpec.describe Robots::DorRepo::Accession::UpdateOrcidWork, type: :robot do
subject(:perform) { test_perform(robot, druid) }

let(:druid) { 'druid:bc234fg5678' }
let(:robot) { described_class.new }

let(:cocina_item) do
let(:object) do
build(:dro, id: 'druid:bc234fg5678').new(
identification: {
doi: '10.25740/bc123df4567',
Expand Down Expand Up @@ -79,10 +80,40 @@
end

before do
allow(CocinaObjectStore).to receive(:find).with(druid).and_return(object)
allow(MaisOrcidClient).to receive(:configure).and_return(mais_orcid_client)
allow(SulOrcidClient).to receive(:configure).and_return(orcid_client)
end

context 'when the object is an admin policy' do
let(:object) { build(:admin_policy, id: druid) }

it 'skips the object' do
expect(perform.status).to eq 'skipped'
expect(perform.note).to eq 'Orcid works are not supported on non-Item objects'
end
end

context 'when the object is a collection policy' do
let(:object) { build(:collection, id: druid) }

it 'skips the object' do
expect(perform.status).to eq 'skipped'
expect(perform.note).to eq 'Orcid works are not supported on non-Item objects'
end
end

context 'when the object belongs to the SDR graveyard APO' do
let(:object) do
build(:dro, id: druid, admin_policy_id: Settings.graveyard_admin_policy.druid)
end

it 'skips the object' do
expect(perform.status).to eq 'skipped'
expect(perform.note).to eq 'Object belongs to the SDR graveyard APO'
end
end

context 'when adding a work' do
it 'creates orcid work and AR orcid work' do
perform
Expand Down Expand Up @@ -170,4 +201,27 @@
expect(orcid_client).not_to have_received(:update_work)
end
end

# context 'when the object is not exportable' do
# let(:exportable) { false }

# it 'raises an error' do
# expect { perform }.to raise_error(RuntimeError, /Item requested a DOI be updated, but it doesn't meet all the preconditions/)
# expect(Cocina::ToDatacite::Attributes).to have_received(:exportable?).with(object)
# end
# end

# context 'when Datacite returns an error' do
# let(:datacite_response_status) { 500 }

# it 'raises an error' do
# expect { perform }.to raise_error(RuntimeError, /Error connecting to datacite/)
# end
# end

# context 'with no errors' do
# it 'succeeds' do
# expect { perform }.not_to raise_error
# end
# end
end
34 changes: 0 additions & 34 deletions spec/requests/update_orcid_work_spec.rb

This file was deleted.

0 comments on commit 3c6f617

Please sign in to comment.