deimos-ruby 2.4.0.pre.beta13 → 2.4.0.pre.beta14

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: 0f50e61a736a80abdd3ccf4b19023fc4eb98401f35e807024f04e2527eed79bb
4
- data.tar.gz: 06d50876e2eddad38af3fc47f2fee14c7561b3844282499d66fde07b411cdb9c
3
+ metadata.gz: 0e7b5d2bdf8cccca9230dd94d03d806d6049b8e83c79544742a582adf80e8e2a
4
+ data.tar.gz: 1006fd3b7ede588433731881e3e7cfbb9f8536183922dfb7805972a55151e4f5
5
5
  SHA512:
6
- metadata.gz: 6ecbc0f494b10201762a0d868db56bc0d7be33453dbfbc2e52cce5256b35ea102381c93f13d5437839c23311f62685cd2a7e134546e0a8d3aaef4f30c59ec7c9
7
- data.tar.gz: 4a3ab37d362e785c16ef34739efbba32a66edfb5bb08a59f08b9646ac310849fe755369cf03d0e45aa5a85478ba1d6a4e620bed9887cdd589f87a6e348c0f96d
6
+ metadata.gz: f3e63d30275bdc6b162f2afbd566c6701d75923e64c9b906b19c8bc8e79fabc7b4121cb75644937a1d127c93fe6c1c9778135ed335d1214fa2ac2a481ee7526c
7
+ data.tar.gz: 67a0e9fc9981ff1c32cd904b626f3c55c2fbd0aadf1ab6f5d808846a70fc0fe65745c5b8a12b5bf59730aba214b67696a33712684a900a922f6de85feaaf5dfd
data/CHANGELOG.md CHANGED
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  ## UNRELEASED
9
9
 
10
10
  - Major change: Switch from using `avro_turf` and `proto_turf` to use `schema_registry_client`, which handles both Avro and Protobuf.
11
+ - Add `registry_url`, `registry_user` and `registry_password` per-topic configuration.
11
12
  - Added `have_sent_including` RSpec matcher to allow for Protobuf messages that use default values to be checked.
12
13
 
13
14
  # 2.3.0 - 2026-01-13
@@ -117,6 +117,9 @@ The following are additional settings that can be added to the `topic` block in
117
117
  | namespace | nil | Namespace of the schema to use when finding it locally. Leave blank for protobuf. |
118
118
  | key_config | nil | Configuration hash for message keys. See [Kafka Message Keys](../README.md#kafka-message-keys). |
119
119
  | use_schema_classes | nil | Set to true or false to enable or disable using the producers schema classes. See [Generated Schema Classes](../README.md#generated-schema-classes). |
120
+ | registry_url | nil | URL of the schema registry to use for this topic. Overrides the global `schema.registry_url` setting. |
121
+ | registry_user | nil | Basic auth user for the schema registry to use for this topic. Overrides the global `schema.user` setting. |
122
+ | registry_password | nil | Basic auth password for the schema registry to use for this topic. Overrides the global `schema.password` setting. |
120
123
 
121
124
  ### Consumer Settings
122
125
 
@@ -13,6 +13,9 @@ module Deimos
13
13
  namespace: nil,
14
14
  key_config: { none: true },
15
15
  schema_backend: nil,
16
+ registry_url: nil,
17
+ registry_user: nil,
18
+ registry_password: nil,
16
19
  use_schema_classes: nil
17
20
  }.each do |field, default|
18
21
  define_method(field) do |*args|
@@ -25,20 +28,31 @@ module Deimos
25
28
  @_deimos_config[:schema][field] || default
26
29
  end
27
30
  end
28
- def _deimos_setup_transcoders # rubocop:disable Metrics/AbcSize
31
+ def _deimos_setup_transcoders
29
32
  use_classes = if use_schema_classes.nil?
30
33
  Deimos.config.schema.use_schema_classes
31
34
  else
32
35
  use_schema_classes
33
36
  end
37
+ registry_info = if registry_url
38
+ Deimos::RegistryInfo.new(registry_url, registry_user, registry_password)
39
+ else
40
+ nil
41
+ end
34
42
  payload = Transcoder.new(
35
43
  schema: schema,
36
44
  namespace: namespace,
37
45
  backend: schema_backend,
38
46
  use_schema_classes: use_classes,
39
- topic: name
47
+ topic: name,
48
+ registry_info: registry_info
40
49
  )
41
50
 
51
+ deserializers.payload = payload
52
+ _deimos_setup_key_transcoder(use_classes, registry_info)
53
+ end
54
+
55
+ def _deimos_setup_key_transcoder(use_classes, registry_info)
42
56
  key = nil
43
57
 
44
58
  if key_config[:plain]
@@ -47,7 +61,8 @@ module Deimos
47
61
  backend: nil,
48
62
  namespace: namespace,
49
63
  use_schema_classes: use_classes,
50
- topic: name
64
+ topic: name,
65
+ registry_info: registry_info
51
66
  )
