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
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MTFiNjAzNDk4MDdmOTFmNWRkZTg1MmY3ODExMmY3ZGU4MTU3YjkzNg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjMwNDRjODEzZDU5YmRmM2E0YmRlNTlmYTVkYzA3NmIxMDA3ZjE1Yg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjEzZDYxZDJjZGI3MWU0NDFmYTYwNzQ2ZmYwZGY4MmQ2Zjc0NWJhZmRiMjli
|
10
|
+
ZjQ0MTA1MzkzYTFkN2RhZTA1YWFkNjc1MDI4MDgwNzYyZDk5YmFhZTdmZDE1
|
11
|
+
ZTJlYjRjZDc5N2IzYmNiNTc0M2Q0NzMzNDhlODk3OTEzZjc0YTU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MzMwNGY1MGZlOTFiZjE3YmI0MDgxYjcwYTUxYTliNTQxNDFjODMwNThkMGUx
|
14
|
+
ZDk5NzE0ZDcwMWY1YzZhMTIxMzgyY2ZiMWJiMTFiZjk4ZmNlMTE0N2JmZThj
|
15
|
+
ZDIxZWM4MzQ0ODc0ODdmNWU5OWEzYmU3ODlkMTE4OTI1ZTNiYWM=
|
@@ -39,7 +39,7 @@ module Hoodoo
|
|
39
39
|
# to keep Rack happy.
|
40
40
|
|
41
41
|
endpoint_uri = URI.parse( 'http://localhost:80' )
|
42
|
-
endpoint_uri.path = @discovery_result.
|
42
|
+
endpoint_uri.path = @discovery_result.routing_path
|
43
43
|
|
44
44
|
@description = Hoodoo::Client::Endpoint::HTTPBased::DescriptionOfRequest.new
|
45
45
|
@description.discovery_result = @discovery_result
|
@@ -136,40 +136,58 @@ module Hoodoo
|
|
136
136
|
action = description_of_request.action
|
137
137
|
data = get_data_for_request( description_of_request )
|
138
138
|
|
139
|
-
# Host and port are
|
139
|
+
# Host and port are only provided to keep Rack happy at the
|
140
140
|
# receiving end of the over-AMQP synthesised HTTP request.
|
141
141
|
|
142
|
-
|
143
|
-
|
144
|
-
:
|
145
|
-
:
|
146
|
-
:
|
147
|
-
|
142
|
+
http_method =
|
143
|
+
{
|
144
|
+
:create => 'POST',
|
145
|
+
:update => 'PATCH',
|
146
|
+
:delete => 'DELETE'
|
147
|
+
}[ action ] || 'GET'
|
148
|
+
|
149
|
+
http_message =
|
150
|
+
{
|
151
|
+
'scheme' => 'http',
|
152
|
+
'verb' => http_method,
|
153
|
+
|
154
|
+
'host' => description_of_request.endpoint_uri.host,
|
155
|
+
'port' => description_of_request.endpoint_uri.port,
|
156
|
+
'path' => data.full_uri.path,
|
157
|
+
'query' => data.query_hash,
|
158
|
+
|
159
|
+
'headers' => data.header_hash,
|
160
|
+
'body' => data.body_string
|
148
161
|
}
|
149
162
|
|
150
163
|
unless self.session_id().nil? # Session comes from Endpoint superclass
|
151
|
-
|
164
|
+
http_message[ 'session_id' ] = self.session_id()
|
152
165
|
end
|
153
166
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
167
|
+
amqp_response = self.alchemy().send_message_to_resource( http_message )
|
168
|
+
|
169
|
+
description_of_response = DescriptionOfResponse.new
|
170
|
+
description_of_response.action = action
|
171
|
+
description_of_response.http_headers = {}
|
159
172
|
|
160
|
-
|
161
|
-
|
173
|
+
if amqp_response == AlchemyFlux::TimeoutError
|
174
|
+
description_of_response.http_status_code = 408
|
175
|
+
description_of_response.raw_body_data = '408 Timeout'
|
162
176
|
|
163
|
-
amqp_response
|
164
|
-
|
165
|
-
|
166
|
-
data.full_uri.path,
|
167
|
-
alchemy_options
|
168
|
-
)
|
177
|
+
elsif amqp_response == AlchemyFlux::MessageNotDeliveredError
|
178
|
+
description_of_response.http_status_code = 404
|
179
|
+
description_of_response.raw_body_data = '404 Not Found'
|
169
180
|
|
170
|
-
|
171
|
-
|
172
|
-
|
181
|
+
elsif amqp_response.is_a?( Hash )
|
182
|
+
description_of_response.http_status_code = amqp_response[ 'status_code' ].to_i
|
183
|
+
description_of_response.http_headers = amqp_response[ 'headers' ] || {}
|
184
|
+
description_of_response.raw_body_data = amqp_response[ 'body' ]
|
185
|
+
|
186
|
+
else
|
187
|
+
description_of_response.http_status_code = 500
|
188
|
+
description_of_response.raw_body_data = '500 Internal Server Error'
|
189
|
+
|
190
|
+
end
|
173
191
|
|
174
192
|
return get_data_for_response( description_of_response )
|
175
193
|
end
|
data/lib/hoodoo/discovery.rb
CHANGED
@@ -15,6 +15,6 @@ require 'hoodoo/services/discovery/results/for_local'
|
|
15
15
|
require 'hoodoo/services/discovery/results/for_remote'
|
16
16
|
|
17
17
|
require 'hoodoo/services/discovery/discoverers/by_convention'
|
18
|
-
require 'hoodoo/services/discovery/discoverers/
|
18
|
+
require 'hoodoo/services/discovery/discoverers/by_flux'
|
19
19
|
require 'hoodoo/services/discovery/discoverers/by_drb/drb_server'
|
20
20
|
require 'hoodoo/services/discovery/discoverers/by_drb/by_drb'
|
@@ -0,0 +1,130 @@
|
|
1
|
+
########################################################################
|
2
|
+
# File:: by_flux.rb
|
3
|
+
# (C):: Loyalty New Zealand 2015
|
4
|
+
#
|
5
|
+
# Purpose:: Discover resource endpoint locations via Alchemy Flux.
|
6
|
+
# ----------------------------------------------------------------------
|
7
|
+
# 03-Mar-2015 (ADH): Created.
|
8
|
+
# 21-Jan-2016 (ADH): Reimplemented for Alchemy Flux.
|
9
|
+
########################################################################
|
10
|
+
|
11
|
+
module Hoodoo
|
12
|
+
module Services
|
13
|
+
class Discovery # Just used as a namespace here
|
14
|
+
|
15
|
+
# Discover resource endpoint locations via Alchemy Flux.
|
16
|
+
#
|
17
|
+
# For Flux, it's less about discovery as it is about convention
|
18
|
+
# and announcing. We have to set some system variables when the
|
19
|
+
# application starts up, _before_ the Rack `run` call gets as
|
20
|
+
# far as the Alchemy Flux server's implementation - in practice
|
21
|
+
# this means announcement needs to happen from the Hoodoo
|
22
|
+
# middleware's constructor, synchronously. The environment
|
23
|
+
# variables tell Flux about this local service's URI-located
|
24
|
+
# endpoints and derive a consistent, replicable 'service name'
|
25
|
+
# from the resources which the service implements.
|
26
|
+
#
|
27
|
+
# Once all that is set up, the local Alchemy instance knows how
|
28
|
+
# to listen for relevant messages for 'this' service on the queue
|
29
|
+
# and Hoodoo in 'this' service knowns which resources are local,
|
30
|
+
# or which are remote; and it knows that Flux is able in turn to
|
31
|
+
# use URI-based to-resource communications for inter-resource
|
32
|
+
# calls without any further explicit discovery within Hoodoo
|
33
|
+
# beyond simply saying "here's the AMQP Flux endpoint class".
|
34
|
+
#
|
35
|
+
class ByFlux < Hoodoo::Services::Discovery
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
# Announce the location of an instance to Alchemy Flux.
|
40
|
+
#
|
41
|
+
# Call via Hoodoo::Services::Discovery::Base#announce.
|
42
|
+
#
|
43
|
+
# +resource+:: Passed to #discover_remote.
|
44
|
+
# +version+:: Passed to #discover_remote.
|
45
|
+
# +options+:: See below.
|
46
|
+
#
|
47
|
+
# The Options hash informs the announcer of the intended endpoint
|
48
|
+
# base URI for the resource and also, where available, provides a
|
49
|
+
# head-up on the full range of resource _names_ that will be
|
50
|
+
# present in this single service application (see
|
51
|
+
# Hoodoo::Services::Service::comprised_of). Keys MUST be Symbols.
|
52
|
+
# Associated required values are:
|
53
|
+
#
|
54
|
+
# +services+:: Array of Hoodoo::Services::Discovery::ForLocal
|
55
|
+
# instances describing available resources in this
|
56
|
+
# local service.
|
57
|
+
#
|
58
|
+
def announce_remote( resource, version, options = {} )
|
59
|
+
|
60
|
+
alchemy_resource_paths = ENV[ 'ALCHEMY_RESOURCE_PATHS' ]
|
61
|
+
alchemy_service_name = ENV[ 'ALCHEMY_SERVICE_NAME' ]
|
62
|
+
|
63
|
+
# Under Flux, we "announce" via a local environment variable when
|
64
|
+
# this service awakens which tells Flux what to listen for on the
|
65
|
+
# AMQP queue.
|
66
|
+
#
|
67
|
+
# Since inbound HTTP calls into the architecture are based on URIs
|
68
|
+
# and paths, there needs to be a mapping at that point to queue
|
69
|
+
# endpoints. Historically Hoodoo adopted an (in hindsight, unwise)
|
70
|
+
# approach of "/v<version>/<pluralised_resource>" c.f. Rails,
|
71
|
+
# rather than just "/<version>/<resource>" - e.g. there was
|
72
|
+
# "/v1/members" instead of "/1/Member". This means things like the
|
73
|
+
# "ByConvention" discoverer have to use pluralisation rules and
|
74
|
+
# exceptions. It's messy.
|
75
|
+
#
|
76
|
+
# To clean things up, the work on Alchemy Flux sets up *two* paths
|
77
|
+
# in Hoodoo - the old one for backwards compatibility, and a new
|
78
|
+
# one of the above simpler form. Now it's easy to go from version
|
79
|
+
# and resource name to path or back internally with no mappings.
|
80
|
+
#
|
81
|
+
if ( alchemy_resource_paths.nil? ||
|
82
|
+
alchemy_resource_paths.strip.empty? )
|
83
|
+
|
84
|
+
services = options[ :services ] || []
|
85
|
+
paths = []
|
86
|
+
|
87
|
+
services.each do | service |
|
88
|
+
custom_path = service.base_path
|
89
|
+
de_facto_path = service.de_facto_base_path
|
90
|
+
|
91
|
+
paths << custom_path << de_facto_path
|
92
|
+
end
|
93
|
+
|
94
|
+
ENV[ 'ALCHEMY_RESOURCE_PATHS' ] = paths.join( ',' )
|
95
|
+
end
|
96
|
+
|
97
|
+
if ( alchemy_service_name.nil? ||
|
98
|
+
alchemy_service_name.strip.empty? )
|
99
|
+
ENV[ 'ALCHEMY_SERVICE_NAME' ] = Hoodoo::Services::Middleware::service_name()
|
100
|
+
end
|
101
|
+
|
102
|
+
return discover_remote( resource, version )
|
103
|
+
end
|
104
|
+
|
105
|
+
# Discover the location of an instance.
|
106
|
+
#
|
107
|
+
# Returns a Hoodoo::Services::Discovery::ForAMQP instance if
|
108
|
+
# the endpoint is found, else +nil+.
|
109
|
+
#
|
110
|
+
# Call via Hoodoo::Services::Discovery::Base#announce.
|
111
|
+
#
|
112
|
+
# +resource+:: Passed to #discover_remote.
|
113
|
+
# +version+:: Passed to #discover_remote.
|
114
|
+
#
|
115
|
+
def discover_remote( resource, version )
|
116
|
+
de_facto_path = Hoodoo::Services::Middleware::de_facto_path_for(
|
117
|
+
resource,
|
118
|
+
version
|
119
|
+
)
|
120
|
+
|
121
|
+
return Hoodoo::Services::Discovery::ForAMQP.new(
|
122
|
+
resource: resource,
|
123
|
+
version: version
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -25,32 +25,26 @@ module Hoodoo
|
|
25
25
|
#
|
26
26
|
attr_accessor :version
|
27
27
|
|
28
|
-
#
|
29
|
-
#
|
28
|
+
# Path at which the resource is expected to be found on the queue
|
29
|
+
# (routing via Topic Exchange and Alchemy Flux's translations of
|
30
|
+
# paths to keys).
|
30
31
|
#
|
31
|
-
|
32
|
-
|
33
|
-
# URL path equivalent that should be mapped to the queue in
|
34
|
-
# #queue_name, as a String (e.g. "/v2/accounts").
|
35
|
-
#
|
36
|
-
attr_accessor :equivalent_path
|
32
|
+
attr_reader :routing_path
|
37
33
|
|
38
34
|
# Create an instance with named parameters as follows:
|
39
35
|
#
|
40
|
-
# +resource+::
|
41
|
-
# +version+::
|
42
|
-
# +queue_name+:: See #queue_name.
|
43
|
-
# +equivalent_pat+:: See #equivalent_pat.
|
36
|
+
# +resource+:: See #resource.
|
37
|
+
# +version+:: See #version.
|
44
38
|
#
|
45
|
-
def initialize( resource:,
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
39
|
+
def initialize( resource:, version: )
|
40
|
+
|
41
|
+
@resource = resource.to_sym
|
42
|
+
@version = version.to_i
|
43
|
+
@routing_path = Hoodoo::Services::Middleware.de_facto_path_for(
|
44
|
+
resource,
|
45
|
+
version
|
46
|
+
)
|
47
|
+
|
54
48
|
end
|
55
49
|
end
|
56
50
|
end
|
@@ -46,6 +46,17 @@ module Hoodoo
|
|
46
46
|
#
|
47
47
|
attr_accessor :routing_regexp
|
48
48
|
|
49
|
+
# The de facto routing equivalent of #base_path. This is not
|
50
|
+
# a custom path based on the interface's declared endpoint; it
|
51
|
+
# is derived directlyf rom resource or version - for example,
|
52
|
+
# "/1/Product" or "/2/Member". String.
|
53
|
+
#
|
54
|
+
attr_accessor :de_facto_base_path
|
55
|
+
|
56
|
+
# As #routing_regexp, but matches #de_facto_base_path.
|
57
|
+
#
|
58
|
+
attr_accessor :de_facto_routing_regexp
|
59
|
+
|
49
60
|
# The Hoodoo::Services::Interface subclass _class_ describing the
|
50
61
|
# resource interface.
|
51
62
|
#
|
@@ -62,6 +73,8 @@ module Hoodoo
|
|
62
73
|
# +version+:: See #version.
|
63
74
|
# +base_path+:: See #base_path.
|
64
75
|
# +routing_regexp+:: See #routing_regexp.
|
76
|
+
# +de_facto_base_path+:: See #de_facto_base_path.
|
77
|
+
# +de_facto_routing_regexp+:: See #de_facto_routing_regexp.
|
65
78
|
# +interface_class+:: See #interface_class.
|
66
79
|
# +implementation_instance+:: See #implementation_instance.
|
67
80
|
#
|
@@ -69,6 +82,8 @@ module Hoodoo
|
|
69
82
|
version:,
|
70
83
|
base_path:,
|
71
84
|
routing_regexp:,
|
85
|
+
de_facto_base_path:,
|
86
|
+
de_facto_routing_regexp:,
|
72
87
|
interface_class:,
|
73
88
|
implementation_instance: )
|
74
89
|
|
@@ -76,6 +91,8 @@ module Hoodoo
|
|
76
91
|
self.version = version.to_i
|
77
92
|
self.base_path = base_path
|
78
93
|
self.routing_regexp = routing_regexp
|
94
|
+
self.de_facto_base_path = de_facto_base_path
|
95
|
+
self.de_facto_routing_regexp = de_facto_routing_regexp
|
79
96
|
self.interface_class = interface_class
|
80
97
|
self.implementation_instance = implementation_instance
|
81
98
|
end
|
@@ -3,8 +3,9 @@
|
|
3
3
|
# (C):: Loyalty New Zealand 2014
|
4
4
|
#
|
5
5
|
# Purpose:: Structured logging onto an AMQP-based queue, via the
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# Alchemy Flux gem. This class just exists to rationalise
|
7
|
+
# any parameters inbound in order to generate a clean
|
8
|
+
# representation for Flux.
|
8
9
|
#
|
9
10
|
# The middleware uses this to put log and error messages
|
10
11
|
# on the queue. Interested services use this to read such
|
@@ -13,173 +14,110 @@
|
|
13
14
|
# 20-Nov-2014 (ADH): Created.
|
14
15
|
########################################################################
|
15
16
|
|
16
|
-
# TODO: See spec/alchemy/alchemy-amq.rb. Remove this once 'real' Alchemy
|
17
|
-
# is opened.
|
18
|
-
#
|
19
|
-
$LOAD_PATH.unshift File.join( File.dirname( __FILE__ ), 'alchemy' )
|
20
|
-
|
21
17
|
module Hoodoo; module Services
|
22
18
|
class Middleware
|
23
19
|
|
24
|
-
|
25
|
-
|
20
|
+
# A representation of a log message placed on an AMQP-based queue.
|
21
|
+
# The primary expected communications interface is Alchemy Flux at
|
22
|
+
# the time of writing.
|
23
|
+
#
|
24
|
+
class AMQPLogMessage
|
26
25
|
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# the queue. Hoodoo::Logger uses this.
|
26
|
+
# The Time +strftime+ formatter used for string conversions in this
|
27
|
+
# class.
|
30
28
|
#
|
31
|
-
|
29
|
+
TIME_FORMATTER = '%Y-%m-%d %H:%M:%S.%12N %Z'
|
30
|
+
|
31
|
+
# A UUID to assign to this log message. See Hoodoo::UUID::generate.
|
32
32
|
#
|
33
|
-
|
34
|
-
|
35
|
-
# The named "type" of this message, to be registered with AlchemyAMQ.
|
36
|
-
#
|
37
|
-
TYPE = 'hoodoo_service_middleware_amqp_log_message'
|
38
|
-
|
39
|
-
# The Time +strftime+ formatter used for string conversions in this
|
40
|
-
# class.
|
41
|
-
#
|
42
|
-
TIME_FORMATTER = '%Y-%m-%d %H:%M:%S.%12N %Z'
|
43
|
-
|
44
|
-
# This line of code registers wth AlchemyAMQ, but also makes RDoc
|
45
|
-
# screw up. RDoc decides that we have a new module,
|
46
|
-
# Hoodoo::Services::Middleware::AMQPLogMessage::AlchemyAMQ. Very
|
47
|
-
# strange...
|
48
|
-
#
|
49
|
-
::AlchemyAMQ::Message.register_type( TYPE, self )
|
50
|
-
|
51
|
-
# ...so do _this_ purely so that we can get 100% real documentation
|
52
|
-
# coverage without it being clouded by RDoc's hiccups.
|
53
|
-
|
54
|
-
# This documentation exists purely to work around an RDoc hiccup where
|
55
|
-
# it thinks such a module exists.
|
56
|
-
#
|
57
|
-
# See file "services/middleware/amqp_log_message.rb" for details.
|
58
|
-
#
|
59
|
-
module AlchemyAMQ
|
60
|
-
end
|
33
|
+
attr_accessor :id
|
61
34
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
# Logging level. See Hoodoo::Logger.
|
67
|
-
#
|
68
|
-
attr_accessor :level
|
69
|
-
|
70
|
-
# Logging component. See Hoodoo::Logger.
|
71
|
-
#
|
72
|
-
attr_accessor :component
|
73
|
-
|
74
|
-
# Component log code. See Hoodoo::Logger.
|
75
|
-
#
|
76
|
-
attr_accessor :code
|
77
|
-
|
78
|
-
# The time at which this log message is being reported to the Logger
|
79
|
-
# instance. This is a formatted *String* to high accuracy. See also
|
80
|
-
# #reported_at=.
|
81
|
-
#
|
82
|
-
attr_reader :reported_at
|
83
|
-
|
84
|
-
# Set the time read back by #reported_at using a Time instance. This
|
85
|
-
# is formatted internally as a String via TIME_FORMATTER and reported
|
86
|
-
# as such in subsequent calls to #reported_at.
|
87
|
-
#
|
88
|
-
# Conversion from Time to String is done here, rather than by the
|
89
|
-
# caller setting this instance's variables, so that we can internally
|
90
|
-
# enforce the accuracy required for this field.
|
91
|
-
#
|
92
|
-
# +time+:: The Time instance to set (and process into a string
|
93
|
-
# internally via TIME_FORMATTER), *or* a String instance
|
94
|
-
# already so formatted, *or* +nil+ to clear the value.
|
95
|
-
#
|
96
|
-
def reported_at=( time )
|
97
|
-
if time.is_a?( String )
|
98
|
-
@reported_at = time
|
99
|
-
elsif time.is_a?( Time )
|
100
|
-
@reported_at = time.strftime( TIME_FORMATTER )
|
101
|
-
else
|
102
|
-
@reported_at = nil
|
103
|
-
end
|
104
|
-
end
|
35
|
+
# Logging level. See Hoodoo::Logger.
|
36
|
+
#
|
37
|
+
attr_accessor :level
|
105
38
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
# Optional calling Caller ID, via session data inside the payload - see
|
111
|
-
# Hoodoo::Logger.
|
112
|
-
#
|
113
|
-
attr_accessor :caller_id
|
114
|
-
|
115
|
-
# Optional interaction UUID, via session data inside the payload - see
|
116
|
-
# Hoodoo::Logger.
|
117
|
-
#
|
118
|
-
attr_accessor :interaction_id
|
119
|
-
|
120
|
-
# Optional hash of identity properties from the session data inside the
|
121
|
-
# payload - see Hoodoo::Logger.
|
122
|
-
#
|
123
|
-
attr_accessor :identity
|
124
|
-
|
125
|
-
# Create an instance with options keyed on the attributes defined for
|
126
|
-
# the class.
|
127
|
-
#
|
128
|
-
def initialize(options = {})
|
129
|
-
update( options ) # Should be called before 'super'
|
130
|
-
super( options )
|
131
|
-
|
132
|
-
@type = AMQPLogMessage::TYPE
|
133
|
-
end
|
39
|
+
# Logging component. See Hoodoo::Logger.
|
40
|
+
#
|
41
|
+
attr_accessor :component
|
134
42
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
def serialize
|
139
|
-
@content = {
|
140
|
-
:id => @id,
|
141
|
-
:level => @level,
|
142
|
-
:component => @component,
|
143
|
-
:code => @code,
|
144
|
-
:reported_at => @reported_at,
|
145
|
-
|
146
|
-
:data => @data,
|
147
|
-
|
148
|
-
:interaction_id => @interaction_id,
|
149
|
-
:caller_id => @caller_id,
|
150
|
-
:identity => @identity
|
151
|
-
}
|
152
|
-
|
153
|
-
super
|
154
|
-
end
|
43
|
+
# Component log code. See Hoodoo::Logger.
|
44
|
+
#
|
45
|
+
attr_accessor :code
|
155
46
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
47
|
+
# The time at which this log message is being reported to the Logger
|
48
|
+
# instance. This is a formatted *String* to high accuracy. See also
|
49
|
+
# #reported_at=.
|
50
|
+
#
|
51
|
+
attr_reader :reported_at
|
52
|
+
|
53
|
+
# Set the time read back by #reported_at using a Time instance. This
|
54
|
+
# is formatted internally as a String via TIME_FORMATTER and reported
|
55
|
+
# as such in subsequent calls to #reported_at.
|
56
|
+
#
|
57
|
+
# Conversion from Time to String is done here, rather than by the
|
58
|
+
# caller setting this instance's variables, so that we can internally
|
59
|
+
# enforce the accuracy required for this field.
|
60
|
+
#
|
61
|
+
# +time+:: The Time instance to set (and process into a string
|
62
|
+
# internally via TIME_FORMATTER), *or* a String instance
|
63
|
+
# already so formatted, *or* +nil+ to clear the value.
|
64
|
+
#
|
65
|
+
def reported_at=( time )
|
66
|
+
if time.is_a?( String )
|
67
|
+
@reported_at = time
|
68
|
+
elsif time.is_a?( Time )
|
69
|
+
@reported_at = time.strftime( TIME_FORMATTER )
|
70
|
+
else
|
71
|
+
@reported_at = nil
|
162
72
|
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Log payload. See Hoodoo::Logger.
|
76
|
+
#
|
77
|
+
attr_accessor :data
|
163
78
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
79
|
+
# Optional calling Caller ID, via session data inside the payload - see
|
80
|
+
# Hoodoo::Logger.
|
81
|
+
#
|
82
|
+
attr_accessor :caller_id
|
83
|
+
|
84
|
+
# Optional interaction UUID, via session data inside the payload - see
|
85
|
+
# Hoodoo::Logger.
|
86
|
+
#
|
87
|
+
attr_accessor :interaction_id
|
88
|
+
|
89
|
+
# Optional hash of identity properties from the session data inside the
|
90
|
+
# payload - see Hoodoo::Logger.
|
91
|
+
#
|
92
|
+
attr_accessor :identity
|
93
|
+
|
94
|
+
# Create an instance with options keyed on the attributes defined for
|
95
|
+
# the class. Option keys may be Strings or Symbols but must only match
|
96
|
+
# defined attribute names.
|
97
|
+
#
|
98
|
+
def initialize( options = {} )
|
99
|
+
options.each do | name, value |
|
100
|
+
send( "#{ name }=", value )
|
179
101
|
end
|
180
102
|
end
|
181
103
|
|
182
|
-
|
104
|
+
# Retrieve a simple Hash representation of this instance.
|
105
|
+
#
|
106
|
+
def to_h
|
107
|
+
{
|
108
|
+
'id' => @id,
|
109
|
+
'level' => @level,
|
110
|
+
'component' => @component,
|
111
|
+
'code' => @code,
|
112
|
+
'reported_at' => @reported_at,
|
113
|
+
|
114
|
+
'data' => @data,
|
115
|
+
|
116
|
+
'interaction_id' => @interaction_id,
|
117
|
+
'caller_id' => @caller_id,
|
118
|
+
'identity' => Hoodoo::Utilities.stringify( @identity )
|
119
|
+
}
|
120
|
+
end
|
183
121
|
end
|
184
122
|
|
185
123
|
end
|