gorg_service 5.3.1 → 6.0.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 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