hoodoo 1.0.5 → 1.1.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.
Files changed (27) hide show
  1. checksums.yaml +8 -8
  2. data/lib/hoodoo/client/endpoint/endpoints/amqp.rb +43 -25
  3. data/lib/hoodoo/discovery.rb +1 -1
  4. data/lib/hoodoo/services/discovery/discoverers/by_flux.rb +130 -0
  5. data/lib/hoodoo/services/discovery/results/for_amqp.rb +15 -21
  6. data/lib/hoodoo/services/discovery/results/for_local.rb +17 -0
  7. data/lib/hoodoo/services/middleware/amqp_log_message.rb +92 -154
  8. data/lib/hoodoo/services/middleware/amqp_log_writer.rb +25 -50
  9. data/lib/hoodoo/services/middleware/middleware.rb +75 -25
  10. data/lib/hoodoo/services/services/service.rb +2 -2
  11. data/lib/hoodoo/version.rb +1 -1
  12. data/spec/services/discovery/discoverers/by_flux_spec.rb +134 -0
  13. data/spec/services/discovery/results/for_amqp_spec.rb +4 -7
  14. data/spec/services/discovery/results/for_local_spec.rb +4 -0
  15. data/spec/services/middleware/amqp_log_message_spec.rb +32 -34
  16. data/spec/services/middleware/amqp_log_writer_spec.rb +2 -5
  17. data/spec/services/middleware/middleware_exotic_communication_spec.rb +147 -143
  18. data/spec/services/middleware/middleware_logging_spec.rb +10 -10
  19. data/spec/services/middleware/middleware_multi_remote_spec.rb +1 -1
  20. data/spec/services/middleware/middleware_public_spec.rb +73 -18
  21. data/spec/services/middleware/middleware_spec.rb +4 -4
  22. data/spec/services/services/application_spec.rb +3 -3
  23. data/spec/spec_helper.rb +3 -8
  24. metadata +19 -7
  25. data/lib/hoodoo/services/discovery/discoverers/by_consul.rb +0 -66
  26. data/spec/alchemy/alchemy-amq.rb +0 -33
  27. data/spec/services/discovery/discoverers/by_consul_spec.rb +0 -29
@@ -4,14 +4,11 @@ describe Hoodoo::Services::Discovery::ForAMQP do
4
4
  it 'stores known quantities and retrieves them' do
5
5
  r = described_class.new(
6
6
  resource: 'Foo', # Note String
7
- version: 3,
8
- queue_name: 'queue.foo',
9
- equivalent_path: '/v3/foos'
7
+ version: 3
10
8
  )
11
9
 
12
- expect( r.resource ).to eq( :Foo ) # Note Symbol
13
- expect( r.version ).to eq( 3 )
14
- expect( r.queue_name ).to eq( 'queue.foo' )
15
- expect( r.equivalent_path ).to eq( '/v3/foos' )
10
+ expect( r.resource ).to eq( :Foo ) # Note Symbol
11
+ expect( r.version ).to eq( 3 )
12
+ expect( r.routing_path ).to eq( '/3/Foo' )
16
13
  end
17
14
  end
@@ -7,6 +7,8 @@ describe Hoodoo::Services::Discovery::ForLocal do
7
7
  version: 3,
8
8
  base_path: '/v3/foos',
9
9
  routing_regexp: /\/v3\/foos.*/,
10
+ de_facto_base_path: '/3/Foo',
11
+ de_facto_routing_regexp: /\/3\/Foo.*/,
10
12
  interface_class: Array, # Just any old class
11
13
  implementation_instance: Array.new # Just any old comparable class instance
12
14
  )
@@ -15,6 +17,8 @@ describe Hoodoo::Services::Discovery::ForLocal do
15
17
  expect( r.version ).to eq( 3 )
16
18
  expect( r.base_path ).to eq( '/v3/foos' )
17
19
  expect( r.routing_regexp ).to eq( /\/v3\/foos.*/ )
20
+ expect( r.de_facto_base_path ).to eq( '/3/Foo' )
21
+ expect( r.de_facto_routing_regexp ).to eq( /\/3\/Foo.*/ )
18
22
  expect( r.interface_class ).to eq( Array )
19
23
  expect( r.implementation_instance ).to eq( Array.new )
20
24
  end
