gorg_service 1.1.0 → 1.2.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 +4 -4
- data/Gemfile +1 -3
- data/README.md +6 -2
- data/gorg_service.gemspec +2 -3
- data/lib/gorg_service.rb +23 -1
- data/lib/gorg_service/configuration.rb +3 -1
- data/lib/gorg_service/listener.rb +51 -33
- data/lib/gorg_service/message.rb +7 -3
- data/lib/gorg_service/version.rb +1 -1
- metadata +18 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73ff949459f530d6de5e500a065a69082b633c13
|
4
|
+
data.tar.gz: f33f7599bf4a38afd2c3c3070757109c45e69f61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d857d88511bd782177f455248b3ce26d9847916250b8f29658c7e678344fbbabc015570d54e4f5d54e8b461aa706c46578eebb42b696f7bfec9e3891d218255
|
7
|
+
data.tar.gz: bcfb9af25144da6982cabc973c5d1ffb9c70502987bc6faeb7263ce8ad7f9d04fb5e9f946285f98a0e2363d17e8e9876a1d0bcc972bd99aac988f276072676b2
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# GorgService
|
2
2
|
[](https://codeclimate.com/github/Zooip/gorg_service) [](https://codeclimate.com/github/Zooip/gorg_service/coverage) [](https://travis-ci.org/Zooip/gorg_service) [](https://badge.fury.io/rb/gorg_service) [](https://gemnasium.com/github.com/Zooip/gorg_service)
|
3
|
+
|
3
4
|
Standard RabbitMQ bot used in Gadz.org SOA
|
4
5
|
|
5
6
|
## Installation
|
@@ -52,6 +53,10 @@ GorgService.configure do |c|
|
|
52
53
|
# maximum number of try before discard a message
|
53
54
|
# c.rabbitmq_max_attempts = 48 # 24h with default deferring delay
|
54
55
|
#
|
56
|
+
# The routing key used when sending a message to the central log system (Hardfail or Warning)
|
57
|
+
# Central logging is disable if nil
|
58
|
+
# c.log_routing_key = nil
|
59
|
+
#
|
55
60
|
# Routing hash
|
56
61
|
# map routing_key of received message with MessageHandler
|
57
62
|
# exemple:
|
@@ -76,8 +81,7 @@ my_service.run
|
|
76
81
|
When running, GorgService act as a consumer on Gadz.org RabbitMQ network.
|
77
82
|
It bind its queue on the main exchange and subscribes to routing keys defines in `message_handler_map`
|
78
83
|
|
79
|
-
Each received message will be routed to the corresponding `MessageHandler
|
80
|
-
> **Warning** : RabbitMQ wildcards characters `#` and `*`are NOT supported for now
|
84
|
+
Each received message will be routed to the corresponding `MessageHandler`. AMQP wildcards are supported.The first key to match the incomiing routing key will be used.
|
81
85
|
|
82
86
|
A `MessageHandler` is a kind of controller. This is where you put the message is processed.
|
83
87
|
A `MessageHandler` expect a `GorgService::Message` as param of its `initializer`method.
|
data/gorg_service.gemspec
CHANGED
@@ -28,12 +28,11 @@ Gem::Specification.new do |spec|
|
|
28
28
|
|
29
29
|
spec.add_dependency 'bunny', '~> 2.2', '>= 2.2.2'
|
30
30
|
spec.add_dependency 'json-schema', '~> 2.6'
|
31
|
+
spec.add_dependency 'gorg_message_sender', '~> 0'
|
31
32
|
|
32
33
|
spec.add_development_dependency "bundler", "~> 1.11"
|
33
34
|
spec.add_development_dependency "rake", "~> 10.0"
|
34
35
|
spec.add_development_dependency "rspec", "~> 3.0"
|
35
|
-
spec.add_development_dependency "codeclimate-test-reporter", "~>
|
36
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.5.0"
|
36
37
|
spec.add_development_dependency 'bogus', '~> 0.1.6'
|
37
|
-
spec.add_development_dependency 'bunny-mock', '~> 1.4'
|
38
|
-
spec.add_development_dependency 'byebug', '~> 9.0'
|
39
38
|
end
|
data/lib/gorg_service.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "gorg_message_sender"
|
1
2
|
require "gorg_service/configuration"
|
2
3
|
require "gorg_service/version"
|
3
4
|
require "gorg_service/errors"
|
@@ -5,9 +6,12 @@ require "gorg_service/listener"
|
|
5
6
|
require "gorg_service/message"
|
6
7
|
require "gorg_service/message_handler"
|
7
8
|
|
9
|
+
#Duplicate GorgMessageSender to avoid configuration conflict
|
10
|
+
RabbitmqProducer=GorgMessageSender.dup
|
11
|
+
|
8
12
|
class GorgService
|
9
13
|
def initialize(listener: nil, bunny_session: nil)
|
10
|
-
|
14
|
+
|
11
15
|
@bunny_session= bunny_session || Bunny.new(
|
12
16
|
:hostname => GorgService.configuration.rabbitmq_host,
|
13
17
|
:port => GorgService.configuration.rabbitmq_port,
|
@@ -23,7 +27,25 @@ class GorgService
|
|
23
27
|
exchange_name: GorgService.configuration.rabbitmq_exchange_name,
|
24
28
|
deferred_time: GorgService.configuration.rabbitmq_deferred_time,
|
25
29
|
max_attempts: GorgService.configuration.rabbitmq_max_attempts,
|
30
|
+
log_routing_key: GorgService.configuration.log_routing_key
|
26
31
|
)
|
32
|
+
|
33
|
+
RabbitmqProducer.configure do |c|
|
34
|
+
# Id used to set the event_sender_id
|
35
|
+
c.application_id = GorgService.configuration.application_id
|
36
|
+
|
37
|
+
# RabbitMQ network and authentification
|
38
|
+
c.host = GorgService.configuration.rabbitmq_host
|
39
|
+
c.port = GorgService.configuration.rabbitmq_port
|
40
|
+
c.vhost = GorgService.configuration.rabbitmq_vhost
|
41
|
+
c.user = GorgService.configuration.rabbitmq_user
|
42
|
+
c.password = GorgService.configuration.rabbitmq_password
|
43
|
+
|
44
|
+
# Exchange configuration
|
45
|
+
c.exchange_name = GorgService.configuration.rabbitmq_exchange_name
|
46
|
+
c.durable_exchange= true
|
47
|
+
end
|
48
|
+
|
27
49
|
end
|
28
50
|
|
29
51
|
def run
|
@@ -27,7 +27,8 @@ class GorgService
|
|
27
27
|
:rabbitmq_user,
|
28
28
|
:rabbitmq_password,
|
29
29
|
:rabbitmq_vhost,
|
30
|
-
:message_handler_map
|
30
|
+
:message_handler_map,
|
31
|
+
:log_routing_key
|
31
32
|
|
32
33
|
|
33
34
|
def initialize
|
@@ -43,6 +44,7 @@ class GorgService
|
|
43
44
|
@rabbitmq_password = nil
|
44
45
|
@rabbitmq_vhost = "/"
|
45
46
|
@rabbitmq_max_attempts = 48 #24h with default timeout
|
47
|
+
@log_routing_key = nil
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|
@@ -6,75 +6,93 @@ require "bunny"
|
|
6
6
|
class GorgService
|
7
7
|
class Listener
|
8
8
|
|
9
|
-
def initialize(bunny_session: nil,queue_name: "gapps", exchange_name: nil, message_handler_map: {default: DefaultMessageHandler}, deferred_time: 1800000, max_attempts: 48)
|
9
|
+
def initialize(bunny_session: nil,queue_name: "gapps", exchange_name: nil, message_handler_map: {default: DefaultMessageHandler}, deferred_time: 1800000, max_attempts: 48,log_routing_key:nil)
|
10
10
|
@queue_name=queue_name
|
11
11
|
@exchange_name=exchange_name
|
12
12
|
@message_handler_map=message_handler_map
|
13
13
|
@deferred_time=deferred_time
|
14
14
|
@max_attempts=max_attempts
|
15
15
|
@rmq_connection=bunny_session
|
16
|
+
@log_routing_key=log_routing_key
|
16
17
|
end
|
17
18
|
|
18
19
|
def listen
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
q = ch.queue(@queue_name, :durable => true)
|
24
|
-
|
25
|
-
@message_handler_map.keys.each do |routing_key|
|
26
|
-
q.bind(@exchange_name, :routing_key => routing_key)
|
27
|
-
end
|
28
|
-
|
29
|
-
q.bind(@exchange_name, :routing_key => '#')
|
30
|
-
|
31
|
-
ch.prefetch(1)
|
32
|
-
|
33
|
-
q.subscribe(:manual_ack => true) do |delivery_info, properties, body|
|
21
|
+
set_rabbitmq_env
|
22
|
+
|
23
|
+
@q.subscribe(:manual_ack => true) do |delivery_info, _properties, body|
|
34
24
|
routing_key=delivery_info[:routing_key]
|
35
25
|
puts " [#] Received message with routing key #{routing_key} containing : #{body}"
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
call_message_handler(message_handler, message)
|
40
|
-
|
41
|
-
ch.ack(delivery_info.delivery_tag)
|
26
|
+
process_message(body,routing_key)
|
27
|
+
@ch.ack(delivery_info.delivery_tag)
|
42
28
|
end
|
43
|
-
|
44
29
|
end
|
45
30
|
|
31
|
+
protected
|
32
|
+
|
46
33
|
def rmq_connection
|
47
34
|
@rmq_connection.start unless @rmq_connection.connected?
|
48
35
|
@rmq_connection
|
49
36
|
end
|
50
37
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
38
|
+
def set_rabbitmq_env
|
39
|
+
conn = rmq_connection
|
40
|
+
@ch = conn.create_channel
|
41
|
+
@ch.prefetch(1)
|
42
|
+
@ch.topic(@exchange_name, :durable => true)
|
43
|
+
@q = @ch.queue(@queue_name, :durable => true)
|
55
44
|
|
45
|
+
@message_handler_map.keys.each do |routing_key|
|
46
|
+
@q.bind(@exchange_name, :routing_key => routing_key)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def process_message(body,routing_key)
|
51
|
+
message=nil
|
52
|
+
incomming_message_error_count=0
|
53
|
+
begin
|
54
|
+
message_handler=message_handler_for routing_key
|
55
|
+
raise HardfailError.new("Routing error : No message handler finded for this routing key") unless message_handler
|
56
|
+
|
57
|
+
begin
|
58
|
+
message=Message.parse_body(body)
|
59
|
+
rescue JSON::ParserError => e
|
60
|
+
raise HardfailError.new("JSON Parse error : Can't parse incoming message",e)
|
61
|
+
rescue JSON::Schema::ValidationError => e
|
62
|
+
raise HardfailError.new("Invalid JSON : This message does not respect Gadz.org JSON Schema",e)
|
63
|
+
end
|
64
|
+
incomming_message_error_count=message.errors.count
|
65
|
+
message_handler.new(message)
|
66
|
+
process_logging(message) if message.errors.count>incomming_message_error_count
|
56
67
|
rescue SoftfailError => e
|
57
|
-
message.log_error(e)
|
58
68
|
process_softfail(e,message)
|
59
|
-
|
60
69
|
rescue HardfailError => e
|
61
|
-
|
62
|
-
process_hardfail(e)
|
70
|
+
process_hardfail(e,message)
|
63
71
|
end
|
64
72
|
end
|
65
73
|
|
66
74
|
def process_softfail(e,message)
|
75
|
+
message.log_error(e)
|
67
76
|
puts " [*] SOFTFAIL ERROR : #{e.message}"
|
68
77
|
if message.errors.count >= @max_attempts
|
69
78
|
puts " [*] DISCARD MESSAGE : #{message.errors.count} errors in message log"
|
79
|
+
process_hardfail(HardfailError.new("Too Much SoftError : This message reached the limit of softerror (max: #{@max_attempts})"),message)
|
70
80
|
else
|
71
81
|
send_to_deferred_queue(message)
|
72
82
|
end
|
73
83
|
end
|
74
84
|
|
75
|
-
def process_hardfail(e)
|
76
|
-
puts " [*]
|
77
|
-
puts " [*] DISCARD MESSAGE"
|
85
|
+
def process_hardfail(e,message)
|
86
|
+
puts " [*] HARDFAIL ERROR : #{e.message}"
|
87
|
+
puts " [*] DISCARD MESSAGE"
|
88
|
+
if message
|
89
|
+
message.log_error(e)
|
90
|
+
process_logging(message)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def process_logging(message)
|
95
|
+
RabbitmqProducer.new.send_raw(message.to_json,@log_routing_key, verbose: true) if @log_routing_key
|
78
96
|
end
|
79
97
|
|
80
98
|
def send_to_deferred_queue(msg)
|
data/lib/gorg_service/message.rb
CHANGED
@@ -31,8 +31,7 @@ class GorgService
|
|
31
31
|
@sender= sender
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
def to_json
|
34
|
+
def to_h
|
36
35
|
body={
|
37
36
|
event_uuid: @id,
|
38
37
|
event_name: @event,
|
@@ -44,7 +43,12 @@ class GorgService
|
|
44
43
|
body[:errors_count]=@errors.count
|
45
44
|
body[:errors]=@errors
|
46
45
|
end
|
47
|
-
body
|
46
|
+
body
|
47
|
+
end
|
48
|
+
|
49
|
+
# Generate RabbitMQ message body
|
50
|
+
def to_json
|
51
|
+
self.to_h.to_json
|
48
52
|
end
|
49
53
|
|
50
54
|
# Log FailError in message body
|
data/lib/gorg_service/version.rb
CHANGED
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: 1.
|
4
|
+
version: 1.2.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: 2016-05-
|
11
|
+
date: 2016-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -44,6 +44,20 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '2.6'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: gorg_message_sender
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
62
|
name: bundler
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,14 +106,14 @@ dependencies:
|
|
92
106
|
requirements:
|
93
107
|
- - "~>"
|
94
108
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
109
|
+
version: 0.5.0
|
96
110
|
type: :development
|
97
111
|
prerelease: false
|
98
112
|
version_requirements: !ruby/object:Gem::Requirement
|
99
113
|
requirements:
|
100
114
|
- - "~>"
|
101
115
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
116
|
+
version: 0.5.0
|
103
117
|
- !ruby/object:Gem::Dependency
|
104
118
|
name: bogus
|
105
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,34 +128,6 @@ dependencies:
|
|
114
128
|
- - "~>"
|
115
129
|
- !ruby/object:Gem::Version
|
116
130
|
version: 0.1.6
|
117
|
-
- !ruby/object:Gem::Dependency
|
118
|
-
name: bunny-mock
|
119
|
-
requirement: !ruby/object:Gem::Requirement
|
120
|
-
requirements:
|
121
|
-
- - "~>"
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
version: '1.4'
|
124
|
-
type: :development
|
125
|
-
prerelease: false
|
126
|
-
version_requirements: !ruby/object:Gem::Requirement
|
127
|
-
requirements:
|
128
|
-
- - "~>"
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
version: '1.4'
|
131
|
-
- !ruby/object:Gem::Dependency
|
132
|
-
name: byebug
|
133
|
-
requirement: !ruby/object:Gem::Requirement
|
134
|
-
requirements:
|
135
|
-
- - "~>"
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
version: '9.0'
|
138
|
-
type: :development
|
139
|
-
prerelease: false
|
140
|
-
version_requirements: !ruby/object:Gem::Requirement
|
141
|
-
requirements:
|
142
|
-
- - "~>"
|
143
|
-
- !ruby/object:Gem::Version
|
144
|
-
version: '9.0'
|
145
131
|
description:
|
146
132
|
email:
|
147
133
|
- alexandre.narbonne@gadz.org
|