stormmq-client 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ 0.0.7
2
+
3
+ * Added additional Rspecs to bring test coverage of the API code
4
+ up to 100%.
5
+
6
+ * It's now possible to load the secret keys from a custom location
7
+ via the API
8
+
1
9
  0.0.6
2
10
 
3
11
  * Update the gemspec to add dependency for Bunny.
@@ -93,7 +93,7 @@ class StormMQ::Application::AMQPEchoTest < StormMQ::Application
93
93
  msg = queue.pop[:payload]
94
94
 
95
95
  if msg == test_message
96
- puts "\nSUCESS: received test message '#{msg}'"
96
+ puts "\nSUCCESS: received test message '#{msg}'"
97
97
  retval = 0
98
98
  else
99
99
  puts "\nFAILURE: expected test message, but got '#{msg}' instead"
@@ -190,10 +190,7 @@ NOTES
190
190
 
191
191
  For a default system, you'll just need your userName.
192
192
 
193
- COPYRIGHT
194
-
195
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
196
- All rights reserved.
193
+ #{_man_copyright}
197
194
 
198
195
  EOM
199
196
  end
@@ -194,10 +194,7 @@ NOTES
194
194
 
195
195
  stormmq-delete-system <userName>
196
196
 
197
- COPYRIGHT
198
-
199
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
200
- All rights reserved.
197
+ #{_man_copyright}
201
198
 
202
199
  SELF TEST
203
200
 
@@ -100,10 +100,7 @@ NOTES
100
100
 
101
101
  stormmq-create-system <userName> <systemName>
102
102
 
103
- COPYRIGHT
104
-
105
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
106
- All rights reserved.
103
+ #{_man_copyright}
107
104
 
108
105
  SELF TEST
109
106
 
@@ -89,10 +89,7 @@ NOTES
89
89
 
90
90
  stormmq-create-system <userName> <systemName>
91
91
 
92
- COPYRIGHT
93
-
94
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
95
- All rights reserved.
92
+ #{_man_copyright}
96
93
 
97
94
  SELF TEST
98
95
 
@@ -118,10 +118,7 @@ NOTES
118
118
 
119
119
  stormmq-create-system <userName> <systemName>
120
120
 
121
- COPYRIGHT
122
-
123
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
124
- All rights reserved.
121
+ #{_man_copyright}
125
122
 
126
123
  SELF TEST
127
124
 
@@ -130,10 +130,7 @@ NOTES
130
130
 
131
131
  stormmq-create-system <userName> <systemName>
132
132
 
133
- COPYRIGHT
134
-
135
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
136
- All rights reserved.
133
+ #{_man_copyright}
137
134
 
138
135
  SELF TEST
139
136
 
@@ -124,10 +124,7 @@ NOTES
124
124
 
125
125
  stormmq-create-system <userName> <systemName>
126
126
 
127
- COPYRIGHT
128
-
129
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
130
- All rights reserved.
127
+ #{_man_copyright}
131
128
 
132
129
  SELF TEST
133
130
 
@@ -68,10 +68,7 @@ NOTES
68
68
  Pretty prints JSON, so not suitable for use with XHTML etc.,
69
69
  response documents.
70
70
 
71
- COPYRIGHT
72
-
73
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
74
- All rights reserved.
71
+ #{_man_copyright}
75
72
 
76
73
  SELF TEST
77
74
 
@@ -112,10 +112,7 @@ NOTES
112
112
 
113
113
  stormmq-create-system <userName> <systemName>
114
114
 
115
- COPYRIGHT
116
-
117
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
118
- All rights reserved.
115
+ #{_man_copyright}
119
116
 
120
117
  SELF TEST
121
118
 
@@ -84,10 +84,7 @@ NOTES
84
84
 
85
85
  stormmq-list-companies
86
86
 
87
- COPYRIGHT
88
-
89
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
90
- All rights reserved.
87
+ #{_man_copyright}
91
88
 
92
89
  SELF TEST
93
90
 
@@ -72,10 +72,7 @@ NOTES
72
72
  Security prevents you from obtaining information about which other
73
73
  users belong to which companies.
74
74
 
75
- COPYRIGHT
76
-
77
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
78
- All rights reserved.
75
+ #{_man_copyright}
79
76
 
