stormmq-client 0.0.6 → 0.0.7

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.
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