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.
- checksums.yaml +8 -8
- data/lib/hoodoo/client/endpoint/endpoints/amqp.rb +43 -25
- data/lib/hoodoo/discovery.rb +1 -1
- data/lib/hoodoo/services/discovery/discoverers/by_flux.rb +130 -0
- data/lib/hoodoo/services/discovery/results/for_amqp.rb +15 -21
- data/lib/hoodoo/services/discovery/results/for_local.rb +17 -0
- data/lib/hoodoo/services/middleware/amqp_log_message.rb +92 -154
- data/lib/hoodoo/services/middleware/amqp_log_writer.rb +25 -50
- data/lib/hoodoo/services/middleware/middleware.rb +75 -25
- data/lib/hoodoo/services/services/service.rb +2 -2
- data/lib/hoodoo/version.rb +1 -1
- data/spec/services/discovery/discoverers/by_flux_spec.rb +134 -0
- data/spec/services/discovery/results/for_amqp_spec.rb +4 -7
- data/spec/services/discovery/results/for_local_spec.rb +4 -0
- data/spec/services/middleware/amqp_log_message_spec.rb +32 -34
- data/spec/services/middleware/amqp_log_writer_spec.rb +2 -5
- data/spec/services/middleware/middleware_exotic_communication_spec.rb +147 -143
- data/spec/services/middleware/middleware_logging_spec.rb +10 -10
- data/spec/services/middleware/middleware_multi_remote_spec.rb +1 -1
- data/spec/services/middleware/middleware_public_spec.rb +73 -18
- data/spec/services/middleware/middleware_spec.rb +4 -4
- data/spec/services/services/application_spec.rb +3 -3
- data/spec/spec_helper.rb +3 -8
- metadata +19 -7
- data/lib/hoodoo/services/discovery/discoverers/by_consul.rb +0 -66
- data/spec/alchemy/alchemy-amq.rb +0 -33
- data/spec/services/discovery/discoverers/by_consul_spec.rb +0 -29
@@ -13,33 +13,33 @@ module Hoodoo; module Services
|
|
13
13
|
class Middleware
|
14
14
|
|
15
15
|
# Log writer which sends structured messages to an AMQP-based queue via
|
16
|
-
# the
|
17
|
-
# talking to the queue might be comparatively slow,
|
18
|
-
#
|
19
|
-
# this logger.
|
16
|
+
# the Alchemy Flux gem. A Hoodoo::Logger::FastWriter subclass, since though
|
17
|
+
# talking to the queue might be comparatively slow, Flux uses Event Machine
|
18
|
+
# for this so there's no need to add another Thread for this logger.
|
20
19
|
#
|
21
|
-
# See also Hoodoo::Logger
|
20
|
+
# See also Hoodoo::Logger.
|
22
21
|
#
|
23
22
|
class AMQPLogWriter < Hoodoo::Logger::FastWriter
|
24
23
|
|
25
24
|
# Create an AMQP logger instance.
|
26
25
|
#
|
27
|
-
# +alchemy+::
|
28
|
-
#
|
26
|
+
# +alchemy+:: The Alchemy endpoint to use for sending messages to the
|
27
|
+
# AMQP-based queue.
|
29
28
|
#
|
30
|
-
# +
|
31
|
-
#
|
32
|
-
#
|
29
|
+
# +routing_key+:: The routing key (as a String) to use. Optional. If
|
30
|
+
# omitted, reads +ENV[ 'AMQ_LOGGING_ENDPOINT' ]+ or if
|
31
|
+
# that is unset, defaults to +platform.logging+.
|
33
32
|
#
|
34
33
|
# If you're running with Rack on top of Alchemy, then the +call+ method's
|
35
|
-
# +env+ parameter containing the Rack environment
|
36
|
-
# +
|
37
|
-
#
|
38
|
-
#
|
34
|
+
# +env+ parameter containing the Rack environment _MUST_ have a key of
|
35
|
+
# +alchemy.service+ with a value that's the AlchemyFlux::Service instance
|
36
|
+
# handling queue communication. This is assigned to the +alchemy+
|
37
|
+
# parameter. The logger will then use this active Alchemy service to send
|
38
|
+
# messages to its configured routing key.
|
39
39
|
#
|
40
|
-
def initialize( alchemy,
|
41
|
-
@alchemy
|
42
|
-
@
|
40
|
+
def initialize( alchemy, routing_key = nil )
|
41
|
+
@alchemy = alchemy
|
42
|
+
@routing_key = routing_key || ENV[ 'AMQ_LOGGING_ENDPOINT' ] || 'platform.logging'
|
43
43
|
end
|
44
44
|
|
45
45
|
# Custom implementation of the Hoodoo::Logger::WriterMixin#report
|
@@ -63,19 +63,15 @@ module Hoodoo; module Services
|
|
63
63
|
# the log payload.
|
64
64
|
#
|
65
65
|
def report( level, component, code, data )
|
66
|
-
return if @alchemy.nil?
|
66
|
+
return if @alchemy.nil?
|
67
67
|
|
68
68
|
# Take care with Symbol keys in 'data' vs string keys in e.g. 'Session'.
|
69
69
|
|
70
70
|
data[ :id ] ||= Hoodoo::UUID.generate()
|
71
71
|
|
72
|
-
|
73
|
-
|
72
|
+
session = data[ :session ] || {}
|
73
|
+
message = Hoodoo::Services::Middleware::AMQPLogMessage.new( {
|
74
74
|
|
75
|
-
caller_id = session[ 'caller_id' ]
|
76
|
-
identity = ( session[ 'identity' ] || {} ).to_h
|
77
|
-
|
78
|
-
message = Hoodoo::Services::Middleware::AMQPLogMessage.new(
|
79
75
|
:id => data[ :id ],
|
80
76
|
:level => level,
|
81
77
|
:component => component,
|
@@ -84,34 +80,13 @@ module Hoodoo; module Services
|
|
84
80
|
|
85
81
|
:data => data,
|
86
82
|
|
87
|
-
:interaction_id => interaction_id,
|
88
|
-
:caller_id => caller_id,
|
89
|
-
:identity => identity
|
90
|
-
|
91
|
-
:routing_key => @queue_name,
|
92
|
-
)
|
83
|
+
:interaction_id => data[ :interaction_id ],
|
84
|
+
:caller_id => session[ 'caller_id' ],
|
85
|
+
:identity => ( session[ 'identity' ] || {} ).to_h
|
93
86
|
|
94
|
-
|
95
|
-
# BigDecimal, which Msgpack can't serialize. At the time of writing,
|
96
|
-
# Alchemy AMQ would thus encounter a serialization exception *within
|
97
|
-
# its EventMachine sending loop*, so in a different *native* thread.
|
98
|
-
# This exception could not be caught by Ruby / Hoodoo in "this"
|
99
|
-
# native thread, so instead the uncaught exception kills the service.
|
100
|
-
# Although Alchemy could catch that itself, there is no way for it to
|
101
|
-
# report the failure to Hoodoo in a way that a log reporting caller
|
102
|
-
# could understand; it's async and in the wrong native thread anyway.
|
103
|
-
#
|
104
|
-
# Solution: In non-production environments only (due to the potential
|
105
|
-
# performance hit), manually serialize the message before sending it.
|
106
|
-
# If this call blows up, the Hoodoo exception handler will catch it
|
107
|
-
# and report the result as a properly formed 500, including the
|
108
|
-
# Msgpack (or other exception) details on exactly what was wrong.
|
109
|
-
#
|
110
|
-
unless Hoodoo::Services::Middleware.environment.production?
|
111
|
-
message.serialize()
|
112
|
-
end
|
87
|
+
} ).to_h()
|
113
88
|
|
114
|
-
@alchemy.
|
89
|
+
@alchemy.send_message_to_queue( @routing_key, message )
|
115
90
|
end
|
116
91
|
end
|
117
92
|
|
@@ -53,7 +53,7 @@ module Hoodoo; module Services
|
|
53
53
|
#
|
54
54
|
# The middleware adds a STDERR stream writer logger by default and an AMQP
|
55
55
|
# log writer on the first Rack +call+ should the Rack environment provide an
|
56
|
-
# Alchemy endpoint (see the
|
56
|
+
# Alchemy endpoint (see the Alchemy Flux gem).
|
57
57
|
#
|
58
58
|
class Middleware
|
59
59
|
|
@@ -211,10 +211,37 @@ module Hoodoo; module Services
|
|
211
211
|
# Are we running on the queue, else (implied) a local HTTP server?
|
212
212
|
#
|
213
213
|
def self.on_queue?
|
214
|
-
q = ENV[ '
|
214
|
+
q = ENV[ 'AMQ_URI' ]
|
215
215
|
q.nil? == false && q.empty? == false
|
216
216
|
end
|
217
217
|
|
218
|
+
# Return a service 'name' derived from the service's collection of
|
219
|
+
# declared resources. The name will be the same across any instances of
|
220
|
+
# the service that implement the same resources. This can be used for
|
221
|
+
# e.g. AMQP-based queue-named operations, that want to target the same
|
222
|
+
# resource collection regardless of instance.
|
223
|
+
#
|
224
|
+
# This method will not work unless the middleware has parsed the set
|
225
|
+
# of service interface declarations (during instance initialisation).
|
226
|
+
# If a least one middleware instance has already been created, it is
|
227
|
+
# safe to call.
|
228
|
+
#
|
229
|
+
def self.service_name
|
230
|
+
@@service_name
|
231
|
+
end
|
232
|
+
|
233
|
+
# For a given resource name and version, return the _de_ _facto_ routing
|
234
|
+
# path based on version and name with no modifications.
|
235
|
+
#
|
236
|
+
# +resource+:: Resource name for the endpoint, e.g. +:Purchase+.
|
237
|
+
# String or symbol.
|
238
|
+
#
|
239
|
+
# +version+:: Implemented version of the endpoint. Integer.
|
240
|
+
#
|
241
|
+
def self.de_facto_path_for( resource, version )
|
242
|
+
"/#{ version }/#{ resource }"
|
243
|
+
end
|
244
|
+
|
218
245
|
# Access the middleware's logging instance. Call +report+ on this to make
|
219
246
|
# structured log entries. See Hoodoo::Logger::WriterMixin#report along
|
220
247
|
# with Hoodoo::Logger for other calls you can use.
|
@@ -338,7 +365,8 @@ module Hoodoo; module Services
|
|
338
365
|
# of the endpoints.
|
339
366
|
#
|
340
367
|
def self.flush_services_for_test
|
341
|
-
@@services
|
368
|
+
@@services = []
|
369
|
+
@@service_name = nil
|
342
370
|
|
343
371
|
ObjectSpace.each_object( self ) do | middleware_instance |
|
344
372
|
discoverer = middleware_instance.instance_variable_get( '@discoverer' )
|
@@ -383,7 +411,8 @@ module Hoodoo; module Services
|
|
383
411
|
# actions Set of symbols naming allowed actions
|
384
412
|
# implementation Hoodoo::Services::Implementation subclass *instance* to
|
385
413
|
# use on match
|
386
|
-
|
414
|
+
#
|
415
|
+
#
|
387
416
|
@@services = service_container.component_interfaces.map do | interface |
|
388
417
|
|
389
418
|
if interface.nil? || interface.endpoint.nil? || interface.implementation.nil?
|
@@ -395,6 +424,13 @@ module Hoodoo; module Services
|
|
395
424
|
#
|
396
425
|
interfaces_have_public_methods() unless interface.public_actions.empty?
|
397
426
|
|
427
|
+
# There are two routes to an implementation - one via the custom path
|
428
|
+
# given through its 'endpoint' declaration, the other a de facto path
|
429
|
+
# determined from the unmodified version and resource name. Both lead
|
430
|
+
# to the same implementation instance.
|
431
|
+
#
|
432
|
+
implementation_instance = interface.implementation.new
|
433
|
+
|
398
434
|
# Regexp explanation:
|
399
435
|
#
|
400
436
|
# Match "/", the version text, "/", the endpoint text, then either
|
@@ -402,17 +438,34 @@ module Hoodoo; module Services
|
|
402
438
|
# everything else. Match data index 1 will be whatever character (if
|
403
439
|
# any) followed after the endpoint ("/" or ".") while index 2 contains
|
404
440
|
# everything else.
|
441
|
+
#
|
442
|
+
custom_path = "/v#{ interface.version }/#{ interface.endpoint }"
|
443
|
+
custom_regexp = /\/v#{ interface.version }\/#{ interface.endpoint }(\.|\/|$)(.*)/
|
444
|
+
|
445
|
+
# Same as above, but for the de facto routing.
|
446
|
+
#
|
447
|
+
de_facto_path = self.class.de_facto_path_for( interface.resource, interface.version )
|
448
|
+
de_facto_regexp = /\/#{ interface.version }\/#{ interface.resource }(\.|\/|$)(.*)/
|
405
449
|
|
406
450
|
Hoodoo::Services::Discovery::ForLocal.new(
|
407
451
|
:resource => interface.resource,
|
408
452
|
:version => interface.version,
|
409
|
-
:base_path =>
|
410
|
-
:routing_regexp =>
|
453
|
+
:base_path => custom_path,
|
454
|
+
:routing_regexp => custom_regexp,
|
455
|
+
:de_facto_base_path => de_facto_path,
|
456
|
+
:de_facto_routing_regexp => de_facto_regexp,
|
411
457
|
:interface_class => interface,
|
412
|
-
:implementation_instance =>
|
458
|
+
:implementation_instance => implementation_instance
|
413
459
|
)
|
460
|
+
|
414
461
|
end
|
415
462
|
|
463
|
+
# Determine the service name from the resources above then announce
|
464
|
+
# the whole collection to any interested discovery engines.
|
465
|
+
|
466
|
+
sorted_resources = @@services.map() { | service | service.resource }.sort()
|
467
|
+
@@service_name = "service.#{ sorted_resources.join( '_' ) }"
|
468
|
+
|
416
469
|
announce_presence_of( @@services )
|
417
470
|
end
|
418
471
|
|
@@ -972,7 +1025,8 @@ module Hoodoo; module Services
|
|
972
1025
|
# +env+:: Rack 'env' parameter from e.g. Rack's invocation of #call.
|
973
1026
|
#
|
974
1027
|
def enable_alchemy_logging_from( env )
|
975
|
-
alchemy = env[ '
|
1028
|
+
alchemy = env[ 'alchemy.service' ]
|
1029
|
+
|
976
1030
|
unless alchemy.nil? || defined?( @@alchemy )
|
977
1031
|
@@alchemy = alchemy
|
978
1032
|
self.class.send( :add_queue_logging, @@alchemy ) unless @@alchemy.nil?
|
@@ -1343,22 +1397,13 @@ module Hoodoo; module Services
|
|
1343
1397
|
end
|
1344
1398
|
end
|
1345
1399
|
|
1346
|
-
# Announce the presence of the
|
1347
|
-
# parties.
|
1400
|
+
# Announce the presence of the local resource endpoints in this service
|
1401
|
+
# to known interested parties.
|
1348
1402
|
#
|
1349
1403
|
# ONLY CALL AS PART OF INSTANCE CREATION (from #initialize).
|
1350
1404
|
#
|
1351
|
-
# +services+:: Array of
|
1352
|
-
#
|
1353
|
-
# Hash keys/values are as follows:
|
1354
|
-
#
|
1355
|
-
# +regexp+:: A regular expression for a URI path which, if matched,
|
1356
|
-
# means that this service endpoint is being called.
|
1357
|
-
# +path+:: The endpoint path that the regexp would match, with
|
1358
|
-
# leading "/" (e.g. "/v1/products")
|
1359
|
-
# +interface+:: The Interface subclass for this endpoint.
|
1360
|
-
# +implementation+:: The Implementation subclass instance for this
|
1361
|
-
# endpoint.
|
1405
|
+
# +services+:: Array of Hoodoo::Services::Discovery::ForLocal instances
|
1406
|
+
# describing available resources in this local service.
|
1362
1407
|
#
|
1363
1408
|
def announce_presence_of( services )
|
1364
1409
|
|
@@ -1370,7 +1415,7 @@ module Hoodoo; module Services
|
|
1370
1415
|
#
|
1371
1416
|
# A class variable is wrong, as entirely new instances of the service
|
1372
1417
|
# middleware might be stood up in one process and could potentially
|
1373
|
-
# be handling different
|
1418
|
+
# be handling different resources. This is typically only the case for
|
1374
1419
|
# running tests, but *might* happen elsewhere too. In any event, we
|
1375
1420
|
# don't want announcements in one instance to pollute the discovery
|
1376
1421
|
# data in another (especially the records of which services were
|
@@ -1378,14 +1423,15 @@ module Hoodoo; module Services
|
|
1378
1423
|
|
1379
1424
|
if self.class.on_queue?
|
1380
1425
|
|
1381
|
-
@discoverer ||= Hoodoo::Services::Discovery::
|
1426
|
+
@discoverer ||= Hoodoo::Services::Discovery::ByFlux.new
|
1382
1427
|
|
1383
1428
|
services.each do | service |
|
1384
1429
|
interface = service.interface_class
|
1385
1430
|
|
1386
1431
|
@discoverer.announce(
|
1387
1432
|
interface.resource,
|
1388
|
-
interface.version
|
1433
|
+
interface.version,
|
1434
|
+
{ :services => services }
|
1389
1435
|
)
|
1390
1436
|
end
|
1391
1437
|
|
@@ -1584,12 +1630,16 @@ module Hoodoo; module Services
|
|
1584
1630
|
# then there's no matching endpoint; badly routed request; 404. If we
|
1585
1631
|
# find many, raise an exception and rely on the exception handler to
|
1586
1632
|
# send back a 500.
|
1633
|
+
#
|
1634
|
+
# We try the custom routing path first, then the de facto path, then
|
1635
|
+
# give up if neither match.
|
1587
1636
|
|
1588
1637
|
uri_path = CGI.unescape( interaction.rack_request.path() )
|
1589
1638
|
|
1590
1639
|
selected_path_data = nil
|
1591
1640
|
selected_services = @@services.select do | service_data |
|
1592
|
-
path_data = process_uri_path( uri_path, service_data.routing_regexp )
|
1641
|
+
path_data = process_uri_path( uri_path, service_data.routing_regexp ) ||
|
1642
|
+
process_uri_path( uri_path, service_data.de_facto_routing_regexp )
|
1593
1643
|
|
1594
1644
|
if path_data.nil?
|
1595
1645
|
false
|
@@ -102,7 +102,7 @@ module Hoodoo; module Services
|
|
102
102
|
# +env+:: Rack environment (ignored).
|
103
103
|
#
|
104
104
|
def call( env )
|
105
|
-
raise "Hoodoo::Services::
|
105
|
+
raise "Hoodoo::Services::Service subclasses should only be called through the middleware - add 'use Hoodoo::Services::Middleware' to (e.g.) config.ru"
|
106
106
|
end
|
107
107
|
|
108
108
|
protected
|
@@ -126,7 +126,7 @@ module Hoodoo; module Services
|
|
126
126
|
#
|
127
127
|
classes.each do | klass |
|
128
128
|
unless klass < Hoodoo::Services::Interface
|
129
|
-
raise "Hoodoo::Services::
|
129
|
+
raise "Hoodoo::Services::Service::comprised_of expects Hoodoo::Services::Interface subclasses only - got '#{ klass }'"
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
data/lib/hoodoo/version.rb
CHANGED
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hoodoo::Services::Discovery::ByFlux do
|
4
|
+
|
5
|
+
after :all do
|
6
|
+
Hoodoo::Services::Middleware.flush_services_for_test()
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'without a mocked service name it' do
|
10
|
+
before :each do
|
11
|
+
@d = described_class.new
|
12
|
+
allow( Hoodoo::Services::Middleware ).to receive( :service_name ).and_return( 'service.Version' )
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'announces' do
|
16
|
+
result = @d.announce( 'Version', '2' ) # Intentional string use
|
17
|
+
|
18
|
+
expect( result ).to be_a( Hoodoo::Services::Discovery::ForAMQP )
|
19
|
+
expect( result.resource ).to eq( :Version )
|
20
|
+
expect( result.version ).to eq( 2 )
|
21
|
+
expect( result.routing_path ).to eq( '/2/Version')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'discovers local' do
|
25
|
+
@d.announce( :Version, 2 )
|
26
|
+
result = @d.discover( 'Version', '2' )
|
27
|
+
|
28
|
+
expect( result ).to be_a( Hoodoo::Services::Discovery::ForAMQP )
|
29
|
+
expect( result.resource ).to eq( :Version )
|
30
|
+
expect( result.version ).to eq( 2 )
|
31
|
+
expect( result.routing_path ).to eq( '/2/Version')
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'discovers remote' do
|
35
|
+
result = @d.discover( 'External', 1 )
|
36
|
+
|
37
|
+
expect( result ).to be_a( Hoodoo::Services::Discovery::ForAMQP )
|
38
|
+
expect( result.resource ).to eq( :External )
|
39
|
+
expect( result.version ).to eq( 1 )
|
40
|
+
expect( result.routing_path ).to eq( '/1/External')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with a real service list it' do
|
45
|
+
|
46
|
+
class FluxDiscovererImplementationA < Hoodoo::Services::Implementation; end
|
47
|
+
class FluxDiscovererImplementationB < Hoodoo::Services::Implementation; end
|
48
|
+
class FluxDiscovererImplementationC < Hoodoo::Services::Implementation; end
|
49
|
+
|
50
|
+
class FluxDiscovererInterfaceA < Hoodoo::Services::Interface
|
51
|
+
interface :InterfaceA do
|
52
|
+
endpoint :a_interfaces, FluxDiscovererImplementationA
|
53
|
+
version 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class FluxDiscovererInterfaceB < Hoodoo::Services::Interface
|
58
|
+
interface :InterfaceB do
|
59
|
+
endpoint :b_interfaces, FluxDiscovererImplementationA
|
60
|
+
version 2
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class FluxDiscovererInterfaceC < Hoodoo::Services::Interface
|
65
|
+
interface :InterfaceC do
|
66
|
+
endpoint :c_interfaces, FluxDiscovererImplementationA
|
67
|
+
version 3
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Intentionally not in alphabetical order, to check for reordering in
|
72
|
+
# service name / queue name environment variable later.
|
73
|
+
#
|
74
|
+
class FluxDiscovererService < Hoodoo::Services::Service
|
75
|
+
comprised_of FluxDiscovererInterfaceB,
|
76
|
+
FluxDiscovererInterfaceA,
|
77
|
+
FluxDiscovererInterfaceC
|
78
|
+
end
|
79
|
+
|
80
|
+
before :each do
|
81
|
+
Hoodoo::Services::Middleware.flush_services_for_test()
|
82
|
+
@d = described_class.new
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'announces and sets environment variables' do
|
86
|
+
ENV.delete( 'ALCHEMY_SERVICE_NAME' )
|
87
|
+
ENV.delete( 'ALCHEMY_RESOURCE_PATHS' )
|
88
|
+
|
89
|
+
expect_any_instance_of( Hoodoo::Services::Middleware ).to receive( :announce_presence_of ) do | instance, services |
|
90
|
+
result = @d.announce( :InterfaceA, '1', { :services => services } )
|
91
|
+
|
92
|
+
expect( result ).to be_a( Hoodoo::Services::Discovery::ForAMQP )
|
93
|
+
expect( result.resource ).to eq( :InterfaceA )
|
94
|
+
expect( result.version ).to eq( 1 )
|
95
|
+
expect( result.routing_path ).to eq( '/1/InterfaceA')
|
96
|
+
end
|
97
|
+
|
98
|
+
Hoodoo::Services::Middleware.new( FluxDiscovererService.new )
|
99
|
+
|
100
|
+
expect( ENV[ 'ALCHEMY_SERVICE_NAME' ] ).to eq( 'service.InterfaceA_InterfaceB_InterfaceC' )
|
101
|
+
expect( ENV[ 'ALCHEMY_RESOURCE_PATHS' ].split( ',' ) ).to match_array(
|
102
|
+
%w{ /v1/a_interfaces /1/InterfaceA /v2/b_interfaces /2/InterfaceB /v3/c_interfaces /3/InterfaceC }
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'discovers local' do
|
107
|
+
expect_any_instance_of( Hoodoo::Services::Middleware ).to receive( :announce_presence_of ) do | instance, services |
|
108
|
+
@d.announce( :InterfaceC, 3, { :services => services } )
|
109
|
+
result = @d.discover( 'InterfaceC', '3' )
|
110
|
+
|
111
|
+
expect( result ).to be_a( Hoodoo::Services::Discovery::ForAMQP )
|
112
|
+
expect( result.resource ).to eq( :InterfaceC )
|
113
|
+
expect( result.version ).to eq( 3 )
|
114
|
+
expect( result.routing_path ).to eq( '/3/InterfaceC')
|
115
|
+
end
|
116
|
+
|
117
|
+
Hoodoo::Services::Middleware.new( FluxDiscovererService.new )
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'discovers remote' do
|
121
|
+
expect_any_instance_of( Hoodoo::Services::Middleware ).to receive( :announce_presence_of ) do | instance, services |
|
122
|
+
result = @d.discover( 'External', 1 )
|
123
|
+
|
124
|
+
expect( result ).to be_a( Hoodoo::Services::Discovery::ForAMQP )
|
125
|
+
expect( result.resource ).to eq( :External )
|
126
|
+
expect( result.version ).to eq( 1 )
|
127
|
+
expect( result.routing_path ).to eq( '/1/External')
|
128
|
+
end
|
129
|
+
|
130
|
+
Hoodoo::Services::Middleware.new( FluxDiscovererService.new )
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|