Skip to content

Commit

Permalink
Merge branch 'release-0.10.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
dchandekstark committed Nov 1, 2017
2 parents 0d0826c + 7f0d9d9 commit d9d500f
Show file tree
Hide file tree
Showing 30 changed files with 328 additions and 364 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ language: ruby
rvm:
- 2.2
- 2.3.1
gemfile:
- gemfiles/Gemfile.activemodel-4.2
- 2.4

3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in duracloud.gemspec
gemspec

gem 'activemodel', '~> 4.2.7'
gem 'byebug'
88 changes: 39 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,21 @@ Option 1. Environment variables

Option 2. Manual configuration

```ruby
Duracloud::Client.configure do |config|
config.host = "foo.duracloud.org"
config.user = "[email protected]"
config.password = "s3cret"
end
```
*Changed in v0.10.0* Set attributes on `Duracloud` module instead of using `Duracloud::Client.configure {|config| ...}` block.

```
> c = Duracloud::Client.new
=> #<Duracloud::Client:0x007fe953a1c630 @config=#<Duracloud::Configuration host="foo.duracloud.org", port=nil, user="[email protected]">>
```
Duracloud.host = "foo.duracloud.org"
Duracloud.user = "[email protected]"
Duracloud.password = "s3cret"

#### Logging

By default, `Duracloud::Client` logs to `STDERR`. Use the `logger` config setting to change:
By default duracloud-client logs to `STDERR`. Use the `logger` config setting to change:

```ruby
Duracloud::Client.configure do |config|
config.logger = Rails.logger
end
```
Duracloud.logger = Rails.logger

You can also silence logging:

```ruby
Duracloud::Client.configure do |config|
config.silence_logging! # sets logger device to null device
end
```
Duracloud.silence_logging! # sets logger device to null device

### List Storage Providers

Expand All @@ -81,7 +66,7 @@ end

```
>> space = Duracloud::Space.create("rest-api-testing2")
D, [2016-04-29T12:12:32.641574 #28275] DEBUG -- : Duracloud::Client PUT https://foo.duracloud.org/durastore/rest-api-testing2 201 Created
D, [2016-04-29T12:12:32.641574 #28275] DEBUG -- : Duracloud::Request PUT https://foo.duracloud.org/durastore/rest-api-testing2 201 Created
=> #<Duracloud::Space space_id="rest-api-testing2", store_id="(default)">
```

