ezid-client 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40cb3555f7bca7cbb5a29841afc004e9d00ebeaa
4
- data.tar.gz: 07da9b35895929c94079f2ef82a24e511bb6f89a
3
+ metadata.gz: fbe64c4c33da9f4e797d596ea878a03b79757e23
4
+ data.tar.gz: 899e1b115a2d2be8c7958c6143c97e3d308df923
5
5
  SHA512:
6
- metadata.gz: 6eb587dffe69c56bd119fcfbebcd06e58d3bc6cf4f7a5a5dcced275411b675e70ebebb0dcf1c19e21e4369b9673235d439860893be455c6e8d1b85f5de11284a
7
- data.tar.gz: c29ec20b8fd8dae31c8e4e60afe0210c460b9817e6367c2284a9fe2045d43638705891dce0a148ad8ce8fc14e00ea70561ba878a963614d1c351e850cfaa0a82
6
+ metadata.gz: 5c720cbfa1e104e7b371b7374e9714a0a4b4a1a7e264d58ef49e85f74ce41c4b4e25a5c987965ffc0b6b6179adbbeffec5dc4b4124471ed243264d16ff2f85ca
7
+ data.tar.gz: b23da5c4d41d643e541683f799c830f979d68a212229ebdd3930bb9f6a65733a2ceecbcfaf28dd5c83d49bfe2b7eba086408dd0d5c17ac4cc41867556cbef7ef
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1
4
+ - 2.0.0
5
+ cache:
6
+ - bundler
7
+ env: SPEC_OPTS="--tag ~type:feature"
8
+ notifications:
9
+ email:
10
+ - lib-drs@duke.edu
data/README.md CHANGED
@@ -16,73 +16,52 @@ Or install it yourself as:
16
16
 
17
17
  $ gem install ezid-client
18
18
 
19
- ## Basic Usage
19
+ ## Resource-oriented Usage (CRUD)
20
20
 
21
- See `Ezid::Client` class for details.
21
+ Create (Mint)
22
22
 
