duracloud-client 0.4.0 → 0.5.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: 850dd8765ce4680a9a81f7453970ac9d8a33ec6d
4
- data.tar.gz: 64f6a963ed6453f7f77af4ed9efbc93200417dfc
3
+ metadata.gz: 60ab1ee918d1618f1f9fe31e0bad7461246a1f9c
4
+ data.tar.gz: 4430b99f0f2a1d98845139e26113179610f7ac57
5
5
  SHA512:
6
- metadata.gz: a938f8b35fe0b32f4d6e73ac80c741adedd32c91513508f64e6cb63486299cff015cb38a394b22df2f1b56fe76024939ce06c1c3968a247406d0d069e08bd9bb
7
- data.tar.gz: 303f6bbedfb8db0950ab9ffece57ba5989fa575dd0ed4b290004f4d13a91dfc88a252b83034bfc1503e1c81c6acfe5fe0b897da2b004ab9ab6234c86587c4128
6
+ metadata.gz: 62eeb59e57a5898783fc310aa848819779aa33eaf7c29b88296d01ff76210f459a4ad37c2c4c872a7871ab0027a757537e24e78fa2aacf6f45d27427d25e8bf3
7
+ data.tar.gz: 24006ad94935c937a5e3a9188b4c42946e9cf485ceb3e643fb4ca14531805e70ff77b341ca4f2ef90c97cac06094dd4727e01ca6e1064ecb8dca546714e45f98
data/README.md CHANGED
@@ -276,6 +276,17 @@ D, [2016-05-19T13:37:39.831013 #28754] DEBUG -- : Duracloud::Client GET https://
276
276
  => ["space_id", "content_id", "md5"]
277
277
  ```
278
278
 
279
+ *Added in v0.5.0: Support for asynchronous generation of manifest (Generate Manifest API)*
280
+
281
+ ```
282
+ >> manifest = Duracloud::Manifest.new('ddr-validation')
283
+ => #<Duracloud::Manifest:0x007f8fd82fe328 @space_id="ddr-validation", @store_id=nil>
284
+ >> manifest.generate
285
+ D, [2017-06-06T20:49:50.191301 #92029] DEBUG -- : Duracloud::Client POST https://duke.duracloud.org/durastore/manifest/ddr-validation 202 Accepted
286
+ I, [2017-06-06T20:49:50.191414 #92029] INFO -- : We are processing your manifest generation request. To retrieve your file, please poll the URI in the Location header of this response: (https://duke.duracloud.org/durastore/x-duracloud-admin/generated-manifests/manifest-ddr-validation_amazon_s3_2017-06-07-00-49-50.txt.gz).
287
+ => "https://duke.duracloud.org/durastore/x-duracloud-admin/generated-manifests/manifest-ddr-validation_amazon_s3_2017-06-07-00-49-50.txt.gz"
288
+ ```
289
+
279
290
  #### Bit Integrity Report
280
291
 
281
292
  ```
@@ -1,3 +1,6 @@
1
+ require 'tempfile'
2
+ require 'zlib'
3
+
1
4
  module Duracloud
2
5
  class Manifest
3
6
  include TSV
@@ -5,6 +8,9 @@ module Duracloud
5
8
  TSV_FORMAT = "TSV"
6
9
  BAGIT_FORMAT = "BAGIT"
7
10
 
11
+ MAX_TRIES = 120
12
+ RETRY_SLEEP = 10
13
+
8
14
  attr_reader :space_id, :store_id
9
15
 
10
16
  def initialize(space_id, store_id = nil)
@@ -30,6 +36,42 @@ module Duracloud
30
36
  download(BAGIT_FORMAT, &block)
31
37
  end
32
38
 
39
+ # Request the manifest for the space to be generated.
40
+ # @param format [Symbol, String] the format of the manifest.
41
+ # Defaults to "TSV".
42
+ # @return [String] the URL of the generated manifest when available.
43
+ # @raise [Duracloud::NotFoundError]
44
+ # @note format parameter changed from positional to keyword argument
45
+ # in v0.5.0.
46
+ def generate(format: TSV_FORMAT)
47
+ fmt = format.to_s.upcase
48
+ response = Client.generate_manifest(space_id, query(fmt))
49
+ response.header["Location"].first
50
+ end
51
+
52
+ # Downloads the generated manifest
53
+ # @yield [String] chunk of the manifest
54
+ # @param format [Symbol, String] the format of the manifest.
55
+ # Defaults to "TSV".
56
+ # @param max_tries [Integer] max number of times to check the generated URL.
57
+ # @param retry_sleep [Integer] number of seconds between re-checks of the
58
+ # generated URL.
59
+ # @raise [Duracloud::NotFoundError
60
+ def download_generated(format: TSV_FORMAT, max_tries: MAX_TRIES, retry_sleep: RETRY_SLEEP, &block)
61
+ url = generate(format: format)
62
+ check_generated(url, max_tries, retry_sleep)
63
+ Tempfile.open(["download", ".gz"], encoding: "ascii-8bit") do |gz_file|
64
+ client.execute(Request, :get, url) do |chunk|
65
+ gz_file.write(chunk)
66
+ end
67
+ gz_file.close
68
+ Zlib::GzipReader.open(gz_file.path) do |unzipped|
69
+ unzipped.each { |line| yield(line) }
70
+ end
71
+ end
72
+ url
73
+ end
74
+
33
75
  # Downloads the manifest
34
76
  # @yield [String] chunk of the manifest, if block given.
35
77
  # @param format [Symbol, String] the format of the manifest.
@@ -37,7 +79,9 @@ module Duracloud
37
79
  # @return [Duracloud::Response, String] the response, if block
38
80
  # given, or the manifest content, if no block.
39
81
  # @raise [Duracloud::NotFoundError]
40
- def download(format = TSV_FORMAT, &block)
82
+ # @note format parameter changed from positional to keyword argument
83
+ # in v0.5.0.
84
+ def download(format: TSV_FORMAT, &block)
41
85
  fmt = format.to_s.upcase
42
86
  if block_given?
43
87
  get_response(fmt, &block)
@@ -48,6 +92,27 @@ module Duracloud
48
92
 
49
93
  private
50
94
 
95
+ def client
96
+ @client ||= Client.new
97
+ end
98
+
99
+ def check_generated(url, max_tries, retry_sleep)
100
+ tries = 0
101
+ begin
102
+ tries += 1
103
+ client.logger.debug "Checking for generated manifest (try #{tries}/#{max_tries}) ... "
104
+ client.execute(Request, :head, url)
105
+ rescue NotFoundError => e
106
+ if tries < max_tries
107
+ client.logger.debug "Retrying in #{retry_sleep} seconds ..."
108
+ sleep(retry_sleep)
109
+ retry
110
+ else
111
+ raise
112
+ end
113
+ end
114
+ end
115
+
51
116
  def get_response(format, &block)
52
117
  Client.get_manifest(space_id, query(format), &block)
53
118
  end
@@ -1,83 +1,108 @@
1
1
  module Duracloud
2
2
  module RestMethods
3
3
 
4
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetStores
4
5
  def get_stores
5
6
  durastore(:get, "stores")
6
7
  end
7
8
 
9
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetSpaces
8
10
  def get_spaces(**query)
9
11
  durastore(:get, "spaces", **query)
10
12
  end
11
13
 
14
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetSpace
12
15
  def get_space(space_id, **query)
13
16
  durastore(:get, space_id, **query)
14
17
  end
15
18
 
19
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetSpaceProperties
16
20
  def get_space_properties(space_id, **query)
17
21
  durastore(:head, space_id, **query)
18
22
  end
19
23
 
24
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetSpaceACLs
20
25
  def get_space_acls(space_id, **query)
21
26
  durastore(:head, "acl/#{space_id}", **query)
22
27
  end
23
28
 
29
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-SetSpaceACLs
24
30
  def set_space_acls(space_id, **options)
25
31
  durastore(:post, "acl/#{space_id}", **options)
26
32
  end
27
33
 
34
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-CreateSpace
28
35
  def create_space(space_id, **query)
29
36
  durastore(:put, space_id, **query)
30
37
  end
31
38
 
39
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-DeleteSpace
32
40
  def delete_space(space_id, **query)
33
41
  durastore(:delete, space_id, **query)
34
42
  end
35
43
 
44
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetContent
36
45
  def get_content(space_id, content_id, **options, &block)
37
46
  durastore_content(:get, space_id, content_id, **options, &block)
38
47
  end
39
48
 
49
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetContentProperties
40
50
  def get_content_properties(space_id, content_id, **options)
41
51
  durastore_content(:head, space_id, content_id, **options)
42
52
  end
43
53
 
54
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-SetContentProperties
44
55
  def set_content_properties(space_id, content_id, **options)
45
56
  durastore_content(:post, space_id, content_id, **options)
46
57
  end
47
58
 
59
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-StoreContent
48
60
  def store_content(space_id, content_id, **options)
49
61
  durastore_content(:put, space_id, content_id, **options)
50
62
  end
51
63
 
64
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-CopyContent
52
65
  def copy_content(target_space_id, target_content_id, **options)
53
66
  durastore_content(:put, target_space_id, target_content_id, **options)
54
67
  end
55
68
 
69
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-DeleteContent
56
70
  def delete_content(space_id, content_id, **options)
57
71
  durastore_content(:delete, space_id, content_id, **options)
58
72
  end
59
73
 
74
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetAuditLog
60
75
  def get_audit_log(space_id, **query)
61
76
  durastore(:get, "audit/#{space_id}", **query)
62
77
  end
63
78
 
79
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetManifest
64
80
  def get_manifest(space_id, **query, &block)
65
81
  durastore(:get, "manifest/#{space_id}", **query, &block)
66
82
  end
67
83
 
84
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GenerateManifest
85
+ def generate_manifest(space_id, **query)
86
+ durastore(:post, "manifest/#{space_id}", **query)
87
+ end
88
+
89
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetBitIntegrityReport
68
90
  def get_bit_integrity_report(space_id, **query)
69
91
  durastore(:get, "bit-integrity/#{space_id}", **query)
70
92
  end
71
93
 
94
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetBitIntegrityReportProperties
72
95
  def get_bit_integrity_report_properties(space_id, **query)
73
96
  durastore(:head, "bit-integrity/#{space_id}", **query)
74
97
  end
75
98
 
99
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-GetTasks
76
100
  def get_tasks(**query)
77
101
  raise NotImplementedError,
78
102
  "The API method 'Get Tasks' has not been implemented."
79
103
  end
80
104
 
105
+ # @see https://wiki.duraspace.org/display/DURACLOUDDOC/DuraCloud+REST+API#DuraCloudRESTAPI-PerformTask
81
106
  def perform_task(task_name, **query)
82
107
  raise NotImplementedError,
83
108
  "The API method 'Perform Task' has not been implemented."
@@ -1,3 +1,3 @@
1
1
  module Duracloud
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -275,6 +275,20 @@ module Duracloud
275
275
  }
276
276
  end
277
277
 
278
+ describe "generate_manifest" do
279
+ specify {
280
+ stub = stub_request(:post, "https://example.com/durastore/manifest/foo")
281
+ subject.generate_manifest("foo")
282
+ expect(stub).to have_been_requested
283
+ }
284
+ specify {
285
+ stub = stub_request(:post, "https://example.com/durastore/manifest/foo")
286
+ .with(query: {format: "BAGIT", storeID: 1})
287
+ subject.generate_manifest("foo", format: "BAGIT", storeID: 1)
288
+ expect(stub).to have_been_requested
289
+ }
290
+ end
291
+
278
292
  describe "get_bit_integrity_report" do
279
293
  specify {
280
294
  stub = stub_request(:get, "https://example.com/durastore/bit-integrity/foo")
@@ -21,5 +21,16 @@ module Duracloud
21
21
  }
22
22
  end
23
23
 
24
+ describe "#generate" do
25
+ before do
26
+ stub_request(:post, "https://example.com/durastore/manifest/myspace?format=TSV")
27
+ .to_return(status: 202,
28
+ headers: { "Location" => "https://example.com/durastore/x-duracloud-admin/generated-manifests/manifest-myspace_amazon_s3_2017-06-02-18-20-14.txt.gz" })
29
+ end
30
+ specify {
31
+ expect(subject.generate).to eq "https://example.com/durastore/x-duracloud-admin/generated-manifests/manifest-myspace_amazon_s3_2017-06-02-18-20-14.txt.gz"
32
+ }
33
+ end
34
+
24
35
  end
25
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duracloud-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.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: 2017-05-22 00:00:00.000000000 Z
11
+ date: 2017-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -222,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
222
  version: '0'
223
223
  requirements: []
224
224
  rubyforge_project:
225
- rubygems_version: 2.6.8
225
+ rubygems_version: 2.6.12
226
226
  signing_key:
227
227
  specification_version: 4
228
228
  summary: Ruby client for communicating with DuraCloud