nulogy_message_bus_consumer 0.3.0 → 0.3.1

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: 2faa5c725b717d217b37a0c9019ecd3f3ae9d40885a2e3b1ce898e626bbb2d3c
4
- data.tar.gz: 865137198c57cfd60bdea31c482a66240a284c34d4f1149033160c28fb2a6cef
3
+ metadata.gz: b0b77dbd208bb83d34c4881d00765baac92c4fd8ba36d5f0395e5adf479fd6ca
4
+ data.tar.gz: 74360efce2d94e148f1792aa7f4b6424c656553c6ca4452cf66583a84352a315
5
5
  SHA512:
6
- metadata.gz: 82c5cf164680d27183b17b341b362c5f1ec70a26fecf79d4f8d982ea3506e107ac8e216604c5182469c627892f3c423336053a2502c8e10c574c85af5dd82402
7
- data.tar.gz: d2109e0aefef9eecebfb57425316cf36dd7cdb92a4356253efb73271f2fed5e4c1ed59e56a46b44a2dc869dd3acb5285b88ae11d6d72b15f50a7506ed85058a2
6
+ metadata.gz: 4503a0fda0106a555a2063319ff1d71127503ab0638a50b4d2fa04e55b38d109039fb7863f1162a397140c15f255f36309d15bc2f6ce3d9f8d168a2f9479f42b
7
+ data.tar.gz: af0f4d1a905cdddfb8b04f7a4b3c232e66eb32d9b90daf28ede558afd4879e529c3992147bac19f75f4b097966a020ec87ff5013e40370ddcc43325fa50d1dd3
data/Rakefile CHANGED
@@ -18,13 +18,15 @@ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
18
18
  load "rails/tasks/engine.rake"
19
19
  load "rails/tasks/statistics.rake"
20
20
 
21
+ require "rspec/core"
22
+ require "rspec/core/rake_task"
21
23
  RSpec::Core::RakeTask.new(:spec)
22
24
  require "rubocop/rake_task"
23
25
  RuboCop::RakeTask.new
24
- task default: [:spec, :rubocop]
26
+ task default: %i[spec rubocop]
25
27
 
26
28
  require "rake/release"
27
29
 
28
30
  Rake::Release::Task.load_all do |spec|
29
- spec.version_tag = "nulogy_message_bus_producer-v#{spec.version}"
31
+ spec.version_tag = "nulogy_message_bus_consumer-v#{spec.version}"
30
32
  end
@@ -31,7 +31,7 @@ module NulogyMessageBusConsumer
31
31
  end
32
32
 
33
33
  def logger
34
- @@logger ||= NullLogger.new
34
+ @logger ||= NullLogger.new
35
35
  end
36
36
 
37
37
  def invoke_pipeline(*steps)
@@ -56,7 +56,7 @@ module NulogyMessageBusConsumer
56
56
  Steps::ConnectToMessageBus.new(config, logger),
57
57
  Steps::SeekBeginningOfTopic.new,
58
58
  Steps::StreamMessagesUntilNoneAreLeft.new(logger),
59
- Handlers::LogUnprocessedMessages.new(logger)
59
+ Handlers::LogUnprocessedMessages.new(logger),
60
60
  ])
61
61
  end
62
62
  end
@@ -7,9 +7,10 @@ module NulogyMessageBusConsumer
7
7
 
8
8
  def call(message:, **_)
9
9
  return if ProcessedMessage.exists?(id: message.id)
10
+
10
11
  @logger.warn(JSON.dump(
11
12
  event: "unprocessed_message",
12
- kafka_message: message.to_h,
13
+ kafka_message: message.to_h
13
14
  ))
14
15
  end
15
16
  end
@@ -13,13 +13,14 @@ module NulogyMessageBusConsumer
13
13
  def wait_for(attempts: 100, interval: 0.1)
14
14
  attempts.times do
15
15
  break if yield
16
+
16
17
  sleep interval
17
18
  end
18
19
  end
19
20
 
20
21
  def every_message_until_none_are_left(consumer)
21
22
  Enumerator.new do |yielder|
22
- while message = consumer.poll(250)
23
+ while (message = consumer.poll(250))
23
24
  yielder.yield(message)
24
25
  end
25
26
  end
@@ -1,9 +1,5 @@
1
1
  module NulogyMessageBusConsumer
2
2
  class Message
3
- def initialize(attrs = {})
4
- attrs.each { |key, value| instance_variable_set("@#{key}", value) }
5
- end
6
-
7
3
  attr_reader :event_data
8
4
  attr_reader :event_data_unparsed
9
5
  attr_reader :id
@@ -14,10 +10,20 @@ module NulogyMessageBusConsumer
14
10
  attr_reader :company_uuid
15
11
  attr_reader :timestamp
16
12
  attr_reader :topic
13
+ attr_reader :created_at
14
+
15
+ def initialize(attrs = {})
16
+ attrs.each { |key, value| instance_variable_set("@#{key}", value) }
17
+ end
17
18
 
18
19
  def self.from_kafka(kafka_message)
