gorg_service 5.3.1 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a69896ea2caff03c8164b627c8d30879bd97f6e
4
- data.tar.gz: e2ae0468acf11367a5de67703597c84e3867b208
3
+ metadata.gz: 4176b3c8a8689ae7474eaa5420f3b45c96fbc916
4
+ data.tar.gz: 0b48b75295d30fbeeabd9245cf22e9d97174a02f
5
5
  SHA512:
6
- metadata.gz: 13d927a1f0079447ec7be9ea188c5dd8808de5d6bd20ad5b1fee2df8bfabfe4cf59caed6b67c71376353545d1b93343fe9286f8de757317a0c6daf606669ab9c
7
- data.tar.gz: df30302c0ff854aa61eef2b395e66e290c78cd6699dca0a85dde5cbd9a65fbe70eaf8e50d148c16b7c65614b7fd34a09cad0bef8f4298a21273b5ed7555d87bd
6
+ metadata.gz: 8fe317544a9bf0a1cb7b5583f0489ba734ff982f9d1142527bfc69147d2779ecde58224720138d816fa8eb4e1fce948f78f89d9672765ee67feb36d880bc0b7d
7
+ data.tar.gz: cec6262709a87326414100b87707f89382f9344be4345c7147bb8403a1040d5b9d9e7ad3615daac78a812026ccf09d4443ae168d9588df792dcf5efcdd721828
@@ -32,8 +32,10 @@ Gem::Specification.new do |spec|
32
32
 
33
33
  spec.add_development_dependency "bundler", "~> 1.11"
34
34
  spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "yard", "~> 0.8.7"
35
36
  spec.add_development_dependency "rspec", "~> 3.0"
36
- spec.add_development_dependency "codeclimate-test-reporter", "~> 0.5.0"
37
+ spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0"
38
+ spec.add_development_dependency "simplecov", "~> 0.13"
37
39
  spec.add_development_dependency 'bogus', '~> 0.1.6'
38
40
  spec.add_development_dependency 'byebug', '~> 9.0'
39
41
  end
@@ -6,10 +6,14 @@ class GorgService
6
6
  #Common behavior of failling errors
7
7
  class FailError < StandardError
8
8
  attr_reader :error_raised
9
+ attr_reader :error_name
10
+ attr_accessor :gorg_service_message
9
11
 
10
- def initialize(message = nil, error_raised = nil)
12
+ def initialize(message = nil, error_raised = nil, gorg_service_message: nil, error_name: nil)
11
13
  @message = message
12
14
  @error_raised = error_raised
15
+ @gorg_service_message = gorg_service_message
16
+ @error_name = error_name
13
17
  end
14
18
 
15
19
  def message
@@ -19,19 +23,41 @@ class GorgService
19
23
  def type
20
24
  ""
21
25
  end
26
+
27
+ def to_log_message
28
+ @gorg_service_message.log_message(
29
+ level: self.log_level,
30
+ error_type: self.type,
31
+ error_name: @error_name
32
+ )
33
+ end
22
34
  end
23
35
 
24
36
  #Softfail error : This message should be processed again later
25
37
  class SoftfailError < FailError
26
38
  def type
27
- "softerror"
39
+ "softfail"
40
+ end
41
+
42
+ def log_level
43
+ 3
44
+ end
45
+
46
+ def to_log_message
47
+ r=super
48
+ r.next_try_in=GorgService.configuration.rabbitmq_deferred_time.to_i
49
+ r
28
50
  end
29
51
  end
30
52
 
31
53
  #Hardfail error : This message is not processable and will never be
32
54
  class HardfailError < FailError
33
55
  def type
34
- "harderror"
56
+ "hardfail"
57
+ end
58
+
59
+ def log_level
60
+ 4
35
61
  end
36
62
  end
37
63
  end
@@ -64,35 +64,38 @@ class GorgService
64
64
  end
65
65
 
66
66
  def process_softfail(e, message)
67
- message.log_error(e)
67
+ e.gorg_service_message ||= message
68
68
  GorgService.logger.error "SOFTFAIL ERROR : #{e.message}"
69
- if message.errors.count.to_i >= @max_attempts
70
- GorgService.logger.info " DISCARD MESSAGE : #{message.errors.count} errors in message log"
71
- process_hardfail(HardfailError.new("Too Much SoftError : This message reached the limit of softerror (max: #{@max_attempts})"), message)
69
+ process_logging(e)
70
+ message.softfail_count+=1
71
+ if message.softfail_count.to_i >= @max_attempts
72
+ GorgService.logger.info " DISCARD MESSAGE : too much soft errors (#{message.softfail_count})"
73
+ process_hardfail(HardfailError.new("Too Much SoftError : This message reached the limit of softerror (max: #{@max_attempts})", gorg_service_message: message, error_name: e.error_name), message)
72
74
  else
73
75
  send_to_deferred_queue(message)
74
76
  end
75
77
  end
76
78
 
77
79
  def process_hardfail(e, message)
80
+ e.gorg_service_message ||= message
78
81
  GorgService.logger.error "HARDFAIL ERROR : #{e.message}, #{e.error_raised&&e.error_raised.inspect}"
79
82
  GorgService.logger.info " DISCARD MESSAGE"
80
- if message
81
- message.log_error(e)
82
- process_logging(message)
83
- end
83
+ process_logging(e)
84
84
  end
85
85
 
86
- def process_logging(message)
86
+ def process_logging(error)
87
+ message=error.to_log_message
87
88
  message.routing_key=@log_routing_key
88
89
  GorgService::Producer.new.publish_message(message)
89
- #RabbitmqProducer.new.send_raw(message.to_json, @log_routing_key, verbose: true) if @log_routing_key
90
90
  end
91
91
 
92
- def send_to_deferred_queue(msg)
93
- if @env.delayed_queue_for msg.event
94
- @env.delayed_in_exchange.publish(msg.to_json, :routing_key => msg.event)
95
- GorgService.logger.info "DEFER MESSAGE : message sent to #{@env.delayed_in_exchange.name} with routing key #{msg.event}"
92
+ def send_to_deferred_queue(message)
93
+
94
+ if @env.delayed_queue_for message.routing_key
95
+ GorgService::Producer.new.publish_message(message, exchange: @env.delayed_in_exchange)
96
+ #
97
+ # @env.delayed_in_exchange.publish(msg.to_json, :routing_key => msg.routing_key)
98
+ GorgService.logger.info "DEFER MESSAGE : message sent to #{@env.delayed_in_exchange.name} with routing key #{message.routing_key}"
96
99
  else
