ezid-client 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -15
  3. data/VERSION +1 -1
  4. data/lib/ezid/client.rb +61 -67
  5. data/lib/ezid/configuration.rb +9 -3
  6. data/lib/ezid/metadata.rb +1 -3
  7. data/lib/ezid/requests/create_identifier_request.rb +15 -0
  8. data/lib/ezid/requests/delete_identifier_request.rb +11 -0
  9. data/lib/ezid/requests/get_identifier_metadata_request.rb +15 -0
  10. data/lib/ezid/requests/identifier_request.rb +22 -0
  11. data/lib/ezid/requests/identifier_with_metadata_request.rb +18 -0
  12. data/lib/ezid/requests/login_request.rb +16 -0
  13. data/lib/ezid/requests/logout_request.rb +20 -0
  14. data/lib/ezid/requests/mint_identifier_request.rb +29 -0
  15. data/lib/ezid/requests/modify_identifier_request.rb +15 -0
  16. data/lib/ezid/requests/request.rb +130 -0
  17. data/lib/ezid/requests/server_status_request.rb +31 -0
  18. data/lib/ezid/responses/create_identifier_response.rb +11 -0
  19. data/lib/ezid/responses/delete_identifier_response.rb +11 -0
  20. data/lib/ezid/responses/get_identifier_metadata_response.rb +15 -0
  21. data/lib/ezid/responses/identifier_response.rb +13 -0
  22. data/lib/ezid/responses/login_response.rb +15 -0
  23. data/lib/ezid/responses/logout_response.rb +11 -0
  24. data/lib/ezid/responses/mint_identifier_response.rb +11 -0
  25. data/lib/ezid/responses/modify_identifier_response.rb +11 -0
  26. data/lib/ezid/responses/new_identifier_response.rb +17 -0
  27. data/lib/ezid/{response.rb → responses/response.rb} +0 -19
  28. data/lib/ezid/{status.rb → responses/server_status_response.rb} +3 -3
  29. data/lib/ezid/session.rb +2 -2
  30. data/lib/ezid/test_helper.rb +2 -1
  31. data/spec/integration/client_spec.rb +1 -0
  32. data/spec/unit/client_spec.rb +10 -15
  33. metadata +24 -5
  34. data/lib/ezid/request.rb +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aadca7c8873de91162829915f9f1eb4a071505a2
4
- data.tar.gz: ded517161bf42799607d34c27caf5297baa60f24
3
+ metadata.gz: 06c4a2e03acdbef8b3da067ca693fd51f8a5ba1e
4
+ data.tar.gz: 5347307f3892f3beaac5ea59e2a8d091b2ad12ac
5
5
  SHA512:
6
- metadata.gz: a8bc419ec35cbd1b0b467c3ea1e71c01066b4b0aa604bd0ac3d5e9339c91b5a74693171cd6c0a478284986fbcb6cdc3659fc6d902a77b9e2d9a601356dc1185b
7
- data.tar.gz: 3a20ac6400849df2dd6ce85c422e693627357f16c54de512c812a73a886545599c328d10ae38bff7a02a15f9d307f4d4d05d104ece70e05675ad039f7974396e
6
+ metadata.gz: acb785db04eaae33f870c1dd7ab1e292ca58b5b4dab7647b2ac15cb0daae37c3d82b4065f60380efb6530353e83c204d25d7206ec506636c19d77d751549293e
7
+ data.tar.gz: 34a9362e2dc610bf0a03c14d4174726556286d8e892a04b4eee9e4a06d9f916802bd668a64679f9e4b67402e66c1613948ed2487859301f01bf4160140aef99b
data/README.md CHANGED
@@ -27,7 +27,7 @@ Or install it yourself as:
27
27
 