52
67
  key.backend_type = :plain
53
68
  elsif !key_config[:none]
@@ -58,7 +73,8 @@ module Deimos
58
73
  namespace: namespace,
59
74
  use_schema_classes: use_classes,
60
75
  key_field: key_config[:field].to_s,
61
- topic: name
76
+ topic: name,
77
+ registry_info: registry_info
62
78
  )
63
79
  elsif key_config[:schema]
64
80
  key = Transcoder.new(
@@ -66,13 +82,13 @@ module Deimos
66
82
  backend: schema_backend,
67
83
  namespace: namespace,
68
84
  use_schema_classes: use_classes,
69
- topic: self.name
85
+ topic: self.name,
86
+ registry_info: registry_info
70
87
  )
71
88
  else
72
89
  raise 'No key config given - if you are not encoding keys, please use `key_config plain: true`'
73
90
  end
74
91
  end
75
- deserializers.payload = payload
76
92
  deserializers.key = key if key
77
93
  end
78
94
  end
@@ -11,7 +11,7 @@ module Deimos
11
11
  attr_accessor :schema_store
12
12
 
13
13
  # @override
14
- def initialize(schema:, namespace:)
14
+ def initialize(schema:, namespace:, registry_info: nil)
15
15
  super
16
16
  @schema_store = SchemaRegistry::AvroSchemaStore.new(path: Deimos.config.schema.path)
17
17
  end
@@ -21,10 +21,10 @@ module Deimos
21
21
  # @return [SchemaRegistry::Client]
22
22
  def schema_registry
23
23
  @schema_registry ||= SchemaRegistry::Client.new(
24
- registry_url: Deimos.config.schema.registry_url,
24
+ registry_url: @registry_info&.url || Deimos.config.schema.registry_url,
25
25
  logger: Karafka.logger,
26
- user: Deimos.config.schema.user,
27
- password: Deimos.config.schema.password,
26
+ user: @registry_info&.user || Deimos.config.schema.user,
27
+ password: @registry_info&.password || Deimos.config.schema.password,
28
28
  schema_type: SchemaRegistry::Schema::Avro.new(schema_store: @schema_store)
29
29
  )
30
30
  @schema_registry
@@ -24,6 +24,24 @@ module Deimos
24
24
  end
25
25
  end
26
26
 
27
+ class RegistryInfo
28
+ # @return [String]
29
+ attr_accessor :url
30
+ # @return [String]
31
+ attr_accessor :user
32
+ # @return [String]
33
+ attr_accessor :password
34
+
35
+ # @param url [String]
36
+ # @param user [String,nil]
37
+ # @param password [String,nil]
38
+ def initialize(url, user, password)
39
+ @url = url
40
+ @user = user
41
+ @password = password
42
+ end
43
+ end
44
+
27
45
  module SchemaBackends
28
46
  # Base class for encoding / decoding.
29
47
  class Base
@@ -33,12 +51,15 @@ module Deimos
33
51
  attr_accessor :namespace
34
52
  # @return [String]
35
53
  attr_accessor :key_schema
54
+ # @return [RegistryInfo]
55
+ attr_accessor :registry_info
36
56
 
37
57
  # @param schema [String,Symbol]
38
58
  # @param namespace [String]