@@ -2,13 +2,8 @@ require 'spec_helper.rb'
2
2
 
3
3
  describe Hoodoo::Services::Middleware::AMQPLogMessage do
4
4
 
5
- require 'msgpack'
6
-
7
- let( :now ) do
8
- Time.now
9
- end
10
-
11
- let( :source_hash ) do
5
+ let( :now ) { Time.now }
6
+ let( :base_hash ) {
12
7
  {
13
8
  :id => '1',
14
9
  :level => 'info',
@@ -19,42 +14,45 @@ describe Hoodoo::Services::Middleware::AMQPLogMessage do
19
14
 
20
15
  :interaction_id => '3',
21
16
  :caller_id => '2',
22
- :identity => { :foo => '4', :bar => '5' }
17
+ :identity => { :foo => '4', :bar => '5' },
23
18
  }
19
+ }
20
+
21
+ ############################################################################
22
+ # All tests must use 'let' to define values for 'reported_at' and
23
+ # 'expected_reported_at'.
24
+ ############################################################################
25
+
26
+ let( :hash ) { base_hash().merge( :reported_at => reported_at() ) }
27
+ let( :expected_result ) {
28
+ Hoodoo::Utilities.stringify( hash() ).merge( 'reported_at' => expected_reported_at() )
29
+ }
30
+
31
+ shared_examples 'a well formed logger' do
32
+ it 'and canonicalises the fields' do
33
+ obj = described_class.new( hash() )
34
+ expect( obj.to_h ).to eq( expected_result() )
35
+ end
24
36
  end
25
37
 
26
- let( :hash ) do
27
- source_hash().merge( :reported_at => now() )
28
- end
38
+ context 'with a Time object in "reported_at"' do
39
+ let( :reported_at ) { Time.now }
40
+ let( :expected_reported_at ) { reported_at().strftime( Hoodoo::Services::Middleware::AMQPLogMessage::TIME_FORMATTER ) }
29
41
 
30
- let( :compare_hash ) do
31
- Hoodoo::Utilities.stringify(
32
- source_hash().merge(
33
- :reported_at => now().strftime( Hoodoo::Services::Middleware::AMQPLogMessage::TIME_FORMATTER )
34
- )
35
- )
42
+ it_behaves_like 'a well formed logger'
36
43
  end
37
44
 
38
- it 'serializes' do
39
- obj = described_class.new( hash )
40
- expect( MessagePack.unpack( obj.serialize ) ).to eq( compare_hash )
41
- end
45
+ context 'with a String object in "reported_at"' do
46
+ let( :reported_at ) { Time.now.iso8601 }
47
+ let( :expected_reported_at ) { reported_at() }
42
48
 
43
- it 'deserializes' do
44
- obj = described_class.new( hash )
45
- expect( MessagePack.unpack( obj.serialize ) ).to eq( compare_hash )
46
- obj.id = nil # Clear some instance vars
47
- obj.level = nil
48
- obj.deserialize # Should reset instance vars based on prior serialization
49
- expect( MessagePack.unpack( obj.serialize ) ).to eq( compare_hash )
49
+ it_behaves_like 'a well formed logger'
50
50
  end
51
51
 
52
- it 'handles nil' do
53
- local_compare_hash = Hoodoo::Utilities.stringify(
54
- source_hash.merge( :reported_at => nil )
55
- )
52
+ context 'with "nil" in "reported_at"' do
53
+ let( :reported_at ) { nil }
54
+ let( :expected_reported_at ) { reported_at() }
56
55
 
57
- obj = described_class.new( source_hash )
58
- expect( MessagePack.unpack( obj.serialize ) ).to eq( local_compare_hash )
56
+ it_behaves_like 'a well formed logger'
59
57
  end
60
58
  end
@@ -80,14 +80,11 @@ describe Hoodoo::Services::Middleware::AMQPLogWriter do
80
80
 
81
81
  :interaction_id => interaction_id,
82
82
  :caller_id => @session.caller_id,
83
- :identity => Hoodoo::Utilities.stringify( @session.identity.to_h ),
84
-
85
- :routing_key => @queue,
83
+ :identity => Hoodoo::Utilities.stringify( @session.identity.to_h )
86
84
  }
87
85
 
88
86
  expect( Hoodoo::Services::Middleware::AMQPLogMessage ).to receive( :new ).with( expected_hash ).and_return( {} )
