hydra-remote_identifier 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hydra/remote_identifier/configuration.rb +41 -39
- data/lib/hydra/remote_identifier/exceptions.rb +39 -37
- data/lib/hydra/remote_identifier/mapper.rb +74 -72
- data/lib/hydra/remote_identifier/minter.rb +25 -23
- data/lib/hydra/remote_identifier/minting_coordinator.rb +20 -18
- data/lib/hydra/remote_identifier/railtie.rb +11 -9
- data/lib/hydra/remote_identifier/registration.rb +32 -30
- data/lib/hydra/remote_identifier/remote_service.rb +55 -53
- data/lib/hydra/remote_identifier/remote_services/doi.rb +9 -3
- data/lib/hydra/remote_identifier/version.rb +1 -1
- data/run-tests +4 -0
- data/spec/fixtures/cassettes/doi-create.yml +3 -3
- data/spec/fixtures/cassettes/doi-integration.yml +3 -3
- data/spec/lib/hydra/remote_identifier/remote_services/doi_spec.rb +1 -1
- data/spec/lib/hydra/remote_identifier_spec.rb +19 -2
- data/spec/spec_helper.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88b472a25583380ecb5baf994bfc73fe3d5d5a65
|
4
|
+
data.tar.gz: 336e74b11670464b4cb545dabca319dd4f02f82d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 667c0f7acb4ceebd6f02114775600bd32c22919940e3a8471afd86a098cbc4e61cb20e01cf03624ec42d8f92630ad7e67dbf08a69e3b3d7a977c993df30c539c
|
7
|
+
data.tar.gz: 3f05bbeae5546cd40d7485c056bbe831a3963de741f807c51ccc09445ff3baa7d7b37feca60ffa086cd0cc42b6107a6d535b6515c83a518f4d77f063a0d4f2cc
|
@@ -1,52 +1,54 @@
|
|
1
1
|
require File.expand_path('../remote_services', __FILE__)
|
2
2
|
require File.expand_path('../registration', __FILE__)
|
3
3
|
|
4
|
-
module Hydra
|
4
|
+
module Hydra
|
5
|
+
module RemoteIdentifier
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
# Configuration is responsible for exposing the available RemoteServices
|
8
|
+
# and configuring those RemoteServices.
|
9
|
+
class Configuration
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
def initialize(options = {})
|
12
|
+
@remote_service_namespace_container = options.fetch(:remote_service_namespace_container, RemoteServices)
|
13
|
+
@registration_builder = options.fetch(:registration_builder, Registration)
|
14
|
+
@remote_services = {}
|
15
|
+
end
|
16
|
+
attr_reader :remote_service_namespace_container, :registration_builder
|
17
|
+
private :remote_service_namespace_container, :registration_builder
|
18
|
+
attr_reader :remote_services
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
def find_remote_service(service_name)
|
21
|
+
remote_services.fetch(service_name.to_sym)
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
# @param service_name [#to_s]
|
25
|
+
# @param args - passed through to RemoteService initializer
|
26
|
+
#
|
27
|
+
# @yieldparam [Registration]
|
28
|
+
def remote_service(service_name, *args)
|
29
|
+
remote_service = find_or_store_remote_service(service_name, *args)
|
30
|
+
registration = registration_builder.new(remote_service)
|
31
|
+
yield(registration)
|
32
|
+
remote_service
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
private
|
36
|
+
def find_or_store_remote_service(service_name, *args)
|
37
|
+
remote_services[service_name.to_sym] ||= remote_service_class_lookup(service_name).new(*args)
|
38
|
+
remote_services.fetch(service_name.to_sym)
|
39
|
+
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
def remote_service_class_lookup(string)
|
42
|
+
remote_service_class_name = string.to_s.gsub(/(?:^|_)([a-z])/) { $1.upcase }
|
43
|
+
if remote_service_namespace_container.const_defined?(remote_service_class_name)
|
44
|
+
remote_service_namespace_container.const_get(remote_service_class_name)
|
45
|
+
else
|
46
|
+
raise NotImplementedError.new(
|
47
|
+
"Unable to find #{self} remote_service '#{string}'. Consider creating #{remote_service_namespace_container}::#{remote_service_class_name}"
|
48
|
+
)
|
49
|
+
end
|
48
50
|
end
|
49
51
|
end
|
50
|
-
end
|
51
52
|
|
53
|
+
end
|
52
54
|
end
|
@@ -1,46 +1,48 @@
|
|
1
|
-
module Hydra
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Hydra
|
2
|
+
module RemoteIdentifier
|
3
|
+
class InvalidServiceMapping < RuntimeError
|
4
|
+
def initialize(errors)
|
5
|
+
super(errors.join(". ") << '.')
|
6
|
+
end
|
5
7
|
end
|
6
|
-
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
class RemoteServiceError < RuntimeError
|
10
|
+
def initialize(exception, uri, payload)
|
11
|
+
@exception = exception
|
12
|
+
@uri = uri
|
13
|
+
@payload = payload
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
def to_s
|
17
|
+
text = ""
|
18
|
+
text << "response.code: #{response_code.inspect}\n"
|
19
|
+
text << "response.body: #{response_body.inspect}\n"
|
20
|
+
text << "\n"
|
21
|
+
text << "request.uri: #{request_sanitized_uri.inspect}\n"
|
22
|
+
text << "request.payload: #{request_sanitized_paylod.inspect}\n"
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
private
|
26
|
+
def request_sanitized_paylod
|
27
|
+
@payload
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
def request_sanitized_uri
|
31
|
+
uri = URI.parse(@uri.to_s)
|
32
|
+
x = "#{uri.scheme}://"
|
33
|
+
x << "xxx:xxx@" if uri.user || uri.password
|
34
|
+
x << File.join(uri.host, uri.path)
|
35
|
+
x << '?' << uri.query if uri.query
|
36
|
+
x
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
def response_code
|
40
|
+
@exception.http_code rescue NoMethodError @exception.to_s
|
41
|
+
end
|
41
42
|
|
42
|
-
|
43
|
-
|
43
|
+
def response_body
|
44
|
+
@exception.http_body rescue NoMethodError 'unknown'
|
45
|
+
end
|
44
46
|
end
|
45
47
|
end
|
46
|
-
end
|
48
|
+
end
|
@@ -1,97 +1,99 @@
|
|
1
1
|
require File.expand_path('../exceptions', __FILE__)
|
2
2
|
|
3
|
-
module Hydra
|
3
|
+
module Hydra
|
4
|
+
module RemoteIdentifier
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
# The Mapper is responsible for transforming a target, via a Map, into an
|
7
|
+
# acceptable format for a Minter
|
8
|
+
class Mapper
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def call(target, wrapper_builder = Wrapper)
|
15
|
-
wrapper_builder.new(map, target)
|
16
|
-
end
|
10
|
+
attr_reader :map
|
11
|
+
def initialize(service_class, map_builder = Map, &mapping_block)
|
12
|
+
@map = map_builder.new(service_class, &mapping_block)
|
13
|
+
end
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
attr_reader :map, :target
|
21
|
-
def initialize(map, target)
|
22
|
-
@map, @target = map, target
|
15
|
+
def call(target, wrapper_builder = Wrapper)
|
16
|
+
wrapper_builder.new(map, target)
|
23
17
|
end
|
24
18
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
# The Wrapper provides the getting and setting behavior for a target based on a Map
|
20
|
+
class Wrapper
|
21
|
+
attr_reader :map, :target
|
22
|
+
def initialize(map, target)
|
23
|
+
@map, @target = map, target
|
29
24
|
end
|
30
|
-
end
|
31
25
|
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
def extract_payload
|
27
|
+
map._getters.each_with_object({}) do |(key, getter), mem|
|
28
|
+
mem[key] = extract_attribute_for(target, getter, key)
|
29
|
+
mem
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_identifier(identifier)
|
34
|
+
update_target(map._setter, target, identifier)
|
35
|
+
end
|
35
36
|
|
36
|
-
|
37
|
+
private
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
def update_target(setter, target, value)
|
40
|
+
if setter.respond_to?(:call)
|
41
|
+
setter.call(target, value)
|
42
|
+
elsif setter.is_a?(Symbol) || setter.is_a?(String)
|
43
|
+
target.send(setter, value)
|
44
|
+
elsif setter.is_a?(Hash)
|
45
|
+
datastream = setter.fetch(:at)
|
46
|
+
field = setter.fetch(:in)
|
47
|
+
target.datastreams["#{datastream}"].send("#{field}=", value)
|
48
|
+
end
|
47
49
|
end
|
48
|
-
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
51
|
+
def extract_attribute_for(target, getter, field_name)
|
52
|
+
if getter.respond_to?(:call)
|
53
|
+
getter.call(target)
|
54
|
+
elsif getter.is_a?(::Symbol) || getter.is_a?(::String)
|
55
|
+
target.send(getter)
|
56
|
+
elsif getter.is_a?(::Hash)
|
57
|
+
datastream = getter.fetch(:at)
|
58
|
+
field = getter.fetch(:in, field_name)
|
59
|
+
target.datastreams["#{datastream}"].send("#{field}")
|
60
|
+
end
|
59
61
|
end
|
60
62
|
end
|
61
|
-
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
64
|
+
# The Map is responsible for defining which attributes on the target map
|
65
|
+
# to the attributes expected in the RemoteService as well as defining
|
66
|
+
# how the RemoteService can update the target
|
67
|
+
class Map < BasicObject
|
68
|
+
attr_reader :service_class, :_getters, :_setter
|
69
|
+
def initialize(service_class, &config)
|
70
|
+
@service_class = service_class
|
71
|
+
@_setter = nil
|
72
|
+
@_getters = {}
|
73
|
+
@errors = []
|
74
|
+
config.call(self)
|
75
|
+
if @_setter.nil?
|
76
|
+
@errors << "Missing :set_identifier"
|
77
|
+
end
|
78
|
+
::Kernel.raise ::Hydra::RemoteIdentifier::InvalidServiceMapping.new(@errors) if @errors.any?
|
76
79
|
end
|
77
|
-
::Kernel.raise ::Hydra::RemoteIdentifier::InvalidServiceMapping.new(@errors) if @errors.any?
|
78
|
-
end
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
def inspect
|
82
|
+
"#<Hydra::RemoteIdentifier::Mapper::Map for #{service_class} (#{__FILE__})>"
|
83
|
+
end
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
85
|
+
def method_missing(method_name, *args, &block)
|
86
|
+
if method_name == :set_identifier
|
87
|
+
@_setter = args.first || block
|
88
|
+
elsif service_class.valid_attribute?(method_name)
|
89
|
+
@_getters[method_name] = args.first || block
|
90
|
+
else
|
91
|
+
@errors << "Invalid mapping #{method_name}"
|
92
|
+
end
|
91
93
|
end
|
92
94
|
end
|
95
|
+
|
93
96
|
end
|
94
97
|
|
95
98
|
end
|
96
|
-
|
97
99
|
end
|
@@ -1,35 +1,37 @@
|
|
1
|
-
module Hydra
|
1
|
+
module Hydra
|
2
|
+
module RemoteIdentifier
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
# The Minter is responsible for passing the target's payload to the
|
5
|
+
# RemoteService then setting the target's identifier based on the response
|
6
|
+
# from the remote_service
|
7
|
+
class Minter
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def self.call(coordinator, target)
|
10
|
+
new(coordinator, target).call
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
+
attr_reader :service, :target
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
def initialize(service, target)
|
16
|
+
@service, @target = service, target
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def call
|
20
|
+
update_target(service.call(payload))
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
+
private
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
def payload
|
26
|
+
target.extract_payload
|
27
|
+
end
|
28
|
+
|
29
|
+
def update_target(identifier)
|
30
|
+
target.set_identifier(identifier)
|
31
|
+
identifier
|
32
|
+
end
|
27
33
|
|
28
|
-
def update_target(identifier)
|
29
|
-
target.set_identifier(identifier)
|
30
|
-
identifier
|
31
34
|
end
|
32
35
|
|
33
36
|
end
|
34
|
-
|
35
37
|
end
|
@@ -1,27 +1,29 @@
|
|
1
1
|
require File.expand_path('../mapper', __FILE__)
|
2
2
|
require File.expand_path('../minter', __FILE__)
|
3
3
|
|
4
|
-
module Hydra
|
4
|
+
module Hydra
|
5
|
+
module RemoteIdentifier
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
# The Minting
|
8
|
+
class MintingCoordinator
|
9
|
+
attr_reader :remote_service, :mapper
|
10
|
+
def initialize(remote_service, mapper_builder = Mapper, &map_config)
|
11
|
+
@remote_service = remote_service
|
12
|
+
@mapper = mapper_builder.new(remote_service, &map_config)
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
# Responsible for passing attributes from the target, as per the map, to
|
16
|
+
# the service and assigning the result of the service to the target, as per
|
17
|
+
# the map.
|
18
|
+
def call(target, minter = Minter)
|
19
|
+
minter.call(remote_service, wrap(target))
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
private
|
23
|
+
def wrap(target)
|
24
|
+
mapper.call(target)
|
25
|
+
end
|
24
26
|
end
|
25
|
-
end
|
26
27
|
|
28
|
+
end
|
27
29
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
-
module Hydra
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Hydra
|
2
|
+
module RemoteIdentifier
|
3
|
+
class Railtie < Rails::Railtie
|
4
|
+
generators do
|
5
|
+
require 'generators/hydra/remote_identifier/install_generator'
|
6
|
+
require 'generators/hydra/remote_identifier/doi_generator'
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
config.to_prepare do
|
10
|
+
Hydra::RemoteIdentifier.send(:configure!)
|
11
|
+
end
|
10
12
|
end
|
11
13
|
end
|
12
|
-
end
|
14
|
+
end
|
@@ -1,43 +1,45 @@
|
|
1
1
|
require 'active_support/core_ext/class/attribute'
|
2
2
|
require File.expand_path('../minting_coordinator', __FILE__)
|
3
3
|
|
4
|
-
module Hydra
|
4
|
+
module Hydra
|
5
|
+
module RemoteIdentifier
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
# The Registration is responsible for connecting a RemoteService and a Target
|
8
|
+
# to a particular Map
|
9
|
+
class Registration
|
10
|
+
attr_reader :remote_service, :minting_coordinator
|
11
|
+
def initialize(remote_service, minting_coordinator = MintingCoordinator, &map)
|
12
|
+
@remote_service = remote_service
|
13
|
+
@minting_coordinator = minting_coordinator
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
# @param target_classes [Array]
|
17
|
+
# @yieldparam map [Map]
|
18
|
+
def register(*target_classes, &map)
|
19
|
+
if map.nil?
|
20
|
+
raise RuntimeError, "You attempted to register the remote service #{remote_service} for #{target_classes} without a map"
|
21
|
+
end
|
22
|
+
Array(target_classes).flatten.compact.each {|target_class|
|
23
|
+
register_target(target_class, &map)
|
24
|
+
}
|
20
25
|
end
|
21
|
-
Array(target_classes).flatten.compact.each {|target_class|
|
22
|
-
register_target(target_class, &map)
|
23
|
-
}
|
24
|
-
end
|
25
26
|
|
26
|
-
|
27
|
+
private
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
def register_target(target_class, &map)
|
30
|
+
target_class.module_exec(remote_service) do |service|
|
31
|
+
unless target_class.respond_to?(:registered_remote_identifier_minters)
|
32
|
+
class_attribute :registered_remote_identifier_minters
|
33
|
+
end
|
34
|
+
attr_accessor service.accessor_name
|
35
|
+
define_method("#{service.accessor_name}?") do
|
36
|
+
instance_variable_get("@#{service.accessor_name}").to_i != 0
|
37
|
+
end
|
36
38
|
end
|
39
|
+
target_class.registered_remote_identifier_minters ||= []
|
40
|
+
target_class.registered_remote_identifier_minters += [minting_coordinator.new(remote_service, &map)]
|
37
41
|
end
|
38
|
-
target_class.registered_remote_identifier_minters ||= []
|
39
|
-
target_class.registered_remote_identifier_minters += [minting_coordinator.new(remote_service, &map)]
|
40
42
|
end
|
41
|
-
end
|
42
43
|
|
44
|
+
end
|
43
45
|
end
|
@@ -1,66 +1,68 @@
|
|
1
1
|
require 'active_support/core_ext/string/inflections'
|
2
|
-
module Hydra
|
2
|
+
module Hydra
|
3
|
+
module RemoteIdentifier
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
# The RemoteService is responsible for delivering a payload to a remote
|
6
|
+
# identification minting service and returning an identifier.
|
7
|
+
#
|
8
|
+
# It is responsible for assisting the construction and validation of a remote
|
9
|
+
# payload.
|
10
|
+
class RemoteService
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def name
|
13
|
+
self.class.to_s.demodulize.underscore.to_sym
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def to_s
|
17
|
+
name.to_s
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
def registered?(target)
|
21
|
+
Hydra::RemoteIdentifier.registered?(self, target)
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def mint(target)
|
25
|
+
Hydra::RemoteIdentifier.mint(self, target)
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
# @param identifier[#to_s] - An identifier that was created by this remote
|
29
|
+
# service
|
30
|
+
# @returns [URI] - The URI for that identifier
|
31
|
+
def remote_uri_for(identifier)
|
32
|
+
raise NotImplementedError,
|
33
|
+
"You must implement #{self.class}#remote_uri_for(identifier)"
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
# When mapping a Target to a RemoteService, this is the name of the
|
37
|
+
# :attr_accessor that will be created on the Target; Helpful for form
|
38
|
+
# construction.
|
39
|
+
#
|
40
|
+
# @returns [Symbol]
|
41
|
+
def accessor_name
|
42
|
+
"mint_#{name}".to_sym
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
# @param identifier[#to_s] - The name of an attribute that is
|
46
|
+
#
|
47
|
+
# @returns [boolean] - Is this a valid attribute to send as part of the
|
48
|
+
# payload for RemoteService#call
|
49
|
+
def valid_attribute?(attribute_name)
|
50
|
+
raise NotImplementedError,
|
51
|
+
"You must implement #{self.class}#valid_attribute?"
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param payload[Hash] - A map with key/value pairs of valid attribute names
|
55
|
+
# and corresponding values that will be used to create the remote
|
56
|
+
# identifier
|
57
|
+
# @return - The remote identifier that was created
|
58
|
+
#
|
59
|
+
# @see RemoteService#valid_attribute?
|
60
|
+
def call(payload)
|
61
|
+
raise NotImplementedError,
|
62
|
+
"You must implement #{self.class}#call"
|
63
|
+
end
|
52
64
|
|
53
|
-
# @param payload[Hash] - A map with key/value pairs of valid attribute names
|
54
|
-
# and corresponding values that will be used to create the remote
|
55
|
-
# identifier
|
56
|
-
# @return - The remote identifier that was created
|
57
|
-
#
|
58
|
-
# @see RemoteService#valid_attribute?
|
59
|
-
def call(payload)
|
60
|
-
raise NotImplementedError,
|
61
|
-
"You must implement #{self.class}#call"
|
62
65
|
end
|
63
66
|
|
64
67
|
end
|
65
|
-
|
66
|
-
end
|
68
|
+
end
|
@@ -11,20 +11,22 @@ module Hydra::RemoteIdentifier
|
|
11
11
|
username: 'apitest',
|
12
12
|
password: 'apitest',
|
13
13
|
shoulder: 'doi:10.5072/FK2',
|
14
|
-
url: "https://ezid.lib.purdue.edu/
|
14
|
+
url: "https://ezid.lib.purdue.edu/",
|
15
|
+
resolver_url: 'http://dx.doi.org/'
|
15
16
|
}
|
16
17
|
|
17
|
-
attr_reader :username, :password, :shoulder, :url
|
18
|
+
attr_reader :username, :password, :shoulder, :url, :resolver_url
|
18
19
|
def initialize(options = {})
|
19
20
|
configuration = options.with_indifferent_access
|
20
21
|
@username = configuration.fetch(:username)
|
21
22
|
@password = configuration.fetch(:password)
|
22
23
|
@shoulder = configuration.fetch(:shoulder)
|
23
24
|
@url = configuration.fetch(:url)
|
25
|
+
@resolver_url = configuration.fetch(:resolver_url) { default_resolver_url }
|
24
26
|
end
|
25
27
|
|
26
28
|
def remote_uri_for(identifier)
|
27
|
-
URI.parse(File.join(
|
29
|
+
URI.parse(File.join(resolver_url, identifier))
|
28
30
|
end
|
29
31
|
|
30
32
|
REQUIRED_ATTRIBUTES = ['target', 'creator', 'title', 'publisher', 'publicationyear' ].freeze
|
@@ -62,6 +64,10 @@ module Hydra::RemoteIdentifier
|
|
62
64
|
data << "datacite.publicationyear: #{payload.fetch(:publicationyear)}"
|
63
65
|
data.join("\n")
|
64
66
|
end
|
67
|
+
|
68
|
+
def default_resolver_url
|
69
|
+
'http://dx.doi.org/'
|
70
|
+
end
|
65
71
|
end
|
66
72
|
end
|
67
73
|
end
|
data/run-tests
ADDED
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: post
|
5
|
-
uri: https://apitest:apitest@ezid.lib.purdue.edu/
|
5
|
+
uri: https://apitest:apitest@ezid.lib.purdue.edu/shoulder/doi:10.5072/FK2
|
6
6
|
body:
|
7
7
|
encoding: UTF-8
|
8
8
|
string: |-
|
@@ -34,7 +34,7 @@ http_interactions:
|
|
34
34
|
Vary:
|
35
35
|
- Cookie
|
36
36
|
Set-Cookie:
|
37
|
-
- sessionid=649cfcff023c40d4c8f1420673837ae6; Path=/
|
37
|
+
- sessionid=649cfcff023c40d4c8f1420673837ae6; Path=/
|
38
38
|
Content-Length:
|
39
39
|
- '53'
|
40
40
|
Content-Type:
|
@@ -46,7 +46,7 @@ http_interactions:
|
|
46
46
|
recorded_at: Thu, 03 Oct 2013 17:50:54 GMT
|
47
47
|
- request:
|
48
48
|
method: post
|
49
|
-
uri: https://apitest:apitest@ezid.lib.purdue.edu/
|
49
|
+
uri: https://apitest:apitest@ezid.lib.purdue.edu/shoulder/doi:10.5072/FK2
|
50
50
|
body:
|
51
51
|
encoding: UTF-8
|
52
52
|
string: |-
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: post
|
5
|
-
uri: https://apitest:apitest@ezid.lib.purdue.edu/
|
5
|
+
uri: https://apitest:apitest@ezid.lib.purdue.edu/shoulder/doi:10.5072/FK2
|
6
6
|
body:
|
7
7
|
encoding: UTF-8
|
8
8
|
string: |-
|
@@ -34,7 +34,7 @@ http_interactions:
|
|
34
34
|
Vary:
|
35
35
|
- Cookie
|
36
36
|
Set-Cookie:
|
37
|
-
- sessionid=995dadb966d7013e9251daf61b6122ba; Path=/
|
37
|
+
- sessionid=995dadb966d7013e9251daf61b6122ba; Path=/
|
38
38
|
Content-Length:
|
39
39
|
- '53'
|
40
40
|
Content-Type:
|
@@ -46,7 +46,7 @@ http_interactions:
|
|
46
46
|
recorded_at: Thu, 03 Oct 2013 19:10:25 GMT
|
47
47
|
- request:
|
48
48
|
method: post
|
49
|
-
uri: https://apitest:apitest@ezid.lib.purdue.edu/
|
49
|
+
uri: https://apitest:apitest@ezid.lib.purdue.edu/shoulder/doi:10.5072/FK2
|
50
50
|
body:
|
51
51
|
encoding: UTF-8
|
52
52
|
string: |-
|
@@ -35,7 +35,7 @@ module Hydra::RemoteIdentifier
|
|
35
35
|
end
|
36
36
|
|
37
37
|
context '.remote_uri_for' do
|
38
|
-
let(:expected_uri) { URI.parse(File.join(subject.
|
38
|
+
let(:expected_uri) { URI.parse(File.join(subject.resolver_url, expected_doi))}
|
39
39
|
it 'should be based on configuration' do
|
40
40
|
expect(subject.remote_uri_for(expected_doi)).to eq(expected_uri)
|
41
41
|
end
|
@@ -109,7 +109,7 @@ module Hydra::RemoteIdentifier
|
|
109
109
|
context '.remote_uri_for' do
|
110
110
|
it {
|
111
111
|
expect(Hydra::RemoteIdentifier.remote_uri_for(:doi, expected_doi)).
|
112
|
-
to eq(URI.parse(File.join(doi_options.fetch(:
|
112
|
+
to eq(URI.parse(File.join(doi_options.fetch(:resolver_url), expected_doi)))
|
113
113
|
}
|
114
114
|
end
|
115
115
|
|
@@ -150,8 +150,25 @@ module Hydra::RemoteIdentifier
|
|
150
150
|
it 'returns false if the target is not configured for identifiers' do
|
151
151
|
expect(Hydra::RemoteIdentifier.mint(:doi, double)).to eq(false)
|
152
152
|
end
|
153
|
+
|
153
154
|
end
|
155
|
+
if ENV['DOI_API_USERNAME'] && ENV['DOI_API_PASSWORD']
|
156
|
+
|
157
|
+
let(:doi_options) {
|
158
|
+
{
|
159
|
+
username: ENV['DOI_API_USERNAME'],
|
160
|
+
password: ENV['DOI_API_PASSWORD'],
|
161
|
+
shoulder: 'doi:10.5072/FK2',
|
162
|
+
url: "https://ezid.lib.purdue.edu/"
|
163
|
+
}
|
164
|
+
}
|
154
165
|
|
166
|
+
context 'against live sandbox' do
|
167
|
+
it 'works!' do
|
168
|
+
Hydra::RemoteIdentifier.mint(:doi, target)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
155
172
|
end
|
156
173
|
|
157
|
-
end
|
174
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -11,6 +11,7 @@ VCR.configure do |config|
|
|
11
11
|
config.cassette_library_dir = 'spec/fixtures/cassettes'
|
12
12
|
config.hook_into :webmock
|
13
13
|
config.configure_rspec_metadata!
|
14
|
+
config.allow_http_connections_when_no_cassette = true
|
14
15
|
end
|
15
16
|
|
16
17
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hydra-remote_identifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Friesen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- lib/hydra/remote_identifier/remote_services.rb
|
119
119
|
- lib/hydra/remote_identifier/remote_services/doi.rb
|
120
120
|
- lib/hydra/remote_identifier/version.rb
|
121
|
+
- run-tests
|
121
122
|
- spec/fixtures/cassettes/doi-create.yml
|
122
123
|
- spec/fixtures/cassettes/doi-integration.yml
|
123
124
|
- spec/lib/hydra/remote_identifier/configuration_spec.rb
|