nulogy_message_bus_consumer 2.0.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/nulogy_message_bus_consumer/config.rb +2 -0
- data/lib/nulogy_message_bus_consumer/kafka_utils.rb +5 -4
- data/lib/nulogy_message_bus_consumer/message.rb +3 -3
- data/lib/nulogy_message_bus_consumer/steps/commit_on_success.rb +15 -0
- data/lib/nulogy_message_bus_consumer/steps/connect_to_message_bus.rb +6 -1
- data/lib/nulogy_message_bus_consumer/steps/stream_messages_until_none_are_left.rb +9 -3
- data/lib/nulogy_message_bus_consumer/version.rb +1 -1
- data/lib/nulogy_message_bus_consumer.rb +1 -1
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/dummy/log/test.log +556 -0
- data/spec/integration/nulogy_message_bus_consumer/auditor_spec.rb +3 -2
- data/spec/integration/nulogy_message_bus_consumer/end_to_end_spec.rb +54 -0
- data/spec/integration/nulogy_message_bus_consumer/kafka_utils_spec.rb +1 -1
- data/spec/integration/nulogy_message_bus_consumer/steps/commit_on_success_spec.rb +50 -43
- data/spec/integration/nulogy_message_bus_consumer/steps/connect_to_message_bus_spec.rb +12 -26
- data/spec/integration/test_topic_spec.rb +4 -0
- data/spec/support/kafka.rb +25 -13
- data/spec/support/test_topic.rb +1 -1
- data/spec/unit/nulogy_message_bus_consumer/steps/commit_on_success_spec.rb +7 -1
- metadata +29 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 862741ddaf92ca7e2d6fde54ed615ba825bba19a4d273d1ebed423251d6b533d
|
4
|
+
data.tar.gz: 600762f9aa198ddbb83fbed2f515408da1eb92fa79906e53de946310e44814ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 675fe6e4b74840afdfcb044ba179f3c82878eb60740d5bfe5abb8568a25d45771b2aafbc33a77bdad97aac75bdc5d3fb047e450a7d970787f23b437ac626d2f6
|
7
|
+
data.tar.gz: e322f8822ebd5cc1c709f4f608cf17ee2ed66fe6e844089467a90304a7b3e73a529ef8847def2264b63208fbf41c17466b82454ce793120fda2879ca4405d84f
|
@@ -3,6 +3,7 @@ module NulogyMessageBusConsumer
|
|
3
3
|
attr_accessor :bootstrap_servers,
|
4
4
|
:client_id,
|
5
5
|
:consumer_group_id,
|
6
|
+
:security_protocol,
|
6
7
|
:lag_check_interval_seconds,
|
7
8
|
:lag_checks,
|
8
9
|
:lag_timeout_milliseconds,
|
@@ -13,6 +14,7 @@ module NulogyMessageBusConsumer
|
|
13
14
|
|
14
15
|
def initialize(options = {})
|
15
16
|
defaults = {
|
17
|
+
security_protocol: "ssl",
|
16
18
|
lag_check_interval_seconds: 20,
|
17
19
|
lag_checks: 6,
|
18
20
|
lag_timeout_milliseconds: 200,
|
@@ -10,17 +10,18 @@ module NulogyMessageBusConsumer
|
|
10
10
|
wait_for { consumer.assignment.empty? }
|
11
11
|
end
|
12
12
|
|
13
|
-
def wait_for(attempts:
|
13
|
+
def wait_for(attempts: 1000, interval: 0.1)
|
14
14
|
attempts.times do
|
15
|
-
|
15
|
+
return if yield
|
16
16
|
|
17
17
|
sleep interval
|
18
18
|
end
|
19
|
+
raise "wait_for timed out!"
|
19
20
|
end
|
20
21
|
|
21
|
-
def every_message_until_none_are_left(consumer)
|
22
|
+
def every_message_until_none_are_left(consumer, timeout = 250)
|
22
23
|
Enumerator.new do |yielder|
|
23
|
-
while (message = consumer.poll(
|
24
|
+
while (message = consumer.poll(timeout))
|
24
25
|
yielder.yield(message)
|
25
26
|
end
|
26
27
|
end
|
@@ -41,9 +41,9 @@ module NulogyMessageBusConsumer
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def to_h
|
44
|
-
|
45
|
-
attribute_name.
|
46
|
-
hash[attribute_name] = public_send(attribute_name)
|
44
|
+
instance_variables.each_with_object({}) do |instance_variable, hash|
|
45
|
+
attribute_name = instance_variable.to_s.delete("@")
|
46
|
+
hash[attribute_name.to_sym] = public_send(attribute_name)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module NulogyMessageBusConsumer
|
2
2
|
module Steps
|
3
3
|
class CommitOnSuccess
|
4
|
+
def initialize(logger)
|
5
|
+
@logger = logger
|
6
|
+
end
|
7
|
+
|
4
8
|
def call(kafka_consumer:, message:, **_)
|
5
9
|
result = yield
|
6
10
|
|
@@ -9,8 +13,18 @@ module NulogyMessageBusConsumer
|
|
9
13
|
if result == :success
|
10
14
|
kafka_consumer.store_offset(message)
|
11
15
|
kafka_consumer.commit
|
16
|
+
@logger.info(JSON.dump({
|
17
|
+
event: "message_committed",
|
18
|
+
kafka_message_id: message.id,
|
19
|
+
message: message.to_h
|
20
|
+
}))
|
12
21
|
else
|
13
22
|
reconnect_to_reprocess_same_message(kafka_consumer)
|
23
|
+
@logger.info(JSON.dump({
|
24
|
+
event: "message_failed",
|
25
|
+
kafka_message_id: message.id,
|
26
|
+
message: message.to_h
|
27
|
+
}))
|
14
28
|
end
|
15
29
|
|
16
30
|
result
|
@@ -22,6 +36,7 @@ module NulogyMessageBusConsumer
|
|
22
36
|
subscriptions = kafka_consumer.subscription
|
23
37
|
kafka_consumer.unsubscribe
|
24
38
|
kafka_consumer.subscribe(*subscriptions.to_h.keys)
|
39
|
+
KafkaUtils.wait_for_assignment(kafka_consumer)
|
25
40
|
end
|
26
41
|
|
27
42
|
def raise_if_invalid(result)
|
@@ -31,7 +31,12 @@ module NulogyMessageBusConsumer
|
|
31
31
|
"bootstrap.servers": @config.bootstrap_servers,
|
32
32
|
"enable.auto.commit": false,
|
33
33
|
"group.id": @config.consumer_group_id,
|
34
|
-
"enable.auto.offset.store": false
|
34
|
+
"enable.auto.offset.store": false,
|
35
|
+
# Connect to the broker(s) using TLS:
|
36
|
+
# See "SSL" section in:
|
37
|
+
# https://github.com/confluentinc/librdkafka/blob/cb8c19c43011b66c4b08b25e5150455a247e1ff3/INTRODUCTION.md
|
38
|
+
# librdkafka will try to use CA certs from OpenSSL if installed
|
39
|
+
"security.protocol": @config.security_protocol
|
35
40
|
}
|
36
41
|
|
37
42
|
config["client.id"] = @config.client_id if @config.client_id
|
@@ -1,17 +1,23 @@
|
|
1
1
|
module NulogyMessageBusConsumer
|
2
2
|
module Steps
|
3
3
|
class StreamMessagesUntilNoneAreLeft
|
4
|
-
def initialize(logger)
|
4
|
+
def initialize(logger, timeout = 250)
|
5
5
|
@logger = logger
|
6
|
+
@timeout = timeout
|
6
7
|
end
|
7
8
|
|
8
9
|
def call(kafka_consumer:, **_)
|
9
|
-
KafkaUtils.every_message_until_none_are_left(kafka_consumer).each do |kafka_message|
|
10
|
-
yield(
|
10
|
+
KafkaUtils.every_message_until_none_are_left(kafka_consumer, @timeout).each do |kafka_message|
|
11
|
+
result = yield(
|
11
12
|
message: Message.from_kafka(kafka_message),
|
12
13
|
kafka_message: kafka_message
|
13
14
|
)
|
15
|
+
if result == :failure
|
16
|
+
# stop reading on failure or else we'll get stuck in a loop
|
17
|
+
return :failure
|
18
|
+
end
|
14
19
|
end
|
20
|
+
:success
|
15
21
|
rescue => e
|
16
22
|
@logger.error(JSON.dump({
|
17
23
|
event: "message_processing_errored",
|
@@ -67,7 +67,7 @@ module NulogyMessageBusConsumer
|
|
67
67
|
Steps::StreamMessages.new(logger),
|
68
68
|
# Message processing steps start here.
|
69
69
|
Steps::LogMessages.new(logger),
|
70
|
-
Steps::CommitOnSuccess.new,
|
70
|
+
Steps::CommitOnSuccess.new(logger),
|
71
71
|
Steps::DeduplicateMessages.new(logger)
|
72
72
|
])
|
73
73
|
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 2020_06_12_184425) do
|
14
14
|
# These are extensions that must be enabled in order to support this database
|
15
15
|
enable_extension "plpgsql"
|
16
16
|
enable_extension "uuid-ossp"
|