89
- expect_any_instance_of( Hash ).to receive( :serialize ).once
90
- expect( @alchemy ).to receive( :send_message ).with( {} ).once
87
+ expect( @alchemy ).to receive( :send_message_to_queue ).with( @queue, {} ).once
91
88
 
92
89
  @logger.report( level, component, code, data )
93
90
  end
@@ -25,8 +25,8 @@ describe Hoodoo::Services::Middleware do
25
25
 
26
26
  context 'on queue' do
27
27
  before :each do
28
- @old_queue = ENV[ 'AMQ_ENDPOINT' ]
29
- ENV[ 'AMQ_ENDPOINT' ] = 'amqp://test:test@127.0.0.1'
28
+ @old_queue = ENV[ 'AMQ_URI' ]
29
+ ENV[ 'AMQ_URI' ] = 'amqp://test:test@127.0.0.1'
30
30
  @mw = Hoodoo::Services::Middleware.new( RSpecTestServiceExoticStub.new )
31
31
 
32
32
  @cvar = false
@@ -43,7 +43,7 @@ describe Hoodoo::Services::Middleware do
43
43
  end
44
44
 
45
45
  after :each do
46
- ENV[ 'AMQ_ENDPOINT' ] = @old_queue
46
+ ENV[ 'AMQ_URI' ] = @old_queue
47
47
 
48
48
  if Hoodoo::Services::Middleware.class_variable_defined?( '@@alchemy' )
49
49
  if @cvar == true
@@ -64,8 +64,7 @@ describe Hoodoo::Services::Middleware do
64
64
  it 'returns known queue endpoint locations' do
65
65
  location = @mw.instance_variable_get( '@discoverer' ).discover( :Version, 2 )
66
66
  expect( location ).to be_a( Hoodoo::Services::Discovery::ForAMQP )
67
- expect( location.queue_name ).to eq( 'service.version' )
68
- expect( location.equivalent_path ).to eq( '/v2/versions' )
67
+ expect( location.routing_path ).to eq( '/2/Version' )
69
68
  end
70
69
 
71
70
  # TODO: Update for real Consul discoverer when implemented.
@@ -90,8 +89,8 @@ describe Hoodoo::Services::Middleware do
90
89
  Hoodoo::Services::Middleware.class_variable_set( '@@alchemy', @mock_alchemy )
91
90
  end
92
91
 