23
- **Create a client**
24
-
25
- ```
26
- >> client = Ezid::Client.new(user: "apitest")
27
- => #<Ezid::Client:0x007f8ce651a890 , @user="apitest", @password="********">
28
- ```
29
-
30
- Initialize with a block (wraps in a session)
31
-
32
- ```
33
- >> Ezid::Client.new(user: "apitest") do |client|
34
- ?> client.server_status("*")
35
- >> end
36
- I, [2014-11-20T13:23:23.120797 #86059] INFO -- : success: session cookie returned
37
- I, [2014-11-20T13:23:25.336596 #86059] INFO -- : success: EZID is up
38
- I, [2014-11-20T13:23:25.804790 #86059] INFO -- : success: authentication credentials flushed
39
- => #<Ezid::Client:0x007faa5a6a9ee0 , @user="apitest", @password="********">
40
- ```
41
-
42
- **Login**
43
-
44
- Note that login is not required to send authenticated requests; it merely establishes a session. See http://ezid.cdlib.org/doc/apidoc.html#authentication.
45
-
46
- ```
47
- >> client.login
48
- I, [2014-11-20T13:10:50.958378 #85954] INFO -- : success: session cookie returned
49
- => #<Ezid::Client:0x007f8ce651a890 LOGGED_IN, @user="apitest", @password="********">
23
+ ```ruby
24
+ >> identifier = Ezid::Identifier.create(shoulder: "ark:/99999/fk4")
25
+ I, [2014-12-04T15:06:02.428445 #86655] INFO -- : EZID MINT ark:/99999/fk4 -- success: ark:/99999/fk4rx9d523
26
+ I, [2014-12-04T15:06:03.249793 #86655] INFO -- : EZID GET ark:/99999/fk4rx9d523 -- success: ark:/99999/fk4rx9d523
27
+ => #<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">
28
+ >> identifier.id
29
+ => "ark:/99999/fk4rx9d523"
30
+ >> identifier.status
31
+ => "public"
32
+ >> identifier.target
33
+ => "http://ezid.cdlib.org/id/ark:/99999/fk4rx9d523"
50
34
  ```
51
35
 
52
- **Mint an identifier**
36
+ Retrieve (Get)
53
37
 
54
- ```
55
- >> response = client.mint_identifier("ark:/99999/fk4")
56
- I, [2014-11-20T13:11:25.894128 #85954] INFO -- : success: ark:/99999/fk4fn19h87
57
- => #<Net::HTTPCreated 201 CREATED readbody=true>
58
- >> response.identifier
59
- => "ark:/99999/fk4fn19h87"
38
+ ```ruby
39
+ >> identifier = Ezid::Identifier.find("ark:/99999/fk4rx9d523")
40
+ I, [2014-12-04T15:07:00.648676 #86655] INFO -- : EZID GET ark:/99999/fk4rx9d523 -- success: ark:/99999/fk4rx9d523
41
+ => #<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">
60
42
  ```
61
43
 
62
- **Get identifier metadata**
44
+ Update (Modify)
63
45
 
64
- ```
65
- >> response = client.get_identifier_metadata(response.identifier)
66
- I, [2014-11-20T13:12:08.700287 #85954] INFO -- : success: ark:/99999/fk4fn19h87
67
- => #<Net::HTTPOK 200 OK readbody=true>
68
- >> puts response.metadata
69
- _updated: 1416507086
70
- _target: http://ezid.cdlib.org/id/ark:/99999/fk4fn19h87
71
- _profile: erc
72
- _ownergroup: apitest
73
- _owner: apitest
74
- _export: yes
75
- _created: 1416507086
76
- _status: public
77
- => nil
46
+ ```ruby
47
+ >> identifier.target = "http://example.com"
48
+ => "http://example.com"
49
+ >> identifier.save
50
+ I, [2014-12-04T15:11:57.263906 #86734] INFO -- : EZID MODIFY ark:/99999/fk4rx9d523 -- success: ark:/99999/fk4rx9d523
51
+ I, [2014-12-04T15:11:58.099128 #86734] INFO -- : EZID GET ark:/99999/fk4rx9d523 -- success: ark:/99999/fk4rx9d523
52
+ => #<Ezid::Identifier id="ark:/99999/fk4rx9d523" status="public" target="http://example.com" created="2014-12-04 20:06:02 UTC">
78
53
  ```
79
54
 
80
- **Logout**
55
+ Delete
81
56
 
82
- ```
83
- >> client.logout
84
- I, [2014-11-20T13:18:47.213566 #86059] INFO -- : success: authentication credentials flushed
85
- => #<Ezid::Client:0x007faa5a712350 , @user="apitest", @password="********">
57
+ ```ruby
58
+ >> identifier = Ezid::Identifier.create(shoulder: "ark:/99999/fk4", status: "reserved")
59
+ I, [2014-12-04T15:12:39.976930 #86734] INFO -- : EZID MINT ark:/99999/fk4 -- success: ark:/99999/fk4n58pc0r
60
+ I, [2014-12-04T15:12:40.693256 #86734] INFO -- : EZID GET ark:/99999/fk4n58pc0r -- success: ark:/99999/fk4n58pc0r
61
+ => #<Ezid::Identifier id="ark:/99999/fk4n58pc0r" status="reserved" target="http://ezid.cdlib.org/id/ark:/99999/fk4n58pc0r" created="2014-12-04 20:12:39 UTC">
62
+ >> identifier.delete
63
+ I, [2014-12-04T15:12:48.853964 #86734] INFO -- : EZID DELETE ark:/99999/fk4n58pc0r -- success: ark:/99999/fk4n58pc0r
64
+ => #<Ezid::Identifier id="ark:/99999/fk4n58pc0r" DELETED>
86
65
  ```
87
66
 
88
67
  ## Metadata handling
@@ -104,7 +83,7 @@ Ezid::Client.configure do |config|
104
83
  end
105
84
  ```
106
85
 
107
- - At client initialization:
86
+ - At client initialization (only if using Ezid::Client explicity):
108
87
 
109
88
  ```ruby
110
89
  client = Ezid::Client.new(user: "eziduser", password: "ezidpass")
@@ -112,9 +91,9 @@ client = Ezid::Client.new(user: "eziduser", password: "ezidpass")
112
91
 
113
92
  ## Running the tests
114
93
 
115
- By default the tests authenticate as user "apitest"; the password is not provided -- see http://ezid.cdlib.org/doc/apidoc.html#testing-the-api.
94
+ See http://ezid.cdlib.org/doc/apidoc.html#testing-the-api.
116
95
 
117
- The test suite uses [VCR](https://relishapp.com/vcr/vcr) and [WebMock](https://github.com/bblimke/webmock) to stub requests and responses after the first run. The VCR "cassettes" are written to `spec/cassettes` and may be cleared with the rake task `test:clean`.
96
+ Integration tests have been tagged `type: :feature`. In order to run those tests successfully, you must supply the password for the test account "apitest" (contact EZID). You can exclude the integration tests with the RSpec option `--tag ~type:feature`.
118
97
 
119
98
  ## Contributing
120
99
 
data/Rakefile CHANGED
@@ -4,11 +4,4 @@ require "rspec/core/rake_task"
4
4
  desc "Run all specs in spec directory"
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
- namespace :test do
8
- desc "Clean up test artifacts (e.g., VCR cassettes)"
9
- task :clean do
10
- FileUtils.rm_rf File.join(__dir__, "spec", "cassettes")
11
- end
12
- end
13
-
14
7
  task default: :spec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
data/ezid-client.gemspec CHANGED
@@ -17,9 +17,11 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
+ spec.required_ruby_version = "~> 2.0"
21
+
22
+ spec.add_dependency "activesupport", "~> 4.0"
23
+
20
24
  spec.add_development_dependency "bundler", "~> 1.6"
21
25
  spec.add_development_dependency "rake"
22
26
  spec.add_development_dependency "rspec", "~> 3.0"
23
- spec.add_development_dependency "vcr"
24
- spec.add_development_dependency "webmock"
25
27
  end
data/lib/ezid/client.rb CHANGED
@@ -1,11 +1,11 @@
1
- require_relative "api"
1
+ require_relative "configuration"
2
2
  require_relative "request"
3
3
  require_relative "response"
4
- require_relative "metadata"
5
4
  require_relative "session"
6
- require_relative "configuration"
5
+ require_relative "metadata"
6
+ require_relative "identifier"
7
7
  require_relative "error"
8
- require_relative "logger"
8
+ require_relative "status"
9
9
 
10
10
  module Ezid
11
11
  #
@@ -25,33 +25,9 @@ module Ezid
25
25
  def configure
26
26
  yield config
27
27
  end
28
-
29
- # Creates an new identifier
30
- # @see #create_identifier
31
- def create_identifier(*args)
32
- Client.new.create_identifier(*args)
33
- end
34
-
35
- # Mints a new identifier
36
- # @see #mint_identifier
37
- def mint_identifier(*args)
38
- Client.new.mint_identifier(*args)
39
- end
40
-
41
- # Retrieve the metadata for an identifier
42
- # @see #get_identifier_metadata
43
- def get_identifier_metadata(*args)
44
- Client.new.get_identifier_metadata(*args)
45
- end
46
-
47
- # Logs into EZID
48
- # @see #login
49
- def login
50
- Client.new.login
51
- end
52
28
  end
53
29
 
54
- attr_reader :session, :user, :password
30
+ attr_reader :session, :user, :password # , :host
55
31
 
56
32
  def initialize(opts = {})
57
33
  @session = Session.new
@@ -65,10 +41,7 @@ module Ezid
65
41
  end
66
42
 
67
43
  def inspect
68
- out = super
69
- out.sub!(/@password="[^\"]+"/, "@password=\"********\"")
70
- out.sub!(/@session=#<[^>]+>/, logged_in? ? "LOGGED_IN" : "")
71
- out
44
+ "#<#{self.class.name} user=\"#{user}\" session=#{logged_in? ? 'OPEN' : 'CLOSED'}>"
72
45
  end
73
46
 
74
47
  # The client configuration
@@ -78,18 +51,23 @@ module Ezid
78
51
  end
79
52
 
80
53
  # The client logger
81
- # @return [Ezid::Logger] the logger
54
+ # @return [Logger] the logger
82
55
  def logger
83
- @logger ||= Ezid::Logger.new(config.logger)
56
+ @logger ||= config.logger
84
57
  end
85
58
 
86
59
  # Open a session
60
+ # @raise [Ezid::Error]
87
61
  # @return [Ezid::Client] the client
88
62
  def login
89
63
  if logged_in?
90
64
  logger.info("Already logged in, skipping login request.")
91
65
  else
92
- do_login
66
+ response = Request.execute(:Get, "/login") do |request|
67
+ add_authentication(request)
68
+ end
69
+ handle_response(response, "LOGIN")
70
+ session.open(response.cookie)
93
71
  end
94
72
  self
95
73
  end
@@ -98,7 +76,9 @@ module Ezid
98
76
  # @return [Ezid::Client] the client
99
77
  def logout
100
78
  if logged_in?
101
- do_logout
79
+ response = Request.execute(:Get, "/logout")
80
+ handle_response(response, "LOGOUT")
81
+ session.close
102
82
  else
103
83
  logger.info("Not logged in, skipping logout request.")
104
84
  end
@@ -112,104 +92,94 @@ module Ezid
112
92
 
113
93
  # @param identifier [String] the identifier string to create
114
94
  # @param metadata [String, Hash, Ezid::Metadata] optional metadata to set
95
+ # @raise [Ezid::Error]
115
96
  # @return [Ezid::Response] the response
116
97
  def create_identifier(identifier, metadata=nil)
117
- request = Request.new(:create_identifier, identifier)
118
- add_authentication(request)
119
- add_metadata(request, metadata)
120
- execute(request)
98
+ response = Request.execute(:Put, "/id/#{identifier}") do |request|
99
+ add_authentication(request)
100
+ add_metadata(request, metadata)
101
+ end
102
+ handle_response(response, "CREATE #{identifier}")
121
103
  end
122
104
 
123
105
  # @param shoulder [String] the shoulder on which to mint a new identifier
124
106
  # @param metadata [String, Hash, Ezid::Metadata] metadata to set
107
+ # @raise [Ezid::Error]
125
108
  # @return [Ezid::Response] the response
126
109
  def mint_identifier(shoulder, metadata=nil)
127
- request = Request.new(:mint_identifier, shoulder)
128
- add_authentication(request)
129
- add_metadata(request, metadata)
130
- execute(request)
110
+ raise Error, "Shoulder missing -- cannot mint identifier." unless shoulder
111
+ response = Request.execute(:Post, "/shoulder/#{shoulder}") do |request|
112
+ add_authentication(request)
113
+ add_metadata(request, metadata)
114
+ end
115
+ handle_response(response, "MINT #{shoulder}")
131
116
  end
132
117
 
133
118
  # @param identifier [String] the identifier to modify
134
119
  # @param metadata [String, Hash, Ezid::Metadata] metadata to set
120
+ # @raise [Ezid::Error]
135
121
  # @return [Ezid::Response] the response
136
122
  def modify_identifier(identifier, metadata)
137
- request = Request.new(:modify_identifier, identifier)
138
- add_authentication(request)
139
- add_metadata(request, metadata)
140
- execute(request)
123
+ response = Request.execute(:Post, "/id/#{identifier}") do |request|
124
+ add_authentication(request)
125
+ add_metadata(request, metadata)
126
+ end
127
+ handle_response(response, "MODIFY #{identifier}")
141
128
  end
142
129
 
143
130
  # @param identifier [String] the identifier to retrieve
131
+ # @raise [Ezid::Error]
144
132
  # @return [Ezid::Response] the response
145
133
  def get_identifier_metadata(identifier)
146
- request = Request.new(:get_identifier_metadata, identifier)
147
- add_authentication(request)
148
- execute(request)
134
+ response = Request.execute(:Get, "/id/#{identifier}") do |request|
135
+ add_authentication(request)
136
+ end
137
+ handle_response(response, "GET #{identifier}")
149
138
  end
150
139
 
151
140
  # @param identifier [String] the identifier to delete
141
+ # @raise [Ezid::Error]
152
142
  # @return [Ezid::Response] the response
153
143
  def delete_identifier(identifier)
154
- request = Request.new(:delete_identifier, identifier)
155
- add_authentication(request)
156
- execute(request)
144
+ response = Request.execute(:Delete, "/id/#{identifier}") do |request|
145
+ add_authentication(request)
146
+ end
147
+ handle_response(response, "DELETE #{identifier}")
157
148
  end
158
149
 
159
150
  # @param subsystems [Array]
160
- # @return [Ezid::Response] the response
151
+ # @raise [Ezid::Error]
152
+ # @return [Ezid::Status] the status response
161
153
  def server_status(*subsystems)
162
- request = Request.new(:server_status, *subsystems)
163
- execute(request)
154
+ response = Request.execute(:Get, "/status?subsystems=#{subsystems.join(',')}")
155
+ handle_response(Status.new(response), "STATUS")
164
156
  end
165
157
 
166
158
  private
167
159
 
168
- def build_request(*args)
169
- request = Request.new(*args)
170
- end
171
-
172
- # Executes the request
173
- # @param request [Ezid::Request] the request
174
- # @raise [Ezid::Error] if the response status indicates an error
175
- # @return [Ezid::Response] the response
176
- def execute(request)
177
- response = Response.new(request.execute)
178
- logger.request_and_response(request, response)
179
- raise Error, response.message if response.error?
180
- response
181
- end
182
-
183
- # Adds metadata to the request
184
- def add_metadata(request, metadata)
185
- return if metadata.nil? || metadata.empty?
186
- metadata = Metadata.new(metadata) # copy/coerce
187
- request.add_metadata(metadata)
188
- end
189
-
190
- # Adds authentication to the request
191
- def add_authentication(request)
192
- if session.open?
193
- request.add_authentication(cookie: session.cookie)
194
- else
195
- request.add_authentication(user: user, password: password)
160
+ # Adds authentication data to the request
161
+ def add_authentication(request)
162
+ if session.open?
163
+ request["Cookie"] = session.cookie
164
+ else
165
+ request.basic_auth(user, password)
166
+ end
196
167
  end
197
- end
198
168
 
199
- # Does the login
200
- def do_login
201
- request = Request.new(:login)
202
- add_authentication(request)
203
- response = execute(request)
204
- session.open(response)
205
- end
169
+ # Adds EZID metadata (if any) to the request body
170
+ def add_metadata(request, metadata)
171
+ return if metadata.nil? || metadata.empty?
172
+ metadata = Metadata.new(metadata) unless metadata.is_a?(Metadata)
173
+ request.body = metadata.to_anvl(false)
174
+ end
206
175
 
207
- # Does the logoug
208
- def do_logout
209
- request = Request.new(:logout)
210
- execute(request)
211
- session.close
212
- end
176
+ def handle_response(response, request_info)
177
+ log_level = response.error? ? Logger::ERROR : Logger::INFO
178
+ message = "EZID #{request_info} -- #{response.status_line}"
179
+ logger.log(log_level, message)
180
+ raise response.exception if response.exception
181
+ response
182
+ end
213
183
 
214
184
  end
215
185
  end
@@ -9,28 +9,43 @@ module Ezid
9
9
  # @api private
10
10
  class Configuration
11
11
 
12
- attr_writer :user, :password, :logger
12
+ # EZID user name
13
+ # Default: value of EZID_USER environment variable
14
+ attr_accessor :user
13
15
 
14
- # Default metadata profile (recommended)
15
- attr_accessor :default_metadata_profile
16
+ # EZID password
17
+ # Default: value of EZID_PASSWORD environment variable
18
+ attr_accessor :password
19
+
20
+ # Ruby logger instance
21
+ # Default device: STDERR
22
+ attr_writer :logger
23
+
24
+ # Default metadata profile
25
+ # attr_accessor :default_metadata_profile
16
26
 
17
27
  # Default status - set only if default should not "public" (EZID default)
18
- attr_accessor :default_status
28
+ # attr_accessor :default_status
19
29
 
20
- # Default shoulder for minting (recommended)
21
- attr_accessor :default_shoulder
30
+ # Default shoulder for minting
31
+ # attr_accessor :default_shoulder
22
32
 
23
- def user
24
- @user ||= ENV["EZID_USER"]
25
- end
33
+ # Hash of options to pass to Net::HTTP.start
34
+ # attr_accessor :http_request_options
26
35
 
27
- def password
28
- @password ||= ENV["EZID_PASSWORD"]
36
+ def initialize
37
+ @user = ENV["EZID_USER"]
38
+ @password = ENV["EZID_PASSWORD"]
39
+ # @http_request_options = default_http_request_options
29
40
  end
30
41
 
31
42
  def logger
32
- @logger ||= ::Logger.new(STDERR)
43
+ @logger ||= Logger.new(STDERR)
33
44
  end
34
45
 
46
+ # def default_http_request_options
47
+ # { use_ssl: true }
48
+ # end
49
+
35
50
  end
36
51
  end