sbmt-kafka_consumer 3.7.1 → 3.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 529772cc93b9d4d6cae27acefde83b6c14c963bc851e58a86d89d4f9c4e2c713
4
- data.tar.gz: 9302cd5e4a6986e269487fa222bc3b224570971565a5522e64c9038a5ae89464
3
+ metadata.gz: c656f9762ff03d838d3cfc7309a9117ffdeb091a5659c702cd354530561fcdbb
4
+ data.tar.gz: 4f34974051efb38a7cf5193d924a1349470685d6fd7f798be055af5bab691f1d
5
5
  SHA512:
6
- metadata.gz: 15341d8328b6442e648aa07b517c5fa49cad45a52b972d1e4a9c3512323d55d32b771701835d76aa9daa5832a2e9a6fbcd1f245e1808210fd5a006ef7ea91ba1
7
- data.tar.gz: 03f3aabd3caf71729ce0293e73d8ca087d5d9fd71454ac87b9d852d537e9922fdd6f6591e43835d08906ab1b601d99d9daa5ee29d20c90a5162df94cf72fb174
6
+ metadata.gz: 95e0b5b31b7aba962b4636d779ae3023786bea42dc5951fdcb1a51c6240d4ded7a215bf7ab1a3b48b6c6dde53759b12134c021384e2264c5961776dbda429514
7
+ data.tar.gz: c4af95c2d74dd2e56cfe0cbf5276e4c303d146fded2afca08f76dfd0b90ecc96b27ee0215d42d329b422a8f1c1d87a79f3e182e5282306ecd620aacdaa724244
data/.rubocop.yml CHANGED
@@ -28,6 +28,14 @@ RSpec/VerifiedDoubles:
28
28
  Exclude:
29
29
  - spec/**/*_spec.rb
30
30
 
31
+ RSpec/SpecFilePathFormat:
32
+ Exclude:
33
+ - spec/generators/**/*
34
+
35
+ RSpec/InstanceVariable:
36
+ Exclude:
37
+ - spec/generators/**/*
38
+
31
39
  Style/SingleLineMethods:
32
40
  Enabled: false
33
41
 
data/Appraisals CHANGED
@@ -3,11 +3,10 @@
3
3
  # See compatibility table at https://www.fastruby.io/blog/ruby/rails/versions/compatibility-table.html
4
4
 
5
5
  versions_map = {
6
- "6.1" => %w[2.7 3.0],
7
- "7.0" => %w[3.1],
8
6
  "7.1" => %w[3.2],
9
7
  "7.2" => %w[3.3],
10
- "8.0" => %w[3.3]
8
+ "8.0" => %w[3.3],
9
+ "8.1" => %w[3.4]
11
10
  }
12
11
 
13
12
  current_ruby_version = RUBY_VERSION.split(".").first(2).join(".")
data/CHANGELOG.md CHANGED
@@ -13,6 +13,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
13
13
 
14
14
  ### Fixed
15
15
 
16
+ ## [3.9.0] - 2026-05-26
17
+
18
+ ## BREAKING
19
+
20
+ - Drop support for Ruby 3.0/3.1
21
+ - Add support for Karafka 2.5
22
+
23
+ ## [3.8.0] - 2026-03-03
24
+
25
+ ### Added
26
+
27
+ - `kafka_consumer:regexp_consumer` generator for injecting a regexp-based consumer group entry into `config/kafka_consumer.yml`; offers to run `kafka_consumer:install` if the config file is missing
28
+
16
29
  ## [3.7.1] - 2026-02-17
17
30
 
18
31
  ### Fixed
data/Gemfile CHANGED
@@ -3,6 +3,3 @@
3
3
  source ENV.fetch("RUBYGEMS_PUBLIC_SOURCE", "https://rubygems.org/")
4
4
 
5
5
  gemspec
