Skip to content

Commit

Permalink
Merge pull request #263 from sul-dlss/metadata-service
Browse files Browse the repository at this point in the history
Move MetadataService from dor-services-app
  • Loading branch information
justinlittman committed May 13, 2019
2 parents 2a3897a + 161fba3 commit f012041
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 13 deletions.
25 changes: 18 additions & 7 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2019-05-07 10:53:17 -0700 using RuboCop version 0.65.0.
# on 2019-05-13 10:30:48 -0500 using RuboCop version 0.65.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand Down Expand Up @@ -29,7 +29,7 @@ Lint/UriEscapeUnescape:
- 'app/controllers/sdr_controller.rb'
- 'spec/controllers/sdr_controller_spec.rb'

# Offense count: 22
# Offense count: 23
Metrics/AbcSize:
Max: 122

Expand Down Expand Up @@ -148,24 +148,26 @@ RSpec/EmptyLineAfterSubject:
Exclude:
- 'spec/models/symphony_reader_spec.rb'

# Offense count: 20
# Offense count: 21
RSpec/ExpectInHook:
Exclude:
- 'spec/dor/update_marc_record_service_spec.rb'
- 'spec/services/metadata_service_spec.rb'
- 'spec/services/public_desc_metadata_service_spec.rb'
- 'spec/services/publish_metadata_service_spec.rb'
- 'spec/services/registration_service_spec.rb'

# Offense count: 127
# Offense count: 137
# Configuration parameters: AssignmentOnly.
RSpec/InstanceVariable:
Exclude:
- 'spec/dor/registration_response_spec.rb'
- 'spec/dor/service_item_spec.rb'
- 'spec/dor/update_marc_record_service_spec.rb'
- 'spec/services/metadata_service_spec.rb'
- 'spec/services/registration_service_spec.rb'

# Offense count: 56
# Offense count: 60
# Configuration parameters: EnforcedStyle.
# SupportedStyles: have_received, receive
RSpec/MessageSpies:
Expand All @@ -175,6 +177,7 @@ RSpec/MessageSpies:
- 'spec/controllers/workflows_controller_spec.rb'
- 'spec/dor/goobi_spec.rb'
- 'spec/dor/update_marc_record_service_spec.rb'
- 'spec/services/metadata_service_spec.rb'
- 'spec/services/public_desc_metadata_service_spec.rb'
- 'spec/services/registration_service_spec.rb'
- 'spec/services/version_service_spec.rb'
Expand Down Expand Up @@ -219,13 +222,14 @@ RSpec/SubjectStub:
Exclude:
- 'spec/dor/update_marc_record_service_spec.rb'

# Offense count: 11
# Offense count: 12
# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
RSpec/VerifiedDoubles:
Exclude:
- 'spec/controllers/objects_controller_spec.rb'
- 'spec/dor/service_item_spec.rb'
- 'spec/dor/update_marc_record_service_spec.rb'
- 'spec/services/metadata_service_spec.rb'
- 'spec/services/version_service_spec.rb'

# Offense count: 3
Expand All @@ -244,6 +248,11 @@ Rails/TimeZone:
Exclude:
- 'spec/services/version_service_spec.rb'

# Offense count: 1
Style/ClassVars:
Exclude:
- 'app/services/metadata_service.rb'

# Offense count: 2
Style/CommentedKeyword:
Exclude:
Expand All @@ -257,7 +266,7 @@ Style/ConditionalAssignment:
Exclude:
- 'spec/support/foxml_helper.rb'

# Offense count: 13
# Offense count: 15
Style/Documentation:
Exclude:
- 'spec/**/*'
Expand All @@ -270,7 +279,9 @@ Style/Documentation:
- 'app/models/dor/registration_response.rb'
- 'app/models/dor/service_item.rb'
- 'app/models/dor/update_marc_record_service.rb'
- 'app/services/catalog_handler.rb'
- 'app/services/dublin_core_service.rb'
- 'app/services/metadata_service.rb'
- 'app/services/registration_service.rb'
- 'config/application.rb'
- 'config/initializers/okcomputer.rb'
Expand Down
3 changes: 2 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ gem 'okcomputer'