80
77
  SELF TEST
81
78
 
@@ -113,10 +113,7 @@ NOTES
113
113
 
114
114
  stormmq-create-system <userName> <systemName>
115
115
 
116
- COPYRIGHT
117
-
118
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
119
- All rights reserved.
116
+ #{_man_copyright}
120
117
 
121
118
  SELF TEST
122
119
 
@@ -113,10 +113,7 @@ NOTES
113
113
 
114
114
  stormmq-create-system <userName> <systemName>
115
115
 
116
- COPYRIGHT
117
-
118
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
119
- All rights reserved.
116
+ #{_man_copyright}
120
117
 
121
118
  SELF TEST
122
119
 
@@ -93,10 +93,7 @@ NOTES
93
93
 
94
94
  stormmq-create-system <userName> <systemName>
95
95
 
96
- COPYRIGHT
97
-
98
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
99
- All rights reserved.
96
+ #{_man_copyright}
100
97
 
101
98
  SELF TEST
102
99
 
@@ -91,10 +91,7 @@ NOTES
91
91
 
92
92
  Advanced use only - commandline subject to change.
93
93
 
94
- COPYRIGHT
95
-
96
- Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
97
- All rights reserved.
94
+ #{_man_copyright}
98
95
 
99
96
  EOM
100
97
  end
@@ -32,5 +32,15 @@ module StormMQ
32
32
  'Self test ouput goes here'
33
33
  end
34
34
 
35
+ def _man_copyright
36
+ <<-EOS
37
+ COPYRIGHT
38
+
39
+ Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
40
+ All rights reserved.
41
+ EOS
42
+ end
43
+
44
+
35
45
  end
36
46
  end
@@ -11,20 +11,23 @@ require 'json'
11
11
  require 'base64'
12
12
  require 'stormmq/base64_extensions'
13
13
  require 'stormmq/errors'
14
+ require 'stormmq/utils'
14
15
 
15
16
  module StormMQ
16
17
 
17
- SECRET_KEYS_SEARCH_PATH = ['~/.stormmq','/etc']
18
+ SECRET_KEYS_SEARCH_PATH = [
19
+ File.join(ENV['HOME'], '.stormmq'),
20
+ File.join('/', 'etc', 'stormmq')
21
+ ]
22
+
18
23
  SECRET_KEYS_FILENAME = 'secret-keys.json'
19
24
 
20
25
  class SecretKeys
21
26
  include Singleton
22
- attr_writer :key_cache
23
27
 
24
- # Returns the base64 encoded secret key for the given user name from the secret keys file.
28
+ # Returns the secret key for the given user name from the secret keys file.
25
29
  def key_for(user)
26
- raise Error::UserNotProvidedError, "user cannot be nil." if user.nil?
27
- raise Error::UserNotProvidedError, "user cannot be empty." if user.empty?
30
+ raise Error::UserNotProvidedError, "user cannot be blank." if user.blank?
28
31
  keys[user] || (raise Error::SecretKeyNotFoundError, "a secret key for user '#{user}' could not be found in the secret key file.", caller)
29
32
  end
30
33
 
@@ -33,21 +36,16 @@ module StormMQ
33
36
  keys.keys
34
37
  end
35
38
 
36
- private
37
-
38
- # Return a hash of keys stored in the secret keys file.
39
- def keys
40
- @secret_keys_cache ||= load_secret_keys
41
- end
42
-
43
39
  # Load the keys from the secret keys file <tt>keyfile</tt>. Walks the locations specified in
44
40
  # <tt>search_path</tt> in order of preference.
45
41
  def load_secret_keys(search_path=SECRET_KEYS_SEARCH_PATH, keyfile=SECRET_KEYS_FILENAME)
46
- full_paths = search_path.map{|p| File.expand_path("#{p}/#{keyfile}")}
42
+ full_paths = search_path.map{|p| File.expand_path(File.join(p,keyfile))}
47
43
  full_paths.each do |full_path|
48
44
  begin
49
- return SecretKeys.secret_keys_hash_from_json(IO.read(full_path))
45
+ return @secret_keys_cache = SecretKeys.secret_keys_hash_from_json(IO.read(full_path))
50
46
  rescue
47
+ # A dummy statement so that this branch is picked up by rcov
48
+ dummy = true
51
49
  end