97
100
  raise "DelayedQueueNotFound"
98
101
  end
@@ -32,28 +32,29 @@ class GorgService
32
32
  end
33
33
  alias_method :msg, :message
34
34
 
35
- def reply_with(data)
36
- self.class.reply_to(message, data)
35
+ def reply_with(*_args, **keyword_args)
36
+ self.class.reply_to(message,**keyword_args)
37
37
  end
38
38
 
39
- def raise_hardfail(error_message, error: nil, data: nil)
40
- self.class.raise_hardfail(error_message, error: error, message:message, data:data)
39
+ def raise_hardfail(*args, **keyword_args)
40
+ self.class.raise_hardfail(*args, **(keyword_args.merge(message:message)))
41
41
  end
42
42
 
43
- def raise_softfail(error_message, error: nil, data: nil)
44
- self.class.raise_softfail(error_message, error: error, message:message, data:data)
43
+ def raise_softfail(*args, **keyword_args)
44
+ self.class.raise_softfail(*args, **(keyword_args.merge(message:message)))
45
45
  end
46
46
 
47
47
  class << self
48
48
 
49
- def reply_to(message,data)
49
+ def reply_to(message, data: {}, status_code: 200, error_type: nil, error_name: nil, next_try_in: nil)
50
50
  if message.expect_reply?
51
51
 