gem 'faraday'
gem 'jwt'
gem 'marc'
gem 'rest-client'
gem 'ruby-cache', '~> 0.3.0'
# Pin net-http-persistent to avoid a problem with exhausting file handles when running under load
gem 'marc'
gem 'net-http-persistent', '~> 2.9'
gem 'progressbar' # for the cleaner rake task
gem 'uuidtools', '~> 2.1.4'
Expand Down
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ DEPENDENCIES
rspec-rails
rubocop (~> 0.65.0)
rubocop-rspec (~> 1.32.0)
ruby-cache (~> 0.3.0)
simplecov
spring
spring-watcher-listen (~> 2.0.0)
Expand Down
23 changes: 23 additions & 0 deletions app/services/catalog_handler.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

class CatalogHandler
def fetch(prefix, identifier)
client = RestClient::Resource.new(Dor::Config.metadata.catalog.url,
Dor::Config.metadata.catalog.user,
Dor::Config.metadata.catalog.pass)
params = "?#{prefix.chomp}=#{identifier.chomp}"
client[params].get
rescue RestClient::Exception => e
raise BadResponseFromCatalog, "#{e.class} - when contacting (with BasicAuth hidden): #{Dor::Config.metadata.catalog.url}#{params}"
end

def label(metadata)
mods = Nokogiri::XML(metadata)
mods.root.add_namespace_definition('mods', 'http://www.loc.gov/mods/v3')
mods.xpath('/mods:mods/mods:titleInfo[1]').xpath('mods:title|mods:nonSort').collect(&:text).join(' ').strip
end

def prefixes
%w[catkey barcode]
end
end
60 changes: 60 additions & 0 deletions app/services/metadata_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true

require 'cache'
class MetadataError < RuntimeError; end

class MetadataService
class << self
@@cache = Cache.new(nil, nil, 250, 300)

def known_prefixes
handlers.keys
end

def can_resolve?(identifier)
(prefix, _identifier) = identifier.split(/:/, 2)
handlers.key?(prefix.to_sym)
end

# TODO: Return a prioritized list
def resolvable(identifiers)
identifiers.select { |identifier| can_resolve?(identifier) }
end

def fetch(identifier)
@@cache.fetch(identifier) do
(prefix, identifier) = identifier.split(/:/, 2)
handler = handler_for(prefix)
handler.fetch(prefix, identifier)
end
end

def label_for(identifier)
(prefix, identifier) = identifier.split(/:/, 2)
handler = handler_for(prefix)
handler.label(handler.fetch(prefix, identifier))
end

def handler_for(prefix)
handler = handlers[prefix.to_sym]
raise MetadataError, "Unknown metadata prefix: #{prefix}" if handler.nil?

handler
end

private

def handlers
@handlers ||= {}.tap do |md_handlers|
# There's only one. If additional handlers are added, will need to be registered here.
register(CatalogHandler.new, md_handlers)
end
end

def register(handler, md_handlers)
handler.prefixes.each do |prefix|
md_handlers[prefix.to_sym] = handler
end
end
end
end
4 changes: 2 additions & 2 deletions app/services/refresh_metadata_action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def run(datastream)

def fetch_datastream
candidates = @object.identityMetadata.otherId.collect(&:to_s)
metadata_id = Dor::MetadataService.resolvable(candidates).first
metadata_id.nil? ? nil : Dor::MetadataService.fetch(metadata_id.to_s)
metadata_id = MetadataService.resolvable(candidates).first
metadata_id.nil? ? nil : MetadataService.fetch(metadata_id.to_s)
end
end
4 changes: 2 additions & 2 deletions app/services/registration_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ def create_from_request(params)
if params[:label] == ':auto'
params.delete(:label)
params.delete('label')
metadata_id = Dor::MetadataService.resolvable(other_ids).first
params[:label] = Dor::MetadataService.label_for(metadata_id)
metadata_id = MetadataService.resolvable(other_ids).first
params[:label] = MetadataService.label_for(metadata_id)
end