39
- def initialize(schema:, namespace: nil)
59
+ def initialize(schema:, namespace: nil, registry_info: nil)
40
60
  @schema = schema
41
61
  @namespace = namespace
62
+ @registry_info = registry_info
42
63
  end
43
64
 
44
65
  # @return [String]
@@ -48,9 +48,9 @@ module Deimos
48
48
 
49
49
  def self.key_schema_registry
50
50
  @key_schema_registry ||= SchemaRegistry::Client.new(
51
- registry_url: Deimos.config.schema.registry_url,
52
- user: Deimos.config.schema.user,
53
- password: Deimos.config.schema.password,
51
+ registry_url: @registry_info&.url || Deimos.config.schema.registry_url,
52
+ user: @registry_info&.user || Deimos.config.schema.user,
53
+ password: @registry_info&.password || Deimos.config.schema.password,
54
54
  logger: Karafka.logger,
55
55
  schema_type: SchemaRegistry::Schema::ProtoJsonSchema.new
56
56
  )
@@ -13,19 +13,22 @@ module Deimos
13
13
  # @param use_schema_classes [Boolean]
14
14
  # @param backend [Symbol]
15
15
  # @param topic [String]
16
- def initialize(schema:, namespace:, key_field: nil, use_schema_classes: nil, topic: nil, backend: nil)
16
+ def initialize(schema:, namespace:, key_field: nil, use_schema_classes: nil, topic: nil, backend: nil,
17
+ registry_info: nil)
17
18
  @schema = schema
18
19
  @namespace = namespace
19
20
  self.key_field = key_field
20
21
  @use_schema_classes = use_schema_classes
21
22
  @backend_type = backend
22
23
  @topic = topic
24
+ @registry_info = registry_info
23
25
  end
24
26
 
25
27
  # @return [Class<Deimos::SchemaBackends::Base>]
26
28
  def backend
27
29
  @backend ||= Deimos.schema_backend(schema: @schema,
28
30
  namespace: @namespace,
31
+ registry_info: @registry_info,
29
32
  backend: @backend_type)
30
33
  end
31
34
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Deimos
4
- VERSION = '2.4.0-beta13'
4
+ VERSION = '2.4.0-beta14'
5
5
  end
data/lib/deimos.rb CHANGED
@@ -76,29 +76,50 @@ module Deimos
76
76
  # @return [SchemaBackends::Base]
77
77
  def schema_backend_for(topic_name)
78
78
  config = Deimos.karafka_config_for(topic: topic_name)
79
+ registry_info = if config.registry_url
80
+ Deimos::RegistryInfo.new(
81
+ config.registry_url,
82
+ config.registry_user,
83
+ config.registry_password
84
+ )
85
+ else
86
+ nil
87
+ end
79
88
  self.schema_backend(schema: config.schema,
80
89
  namespace: config.namespace,
90
+ registry_info: registry_info,
81
91
  backend: config.schema_backend || Deimos.config.schema.backend)
82
92
  end
83
93
 
84
94
  # @param schema [String, Symbol]
85
95
  # @param namespace [String]
96
+ # @param registry_info [Deimos::RegistryInfo]
86
97
  # @return [Deimos::SchemaBackends::Base]
87
- def schema_backend(schema:, namespace:, backend: Deimos.config.schema.backend)
98
+ def schema_backend(schema:, namespace:,
99
+ registry_info: nil,
100
+ backend: Deimos.config.schema.backend)
88
101
  if config.schema.use_schema_classes
89
102
  # Initialize an instance of the provided schema
90
103
  # in the event the schema class is an override, the inherited
91
104
  # schema and namespace will be applied
92
105
  schema_class = Utils::SchemaClass.klass(schema, namespace)
93
106
  if schema_class.nil?
94
- schema_backend_class(backend: backend).new(schema: schema, namespace: namespace)
107
+ schema_backend_class(backend: backend).
108
+ new(
109
+ schema: schema,
110
+ namespace: namespace,
111
+ registry_info: registry_info
112
+ )
95
113
  else
96
114
  schema_instance = schema_class.allocate
97
115
  schema_backend_class(backend: backend).