52
- reply=GorgService::Message.new(
53
- event: message.reply_routing_key,
52
+ reply=message.reply_message(
54
53
  data: data,
55
- correlation_id: message.id,
56
- type: "reply"
54
+ status_code: status_code,
55
+ error_type: error_type,
56
+ error_name: error_name,
57
+ next_try_in: next_try_in,
57
58
  )
58
59
 
59
60
  replier=GorgService::Producer.new
@@ -61,28 +62,38 @@ class GorgService
61
62
  end
62
63
  end
63
64
 
64
- def raise_hardfail(error_message,message:nil, error: nil, data: nil)
65
+ def raise_hardfail(error_message,message:nil, error: nil, data: nil, status_code: 500, error_name: nil)
65
66
  if message
66
67
  reply_to(message,{
67
- status: 'hardfail',
68
- error_message: error_message,
69
- debug_message: error&&error.inspect,
70
- error_data: data
68
+ error_type: 'hardfail',
69
+ status_code: status_code,
70
+ error_name: error_name,
71
+ data:{
72
+ error_message: error_message,
73
+ debug_message: error&&error.inspect,
74
+ error_data: data
75
+ },
76
+
71
77
  })
72
78
  end
73
- raise HardfailError.new(error_message, error)
79
+ raise HardfailError.new(error_message, error, gorg_service_message: message, error_name: error_name)
74
80
  end
75
81
 
76
- def raise_softfail(error_message,message:nil, error: nil, data: nil)
82
+ def raise_softfail(error_message,message:nil, error: nil, data: nil, status_code: 500, error_name: nil)
77
83
  if message
78
84
  reply_to(message,{
79
- status: 'softfail',
80
- error_message: error_message,
81
- debug_message: error&&error.inspect,
82
- error_data: data
85
+ error_type: 'softfail',
86
+ next_try_in: GorgService.configuration.rabbitmq_deferred_time.to_i,
87
+ status_code: status_code,
88
+ error_name: error_name,
89
+ data:{
90
+ error_message: error_message,
91
+ debug_message: error&&error.inspect,
92
+ error_data: data
93
+ },
83
94
  })
84
95
  end
85
- raise SoftfailError.new(error_message, error)
96
+ raise SoftfailError.new(error_message, error, gorg_service_message: message, error_name: error_name)
86
97
  end
87
98
 
88
99
  def handle_error(*errorClasses,&block)
@@ -0,0 +1,13 @@
1
+ class GorgService
2
+ class EventMessage<Message
3
+
4
+ def type
5
+ "event"
6
+ end
7
+
8
+ def validate
9
+ super
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ class GorgService
2
+ class LogMessage<Message
3
+ # @return [String] Level of the log
4
+ # 0 => DEBUG
5
+ # 1 => INFO
6
+ # 2 => WARNING
7
+ # 3 => SOFTFAIL
8
+ # 4 => HARDFAIL
9
+ attr_accessor :level
10
+
11
+ # @return [String] Error type ('hardfail','softfail')
12
+ attr_accessor :error_type
13
+
14
+ # @return [Integer] Time until next attempts in milliseconds
15
+ attr_accessor :next_try_in
16
+
17
+ # @return [String] Name identifying the error
18
+ attr_accessor :error_name
19
+
20
+ def type
21
+ "log"
22
+ end
23
+
24
+ # @param opts [Hash] Attributes of the message
25
+ # @option opts [String] :level See {#level}. Default : 1
26
+ # @option opts [String] :error_type See {#error_type}. Default : nil
27
+ # @option opts [Integer] :next_try_in See {#next_try_in}. Default : nil
28
+ # @option opts [String] :error_name See {#error_name}. Default : nil
29
+ # @see GorgService::Message#initialize
30
+ def initialize(opts={})
31
+ super
32
+ self.level= opts.fetch(:level,1)
33
+ self.error_type= opts.fetch(:error_type,nil)
34
+ self.next_try_in= opts.fetch(:next_try_in,nil)
35
+ self.error_name= opts.fetch(:error_name,nil)
36
+ end
37
+
38
+ def validate
39
+ self.validation_errors[:level]+=["is null"] unless self.level
40
+ self.validation_errors[:level]+=["is not in [0,1,2,3,4]"] unless (0..4).to_a.include?(self.level)
41
+ self.validation_errors[:error_type]+=["is not in (softfail hardfail)"] unless self.error_type && (%w(softfail hardfail).include? self.error_type)
42
+ super
43
+ end
44
+
45
+ end
46
+ end
@@ -8,11 +8,26 @@ require 'securerandom'
8
8
  require "gorg_service/message/json_schema"
9
9
  require "gorg_service/message/error_log"
10
10
 
11
+ require "gorg_service/reply_message"
12
+ require "gorg_service/event_message"
13
+ require "gorg_service/log_message"
14
+ require "gorg_service/request_message"
15
+
16
+ require "gorg_service/message/formatters"
17
+
18
+
19
+
20
+ # Message transferred through Bunny. Follow Gorg SOA specification v2.0 ans maintain support for v1.0
21
+ #
22
+ # @author Alexandre Narbonne
11
23
  class GorgService
12
24
  class Message
13
25
 
26
+ DEFAULT_SOA_VERSION="1.0"
27
+
14
28
  class DataValidationError < StandardError
15
29
 
30
+ # @return [Hash] Mapping of invalid data
16
31
  attr_reader :errors
17
32
 
18
33
  def initialize(errors)
@@ -20,81 +35,165 @@ class GorgService
20
35
  end
21
36
  end
22
37
 
38
+ class MessageValidationError < StandardError
39
+
40
+ # @return [Hash] Mapping of invalid data
41
+ attr_reader :errors
42
+
43
+ def initialize(errors)
44
+ @errors=errors
45
+ end
46
+ end
47
+
48
+ # @return [String] UUID of the message
23
49
  attr_accessor :id
24
- attr_accessor :reply_to
25
- attr_accessor :correlation_id
50
+
51
+ # @return [String] Id of the app which generated the message
26
52
  attr_accessor :sender_id
53
+ alias_method :sender, :sender_id
54
+ alias_method :sender=, :sender_id=
55
+
56
+ # @return [String] Content type of the payload
57
+ # @note The only content type officially supported by Gadz.org SOA is 'application/json'
27
58
  attr_accessor :content_type
59
+
60
+ # @return [String] Content encoding of the payload
61
+ # @note The only content encoding officially supported by Gadz.org SOA is 'deflate'
28
62
  attr_accessor :content_encoding
29
- attr_accessor :headers
30
- attr_accessor :type
31
63
 
32
- attr_accessor :event_id
64
+ # @return [String] The Gadz.org SOA specs version used to generate this message
65
+ # @note Incomming message without this information should be considered v1.0
66
+ attr_accessor :soa_version
67
+
68
+ # @return [String] Major version of the soa version
69
+ def soa_version_major
70
+ (self.soa_version||DEFAULT_SOA_VERSION).split('.')[0]
71
+ end
72
+
73
+ # @return [String] identifier of the library used to generate this message, for debug and compatibility purpose
74
+ attr_accessor :client_library
75
+
76
+ # @return [String] Identifier of the admin who triggered the generation of this message
77
+ # @note In case of autonomous actions, there is no admin_id
78
+ attr_accessor :admin_id
79
+
80
+ # @return [String] Routing of the message
33
81
  attr_accessor :routing_key
34
- attr_accessor :event
82
+
83
+ # @return [Hash] Data of the payload as an hash
84
+ # @note for further compatibility, don't assume that data is an hash but check Content-Type
35
85
  attr_accessor :data
36
- attr_accessor :errors
86
+
87
+ # @return [DateTime] Message generation datetime
37
88
  attr_accessor :creation_time
38
- attr_accessor :sender
39
89
 
90
+ # @return [String] Name of the exchange used to receive reply
91
+ attr_accessor :reply_to
92
+ alias_method :reply_exchange, :reply_to
93
+
94
+ # @return [String] UUID of the message the this message refer to (reply or log)
95
+ attr_accessor :correlation_id
96
+
97
+ # @return [nil] Type of message (event,log,request,reply). To be overwritten by children classes
98
+ def type
99
+ nil
100
+ end
101
+
102
+ # @return [Hash] Additional headers
103
+ attr_accessor :headers
104
+
105
+ # @return [Integer] Number of softfails associated to this message
106
+ attr_accessor :softfail_count
107
+
108
+ # @deprecated In Gadz.org Soa v2.0 errors are not store in messages anymore
109
+ # @return [Array<Message::ErrorLog>] List of errors associated to this message
110
+ attr_accessor :errors
111
+
112
+ # @return [Hash] Mapping of attributes errors in regard of Gadz.org SOA v2
113
+ attr_accessor :validation_errors
114
+ def validation_errors
115
+ @validation_errors||= Hash.new([].freeze)
116
+ end
117
+
118
+ # @deprecated Use {#routing_key} instead. event is no longer a part of GorgSOA specs
119
+ # @return [String] the name of the event
120
+ attr_accessor :event
121
+ def event
122
+ warn "[DEPRECATION] Message.event is deprecated and will be removed soon. Use id instead (called from #{caller_locations(1,1)[0]})"
123
+ self.routing_key
124
+ end
125
+ def event=(value)
126
+ warn "[DEPRECATION] Message.event is deprecated and will be removed soon. Use id instead (called from #{caller_locations(1,1)[0]})"
127
+ self.routing_key=value
128
+ end
129
+
130
+
131
+
132
+ # @deprecated Use {#id} instead. event_id is no longer a part of GorgSOA specs
133
+ # @return [String] UUID of the message
134
+ attr_accessor :event_id
135
+ def event_id
136
+ warn "[DEPRECATION] Message.event_id is deprecated and will be removed soon. Use id instead (called from #{caller_locations(1,1)[0]})"
137
+ self.id
138
+ end
139
+ def event_id=(value)
140
+ warn "[DEPRECATION] Message.event_id is deprecated and will be removed soon. Use id instead (called from #{caller_locations(1,1)[0]})"
141
+ self.id=value
142
+ end
143
+
144
+ # @deprecated In Gadz.org Soa v2.0 errors are not store in messages anymore
145
+ # @return [Array<Message::ErrorLog>] List of errors associated to this message
40
146
  def errors
41
147
  @errors||=[]
42
148
  end
43
149
 
44
-
150
+ # @param opts [Hash] Attributes of the message
151
+ # @option opts [String] :id See {#id}. Default : Random UUID4
152
+ # @option opts [Array<Message::ErrorLog>] :errors See {#errors}. Default : []
153
+ # @option opts [DateTime] :creation_time See {#creation_time}. Default : DateTime.now
154
+ # @option opts [String] :sender See {#sender}. Default : GorgService.configuration.application_id
155
+ # @option opts [String] :data See {#data}. Default : nil
156
+ # @option opts [String] :routing_key See {#routing_key}. Default : nil
157
+ # @option opts [String] :reply_to See {#reply_to}. Default : nil
158
+ # @option opts [String] :correlation_id See {#correlation_id}. Default : nil
159
+ # @option opts [String] :content_type See {#content_type}. Default : "application/json"
160
+ # @option opts [String] :content_encoding See {#content_encoding}. Default : "deflate"
161
+ # @option opts [String] :headers See {#headers}. Default : {}
45
162
  def initialize(opts={})
46
- ##Message payload params
47
- @event_id= opts.fetch(:event_id,generate_id)
48
- @errors= opts.fetch(:errors,nil)
49
- @creation_time= opts.fetch(:creation_time,DateTime.now.iso8601)
50
- @sender= opts.fetch(:sender,application_id)
51
- @event= opts.fetch(:event,nil)
52
- @data= opts.fetch(:data,nil)
53
-
54
- #Message Attributes params
55
- @routing_key= opts.fetch(:routing_key,event)
56
- @id= opts.fetch(:id,generate_id)
57
- @reply_to= opts.fetch(:reply_to,nil)
58
- @correlation_id= opts.fetch(:correlation_id,nil)
59
- @sender_id= opts.fetch(:sender_id,application_id)
60
- @content_type= opts.fetch(:content_type,"application/json")
61
- @content_encoding= opts.fetch(:content_encoding,"deflate")
62
- @headers= opts.fetch(:headers,{})
63
- @type= opts.fetch(:type,"event")
163
+ self.id= opts.fetch(:event_id,nil)||opts.fetch(:id,generate_id)
164
+
165
+ self.errors= opts.fetch(:errors,[])
166
+ self.creation_time= opts.fetch(:creation_time,DateTime.now)
167
+ self.sender= opts.fetch(:sender,application_id)
168
+ self.data= opts.fetch(:data,nil)
169
+ self.routing_key= opts.fetch(:routing_key,nil)||opts.fetch(:event,nil)
170
+ self.softfail_count= opts.fetch(:softfail_count,0)
171
+
172
+ self.reply_to= opts.fetch(:reply_to,nil)
173
+ self.correlation_id= opts.fetch(:correlation_id,nil)
174
+ self.content_type= opts.fetch(:content_type,"application/json")
175
+ self.content_encoding= opts.fetch(:content_encoding,"deflate")
176
+ self.headers= opts.fetch(:headers,{})
177
+ self.soa_version= opts.fetch(:soa_version, DEFAULT_SOA_VERSION)
64
178
  end
65
179
 
180
+ # @deprecated Please use directly the rendering interface of the formatter
181
+ # @param formatter [Message::FormatterV1] The formatter to be used. Default : an instance of Message::FormatterV1
182
+ # @return [Hash] The un-serialized payload of the RabbitMq message
66
183
  def body
67
- _body={
68
- event_uuid: @event_id,
69
- event_name: @event,
70
- event_sender_id: @sender,
71
- event_creation_time: @creation_time,
72
- data: @data,
73
- }
74
- if errors.any?
75
- _body[:errors_count]=@errors.count
76
- _body[:errors]=@errors.map{|e| e.to_h}
77
- end
78
- _body
184
+ Message::Formatter.formatter_for_version(self.soa_version).new(self).body
79
185
  end
80
186
  alias_method :to_h, :body
81
187
  alias_method :payload, :body
82
188
 
83
- def properties
84
- {
85
- routing_key: routing_key,
86
- reply_to: reply_to,
87
- correlation_id: correlation_id,
88
- content_type: content_type,
89
- content_encoding: content_encoding,
90
- headers: headers,
91
- app_id: sender_id,
92
- type: type,
93
- message_id: id,
94
- }
95
- end
96
-
97
- # Generate RabbitMQ message body
189
+ # @deprecated Please use directly the rendering interface of the formatter
190
+ # @param formatter [Message::FormatterV1] The formatter to be used. Default : an instance of Message::FormatterV1
191
+ # @return [Hash] The properties of the RabbitMq message
192
+ def properties(formatter: Message::FormatterV1.new(self))
193
+ Message::Formatter.formatter_for_version(self.soa_version).new(self).properties
194
+ end
195
+
196
+ # @return [String] The serialized (JSON) value of the RabbitMQ payload
98
197
  def to_json
99
198
  self.to_h.to_json
100
199
  end
@@ -109,22 +208,76 @@ class GorgService
109
208
  errors<<e
110
209
  end
111
210
 
112
- def reply_exchange
113
- reply_to
114
- end
115
-
211
+ # @return [Boolean] Does this message expect a reply ?
116
212
  def expect_reply?
117
213
  !!reply_to
118
214
  end
119
215
 
216
+ # @return [Stirng] Routing key to use to reply to this message
120
217
  def reply_routing_key
121
- event.sub('request','reply')
218
+ routing_key.sub('request','reply')
219
+ end
220
+
221
+ # @return [GorgService::ReplyMessage] the response to send
222
+
223
+ def reply_message(opts)
224
+ args= {
225
+ routing_key: self.reply_routing_key,
226
+ correlation_id: self.id,
227
+ soa_version: self.soa_version
228
+ }.merge(opts)
229
+
230
+ GorgService::ReplyMessage.new(args)
231
+ end
232
+
233
+ def log_message(opts)
234
+ args= {
235
+ routing_key: self.reply_routing_key,
236
+ correlation_id: self.id,
237
+ soa_version: '2.0' #v1 messages generate v2 logs
238
+ }.merge(opts)
239
+
240
+ GorgService::LogMessage.new(args)
122
241
  end
123
242
 
243
+ # Validate the message against rules specified in {https://confluence.gadz.org/display/INFRA/Messages the Gadz.org SOA Message Specification}
244
+ def validate
245
+ self.validation_errors= Hash.new([].freeze)
246
+
247
+ self.validation_errors[:content_type]+=["is not supported by Gadz.org SOA"] unless ['application/json'].include? self.content_type
248
+ self.validation_errors[:content_encoding]+=["is not supported by Gadz.org SOA"] unless ['deflate','gzip'].include? self.content_encoding
249
+ # "gzip" is not officially supported by Gadz.org but I don't feel comfortable blocking it :)
250
+
251
+ self.validation_errors[:id]+=["is null"] unless self.id
252
+ self.validation_errors[:id]+=["is not a UUID"] unless !self.id || /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/.match(self.id)
253
+
254
+ self.validation_errors[:correlation_id]+=["is not a UUID"] unless !self.correlation_id || /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/.match()
255
+
256
+ self.validation_errors[:creation_time]+=["is not DateTime"] unless self.creation_time.is_a? DateTime
257
+
258
+ self.validation_errors[:type]+=["is not in (event, log, request, reply)"] unless %w(event log request reply).include? self.type
259
+
260
+ self.validation_errors[:sender]+=["is null"] unless self.sender
261
+
262
+ self.validation_errors[:soa_version]+=["is null"] unless self.soa_version
263
+
264
+ return self.validation_errors.empty?
265
+ end
266
+ alias_method :valid?, :validate
267
+
268
+ # @see #validate
269
+ # @raise [MessageValidationError] Raise an exception containing the errors if the message is invalid
270
+ def validate!
271
+ raise MessageValidationError.new(self.errors) unless validate
272
+ end
273
+
274
+ # @param [String,Hash] A JSON Schema usable by {JSON::Validator}
275
+ # @return [Boolean] True if the message is valid against the provided JSON Schema
276
+ # @raise [DataValidationError] Validation exception containing errors ( See {DataValidationError#errors})
124
277
  def validate_data_with(schema)
125
- errors=JSON::Validator.fully_validate(schema, self.data)
126
- if errors.any?
127
- raise DataValidationError.new(errors)
278
+ data_validation_errors=JSON::Validator.fully_validate(schema, self.data)
279
+ if data_validation_errors.any?
280
+ raise DataValidationError.new(data_validation_errors)
128
281
  else
129
282
  return true
130
283
  end
@@ -134,54 +287,17 @@ class GorgService
134
287
 
135
288
  ### Class methods
136
289
 
290
+ # @param [Hash] delivery_info delivery_info provided by {Bunny}
291
+ # @param [Hash] properties properties provided by {Bunny}
292
+ # @param [Hash] body body provided by {Bunny}
293
+ # @param [Class] formatter_class The formatter to be used to parse the message. Default to {Message::FormatterV1}
294
+ # @return [GorgService::Message] A kind of GorgService::Message
137
295
  def self.parse(delivery_info, properties, body)
138
- begin
139
- json_body=JSON.parse(body)
140
-
141
- JSON::Validator.validate!(GorgService::Message::JSON_SCHEMA,json_body)
142
-
143
- msg=self.new(
144
- routing_key: delivery_info[:routing_key],
145
- id: properties[:message_id],
146
- reply_to: properties[:reply_to],
147
- correlation_id: properties[:correlation_id],
148
- sender_id: properties[:app_id],
149
- content_type: properties[:content_type],
150
- content_encoding: properties[:content_encoding],
151
- headers: properties[:header],
152
- type: properties[:type],
153
-
154
- event_id: json_body["event_uuid"],
155
- event: json_body["event_name"],
156
- data: convert_keys_to_sym(json_body["data"]),
157
- creation_time: json_body["event_creation_time"] && DateTime.parse(json_body["event_creation_time"]),
158
- sender: json_body["event_sender_id"],
159
- errors: json_body["errors"]&&json_body["errors"].map{|e| GorgService::Message::ErrorLog.parse(e)},
160
- )
161
- msg
162
- rescue JSON::ParserError => e
163
- raise GorgService::Consumer::HardfailError.new("Unprocessable message : Unable to parse JSON message body", e)
164
- rescue JSON::Schema::ValidationError => e
165
- raise GorgService::Consumer::HardfailError.new("Invalid JSON : This message does not respect Gadz.org JSON Schema",e)
166
- end
296
+ formatter_class=Message::Formatter.formatter_for_version(properties.to_h[:headers].to_h["soa-version"]||"1")
297
+ formatter_class.parse(delivery_info, properties, body)
167
298
  end
168
299
 
169
-
170
- def self.convert_keys_to_sym input_hash
171
- s2s =
172
- lambda do |h|
173
- Hash === h ?
174
- Hash[
175
- h.map do |k, v|
176
- [k.respond_to?(:to_sym) ? k.to_sym : k, s2s[v]]
177
- end
178
- ] : h
179
- end
180
- s2s[input_hash]
181
- end
182
-
183
- private
184
-
300
+ protected
185
301
  # Generate new id
186
302
  def generate_id
187
303
  SecureRandom.uuid()
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ class GorgService::Message
5
+ class Formatter
6
+
7
+ def initialize(message)
8
+ @message=message
9
+ end
10
+
11
+ def message
12
+ @message
13
+ end
14
+
15
+ def self.formatter_for_version(version)
16
+ major_version=version.split('.')[0]
17
+ case major_version
18
+ when '1'
19
+ FormatterV1
20
+ when '2'
21
+ FormatterV2
22
+ else
23
+ raise "Unknown Gorg SOA version"
24
+ end
25
+ end
26
+
27
+ def self.convert_keys_to_sym input_hash
28
+ s2s =
29
+ lambda do |h|
30
+ Hash === h ?
31
+ Hash[
32
+ h.map do |k, v|
33
+ [k.respond_to?(:to_sym) ? k.to_sym : k, s2s[v]]
34
+ end
35
+ ] : h
36
+ end
37
+ s2s[input_hash]
38
+ end
39
+
40
+ end
41
+
42
+ class FormatterV1 < Formatter
43
+
44
+ JSON_SCHEMA_V1 = JSON.parse('{
45
+ "$schema": "http://json-schema.org/draft-04/schema#",
46
+ "type": "object",
47
+ "properties": {
48
+ "event_name": {
49
+ "type": "string",
50
+ "pattern": "^[_a-z]+((\\.)?[_a-z]+)*$",
51
+ "description": "Event type. Must match the routing key"
52
+ },
53
+ "event_uuid": {
54
+ "type": "string",
55
+ "description": "The unique identifier of this message as UUID",
56
+ "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"
57
+ },
58
+ "event_creation_time": {
59
+ "type": "string",
60
+ "description": "Creation time in UTC ISO 8601 format",
61
+ "pattern": "^([\\\+-]?\\\d{4}(?!\\\d{2}\\\b))((-?)((0[1-9]|1[0-2])(\\\3([12]\\\d|0[1-9]|3[01]))?|W([0-4]\\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\\d|[12]\\\d{2}|3([0-5]\\\d|6[1-6])))([T\\\s]((([01]\\\d|2[0-3])((:?)[0-5]\\\d)?|24\\\:?00)([\\\.,]\\\d+(?!:))?)?(\\\17[0-5]\\\d([\\\.,]\\\d+)?)?([zZ]|([\\\+-])([01]\\\d|2[0-3]):?([0-5]\\\d)?)?)?)?$"
62
+ },
63
+ "event_sender_id": {
64
+ "type": "string",
65
+ "description": "Producer that sent the original message"
66
+ },
67
+ "data": {
68
+ "type": "object",
69
+ "description": "Data used to process this message"
70
+ },
71
+ "errors_count": {
72
+ "type": "integer",
73
+ "description": "Helper for counting errors"
74
+ },
75
+ "errors": {
76
+ "type": "array",
77
+ "items": {
78
+ "type": "object",
79
+ "properties": {
80
+ "error_type": {
81
+ "enum": [ "debug", "info", "warning", "softerror", "harderror" ],
82
+ "description": "Type of error."
83
+ },
84
+ "error_sender": {
85
+ "type": "string",
86
+ "description": "Consummer that sent this error"
87
+ },
88
+ "error_code":{
89
+ "type":"string",
90
+ "description": "Optionnal error code from the consummer"
91
+ },
92
+ "error_uuid":{
93
+ "type":"string",
94
+ "description": "The unique identifier of this error as UUID",
95
+ "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"
96
+ },
97
+ "error_message":{
98
+ "type":"string",
99
+ "description": "Error explanation"
100
+ },
101
+ "timestamp": {
102
+ "type": "string",
103
+ "description": "Time of occuring error in UTC ISO 8601",
104
+ "pattern": "^([\\\+-]?\\\d{4}(?!\\\d{2}\\\b))((-?)((0[1-9]|1[0-2])(\\\3([12]\\\d|0[1-9]|3[01]))?|W([0-4]\\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\\d|[12]\\\d{2}|3([0-5]\\\d|6[1-6])))([T\\\s]((([01]\\\d|2[0-3])((:?)[0-5]\\\d)?|24\\\:?00)([\\\.,]\\\d+(?!:))?)?(\\\17[0-5]\\\d([\\\.,]\\\d+)?)?([zZ]|([\\\+-])([01]\\\d|2[0-3]):?([0-5]\\\d)?)?)?)?$"
105
+ },
106
+ "error_debug": {
107
+ "type": "object",
108
+ "description": "Complementary informations for debugging"
109
+ }
110
+ },
111
+ "additionalProperties": false,
112
+ "required": [
113
+ "error_type",
114
+ "error_sender",
115
+ "timestamp",
116
+ "error_uuid",
117
+ "error_message"
118
+ ]
119
+ }
120
+ }
121
+ },
122
+ "additionalProperties": false,
123
+ "required": [
124
+ "event_name",
125
+ "event_uuid",
126
+ "event_creation_time",
127
+ "event_sender_id",
128
+ "data"
129
+ ]
130
+ }')
131
+
132
+ DEFAULT_HEADERS={
133
+ "soa-version" => "1.0",
134
+ "client-library" => "GorgService #{GorgService::VERSION}",
135
+ }
136
+
137
+ def properties
138
+ {
139
+ routing_key: message.routing_key,
140
+ reply_to: message.reply_to,
141
+ correlation_id: message.correlation_id,
142
+ content_type: message.content_type,
143
+ content_encoding: message.content_encoding,
144
+ headers: DEFAULT_HEADERS.merge(message.headers.to_h).merge(
145
+ 'softfail-count' => message.softfail_count,
146
+ ),
147
+ app_id: message.sender_id,
148
+ type: message.type,
149
+ message_id: message.id,
150
+ }
151
+ end
152
+
153
+ def body
154
+ b={
155
+ event_uuid: message.id,
156
+ event_name: message.routing_key,
157
+ event_sender_id: message.sender,
158
+ event_creation_time: message.creation_time.iso8601,
159
+ data: message.data,
160
+ }
161
+ if message.errors.any?
162
+ b[:errors_count]=message.errors.count
163
+ b[:errors]=message.errors.map{|e| e.to_h}
164
+ end
165
+ b
166
+ end
167
+
168
+ def payload
169
+ body.to_json
170
+ end
171
+
172
+ def self.parse(delivery_info, properties, body)
173
+ begin
174
+ json_body=JSON.parse(body)
175
+ JSON::Validator.validate!(JSON_SCHEMA_V1, json_body)
176
+
177
+ msg=GorgService::Message.new(
178
+ routing_key: delivery_info[:routing_key],
179
+ reply_to: properties[:reply_to],
180
+ correlation_id: properties[:correlation_id],
181
+ sender_id: properties[:app_id],
182
+ content_type: properties[:content_type],
183
+ content_encoding: properties[:content_encoding],
184
+ headers: properties[:headers],
185
+ type: properties[:type],
186
+
187
+ softfail_count: properties[:headers].to_h.delete('softfail-count'),
188
+
189
+ id: json_body["event_uuid"],
190
+ event_id: json_body["event_uuid"],
191
+ event: json_body["event_name"],
192
+ data: convert_keys_to_sym(json_body["data"]),
193
+ creation_time: json_body["event_creation_time"] && DateTime.parse(json_body["event_creation_time"]),
194
+ sender: json_body["event_sender_id"],
195
+ errors: json_body["errors"]&&json_body["errors"].map{|e| GorgService::Message::ErrorLog.parse(e)},
196
+ )
197
+ msg
198
+ rescue JSON::ParserError => e
199
+ raise GorgService::Consumer::HardfailError.new("Unprocessable message : Unable to parse JSON message body", e)
200
+ rescue JSON::Schema::ValidationError => e
201
+ raise GorgService::Consumer::HardfailError.new("Invalid JSON : This message does not respect Gadz.org JSON Schema",e,{})
202
+ end
203
+ end
204
+ end
205
+
206
+
207
+ class FormatterV2 < Formatter
208
+
209
+ DEFAULT_HEADERS={
210
+ "soa-version" => "2.0",
211
+ "client-library" => "GorgService #{GorgService::VERSION}",
212
+ }
213
+
214
+ EXTRA_HEADERS_FOR ={
215
+ GorgService::ReplyMessage => {
216
+ 'status-code' => :status_code,
217
+ 'error-type' => :error_type,
218
+ 'next-try-in' => :next_try_in,
219
+ 'error-name' => :error_name,
220
+ },
221
+ GorgService::LogMessage => {
222
+ 'level' => :level,
223
+ 'error-type' => :error_type,
224
+ 'next-try-in' => :next_try_in,
225
+ 'error-name' => :error_name,
226
+ },
227
+
228
+ }
229
+
230
+ def properties
231
+
232
+ headers=DEFAULT_HEADERS.merge(message.headers.to_h).merge(
233
+ 'softfail-count' => message.softfail_count,
234
+ )
235
+
236
+ extra_headers=EXTRA_HEADERS_FOR[message.class].to_h.map do|key,method_name|
237
+ [key,message.public_send(method_name)]
238
+ end.to_h
239
+
240
+
241
+ headers.merge!(extra_headers)
242
+
243
+ {
244
+ routing_key: message.routing_key,
245
+ reply_to: message.reply_to,
246
+ correlation_id: message.correlation_id,
247
+ content_type: message.content_type,
248
+ content_encoding: message.content_encoding,
249
+ headers: headers,
250
+ app_id: message.sender_id,
251
+ type: message.type,
252
+ message_id: message.id,
253
+ }
254
+ end
255
+
256
+ def body
257
+ message.data
258
+ end
259
+
260
+ def payload
261
+ body.to_json
262
+ end
263
+
264
+ def self.parse(delivery_info, properties, body)
265
+ begin
266
+
267
+ type=properties[:type]
268
+ unless type
269
+ type=delivery_info[:routing_key].split('.').first
270
+ end
271
+
272
+ type_map={event: GorgService::EventMessage, request: GorgService::RequestMessage, reply: GorgService::ReplyMessage, log: GorgService::LogMessage}
273
+ klass=type_map[type.to_s.to_sym]
274
+
275
+ raise "Unknown type" unless klass
276
+
277
+ headers=properties[:headers]||{}
278
+
279
+ args={
280
+ data: convert_keys_to_sym(JSON.parse(body)),
281
+ id:properties[:message_id],
282
+
283
+ creation_time: properties[:timestamp] && DateTime.parse(properties[:timestamp]),
284
+ sender:properties[:app_id],
285
+ routing_key: delivery_info[:routing_key],
286
+
287
+ reply_to: properties[:reply_to],
288
+ correlation_id: properties[:correlation_id],
289
+ content_type: properties[:content_type],
290
+ content_encoding:properties[:content_encoding],
291
+ soa_version: headers.delete('soa-version'),
292
+
293
+ softfail_count: headers.delete('softfail-count'),
294
+
295
+ headers: headers,
296
+ }
297
+
298
+ extra_args=EXTRA_HEADERS_FOR[klass].to_h.map do |key,method_name|
299
+ [method_name,headers.delete(key)]
300
+ end.to_h
301
+
302
+ args.merge!(extra_args)
303
+
304
+ klass.new(args)
305
+ rescue JSON::ParserError => e
306
+ raise GorgService::Consumer::HardfailError.new("Unprocessable message : Unable to parse JSON message body", e)
307
+ rescue JSON::Schema::ValidationError => e
308
+ raise GorgService::Consumer::HardfailError.new("Invalid JSON : This message does not respect Gadz.org JSON Schema",e)
309
+ end
310
+ end
311
+
312
+ end
313
+ end
@@ -6,93 +6,7 @@ require 'json'
6
6
  class GorgService
7
7
  class Message
8
8
 
9
- JSON_SCHEMA = JSON.parse('{
10
- "$schema": "http://json-schema.org/draft-04/schema#",
11
- "type": "object",
12
- "properties": {
13
- "event_name": {
14
- "type": "string",
15
- "pattern": "^[_a-z]+((\\.)?[_a-z]+)*$",
16
- "description": "Event type. Must match the routing key"
17
- },
18
- "event_uuid": {
19
- "type": "string",
20
- "description": "The unique identifier of this message as UUID",
21
- "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"
22
- },
23
- "event_creation_time": {
24
- "type": "string",
25
- "description": "Creation time in UTC ISO 8601 format",
26
- "pattern": "^([\\\+-]?\\\d{4}(?!\\\d{2}\\\b))((-?)((0[1-9]|1[0-2])(\\\3([12]\\\d|0[1-9]|3[01]))?|W([0-4]\\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\\d|[12]\\\d{2}|3([0-5]\\\d|6[1-6])))([T\\\s]((([01]\\\d|2[0-3])((:?)[0-5]\\\d)?|24\\\:?00)([\\\.,]\\\d+(?!:))?)?(\\\17[0-5]\\\d([\\\.,]\\\d+)?)?([zZ]|([\\\+-])([01]\\\d|2[0-3]):?([0-5]\\\d)?)?)?)?$"
27
- },
28
- "event_sender_id": {
29
- "type": "string",
30
- "description": "Producer that sent the original message"
31
- },
32
- "data": {
33
- "type": "object",
34
- "description": "Data used to process this message"
35
- },
36
- "errors_count": {
37
- "type": "integer",
38
- "description": "Helper for counting errors"
39
- },
40
- "errors": {
41
- "type": "array",
42
- "items": {
43
- "type": "object",
44
- "properties": {
45
- "error_type": {
46
- "enum": [ "debug", "info", "warning", "softerror", "harderror" ],
47
- "description": "Type of error."
48
- },
49
- "error_sender": {
50
- "type": "string",
51
- "description": "Consummer that sent this error"
52
- },
53
- "error_code":{
54
- "type":"string",
55
- "description": "Optionnal error code from the consummer"
56
- },
57
- "error_uuid":{
58
- "type":"string",
59
- "description": "The unique identifier of this error as UUID",
60
- "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"
61
- },
62
- "error_message":{
63
- "type":"string",
64
- "description": "Error explanation"
65
- },
66
- "timestamp": {
67
- "type": "string",
68
- "description": "Time of occuring error in UTC ISO 8601",
69
- "pattern": "^([\\\+-]?\\\d{4}(?!\\\d{2}\\\b))((-?)((0[1-9]|1[0-2])(\\\3([12]\\\d|0[1-9]|3[01]))?|W([0-4]\\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\\d|[12]\\\d{2}|3([0-5]\\\d|6[1-6])))([T\\\s]((([01]\\\d|2[0-3])((:?)[0-5]\\\d)?|24\\\:?00)([\\\.,]\\\d+(?!:))?)?(\\\17[0-5]\\\d([\\\.,]\\\d+)?)?([zZ]|([\\\+-])([01]\\\d|2[0-3]):?([0-5]\\\d)?)?)?)?$"
70
- },
71
- "error_debug": {
72
- "type": "object",
73
- "description": "Complementary informations for debugging"
74
- }
75
- },
76
- "additionalProperties": false,
77
- "required": [
78
- "error_type",
79
- "error_sender",
80
- "timestamp",
81
- "error_uuid",
82
- "error_message"
83
- ]
84
- }
85
- }
86
- },
87
- "additionalProperties": false,
88
- "required": [
89
- "event_name",
90
- "event_uuid",
91
- "event_creation_time",
92
- "event_sender_id",
93
- "data"
94
- ]
95
- }')
9
+
96
10
 
97
11
  end
98
12
  end
@@ -0,0 +1,41 @@
1
+ class GorgService
2
+ class ReplyMessage<Message
3
+
4
+ # @return [String] Error code, HTTP like
5
+ attr_accessor :status_code
6
+
7
+ # @return [String] Error type ('hardfail','softfail')
8
+ attr_accessor :error_type
9
+
10
+ # @return [Integer] Time until next attempts in milliseconds
11
+ attr_accessor :next_try_in
12
+
13
+ # @return [String] Name identifying the error
14
+ attr_accessor :error_name
15
+
16
+ def type
17
+ "reply"
18
+ end
19
+
20
+ # @param opts [Hash] Attributes of the message
21
+ # @option opts [String] :status_code See {#status_code}. Default : nil
22
+ # @option opts [String] :error_type See {#error_type}. Default : nil
23
+ # @option opts [Integer] :next_try_in See {#next_try_in}. Default : nil
24
+ # @option opts [String] :error_name See {#error_name}. Default : nil
25
+ # @see GorgService::Message#initialize
26
+ def initialize(opts={})
27
+ super
28
+ self.status_code= opts.fetch(:status_code,nil)
29
+ self.error_type= opts.fetch(:error_type,nil)
30
+ self.next_try_in= opts.fetch(:next_try_in,nil)
31
+ self.error_name= opts.fetch(:error_name,nil)
32
+ end
33
+
34
+ def validate
35
+ self.validation_errors[:status_code]+=["is null"] unless self.status_code
36
+ self.validation_errors[:error_type]+=["is not in (softfail hardfail)"] unless self.error_type && (%w(softfail hardfail).include? self.error_type)
37
+ super
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,13 @@
1
+ class GorgService
2
+ class RequestMessage<Message
3
+
4
+ def type
5
+ "request"
6
+ end
7
+
8
+ def validate
9
+ super
10
+ end
11
+
12
+ end
13
+ end
@@ -9,15 +9,15 @@ class LogMessageHandler < GorgService::Consumer::MessageHandler::Base
9
9
  end
10
10
 
11
11
  def self.has_received_error?(type)
12
- messages.any?{|m| m.errors.any?{|x| x.type==type}}
12
+ messages.any?{|m| m.errors.any?{|x| x.type==type}} || messages.any?{|m| m.type=='log'&&m.error_type=type}
13
13
  end
14
14
 
15
15
  def self.has_received_hardfail?
16
- self.has_received_error?("harderror")
16
+ self.has_received_error?("hardfail")
17
17
  end
18
18
 
19
- def self.has_received_hardfail?
20
- self.has_received_error?("softerror")
19
+ def self.has_received_softfail?
20
+ self.has_received_error?("softfail")
21
21
  end
22
22
 
23
23
  def self.has_received_a_message_with_routing_key?(routing_key)
@@ -2,5 +2,5 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  class GorgService
5
- VERSION = "5.3.1"
5
+ VERSION = "6.0.0"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gorg_service
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.1
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre Narbonne
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-18 00:00:00.000000000 Z
11
+ date: 2017-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -86,6 +86,20 @@ dependencies:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
88
  version: '10.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: yard
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.8.7
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 0.8.7
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: rspec
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -106,14 +120,28 @@ dependencies:
106
120
  requirements:
107
121
  - - "~>"
108
122
  - !ruby/object:Gem::Version
109
- version: 0.5.0
123
+ version: '1.0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '1.0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: simplecov
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '0.13'
110
138
  type: :development
111
139
  prerelease: false
112
140
  version_requirements: !ruby/object:Gem::Requirement
113
141
  requirements:
114
142
  - - "~>"
115
143
  - !ruby/object:Gem::Version
116
- version: 0.5.0
144
+ version: '0.13'
117
145
  - !ruby/object:Gem::Dependency
118
146
  name: bogus
119
147
  requirement: !ruby/object:Gem::Requirement
@@ -173,11 +201,16 @@ files:
173
201
  - lib/gorg_service/consumer/message_handler/reply_handler.rb
174
202
  - lib/gorg_service/consumer/message_handler/request_handler.rb
175
203
  - lib/gorg_service/consumer/message_router.rb
204
+ - lib/gorg_service/event_message.rb
205
+ - lib/gorg_service/log_message.rb
176
206
  - lib/gorg_service/message.rb
177
207
  - lib/gorg_service/message/error_log.rb
208
+ - lib/gorg_service/message/formatters.rb
178
209
  - lib/gorg_service/message/json_schema.rb
179
210
  - lib/gorg_service/producer.rb
180
211
  - lib/gorg_service/rabbitmq_env_builder.rb
212
+ - lib/gorg_service/reply_message.rb
213
+ - lib/gorg_service/request_message.rb
181
214
  - lib/gorg_service/rspec/bunny_cleaner.rb
182
215
  - lib/gorg_service/rspec/log_message_handler.rb
183
216
  - lib/gorg_service/version.rb