bmc-daemon-lib 0.3.12 → 0.3.14

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: 0a8fc6e53d26c10707cdbc0a2475481e13905d12
4
- data.tar.gz: 3fa1c0534f69a402c9373b02e638e47dd6f5f487
3
+ metadata.gz: fef18aedd6818e48a75388b4846eed1888c99798
4
+ data.tar.gz: 6a9cc6898093c487798628a1bb2e2c5af6657d24
5
5
  SHA512:
6
- metadata.gz: 2b1200bb25c93bf91d67b9ed69623cc85e65836bd69cbf2b45f5efd6f1211e6833e0f6563efbe8d2a0a0bb3ff6c41f7c8eee3c95a4bead0feb79e7a76fa0affe
7
- data.tar.gz: 28521bb664156224158ff44630091ff9757d6f2334123ee106e037a1cdea496f5a28cd28096b7071916fcfc973076824b9364cf074c4bb2f0aea35e36d3a0c8c
6
+ metadata.gz: 646b6fe2be7e4716b3e50cd5b9307ba769105b949f65a0727c82c3d29053998002ee56d80d01f4fb84abaf36a8d93d69d69116a169ecc57739388c5e4d24916a
7
+ data.tar.gz: 7f8b49162ab83e593fe0b7a3b7572c71128591d48fca1af62666a7a60f7185faa30c53fc51a0fb670a197e2095d454669ee25544e9b92342e0bd2634f54f992d
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.2
1
+ 2.3.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bmc-daemon-lib (0.3.12)
4
+ bmc-daemon-lib (0.3.14)
5
5
  chamber (~> 2.9)
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  Gem::Specification.new do |spec|
3
3
  # Project version
4
- spec.version = "0.3.12"
4
+ spec.version = "0.3.14"
5
5
 
6
6
  # Project description
7
7
  spec.name = "bmc-daemon-lib"
@@ -10,4 +10,5 @@ require_relative "bmc-daemon-lib/logger_formatter"
10
10
  require_relative "bmc-daemon-lib/logger_helper"
11
11
  require_relative "bmc-daemon-lib/logger_pool"
12
12
  require_relative "bmc-daemon-lib/worker_base"
13
+ require_relative "bmc-daemon-lib/mq_endpoint"
13
14
  require_relative "bmc-daemon-lib/mq_consumer"
@@ -6,47 +6,24 @@ module BmcDaemonLib
6
6
  protected
7
7
 
8
8
  def log_info message, details = nil
9
- build_messages Logger::INFO, message, details
9
+ log Logger::INFO, message, details
10
10
  end
11
11
 
12
12
  def log_error message, details = nil
13
- build_messages Logger::ERROR, message, details
13
+ log Logger::ERROR, message, details
14
14
  end
15
15
 
16
16
  def log_debug message, details = nil
17
- build_messages Logger::DEBUG, message, details
17
+ log Logger::DEBUG, message, details
18
18
  end
19
19
 
20
20
  alias info log_info
21
21
  alias error log_error
22
22
  alias debug log_debug
23
23
 
24
- private
24
+ def log severity, message, details = nil
25
+ fail "LoggerHelper.log: invalid logger" unless logger.respond_to? :add
25
26
 
26
- # Builds prefix if LOG_PREFIX_FORMAT defined and caller has log_prefix method to provide values
27
- def build_prefix
28
- # Skip if no format defined
29
- return unless defined?('LOG_PREFIX_FORMAT')
30
- return unless LOG_PREFIX_FORMAT.is_a? String
31
-
32
- # Skip if no values from user class
33
- return unless respond_to?(:log_prefix, true)
34
- values = log_prefix
35
-
36
- # Change to an array if not already
37
- values = [values] if values.is_a? String
38
-
39
- # Stop if still not an array
40
- return unless values.is_a? Array
41
-
42
- # Finally format the string
43
- return LOG_PREFIX_FORMAT % values.map(&:to_s)
44
-
45
- rescue ArgumentError
46
- return "INVALID_FORMAT"
47
- end
48
-
49
- def build_messages severity, message, details = nil
50
27
  messages = []
51
28
 