98
- new(schema: schema_instance.schema, namespace: schema_instance.namespace)
116
+ new(schema: schema_instance.schema,
117
+ namespace: schema_instance.namespace,
118
+ registry_info: registry_info)
99
119
  end
100
120
  else
101
- schema_backend_class(backend: backend).new(schema: schema, namespace: namespace)
121
+ schema_backend_class(backend: backend).
122
+ new(schema: schema, namespace: namespace, registry_info: registry_info)
102
123
  end
103
124
  end
104
125
 
data/spec/deimos_spec.rb CHANGED
@@ -126,6 +126,42 @@ describe Deimos do
126
126
  backend = described_class.schema_backend_for('backend-test-topic-global')
127
127
  expect(backend).to be_a(Deimos::SchemaBackends::AvroValidation)
128
128
  end
129
+
130
+ it 'should use topic-specific registry configuration' do
131
+ Karafka::App.routes.redraw do
132
+ topic 'backend-test-topic-registry' do
133
+ active false
134
+ schema 'MySchema'
135
+ namespace 'com.my-namespace'
136
+ key_config none: true
137
+ registry_url 'http://topic-specific-registry:8081'
138
+ registry_user 'topic-user'
139
+ registry_password 'topic-password'
140
+ end
141
+ end
142
+
143
+ backend = described_class.schema_backend_for('backend-test-topic-registry')
144
+ # Backend will be AvroValidation in test mode, but should have registry_info
145
+ expect(backend.registry_info).not_to be_nil
146
+ expect(backend.registry_info.url).to eq('http://topic-specific-registry:8081')
147
+ expect(backend.registry_info.user).to eq('topic-user')
148
+ expect(backend.registry_info.password).to eq('topic-password')
149
+ end
150
+
151
+ it 'should create backend with nil registry_info when not specified' do
152
+ Karafka::App.routes.redraw do
153
+ topic 'backend-test-topic-no-registry' do
154
+ active false
155
+ schema 'MySchema'
156
+ namespace 'com.my-namespace'
157
+ key_config none: true
158
+ end
159
+ end
160
+
161
+ backend = described_class.schema_backend_for('backend-test-topic-no-registry')
162
+ # registry_info should be nil when not specified in topic config
163
+ expect(backend.registry_info).to be_nil
164
+ end
129
165
  end
130
166
 
131
167
  describe '#schema_backend_class with mock_backends' do
@@ -76,6 +76,58 @@ RSpec.describe Karafka::Routing::Topic do
76
76
  expect('MyTopic').to have_sent({ test_id: 'id1', some_int: 5 }, { test_id: 'id3' })
77
77
  end
78
78
 
79
+ it 'should work with custom registry configuration' do
80
+ KarafkaApp.routes.draw do
81
+ topic 'MyTopic' do
82
+ producer_class MyProducer
83
+ schema 'MySchema'
84
+ namespace 'com.my-namespace'
85
+ key_config(none: true)
86
+ registry_url 'http://custom-registry:8081'
87
+ registry_user 'custom-user'
88
+ registry_password 'custom-password'
89
+ end
90
+ end
91
+
92
+ # Verify the topic configuration has the registry settings
93
+ topic_config = Deimos.karafka_config_for(topic: 'MyTopic')
94
+ expect(topic_config.registry_url).to eq('http://custom-registry:8081')
95
+ expect(topic_config.registry_user).to eq('custom-user')
96
+ expect(topic_config.registry_password).to eq('custom-password')
97
+
98
+ # Verify schema_backend_for uses the custom registry settings
99
+ backend = Deimos.schema_backend_for('MyTopic')
100
+ expect(backend.registry_info).not_to be_nil
101
+ expect(backend.registry_info.url).to eq('http://custom-registry:8081')
102
+ expect(backend.registry_info.user).to eq('custom-user')
103
+ expect(backend.registry_info.password).to eq('custom-password')
104
+ end
105
+
106
+ it 'should work with partial registry configuration' do
107
+ KarafkaApp.routes.draw do
108
+ topic 'MyTopic' do
109
+ producer_class MyProducer
110
+ schema 'MySchema'
111
+ namespace 'com.my-namespace'
112
+ key_config(none: true)
113
+ registry_url 'http://custom-registry:8081'
114
+ # No user or password specified
115
+ end
116
+ end
117
+
118
+ topic_config = Deimos.karafka_config_for(topic: 'MyTopic')
119
+ expect(topic_config.registry_url).to eq('http://custom-registry:8081')
120
+ expect(topic_config.registry_user).to be_nil
121
+ expect(topic_config.registry_password).to be_nil
122
+
123
+ # Verify schema_backend_for creates registry_info with nil user/password
124
+ backend = Deimos.schema_backend_for('MyTopic')
125
+ expect(backend.registry_info).not_to be_nil
126
+ expect(backend.registry_info.url).to eq('http://custom-registry:8081')
127
+ expect(backend.registry_info.user).to be_nil
128
+ expect(backend.registry_info.password).to be_nil
129
+ end
130
+
79
131
  end
