nightcrawler_swift 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e8ef6b380623f8ce83cfea1491c10c44bfc8ed04
4
- data.tar.gz: 9df2abbd80c6f1fceedf2dddc58d59be45e33520
3
+ metadata.gz: 206f894e8de465851f7a45dcea23615de0666dd4
4
+ data.tar.gz: 69f0ed04088e491d8d7bf1ea6e6b2c5c3bd03049
5
5
  SHA512:
6
- metadata.gz: 8fdf97c07f42e76d5b83941b2f95d8cb32270bba360369c0b28547a25151ad56290aad0ea5ecfb076d1c012fb5abf4a331c579f216ed815dd342f9f5addf97d5
7
- data.tar.gz: 9f2d5e258abc3f309cc57759a81938041ddf8ec49111276e3b4ee3bf6120edf527c875a01715b28a030aa970c508d5dbbfb185d702dd2d354e068cba11d6eff3
6
+ metadata.gz: 9432b08baae481fc88123911809c78ada1300653af4ecd1cadda04d5b3776bbdfdfb6288fd3284a42aacca7056632c1fd26f9bd1eb833401efdec43504eb9226
7
+ data.tar.gz: 1d14060fafd907d4e0185ff5612a84c087ea58234219638fae4f07eabd6d5c3d50a78b264d548d90c50e1731b60e58628a5e59267df9b8bd1ceb23536fb9b982
data/Changelog.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0
4
+
5
+ - Added support for ssl_version configuration
6
+ - Command for object metadata. Available for cli (closes #16, #17)
7
+
3
8
  ## 0.7.0
4
9
 
5
10
  - CLI now supports ```--no-cache``` which ignores the cached connection and removes the cache file if it exists (issue #12)
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nightcrawler_swift (0.7.0)
4
+ nightcrawler_swift (0.8.0)
5
+ concurrent-ruby (~> 0.8.0)
5
6
  multi_mime (>= 1.0.1)
6
7
  rest-client
7
8
 
@@ -15,6 +16,8 @@ GEM
15
16
  codeclimate-test-reporter (0.4.0)
16
17
  simplecov (>= 0.7.1, < 1.0.0)
17
18
  columnize (0.9.0)
19
+ concurrent-ruby (0.8.0)
20
+ ref (~> 1.0, >= 1.0.5)
18
21
  debugger-linecache (1.2.0)
19
22
  diff-lcs (1.2.5)
20
23
  docile (1.1.5)
@@ -23,6 +26,7 @@ GEM
23
26
  multi_mime (1.0.1)
24
27
  netrc (0.10.2)
25
28
  rake (10.3.2)
29
+ ref (1.0.5)
26
30
  rest-client (1.7.2)
27
31
  mime-types (>= 1.16, < 3.0)
28
32
  netrc (~> 0.7)
data/README.md CHANGED
@@ -74,6 +74,9 @@ config.nightcrawler_swift.ssl_client_key =
74
74
 
75
75
  # default: nil
76
76
  config.nightcrawler_swift.ssl_ca_file = "ca_certificate.pem"
77
+
78
+ #default: nil
79
+ config.nightcrawler_swift.ssl_version = "SSLv23"
77
80
  ```
78
81
 
79
82
  By default it will use ```Rails.logger``` as logger, to change that use a different logger in configurations, like:
@@ -212,6 +215,19 @@ $ nswift delete <swift_path> # nswift delete assets/robots.txt
212
215
  ```sh
213
216
  $ nswift url-for <swift_path> # nswift url-for assets/robots.txt
214
217
  ```
218
+ ```sh
219
+ $ nswift metadata <swift_path>
220
+ # {
221
+ # "date": "Tue, 31 Mar 2015 02:10:40 GMT",
222
+ # "content_type": "text/css",
223
+ # "content_length": "50013",
224
+ # "last_modified": "Wed, 15 Oct 2014 13:38:56 GMT",
225
+ # "etag": "e13839c545f32be23b942a41f3ea7724",
226
+ # "x_timestamp": "1413380335.38118",
227
+ # "cache_control": "public, max-age=604800",
228
+ # "x_trans_id": "tx824d632ef9e54685a7563-005519f838"
229
+ # }
230
+ ```
215
231
 
216
232
  For any commands you could provide a different configuration file through the _-c_/_--config_ switch, as:
217
233
 
@@ -275,6 +291,37 @@ list.execute prefix: '/some/path'
275
291
  # [{"hash": "...", "name": "/some/path/with/my_file_path.txt"}, {}, {}, ...]
276
292
  ```
277
293
 
294
+ ### Metadata
295
+
296
+ ```ruby
297
+ metadata = NightcrawlerSwift::Metadata.new
298
+ metadata.execute "my_file.css"
299
+ # {
300
+ # :date=>"Tue, 31 Mar 2015 01:46:10 GMT",
301
+ # :content_type=>"text/css",
302
+ # :content_length=>"50013",
303
+ # :last_modified=>"Wed, 15 Oct 2014 13:38:56 GMT",
304
+ # :etag=>"e13839c545f32be23b942a41f3ea7724",
305
+ # :x_timestamp=>"1413380335.38118",
306
+ # :cache_control=>"public, max-age=604800",
307
+ # :x_trans_id=>"tx92ca1becd1a74fa3ae1f2-005519fc62"
308
+ # }
309
+
310
+ # Consulting the bucket/container metadata
311
+ metadata.execute
312
+ # {
313
+ # :date=>"Tue, 31 Mar 2015 01:41:25 GMT",
314
+ # :content_type=>"application/xml; charset=utf-8",
315
+ # :content_length=>"98171",
316
+ # :x_container_object_count=>"374",
317
+ # :x_storage_policy=>"default-3x",
318
+ # :x_container_read=>".r:*",
319
+ # :x_container_bytes_used=>"7171468",
320
+ # :x_timestamp=>"1409750420.36261",
321
+ # :x_trans_id=>"tx17d8c66ab746436b8b7b6-005519fb40"
322
+ # }
323
+ ```
324
+
278
325
  ### Delete
279
326
 
280
327
  ```ruby
@@ -30,6 +30,12 @@ module NightcrawlerSwift::CLI
30
30
  @runner.log(deleted ? "success" : "failure")
31
31
  end
32
32
 
33
+ def command_metadata command
34
+ filepath = @runner.argv.first
35
+ metadata = command.new.execute(filepath)
36
+ @runner.log JSON.pretty_generate(metadata)
37
+ end
38
+
33
39
  def command_url_for command
34
40
  filepath = @runner.argv.first
35
41
  @runner.log command.new.execute(filepath)
@@ -32,6 +32,11 @@ module NightcrawlerSwift
32
32
  command: NightcrawlerSwift::Delete
33
33
  },
34
34
 
35
+ "metadata" => {
36
+ description: "Returns the object metadata in JSON format. Without <swift_path> returns the bucket/container metadata. Ex: nswift metadata assets/robots.txt",
37
+ command: NightcrawlerSwift::Metadata
38
+ },
39
+
35
40
  "url-for" => {
36
41
  description: "Returns the public url of an object. Format: nswift url-for <swift_path> Ex: nswift url-for robots.txt",
37
42
  command: NightcrawlerSwift::CLI::UrlFor
@@ -19,9 +19,18 @@ module NightcrawlerSwift
19
19
 
20
20
  protected
21
21
 
22
- def get url, args = {}
23
- prepare_args args
24
- Gateway.new(url).request {|r| r.get headers_and_params(args)}
22
+ [
23
+ :get,
24
+ :head,
25
+ :delete
26
+ ].each do |http_verb|
27
+ define_method http_verb do |*method_args|
28
+ url = method_args[0]
29
+ args = method_args[1] || {}
30
+
31
+ prepare_args args
32
+ Gateway.new(url).request {|r| r.send(http_verb, headers_and_params(args))}
33
+ end
25
34
  end
26
35
 
27
36
  def put url, args = {}
@@ -29,11 +38,6 @@ module NightcrawlerSwift
29
38
  Gateway.new(url).request {|r| r.put args[:body], headers_and_params(args)}
30
39
  end
31
40
 
32
- def delete url, args = {}
33
- prepare_args args
34
- Gateway.new(url).request {|r| r.delete headers_and_params(args)}
35
- end
36
-
37
41
  private
38
42
  def prepare_args args
39
43
  args[:headers] ||= {}
@@ -0,0 +1,13 @@
1
+ module NightcrawlerSwift
2
+ class Metadata < Command
3
+
4
+ def execute path = nil
5
+ resource_url = "#{connection.internal_url}/#{options.bucket}/#{path}"
6
+ resource_url.gsub!(/\/$/, '') unless path
7
+
8
+ response = head resource_url
9
+ response.headers.symbolize_keys
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ module NightcrawlerSwift
2
+ class MultithreadSync < Command
3
+ DEFAULT_POOL_SIZE = 5
4
+
5
+ def initialize
6
+ require 'concurrent/utilities'
7
+ require 'concurrent/executors'
8
+ @logger = NightcrawlerSwift.logger
9
+ end
10
+
11
+ def execute args = {}
12
+ pool_size = args[:pool_size] || DEFAULT_POOL_SIZE
13
+ dir_path = args[:dir_path]
14
+
15
+ @logger.info "[NightcrawlerSwift] dir_path: #{dir_path}"
16
+ @logger.info "[NightcrawlerSwift] multithread sync, #{Concurrent.processor_count} processors"
17
+
18
+ assets = Dir["#{dir_path}/**/**"].
19
+ reject {|fullpath| File.directory?(fullpath)}.
20
+ map {|fullpath|
21
+ path = fullpath.gsub("#{dir_path}/", "")
22
+ OpenStruct.new(path: path, fullpath: fullpath)
23
+ }
24
+
25
+ pool = Concurrent::FixedThreadPool.new pool_size
26
+
27
+ assets.each do |asset|
28
+ pool.post do
29
+ @logger.info "[NightcrawlerSwift] #{asset.path}"
30
+
31
+ upload = Upload.new
32
+ upload.execute asset.path, File.open(asset.fullpath, "r")
33
+ end
34
+ end
35
+
36
+ sleep(1) while pool.queue_length > 0
37
+
38
+ @logger.info "[NightcrawlerSwift] shutting down"
39
+ pool.shutdown
40
+ pool.wait_for_termination
41
+ end
42
+
43
+ end
44
+ end
@@ -59,7 +59,8 @@ module NightcrawlerSwift
59
59
  :verify_ssl,
60
60
  :ssl_client_cert,
61
61
  :ssl_client_key,
62
- :ssl_ca_file
62
+ :ssl_ca_file,
63
+ :ssl_version
63
64
 
64
65
  ].inject({}) {|hash, key|
65
66
  hash.tap {
@@ -1,3 +1,3 @@
1
1
  module NightcrawlerSwift
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require "cgi"
2
2
  require "date"
3
+ require "json"
3
4
  require "logger"
4
5
  require "digest"
5
6
  require "ostruct"
@@ -16,9 +17,11 @@ require "nightcrawler_swift/connection"
16
17
  require "nightcrawler_swift/command"
17
18
  require "nightcrawler_swift/commands/upload"
18
19
  require "nightcrawler_swift/commands/download"
20
+ require "nightcrawler_swift/commands/metadata"
19
21
  require "nightcrawler_swift/commands/list"
20
22
  require "nightcrawler_swift/commands/delete"
21
23
  require "nightcrawler_swift/commands/sync"
24
+ require "nightcrawler_swift/commands/multithread_sync"
22
25
  require "nightcrawler_swift/railtie" if defined?(Rails)
23
26
 
24
27
  module NightcrawlerSwift
@@ -19,7 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "rest-client"
22
- spec.add_dependency "multi_mime", ">= 1.0.1"
22
+ spec.add_dependency "multi_mime", ">= 1.0.1"
23
+ spec.add_dependency "concurrent-ruby", "~> 0.8.0"
23
24
 
24
25
  spec.add_development_dependency "bundler", "~> 1.6"
25
26
  spec.add_development_dependency "rake"
@@ -100,6 +100,24 @@ describe NightcrawlerSwift::CLI::Formatters::Basic do
100
100
  end
101
101
  end
102
102
 
103
+ describe "#command_metadata" do
104
+ let :command_class do
105
+ NightcrawlerSwift::Metadata
106
+ end
107
+
108
+ let :metadata do
109
+ {some_metadata: true}
110
+ end
111
+
112
+ it "returns the metadata of the given path" do
113
+ expect(command_class).to receive(:new).and_return(command)
114
+ expect(command).to receive(:execute).with(filepath).and_return(metadata)
115
+ expect(runner).to receive(:log).with(JSON.pretty_generate(metadata))
116
+ expect(runner).to receive(:argv).and_return([filepath])
117
+ subject.command_metadata command_class
118
+ end
119
+ end
120
+
103
121
  describe "#command_url_for" do
104
122
  let :command_class do
105
123
  NightcrawlerSwift::CLI::UrlFor
@@ -15,7 +15,7 @@ describe NightcrawlerSwift::Command do
15
15
  end
16
16
 
17
17
  let(:connection) { NightcrawlerSwift::Connection.new }
18
- let(:restclient) { double(:restclient, put: response, get: response, delete: response) }
18
+ let(:restclient) { double(:restclient, put: response, get: response, head: response, delete: response) }
19
19
  let(:response) { double(:response) }
20
20
  let(:url) { "http://url-com" }
21
21
  let(:token) { "token" }
@@ -28,6 +28,33 @@ describe NightcrawlerSwift::Command do
28
28
  end
29
29
  end
30
30
 
31
+ shared_examples "standard http method" do
32
+ let :execute_http do
33
+ subject.send http_verb, url, body: 'ignore_me', headers: { content_type: :json }, params: { b: 2 }
34
+ end
35
+
36
+ it_behaves_like "command with configured gateway"
37
+
38
+ it "ignores body" do
39
+ execute_http
40
+ expect(restclient).to have_received(http_verb).with(kind_of(Hash))
41
+ end
42
+
43
+ it "sends headers with token" do
44
+ execute_http
45
+ expect(restclient).to have_received(http_verb).with(hash_including({ content_type: :json, "X-Storage-Token" => token }))
46
+ end
47
+
48
+ it "sends params" do
49
+ execute_http
50
+ expect(restclient).to have_received(http_verb).with(hash_including(params: { b: 2 }))
51
+ end
52
+
53
+ it "returns RestClient response" do
54
+ expect(execute_http).to eql(response)
55
+ end
56
+ end
57
+
31
58
  describe "#connection" do
32
59
  context "when disconnected" do
33
60
  before do
@@ -59,57 +86,18 @@ describe NightcrawlerSwift::Command do
59
86
  end
60
87
 
61
88
  describe "#get" do
62
- let :execute_http do
63
- subject.send :get, url, body: 'ignore_me', headers: { content_type: :json }, params: { b: 2 }
64
- end
65
-
66
- it_behaves_like "command with configured gateway"
67
-
68
- it "ignores body" do
69
- execute_http
70
- expect(restclient).to have_received(:get).with(kind_of(Hash))
71
- end
72
-
73
- it "sends headers with token" do
74
- execute_http
75
- expect(restclient).to have_received(:get).with(hash_including({ content_type: :json, "X-Storage-Token" => token }))
76
- end
77
-
78
- it "sends params" do
79
- execute_http
80
- expect(restclient).to have_received(:get).with(hash_including(params: { b: 2 }))
81
- end
89
+ let(:http_verb) { :get }
90
+ it_behaves_like "standard http method"
91
+ end
82
92
 
83
- it "returns RestClient response" do
84
- expect(execute_http).to eql(response)
85
- end
93
+ describe "#head" do
94
+ let(:http_verb) { :head }
95
+ it_behaves_like "standard http method"
86
96
  end
87
97
 
88
98
  describe "#delete" do
89
- let :execute_http do
90
- subject.send :delete, url, body: 'ignore_me', headers: { content_type: :json }, params: { b: 2 }
91
- end
92
-
93
- it_behaves_like "command with configured gateway"
94
-
95
- it "ignores body" do
96
- execute_http
97
- expect(restclient).to have_received(:delete).with(kind_of(Hash))
98
- end
99
-
100
- it "sends headers with token" do
101
- execute_http
102
- expect(restclient).to have_received(:delete).with(hash_including({ content_type: :json, "X-Storage-Token" => token }))
103
- end
104
-
105
- it "sends params" do
106
- execute_http
107
- expect(restclient).to have_received(:delete).with(hash_including(params: { b: 2 }))
108
- end
109
-
110
- it "returns RestClient response" do
111
- expect(execute_http).to eql(response)
112
- end
99
+ let(:http_verb) { :delete }
100
+ it_behaves_like "standard http method"
113
101
  end
114
102
 
115
103
  describe "#put" do
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe NightcrawlerSwift::Metadata do
4
+
5
+ let(:connection) { NightcrawlerSwift::Connection.new }
6
+ let(:token) { "token" }
7
+ let(:expires_at) { (DateTime.now + 60).to_time }
8
+ let(:internal_url) { "server-url" }
9
+ let(:bucket) { "rogue" }
10
+
11
+ subject do
12
+ NightcrawlerSwift::Metadata.new
13
+ end
14
+
15
+ before do
16
+ allow(NightcrawlerSwift).to receive(:connection).and_return(connection)
17
+ allow(connection).to receive(:token_id).and_return(token)
18
+ allow(connection).to receive(:expires_at).and_return(expires_at)
19
+ allow(connection).to receive(:internal_url).and_return(internal_url)
20
+ NightcrawlerSwift.configure bucket: bucket
21
+ end
22
+
23
+ describe "#execute" do
24
+ let(:file_path) { "file_path.css" }
25
+ let(:execute) { subject.execute file_path }
26
+
27
+ let :response do
28
+ double(:response, code: 200, body: "", headers: {
29
+ "content_type" => "text/css",
30
+ "content_length" => "50013",
31
+ "last_modified" => "Wed, 15 Oct 2014 13:38:56 GMT",
32
+ "etag" => "e13839c545f32be23b942a41f3ea7724",
33
+ "x_timestamp" => "1413380335.38118",
34
+ "cache_control" => "public, max-age=604800",
35
+ "x_trans_id" => "tx824d632ef9e54685a7563-005519f838"
36
+ })
37
+ end
38
+
39
+ before do
40
+ allow(subject).to receive(:head).and_return(response)
41
+ end
42
+
43
+ context "success" do
44
+ it "gets using internal url" do
45
+ execute
46
+ expect(subject).to have_received(:head).with("server-url/#{bucket}/#{file_path}")
47
+ end
48
+
49
+ it "returns headers with symbolized keys" do
50
+ output = execute
51
+ expect(output).to eql response.headers.symbolize_keys
52
+ end
53
+ end
54
+
55
+ context "when the path was not informed" do
56
+ let(:file_path) { nil }
57
+
58
+ it "removes the trailing slash" do
59
+ execute
60
+ expect(subject).to have_received(:head).with("server-url/#{bucket}")
61
+ end
62
+ end
63
+ end
64
+ end
@@ -81,6 +81,22 @@ describe NightcrawlerSwift::Gateway do
81
81
  end
82
82
  end
83
83
 
84
+ context "but only 'ssl_version'" do
85
+ let :opts do
86
+ {ssl_version: 'sslversion'}
87
+ end
88
+
89
+ it "uses the configured option" do
90
+ expect(RestClient::Resource).to receive(:new).with(
91
+ url,
92
+ timeout: NightcrawlerSwift.options.timeout,
93
+ verify_ssl: NightcrawlerSwift.options.verify_ssl,
94
+ ssl_version: NightcrawlerSwift.options.ssl_version
95
+ )
96
+ subject
97
+ end
98
+ end
99
+
84
100
  context "using all options" do
85
101
  let :opts do
86
102
  {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nightcrawler_swift
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tulios
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-02-12 00:00:00.000000000 Z
12
+ date: 2015-05-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -39,6 +39,20 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: 1.0.1
42
+ - !ruby/object:Gem::Dependency
43
+ name: concurrent-ruby
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: 0.8.0
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: 0.8.0
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: bundler
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -141,6 +155,8 @@ files:
141
155
  - lib/nightcrawler_swift/commands/delete.rb
142
156
  - lib/nightcrawler_swift/commands/download.rb
143
157
  - lib/nightcrawler_swift/commands/list.rb
158
+ - lib/nightcrawler_swift/commands/metadata.rb
159
+ - lib/nightcrawler_swift/commands/multithread_sync.rb
144
160
  - lib/nightcrawler_swift/commands/sync.rb
145
161
  - lib/nightcrawler_swift/commands/upload.rb
146
162
  - lib/nightcrawler_swift/connection.rb
@@ -168,6 +184,7 @@ files:
168
184
  - spec/lib/nightcrawler_swift/commands/delete_spec.rb
169
185
  - spec/lib/nightcrawler_swift/commands/download_spec.rb
170
186
  - spec/lib/nightcrawler_swift/commands/list_spec.rb
187
+ - spec/lib/nightcrawler_swift/commands/metadata_spec.rb
171
188
  - spec/lib/nightcrawler_swift/commands/sync_spec.rb
172
189
  - spec/lib/nightcrawler_swift/commands/upload_spec.rb
173
190
  - spec/lib/nightcrawler_swift/connection_spec.rb
@@ -219,6 +236,7 @@ test_files:
219
236
  - spec/lib/nightcrawler_swift/commands/delete_spec.rb
220
237
  - spec/lib/nightcrawler_swift/commands/download_spec.rb
221
238
  - spec/lib/nightcrawler_swift/commands/list_spec.rb
239
+ - spec/lib/nightcrawler_swift/commands/metadata_spec.rb
222
240
  - spec/lib/nightcrawler_swift/commands/sync_spec.rb
223
241
  - spec/lib/nightcrawler_swift/commands/upload_spec.rb
224
242
  - spec/lib/nightcrawler_swift/connection_spec.rb