28
28
  [Mint an identifier on a shoulder](http://ezid.cdlib.org/doc/apidoc.html#operation-mint-identifier)
29
29
 
30
- ```ruby
30
+ ```
31
31
  >> identifier = Ezid::Identifier.create(shoulder: "ark:/99999/fk4")
32
32
  I, [2014-12-04T15:06:02.428445 #86655] INFO -- : EZID MINT ark:/99999/fk4 -- success: ark:/99999/fk4rx9d523
33
33
  I, [2014-12-04T15:06:03.249793 #86655] INFO -- : EZID GET ark:/99999/fk4rx9d523 -- success: ark:/99999/fk4rx9d523
@@ -58,7 +58,7 @@ end
58
58
 
59
59
  New identifiers will then be minted on the default shoulder when a shoulder is not specified:
60
60
 
61
- ```ruby
61
+ ```
62
62
  >> identifier = Ezid::Identifier.create
63
63
  I, [2014-12-09T11:22:34.499860 #32279] INFO -- : EZID MINT ark:/99999/fk4 -- success: ark:/99999/fk43f4wd4v
64
64
  I, [2014-12-09T11:22:35.317181 #32279] INFO -- : EZID GET ark:/99999/fk43f4wd4v -- success: ark:/99999/fk43f4wd4v
@@ -67,7 +67,7 @@ I, [2014-12-09T11:22:35.317181 #32279] INFO -- : EZID GET ark:/99999/fk43f4wd4v
67
67
 
68
68
  [Create a specific identifier](http://ezid.cdlib.org/doc/apidoc.html#operation-create-identifier)
69
69
 
70
- ```ruby
70
+ ```
71
71
  >> identifier = Ezid::Identifier.create(id: "ark:/99999/fk4rx9d523/12345")
72
72
  I, [2014-12-09T11:21:42.077297 #32279] INFO -- : EZID CREATE ark:/99999/fk4rx9d523/12345 -- success: ark:/99999/fk4rx9d523/12345
73
73
  I, [2014-12-09T11:21:42.808534 #32279] INFO -- : EZID GET ark:/99999/fk4rx9d523/12345 -- success: ark:/99999/fk4rx9d523/12345
@@ -76,7 +76,7 @@ I, [2014-12-09T11:21:42.808534 #32279] INFO -- : EZID GET ark:/99999/fk4rx9d523
76
76
 
77
77
  **Retrieve** (Get Metadata)
78
78
 
79
- ```ruby
79
+ ```
80
80
  >> identifier = Ezid::Identifier.find("ark:/99999/fk4rx9d523")
81
81
  I, [2014-12-04T15:07:00.648676 #86655] INFO -- : EZID GET ark:/99999/fk4rx9d523 -- success: ark:/99999/fk4rx9d523
82
82
  => #<Ezid::Identifier id="ark:/99999/fk4rx9d523" status="public" target="http://ezid.cdlib.org/id/ark:/99999/fk4rx9d523" created="2014-12-04 20:06:02 UTC">
@@ -84,7 +84,7 @@ I, [2014-12-04T15:07:00.648676 #86655] INFO -- : EZID GET ark:/99999/fk4rx9d523
84
84
 
85
85
  **Update** (Modify)
86
86
 
87
- ```ruby
87
+ ```
88
88
  >> identifier.target
89
89
  => "http://ezid.cdlib.org/id/ark:/99999/fk43f4wd4v"
90
90
  >> identifier.target = "http://example.com"
@@ -101,7 +101,7 @@ I, [2014-12-09T11:24:27.039288 #32279] INFO -- : EZID GET ark:/99999/fk43f4wd4v
101
101
 
102
102
  *Identifier status must be "reserved" to delete.* http://ezid.cdlib.org/doc/apidoc.html#operation-delete-identifier
103
103
 
104
- ```ruby
104
+ ```
105
105
  >> identifier = Ezid::Identifier.create(shoulder: "ark:/99999/fk4", status: "reserved")
106
106
  I, [2014-12-04T15:12:39.976930 #86734] INFO -- : EZID MINT ark:/99999/fk4 -- success: ark:/99999/fk4n58pc0r
107
107
  I, [2014-12-04T15:12:40.693256 #86734] INFO -- : EZID GET ark:/99999/fk4n58pc0r -- success: ark:/99999/fk4n58pc0r
@@ -117,7 +117,7 @@ Accessors are provided to ease the use of EZID [reserved metadata elements](http
117
117
 
118
118
  **Reserved elements** can be read and written using the name of the element without the leading underscore:
119
119
 
120
- ```ruby
120
+ ```
121
121
  >> identifier.status # reads "_status" element
122
122
  => "public"
123
123
  >> identifier.status = "unavailable" # writes "_status" element
@@ -131,7 +131,7 @@ Notes:
131
131
 
132
132
  **Metadata profile elements** can be read and written using the name of the element, replacing the dot (".") with an underscore:
133
133
 
134
- ```ruby
134
+ ```
135
135
  >> identifier.dc_type # reads "dc.type" element
136
136
  => "Collection"
137
137
  >> identifier.dc_type = "Image" # writes "dc.type" element
@@ -167,7 +167,7 @@ end
167
167
 
168
168
  Then new identifiers will receive the defaults:
169
169
 
170
- ```ruby
170
+ ```
171
171
  >> identifier = Ezid::Identifier.create(shoulder: "ark:/99999/fk4")
172
172
  I, [2014-12-09T11:38:37.335136 #32279] INFO -- : EZID MINT ark:/99999/fk4 -- success: ark:/99999/fk4zs2w500
173
173
  I, [2014-12-09T11:38:38.153546 #32279] INFO -- : EZID GET ark:/99999/fk4zs2w500 -- success: ark:/99999/fk4zs2w500
@@ -204,15 +204,16 @@ end
204
204
  client = Ezid::Client.new(user: "eziduser", password: "ezidpass")
205
205
  ```
206
206
 
207
- ## Alternate Host and Disabling SSL
207
+ ## Alternate Host and Port
208
208
 
209
- By default `Ezid::Client` connects over SSL to the EZID host at [ezid.cdlib.org](http://ezid.cdlib.org), but the host and SSL settings may be overridden:
209
+ By default `Ezid::Client` connects via SSL over port 443 to the EZID host at [ezid.cdlib.org](https://ezid.cdlib.org), but the host, port and SSL settings may be overridden:
210
210
 
211
211
  - By environment variables:
212
212
 
213
213
  ```sh
214
214
  export EZID_HOST="localhost"
215
- export EZID_USE_SSL="false" # "false" disables SSL for all requests
215
+ export EZID_PORT=8443
216
+ export EZID_USE_SSL="true"
216
217
  ```
217
218
 
218
219
  - Client configuration:
@@ -220,14 +221,15 @@ export EZID_USE_SSL="false" # "false" disables SSL for all requests
220
221
  ```ruby
221
222
  Ezid::Client.configure do |config|
222
223
  config.host = "localhost"
223
- config.use_ssl = false
224
+ config.port = 8443
225
+ config.use_ssl = true
224
226
  end
225
227
  ```
226
228
 
227
229
  - At client initialization (only if explicitly instantiating `Ezid::Client`):
228
230
 
229
231
  ```ruby
230
- client = Ezid::Client.new(host: "localhost", use_ssl: false)
232
+ client = Ezid::Client.new(host: "localhost", port: 80)
231
233
  ```
232
234
 
233
235
  ## Test Helper
@@ -244,13 +246,14 @@ The module provides constants:
244
246
  - `TEST_DOI_SHOULDER` => "doi:10.5072/FK2"
245
247
  - `TEST_USER` => "apitest"
246
248
  - `TEST_HOST` => "ezid.cdlib.org"
249
+ - `TEST_PORT` => 443
247
250
 
248
251
  The test user password is not provided - contact EZID and configure as above - or use your own EZID credentials, since all accounts can mint/create on the test shoulders.
249
252
 
250
253
  A convenience method `ezid_test_mode!` is provided to configure the client to:
251
254
 
252
255
  - authenticate as `TEST_USER`
253
- - use `TEST_HOST` as the host
256
+ - use `TEST_HOST` as the host and `TEST_PORT` as the port
254
257
  - use `TEST_ARK_SHOULDER` as the default shoulder
255
258
  - log to the null device (instead of default STDERR)
256
259
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.0
1
+ 0.12.0
@@ -1,13 +1,13 @@
1
- require "uri"
1
+ require "net/http"
2
2
 
3
3
  require_relative "configuration"
4
- require_relative "request"
5
- require_relative "response"
6
4
  require_relative "session"
7
5
  require_relative "metadata"
8
6
  require_relative "identifier"
9
7
  require_relative "error"
10
- require_relative "status"
8
+
9
+ Dir[File.expand_path("../responses/*.rb", __FILE__)].each { |m| require m }
10
+ Dir[File.expand_path("../requests/*.rb", __FILE__)].each { |m| require m }
11
11
 
12
12
  module Ezid
13
13
  #
@@ -42,16 +42,14 @@ module Ezid
42
42
  end
43
43
  end
44
44
 
45
- attr_reader :session, :user, :password, :host, :use_ssl
45
+ attr_reader :user, :password, :host, :port, :use_ssl
46
46
 
47
47
  def initialize(opts = {})
48
- @session = Session.new
49
48
  @host = opts[:host] || config.host
50
- @use_ssl = opts.fetch(:use_ssl, config.use_ssl)
49
+ @port = (opts[:port] || config.port).to_i
50
+ @use_ssl = opts[:use_ssl] || config.use_ssl
51
51
  @user = opts[:user] || config.user
52
- raise Error, "User name is required." unless user
53
52
  @password = opts[:password] || config.password
54
- raise Error, "Password is required." unless password
55
53
  if block_given?
56
54
  login
57
55
  yield self
@@ -60,7 +58,8 @@ module Ezid
60
58
  end
61
59
 
62
60
  def inspect
63
- "#<#{self.class.name} host=\"#{host}\" user=\"#{user}\" session=#{logged_in? ? 'OPEN' : 'CLOSED'}>"
61
+ "#<#{self.class.name} connection=#{connection.inspect} " \
62
+ "user=\"#{user}\" session=#{logged_in? ? 'OPEN' : 'CLOSED'}>"
64
63
  end
65
64
 
66
65
  # The client configuration
@@ -75,6 +74,12 @@ module Ezid
75
74
  @logger ||= config.logger
76
75
  end
77
76
 
77
+ # The client session
78
+ # @return [Ezid::Session] the session
79
+ def session
80
+ @session ||= Session.new
81
+ end
82
+
78
83
  # Open a session
79
84
  # @raise [Ezid::Error]
80
85
  # @return [Ezid::Client] the client
@@ -82,10 +87,7 @@ module Ezid
82
87
  if logged_in?
83
88
  logger.info("Already logged in, skipping login request.")
84
89
  else
85
- response = Request.execute(:Get, build_uri("/login")) do |request|
86
- add_authentication(request)
87
- end
88
- handle_response(response, "LOGIN")
90
+ response = execute LoginRequest
89
91
  session.open(response.cookie)
90
92
  end
91
93
  self
@@ -95,8 +97,7 @@ module Ezid
95
97
  # @return [Ezid::Client] the client
96
98
  def logout
97
99
  if logged_in?
98
- response = Request.execute(:Get, build_uri("/logout"))
99
- handle_response(response, "LOGOUT")
100
+ execute LogoutRequest
100
101
  session.close
101
102
  else
102
103
  logger.info("Not logged in, skipping logout request.")
@@ -109,18 +110,18 @@ module Ezid
109
110
  session.open?
110
111
  end
111
112
 
113
+ # Create an identifier (PUT an existing identifier)
114
+ # @see http://ezid.cdlib.org/doc/apidoc.html#operation-create-identifier
112
115
  # @param identifier [String] the identifier string to create
113
116
  # @param metadata [String, Hash, Ezid::Metadata] optional metadata to set
114
117
  # @raise [Ezid::Error]
115
118
  # @return [Ezid::Response] the response
116
119
  def create_identifier(identifier, metadata=nil)
117
- response = Request.execute(:Put, build_uri("/id/#{identifier}")) do |request|
118
- add_authentication(request)
119
- add_metadata(request, metadata)
120
- end
121
- handle_response(response, "CREATE #{identifier}")
120
+ execute CreateIdentifierRequest, identifier, metadata
122
121
  end
123
122
 
123
+ # Mint an identifier
124
+ # @see http://ezid.cdlib.org/doc/apidoc.html#operation-mint-identifier
124
125
  # @param shoulder [String] the shoulder on which to mint a new identifier
125
126
  # @param metadata [String, Hash, Ezid::Metadata] metadata to set
126
127
  # @raise [Ezid::Error]
@@ -128,83 +129,76 @@ module Ezid
128
129
  def mint_identifier(shoulder=nil, metadata=nil)
129
130
  shoulder ||= config.default_shoulder
130
131
  raise Error, "Shoulder missing -- cannot mint identifier." unless shoulder
131
- response = Request.execute(:Post, build_uri("/shoulder/#{shoulder}")) do |request|
132
- add_authentication(request)
133
- add_metadata(request, metadata)
134
- end
135
- handle_response(response, "MINT #{shoulder}")
132
+ execute MintIdentifierRequest, shoulder, metadata
136
133
  end
137
134
 
135
+ # Modify an identifier
136
+ # @see http://ezid.cdlib.org/doc/apidoc.html#operation-modify-identifier
138
137
  # @param identifier [String] the identifier to modify
139
138
  # @param metadata [String, Hash, Ezid::Metadata] metadata to set
140
139
  # @raise [Ezid::Error]
141
140
  # @return [Ezid::Response] the response
142
141
  def modify_identifier(identifier, metadata)
143
- response = Request.execute(:Post, build_uri("/id/#{identifier}")) do |request|
144
- add_authentication(request)
145
- add_metadata(request, metadata)
146
- end
147
- handle_response(response, "MODIFY #{identifier}")
142
+ execute ModifyIdentifierRequest, identifier, metadata
148
143
  end
149
144
 
145
+ # Get the metadata for an identifier
146
+ # @see http://ezid.cdlib.org/doc/apidoc.html#operation-get-identifier-metadata
150
147
  # @param identifier [String] the identifier to retrieve
151
148
  # @raise [Ezid::Error]
152
149
  # @return [Ezid::Response] the response
153
150
  def get_identifier_metadata(identifier)
154
- response = Request.execute(:Get, build_uri("/id/#{identifier}")) do |request|
155
- add_authentication(request)
156
- end
157
- handle_response(response, "GET #{identifier}")
151
+ execute GetIdentifierMetadataRequest, identifier
158
152
  end
159
153
 
154
+ # Delete an identifier (only reserved identifier can be deleted)
155
+ # @see http://ezid.cdlib.org/doc/apidoc.html#operation-delete-identifier
160
156
  # @param identifier [String] the identifier to delete
161
157
  # @raise [Ezid::Error]
162
158
  # @return [Ezid::Response] the response
163
159
  def delete_identifier(identifier)
164
- response = Request.execute(:Delete, build_uri("/id/#{identifier}")) do |request|
165
- add_authentication(request)
166
- end
167
- handle_response(response, "DELETE #{identifier}")
160
+ execute DeleteIdentifierRequest, identifier
168
161
  end
169
162
 
163
+ # Get the EZID server status (and the status of one or more subsystems)
164
+ # @see http://ezid.cdlib.org/doc/apidoc.html#server-status
170
165
  # @param subsystems [Array]
171
166
  # @raise [Ezid::Error]
172
- # @return [Ezid::Status] the status response
167
+ # @return [Ezid::StatusResponse] the status response
173
168
  def server_status(*subsystems)
174
- response = Request.execute(:Get, build_uri("/status?subsystems=#{subsystems.join(',')}"))
175
- handle_response(Status.new(response), "STATUS")
169
+ execute ServerStatusRequest, *subsystems
170
+ end
171
+
172
+ # The Net::HTTP object used to connect to EZID
173
+ # @return [Net::HTTP] the connection
174
+ def connection
175
+ @connection ||= build_connection
176
176
  end
177
177
 
178
178
  private
179
179
 
180
- def build_uri(path)
181
- scheme = use_ssl ? "https" : "http"
182
- URI([scheme, "://", host, path].join)
183
- end
180
+ def use_ssl?
181
+ use_ssl || port == 443
182
+ end
184
183
 
185
- # Adds authentication data to the request
186
- def add_authentication(request)
187
- if session.open?
188
- request["Cookie"] = session.cookie
189
- else
190
- request.basic_auth(user, password)
191
- end
192
- end
184
+ def build_connection
185
+ conn = Net::HTTP.new(host, port)
186
+ conn.use_ssl = use_ssl?
187
+ conn
188
+ end
193
189
 
194
- # Adds EZID metadata (if any) to the request body
195
- def add_metadata(request, metadata)
196
- return if metadata.nil? || metadata.empty?
197
- metadata = Metadata.new(metadata) unless metadata.is_a?(Metadata)
198
- request.body = metadata.to_anvl(false)
199
- end
190
+ def handle_response(response, request_name)
191
+ log_level = response.error? ? Logger::ERROR : Logger::INFO
192
+ message = "EZID #{request_name} -- #{response.status_line}"
193
+ logger.log(log_level, message)
194
+ raise response.exception if response.exception
195
+ response
196
+ end
200
197
 
201
- def handle_response(response, request_info)
202
- log_level = response.error? ? Logger::ERROR : Logger::INFO
203
- message = "EZID #{request_info} -- #{response.status_line}"
204
- logger.log(log_level, message)
205
- raise response.exception if response.exception
206
- response
207
- end
198
+ def execute(request_class, *args)
199
+ response = request_class.execute(self, *args)
200
+ handle_response(response, request_class.short_name)
201
+ end
208
202
 
209
203
  end
210
204
  end
@@ -11,15 +11,20 @@ module Ezid
11
11
  class Configuration
12
12
 
13
13
  HOST = "ezid.cdlib.org"
14
+ PORT = 443
14
15
 
15
16
  # EZID host name
16
17
  # Default: value of `EZID_HOST` environment variable, if present, or
17
18
  # the EZID service host "ezid.cdlib.org".
18
19
  attr_accessor :host
19
20
 
21
+ # EZID TCP/IP port
22
+ # Default: value of `EZID_PORT` variable
23
+ attr_accessor :port
24
+
20
25
  # Use HTTPS?
21
- # Default: `true`, unless `EZID_USE_SSL` environment variable is set
22
- # to the string "false".
26
+ # Default: `nil`; `true` if `EZID_USE_SSL` environment variable is set
27
+ # to the string "true".
23
28
  attr_accessor :use_ssl
24
29
 
25
30
  # EZID user name
@@ -42,7 +47,8 @@ module Ezid
42
47
  @user = ENV["EZID_USER"]
43
48
  @password = ENV["EZID_PASSWORD"]
44
49
  @host = ENV["EZID_HOST"] || HOST
45
- @use_ssl = ENV["EZID_USE_SSL"] != false.to_s
50
+ @port = ENV["EZID_PORT"] || PORT
51
+ @use_ssl = true if ENV["EZID_USE_SSL"] == true.to_s
46
52
  @default_shoulder = ENV["EZID_DEFAULT_SHOULDER"]
47
53
  end
48
54
 
@@ -4,9 +4,7 @@ module Ezid
4
4
  #
5
5
  # EZID metadata collection for an identifier.
6
6
  #
7
- # @note Although this API is not private, its direct use is discouraged.
8
- # Instead use the metadata element accessors through Ezid::Identifier.
9
- # @api public
7
+ # @api private
10
8
  #
11
9
  class Metadata < SimpleDelegator
12
10
 
@@ -0,0 +1,15 @@
1
+ require_relative "identifier_with_metadata_request"
2
+ require_relative "../responses/create_identifier_response"
3
+
4
+ module Ezid
5
+ #
6
+ # A request to create (PUT) an identifier in EZID
7
+ # @api private
8
+ #
9
+ class CreateIdentifierRequest < IdentifierWithMetadataRequest
10
+
11
+ self.http_method = PUT
12
+ self.response_class = CreateIdentifierResponse
13
+
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "identifier_request"
2
+ require_relative "../responses/delete_identifier_response"
3
+
4
+ module Ezid
5
+ class DeleteIdentifierRequest < IdentifierRequest
6
+
7
+ self.http_method = DELETE
8
+ self.response_class = DeleteIdentifierResponse
9
+
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "identifier_request"
2
+ require_relative "../responses/get_identifier_metadata_response"
3
+
4
+ module Ezid
5
+ #
6
+ # A request to get the metadata of an identifier
7
+ # @api private
8
+ #
9
+ class GetIdentifierMetadataRequest < IdentifierRequest
10
+
11
+ self.http_method = GET
12
+ self.response_class = GetIdentifierMetadataResponse
13
+
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "request"
2
+
3
+ module Ezid
4
+ #
5
+ # @abstract
6
+ # @api private
7
+ #
8
+ class IdentifierRequest < Request
9
+
10
+ attr_reader :identifier
11
+
12
+ def initialize(client, identifier)
13
+ @identifier = identifier
14
+ super
15
+ end
16
+
17
+ def path
18
+ "/id/#{identifier}"
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "identifier_request"
2
+
3
+ module Ezid
4
+ #
5
+ # @abstract
6
+ # @api private
7
+ #
8
+ class IdentifierWithMetadataRequest < IdentifierRequest
9
+
10
+ attr_reader :metadata
11
+
12
+ def initialize(client, identifier, metadata)
13
+ @metadata = Metadata.new(metadata)
14
+ super(client, identifier)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ require_relative "request"
2
+ require_relative "../responses/login_response"
3
+
4
+ module Ezid
5
+ #
6
+ # A request to login to EZID
7
+ # @api private
8
+ #
9
+ class LoginRequest < Request
10
+
11
+ self.http_method = GET
12
+ self.path = "/login"
13
+ self.response_class = LoginResponse
14
+
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ require_relative "request"
2
+ require_relative "../responses/logout_response"
3
+
4
+ module Ezid
5
+ #
6
+ # A request to logout of EZID
7
+ # @api private
8
+ #
9
+ class LogoutRequest < Request
10
+
11
+ self.http_method = GET
12
+ self.path = "/logout"
13
+ self.response_class = LogoutResponse
14
+
15
+ def authentication_required?
16
+ false
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ require_relative "request"
2
+ require_relative "../metadata"
3
+ require_relative "../responses/mint_identifier_response"
4
+
5
+ module Ezid
6
+ #
7
+ # A request to EZID to mint a new identifier
8
+ # @api private
9
+ # @see http://ezid.cdlib.org/doc/apidoc.html#operation-modify-identifier
10
+ #
11
+ class MintIdentifierRequest < Request
12
+
13
+ self.http_method = POST
14
+ self.response_class = MintIdentifierResponse
15
+
16
+ attr_reader :shoulder, :metadata
17
+
18
+ def initialize(client, shoulder, metadata)
19
+ @shoulder = shoulder
20
+ @metadata = Metadata.new(metadata)
21
+ super
22
+ end
23
+
24
+ def path
25
+ "/shoulder/#{shoulder}"
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "identifier_with_metadata_request"
2
+ require_relative "../responses/modify_identifier_response"
3
+
4
+ module Ezid
5
+ #
6
+ # A request to modify the metadata of an identifier
7
+ # @api private
8
+ #
9
+ class ModifyIdentifierRequest < IdentifierWithMetadataRequest
10
+
11
+ self.http_method = POST
12
+ self.response_class = ModifyIdentifierResponse
13
+
14
+ end
15
+ end
@@ -0,0 +1,130 @@
1
+ require "delegate"
2
+ require "uri"
3
+ require "net/http"
4
+ require "forwardable"
5
+
6
+ require_relative "../responses/response"
7
+
8
+ module Ezid
9
+ #
10
+ # A request to the EZID service.
11
+ #
12
+ # @api private
13
+ # @abstract
14
+ #
15
+ class Request < SimpleDelegator
16
+ extend Forwardable
17
+
18
+ CHARSET = "UTF-8"
19
+ CONTENT_TYPE = "text/plain"
20
+
21
+ # HTTP methods
22
+ GET = Net::HTTP::Get
23
+ PUT = Net::HTTP::Put
24
+ POST = Net::HTTP::Post
25
+ DELETE = Net::HTTP::Delete
26
+
27
+ class << self
28
+ attr_accessor :http_method, :path, :response_class
29
+
30
+ def execute(client, *args)
31
+ request = new(client, *args)
32
+ yield request if block_given?
33
+ request.execute
34
+ end
35
+
36
+ def short_name
37
+ name.split("::").last.sub("Request", "")
38
+ end
39
+ end
40
+
41
+ attr_reader :client
42
+ def_delegators :client, :connection, :user, :password, :session
43
+
44
+ # @param client [Ezid::Client] the client
45
+ def initialize(client, *args)
46
+ @client = client
47
+ super build_request
48
+ end
49
+
50
+ # Executes the request and returns the response
51
+ # @return [Ezid::Response] the response
52
+ def execute
53
+ response_class.new(get_response_for_request)
54
+ end
55
+
56
+ # The request URI
57
+ # @return [URI] the URI
58
+ def uri
59
+ @uri ||= build_uri
60
+ end
61
+
62
+ # HTTP request path
63
+ # @return [String] the path
64
+ def path
65
+ self.class.path
66
+ end
67
+
68
+ # Class to wrap Net::HTTPResponse
69
+ # @return [Class]
70
+ def response_class
71
+ self.class.response_class || Response
72
+ end
73
+
74
+ # HTTP request query string
75
+ # @return [String] the query string
76
+ def query; end
77
+
78
+ def authentication_required?
79
+ true
80
+ end
81
+
82
+ def has_metadata?
83
+ !metadata.empty? rescue false
84
+ end
85
+
86
+ def handle_response(http_response)
87
+ response_class.new(http_response).tap do |response|
88
+ yield response if block_given?
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def get_response_for_request
95
+ connection.start do |conn|
96
+ set_content_type(CONTENT_TYPE, charset: CHARSET)
97
+ add_authentication if authentication_required?
98
+ add_metadata if has_metadata?
99
+ conn.request(__getobj__)
100
+ end
101
+ end
102
+
103
+ def build_request
104
+ self.class.http_method.new(uri)
105
+ end
106
+
107
+ def host
108
+ connection.address
109
+ end
110
+
111
+ def build_uri
112
+ uri_klass = connection.use_ssl? ? URI::HTTPS : URI::HTTP
113
+ uri_klass.build(host: host, path: path, query: query)
114
+ end
115
+
116
+ # Adds authentication data to the request
117
+ def add_authentication
118
+ if session.open?
119
+ self["Cookie"] = session.cookie
120
+ else
121
+ basic_auth(user, password)
122
+ end
123
+ end
124
+
125
+ def add_metadata
126
+ self.body = metadata.to_anvl(false)
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,31 @@
1
+ require_relative "request"
2
+ require_relative "../responses/server_status_response"
3
+
4
+ module Ezid
5
+ #
6
+ # A request for the EZID server status
7
+ # @api private
8
+ #
9
+ class ServerStatusRequest < Request
10
+
11
+ self.http_method = GET
12
+ self.path = "/status"
13
+ self.response_class = ServerStatusResponse
14
+
15
+ attr_reader :subsystems
16
+
17
+ def initialize(client, *args)
18
+ @subsystems = args
19
+ super
20
+ end
21
+
22
+ def query
23
+ "subsystems=#{subsystems.join(',')}"
24
+ end
25
+
26
+ def authentication_required?
27
+ false
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "new_identifier_response"
2
+
3
+ module Ezid
4
+ #
5
+ # Response to a create identifier request
6
+ # @api private
7
+ #
8
+ class CreateIdentifierResponse < NewIdentifierResponse
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "identifier_response"
2
+
3
+ module Ezid
4
+ #
5
+ # Response to a delete identifier request
6
+ # @api private
7
+ #
8
+ class DeleteIdentifierResponse < IdentifierResponse
9
+
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "identifier_response"
2
+
3
+ module Ezid
4
+ #
5
+ # Response to a get identifier metadata request
6
+ # @api private
7
+ #
8
+ class GetIdentifierMetadataResponse < IdentifierResponse
9
+
10
+ def metadata
11
+ content[1]
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ require_relative "response"
2
+
3
+ module Ezid
4
+ class IdentifierResponse < Response
5
+
6
+ IDENTIFIER_RE = /^(doi|ark|urn):[^\s]+/
7
+
8
+ def id
9
+ @id ||= IDENTIFIER_RE.match(message)[0]
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "response"
2
+
3
+ module Ezid
4
+ #
5
+ # Response to a login request
6
+ # @api private
7
+ #
8
+ class LoginResponse < Response
9
+
10
+ def cookie
11
+ self["Set-Cookie"].split(";").first rescue nil
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "response"
2
+
3
+ module Ezid
4
+ #
5
+ # Response to logout request
6
+ # @api private
7
+ #
8
+ class LogoutResponse < Response
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "new_identifier_response"
2
+
3
+ module Ezid
4
+ #
5
+ # Response to a mint identifier request
6
+ # @api private
7
+ #
8
+ class MintIdentifierResponse < NewIdentifierResponse
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "identifier_response"
2
+
3
+ module Ezid
4
+ #
5
+ # Response to a Ezid::ModifyIdentifierRequest
6
+ # @api private
7
+ #
8
+ class ModifyIdentifierResponse < IdentifierResponse
9
+
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "identifier_response"
2
+
3
+ module Ezid
4
+ #
5
+ # A response to a mint or create request to make a new identifier in EZID
6
+ # @api private
7
+ #
8
+ class NewIdentifierResponse < IdentifierResponse
9
+
10
+ SHADOW_ARK_RE = /\| (ark:[^\s]+)/
11
+
12
+ def shadow_ark
13
+ @shadow_ark ||= SHADOW_ARK_RE.match(message)[1]
14
+ end
15
+
16
+ end
17
+ end
@@ -14,21 +14,6 @@ module Ezid
14
14
  # Error response status
15
15
  ERROR = "error"
16
16
 
17
- IDENTIFIER_RE = /^(doi|ark|urn):[^\s]+/
18
- SHADOW_ARK_RE = /\| (ark:[^\s]+)/
19
-
20
- def id
21
- @id ||= IDENTIFIER_RE.match(message)[0]
22
- end
23
-
24
- def shadow_ark
25
- @shadow_ark ||= SHADOW_ARK_RE.match(message)[1]
26
- end
27
-
28
- def metadata
29
- content[1]
30
- end
31
-
32
17
  # The response status -- "success" or "error"
33
18
  # @return [String] the status
34
19
  def status
@@ -83,9 +68,5 @@ module Ezid
83
68
  __getobj__.uri.path
84
69
  end
85
70
 
86
- def cookie
87
- self["Set-Cookie"].split(";").first rescue nil
88
- end
89
-
90
71
  end
91
72
  end
@@ -1,11 +1,11 @@
1
+ require_relative "response"
2
+
1
3
  module Ezid
2
4
  #
3
5
  # A response to an EZID status request
4
- #
5
- # @see Ezid::Response
6
6
  # @api private
7
7
  #
8
- class Status < SimpleDelegator
8
+ class ServerStatusResponse < Response
9
9
 
10
10
  SUBSYSTEMS = %w( noid ldap datacite )
11
11
 
@@ -8,8 +8,8 @@ module Ezid
8
8
 
9
9
  attr_reader :cookie
10
10
 
11
- def initialize(response=nil)
12
- open(response) if response
11
+ def initialize(cookie=nil)
12
+ open(cookie) if cookie
13
13
  end
14
14
 
15
15
  def inspect
@@ -8,6 +8,7 @@ module Ezid
8
8
 
9
9
  TEST_USER = "apitest"
10
10
  TEST_HOST = Configuration::HOST
11
+ TEST_PORT = Configuration::PORT
11
12
  TEST_SHOULDER = TEST_ARK_SHOULDER
12
13
 
13
14
  def ezid_test_mode!
@@ -15,7 +16,7 @@ module Ezid
15
16
  config.user = ENV["EZID_TEST_USER"] || TEST_USER
16
17
  config.password = ENV["EZID_TEST_PASSWORD"]
17
18
  config.host = ENV["EZID_TEST_HOST"] || TEST_HOST
18
- config.use_ssl = true
19
+ config.port = ENV["EZID_TEST_PORT"] || TEST_PORT
19
20
  config.logger = Logger.new(File::NULL)
20
21
  config.default_shoulder = ENV["EZID_TEST_SHOULDER"] || TEST_SHOULDER
21
22
  end
@@ -9,6 +9,7 @@ module Ezid
9
9
  modified = client.modify_identifier(@id, "dc.title" => "Test")
10
10
  expect(modified).to be_success
11
11
  retrieved = client.get_identifier_metadata(@id)
12
+ puts retrieved.class.to_s
12
13
  expect(retrieved).to be_success
13
14
  expect(retrieved.metadata).to match(/dc.title: Test/)
14
15
  deleted = client.delete_identifier(@id)
@@ -1,9 +1,6 @@
1
1
  module Ezid
2
2
  RSpec.describe Client do
3
3
 
4
- let(:stub_response) { Response.new(http_response) }
5
- let(:stub_uri) { double }
6
-
7
4
  describe "initialization without a block" do
8
5
  it "should not login" do
9
6
  expect_any_instance_of(described_class).not_to receive(:login)
@@ -14,9 +11,9 @@ module Ezid
14
11
  describe "#create_identifier" do
15
12
  let(:id) { "ark:/99999/fk4fn19h88" }
16
13
  let(:http_response) { double(body: "success: ark:/99999/fk4fn19h88") }
14
+ let(:stub_response) { CreateIdentifierResponse.new(http_response) }
17
15
  before do
18
- allow(subject).to receive(:build_uri).with("/id/#{id}") { stub_uri }
19
- allow(Request).to receive(:execute).with(:Put, stub_uri) { stub_response }
16
+ allow(CreateIdentifierRequest).to receive(:execute).with(subject, id, nil) { stub_response }
20
17
  end
21
18
  it "should be a success" do
22
19
  response = subject.create_identifier(id)
@@ -26,14 +23,12 @@ module Ezid
26
23
  end
27
24
 
28
25
  describe "#mint_identifier" do
26
+ let(:stub_response) { MintIdentifierResponse.new(http_response) }
29
27
  before do
30
- allow(Request).to receive(:execute).with(:Post, stub_uri) { stub_response }
28
+ allow(MintIdentifierRequest).to receive(:execute).with(subject, TEST_ARK_SHOULDER, nil) { stub_response }
31
29
  end
32
30
  describe "which is an ARK" do
33
31
  let(:http_response) { double(body: "success: ark:/99999/fk4fn19h88") }
34
- before do
35
- allow(subject).to receive(:build_uri).with("/shoulder/#{TEST_ARK_SHOULDER}") { stub_uri }
36
- end
37
32
  it "should be a success" do
38
33
  response = subject.mint_identifier(TEST_ARK_SHOULDER)
39
34
  expect(response).to be_success
@@ -52,7 +47,7 @@ datacite.resourcetype: Other
52
47
  EOS
53
48
  end
54
49
  before do
55
- allow(subject).to receive(:build_uri).with("/shoulder/#{TEST_DOI_SHOULDER}") { stub_uri }
50
+ allow(MintIdentifierRequest).to receive(:execute).with(subject, TEST_DOI_SHOULDER, metadata) { stub_response }
56
51
  end
57
52
  it "should be a sucess" do
58
53
  response = subject.mint_identifier(TEST_DOI_SHOULDER, metadata)
@@ -65,7 +60,7 @@ EOS
65
60
  let(:http_response) { double(body: "success: ark:/99999/fk4fn19h88") }
66
61
  context "and the :default_shoulder config option is set" do
67
62
  before do
68
- allow(subject).to receive(:build_uri).with("/shoulder/#{TEST_ARK_SHOULDER}") { stub_uri }
63
+ allow(MintIdentifierRequest).to receive(:execute).with(subject, TEST_ARK_SHOULDER, nil) { stub_response }
69
64
  allow(Client.config).to receive(:default_shoulder) { TEST_ARK_SHOULDER }
70
65
  end
71
66
  it "should use the default shoulder" do
@@ -98,9 +93,9 @@ _status: public
98
93
  EOS
99
94
  )
100
95
  end
96
+ let(:stub_response) { GetIdentifierMetadataResponse.new(http_response) }
101
97
  before do
102
- allow(subject).to receive(:build_uri).with("/id/#{id}") { stub_uri }
103
- allow(Request).to receive(:execute).with(:Get, stub_uri) { stub_response }
98
+ allow(GetIdentifierMetadataRequest).to receive(:execute).with(subject, id) { stub_response }
104
99
  end
105
100
  it "should retrieve the metadata" do
106
101
  response = subject.get_identifier_metadata(id)
@@ -119,6 +114,7 @@ EOS
119
114
  end
120
115
 
121
116
  describe "server status" do
117
+ let(:stub_response) { ServerStatusResponse.new(http_response) }
122
118
  let(:http_response) do
123
119
  double(body: <<-EOS
124
120
  success: EZID is up
@@ -128,8 +124,7 @@ EOS
128
124
  )
129
125
  end
130
126
  before do
131
- allow(subject).to receive(:build_uri).with("/status?subsystems=*") { stub_uri }
132
- allow(Request).to receive(:execute).with(:Get, stub_uri) { stub_response }
127
+ allow(ServerStatusRequest).to receive(:execute).with(subject, "*") { stub_response }
133
128
  end
134
129
  it "should report the status of EZID and subsystems" do
135
130
  response = subject.server_status("*")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ezid-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Chandek-Stark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-21 00:00:00.000000000 Z
11
+ date: 2015-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -74,10 +74,29 @@ files:
74
74
  - lib/ezid/error.rb
75
75
  - lib/ezid/identifier.rb
76
76
  - lib/ezid/metadata.rb
77
- - lib/ezid/request.rb
78
- - lib/ezid/response.rb
77
+ - lib/ezid/requests/create_identifier_request.rb
78
+ - lib/ezid/requests/delete_identifier_request.rb
79
+ - lib/ezid/requests/get_identifier_metadata_request.rb
80
+ - lib/ezid/requests/identifier_request.rb
81
+ - lib/ezid/requests/identifier_with_metadata_request.rb
82
+ - lib/ezid/requests/login_request.rb
83
+ - lib/ezid/requests/logout_request.rb
84
+ - lib/ezid/requests/mint_identifier_request.rb
85
+ - lib/ezid/requests/modify_identifier_request.rb
86
+ - lib/ezid/requests/request.rb
87
+ - lib/ezid/requests/server_status_request.rb
88
+ - lib/ezid/responses/create_identifier_response.rb
89
+ - lib/ezid/responses/delete_identifier_response.rb
90
+ - lib/ezid/responses/get_identifier_metadata_response.rb
91
+ - lib/ezid/responses/identifier_response.rb
92
+ - lib/ezid/responses/login_response.rb
93
+ - lib/ezid/responses/logout_response.rb
94
+ - lib/ezid/responses/mint_identifier_response.rb
95
+ - lib/ezid/responses/modify_identifier_response.rb
96
+ - lib/ezid/responses/new_identifier_response.rb
97
+ - lib/ezid/responses/response.rb
98
+ - lib/ezid/responses/server_status_response.rb
79
99
  - lib/ezid/session.rb
80
- - lib/ezid/status.rb
81
100
  - lib/ezid/test_helper.rb
82
101
  - spec/integration/client_spec.rb
83
102
  - spec/integration/identifier_spec.rb
@@ -1,44 +0,0 @@
1
- require "delegate"
2
- require "uri"
3
- require "net/http"
4
-
5
- module Ezid
6
- #
7
- # A request to the EZID service.
8
- #
9
- # @api private
10
- #
11
- class Request < SimpleDelegator
12
-
13
- CHARSET = "UTF-8"
14
- CONTENT_TYPE = "text/plain"
15
-
16
- def self.execute(*args)
17
- request = new(*args)
18
- yield request if block_given?
19
- request.execute
20
- end
21
-
22
- # @param method [Symbol] the Net::HTTP constant for the request method
23
- # @param uri [URI] the uri
24
- def initialize(method, uri)
25
- http_method = Net::HTTP.const_get(method)
26
- super(http_method.new(uri))
27
- set_content_type(CONTENT_TYPE, charset: CHARSET)
28
- end
29
-
30
- # Executes the request and returns the response
31
- # @return [Ezid::Response] the response
32
- def execute
33
- http_response = Net::HTTP.start(uri.host, use_ssl: use_ssl?) do |http|
34
- http.request(__getobj__)
35
- end
36
- Response.new(http_response)
37
- end
38
-
39
- def use_ssl?
40
- uri.is_a?(URI::HTTPS)
41
- end
42
-
43
- end
44
- end