52
29
  prefix = build_prefix
@@ -68,5 +45,34 @@ module BmcDaemonLib
68
45
  logger.add severity, messages
69
46
  end
70
47
 
48
+ private
49
+
50
+ # Builds prefix if LOG_PREFIX_FORMAT defined and caller has log_prefix method to provide values
51
+ def build_prefix
52
+ # Skip if no format defined
53
+ return unless defined?('LOG_PREFIX_FORMAT')
54
+ return unless LOG_PREFIX_FORMAT.is_a? String
55
+
56
+ # At start, values is an empty array
57
+ values = nil
58
+
59
+ # Call the instance's method
60
+ if respond_to?(:log_prefix, true)
61
+ values = log_prefix
62
+ end
63
+
64
+ # Change to an array if a simple string
65
+ values = [values] if values.is_a? String
66
+
67
+ # Ensure we always have an array (method not found, or log_prefix returning something else)
68
+ values = [] unless values.is_a? Array
69
+
70
+ # Finally format the string
71
+ return LOG_PREFIX_FORMAT % values.map(&:to_s)
72
+
73
+ rescue ArgumentError => ex
74
+ return "(LOG_PREFIX_FORMAT has an invalid format)"
75
+ end
76
+
71
77
  end
72
78
  end
@@ -1,92 +1,65 @@
1
1
  module BmcDaemonLib
2
- # class ShouterResponseError < StandardError; end
3
- # class ShouterChannelClosed < StandardError; end
4
- # class ShouterPreconditionFailed < StandardError; end
5
- # class ShouterInterrupted < StandardError; end
6
- # class EndpointTopicContext < StandardError; end
7
- class EndpointConnexionContext < StandardError; end
8
- class EndpointConnectionError < StandardError; end
9
- class EndpointSubscribeContext < StandardError; end
10
- class EndpointSubscribeError < StandardError; end
11
-
12
- class MqConsumer
13
- include LoggerHelper
14
- attr_reader :logger
2
+ class MqConsumerError < StandardError; end
15
3
 
16
- protected
4
+ class MqConsumer < MqEndpoint
17
5
 
18
- def log_prefix
19
- self.class.name.split('::').last
20
- end
6
+ include LoggerHelper
7
+ attr_reader :logger
21
8
 
22
- def subscribe_on_queue name
23
- info "use_queue [#{name}]"
9
+ def subscribe_to_queue name, context = nil
10
+ log_info "subscribe_to_queue [#{name}]"
24
11
 
25
12
  # Queue for this rule
26
13
  @queue = @channel.queue(name, auto_delete: false, durable: true)
27
14
 
28
15
  # Create consumer on this queue
29
16
  @queue.subscribe(manual_ack: AMQP_MANUAL_ACK, on_cancellation: :consumer_cancelled) do |delivery_info, metadata, payload|
30
- # Prepare data
31
- msg_exchange = delivery_info.exchange
32
- msg_rkey = delivery_info.routing_key.force_encoding('UTF-8')
33
- msg_tag = delivery_info.delivery_tag
17
+ handle_receive context, delivery_info, metadata, payload
18
+ end
19
+ end
34
20
 
35
- msg_headers = metadata.headers || {}
21
+ def listen_to topic, rkey
22
+ # Exchange to this rule
23
+ exchange = @channel.topic(topic, durable: true, persistent: false)
36
24
 
37
- # Extract payload
38
- msg_data = payload_parse payload, metadata.content_type
25
+ log_info "listen_to [#{topic}] [#{rkey}] > [#{@queue.name}]"
26
+ @queue.bind exchange, routing_key: rkey
27
+ end
39
28
 
40
- # Announce
41
- announce msg_rkey, msg_tag, msg_data, metadata, msg_exchange, payload.bytesize
29
+ protected
42
30
 
43
- # Hand to the callback
44
- receive msg_rkey, msg_tag, msg_data, metadata, delivery_info
45
- end
46
- end
31
+ def handle_receive context, delivery_info, metadata, payload
32
+ # raise MqConsumerError, "testing!"
47
33
 