93
- def run_expectations( action, mock_queue, full_path, mock_method, mock_query, mock_remote, mock_response )
94
- expect_any_instance_of( Hoodoo::Services::Discovery::ByConsul ).to receive(
92
+ def run_expectations( action, full_path, mock_method, mock_query, mock_remote, mock_response )
93
+ expect_any_instance_of( Hoodoo::Services::Discovery::ByFlux ).to receive(
95
94
  :discover_remote
96
95
  ).and_return(
97
96
  mock_remote
@@ -103,26 +102,26 @@ describe Hoodoo::Services::Middleware do
103
102
  mock_query[ 'filter' ] = URI.encode_www_form( mock_query[ 'filter' ] ) if ( mock_query[ 'filter' ].is_a?( ::Hash ) )
104
103
  end
105
104
 
106
- expect( @mock_alchemy ).to receive( :http_request ).once do | queue, method, path, opts |
107
- expect( queue ).to eq( mock_queue )
108
- expect( method ).to eq( mock_method )
109
- expect( path ).to eq( full_path )
110
- expect( opts ).to eq(
111
- {
112
- :session_id => @interaction.context.session.session_id,
113
- :host => 'localhost',
114
- :port => 80,
115
- :body => action == :create || action == :update ? '{}' : '',
116
- :query => mock_query,
117
- :headers => {
118
- 'Content-Type' => 'application/json; charset=utf-8',
119
- 'Content-Language' => 'fr',
120
- 'Accept-Language' => 'fr',
121
- 'X-Interaction-ID' => @interaction.interaction_id,
122
- 'X-Session-ID' => @interaction.context.session.session_id
123
- }
124
- }
125
- )
105
+ expect( @mock_alchemy ).to receive( :send_message_to_resource ).once do | message |
106
+ expect( message ).to eq( {
107
+ 'scheme' => 'http',
108
+ 'verb' => mock_method,
109
+
110
+ 'host' => 'localhost',
111
+ 'port' => 80,
112
+ 'path' => full_path,
113
+ 'query' => mock_query,
114
+
115
+ 'session_id' => @interaction.context.session.session_id,
116
+ 'body' => action == :create || action == :update ? '{}' : '',
117
+ 'headers' => {
118
+ 'Content-Type' => 'application/json; charset=utf-8',
119
+ 'Content-Language' => 'fr',
120
+ 'Accept-Language' => 'fr',
121
+ 'X-Interaction-ID' => @interaction.interaction_id,
122
+ 'X-Session-ID' => @interaction.context.session.session_id
123
+ },
124
+ } )
126
125
  end.and_return( mock_response )
127
126
  end
128
127
 
@@ -140,18 +139,15 @@ describe Hoodoo::Services::Middleware do
140
139
  #
141
140
  @mw = Hoodoo::Services::Middleware.new( RSpecTestServiceExoticStub.new )
142
141
 
143
- mock_queue = 'service.version'
144
- mock_path = '/v2/version/'
142
+ mock_path = '/2/Version/'
145
143
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
146
144
  resource: 'Version',
147
- version: 2,
148
- queue_name: mock_queue,
149
- equivalent_path: mock_path
145
+ version: 2
150
146
  )
151
147
 
152
148
  # We expect local discovery, so no discover_remote call.
153
149
 
154
- expect_any_instance_of( Hoodoo::Services::Discovery::ByConsul ).to_not receive( :discover_remote )
150
+ expect_any_instance_of( Hoodoo::Services::Discovery::ByFlux ).to_not receive( :discover_remote )
155
151
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
156
152
 
157
153
  # The endpoint should've been called locally; the implementation at
@@ -163,17 +159,14 @@ describe Hoodoo::Services::Middleware do
163
159
  end
164
160
 
165
161
  it 'complains about a missing Alchemy instance' do
166
- mock_queue = 'service.version'
167
- mock_path = '/v2/version/'
162
+ mock_path = '/2/Version/'
168
163
 
169
164
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
170
165
  resource: 'Version',
171
- version: 2,
172
- queue_name: mock_queue,
173
- equivalent_path: mock_path
166
+ version: 2
174
167
  )
175
168
 