52
50
  end
53
51
  raise Error::LoadSecretKeysError,
@@ -55,6 +53,18 @@ module StormMQ
55
53
  caller
56
54
  end
57
55
 
56
+ def forget_keys
57
+ @secret_keys_cache = nil
58
+ end
59
+
60
+ private
61
+
62
+ # Return a hash of keys stored in the secret keys file.
63
+ def keys
64
+ @secret_keys_cache ||= load_secret_keys
65
+ end
66
+
67
+
58
68
  def self.key_for(*args)
59
69
  self.instance.key_for(*args)
60
70
  end
data/lib/stormmq/url.rb CHANGED
@@ -11,7 +11,7 @@ require 'cgi'
11
11
  require 'hmac'
12
12
  require 'hmac-sha2'
13
13
  require 'base64'
14
-
14
+ require 'stormmq/base64_extensions'
15
15
  require 'stormmq/errors'
16
16
 
17
17
  module StormMQ
@@ -80,7 +80,7 @@ module StormMQ
80
80
 
81
81
  def to_h
82
82
  components = URI.split(@url.to_s)
83
- {
83
+ component_hash = {
84
84
  :scheme => components[0],
85
85
  :userinfo => components[1],
86
86
  :host => components[2],
@@ -91,6 +91,7 @@ module StormMQ
91
91
  :query => components[7],
92
92
  :fragment => components[8]
93
93
  }.reject {|k,v| v.nil?}
94
+ component_hash
94
95
  end
95
96
 
96
97
  def self.escape(string)
@@ -1,3 +1,3 @@
1
1
  module StormMQ
2
- VERSION = '0.0.6'
2
+ VERSION = '0.0.7'
3
3
  end
@@ -0,0 +1 @@
1
+ {"test":"qQC5BNDK5rMOxLC0G2hkOoW5Z7P-c4aO2pok5r0V0Ac"}
@@ -0,0 +1,2 @@
1
+ $:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
2
+ require 'spec'
@@ -6,9 +6,25 @@
6
6
  # for terms of use and redistribution.
7
7
  #++
8
8
 
9
- require File.dirname(__FILE__) + '/../../lib/stormmq/amqp'
9
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
10
+ require 'stormmq/amqp'
10
11
 
11
12
  describe StormMQ::AMQPClient do
13
+
14
+ it "adds default StormMQ client options to an option hash" do
15
+ options = {
16
+ :company => 'a_company',
17
+ :system => 'a_system',
18
+ :environment => 'an_environment'
19
+ }
20
+ new_options = StormMQ::AMQPClient.add_stormmq_options(options)
21
+
22
+ new_options[:host].should == 'amqp.stormmq.com'
23
+ new_options[:port].should == 443
24
+ new_options[:vhost].should == '/a_company/a_system/an_environment'
25
+ new_options[:ssl].should be_true
26
+ end
27
+
12
28
  it "constructs the virtual host string from the StormMQ specific options in the connect option hash" do
13
29
  options = {
14
30
  :company => 'a_company',
@@ -17,5 +33,17 @@ describe StormMQ::AMQPClient do
17
33
  }
18
34
  StormMQ::AMQPClient.vhost_from_options(options).should == '/a_company/a_system/an_environment'
19
35
  end
36
+
37
+ it "returns an instance of the Bunny AMQP client" do
38
+ StormMQ::AMQPClient.instance.should be_instance_of(Bunny::Client)
39
+ end
40
+
41
+ it "run block in scope of Bunny AMQP client instance" do
42
+ block = Proc.new { }
43
+ options = StormMQ::AMQPClient.add_stormmq_options({})
44
+ Bunny.should_receive(:run).with(options, &block)
45
+ StormMQ::AMQPClient.run({}, &block)
46
+ end
47
+
20
48
  end
21
49
 
@@ -0,0 +1,28 @@
1
+ #--
2
+ # Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
3
+ # All rights reserved.
4
+ #
5
+ # Please refer to the LICENSE file that accompanies this source
6
+ # for terms of use and redistribution.
7
+ #++
8
+
9
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
10
+ require 'base64'
11
+ require 'stormmq/base64_extensions'
12
+
13
+ describe Base64 do
14
+
15
+ before(:each) do
16
+ @unsafe_encoded = "jv7N7mnDnl4FWgayyxzN695zYJ4SC/OTnXel9SPIP/2XV6d7+3vTyV4v0zQWAfvNwZm/bB/h6P+X+FUUdcvJig=="
17
+ @safe_encoded = "jv7N7mnDnl4FWgayyxzN695zYJ4SC_OTnXel9SPIP_2XV6d7-3vTyV4v0zQWAfvNwZm_bB_h6P-X-FUUdcvJig=="
18
+ end
19
+
20
+ it "implements a URL safe base64 decode" do
21
+ Base64.encode64(Base64.urlsafe_decode64(@safe_encoded)).gsub(/\n/,'').should == @unsafe_encoded
22
+ end
23
+
24
+ it "implements a URL safe base64 encode" do
25
+ Base64.urlsafe_encode64(Base64.decode64(@unsafe_encoded)).gsub(/\n/,'').should == @safe_encoded
26
+ end
27
+
28
+ end
@@ -6,9 +6,11 @@
6
6
  # for terms of use and redistribution.
7
7
  #++
8
8
 
9
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
9
10
  require 'base64'
10
- require File.dirname(__FILE__) + '/../../lib/stormmq/secret_keys'
11
- require File.dirname(__FILE__) + '/../../lib/stormmq/base64_extensions'
11
+ require 'stormmq/secret_keys'
12
+ require 'stormmq/base64_extensions'
13
+ require 'stormmq/errors'
12
14
 
13
15
  describe StormMQ::SecretKeys do
14
16
 
@@ -22,4 +24,51 @@ describe StormMQ::SecretKeys do
22
24
 
23
25
  end
24
26
 
27
+ describe "loading of keys from keyfile" do
28
+
29
+ it "should throw an error when keyfile does not exist" do
30
+ keystore = StormMQ::SecretKeys.instance
31
+ lambda { keystore.load_secret_keys('/non-existing-path') }.should raise_error(StormMQ::Error::LoadSecretKeysError)
32
+ end
33
+
34
+ it "should load keys from a file" do
35
+ keystore = StormMQ::SecretKeys.instance
36
+ lambda { keystore.load_secret_keys(File.join('spec')) }.should_not raise_error(StormMQ::Error::LoadSecretKeysError)
37
+ end
38
+
39
+ it "should handle an error while reading the keyfile" do
40
+ IO.should_receive(:read).and_raise "bang! The universe has ended."
41
+ keystore = StormMQ::SecretKeys.instance
42
+ lambda { keystore.load_secret_keys(File.join('spec')) }.should raise_error(StormMQ::Error::LoadSecretKeysError)
43
+ end
44
+
45
+ end
46
+
47
+ describe "key and user retrieval" do
48
+
49
+ before(:each) do
50
+ @keystore = StormMQ::SecretKeys.instance
51
+ @keystore.forget_keys
52
+ @keystore.load_secret_keys(File.join('spec'))
53
+ end
54
+
55
+ it "should return a list of users found in the key file" do
56
+ @keystore.users.should == ['test']
57
+ StormMQ::SecretKeys.key_for('test').should_not be_nil
58
+ end
59
+
60
+ it "should retrieve the key for a named user" do
61
+ @keystore.key_for('test').should_not be_nil
62
+ end
63
+
64
+ it "should retrieve the key for a named user when using the class method" do
65
+ StormMQ::SecretKeys.key_for('test').should_not be_nil
66
+ end
67
+
68
+ it "should raise an error when a key for a named user is not present in the keyfile" do
69
+ lambda { @keystore.key_for('wibble') }.should raise_error(StormMQ::Error::SecretKeyNotFoundError)
70
+ end
71
+
72
+ end
73
+
25
74
  end
@@ -6,7 +6,8 @@
6
6
  # for terms of use and redistribution.
7
7
  #++
8
8
 
9
- require File.dirname(__FILE__) + '/../../lib/stormmq/url'
9
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
10
+ require 'stormmq/url'
10
11
 
11
12
  describe StormMQ::URL do
12
13
 
@@ -126,4 +127,72 @@ describe StormMQ::URL do
126
127
 
127
128
  end
128
129
 
130
+ describe "valid?" do
131
+
132
+ it "a valid URL" do
133
+ StormMQ::URL.new("http://www.byrnehq.com").valid?.should be_true
134
+ end
135
+
136
+ it "an invalid URL" do
137
+ lambda { StormMQ::URL.new("random://www") }.should raise_error(StormMQ::Error::InvalidURLError)
138
+ end
139
+
140
+ it "an invalid URI as detected by URI.parse" do
141
+ URI.should_receive(:parse).and_raise URI::InvalidURIError
142
+ lambda { StormMQ::URL.new({:host => 'www.byrnehq.com'}) }.should raise_error(StormMQ::Error::InvalidURLError)
143
+ end
144
+
145
+ end
146
+
147
+ describe "to_h" do
148
+
149
+ before(:each) do
150
+ @hash = StormMQ::URL.new('http://www.stormmq.com:81/path?query=1').to_h
151
+ end
152
+
153
+ it "should extract the scheme" do
154
+ @hash[:scheme].should == 'http'
155
+ end
156
+
157
+ it "should extract the host" do
158
+ @hash[:host].should == 'www.stormmq.com'
159
+ end
160
+
161
+ it "should extract the port" do
162
+ @hash[:port].should == '81'
163
+ end
164
+
165
+ it "should extract the path" do
166
+ @hash[:path].should == '/path'
167
+ end
168
+
169
+ it "should extract the query" do
170
+ @hash[:query].should == 'query=1'
171
+ end
172
+
173
+ it "should not contain a fragment" do
174
+ @hash[:fragment].should be_nil
175
+ end
176
+
177
+ it "should not contain an opaque" do
178
+ @hash[:opaque].should be_nil
179
+ end
180
+
181
+ it "should not contain a registry" do
182
+ @hash[:registry].should be_nil
183
+ end
184
+
185
+ end
186
+
187
+ describe "canonicalise and sign" do
188
+
189
+ it "should canonicalise and sign a URL (in one step)" do
190
+ base64key = "d60bfe079c88f2c78310131d9bb419214ec3badb0bdfccb20a1c568f380426c5"
191
+ key = Base64::decode64(base64key)
192
+ StormMQ::URL.new('http://api.stormmq.com/').canonicalise_and_sign('test', base64key).to_s.should ==
193
+ 'http://api.stormmq.com:80/?signature=qQC5BNDK5rMOxLC0G2hkOoW5Z7P-c4aO2pok5r0V0Ac%3D&user=test&version=0'
194
+ end
195
+
196
+ end
197
+
129
198
  end
@@ -6,8 +6,33 @@
6
6
  # for terms of use and redistribution.
7
7
  #++
8
8
 
9
- require File.dirname(__FILE__) + '/../../lib/stormmq/utils'
9
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
10
+ require 'stormmq/utils'
10
11
 
11
12
  describe StormMQ::Utils do
12
13
 
14
+ describe NilClass, 'blank?' do
15
+
16
+ it "should extend NilClass to add a 'blank?' method" do
17
+ nil.blank?.should be_true
18
+ end
19
+
20
+ end
21
+
22
+ describe String, 'blank?' do
23
+
24
+ it "a string with non space characters is not blank" do
25
+ 'not blank'.blank?.should be_false
26
+ end
27
+
28
+ it "an empty string is blank" do
29
+ ''.blank?.should be_true
30
+ end
31
+
32
+ it "a string containing only space is blank" do
33
+ ' '.blank?.should be_true
34
+ end
35
+
36
+ end
37
+
13
38
  end
metadata CHANGED
@@ -1,20 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stormmq-client
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tony Byrne
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain:
17
- date: 2010-06-08 00:00:00 +01:00
17
+ date: 2010-06-18 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -209,7 +209,10 @@ files:
209
209
  - bin/stormmq-list-queues
210
210
  - bin/stormmq-list-systems
211
211
  - bin/stormmq-url-signer
212
+ - spec/secret-keys.json
213
+ - spec/spec_helper.rb
212
214
  - spec/stormmq/amqp_spec.rb
215
+ - spec/stormmq/base64_extensions_spec.rb
213
216
  - spec/stormmq/secret_keys_spec.rb
214
217
  - spec/stormmq/url_spec.rb
215
218
  - spec/stormmq/utils_spec.rb