Expand All @@ -91,7 +76,7 @@ A `Duracloud::BadRequestError` exception is raised if the space ID is invalid (i

```
>> space = Duracloud::Space.find("rest-api-testing")
D, [2016-04-29T12:15:12.593075 #28275] DEBUG -- : Duracloud::Client HEAD https://foo.duracloud.org/durastore/rest-api-testing 200 OK
D, [2016-04-29T12:15:12.593075 #28275] DEBUG -- : Duracloud::Request HEAD https://foo.duracloud.org/durastore/rest-api-testing 200 OK
=> #<Duracloud::Space space_id="rest-api-testing", store_id="(default)">
>> space.count
Expand All @@ -103,11 +88,11 @@ D, [2016-04-29T12:15:12.593075 #28275] DEBUG -- : Duracloud::Client HEAD https:/

A `Duracloud::NotFoundError` exception is raised if the space does not exist.

NOTE: When the object count in a space exceeds 1000, Duracloud returns "1000+" as the count. Ruby's integer coercion `to_i`
**Note:** When the object count in a space exceeds 1000, Duracloud returns `1000+` as the count. Ruby's integer coercion `to_i`
turns that string into the integer 1000. Getting an exact count above 1000 requires (on the client side) enumerating the content_ids
(below, fixed in v0.7.2 when count is >= 1000) which can take a long time for a space with a lot of content items,
since a maxiumum of 1000 ids can be retrived at one time. If an up-to-the-minute
count is not required, the storage report for the space (not yet implemented in this library) shows an exact count on a daily basis.
(below, fixed in v0.7.2 when count is >= 1000) which can take a long time for a space with a lot of content items
(a maxiumum of 1000 ids can be retrived at one time). If an up-to-the-minute
count is not required, the storage report for the space shows an exact count on a daily basis.

#### Enumerate the content IDs of the space

Expand Down Expand Up @@ -152,10 +137,11 @@ Duracloud::SyncValidation.call(space_id: 'foo', content_dir: '/var/foo/bar')
create a temporary directory which is deleted on completion of the process. If `:work_dir` is specified, no cleanup is performed.

Files created in work directory:
- `{SPACE_ID}-manifest.tsv` (DuraCloud manifest as downloaded)
- `{SPACE_ID}-md5.txt` (Munged manifest for md5deep)
- `{SPACE_ID}-audit.txt` (Output of md5deep, empty if all files match)
- `{SPACE_ID}-recheck.txt` (Out of audit recheck, if necessary)

{SPACE_ID}-manifest.tsv DuraCloud manifest as downloaded
{SPACE_ID}-md5.txt Munged manifest for md5deep
{SPACE_ID}-audit.txt Output of md5deep, empty if all files match
{SPACE_ID}-recheck.txt Output of audit recheck, if necessary

*Added in version 0.9.0* - `Duracloud::FastSyncValidation`. This variant of sync validation does not compute local hashes but instead compares the local file list (generated with `find`) to the list of content IDs in the space manifest. Local misses are rechecked as in `SyncValidation` (but without MD5 comparison).

Expand All @@ -181,6 +167,8 @@ When storing content a `Duracloud::NotFoundError` is raised if the space does no
A `Duracloud::BadRequestError` is raised if the content ID is invalid.
A `Duracloud::ConflictError` is raised if the provided MD5 digest does not match the stored digest.

**Note:** duracloud-client does not currently provide for chunking of large files as, for example, the DuraCloud Sync Tool does.

#### Retrieve an existing content item from DuraCloud

```
Expand All @@ -196,7 +184,7 @@ raised if the content ID exists and the stored digest does not match.

If a content item is not found at the content ID, `Duracloud::Content.find` will look for a "content manifest"
by appending ".dura-manifest" to the content ID. If the manifest is found, the content item is marked as
"chunked". **Caution: Working with chunked files should be considered EXPERIMENTAL.**
"chunked". **Caution: Working with chunked files should be considered EXPERIMENTAL and unsupported.**

#### Update the properties for a content item

Expand All @@ -205,20 +193,20 @@ by appending ".dura-manifest" to the content ID. If the manifest is found, the c
=> #<Duracloud::Space space_id="rest-api-testing", store_id="(default)">
>> content = space.find_content("foo3")
D, [2016-04-29T18:31:16.975749 #32379] DEBUG -- : Duracloud::Client HEAD https://foo.duracloud.org/durastore/rest-api-testing/foo3 200 OK
D, [2016-04-29T18:31:16.975749 #32379] DEBUG -- : Duracloud::Request HEAD https://foo.duracloud.org/durastore/rest-api-testing/foo3 200 OK
=> #<Duracloud::Content space_id="rest-api-testing", content_id="foo3", store_id=(default)>
>> content.properties
=> #<Duracloud::ContentProperties x-dura-meta-owner="[email protected]">
>> content.properties["x-dura-meta-creator"] = "[email protected]"
>> content.save
D, [2016-04-29T18:31:52.770195 #32379] DEBUG -- : Duracloud::Client POST https://foo.duracloud.org/durastore/rest-api-testing/foo3 200 OK
D, [2016-04-29T18:31:52.770195 #32379] DEBUG -- : Duracloud::Request POST https://foo.duracloud.org/durastore/rest-api-testing/foo3 200 OK
I, [2016-04-29T18:31:52.770293 #32379] INFO -- : Content foo3 updated successfully
=> true
>> content.properties["x-dura-meta-creator"]
D, [2016-04-29T18:32:06.465928 #32379] DEBUG -- : Duracloud::Client HEAD https://foo.duracloud.org/durastore/rest-api-testing/foo3 200 OK
D, [2016-04-29T18:32:06.465928 #32379] DEBUG -- : Duracloud::Request HEAD https://foo.duracloud.org/durastore/rest-api-testing/foo3 200 OK
=> "[email protected]"
```

Expand All @@ -234,30 +222,30 @@ Also, `:space_id` and `:content_id` arguments are not required, but default to t

```
>> content = Duracloud::Content.find(space_id: 'rest-api-testing', content_id: 'contentItem.txt')
D, [2017-01-27T17:16:45.846459 #93283] DEBUG -- : Duracloud::Client HEAD https://duke.duracloud.org/durastore/rest-api-testing/contentItem.txt 200 OK
D, [2017-01-27T17:16:45.846459 #93283] DEBUG -- : Duracloud::Request HEAD https://duke.duracloud.org/durastore/rest-api-testing/contentItem.txt 200 OK
=> #<Duracloud::Content space_id="rest-api-testing", content_id="contentItem.txt", store_id=(default)>
>> content.copy(space_id: 'rest-api-testing2')
D, [2017-01-27T17:17:59.848741 #93283] DEBUG -- : Duracloud::Client PUT https://duke.duracloud.org/durastore/rest-api-testing2/contentItem.txt 201 Created
D, [2017-01-27T17:17:59.848741 #93283] DEBUG -- : Duracloud::Request PUT https://duke.duracloud.org/durastore/rest-api-testing2/contentItem.txt 201 Created
=> #<Duracloud::Content space_id="rest-api-testing2", content_id="contentItem.txt", store_id=(default)>
```

#### Move a content item

*Added in v0.3.0; Changed in v0.4.0.*

See also *Copy a content item, above.
See also *Copy a content item*, above.

```
This is a convenience operation -- copy and delete -- not directly supported by the DuraCloud REST API.
>> content = Duracloud::Content.find(space_id: 'rest-api-testing', content_id: 'contentItem.txt')
D, [2017-01-27T17:19:41.926994 #93286] DEBUG -- : Duracloud::Client HEAD https://duke.duracloud.org/durastore/rest-api-testing/contentItem.txt 200 OK
D, [2017-01-27T17:19:41.926994 #93286] DEBUG -- : Duracloud::Request HEAD https://duke.duracloud.org/durastore/rest-api-testing/contentItem.txt 200 OK
=> #<Duracloud::Content space_id="rest-api-testing", content_id="contentItem.txt", store_id=(default)>
>> content.move(space_id: 'rest-api-testing2')
D, [2017-01-27T17:20:07.542468 #93286] DEBUG -- : Duracloud::Client PUT https://duke.duracloud.org/durastore/rest-api-testing2/contentItem.txt 201 Created
D, [2017-01-27T17:20:08.442504 #93286] DEBUG -- : Duracloud::Client DELETE https://duke.duracloud.org/durastore/rest-api-testing/contentItem.txt 200 OK
D, [2017-01-27T17:20:07.542468 #93286] DEBUG -- : Duracloud::Request PUT https://duke.duracloud.org/durastore/rest-api-testing2/contentItem.txt 201 Created
D, [2017-01-27T17:20:08.442504 #93286] DEBUG -- : Duracloud::Request DELETE https://duke.duracloud.org/durastore/rest-api-testing/contentItem.txt 200 OK
=> #<Duracloud::Content space_id="rest-api-testing2", content_id="contentItem.txt", store_id=(default)>
>> content.deleted?
Expand All @@ -274,15 +262,17 @@ D, [2017-01-27T17:20:08.442504 #93286] DEBUG -- : Duracloud::Client DELETE https
=> #<Duracloud::Content space_id="rest-api-testing", content_id="foo2", store_id=(default)>
>> content.delete
D, [2016-04-29T18:28:31.459962 #32379] DEBUG -- : Duracloud::Client DELETE https://foo.duracloud.org/durastore/rest-api-testing/foo2 200 OK
D, [2016-04-29T18:28:31.459962 #32379] DEBUG -- : Duracloud::Request DELETE https://foo.duracloud.org/durastore/rest-api-testing/foo2 200 OK
I, [2016-04-29T18:28:31.460069 #32379] INFO -- : Content foo2 deleted successfully
=> #<Duracloud::Content space_id="rest-api-testing", content_id="foo2", store_id=(default)>
>> Duracloud::Content.exist?(space_id: "rest-api-testing", content_id: "foo2")
D, [2016-04-29T18:29:03.935451 #32379] DEBUG -- : Duracloud::Client HEAD https://foo.duracloud.org/durastore/rest-api-testing/foo2 404 Not Found
D, [2016-04-29T18:29:03.935451 #32379] DEBUG -- : Duracloud::Request HEAD https://foo.duracloud.org/durastore/rest-api-testing/foo2 404 Not Found
=> false
```

*Added in v0.10.0.pre* `Duracloud::Content.delete` class method.

### Reports

The audit logs, bit integrity reports and manifests are accessible in their original TSV format and in normalized CSV tables.
Expand All @@ -295,7 +285,7 @@ The audit logs, bit integrity reports and manifests are accessible in their orig
=> #<Duracloud::AuditLog:0x007fd44c077f38 @space_id="rest-api-testing", @store_id=nil, @response=nil>
>> audit_log.csv
D, [2016-05-19T13:36:49.107520 #28754] DEBUG -- : Duracloud::Client GET https://duke.duracloud.org/durastore/audit/rest-api-testing 200 OK
D, [2016-05-19T13:36:49.107520 #28754] DEBUG -- : Duracloud::Request GET https://duke.duracloud.org/durastore/audit/rest-api-testing 200 OK
=> #<CSV::Table mode:col_or_row row_count:168>
```

Expand All @@ -307,20 +297,20 @@ D, [2016-05-19T13:36:49.107520 #28754] DEBUG -- : Duracloud::Client GET https://
=> #<Duracloud::Manifest:0x007fd44d3c7048 @space_id="rest-api-testing", @store_id=nil, @tsv_response=nil, @bagit_response=nil>
>> manifest.csv
D, [2016-05-19T13:37:39.831013 #28754] DEBUG -- : Duracloud::Client GET https://duke.duracloud.org/durastore/manifest/rest-api-testing 200 OK
D, [2016-05-19T13:37:39.831013 #28754] DEBUG -- : Duracloud::Request GET https://duke.duracloud.org/durastore/manifest/rest-api-testing 200 OK
=> #<CSV::Table mode:col_or_row row_count:10>
>> manifest.csv.headers
=> ["space_id", "content_id", "md5"]
```

*Added in v0.5.0: Support for asynchronous generation of manifest (Generate Manifest API)*
*Added in v0.5.0* Support for asynchronous generation of manifest (Generate Manifest API)

```
>> manifest = Duracloud::Manifest.new('ddr-validation')
=> #<Duracloud::Manifest:0x007f8fd82fe328 @space_id="ddr-validation", @store_id=nil>
>> manifest.generate
D, [2017-06-06T20:49:50.191301 #92029] DEBUG -- : Duracloud::Client POST https://duke.duracloud.org/durastore/manifest/ddr-validation 202 Accepted
D, [2017-06-06T20:49:50.191301 #92029] DEBUG -- : Duracloud::Request POST https://duke.duracloud.org/durastore/manifest/ddr-validation 202 Accepted
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).
=> "https://duke.duracloud.org/durastore/x-duracloud-admin/generated-manifests/manifest-ddr-validation_amazon_s3_2017-06-07-00-49-50.txt.gz"
```
Expand All @@ -333,7 +323,7 @@ D, [2016-05-19T13:37:39.831013 #28754] DEBUG -- : Duracloud::Client GET https://
=> #<Duracloud::BitIntegrityReport:0x007f88e39a2950 @space_id="rest-api-testing", @store_id=nil, @report=nil, @properties=nil>
>> bit_integrity_report.csv
D, [2016-05-19T15:39:33.538448 #29974] DEBUG -- : Duracloud::Client GET https://duke.duracloud.org/durastore/bit-integrity/rest-api-testing 200 OK
D, [2016-05-19T15:39:33.538448 #29974] DEBUG -- : Duracloud::Request GET https://duke.duracloud.org/durastore/bit-integrity/rest-api-testing 200 OK
=> #<CSV::Table mode:col_or_row row_count:8>
```

Expand Down
1 change: 0 additions & 1 deletion duracloud.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ Gem::Specification.new do |spec|
spec.add_dependency "addressable", "~> 2.5"
spec.add_dependency "hashie", "~> 3.4"
spec.add_dependency "httpclient", "~> 2.7"
spec.add_dependency "activemodel", ">= 4.2", "< 6"
spec.add_dependency "nokogiri", "~> 1.6"

spec.add_development_dependency "webmock", "~> 2.0"
Expand Down
3 changes: 0 additions & 3 deletions gemfiles/Gemfile.activemodel-4.2

This file was deleted.

3 changes: 0 additions & 3 deletions gemfiles/Gemfile.activemodel-5.0

This file was deleted.

42 changes: 34 additions & 8 deletions lib/duracloud.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
require "duracloud/version"
require "duracloud/error"
require 'logger'
require 'uri'
require 'duracloud/version'
require 'duracloud/error'

module Duracloud

autoload :AbstractEntity, "duracloud/abstract_entity"
autoload :AuditLog, "duracloud/audit_log"
autoload :BitIntegrityReport, "duracloud/bit_integrity_report"
Expand All @@ -10,24 +13,47 @@ module Duracloud
autoload :CLI, "duracloud/cli"
autoload :CommandOptions, "duracloud/command_options"
autoload :Commands, "duracloud/commands"
autoload :Configuration, "duracloud/configuration"
autoload :Connection, "duracloud/connection"
autoload :Content, "duracloud/content"
autoload :ContentManifest, "duracloud/content_manifest"
autoload :DurastoreRequest, "duracloud/durastore_request"
autoload :ErrorHandler, "duracloud/error_handler"
autoload :FastSyncValidation, "duracloud/fast_sync_validation"
autoload :Manifest, "duracloud/manifest"
autoload :Persistence, "duracloud/persistence"
autoload :Properties, "duracloud/properties"
autoload :Request, "duracloud/request"
autoload :Response, "duracloud/response"
autoload :ResponseHandler, "duracloud/response_handler"
autoload :RestMethods, "duracloud/rest_methods"
autoload :Space, "duracloud/space"
autoload :SpaceAcls, "duracloud/space_acls"
autoload :Store, "duracloud/store"
autoload :StorageReport, "duracloud/storage_report"
autoload :StorageReports, "duracloud/storage_reports"
autoload :Store, "duracloud/store"
autoload :SyncValidation, "duracloud/sync_validation"
autoload :TSV, "duracloud/tsv"

class << self
attr_accessor :host, :port, :user, :password
attr_writer :logger

def logger
@logger ||= Logger.new(STDERR)
end

def silence_logging!
self.logger = Logger.new(File::NULL)
end

def base_url
URI::HTTPS.build(host: host, port: port, path: '/')
end

def auth?
!!user
end
end

self.host = ENV["DURACLOUD_HOST"]
self.port = ENV["DURACLOUD_PORT"]
self.user = ENV["DURACLOUD_USER"]
self.password = ENV["DURACLOUD_PASSWORD"]

end
33 changes: 11 additions & 22 deletions lib/duracloud/abstract_entity.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,21 @@
require "active_model"
require 'hashie'

module Duracloud
class AbstractEntity
include ActiveModel::Model
extend ActiveModel::Callbacks

define_model_callbacks :save, :delete, :load_properties
after_save :persisted!
after_save :reset_properties
after_load_properties :persisted!
before_delete :reset_properties
after_delete :deleted!
after_delete :freeze
class AbstractEntity < Hashie::Dash

def save
raise Error, "Cannot save deleted #{self.class}." if deleted?
run_callbacks :save do
do_save
end
do_save
persisted!
reset_properties
end

def delete
raise Error, "Cannot delete, already deleted." if deleted?
run_callbacks :delete do
do_delete
end
reset_properties
do_delete
deleted!
freeze
end

def persisted?
Expand All @@ -45,11 +36,9 @@ def properties
@properties ||= Properties.new
end


def load_properties
run_callbacks :load_properties do
do_load_properties
end
do_load_properties
persisted!
end

private
Expand Down
Loading

0 comments on commit d9d500f

Please sign in to comment.