nulogy_message_bus_consumer 0.1.0 → 0.2.0
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 +4 -4
- data/Rakefile +0 -1
- data/lib/nulogy_message_bus_consumer.rb +38 -28
- data/lib/nulogy_message_bus_consumer/config.rb +4 -0
- data/lib/nulogy_message_bus_consumer/handlers/log_unprocessed_messages.rb +17 -0
- data/lib/nulogy_message_bus_consumer/kafka_utils.rb +61 -0
- data/lib/nulogy_message_bus_consumer/message.rb +32 -13
- data/lib/nulogy_message_bus_consumer/null_logger.rb +9 -0
- data/lib/nulogy_message_bus_consumer/pipeline.rb +41 -0
- data/lib/nulogy_message_bus_consumer/steps/commit_on_success.rb +36 -0
- data/lib/nulogy_message_bus_consumer/steps/connect_to_message_bus.rb +4 -0
- data/lib/nulogy_message_bus_consumer/steps/monitor_replication_lag.rb +1 -1
- data/lib/nulogy_message_bus_consumer/steps/seek_beginning_of_topic.rb +10 -0
- data/lib/nulogy_message_bus_consumer/steps/{stream_individual_messages.rb → stream_messages.rb} +4 -12
- data/lib/nulogy_message_bus_consumer/steps/stream_messages_until_none_are_left.rb +26 -0
- data/lib/nulogy_message_bus_consumer/version.rb +1 -1
- data/lib/tasks/engine/message_bus_consumer.rake +16 -0
- metadata +46 -11
- data/lib/nulogy_message_bus_consumer/steps/result_validation.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2ef8a36c5d0ba49ef96b39045cada64669993cd7f627951199ffaee2413c0cb
|
4
|
+
data.tar.gz: 63bb5a74cc469511876d7443be41ee0fab4b43782b394e469cc8fc724f82ed3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1c99f7925a176c7d4e0637c4fb95cfe88768c76bc316352b2ac829758c79c6e765c6c051256a8b46cc9ffdb16e310ed5d46fc9aa33460ebd96073fd59509e8e
|
7
|
+
data.tar.gz: 683efad3187b13a70d88bb13ebe84e1ce44509a2f64a4324014d521e331df2d50baac5718e8758d93700eaf73e19e1251985784bace259e30fd7fc1fa3fc0438
|
data/Rakefile
CHANGED
@@ -1,52 +1,62 @@
|
|
1
|
+
require "rdkafka"
|
2
|
+
|
1
3
|
require "nulogy_message_bus_consumer/engine"
|
4
|
+
|
2
5
|
require "nulogy_message_bus_consumer/config"
|
6
|
+
require "nulogy_message_bus_consumer/handlers/log_unprocessed_messages"
|
7
|
+
require "nulogy_message_bus_consumer/kafka_utils"
|
3
8
|
require "nulogy_message_bus_consumer/message"
|
9
|
+
require "nulogy_message_bus_consumer/null_logger"
|
10
|
+
require "nulogy_message_bus_consumer/pipeline"
|
4
11
|
require "nulogy_message_bus_consumer/processed_message"
|
12
|
+
require "nulogy_message_bus_consumer/steps/commit_on_success"
|
5
13
|
require "nulogy_message_bus_consumer/steps/connect_to_message_bus"
|
6
14
|
require "nulogy_message_bus_consumer/steps/deduplicate_messages"
|
7
15
|
require "nulogy_message_bus_consumer/steps/log_messages"
|
8
16
|
require "nulogy_message_bus_consumer/steps/monitor_replication_lag"
|
9
|
-
require "nulogy_message_bus_consumer/steps/
|
10
|
-
require "nulogy_message_bus_consumer/steps/
|
17
|
+
require "nulogy_message_bus_consumer/steps/seek_beginning_of_topic"
|
18
|
+
require "nulogy_message_bus_consumer/steps/stream_messages"
|
19
|
+
require "nulogy_message_bus_consumer/steps/stream_messages_until_none_are_left"
|
11
20
|
|
12
21
|
module NulogyMessageBusConsumer
|
13
22
|
module_function
|
14
23
|
|
24
|
+
mattr_accessor :config
|
25
|
+
mattr_accessor :logger
|
26
|
+
|
27
|
+
def configure(options = {})
|
28
|
+
self.config ||= Config.new
|
29
|
+
config.update(options) if options.present?
|
30
|
+
yield(config) if block_given?
|
31
|
+
end
|
32
|
+
|
33
|
+
def logger
|
34
|
+
@@logger ||= NullLogger.new
|
35
|
+
end
|
36
|
+
|
15
37
|
def invoke_pipeline(*steps)
|
16
|
-
|
38
|
+
Pipeline.new(steps).invoke
|
17
39
|
end
|
18
40
|
|
19
|
-
def
|
20
|
-
[
|
41
|
+
def recommended_consumer_pipeline(config: self.config, logger: self.logger)
|
42
|
+
Pipeline.new([
|
21
43
|
# The first three are really system processing steps
|
22
44
|
Steps::ConnectToMessageBus.new(config, logger),
|
23
45
|
Steps::MonitorReplicationLag.new(logger),
|
24
|
-
Steps::
|
46
|
+
Steps::StreamMessages.new(logger),
|
25
47
|
# Message processing steps start here.
|
26
48
|
Steps::LogMessages.new(logger),
|
49
|
+
Steps::CommitOnSuccess.new,
|
27
50
|
Steps::DeduplicateMessages.new(logger),
|
28
|
-
|
29
|
-
]
|
51
|
+
])
|
30
52
|
end
|
31
53
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def compose_with_merged_args(context, func)
|
44
|
-
lambda do |**inner_args|
|
45
|
-
existing = context.keys & inner_args.keys
|
46
|
-
|
47
|
-
raise "Cannot override existing key(s): #{existing.join(', ')}" if existing.any?
|
48
|
-
|
49
|
-
func.call(**context.merge(inner_args))
|
50
|
-
end
|
54
|
+
def consumer_audit_pipeline(config: self.config, logger: self.logger)
|
55
|
+
Pipeline.new([
|
56
|
+
Steps::ConnectToMessageBus.new(config, logger),
|
57
|
+
Steps::SeekBeginningOfTopic.new,
|
58
|
+
Steps::StreamMessagesUntilNoneAreLeft.new(logger),
|
59
|
+
Handlers::LogUnprocessedMessages.new(logger)
|
60
|
+
])
|
51
61
|
end
|
52
|
-
end
|
62
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module NulogyMessageBusConsumer
|
2
|
+
module Handlers
|
3
|
+
class LogUnprocessedMessages
|
4
|
+
def initialize(logger)
|
5
|
+
@logger = logger
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(message:, **_)
|
9
|
+
return if ProcessedMessage.exists?(id: message.id)
|
10
|
+
@logger.warn(JSON.dump(
|
11
|
+
event: "unprocessed_message",
|
12
|
+
kafka_message: message.to_h,
|
13
|
+
))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module NulogyMessageBusConsumer
|
2
|
+
module KafkaUtils
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def wait_for_assignment(consumer)
|
6
|
+
wait_for { !consumer.assignment.empty? }
|
7
|
+
end
|
8
|
+
|
9
|
+
def wait_for_unassignment(consumer)
|
10
|
+
wait_for { consumer.assignment.empty? }
|
11
|
+
end
|
12
|
+
|
13
|
+
def wait_for(attempts: 100, interval: 0.1)
|
14
|
+
attempts.times do
|
15
|
+
break if yield
|
16
|
+
sleep interval
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def every_message_until_none_are_left(consumer)
|
21
|
+
Enumerator.new do |yielder|
|
22
|
+
while message = consumer.poll(250)
|
23
|
+
yielder.yield(message)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def seek_beginning(consumer)
|
29
|
+
wait_for_assignment(consumer)
|
30
|
+
assigned_partitions(consumer).each do |topic_name, partition|
|
31
|
+
message = Message.new(
|
32
|
+
topic: topic_name,
|
33
|
+
partition: partition,
|
34
|
+
offset: BEGINNING_OFFSET
|
35
|
+
)
|
36
|
+
consumer.seek(message)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def seek_ending(consumer)
|
41
|
+
wait_for_assignment(consumer)
|
42
|
+
assigned_partitions(consumer).each do |topic_name, partition|
|
43
|
+
message = Message.new(
|
44
|
+
topic: topic_name,
|
45
|
+
partition: partition,
|
46
|
+
offset: END_OFFSET
|
47
|
+
)
|
48
|
+
consumer.seek(message)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def assigned_partitions(consumer)
|
53
|
+
consumer.assignment.to_h
|
54
|
+
.flat_map { |topic_name, partitions| [topic_name].product(partitions) }
|
55
|
+
.map { |topic_name, partition| [topic_name, partition.partition] }
|
56
|
+
end
|
57
|
+
|
58
|
+
BEGINNING_OFFSET = 0
|
59
|
+
END_OFFSET = -1
|
60
|
+
end
|
61
|
+
end
|
@@ -1,21 +1,40 @@
|
|
1
1
|
module NulogyMessageBusConsumer
|
2
|
-
Message
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
:
|
8
|
-
|
9
|
-
|
2
|
+
class Message
|
3
|
+
def initialize(attrs = {})
|
4
|
+
attrs.each { |key, value| instance_variable_set("@#{key}", value) }
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_reader :event_data
|
8
|
+
attr_reader :id
|
9
|
+
attr_reader :key
|
10
|
+
attr_reader :offset
|
11
|
+
attr_reader :partition
|
12
|
+
attr_reader :public_subscription_id
|
13
|
+
attr_reader :tenant_id
|
14
|
+
attr_reader :timestamp
|
15
|
+
attr_reader :topic
|
16
|
+
|
10
17
|
def self.from_kafka(kafka_message)
|
11
|
-
envelope_data = JSON.parse(kafka_message.payload)
|
18
|
+
envelope_data = JSON.parse(kafka_message.payload, symbolize_names: true)
|
12
19
|
|
13
20
|
new(
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
21
|
+
event_data: envelope_data[:event_json],
|
22
|
+
id: envelope_data[:id],
|
23
|
+
key: kafka_message.key,
|
24
|
+
offset: kafka_message.offset,
|
25
|
+
partition: kafka_message.partition,
|
26
|
+
public_subscription_id: envelope_data[:public_subscription_id],
|
27
|
+
tenant_id: envelope_data[:tenant_id],
|
28
|
+
timestamp: kafka_message.timestamp,
|
29
|
+
topic: kafka_message.topic,
|
18
30
|
)
|
19
31
|
end
|
32
|
+
|
33
|
+
def to_h
|
34
|
+
instance_variable_names.each_with_object({}) do |attribute_name, hash|
|
35
|
+
attribute_name.sub!("@", "")
|
36
|
+
hash[attribute_name] = public_send(attribute_name)
|
37
|
+
end
|
38
|
+
end
|
20
39
|
end
|
21
40
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module NulogyMessageBusConsumer
|
2
|
+
class Pipeline
|
3
|
+
def initialize(steps)
|
4
|
+
@steps = steps
|
5
|
+
end
|
6
|
+
|
7
|
+
def invoke
|
8
|
+
convert_steps_into_lambda.call
|
9
|
+
end
|
10
|
+
|
11
|
+
def insert(step, after:)
|
12
|
+
index = @steps.find_index { |step| step.is_a?(after) }
|
13
|
+
@steps.insert(index + 1, step)
|
14
|
+
end
|
15
|
+
|
16
|
+
def append(step)
|
17
|
+
@steps << step
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def convert_steps_into_lambda
|
23
|
+
last_step = ->(**_) { raise "Handlers are the end of the line. Do not use yield." }
|
24
|
+
|
25
|
+
@steps.reverse.reduce(last_step) do |composed_steps, previous_step|
|
26
|
+
lambda do |**args|
|
27
|
+
invoke_next = compose_with_merged_args(args, composed_steps)
|
28
|
+
previous_step.call(**args, &invoke_next)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def compose_with_merged_args(existing_args, func)
|
34
|
+
lambda do |**yielded_args|
|
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?
|
37
|
+
func.call(**existing_args.merge(yielded_args))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module NulogyMessageBusConsumer
|
2
|
+
module Steps
|
3
|
+
class CommitOnSuccess
|
4
|
+
def call(kafka_consumer:, message:, **_)
|
5
|
+
result = yield
|
6
|
+
|
7
|
+
raise_if_invalid(result)
|
8
|
+
|
9
|
+
if result == :success
|
10
|
+
kafka_consumer.commit
|
11
|
+
else
|
12
|
+
reconnect_to_reprocess_same_message(kafka_consumer)
|
13
|
+
end
|
14
|
+
|
15
|
+
result
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def reconnect_to_reprocess_same_message(kafka_consumer)
|
21
|
+
subscriptions = kafka_consumer.subscription
|
22
|
+
kafka_consumer.unsubscribe
|
23
|
+
kafka_consumer.subscribe(*subscriptions.to_h.keys)
|
24
|
+
end
|
25
|
+
|
26
|
+
def raise_if_invalid(result)
|
27
|
+
return if %i[success failure].include?(result)
|
28
|
+
|
29
|
+
raise(
|
30
|
+
StandardError,
|
31
|
+
"'#{result}' is not a valid processing outcome. Must be :success or :failure"
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -11,8 +11,12 @@ module NulogyMessageBusConsumer
|
|
11
11
|
consumer = Rdkafka::Config.new(consumer_config).consumer
|
12
12
|
@logger.info("Using consumer group id: #{@config.consumer_group_id}")
|
13
13
|
|
14
|
+
consumer.subscribe(@config.topic_name)
|
15
|
+
@logger.info("Listening for kafka messages on topic #{@config.topic_name}")
|
16
|
+
|
14
17
|
trap("TERM") { consumer.close }
|
15
18
|
|
19
|
+
KafkaUtils.wait_for_assignment(consumer)
|
16
20
|
yield(kafka_consumer: consumer)
|
17
21
|
end
|
18
22
|
|
@@ -15,7 +15,7 @@ module NulogyMessageBusConsumer
|
|
15
15
|
# Delayed start. If we attempt to read consumer#committed immediately, it may fail.
|
16
16
|
# We suspect this is because the consumer#committed is called before the consumer
|
17
17
|
# has finished connecting. There appears to be a race condition.
|
18
|
-
|
18
|
+
KafkaUtils.wait_for_assignment(kafka_consumer)
|
19
19
|
|
20
20
|
loop do
|
21
21
|
lag_per_topic = kafka_consumer.lag(kafka_consumer.committed)
|
data/lib/nulogy_message_bus_consumer/steps/{stream_individual_messages.rb → stream_messages.rb}
RENAMED
@@ -1,22 +1,16 @@
|
|
1
1
|
module NulogyMessageBusConsumer
|
2
2
|
module Steps
|
3
|
-
class
|
4
|
-
def initialize(
|
5
|
-
@config = config
|
3
|
+
class StreamMessages
|
4
|
+
def initialize(logger)
|
6
5
|
@logger = logger
|
7
6
|
end
|
8
7
|
|
9
8
|
def call(kafka_consumer:, **_)
|
10
|
-
kafka_consumer.subscribe(@config.topic_name)
|
11
|
-
@logger.info "Listening for kafka messages on topic #{@config.topic_name}"
|
12
|
-
|
13
9
|
kafka_consumer.each do |kafka_message|
|
14
|
-
|
15
|
-
message:
|
10
|
+
yield(
|
11
|
+
message: Message.from_kafka(kafka_message),
|
16
12
|
kafka_message: kafka_message
|
17
13
|
)
|
18
|
-
|
19
|
-
kafka_consumer.commit if result == :success
|
20
14
|
end
|
21
15
|
rescue StandardError => e
|
22
16
|
@logger.error(JSON.dump({
|
@@ -25,8 +19,6 @@ module NulogyMessageBusConsumer
|
|
25
19
|
message: e.message,
|
26
20
|
}))
|
27
21
|
|
28
|
-
kafka_consumer.unsubscribe
|
29
|
-
|
30
22
|
raise
|
31
23
|
end
|
32
24
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module NulogyMessageBusConsumer
|
2
|
+
module Steps
|
3
|
+
class StreamMessagesUntilNoneAreLeft
|
4
|
+
def initialize(logger)
|
5
|
+
@logger = logger
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(kafka_consumer:, **_)
|
9
|
+
KafkaUtils.every_message_until_none_are_left(kafka_consumer).each do |kafka_message|
|
10
|
+
yield(
|
11
|
+
message: Message.from_kafka(kafka_message),
|
12
|
+
kafka_message: kafka_message
|
13
|
+
)
|
14
|
+
end
|
15
|
+
rescue StandardError => e
|
16
|
+
@logger.error(JSON.dump({
|
17
|
+
event: "message_processing_errored",
|
18
|
+
class: e.class,
|
19
|
+
message: e.message,
|
20
|
+
}))
|
21
|
+
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
namespace :message_bus_consumer do
|
2
|
+
desc "Verifies that the messages in the message bus have been processed"
|
3
|
+
task :audit => :environment do
|
4
|
+
config = build_audit_config
|
5
|
+
|
6
|
+
NulogyMessageBusConsumer
|
7
|
+
.consumer_audit_pipeline(config: config)
|
8
|
+
.invoke
|
9
|
+
end
|
10
|
+
|
11
|
+
def build_audit_config
|
12
|
+
audit_config = NulogyMessageBusConsumer.config.dup
|
13
|
+
audit_config.consumer_group_id = "#{audit_config.consumer_group_id}_consumer_audit"
|
14
|
+
NulogyMessageBusConsumer.config
|
15
|
+
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.
|
4
|
+
version: 0.2.0
|
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-
|
11
|
+
date: 2020-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '5.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rdkafka
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rails
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +80,20 @@ dependencies:
|
|
66
80
|
- - '='
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: 3.9.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-rails
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 4.0.1
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 4.0.1
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: rspec-json_expectations
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,20 +137,20 @@ dependencies:
|
|
109
137
|
- !ruby/object:Gem::Version
|
110
138
|
version: 1.38.1
|
111
139
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
140
|
+
name: pg
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
114
142
|
requirements:
|
115
143
|
- - '='
|
116
144
|
- !ruby/object:Gem::Version
|
117
|
-
version: 1.
|
145
|
+
version: 1.2.3
|
118
146
|
type: :development
|
119
147
|
prerelease: false
|
120
148
|
version_requirements: !ruby/object:Gem::Requirement
|
121
149
|
requirements:
|
122
150
|
- - '='
|
123
151
|
- !ruby/object:Gem::Version
|
124
|
-
version: 1.
|
125
|
-
description:
|
152
|
+
version: 1.2.3
|
153
|
+
description:
|
126
154
|
email:
|
127
155
|
- tass@nulogy.com
|
128
156
|
executables: []
|
@@ -135,20 +163,27 @@ files:
|
|
135
163
|
- lib/nulogy_message_bus_consumer.rb
|
136
164
|
- lib/nulogy_message_bus_consumer/config.rb
|
137
165
|
- lib/nulogy_message_bus_consumer/engine.rb
|
166
|
+
- lib/nulogy_message_bus_consumer/handlers/log_unprocessed_messages.rb
|
167
|
+
- lib/nulogy_message_bus_consumer/kafka_utils.rb
|
138
168
|
- lib/nulogy_message_bus_consumer/message.rb
|
169
|
+
- lib/nulogy_message_bus_consumer/null_logger.rb
|
170
|
+
- lib/nulogy_message_bus_consumer/pipeline.rb
|
139
171
|
- lib/nulogy_message_bus_consumer/processed_message.rb
|
172
|
+
- lib/nulogy_message_bus_consumer/steps/commit_on_success.rb
|
140
173
|
- lib/nulogy_message_bus_consumer/steps/connect_to_message_bus.rb
|
141
174
|
- lib/nulogy_message_bus_consumer/steps/deduplicate_messages.rb
|
142
175
|
- lib/nulogy_message_bus_consumer/steps/log_messages.rb
|
143
176
|
- lib/nulogy_message_bus_consumer/steps/monitor_replication_lag.rb
|
144
|
-
- lib/nulogy_message_bus_consumer/steps/
|
145
|
-
- lib/nulogy_message_bus_consumer/steps/
|
177
|
+
- lib/nulogy_message_bus_consumer/steps/seek_beginning_of_topic.rb
|
178
|
+
- lib/nulogy_message_bus_consumer/steps/stream_messages.rb
|
179
|
+
- lib/nulogy_message_bus_consumer/steps/stream_messages_until_none_are_left.rb
|
146
180
|
- lib/nulogy_message_bus_consumer/version.rb
|
181
|
+
- lib/tasks/engine/message_bus_consumer.rake
|
147
182
|
homepage: https://github.com/nulogy/message-bus/tree/master/gems/nulogy_message_bus_consumer
|
148
183
|
licenses: []
|
149
184
|
metadata:
|
150
185
|
allowed_push_host: https://rubygems.org/
|
151
|
-
post_install_message:
|
186
|
+
post_install_message:
|
152
187
|
rdoc_options: []
|
153
188
|
require_paths:
|
154
189
|
- lib
|
@@ -164,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
199
|
version: '0'
|
165
200
|
requirements: []
|
166
201
|
rubygems_version: 3.0.3
|
167
|
-
signing_key:
|
202
|
+
signing_key:
|
168
203
|
specification_version: 4
|
169
204
|
summary: Code for accessing the Nulogy Message Bus
|
170
205
|
test_files: []
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module NulogyMessageBusConsumer
|
2
|
-
module Steps
|
3
|
-
class ResultValidation
|
4
|
-
def call(**_)
|
5
|
-
result = yield
|
6
|
-
|
7
|
-
return result if %i[success failure].include?(result)
|
8
|
-
|
9
|
-
raise(
|
10
|
-
StandardError,
|
11
|
-
"'#{result}' is not a valid processing outcome. Must be :success or :failure"
|
12
|
-
)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|