istox 0.1.103 → 0.1.104

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
  SHA256:
3
- metadata.gz: 2a4fdf1c4ef6e43e08853ee0921fe24c7a5055954f09e8994947d319f95e127f
4
- data.tar.gz: fb11c641a84a1f285ef85ea5ad532b3896d3db6971f65ce4c83ec0970c43ed9d
3
+ metadata.gz: 017e8b356e88bb9934ee5e01dce3ef6ce1ccdbf937bd5e8463ccd138c074ccee
4
+ data.tar.gz: 606737426dc9eaf9ca1b3d1f879b0dda17f46dacc89817cacf80990ce8a9fad2
5
5
  SHA512:
6
- metadata.gz: 4bec68b057c3f448e08f4958b7a51964cbda8b99a5689028107928e2b5a385914e78ff703d74ac43542e4f1c93b615be1c3a0a07a130c9fa4264df223be67fe9
7
- data.tar.gz: 9f5d910541029a58e96bb1ef1955671b0ba431bb68acdd59de4e8da7a957485a1e68ad92e79ef278f80dc13f640a9e5c81b148e2a62f4eec4e79ea29ca007b58
6
+ metadata.gz: 38bd1dcc56ce327d8c994f5743310cf3e34d3f70639513dcdfdcb0bd2a9b6a3c5cdef19e5b3b26c4ac43d8ee5742146cfb798b73be17fd4f9838bb14c7b5013c
7
+ data.tar.gz: d338cf9fe623a1a99481581c57142a5637899509f319407d489662ce8c511318d5a5747a8f091072f17a796bc51038382162278b89b5a72b0cd9c1a739e506e2
data/.rubocop.yml CHANGED
@@ -74,7 +74,7 @@ Metrics/ParameterLists:
74
74
  CountKeywordArgs: true
75
75
 
76
76
  Metrics/PerceivedComplexity:
77
- Max: 12
77
+ Max: 20
78
78
 
79
79
  Style/FrozenStringLiteralComment:
80
80
  Enabled: false
data/Gemfile.lock CHANGED
@@ -1,13 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- istox (0.1.102)
4
+ istox (0.1.103)
5
+ awesome_print
5
6
  binding_of_caller
6
7
  bunny (>= 2.12.0)
7
8
  graphlient
8
9
  gruf
9
10
  istox_gruf
10
11
  listen (~> 3.0.5)
12
+ ougai
11
13
  paranoia (~> 2.2)
12
14
  vault (~> 0.1)
13
15
 
@@ -57,6 +59,7 @@ GEM
57
59
  tzinfo (~> 1.1)
58
60
  amq-protocol (2.3.0)
59
61
  arel (9.0.0)
62
+ awesome_print (1.8.0)
60
63
  aws-eventstream (1.0.3)
61
64
  aws-sigv4 (1.1.0)
62
65
  aws-eventstream (~> 1.0, >= 1.0.2)
@@ -66,7 +69,7 @@ GEM
66
69
  bullet (5.7.6)
67
70
  activesupport (>= 3.0.0)
68
71
  uniform_notifier (~> 1.11.0)
69
- bunny (2.14.2)
72
+ bunny (2.14.3)
70
73
  amq-protocol (~> 2.3, >= 2.3.0)
71
74
  concurrent-ruby (1.1.4)
72
75
  crass (1.0.4)
@@ -81,29 +84,29 @@ GEM
81
84
  railties (>= 3.0.0)
82
85
  faker (1.7.3)
83
86
  i18n (~> 0.5)
84
- faraday (0.15.4)
87
+ faraday (0.17.3)
85
88
  multipart-post (>= 1.2, < 3)
86
89
  faraday_middleware (0.13.1)
87
90
  faraday (>= 0.7.4, < 1.0)
88
- ffi (1.11.1)
91
+ ffi (1.11.3)
89
92
  globalid (0.4.2)
90
93
  activesupport (>= 4.2.0)
91
- google-protobuf (3.9.1-universal-darwin)
94
+ google-protobuf (3.11.2)
92
95
  googleapis-common-protos-types (1.0.4)
93
96
  google-protobuf (~> 3.0)
94
- graphlient (0.3.6)
97
+ graphlient (0.3.7)
95
98
  faraday
96
99
  faraday_middleware
97
100
  graphql-client