dor_params = {
Expand Down
69 changes: 69 additions & 0 deletions spec/fixtures/mods_record.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.loc.gov/mods/v3"
version="3.3"
xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-3.xsd">
<titleInfo>
<nonSort>The</nonSort>
<title>isomorphism and thermal properties of the feldspars</title>
</titleInfo>
<name type="personal">
<namePart>Day, Arthur L. (Arthur Louis)</namePart>
<namePart type="date">1869-</namePart>
<role>
<roleTerm authority="marcrelator" type="text">creator</roleTerm>
</role>
</name>
<name type="personal">
<namePart>Allen, Eugene Thomas</namePart>
<namePart type="date">1864-</namePart>
</name>
<name type="personal">
<namePart>Iddings, Joseph Paxson</namePart>
<namePart type="date">1857-1920</namePart>
</name>
<name type="personal">
<namePart>Becker, George F. (George Ferdinand)</namePart>
<namePart type="date">1847-1919</namePart>
</name>
<typeOfResource>text</typeOfResource>
<originInfo>
<place>
<placeTerm type="code" authority="marccountry">dcu</placeTerm>
</place>
<place>
<placeTerm type="text">Washington, D.C</placeTerm>
</place>
<publisher>Carnegie Institution of Washington</publisher>
<dateIssued>1905</dateIssued>
<dateIssued encoding="marc" keyDate="yes">1905</dateIssued>
<issuance>monographic</issuance>
</originInfo>
<language>
<languageTerm authority="iso639-2b" type="code">eng</languageTerm>
</language>
<physicalDescription>
<form authority="marcform">print</form>
<extent>95 p. illus., XXVI (i.e. 27) pl. 27 cm.</extent>
</physicalDescription>
<note displayLabel="statement of responsibility">Part I- Thermal study [by] Arthur L. Day and E. T. Allen. Part II- Optical study [by] J. P. Iddings. With an introduction by George F. Becker.</note>
<subject authority="lcsh">
<topic>Crystallography</topic>
</subject>
<subject authority="lcsh">
<topic>Feldspar</topic>
</subject>
<classification authority="lcc">QD931 .D27</classification>
<relatedItem type="series">
<titleInfo>
<title>Carnegie Institution of Washington publication ; 31</title>
</titleInfo>
</relatedItem>
<identifier type="lccn">05032416</identifier>
<recordInfo>
<recordContentSource authority="marcorg">DLC</recordContentSource>
<recordCreationDate encoding="marc">770104</recordCreationDate>
<recordChangeDate encoding="iso8601">19900306063726.0</recordChangeDate>
<recordIdentifier>a45873</recordIdentifier>
</recordInfo>
</mods>
39 changes: 39 additions & 0 deletions spec/services/metadata_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe MetadataService do
before do
@specdir = File.join(File.dirname(__FILE__), '..')
end

it 'raises an exception if an unknown metadata type is requested' do
expect { described_class.fetch('foo:bar') }.to raise_exception(MetadataError)
end

describe 'Symphony handler' do
before do
@mods = File.read(File.join(@specdir, 'fixtures', 'mods_record.xml'))
@mock_resource = double('catalog-resource', get: @mods)
allow(@mock_resource).to receive(:[]).and_return(@mock_resource)
expect(RestClient::Resource).to receive(:new).with(Dor::Config.metadata.catalog.url,
Dor::Config.metadata.catalog.user,
Dor::Config.metadata.catalog.pass).and_return(@mock_resource)
end

it 'fetches a record based on barcode' do
expect(@mock_resource).to receive(:[]).with('?barcode=12345')
expect(described_class.fetch('barcode:12345')).to be_equivalent_to(@mods)
end

it 'fetches a record based on catkey' do
expect(@mock_resource).to receive(:[]).with('?catkey=12345')
expect(described_class.fetch('catkey:12345')).to be_equivalent_to(@mods)
end

it 'returns the MODS title as the label' do
expect(@mock_resource).to receive(:[]).with('?barcode=12345')
expect(described_class.label_for('barcode:12345')).to eq('The isomorphism and thermal properties of the feldspars')
end
end
end
2 changes: 1 addition & 1 deletion spec/services/refresh_metadata_action_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

before do
allow(item.identityMetadata).to receive(:otherId).and_return(['catkey:123'])
allow(Dor::MetadataService).to receive(:fetch).and_return('<xml/>')
allow(MetadataService).to receive(:fetch).and_return('<xml/>')
end

it 'gets the data an puts it in descMetadata' do
Expand Down

0 comments on commit f012041

Please sign in to comment.