19
20
  envelope_data = JSON.parse(kafka_message.payload, symbolize_names: true)
20
- event_data = JSON.parse(envelope_data[:event_json], symbolize_names: true) rescue {}
21
+ event_data =
22
+ begin
23
+ JSON.parse(envelope_data[:event_json], symbolize_names: true)
24
+ rescue StandardError
25
+ {}
26
+ end
21
27
 
22
28
  new(
23
29
  event_data: event_data,
@@ -30,6 +36,7 @@ module NulogyMessageBusConsumer
30
36
  company_uuid: envelope_data[:company_uuid] || envelope_data[:tenant_id],
31
37
  timestamp: kafka_message.timestamp,
32
38
  topic: kafka_message.topic,
39
+ created_at: envelope_data[:created_at]
33
40
  )
34
41
  end
35
42
 
@@ -9,7 +9,7 @@ module NulogyMessageBusConsumer
9
9
  end
10
10
 
11
11
  def insert(step, after:)
12
- index = @steps.find_index { |step| step.is_a?(after) }
12
+ index = @steps.find_index { |s| s.is_a?(after) }
13
13
  @steps.insert(index + 1, step)
14
14
  end
15
15
 
@@ -25,7 +25,7 @@ module NulogyMessageBusConsumer
25
25
  @steps.reverse.reduce(last_step) do |composed_steps, previous_step|
26
26
  lambda do |**args|
27
27
  invoke_next = compose_with_merged_args(args, composed_steps)
28
- previous_step.call(**args, &invoke_next)
28
+ previous_step.call(**args, &invoke_next)
29
29
  end
30
30
  end
31
31
  end
@@ -33,7 +33,10 @@ module NulogyMessageBusConsumer
33
33
  def compose_with_merged_args(existing_args, func)
34
34
  lambda do |**yielded_args|
35
35
  args_to_be_overridden = existing_args.keys & yielded_args.keys
36
- raise "Cannot override existing argument(s): #{args_to_be_overridden.join(', ')}" if args_to_be_overridden.any?
36
+ if args_to_be_overridden.any?
37
+ raise "Cannot override existing argument(s): #{args_to_be_overridden.join(', ')}"
38
+ end
39
+
37
40
  func.call(**existing_args.merge(yielded_args))
38
41
  end
39
42
  end
@@ -1,7 +1,7 @@
1
1
  module NulogyMessageBusConsumer
2
2
  module Steps
3
3
  class CommitOnSuccess
4
- def call(kafka_consumer:, message:, **_)
4
+ def call(kafka_consumer:, **_)
5
5
  result = yield
6
6
 
7
7
  raise_if_invalid(result)
@@ -1,14 +1,15 @@
1
1
  module NulogyMessageBusConsumer
2
2
  module Steps
3
3
  class ConnectToMessageBus
4
- def initialize(config, logger)
4
+ def initialize(config, logger, kafka_consumer: nil)
5
5
  @config = config
6
6
  @logger = logger
7
+ @kafka_consumer = kafka_consumer
7
8
  end
8
9
 
9
10
  def call(**_)
10
11
  @logger.info("Connecting to the MessageBus")
11
- consumer = Rdkafka::Config.new(consumer_config).consumer
12
+ consumer = build_consumer
12
13
  @logger.info("Using consumer group id: #{@config.consumer_group_id}")
13
14
 
14
15
  consumer.subscribe(@config.topic_name)
@@ -22,6 +23,10 @@ module NulogyMessageBusConsumer
22
23
 
23
24
  private
24
25
 
26
+ def build_consumer
27
+ @kafka_consumer || Rdkafka::Config.new(consumer_config).consumer
28
+ end
29
+
25
30
  def consumer_config