48
- def announce msg_rkey, msg_tag, msg_data, metadata, msg_exchange, payload_bytesize
49
34
  # Prepare data
35
+ msg_topic = delivery_info.exchange
36
+ msg_rkey = delivery_info.routing_key.force_encoding('UTF-8')
37
+ msg_tag = delivery_info.delivery_tag
50
38
  msg_headers = metadata.headers || {}
51
39
 
40
+ # Extract payload
41
+ msg_data = payload_parse payload, metadata.content_type
42
+
52
43
  # Announce match
53
- log_message MSG_RECV, msg_exchange, msg_rkey, msg_data, {
54
- 'channel.dtag' => "#{@channel.id}.#{msg_tag}",
55
- 'app-id' => metadata.app_id,
56
- 'content-type' => metadata.content_type,
57
- 'delay (ms)' => extract_delay(msg_headers),
58
- 'body size' => format_bytes(payload_bytesize, "B"),
44
+ payload_bytesize = payload.bytesize
45
+ log_message MSG_RECV, msg_topic, msg_rkey, msg_data, {
46
+ app_id: metadata.app_id,
47
+ channel_tag: "#{@channel.id}.#{msg_tag}",
48
+ content_type: metadata.content_type,
49
+ delay_ms: extract_delay(msg_headers),
50
+ body_size: format_bytes(payload_bytesize, "B"),
59
51
  }
60
- end
61
-
62
- def bind_on topic, route
63
- # Exchange to this rule
64
- exchange = @channel.topic(topic, durable: true, persistent: false)
65
52
 
66
- info "bind_on [#{topic}] [#{route}] > [#{@queue.name}]"
67
- @queue.bind exchange, routing_key: route
53
+ # Hand to the callback
54
+ handle_message context, metadata, delivery_info,
55
+ topic: msg_topic,
56
+ rkey: msg_rkey,
57
+ tag: msg_tag,
58
+ data: msg_data
68
59
  end
69
60
 
70
61
  def consumer_cancelled all={}
71
- error "consumer cancelled remotely: #{all.inspect}"
72
- end
73
-
74
- def identifier len
75
- rand(36**len).to_s(36)
76
- end
77
-
78
- def log_message msg_way, msg_exchange, msg_key, msg_body = [], msg_attrs = {}
79
- # Message header
80
- info sprintf("%3s %-15s %s", msg_way, msg_exchange, msg_key)
81
-
82
- # Body lines
83
- if msg_body.is_a?(Enumerable) && !msg_body.empty?
84
- body_json = JSON.pretty_generate(msg_body)
85
- log_debug nil, body_json.lines
86
- end
87
-
88
- # Attributes lines
89
- log_debug nil, msg_attrs if msg_attrs
62
+ log_error "consumer_cancelled remotely: #{all.inspect}"
90
63
  end
91
64
 
92
65
  def extract_delay msg_headers
@@ -101,19 +74,8 @@ module BmcDaemonLib
101
74
  return ((Time.now - sent_at)*1000).round(2)
102
75
  end
103
76
 
104
- def format_bytes number, unit="", decimals = 0
105
- return "&Oslash;" if number.nil? || number.to_f.zero?
106
-
107
- units = ["", "k", "M", "G", "T", "P" ]
108
- index = ( Math.log(number) / Math.log(2) ).to_i / 10
109
- converted = number.to_f / (1024 ** index)
110
-
111
- truncated = converted.round(decimals)
112
- return "#{truncated} #{units[index]}#{unit}"
113
- end
114
-
115
- def receive delivery_info, metadata, payload
116
- debug "MqConsumer.receive"
77
+ def handle_message context, metadata, delivery_info, message = {}
78
+ log_error "MqConsumer.handle_message [#{context.to_s}] #{message.inspect}"
117
79
  end
118
80
 
119
81
  def payload_parse payload, content_type #, fields = []
@@ -0,0 +1,78 @@
1
+ module BmcDaemonLib
2
+ # class ShouterResponseError < StandardError; end
3
+ # class ShouterChannelClosed < StandardError; end
4
+ # class ShouterPreconditionFailed < StandardError; end
5
+ # class ShouterInterrupted < StandardError; end
6
+ # class EndpointTopicContext < StandardError; end
7
+ class EndpointConnexionContext < StandardError; end
8
+ class EndpointConnectionError < StandardError; end
9
+ class EndpointSubscribeContext < StandardError; end
10
+ class EndpointSubscribeError < StandardError; end
11
+
12
+ class MqEndpoint
13
+ include LoggerHelper
14
+ attr_reader :logger
15
+
16
+ protected
17
+
18
+ def log_prefix
19
+ self.class.name.split('::').last
20
+ end
21
+
22
+ def log_message msg_way, msg_topic, msg_key, msg_body = [], msg_attrs = {}
23
+ # Message header
24
+ log_info sprintf("%4s %-20s %s", msg_way, msg_topic, msg_key)
25
+
26
+ # Message attributes
27
+ log_debug nil, msg_attrs if msg_attrs
28
+
29
+ # Body lines
30
+ if msg_body.is_a?(Enumerable) && !msg_body.empty?
31
+ body_json = JSON.pretty_generate(msg_body)
32
+ log_debug nil, body_json.lines
33
+ end
34
+ end
35
+
36
+ def identifier len
37
+ rand(36**len).to_s(36)
38
+ end
39
+
40
+ def format_bytes number, unit="", decimals = 0
41
+ return "&Oslash;" if number.nil? || number.to_f.zero?
42
+
43
+ units = ["", "k", "M", "G", "T", "P" ]
44
+ index = ( Math.log(number) / Math.log(2) ).to_i / 10
45
+ converted = number.to_f / (1024 ** index)
46
+
47
+ truncated = converted.round(decimals)
48
+ return "#{truncated} #{units[index]}#{unit}"
49
+ end
50
+
51
+ # Start connexion to RabbitMQ
52
+ def connect_to busconf
53
+ fail BmcDaemonLib::EndpointConnexionContext, "connect_to/busconf" unless busconf
54
+ log_info "connecting to bus", {
55
+ broker: busconf,
56
+ recover: AMQP_RECOVERY_INTERVAL,
57
+ heartbeat: AMQP_HEARTBEAT_INTERVAL,
58
+ prefetch: AMQP_PREFETCH
59
+ }
60
+ conn = Bunny.new busconf.to_s,
61
+ logger: @logger,
62
+ # heartbeat: :server,
63
+ automatically_recover: true,
64
+ network_recovery_interval: AMQP_RECOVERY_INTERVAL,
65
+ heartbeat_interval: AMQP_HEARTBEAT_INTERVAL,
66
+ read_write_timeout: AMQP_HEARTBEAT_INTERVAL*2
67
+ conn.start
68
+
69
+ rescue Bunny::TCPConnectionFailedForAllHosts, Bunny::AuthenticationFailureError, AMQ::Protocol::EmptyResponseError => e
70
+ fail BmcDaemonLib::EndpointConnectionError, "error connecting (#{e.class})"
71
+ rescue StandardError => e
72
+ fail BmcDaemonLib::EndpointConnectionError, "unknow (#{e.inspect})"
73
+ else
74
+ return conn
75
+ end
76
+
77
+ end
78
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bmc-daemon-lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.12
4
+ version: 0.3.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno MEDICI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-09 00:00:00.000000000 Z
11
+ date: 2016-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,6 +100,7 @@ files:
100
100
  - lib/bmc-daemon-lib/logger_helper.rb
101
101
  - lib/bmc-daemon-lib/logger_pool.rb
102
102
  - lib/bmc-daemon-lib/mq_consumer.rb
103
+ - lib/bmc-daemon-lib/mq_endpoint.rb
103
104
  - lib/bmc-daemon-lib/worker_base.rb
104
105
  homepage: http://github.com/bmedici/bmc-daemon-lib
105
106
  licenses:
@@ -121,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
122
  version: '0'
122
123
  requirements: []
123
124
  rubyforge_project:
124
- rubygems_version: 2.4.5
125
+ rubygems_version: 2.6.6
125
126
  signing_key:
126
127
  specification_version: 4
127
128
  summary: 'Shared utilities to build a daemon: logger, configuration, helpers'