80
132
 
81
133
  it 'should be able to pick up a consumer' do
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Deimos::RegistryInfo do
4
+ describe '#initialize' do
5
+ it 'should initialize with url, user, and password' do
6
+ registry_info = described_class.new('http://localhost:8081', 'user1', 'pass1')
7
+ expect(registry_info.url).to eq('http://localhost:8081')
8
+ expect(registry_info.user).to eq('user1')
9
+ expect(registry_info.password).to eq('pass1')
10
+ end
11
+
12
+ it 'should allow nil user and password' do
13
+ registry_info = described_class.new('http://localhost:8081', nil, nil)
14
+ expect(registry_info.url).to eq('http://localhost:8081')
15
+ expect(registry_info.user).to be_nil
16
+ expect(registry_info.password).to be_nil
17
+ end
18
+
19
+ it 'should allow setting attributes' do
20
+ registry_info = described_class.new('http://localhost:8081', 'user1', 'pass1')
21
+ registry_info.url = 'http://newhost:8081'
22
+ registry_info.user = 'user2'
23
+ registry_info.password = 'pass2'
24
+
25
+ expect(registry_info.url).to eq('http://newhost:8081')
26
+ expect(registry_info.user).to eq('user2')
27
+ expect(registry_info.password).to eq('pass2')
28
+ end
29
+ end
30
+ end
@@ -28,4 +28,26 @@ RSpec.describe Deimos::SchemaBackends::AvroSchemaRegistry do
28
28
  with('encoded-payload')
29
29
  end
30
30
 
31
+ describe 'with registry_info' do
32
+ let(:registry_info) do
33
+ Deimos::RegistryInfo.new('http://custom-registry:8081', 'custom-user', 'custom-password')
34
+ end
35
+ let(:backend_with_registry) do
36
+ described_class.new(schema: 'MySchema', namespace: 'com.my-namespace', registry_info: registry_info)
37
+ end
38
+
39
+ it 'should store registry_info when provided' do
40
+ expect(backend_with_registry.registry_info).to eq(registry_info)
41
+ expect(backend_with_registry.registry_info.url).to eq('http://custom-registry:8081')
42
+ expect(backend_with_registry.registry_info.user).to eq('custom-user')
43
+ expect(backend_with_registry.registry_info.password).to eq('custom-password')
44
+ end
45
+
46
+ it 'should have nil registry_info when not provided' do
47
+ backend_without_registry = described_class.new(schema: 'MySchema', namespace: 'com.my-namespace',
48
+ registry_info: nil)
49
+ expect(backend_without_registry.registry_info).to be_nil
50
+ end
51
+ end
52
+
31
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deimos-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0.pre.beta13
4
+ version: 2.4.0.pre.beta14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner
@@ -597,6 +597,7 @@ files:
597
597
  - spec/protos/sample/v1/sample.proto
598
598
  - spec/protos/sample/v1/sample_key.proto
599
599
  - spec/rake_spec.rb
600
+ - spec/registry_info_spec.rb
600
601
  - spec/schema_backends/avro_base_shared.rb
601
602
  - spec/schema_backends/avro_local_spec.rb
602
603
  - spec/schema_backends/avro_schema_registry_spec.rb