6
-
7
- # FIXME: remove this after drop support for Ruby 2.7
8
- gem "ffi", "< 1.17"
data/README.md CHANGED
@@ -53,6 +53,50 @@ To generate an Inbox consumer for use with gem [sbmt-outbox](https://github.com/
53
53
  rails g kafka_consumer:inbox_consumer MaybeNamespaced::Name some-consumer-group some-topic
54
54
  ```
55
55
 
56
+ ### Regexp consumer
57
+
58
+ To generate a regexp-topic consumer:
59
+
60
+ ```shell
61
+ rails g kafka_consumer:regexp_consumer GROUP_KEY CONSUMER_KLASS TOPIC_REGEXP --env-prefix ENV_PREFIX
62
+ ```
63
+
64
+ Where:
65
+ - `GROUP_KEY` — YAML key for the consumer group (e.g. `order`)
66
+ - `CONSUMER_KLASS` — consumer class name (e.g. `MyApp::OrderConsumer`)
67
+ - `TOPIC_REGEXP` — topic regexp (e.g. `'my\.app\.order(\.\d+)?$'`)
68
+ - `--env-prefix` (required) — prefix for the `ENV_PREFIX_CONSUMER_GROUP_NAME` and `ENV_PREFIX_TOPIC_REGEXP` environment variables
69
+ - `--init-attrs key:value ...` — optional consumer `init_attrs` as `key:value` pairs; boolean values (`true`/`false`) are emitted unquoted
70
+ - `--deserializer-klass` — optional deserializer class; omit to skip the `deserializer:` section
71
+
72
+ If `config/kafka_consumer.yml` does not exist, the generator will offer to run `kafka_consumer:install` first.
73
+
74
+ Examples:
75
+
76
+ ```shell
77
+ # Consumer with init_attrs
78
+ rails g kafka_consumer:regexp_consumer order \
79
+ "MyApp::OrderConsumer" \
80
+ 'my\.app\.order(\.\d+)?$' \
81
+ --env-prefix MY_APP_ORDER \
82
+ --init-attrs inbox_item:OrderInboxItem
83
+
84
+ # Consumer with deserializer
85
+ rails g kafka_consumer:regexp_consumer events \
86
+ "MyApp::EventsConsumer" \
87
+ 'my\.app\.events(\.\d+)?$' \
88
+ --env-prefix MY_APP_EVENTS \
89
+ --deserializer-klass "Sbmt::KafkaConsumer::Serialization::JsonDeserializer"
90
+
91
+ # Consumer with both
92
+ rails g kafka_consumer:regexp_consumer order_init \
93
+ "MyApp::OrderInitConsumer" \
94
+ 'my\.app\.order\.init(\.\d+)?$' \
95
+ --env-prefix MY_APP_ORDER_INIT \
96
+ --init-attrs envelope_schema:my.envelope data_schema:my.app.order.init skip_on_error:true \
97
+ --deserializer-klass "Sbmt::KafkaConsumer::Serialization::JsonDeserializer"
98
+ ```
99
+
56
100
  ## Manual configuration
57
101
 
58
102
  The `config/kafka_consumer.yml` file is a main configuration for the gem.
data/dip.yml CHANGED
@@ -35,14 +35,14 @@ interaction:
35
35
  subcommands:
36
36
  all:
37
37
  command: bundle exec appraisal rspec
38
- rails-6.1:
39
- command: bundle exec appraisal rails-6.1 rspec
40
- rails-7.0:
41
- command: bundle exec appraisal rails-7.0 rspec
42
38
  rails-7.1:
43
39
  command: bundle exec appraisal rails-7.1 rspec
44
40
  rails-7.2:
45
41
  command: bundle exec appraisal rails-7.2 rspec
42
+ rails-8.0:
43
+ command: bundle exec appraisal rails-8.0 rspec
44
+ rails-8.1:
45
+ command: bundle exec appraisal rails-8.1 rspec
46
46
 
47
47
  rubocop:
48
48
  description: Run Ruby linter
@@ -0,0 +1,29 @@
1
+ Description:
2
+ Injects a regexp-based consumer group entry into config/kafka_consumer.yml.
3
+ If kafka_consumer.yml does not exist, offers to run kafka_consumer:install first.
4
+
5
+ Required positional args: GROUP_KEY, CONSUMER_KLASS, TOPIC_REGEXP
6
+ Required option: --env-prefix
7
+
8
+ Example:
9
+ # Inbox consumer with init_attrs (no deserializer)
10
+ bin/rails generate kafka_consumer:regexp_consumer order \
11
+ "Ecom::EventStreaming::Kafka::RegularEventsInboxConsumer" \
12
+ 'seeker\.paas-stand\.event-streaming\.order(\.\d+)?$' \
13
+ --env-prefix ES_ORDER \
14
+ --init-attrs inbox_item:EsOrderInboxItem
15
+
16
+ # Consumer with deserializer (no init_attrs)
17
+ bin/rails generate kafka_consumer:regexp_consumer init_exports \
18
+ "Ecom::EventStreaming::Kafka::ControlRequestsConsumer" \
19
+ 'yc\.seeker\.paas-stand\.event-streaming\.control\.in(\.\d+)?' \
20
+ --env-prefix ES_CONTROL_REQUESTS \
21
+ --deserializer-klass "Sbmt::KafkaConsumer::Serialization::JsonDeserializer"
22
+
23
+ # Consumer with both init_attrs (including boolean) and deserializer
24
+ bin/rails generate kafka_consumer:regexp_consumer seeker_init_exports \
25
+ "SeekerInitEventsConsumer" \
26
+ 'seeker\.paas-stand\.event-streaming\.order\.init(\.\d+)?$' \
27
+ --env-prefix ES_SEEKER_INIT_EXPORTS \
28
+ --init-attrs envelope_schema:cloud-events.init.envelope data_schema:seeker.paas-stand.event-streaming.order.init skip_on_error:true \
29
+ --deserializer-klass "Sbmt::KafkaConsumer::Serialization::JsonDeserializer"
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/named_base"
4
+ require "generators/kafka_consumer/concerns/configuration"
5
+
6
+ module KafkaConsumer
7
+ module Generators
8
+ class RegexpConsumerGenerator < Rails::Generators::NamedBase
9
+ include Concerns::Configuration
10
+
11
+ source_root File.expand_path("templates", __dir__)
12
+
13
+ desc "Injects a regexp-based consumer group entry into config/kafka_consumer.yml"
14
+
15
+ argument :consumer_klass, type: :string,
16
+ desc: "Consumer class name (e.g. Ecom::EventStreaming::Kafka::RegularEventsInboxConsumer)"
17
+
18
+ argument :topic_regexp, type: :string,
19
+ desc: "Topic regexp value (e.g. 'seeker\\.paas-stand\\.event-streaming\\.order(\\.\\d+)?\\$')"
20
+
21
+ class_option :env_prefix, type: :string, required: true,
22
+ desc: "ENV variable prefix for CONSUMER_GROUP_NAME and TOPIC_REGEXP (e.g. ES_ORDER)"
23
+
24
+ class_option :init_attrs, type: :hash, default: {},
25
+ banner: "key:value key:value",
26
+ desc: "Consumer init_attrs as key:value pairs (e.g. inbox_item:Foo skip_on_error:true)"
27
+
28
+ class_option :deserializer_klass, type: :string, default: nil,
29
+ desc: "Deserializer class (omit to skip deserializer section)"
30
+
31
+ def inject_consumer_group
32
+ check_config_file!
33
+ insert_into_file CONFIG_PATH, consumer_group_entry, after: "consumer_groups:\n"
34
+ end
35
+
36
+ private
37
+
38
+ # Override to resolve path relative to destination_root (works in both
39
+ # app context and generator tests with a tmpdir destination_root).
40
+ def check_config_file!
41
+ return if File.exist?(File.join(destination_root, CONFIG_PATH))
42
+
43
+ generator_name = "kafka_consumer:install"
44
+ answer = ask("The file #{CONFIG_PATH} does not appear to exist. Would you like to generate it? [Yn]")
45
+ if (answer.presence || "y").casecmp("y").zero?
46
+ generate generator_name
47
+ else
48
+ raise Rails::Generators::Error,
49
+ "Please generate #{CONFIG_PATH} by running `bin/rails g #{generator_name}` or add this file manually."
50
+ end
51
+ end
52
+
53
+ def group_key
54
+ file_name
55
+ end
56
+
57
+ def env_prefix
58
+ options[:env_prefix]
59
+ end
60
+
61
+ def init_attrs
62
+ options[:init_attrs]
63
+ end
64
+
65
+ def deserializer_klass
66
+ options[:deserializer_klass]
67
+ end
68
+
69
+ def format_attr_value(value)
70
+ (value == "true" || value == "false") ? value : "\"#{value}\""
71
+ end
72
+
73
+ def consumer_group_entry
74
+ template_path = File.join(self.class.source_root, "consumer_group.yml.erb")
75
+ ERB.new(File.read(template_path), trim_mode: "%-").result(binding)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,16 @@
1
+ '<%= group_key %>':
2
+ name: <%%= ENV.fetch("<%= env_prefix %>_CONSUMER_GROUP_NAME", "<%= group_key %>") %><%%= ENV.fetch("CONSUMER_GROUP_SUFFIX", "") %>
3
+ topics:
4
+ - regexp: <%%= ENV.fetch("<%= env_prefix %>_TOPIC_REGEXP", '<%= topic_regexp %>') %>
5
+ consumer:
6
+ klass: "<%= consumer_klass %>"
7
+ <%- unless init_attrs.empty? -%>
8
+ init_attrs:
9
+ <%- init_attrs.each do |key, value| -%>
10
+ <%= key %>: <%= format_attr_value(value) %>
11
+ <%- end -%>
12
+ <%- end -%>
13
+ <%- if deserializer_klass -%>
14
+ deserializer:
15
+ klass: "<%= deserializer_klass %>"
16
+ <%- end -%>
@@ -12,7 +12,12 @@ RSpec.shared_context "with sbmt karafka consumer" do
12
12
  instance
13
13
  }
