gorg_service 1.1.0 → 1.2.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: b61b732f42639dd14b22f68e32bf318e598c10f1
4
- data.tar.gz: 22e05f3bf14224e468001802a6a59fd28b40f9b9
3
+ metadata.gz: 73ff949459f530d6de5e500a065a69082b633c13
4
+ data.tar.gz: f33f7599bf4a38afd2c3c3070757109c45e69f61
5
5
  SHA512:
6
- metadata.gz: a407353c48c6c6ddacb7f8ea95c0bd65bf5b289cb95eb4820a1000ffdc6f8639456c1c63a1ce4221f88cd20f410c5b9fc42ab50e93f07d1fb3f0c7ea94604979
7
- data.tar.gz: 00b386980b7eb2e235218f890cbe7194eb9323996c99c6b06eeb5a074e5ade05c40f2d7924ae750da6594cc2cc02eb54ec5a76a59fdfcef8f3a7b7309ee788b1
6
+ metadata.gz: 1d857d88511bd782177f455248b3ce26d9847916250b8f29658c7e678344fbbabc015570d54e4f5d54e8b461aa706c46578eebb42b696f7bfec9e3891d218255
7
+ data.tar.gz: bcfb9af25144da6982cabc973c5d1ffb9c70502987bc6faeb7263ce8ad7f9d04fb5e9f946285f98a0e2363d17e8e9876a1d0bcc972bd99aac988f276072676b2
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gemspec
4
- gem "codeclimate-test-reporter", group: :test, require: nil
5
- gem 'reek', '~> 4.0'
3
+ gemspec
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # GorgService
2
2
  [![Code Climate](https://codeclimate.com/github/Zooip/gorg_service/badges/gpa.svg)](https://codeclimate.com/github/Zooip/gorg_service) [![Test Coverage](https://codeclimate.com/github/Zooip/gorg_service/badges/coverage.svg)](https://codeclimate.com/github/Zooip/gorg_service/coverage) [![Build Status](https://travis-ci.org/Zooip/gorg_service.svg?branch=master)](https://travis-ci.org/Zooip/gorg_service) [![Gem Version](https://badge.fury.io/rb/gorg_service.svg)](https://badge.fury.io/rb/gorg_service) [![Dependency Status](https://gemnasium.com/badges/github.com/Zooip/gorg_service.svg)](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", "~> 3.0"
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
- conn = rmq_connection
21
- ch = conn.create_channel
22
- x = ch.topic(@exchange_name, :durable => true)
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
- message_handler=message_handler_for routing_key
37
- message=Message.parse_body(body)
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 call_message_handler(message_handler, message)
52
- begin
53
- raise HardfailError.new(), "Routing error" unless message_handler
54
- message_handler.new(message)
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
- message.log_error(e)
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 " [*] SOFTFAIL ERROR : #{e.message}"
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)
@@ -31,8 +31,7 @@ class GorgService
31
31
  @sender= sender
32
32
  end
33
33
 
34
- # Generate RabbitMQ message body
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.to_json
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
@@ -2,5 +2,5 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  class GorgService
5
- VERSION = "1.1.0"
5
+ VERSION = "1.2.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: 1.1.0
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-30 00:00:00.000000000 Z
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: '3.0'
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: '3.0'
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