98
- graphql (1.9.12)
99
- graphql-client (0.15.0)
101
+ graphql (1.9.17)
102
+ graphql-client (0.16.0)
100
103
  activesupport (>= 3.0)
101
104
  graphql (~> 1.8)
102
- grpc (1.23.0-universal-darwin)
105
+ grpc (1.26.0)
103
106
  google-protobuf (~> 3.8)
104
107
  googleapis-common-protos-types (~> 1.0)
105
- grpc-tools (1.23.0)
106
- gruf (2.7.0)
108
+ grpc-tools (1.26.0)
109
+ gruf (2.7.1)
107
110
  activesupport (> 4)
108
111
  concurrent-ruby (> 1)
109
112
  grpc (~> 1.10)
@@ -136,6 +139,9 @@ GEM
136
139
  nio4r (2.3.1)
137
140
  nokogiri (1.10.1)
138
141
  mini_portile2 (~> 2.4.0)
142
+ oj (3.10.0)
143
+ ougai (1.8.2)
144
+ oj (~> 3.4)
139
145
  paranoia (2.4.2)
140
146
  activerecord (>= 4.0, < 6.1)
141
147
  rack (2.0.6)
@@ -167,7 +173,7 @@ GEM
167
173
  thor (>= 0.19.0, < 2.0)
168
174
  rake (10.5.0)
169
175
  rb-fsevent (0.10.3)
170
- rb-inotify (0.10.0)
176
+ rb-inotify (0.10.1)
171
177
  ffi (~> 1.0)
172
178
  rspec (3.8.0)
173
179
  rspec-core (~> 3.8.0)
@@ -204,7 +210,7 @@ GEM
204
210
  tzinfo (1.2.5)
205
211
  thread_safe (~> 0.1)
206
212
  uniform_notifier (1.11.0)
207
- vault (0.12.0)
213
+ vault (0.13.0)
208
214
  aws-sigv4
209
215
  websocket-driver (0.7.0)
210
216
  websocket-extensions (>= 0.1.0)
data/istox.gemspec CHANGED
@@ -39,6 +39,8 @@ Gem::Specification.new do |spec|
39
39
  spec.add_dependency "graphlient"
40
40
  spec.add_dependency 'listen', '~> 3.0.5'
41
41
  spec.add_dependency "binding_of_caller"
42
+ spec.add_dependency "ougai"
43
+ spec.add_dependency "awesome_print"
42
44
  spec.add_development_dependency "bundler", "~> 1.16"
43
45
  spec.add_development_dependency "rake", "~> 10.0"
44
46
  spec.add_development_dependency "rspec", "~> 3.0"
data/lib/istox.rb CHANGED
@@ -12,6 +12,7 @@ module Istox
12
12
  end
13
13
  end
14
14
 
15
+ require 'istox/helpers/logger'
15
16
  require 'istox/interfaces/chainhub/transaction'
16
17
  require 'istox/helpers/publisher'
17
18
  require 'istox/helpers/bunny_boot'
@@ -1,3 +1,5 @@
1
+ require 'istox/helpers/logger'
2
+
1
3
  module Istox
2
4
  class BlockchainStatusHandler
3
5
  class << self
@@ -14,7 +16,7 @@ module Istox
14
16
  def chainhub_response_event(transaction)
15
17
  receipt = ::Istox::BlockchainReceipt.where(txid: transaction.uuid).first
16
18
  if receipt.blank?
17
- puts 'Transaction doesn\'t belong to this backend, skipping...'
19
+ log.info 'Transaction doesn\'t belong to this backend, skipping...'
18
20
  return
19
21
  end
20
22
 
@@ -26,7 +28,7 @@ module Istox
26
28
  resource = begin
27
29
  class_eval("::#{receipt.resource_name}", __FILE__, __LINE__).find(receipt.resource_id)
28
30
  rescue NameError
29
- puts 'Class not found, skipping...'
31
+ log.warn "Transaction bind to #{receipt.resource_name} with id #{receipt.resource_id} class not found, skipping..."
30
32
  return
31
33
  end
32
34
 
@@ -49,36 +51,42 @@ module Istox
49
51
  private
50
52
 
51
53
  def publish_to_frontend(model, success, receipt, sid)