176
- expect_any_instance_of( Hoodoo::Services::Discovery::ByConsul ).to receive(
169
+ expect_any_instance_of( Hoodoo::Services::Discovery::ByFlux ).to receive(
177
170
  :discover_remote
178
171
  ).and_return(
179
172
  mock_remote
@@ -184,10 +177,10 @@ describe Hoodoo::Services::Middleware do
184
177
  # Fragile! Hack for test only.
185
178
  endpoint.instance_variable_get( '@wrapped_endpoint' ).alchemy = nil
186
179
 
187
- mock_response = AlchemyAMQ::HTTPResponse.new(
188
- :status_code => 200,
189
- :body => '{"_data":[]}'
190
- )
180
+ mock_response = {
181
+ 'status_code' => 200,
182
+ 'body' => '{"_data":[]}'
183
+ }
191
184
 
192
185
  expect {
193
186
  mock_result = endpoint.list()
@@ -195,24 +188,21 @@ describe Hoodoo::Services::Middleware do
195
188
  end
196
189
 
197
190
  it 'calls #list over Alchemy and handles 200' do
198
- mock_queue = 'service.version'
199
- mock_path = '/v2/version'
191
+ mock_path = '/2/Version'
200
192
  mock_method = 'GET'
201
193
  mock_query = { :search => { :foo => :bar } }
202
194
 
203
195
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
204
196
  resource: 'Version',
205
- version: 2,
206
- queue_name: mock_queue,
207
- equivalent_path: mock_path
197
+ version: 2
208
198
  )
209
199
 
210
- mock_response = AlchemyAMQ::HTTPResponse.new(
211
- :status_code => 200,
212
- :body => '{"_data":[]}'
213
- )
200
+ mock_response = {
201
+ 'status_code' => 200,
202
+ 'body' => '{"_data":[]}'
203
+ }
214
204
 
215
- run_expectations( :list, mock_queue, mock_path + '/', mock_method, mock_query, mock_remote, mock_response )
205
+ run_expectations( :list, mock_path + '/', mock_method, mock_query, mock_remote, mock_response )
216
206
 
217
207
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
218
208
  mock_result = endpoint.list( mock_query )
@@ -221,24 +211,21 @@ describe Hoodoo::Services::Middleware do
221
211
  end
222
212
 
223
213
  it 'calls #show over Alchemy and handles 200' do
224
- mock_queue = 'service.version'
225
- mock_path = '/v2/version'
214
+ mock_path = '/2/Version'
226
215
  mock_method = 'GET'
227
216
  mock_query = { :search => { :foo => :bar } }
228
217
 
229
218
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
230
219
  resource: 'Version',
231
- version: 2,
232
- queue_name: mock_queue,
233
- equivalent_path: mock_path
220
+ version: 2
234
221
  )
235
222
 
236
- mock_response = AlchemyAMQ::HTTPResponse.new(
237
- :status_code => 200,
238
- :body => '{}'
239
- )
223
+ mock_response = {
224
+ 'status_code' => 200,
225
+ 'body' => '{}'
226
+ }
240
227
 
241
- run_expectations( :show, mock_queue, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
228
+ run_expectations( :show, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
242
229
 
243
230
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
244
231
  mock_result = endpoint.show( 'ident', mock_query )
@@ -247,24 +234,21 @@ describe Hoodoo::Services::Middleware do
247
234
  end
248
235
 
249
236
  it 'calls #create over Alchemy and handles 200' do
250
- mock_queue = 'service.version'
251
- mock_path = '/v2/version'
237
+ mock_path = '/2/Version'
252
238
  mock_method = 'POST'
253
239
  mock_query = { :search => { :foo => :bar } }
254
240
 
255
241
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
256
242
  resource: 'Version',
257
- version: 2,
258
- queue_name: mock_queue,
259
- equivalent_path: mock_path
243
+ version: 2
260
244
  )
261
245
 
262
- mock_response = AlchemyAMQ::HTTPResponse.new(
263
- :status_code => 200,
264
- :body => '{}'
265
- )
246
+ mock_response = {
247
+ 'status_code' => 200,
248
+ 'body' => '{}'
249
+ }
266
250
 
267
- run_expectations( :create, mock_queue, mock_path + '/', mock_method, mock_query, mock_remote, mock_response )
251
+ run_expectations( :create, mock_path + '/', mock_method, mock_query, mock_remote, mock_response )
268
252
 
269
253
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
270
254
  mock_result = endpoint.create( {}, mock_query )
@@ -273,24 +257,21 @@ describe Hoodoo::Services::Middleware do
273
257
  end
274
258
 
275
259
  it 'calls #update over Alchemy and handles 200' do
276
- mock_queue = 'service.version'
277
- mock_path = '/v2/version'
260
+ mock_path = '/2/Version'
278
261
  mock_method = 'PATCH'
279
262
  mock_query = { :search => { :foo => :bar } }
280
263
 
281
264
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
282
265
  resource: 'Version',
283
- version: 2,
284
- queue_name: mock_queue,
285
- equivalent_path: mock_path
266
+ version: 2
286
267
  )
287
268
 
288
- mock_response = AlchemyAMQ::HTTPResponse.new(
289
- :status_code => 200,
290
- :body => '{}'
291
- )
269
+ mock_response = {
270
+ 'status_code' => 200,
271
+ 'body' => '{}'
272
+ }
292
273
 
293
- run_expectations( :update, mock_queue, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
274
+ run_expectations( :update, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
294
275
 
295
276
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
296
277
  mock_result = endpoint.update( 'ident', {}, mock_query )
@@ -299,24 +280,21 @@ describe Hoodoo::Services::Middleware do
299
280
  end
300
281
 
301
282
  it 'calls #delete over Alchemy and handles 200' do
302
- mock_queue = 'service.version'
303
- mock_path = '/v2/version'
283
+ mock_path = '/2/Version'
304
284
  mock_method = 'DELETE'
305
285
  mock_query = { :search => { :foo => :bar } }
306
286
 
307
287
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
308
288
  resource: 'Version',
309
- version: 2,
310
- queue_name: mock_queue,
311
- equivalent_path: mock_path
289
+ version: 2
312
290
  )
313
291
 
314
- mock_response = AlchemyAMQ::HTTPResponse.new(
315
- :status_code => 200,
316
- :body => '{}'
317
- )
292
+ mock_response = {
293
+ 'status_code' => 200,
294
+ 'body' => '{}'
295
+ }
318
296
 
319
- run_expectations( :delete, mock_queue, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
297
+ run_expectations( :delete, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
320
298
 
321
299
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
322
300
  mock_result = endpoint.delete( 'ident', mock_query )
@@ -325,24 +303,18 @@ describe Hoodoo::Services::Middleware do
325
303
  end
326
304
 
327
305
  it 'calls #show over Alchemy and handles 408' do
328
- mock_queue = 'service.version'
329
- mock_path = '/v2/version'
306
+ mock_path = '/2/Version'
330
307
  mock_method = 'GET'
331
308
  mock_query = { :search => { :foo => :bar } }
332
309
 
333
310
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
334
311
  resource: 'Version',
335
- version: 2,
336
- queue_name: mock_queue,
337
- equivalent_path: mock_path
312
+ version: 2
338
313
  )
339
314
 
340
- mock_response = AlchemyAMQ::HTTPResponse.new(
341
- :status_code => 408,
342
- :body => '408 Timeout'
343
- )
315
+ mock_response = AlchemyFlux::TimeoutError
344
316
 
345
- run_expectations( :show, mock_queue, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
317
+ run_expectations( :show, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
346
318
 
347
319
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
348
320
  mock_result = endpoint.show( 'ident', mock_query )
@@ -359,24 +331,18 @@ describe Hoodoo::Services::Middleware do
359
331
  end
360
332
 
361
333
  it 'calls #show over Alchemy and handles 404' do
362
- mock_queue = 'service.version'
363
- mock_path = '/v2/version'
334
+ mock_path = '/2/Version'
364
335
  mock_method = 'GET'
365
336
  mock_query = { :search => { :foo => :bar } }
366
337
 
367
338
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
368
339
  resource: 'Version',
369
- version: 2,
370
- queue_name: mock_queue,
371
- equivalent_path: mock_path
340
+ version: 2
372
341
  )
373
342
 
374
- mock_response = AlchemyAMQ::HTTPResponse.new(
375
- :status_code => 404,
376
- :body => '404 Not Found'
377
- )
343
+ mock_response = AlchemyFlux::MessageNotDeliveredError
378
344
 
379
- run_expectations( :show, mock_queue, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
345
+ run_expectations( :show, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
380
346
 
381
347
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
382
348
  mock_result = endpoint.show( 'ident', mock_query )
@@ -392,26 +358,23 @@ describe Hoodoo::Services::Middleware do
392
358
  expect( errors[ 'errors' ][ 0 ][ 'code' ] ).to eq( 'platform.not_found' )
393
359
  end
394
360
 
395
- it 'calls #show over Alchemy and handles "unexpected" status codes' do
396
- mock_queue = 'service.version'
397
- mock_path = '/v2/version'
361
+ it 'calls #show over Alchemy and handles unusual HTTP status codes' do
362
+ mock_path = '/2/Version'
398
363
  mock_method = 'GET'
399
364
  mock_query = { :search => { :foo => :bar } }
400
365
 
401
366
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
402
367
  resource: 'Version',
403
- version: 2,
404
- queue_name: mock_queue,
405
- equivalent_path: mock_path
368
+ version: 2
406
369
  )
407
370
 
408
- bad_body_data = '499 Invented'
409
- mock_response = AlchemyAMQ::HTTPResponse.new(
410
- :status_code => 499,
411
- :body => bad_body_data
412
- )
371
+ bad_body_data = '499 Unusual Code'
372
+ mock_response = {
373
+ 'status_code' => 499,
374
+ 'body' => bad_body_data
375
+ }
413
376
 
414
- run_expectations( :show, mock_queue, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
377
+ run_expectations( :show, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
415
378
 
416
379
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
417
380
  mock_result = endpoint.show( 'ident', mock_query )
@@ -430,26 +393,55 @@ describe Hoodoo::Services::Middleware do
430
393
  expect( errors[ 'errors' ][ 0 ][ 'reference' ] ).to eq( "#{ bad_body_data }" )
431
394
  end
432
395
 
396
+ it 'calls #show over Alchemy and handles unrecognised return types' do
397
+ mock_path = '/2/Version'
398
+ mock_method = 'GET'
399
+ mock_query = { :search => { :foo => :bar } }
400
+
401
+ mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
402
+ resource: 'Version',
403
+ version: 2
404
+ )
405
+
406
+ bad_body_data = '500 Internal Server Error'
407
+ mock_response = Object.new
408
+
409
+ run_expectations( :show, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
410
+
411
+ endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
412
+ mock_result = endpoint.show( 'ident', mock_query )
413
+
414
+ expect( mock_result ).to be_a( Hoodoo::Client::AugmentedHash )
415
+ expect( mock_result.platform_errors ).to_not be_nil
416
+
417
+ errors = mock_result.platform_errors.render( Hoodoo::UUID.generate )
418
+
419
+ expect( errors ).to have_key( 'errors' )
420
+ expect( errors[ 'errors' ] ).to be_a( Array )
421
+ expect( errors[ 'errors' ][ 0 ] ).to_not be_nil
422
+
423
+ expect( errors[ 'errors' ][ 0 ][ 'code' ] ).to eq( 'platform.fault' )
424
+ expect( errors[ 'errors' ][ 0 ][ 'message' ] ).to eq( 'Unexpected raw HTTP status code 500 with non-JSON response' )
425
+ expect( errors[ 'errors' ][ 0 ][ 'reference' ] ).to eq( "#{ bad_body_data }" )
426
+ end
427
+
433
428
  it 'calls #show over Alchemy and handles 200 status but bad JSON' do
434
- mock_queue = 'service.version'
435
- mock_path = '/v2/version'
429
+ mock_path = '/2/Version'
436
430
  mock_method = 'GET'
437
431
  mock_query = { :search => { :foo => :bar } }
438
432
 
439
433
  mock_remote = Hoodoo::Services::Discovery::ForAMQP.new(
440
434
  resource: 'Version',
441
- version: 2,
442
- queue_name: mock_queue,
443
- equivalent_path: mock_path
435
+ version: 2
444
436
  )
445
437
 
446
438
  bad_body_data = 'Not JSON'
447
- mock_response = AlchemyAMQ::HTTPResponse.new(
448
- :status_code => 200,
449
- :body => bad_body_data
450
- )
439
+ mock_response = {
440
+ 'status_code' => 200,
441
+ 'body' => bad_body_data
442
+ }
451
443
 
452
- run_expectations( :show, mock_queue, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
444
+ run_expectations( :show, mock_path + '/ident', mock_method, mock_query, mock_remote, mock_response )
453
445
 
454
446
  endpoint = @mw.inter_resource_endpoint_for( 'Version', 2, @interaction )
455
447
  mock_result = endpoint.show( 'ident', mock_query )
@@ -483,14 +475,26 @@ describe Hoodoo::Services::Middleware do
483
475
  # the appropriate spec_helper.rb support method, just to see if it's awake.
484
476
  # If not, we don't expect the middleware's internal routines to manage it!
485
477
  #
486
- it 'demonstrates working HTTPS generally' do
487
- response = spec_helper_http(
488
- port: @port,
489
- path: '/v2/version',
490
- ssl: true
491
- )
478
+ context 'demonstrates working HTTPS generally via the' do
479
+ it 'custom endpoint route' do
480
+ response = spec_helper_http(
481
+ port: @port,
482
+ path: '/v2/version',
483
+ ssl: true
484
+ )
485
+
486
+ expect( response.code ).to eq( '200' )
487
+ end
492
488
 
493
- expect( response.code ).to eq( '200' )
489
+ it 'de facto endpoint route' do
490
+ response = spec_helper_http(
491
+ port: @port,
492
+ path: '/2/Version',
493
+ ssl: true
494
+ )
495
+
496
+ expect( response.code ).to eq( '200' )
497
+ end
494
498
  end
495
499
 
496
500
  # This is the *real* internal test, though done via calling down into the
@@ -517,7 +521,7 @@ describe Hoodoo::Services::Middleware do
517
521
  mock_wrapped_discovery_result = Hoodoo::Services::Discovery::ForHTTP.new(
518
522
  resource: 'Version',
519
523
  version: 2,
520
- endpoint_uri: URI.parse( "https://127.0.0.1:#{ @port }/v2/version" ),
524
+ endpoint_uri: URI.parse( "https://127.0.0.1:#{ @port }/2/Version" ),
521
525
  ca_file: 'spec/files/ca/ca-cert.pem'
522
526
  )
523
527