hoodoo 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|