52
- ::Istox::Publisher.publish(
53
- 'amq.topic',
54
- model.class.name.gsub('::', '').underscore.to_s,
55
- data: {
56
- id: model.id,
57
- extra: model.handle_extra
54
+ ::Istox::Publisher.manual_publish(
55
+ exchange: 'amq.topic',
56
+ exchange_type: 'direct',
57
+ routing_key: model.class.name.gsub('::', '').underscore.to_s,
58
+ message: {
59
+ data: {
60
+ id: model.id,
61
+ extra: model.handle_extra
62
+ }
58
63
  }
59
64
  )
60
65
 
61
- ::Istox::Publisher.publish(
62
- 'amq.topic',
63
- sid,
64
- data: {
65
- success: success,
66
- purpose: receipt.activity,
67
- message: receipt.message
66
+ ::Istox::Publisher.manual_publish(
67
+ exchange: 'amq.topic',
68
+ exchange_type: 'direct',
69
+ routing_key: sid,
70
+ message: {
71
+ data: {
72
+ success: success,
73
+ purpose: receipt.activity,
74
+ message: receipt.message
75
+ }
68
76
  }
69
77
  )
70
78
  rescue StandardError => e
71
- Rails.logger.warning "Unable to publish to frontend for receipt #{receipt.inspect},
79
+ log.warn "Unable to publish to frontend for receipt #{receipt.inspect},
72
80
  but will silently ignore the error"
73
- Rails.logger.warning e
81
+ log.warn e
74
82
  end
75
83
 
76
84
  def mark_resource_handled(receipt)
77
85
  receipt.update(resource_handled: true)
78
86
  rescue StandardError => e
79
- Rails.logger.warning "Unable to update resource_handled for receipt #{receipt.inspect},
87
+ log.warn "Unable to update resource_handled for receipt #{receipt.inspect},
80
88
  but will silently ignore the error"
81
- Rails.logger.warning e
89
+ log.warn e
82
90
  end
83
91
 
84
92
  def resource_handled?(receipt)
@@ -1,77 +1,124 @@
1
1
  require 'bunny'
2
+ require 'istox/helpers/logger'
3
+
2
4
  module Istox
3
5
  class BunnyBoot
4
6
  class << self
7
+ # path to amqp.yml
5
8
  def initialize!(amqp_config_path)
6
- @@amqp_config_path = amqp_config_path
7
- ::Istox::Publisher.initialize!(amqp_config_path)
8
- connect
9
- end
9
+ @amqp_config_path = amqp_config_path
10
10
 
11
- def start_subscribe
12
- subscribe_to_queues
11
+ data
13
12
  end
14
13
 
15
- def connect
16
- connection = Bunny.new(data[:connect].symbolize_keys)
17
- connection.start
18
- $channel = connection.create_channel
19
- end
14
+ # optionally can pass in consumer_key for single subscription / consumer_keys for multiple subcriptions
15
+ # consumer_key must be defined in amqp.yml
16
+ # if nothing pass in it will auto subscribe to all available consumers defined in amqp.yml queues key
17
+ def start_subscribe(consumer_key: nil, consumer_keys: nil)
18
+ subscribing_consumer_keys = consumer_keys.present? ? consumer_keys : []
19
+
20
+ if subscribing_consumer_keys.empty? && consumer_key.nil?
21
+ subscribing_consumer_keys = data['queues'].keys
22
+ elsif subscribing_consumer_keys.empty? && consumer_key.present?
23
+ subscribing_consumer_keys = [consumer_key]
24
+ end
20
25
 
21
- protected
22
-
23
- def subscribe_to_queues
24
- data&.queues&.each do |data|
25
- config = OpenStruct.new(data[1])
26
- klass = Object.const_get('::' + "#{data[0]}_consumer".camelize)
27
- exchange_type = if config.exchange.ends_with?('.fanout')
28
- :fanout
29
- else
30
- :direct
31
- end
32
- options = {}
33
- options[:routing_key] = config.name if exchange_type != :fanout
34
- queue = $channel.queue(
35
- config.name,
36
- durable: config.durable
37
- ).bind(exchange(config.exchange, exchange_type), options)
38
-
39
- manual_ack = true
40
- manual_ack = config.manual_ack unless config.manual_ack.nil?
41
-
42
- queue.subscribe manual_ack: manual_ack do |delivery_info, metadata, payload|
43
- Rails.logger.debug("Processing in consumer: #{klass}")
44
- klass.new.process(
45
- Hashie::Mash.new(JSON.parse(payload)),
46
- metadata,
47
- delivery_info
48
- )
49
- $channel.ack(delivery_info.delivery_tag) if manual_ack
50
- rescue StandardError => e
51
- Rails.logger.error(e)
52
- $channel.nack(delivery_info.delivery_tag, false, true)
53
- end
26
+ subscribing_consumer_keys.each do |key|
27
+ subscribe_to_consumer(key.to_s)
54
28
  end
55
29
  end
56
30
 
57
- private
31
+ #############################################################################################
32
+ ## INTERNAL METHODS START
33
+ ############################################################################################
58
34
 
59
- def read_file
60
- YAML.safe_load(ERB.new(File.read(@@amqp_config_path)).result)
35
+ def channel
36
+ return @channel if @channel.present?
37
+
38
+ @channel = connection.create_channel(nil, data['channel_pool_size'] || 1)
39
+ @channel.prefetch(data['channel_prefetch'] || 1)
40
+
41
+ @channel
61
42
  end
62
43
 
63
- def data
64
- OpenStruct.new(read_file)
44
+ # calling this method will spawn another channel, please use the normal channel method if you like to use the same channel
45
+ def create_new_channel(channel_config)
46
+ channel = connection.create_channel(nil, channel_config['channel_pool_size'] || data['channel_pool_size'] || 1)
47
+ channel.prefetch(channel_config['channel_prefetch'] || data['channel_prefetch'] || 1)
48
+
49
+ channel
65
50
  end
66
51
 
67
- def exchange(host_exchange, exchange_type)
68
- case exchange_type
69
- when :fanout
70
- $channel.fanout(host_exchange, durable: true)
52
+ def subscribe_to_consumer(consumer_key)
53
+ queue_config = data['queues'][consumer_key]
54
+
55
+ raise "Unable to find consumer with key #{consumer_key}, have you forgotten to define it in amqp.yml?" if queue_config.nil?
56
+
57
+ klass = Object.const_get(
58
+ '::' + (queue_config['ruby_class'].nil? ? "#{consumer_key.to_s.underscore}_consumer" : queue_config['ruby_class']).camelize
59
+ )
60
+
61
+ exchange = nil
62
+ exchange_config = exchange_config!(consumer_key)
63
+
64
+ active_channel = queue_config['channel'].present? ? create_new_channel(queue_config['channel']) : channel
65
+
66
+ queue_options = {}
67
+
68
+ exchange_durable = exchange_config['durable'].nil? ? true : exchange_config['durable']
69
+
70
+ case exchange_config['type']
71
+ when 'fanout'
72
+ exchange = active_channel.fanout(queue_config['exchange'], durable: exchange_durable)
73
+ when 'direct'
74
+ exchange = active_channel.direct(queue_config['exchange'], durable: exchange_durable)
75
+ queue_options[:routing_key] = queue_config['queue_name']
71
76
  else
72
- $channel.direct(host_exchange, durable: true)
77
+ raise "Exchange type #{exchange_config.type} is not valid/supported."
78
+ end
79
+
80
+ queue = active_channel.queue(queue_config['queue_name'],
81
+ durable: queue_config['durable'].nil? ? exchange_durable : queue_config['durable']).bind(exchange, queue_options)
82
+
83
+ manual_ack = queue_config['manual_ack'].nil? ? true : queue_config['manual_ack']
84
+
85
+ queue.subscribe manual_ack: manual_ack do |delivery_info, metadata, payload|
86
+ processing_paylod = JSON.parse(payload)
87
+ log.info "Processing in consumer: #{klass}, paylod: #{processing_paylod.inspect}"
88
+
89
+ klass.new.process(::Istox::CommonHelper.to_open_struct(processing_paylod, metadata, delivery_info))
90
+ active_channel.ack(delivery_info.delivery_tag) if manual_ack
91
+ rescue StandardError => e
92
+ log.error(e)
93
+ active_channel.nack(delivery_info.delivery_tag, false, true) if manual_ack
73
94
  end
74
95
  end
96
+
97
+ def data
98
+ raise 'Unable to find amqp configuration file, have you forgotten to initialise Istox::BunnyBoot?' if @amqp_config_path.empty?
99
+
100
+ @data ||= JSON.parse(YAML.load_file(@amqp_config_path).to_json)
101
+ end
102
+
103
+ def connection
104
+ return @connection if @connection.present?
105
+
106
+ raise 'RabbitMQ connection configuration not found, have you forgotten to define connect key in amqp.yml?' if data['connect'].nil?
107
+
108
+ @connection = Bunny.new(data['connect'].symbolize_keys)
109
+ @connection.start
110
+
111
+ @connection
112
+ end
113
+
114
+ def exchange_config!(consumer_key)
115
+ exchange_name = data['queues'][consumer_key]['exchange']
116
+ exchange_config = data['exchanges'][exchange_name]
117
+
118
+ raise "Exchange #{exchange_name} config not found, have you forgotten to define the exchange in amqp.yml?" if exchange_config.nil?
119
+
120
+ exchange_config
121
+ end
75
122
  end
76
123
  end
77
124
  end
@@ -1,4 +1,5 @@
1
1
  require 'graphlient'
2
+ require 'istox/helpers/logger'
2
3
 
3
4
  module Istox
4
5
  class GraphqlClient
@@ -13,12 +14,12 @@ module Istox
13
14
 
14
15
  raise "Please make sure you have initialised graphql cient for host #{host_type}" unless client
15
16
 
16
- Rails.logger.debug "Querying Graphql host: #{host_type}, query: #{query}, variables: #{variables.inspect}"
17
+ log.info "Querying Graphql host: #{host_type}, query: #{query}, variables: #{variables.inspect}"
17
18
  result = client.query(query, variables)
18
19
 
19
20
  return_values = ::Istox::CommonHelper.to_open_struct(result&.data)
20
21
 
21
- Rails.logger.debug "Graphql result: #{return_values.inspect}"
22
+ log.info "Graphql result: #{return_values.inspect}"
22
23
 
23
24
  return_values
24
25
  end
@@ -1,3 +1,5 @@
1
+ require 'istox/helpers/logger'
2
+
1
3
  module Istox
2
4
  class GrpcClient
3
5
  class << self
@@ -18,14 +20,14 @@ module Istox
18
20
  private
19
21
 
20
22
  def execute(host_type, service, method, **keyword_args)
21
- Rails.logger.debug "Calling method in grpc method: #{method.inspect}, params: #{keyword_args.inspect}"
23
+ log.info "Calling method in grpc method: #{method.inspect}, params: #{keyword_args.inspect}"
22
24
  t1 = Time.now
23
25
 
24
26
  result = get_host(host_type, service).call(method, keyword_args)
25
- Rails.logger.debug "Time taken for grpc execution: #{Time.now - t1} seconds"
27
+ log.info "Time taken for grpc execution: #{Time.now - t1} seconds"
26
28
 
27
29
  return_values = ::Istox::CommonHelper.to_open_struct(result.message)
28
- Rails.logger.debug "Result: #{return_values}"
30
+ log.info "Result: #{return_values}"
29
31
 
30
32
  return_values
31
33
  end
@@ -49,10 +51,10 @@ module Istox
49
51
  host_url = @@hosts[host_type]
50
52
  raise StandardError, 'Unable to find host, have you forgotten to add host to grpc client?' unless host_url
51
53
 
52
- Rails.logger.debug 'Reinitiating to grpc host at ' + host_url
54
+ log.info 'Reinitiating to grpc host at ' + host_url
53
55
  t1 = Time.now
54
56
  @@services[get_key(host_type, service)] = ::Gruf::Client.new(service: service, options: { hostname: host_url })
55
- Rails.logger.debug "Time taken for reinitiating grpc host: #{Time.now - t1} seconds"
57
+ log.info "Time taken for reinitiating grpc host: #{Time.now - t1} seconds"
56
58
  end
57
59
 
58
60
  def get_key(host_type, service)
@@ -1,21 +1,21 @@
1
1
  module Istox
2
- class GrufListenerHook < ::Gruf::Hooks::Base
3
- def before_server_start(server:)
4
- # do my thing before the server starts
2
+ class GrufListenerHook < ::Gruf::Hooks::Base
3
+ def before_server_start(server:)
4
+ # do my thing before the server starts
5
5
 
6
- @listener = ::Listen.to('app/rpc') do |modified, added, removed|
7
- puts "modified absolute path: #{modified}"
8
- puts "added absolute path: #{added}"
9
- puts "removed absolute path: #{removed}"
10
-
11
- server.init_restart
12
- end
13
- @listener.start # not blocking
14
- end
15
-
16
- def after_server_stop(server:)
17
- # do my thing after the server stops
18
- @listener.stop
19
- end
6
+ @listener = ::Listen.to('app/rpc') do |modified, added, removed|
7
+ puts "modified absolute path: #{modified}"
8
+ puts "added absolute path: #{added}"
9
+ puts "removed absolute path: #{removed}"
10
+
11
+ server.init_restart
12
+ end
13
+ @listener.start # not blocking
14
+ end
15
+
16
+ def after_server_stop(server:)
17
+ # do my thing after the server stops
18
+ @listener.stop
20
19
  end
21
- end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ require 'ougai'
2
+
3
+ module Istox
4
+ class Logger
5
+ def self.logger
6
+ return @logger if @logger.present?
7
+
8
+ @logger = ::Ougai::Logger.new(STDOUT)
9
+ @logger.formatter = ::Ougai::Formatters::Readable.new unless Rails.env.production?
10
+
11
+ @logger
12
+ end
13
+ end
14
+ end
15
+
16
+ def log
17
+ ::Istox::Logger.logger
18
+ end
@@ -1,46 +1,51 @@
1
1
  module Istox
2
- class MessageService
3
- class << self
4
- def send_sms(number, subject, content)
5
- publish('sms', data: {
6
- to: number,
7
- subject: subject,
8
- body: content
9
- },
10
- type: __method__.to_s.upcase!)
11
- end
2
+ class MessageService
3
+ class << self
4
+ def send_sms(number, subject, content)
5
+ publish('sms', data: {
6
+ to: number,
7
+ subject: subject,
8
+ body: content
9
+ },
10
+ type: __method__.to_s.upcase!)
11
+ end
12
12
 
13
- def send_sms_template(number, template)
14
- publish('sms', data: {
15
- to: number,
16
- template: template
17
- },
18
- type: __method__.to_s.upcase!)
19
- end
13
+ def send_sms_template(number, template)
14
+ publish('sms', data: {
15
+ to: number,
16
+ template: template
17
+ },
18
+ type: __method__.to_s.upcase!)
19
+ end
20
20
 
21
- def send_email(email, subject, content)
22
- publish('email', data: {
23
- to: email,
24
- subject: subject,
25
- type: 'text/plain',
26
- body: content
27
- },
28
- type: __method__.to_s.upcase!)
29
- end
21
+ def send_email(email, subject, content)
22
+ publish('email', data: {
23
+ to: email,
24
+ subject: subject,
25
+ type: 'text/plain',
26
+ body: content
27
+ },
28
+ type: __method__.to_s.upcase!)
29
+ end
30
30
 
31
- def send_email_template(email, template)
32
- publish('email', data: {
33
- to: email,
34
- template: template
35
- },
36
- type: __method__.to_s.upcase!)
37
- end
31
+ def send_email_template(email, template)
32
+ publish('email', data: {
33
+ to: email,
34
+ template: template
35
+ },
36
+ type: __method__.to_s.upcase!)
37
+ end
38
38
 
39
- private
39
+ private
40
40
 
41
- def publish(type, payload)
42
- ::Istox::Publisher.publish('message', "#{type}.message", payload)
43
- end
44
- end
41
+ def publish(type, payload)
42
+ ::Istox::Publisher.manual_publish(
43
+ exchange: 'message',
44
+ exchange_type: 'direct',
45
+ routing_key: "#{type}.message",
46
+ message: payload
47
+ )
48
+ end
45
49
  end
46
- end
50
+ end
51
+ end
@@ -1,44 +1,102 @@
1
+ require 'istox/helpers/logger'
2
+
1
3
  module Istox
4
+ # Publisher is relying on BunnyBoot to publish message, please make sure BunnyBoot is initalised properly first during runtime.
2
5
  class Publisher
3
6
  class << self
4
- def initialize!(amqp_config_path)
5
- @@amqp_config_path = amqp_config_path
6
- end
7
-
8
- def publish(exchange, routing_key, message, persistent: true)
9
- Rails.logger.debug 'Before publish retrieve data..'
10
- durable = data.fetch('publish')[exchange]['durable']
11
- Rails.logger.debug "Publishing message: #{message} with exchange: #{exchange} routing key: #{routing_key}"
12
- enqueue do
13
- $channel
14
- .direct(exchange, durable: durable)
15
- .publish(message.to_json, routing_key: routing_key, durable: durable, persistent: persistent)
7
+ # routing_key can be nil if publishing to fanout exchange
8
+ # exchange can be nil if routing_key is unique in "publish" section, this function will be able to identify which exchange it is using
9
+ # else both routing_key and exchange should be provided
10
+ # check http://reference.rubybunny.info/Bunny/Exchange.html#publish-instance_method for available publish options
11
+ def publish(exchange: nil, routing_key: nil, message:, options: {})
12
+ raise 'Exchange and routing key cannot be nil at the same time.' if exchange.nil? && routing_key.nil?
13
+
14
+ queue_publish_config = nil
15
+ if routing_key.present?
16
+ exchange = search_exchange_of_routing_key!(routing_key) if exchange.nil?
17
+
18
+ puts "EXCYANGE IS #{exchange}"
19
+
20
+ queue_publish_config = queue_publish_config!(routing_key: routing_key, exchange: exchange)
16
21
  end
22
+
23
+ exchange_config = exchange_config!(exchange)
24
+ exchange_durable = exchange_config['durable'].nil? ? true : exchange_config['durable']
25
+
26
+ queue_durable = queue_publish_config.present? ? queue_publish_config['durable'] : nil
27
+ queue_durable = exchange_config['durable'].nil? ? true : exchange_config['durable'] if queue_durable.nil?
28
+
29
+ options[:durable] = queue_durable
30
+ options[:persistent] = options[:persistent].nil? ? true : options[:persistent]
31
+
32
+ send_message(exchange: exchange, routing_key: routing_key, message: message,
33
+ exchange_type: exchange_config['type'], exchange_durable: exchange_durable, options: options)
17
34
  end
18
35
 
19
- def publish_to_fanout(exchange, message, persistent: true)
20
- Rails.logger.debug 'Before publish retrieve data..'
21
- durable = data.fetch('publish')[exchange]['durable']
22
- enqueue do
23
- $channel
24
- .fanout(exchange, durable: durable)
25
- .publish(message.to_json, durable: durable, persistent: persistent)
26
- end
36
+ # publish without defining exchange and queue in amqp.yml
37
+ def manual_publish(exchange:, routing_key: nil, message:, exchange_type: 'direct', exchange_durable: true, options: {})
38
+ options[:durable] = options[:durable].nil? ? true : options[:durable]
39
+ options[:persistent] = options[:persistent].nil? ? true : options[:persistent]
40
+
41
+ send_message(exchange: exchange, routing_key: routing_key, message: message,
42
+ exchange_type: exchange_type, exchange_durable: exchange_durable, options: options)
27
43
  end
28
44
 
29
45
  private
30
46
 
31
- def enqueue
32
- initialize_channel! unless !!$channel
33
- yield
34
- end
47
+ def send_message(exchange:, routing_key: nil, message:, exchange_type:, exchange_durable:, options: {})
48
+ log.info "Publishing RABBITMQ message to exchange: #{exchange}, routing key: #{routing_key}, data: #{message}, options: #{options.inspect}"
35
49
 
36
- def initialize_channel!
37
- ::Istox::BunnyBoot.connect
50
+ case exchange_type
51
+ when 'direct'
52
+ raise 'Routing key cannot be empty for exchange type direct' if routing_key.blank?
53
+
54
+ options[:routing_key] = routing_key
55
+ channel.direct(exchange, durable: exchange_durable).publish(message.to_json, options)
56
+ when 'fanout'
57
+ channel.fanout(exchange, durable: exchange_durable).publish(message.to_json, options)
58
+ else
59
+ raise "Exchange type #{exchange_config.type} is not valid/supported."
60
+ end
38
61
  end
39
62
 
40
63
  def data
41
- YAML.safe_load(ERB.new(File.read(@@amqp_config_path)).result)
64
+ ::Istox::BunnyBoot.data
65
+ end
66
+
67
+ def channel
68
+ ::Istox::BunnyBoot.channel
69
+ end
70
+
71
+ def queue_publish_config!(routing_key:, exchange:)
72
+ queue_publish_config = data['publish'][exchange][routing_key]
73
+ unless data['publish'][exchange].key?(routing_key)
74
+ raise "Cannot find publish queue config for exchange #{exchange} and routing key #{routing_key},
75
+ have you forgotten to define it in exchange section in amqp.yml"
76
+ end
77
+
78
+ queue_publish_config
79
+ end
80
+
81
+ def search_exchange_of_routing_key!(routing_key)
82
+ data['publish'].each do |k, v|
83
+ v.each do |k2, _v2|
84
+ return k if k2 == routing_key
85
+ end
86
+ end
87
+
88
+ raise "Cannot find exchange of routing key #{routing_key}, have you forgotten to define it in exchange section in amqp.yml"
89
+ end
90
+
91
+ def exchange_config!(exchange_name)
92
+ exchange_config = data['exchanges'][exchange_name]
93
+
94
+ if exchange_config.nil?
95
+ raise "Exchange config of #{exchange_name} cannot be found, have you
96
+ forgotten to define it in exchange section in amqp.yml"
97
+ end
98
+
99
+ exchange_config
42
100
  end
43
101
  end
44
102
  end
@@ -1,3 +1,4 @@
1
+ require 'istox/helpers/logger'
1
2
  require 'vault'
2
3
 
3
4
  module Istox
@@ -5,7 +6,7 @@ module Istox
5
6
  module TOTP
6
7
  class << self
7
8
  def create(sid, host)
8
- Rails.logger.debug { "Generate vault TOTP for key #{totp_key(sid).inspect}" }
9
+ log.debug { "Generate vault TOTP for key #{totp_key(sid).inspect}" }
9
10
 
10
11
  write_data(totp_key(sid),
11
12
  generate: true,
@@ -16,17 +17,17 @@ module Istox
16
17
  end
17
18
 
18
19
  def generate_code(sid)
19
- Rails.logger.debug { "Generate 6-digit OTP code: key #{totp_code_key(sid)}" }
20
+ log.debug { "Generate 6-digit OTP code: key #{totp_code_key(sid)}" }
20
21
  read_data(totp_code_key(sid)).data[:code]
21
22
  end
22
23
 
23
24
  def validate?(sid, code)
24
- Rails.logger.debug { "Validate TOTP code: key #{totp_code_key(sid)}, code: #{code}" }
25
+ log.debug { "Validate TOTP code: key #{totp_code_key(sid)}, code: #{code}" }
25
26
  result = write_data(totp_code_key(sid), code: code).data[:valid]
26
27
 
27
28
  unless result
28
29
  code = read_data(totp_code_key(sid)).data[:code]
29
- Rails.logger.debug { "Code is not valid, it should be #{code}" }
30
+ log.debug { "Code is not valid, it should be #{code}" }
30
31
  end
31
32
 
32
33
  result
@@ -67,7 +68,7 @@ module Istox
67
68
  config.ssl_verify = false
68
69
  config.timeout = 60
69
70
  else
70
- Rails.logger.info 'Vault token not found, OTP will not be able to use'
71
+ log.info 'Vault token not found, OTP will not be able to use'
71
72
  end
72
73
  end
73
74
  end
@@ -79,9 +80,6 @@ module Istox
79
80
 
80
81
  def validate_otp(sid, otp)
81
82
  ::Istox::Vault::TOTP.validate?(sid, otp)
82
- rescue StandardError => e
83
- raise e
84
- false
85
83
  end
86
84
  end
87
85
  end
data/lib/istox/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Istox
2
- VERSION = '0.1.103'.freeze
2
+ VERSION = '0.1.104'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: istox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.103
4
+ version: 0.1.104
5
5
  platform: ruby
6
6
  authors:
7
7
  - Siong Leng
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-02 00:00:00.000000000 Z
11
+ date: 2020-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -122,6 +122,34 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: ougai
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: awesome_print
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: bundler
127
155
  requirement: !ruby/object:Gem::Requirement
@@ -297,6 +325,7 @@ files:
297
325
  - lib/istox/helpers/graphql_client.rb
298
326
  - lib/istox/helpers/grpc_client.rb
299
327
  - lib/istox/helpers/gruf_listener_hook.rb
328
+ - lib/istox/helpers/logger.rb
300
329
  - lib/istox/helpers/message_service.rb
301
330
  - lib/istox/helpers/my_open_struct.rb
302
331
  - lib/istox/helpers/order_book_price_time.rb