26
31
  {
27
32
  "bootstrap.servers": @config.bootstrap_servers,
@@ -1,8 +1,16 @@
1
1
  module NulogyMessageBusConsumer
2
2
  module Steps
3
+ class Clock
4
+ # milliseconds since epoch
5
+ def now
6
+ Time.zone.now.to_datetime.strftime("%Q").to_i
7
+ end
8
+ end
9
+
3
10
  class LogMessages
4
- def initialize(logger)
11
+ def initialize(logger, clock: Clock.new)
5
12
  @logger = logger
13
+ @clock = clock
6
14
  end
7
15
 
8
16
  def call(message:, **_)
@@ -14,15 +22,25 @@ module NulogyMessageBusConsumer
14
22
 
15
23
  result = yield
16
24
 
25
+ millis = diff_millis(message.created_at, @clock.now)
17
26
  @logger.info(JSON.dump({
18
27
  event: "message_processed",
19
28
  kafka_message_id: message.id,
20
29
  message: "Processed #{message.id}",
21
30
  result: result,
31
+ time_to_processed: millis,
22
32
  }))
23
33
 
24
34
  result
25
35
  end
36
+
37
+ # Debezium appears to be giving us nanos since epoch
38
+ # https://github.com/debezium/debezium/blob/5a115e902cdc1dc399ec02758dd1039a33e99bc2/debezium-core/src/main/java/io/debezium/jdbc/JdbcValueConverters.java#L237
39
+ def diff_millis(oldest_nanos, newest_millis)
40
+ old_millis = oldest_nanos / 1000
41
+
42
+ newest_millis - old_millis
43
+ end
26
44
  end
27
45
  end
28
46
  end
@@ -1,3 +1,3 @@
1
1
  module NulogyMessageBusConsumer
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  namespace :message_bus_consumer do
2
2
  desc "Verifies that the messages in the message bus have been processed"
3
- task :audit => :environment do
3
+ task audit: :environment do
4
4
  config = build_audit_config
5
5
 
6
6
  NulogyMessageBusConsumer
@@ -13,4 +13,4 @@ namespace :message_bus_consumer do
13
13
  audit_config.consumer_group_id = "#{audit_config.consumer_group_id}_consumer_audit"
14
14
  NulogyMessageBusConsumer.config
15
15
  end
16
- end
16
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nulogy_message_bus_consumer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nulogy
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-05 00:00:00.000000000 Z
11
+ date: 2020-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -52,6 +52,48 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pg
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.2.3
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 1.2.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
55
97
  - !ruby/object:Gem::Dependency
56
98
  name: rails
57
99
  requirement: !ruby/object:Gem::Requirement
@@ -95,33 +137,33 @@ dependencies:
95
137
  - !ruby/object:Gem::Version
96
138
  version: 3.9.0
97
139
  - !ruby/object:Gem::Dependency
98
- name: rspec-rails
140
+ name: rspec-json_expectations
99
141
  requirement: !ruby/object:Gem::Requirement
100
142
  requirements:
101
143
  - - '='
102
144
  - !ruby/object:Gem::Version
103
- version: 4.0.1
145
+ version: 2.2.0
104
146
  type: :development
105
147
  prerelease: false
106
148
  version_requirements: !ruby/object:Gem::Requirement
107
149
  requirements:
108
150
  - - '='
109
151
  - !ruby/object:Gem::Version
110
- version: 4.0.1
152
+ version: 2.2.0
111
153
  - !ruby/object:Gem::Dependency
112
- name: rspec-json_expectations
154
+ name: rspec-rails
113
155
  requirement: !ruby/object:Gem::Requirement
114
156
  requirements:
115
157
  - - '='
116
158
  - !ruby/object:Gem::Version
117
- version: 2.2.0
159
+ version: 4.0.1
118
160
  type: :development
119
161
  prerelease: false
120
162
  version_requirements: !ruby/object:Gem::Requirement
121
163
  requirements:
122
164
  - - '='
123
165
  - !ruby/object:Gem::Version
124
- version: 2.2.0
166
+ version: 4.0.1
125
167
  - !ruby/object:Gem::Dependency
126
168
  name: rubocop
127
169
  requirement: !ruby/object:Gem::Requirement
@@ -137,34 +179,34 @@ dependencies:
137
179
  - !ruby/object:Gem::Version
138
180
  version: 0.81.0
139
181
  - !ruby/object:Gem::Dependency
140
- name: rubocop-rspec
182
+ name: rubocop-rails
141
183
  requirement: !ruby/object:Gem::Requirement
142
184
  requirements:
143
185
  - - '='
144
186
  - !ruby/object:Gem::Version
145
- version: 1.38.1
187
+ version: 2.5.2
146
188
  type: :development
147
189
  prerelease: false
148
190
  version_requirements: !ruby/object:Gem::Requirement
149
191
  requirements:
150
192
  - - '='
151
193
  - !ruby/object:Gem::Version
152
- version: 1.38.1
194
+ version: 2.5.2
153
195
  - !ruby/object:Gem::Dependency
154
- name: pg
196
+ name: rubocop-rspec
155
197
  requirement: !ruby/object:Gem::Requirement
156
198
  requirements:
157
199
  - - '='
158
200
  - !ruby/object:Gem::Version
159
- version: 1.2.3
201
+ version: 1.38.1
160
202
  type: :development
161
203
  prerelease: false
162
204
  version_requirements: !ruby/object:Gem::Requirement
163
205
  requirements:
164
206
  - - '='
165
207
  - !ruby/object:Gem::Version
166
- version: 1.2.3
167
- description:
208
+ version: 1.38.1
209
+ description:
168
210
  email:
169
211
  - tass@nulogy.com
170
212
  executables: []
@@ -197,7 +239,7 @@ homepage: https://github.com/nulogy/message-bus/tree/master/gems/nulogy_message_
197
239
  licenses: []
198
240
  metadata:
199
241
  allowed_push_host: https://rubygems.org/
200
- post_install_message:
242
+ post_install_message:
201
243
  rdoc_options: []
202
244
  require_paths:
203
245
  - lib
@@ -213,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
213
255
  version: '0'
214
256
  requirements: []
215
257
  rubygems_version: 3.0.3
216
- signing_key:
258
+ signing_key:
217
259
  specification_version: 4
218
260
  summary: Code for accessing the Nulogy Message Bus
219
261
  test_files: []