14
14
  let(:test_consumer_group) { Karafka::Routing::ConsumerGroup.new(:test_group) }
15
- let(:test_topic) { Karafka::Routing::Topic.new(:test_topic, test_consumer_group) }
15
+ let(:test_topic) do
16
+ topic = Karafka::Routing::Topic.new(:test_topic, test_consumer_group)
17
+ topic.subscription_group_details = test_consumer_group.current_subscription_group_details
18
+ topic
19
+ end
20
+ let(:test_topics) { Karafka::Routing::Topics.new([test_topic]) }
16
21
  let(:kafka_client) { instance_double(Karafka::Connection::Client) }
17
22
  let(:null_deserializer) { Sbmt::KafkaConsumer::Serialization::NullDeserializer.new }
18
23
  let(:client_configurer_options) { {skip_regexp_consumers_init: true} }
@@ -22,6 +27,7 @@ RSpec.shared_context "with sbmt karafka consumer" do
22
27
 
23
28
  before {
24
29
  Sbmt::KafkaConsumer::ClientConfigurer.configure!(**client_configurer_options)
30
+ test_consumer_group.subscription_groups_builder.call(test_topics)
25
31
  allow(kafka_client).to receive(:assignment_lost?).and_return(false)
26
32
  allow(kafka_client).to receive(:mark_as_consumed!).and_return(true)
27
33
  allow(kafka_client).to receive(:mark_as_consumed).and_return(true)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sbmt
4
4
  module KafkaConsumer
5
- VERSION = "3.7.1"
5
+ VERSION = "3.9.0"
6
6
  end
7
7
  end
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = "Ruby gem for consuming Kafka messages"
12
12
  spec.description = "This gem is used for consuming Kafka messages. It represents a wrapper over Karafka gem and is recommended for using as a transport with sbmt-outbox"
13
13
  spec.homepage = "https://github.com/Kuper-Tech/sbmt-kafka_consumer"
14
- spec.required_ruby_version = ">= 3.0.0"
14
+ spec.required_ruby_version = ">= 3.2.0"
15
15
 
16
16
  spec.metadata["allowed_push_host"] = ENV.fetch("NEXUS_URL", "https://rubygems.org")
17
17
 
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
33
33
 
34
34
  spec.add_dependency "rails", ">= 6.1"
35
35
  spec.add_dependency "zeitwerk", "~> 2.3"
36
- spec.add_dependency "karafka", "~> 2.4.0"
36
+ spec.add_dependency "karafka", "~> 2.5.1"
37
37
  spec.add_dependency "yabeda", ">= 0.11"
38
38
  spec.add_dependency "anyway_config", ">= 2.4.0"
39
39
  spec.add_dependency "thor"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sbmt-kafka_consumer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.1
4
+ version: 3.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kuper Ruby-Platform Team
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2026-02-17 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
@@ -44,14 +43,14 @@ dependencies:
44
43
  requirements:
45
44
  - - "~>"
46
45
  - !ruby/object:Gem::Version
47
- version: 2.4.0
46
+ version: 2.5.1
48
47
  type: :runtime
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - "~>"
53
52
  - !ruby/object:Gem::Version
54
- version: 2.4.0
53
+ version: 2.5.1
55
54
  - !ruby/object:Gem::Dependency
56
55
  name: yabeda
57
56
  requirement: !ruby/object:Gem::Requirement
@@ -460,7 +459,6 @@ dependencies:
460
459
  version: '0'
461
460
  description: This gem is used for consuming Kafka messages. It represents a wrapper
462
461
  over Karafka gem and is recommended for using as a transport with sbmt-outbox
463
- email:
464
462
  executables:
465
463
  - kafka_consumer
466
464
  extensions: []
@@ -492,6 +490,9 @@ files:
492
490
  - lib/generators/kafka_consumer/install/install_generator.rb
493
491
  - lib/generators/kafka_consumer/install/templates/Kafkafile
494
492
  - lib/generators/kafka_consumer/install/templates/kafka_consumer.yml
493
+ - lib/generators/kafka_consumer/regexp_consumer/USAGE
494
+ - lib/generators/kafka_consumer/regexp_consumer/regexp_consumer_generator.rb
495
+ - lib/generators/kafka_consumer/regexp_consumer/templates/consumer_group.yml.erb
495
496
  - lib/sbmt/kafka_consumer.rb
496
497
  - lib/sbmt/kafka_consumer/app_initializer.rb
497
498
  - lib/sbmt/kafka_consumer/base_consumer.rb
@@ -555,7 +556,6 @@ metadata:
555
556
  source_code_uri: https://github.com/Kuper-Tech/sbmt-kafka_consumer
556
557
  changelog_uri: https://github.com/Kuper-Tech/sbmt-kafka_consumer/blob/master/CHANGELOG.md
557
558
  rubygems_mfa_required: 'false'
558
- post_install_message:
559
559
  rdoc_options: []
560
560
  require_paths:
561
561
  - lib
@@ -563,15 +563,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
563
563
  requirements:
564
564
  - - ">="
565
565
  - !ruby/object:Gem::Version
566
- version: 3.0.0
566
+ version: 3.2.0
567
567
  required_rubygems_version: !ruby/object:Gem::Requirement
568
568
  requirements:
569
569
  - - ">="
570
570
  - !ruby/object:Gem::Version
571
571
  version: '0'
572
572
  requirements: []
573
- rubygems_version: 3.3.7
574
- signing_key:
573
+ rubygems_version: 3.6.9
575
574
  specification_version: 4
576
575
  summary: Ruby gem for consuming Kafka messages
577
576
  test_files: []