karafka-rdkafka 0.14.0 → 0.14.1
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
- checksums.yaml.gz.sig +0 -0
- data/.github/FUNDING.yml +1 -0
- data/CHANGELOG.md +104 -96
- data/README.md +32 -22
- data/docker-compose.yml +2 -0
- data/lib/rdkafka/admin/acl_binding_result.rb +37 -0
- data/lib/rdkafka/admin/create_acl_handle.rb +28 -0
- data/lib/rdkafka/admin/create_acl_report.rb +24 -0
- data/lib/rdkafka/admin/delete_acl_handle.rb +30 -0
- data/lib/rdkafka/admin/delete_acl_report.rb +23 -0
- data/lib/rdkafka/admin/delete_groups_handle.rb +28 -0
- data/lib/rdkafka/admin/delete_groups_report.rb +24 -0
- data/lib/rdkafka/admin/describe_acl_handle.rb +30 -0
- data/lib/rdkafka/admin/describe_acl_report.rb +23 -0
- data/lib/rdkafka/admin.rb +377 -0
- data/lib/rdkafka/bindings.rb +108 -0
- data/lib/rdkafka/callbacks.rb +167 -0
- data/lib/rdkafka/consumer/headers.rb +1 -1
- data/lib/rdkafka/consumer/topic_partition_list.rb +8 -7
- data/lib/rdkafka/consumer.rb +18 -18
- data/lib/rdkafka/error.rb +13 -2
- data/lib/rdkafka/producer.rb +2 -2
- data/lib/rdkafka/version.rb +1 -1
- data/lib/rdkafka.rb +9 -0
- data/spec/rdkafka/admin/create_acl_handle_spec.rb +56 -0
- data/spec/rdkafka/admin/create_acl_report_spec.rb +18 -0
- data/spec/rdkafka/admin/delete_acl_handle_spec.rb +85 -0
- data/spec/rdkafka/admin/delete_acl_report_spec.rb +71 -0
- data/spec/rdkafka/admin/describe_acl_handle_spec.rb +85 -0
- data/spec/rdkafka/admin/describe_acl_report_spec.rb +72 -0
- data/spec/rdkafka/admin_spec.rb +204 -0
- data/spec/rdkafka/consumer_spec.rb +9 -0
- data/spec/rdkafka/producer_spec.rb +0 -35
- data/spec/spec_helper.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +24 -2
- metadata.gz.sig +0 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Rdkafka::Admin::DescribeAclHandle do
|
6
|
+
let(:response) { Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR }
|
7
|
+
let(:resource_name) {"acl-test-topic"}
|
8
|
+
let(:resource_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_TOPIC}
|
9
|
+
let(:resource_pattern_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL}
|
10
|
+
let(:principal) {"User:anonymous"}
|
11
|
+
let(:host) {"*"}
|
12
|
+
let(:operation) {Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_READ}
|
13
|
+
let(:permission_type) {Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW}
|
14
|
+
let(:describe_acl_ptr) {FFI::Pointer::NULL}
|
15
|
+
|
16
|
+
subject do
|
17
|
+
error_buffer = FFI::MemoryPointer.from_string(" " * 256)
|
18
|
+
describe_acl_ptr = Rdkafka::Bindings.rd_kafka_AclBinding_new(
|
19
|
+
resource_type,
|
20
|
+
FFI::MemoryPointer.from_string(resource_name),
|
21
|
+
resource_pattern_type,
|
22
|
+
FFI::MemoryPointer.from_string(principal),
|
23
|
+
FFI::MemoryPointer.from_string(host),
|
24
|
+
operation,
|
25
|
+
permission_type,
|
26
|
+
error_buffer,
|
27
|
+
256
|
28
|
+
)
|
29
|
+
if describe_acl_ptr.null?
|
30
|
+
raise Rdkafka::Config::ConfigError.new(error_buffer.read_string)
|
31
|
+
end
|
32
|
+
pointer_array = [describe_acl_ptr]
|
33
|
+
describe_acls_array_ptr = FFI::MemoryPointer.new(:pointer)
|
34
|
+
describe_acls_array_ptr.write_array_of_pointer(pointer_array)
|
35
|
+
Rdkafka::Admin::DescribeAclHandle.new.tap do |handle|
|
36
|
+
handle[:pending] = pending_handle
|
37
|
+
handle[:response] = response
|
38
|
+
handle[:response_string] = FFI::MemoryPointer.from_string("")
|
39
|
+
handle[:acls] = describe_acls_array_ptr
|
40
|
+
handle[:acls_count] = 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
after do
|
45
|
+
if describe_acl_ptr != FFI::Pointer::NULL
|
46
|
+
Rdkafka::Bindings.rd_kafka_AclBinding_destroy(describe_acl_ptr)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#wait" do
|
51
|
+
let(:pending_handle) { true }
|
52
|
+
|
53
|
+
it "should wait until the timeout and then raise an error" do
|
54
|
+
expect {
|
55
|
+
subject.wait(max_wait_timeout: 0.1)
|
56
|
+
}.to raise_error Rdkafka::Admin::DescribeAclHandle::WaitTimeoutError, /describe acl/
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when not pending anymore and no error" do
|
60
|
+
let(:pending_handle) { false }
|
61
|
+
|
62
|
+
it "should return a describe acl report" do
|
63
|
+
report = subject.wait
|
64
|
+
|
65
|
+
expect(report.acls.length).to eq(1)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should wait without a timeout" do
|
69
|
+
report = subject.wait(max_wait_timeout: nil)
|
70
|
+
|
71
|
+
expect(report.acls[0].matching_acl_resource_name).to eq("acl-test-topic")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#raise_error" do
|
77
|
+
let(:pending_handle) { false }
|
78
|
+
|
79
|
+
it "should raise the appropriate error" do
|
80
|
+
expect {
|
81
|
+
subject.raise_error
|
82
|
+
}.to raise_exception(Rdkafka::RdkafkaError, /Success \(no_error\)/)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Rdkafka::Admin::DescribeAclReport do
|
6
|
+
|
7
|
+
let(:resource_name) {"acl-test-topic"}
|
8
|
+
let(:resource_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_TOPIC}
|
9
|
+
let(:resource_pattern_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL}
|
10
|
+
let(:principal) {"User:anonymous"}
|
11
|
+
let(:host) {"*"}
|
12
|
+
let(:operation) {Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_READ}
|
13
|
+
let(:permission_type) {Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW}
|
14
|
+
let(:describe_acl_ptr) {FFI::Pointer::NULL}
|
15
|
+
|
16
|
+
subject do
|
17
|
+
error_buffer = FFI::MemoryPointer.from_string(" " * 256)
|
18
|
+
describe_acl_ptr = Rdkafka::Bindings.rd_kafka_AclBinding_new(
|
19
|
+
resource_type,
|
20
|
+
FFI::MemoryPointer.from_string(resource_name),
|
21
|
+
resource_pattern_type,
|
22
|
+
FFI::MemoryPointer.from_string(principal),
|
23
|
+
FFI::MemoryPointer.from_string(host),
|
24
|
+
operation,
|
25
|
+
permission_type,
|
26
|
+
error_buffer,
|
27
|
+
256
|
28
|
+
)
|
29
|
+
if describe_acl_ptr.null?
|
30
|
+
raise Rdkafka::Config::ConfigError.new(error_buffer.read_string)
|
31
|
+
end
|
32
|
+
pointer_array = [describe_acl_ptr]
|
33
|
+
describe_acls_array_ptr = FFI::MemoryPointer.new(:pointer)
|
34
|
+
describe_acls_array_ptr.write_array_of_pointer(pointer_array)
|
35
|
+
Rdkafka::Admin::DescribeAclReport.new(acls: describe_acls_array_ptr, acls_count: 1)
|
36
|
+
end
|
37
|
+
|
38
|
+
after do
|
39
|
+
if describe_acl_ptr != FFI::Pointer::NULL
|
40
|
+
Rdkafka::Bindings.rd_kafka_AclBinding_destroy(describe_acl_ptr)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
it "should get matching acl resource type as Rdkafka::Bindings::RD_KAFKA_RESOURCE_TOPIC" do
|
46
|
+
expect(subject.acls[0].matching_acl_resource_type).to eq(Rdkafka::Bindings::RD_KAFKA_RESOURCE_TOPIC)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should get matching acl resource name as acl-test-topic" do
|
50
|
+
expect(subject.acls[0].matching_acl_resource_name).to eq(resource_name)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should get matching acl resource pattern type as Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL" do
|
54
|
+
expect(subject.acls[0].matching_acl_pattern_type).to eq(Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should get matching acl principal as User:anonymous" do
|
58
|
+
expect(subject.acls[0].matching_acl_principal).to eq("User:anonymous")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should get matching acl host as * " do
|
62
|
+
expect(subject.acls[0].matching_acl_host).to eq("*")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should get matching acl operation as Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_READ" do
|
66
|
+
expect(subject.acls[0].matching_acl_operation).to eq(Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_READ)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should get matching acl permission_type as Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW" do
|
70
|
+
expect(subject.acls[0].matching_acl_permission_type).to eq(Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW)
|
71
|
+
end
|
72
|
+
end
|
data/spec/rdkafka/admin_spec.rb
CHANGED
@@ -9,6 +9,10 @@ describe Rdkafka::Admin do
|
|
9
9
|
after do
|
10
10
|
# Registry should always end up being empty
|
11
11
|
expect(Rdkafka::Admin::CreateTopicHandle::REGISTRY).to be_empty
|
12
|
+
expect(Rdkafka::Admin::CreatePartitionsHandle::REGISTRY).to be_empty
|
13
|
+
expect(Rdkafka::Admin::DescribeAclHandle::REGISTRY).to be_empty
|
14
|
+
expect(Rdkafka::Admin::CreateAclHandle::REGISTRY).to be_empty
|
15
|
+
expect(Rdkafka::Admin::DeleteAclHandle::REGISTRY).to be_empty
|
12
16
|
admin.close
|
13
17
|
end
|
14
18
|
|
@@ -17,6 +21,15 @@ describe Rdkafka::Admin do
|
|
17
21
|
let(:topic_replication_factor) { 1 }
|
18
22
|
let(:topic_config) { {"cleanup.policy" => "compact", "min.cleanable.dirty.ratio" => 0.8} }
|
19
23
|
let(:invalid_topic_config) { {"cleeeeenup.policee" => "campact"} }
|
24
|
+
let(:group_name) { "test-group-#{Random.new.rand(0..1_000_000)}" }
|
25
|
+
|
26
|
+
let(:resource_name) {"acl-test-topic"}
|
27
|
+
let(:resource_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_TOPIC}
|
28
|
+
let(:resource_pattern_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL}
|
29
|
+
let(:principal) {"User:anonymous"}
|
30
|
+
let(:host) {"*"}
|
31
|
+
let(:operation) {Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_READ}
|
32
|
+
let(:permission_type) {Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW}
|
20
33
|
|
21
34
|
describe "#create_topic" do
|
22
35
|
describe "called with invalid input" do
|
@@ -200,4 +213,195 @@ describe Rdkafka::Admin do
|
|
200
213
|
expect(delete_topic_report.result_name).to eq(topic_name)
|
201
214
|
end
|
202
215
|
end
|
216
|
+
|
217
|
+
describe "#ACL tests" do
|
218
|
+
let(:non_existing_resource_name) {"non-existing-topic"}
|
219
|
+
before do
|
220
|
+
#create topic for testing acl
|
221
|
+
create_topic_handle = admin.create_topic(resource_name, topic_partition_count, topic_replication_factor)
|
222
|
+
create_topic_report = create_topic_handle.wait(max_wait_timeout: 15.0)
|
223
|
+
end
|
224
|
+
|
225
|
+
after do
|
226
|
+
#delete acl
|
227
|
+
delete_acl_handle = admin.delete_acl(resource_type: resource_type, resource_name: resource_name, resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
228
|
+
delete_acl_report = delete_acl_handle.wait(max_wait_timeout: 15.0)
|
229
|
+
|
230
|
+
#delete topic that was created for testing acl
|
231
|
+
delete_topic_handle = admin.delete_topic(resource_name)
|
232
|
+
delete_topic_report = delete_topic_handle.wait(max_wait_timeout: 15.0)
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "#create_acl" do
|
236
|
+
it "create acl for a topic that does not exist" do
|
237
|
+
# acl creation for resources that does not exist will still get created successfully.
|
238
|
+
create_acl_handle = admin.create_acl(resource_type: resource_type, resource_name: non_existing_resource_name, resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
239
|
+
create_acl_report = create_acl_handle.wait(max_wait_timeout: 15.0)
|
240
|
+
expect(create_acl_report.rdkafka_response).to eq(0)
|
241
|
+
expect(create_acl_report.rdkafka_response_string).to eq("")
|
242
|
+
|
243
|
+
# delete the acl that was created for a non existing topic"
|
244
|
+
delete_acl_handle = admin.delete_acl(resource_type: resource_type, resource_name: non_existing_resource_name, resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
245
|
+
delete_acl_report = delete_acl_handle.wait(max_wait_timeout: 15.0)
|
246
|
+
expect(delete_acl_handle[:response]).to eq(0)
|
247
|
+
expect(delete_acl_report.deleted_acls.size).to eq(1)
|
248
|
+
end
|
249
|
+
|
250
|
+
it "creates a acl for topic that was newly created" do
|
251
|
+
create_acl_handle = admin.create_acl(resource_type: resource_type, resource_name: resource_name, resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
252
|
+
create_acl_report = create_acl_handle.wait(max_wait_timeout: 15.0)
|
253
|
+
expect(create_acl_report.rdkafka_response).to eq(0)
|
254
|
+
expect(create_acl_report.rdkafka_response_string).to eq("")
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe "#describe_acl" do
|
259
|
+
it "describe acl of a topic that does not exist" do
|
260
|
+
describe_acl_handle = admin.describe_acl(resource_type: resource_type, resource_name: non_existing_resource_name, resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
261
|
+
describe_acl_report = describe_acl_handle.wait(max_wait_timeout: 15.0)
|
262
|
+
expect(describe_acl_handle[:response]).to eq(0)
|
263
|
+
expect(describe_acl_report.acls.size).to eq(0)
|
264
|
+
end
|
265
|
+
|
266
|
+
it "create acls and describe the newly created acls" do
|
267
|
+
#create_acl
|
268
|
+
create_acl_handle = admin.create_acl(resource_type: resource_type, resource_name: "test_acl_topic_1", resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
269
|
+
create_acl_report = create_acl_handle.wait(max_wait_timeout: 15.0)
|
270
|
+
expect(create_acl_report.rdkafka_response).to eq(0)
|
271
|
+
expect(create_acl_report.rdkafka_response_string).to eq("")
|
272
|
+
|
273
|
+
create_acl_handle = admin.create_acl(resource_type: resource_type, resource_name: "test_acl_topic_2", resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
274
|
+
create_acl_report = create_acl_handle.wait(max_wait_timeout: 15.0)
|
275
|
+
expect(create_acl_report.rdkafka_response).to eq(0)
|
276
|
+
expect(create_acl_report.rdkafka_response_string).to eq("")
|
277
|
+
|
278
|
+
#describe_acl
|
279
|
+
describe_acl_handle = admin.describe_acl(resource_type: Rdkafka::Bindings::RD_KAFKA_RESOURCE_ANY, resource_name: nil, resource_pattern_type: Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_ANY, principal: nil, host: nil, operation: Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_ANY, permission_type: Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ANY)
|
280
|
+
describe_acl_report = describe_acl_handle.wait(max_wait_timeout: 15.0)
|
281
|
+
expect(describe_acl_handle[:response]).to eq(0)
|
282
|
+
expect(describe_acl_report.acls.length).to eq(2)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
describe "#delete_acl" do
|
287
|
+
it "delete acl of a topic that does not exist" do
|
288
|
+
delete_acl_handle = admin.delete_acl(resource_type: resource_type, resource_name: non_existing_resource_name, resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
289
|
+
delete_acl_report = delete_acl_handle.wait(max_wait_timeout: 15.0)
|
290
|
+
expect(delete_acl_handle[:response]).to eq(0)
|
291
|
+
expect(delete_acl_report.deleted_acls.size).to eq(0)
|
292
|
+
end
|
293
|
+
|
294
|
+
it "create an acl and delete the newly created acl" do
|
295
|
+
#create_acl
|
296
|
+
create_acl_handle = admin.create_acl(resource_type: resource_type, resource_name: "test_acl_topic_1", resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
297
|
+
create_acl_report = create_acl_handle.wait(max_wait_timeout: 15.0)
|
298
|
+
expect(create_acl_report.rdkafka_response).to eq(0)
|
299
|
+
expect(create_acl_report.rdkafka_response_string).to eq("")
|
300
|
+
|
301
|
+
create_acl_handle = admin.create_acl(resource_type: resource_type, resource_name: "test_acl_topic_2", resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
302
|
+
create_acl_report = create_acl_handle.wait(max_wait_timeout: 15.0)
|
303
|
+
expect(create_acl_report.rdkafka_response).to eq(0)
|
304
|
+
expect(create_acl_report.rdkafka_response_string).to eq("")
|
305
|
+
|
306
|
+
#delete_acl - resource_name nil - to delete all acls with any resource name and matching all other filters.
|
307
|
+
delete_acl_handle = admin.delete_acl(resource_type: resource_type, resource_name: nil, resource_pattern_type: resource_pattern_type, principal: principal, host: host, operation: operation, permission_type: permission_type)
|
308
|
+
delete_acl_report = delete_acl_handle.wait(max_wait_timeout: 15.0)
|
309
|
+
expect(delete_acl_handle[:response]).to eq(0)
|
310
|
+
expect(delete_acl_report.deleted_acls.length).to eq(2)
|
311
|
+
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
describe('Group tests') do
|
317
|
+
describe "#delete_group" do
|
318
|
+
describe("with an existing group") do
|
319
|
+
let(:consumer_config) { rdkafka_consumer_config('group.id': group_name) }
|
320
|
+
let(:producer_config) { rdkafka_producer_config }
|
321
|
+
let(:producer) { producer_config.producer }
|
322
|
+
let(:consumer) { consumer_config.consumer }
|
323
|
+
|
324
|
+
before do
|
325
|
+
# Create a topic, post a message to it, consume it and commit offsets, this will create a group that we can then delete.
|
326
|
+
admin.create_topic(topic_name, topic_partition_count, topic_replication_factor).wait(max_wait_timeout: 15.0)
|
327
|
+
|
328
|
+
producer.produce(topic: topic_name, payload: "test", key: "test").wait(max_wait_timeout: 15.0)
|
329
|
+
|
330
|
+
consumer.subscribe(topic_name)
|
331
|
+
wait_for_assignment(consumer)
|
332
|
+
message = consumer.poll(100)
|
333
|
+
|
334
|
+
expect(message).to_not be_nil
|
335
|
+
|
336
|
+
consumer.commit
|
337
|
+
consumer.close
|
338
|
+
end
|
339
|
+
|
340
|
+
after do
|
341
|
+
producer.close
|
342
|
+
consumer.close
|
343
|
+
end
|
344
|
+
|
345
|
+
it "deletes the group" do
|
346
|
+
delete_group_handle = admin.delete_group(group_name)
|
347
|
+
report = delete_group_handle.wait(max_wait_timeout: 15.0)
|
348
|
+
|
349
|
+
expect(report.result_name).to eql(group_name)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
describe "called with invalid input" do
|
354
|
+
describe "with the name of a group that does not exist" do
|
355
|
+
it "raises an exception" do
|
356
|
+
delete_group_handle = admin.delete_group(group_name)
|
357
|
+
|
358
|
+
expect {
|
359
|
+
delete_group_handle.wait(max_wait_timeout: 15.0)
|
360
|
+
}.to raise_exception { |ex|
|
361
|
+
expect(ex).to be_a(Rdkafka::RdkafkaError)
|
362
|
+
expect(ex.message).to match(/Broker: The group id does not exist \(group_id_not_found\)/)
|
363
|
+
}
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
describe '#create_partitions' do
|
372
|
+
let(:metadata) { admin.metadata(topic_name).topics.first }
|
373
|
+
|
374
|
+
context 'when topic does not exist' do
|
375
|
+
it 'expect to fail due to unknown partition' do
|
376
|
+
expect { admin.create_partitions(topic_name, 10).wait }.to raise_error(Rdkafka::RdkafkaError, /unknown_topic_or_part/)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
context 'when topic already has the desired number of partitions' do
|
381
|
+
before { admin.create_topic(topic_name, 2, 1).wait }
|
382
|
+
|
383
|
+
it 'expect not to change number of partitions' do
|
384
|
+
expect { admin.create_partitions(topic_name, 2).wait }.to raise_error(Rdkafka::RdkafkaError, /invalid_partitions/)
|
385
|
+
expect(metadata[:partition_count]).to eq(2)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
context 'when topic has more than the requested number of partitions' do
|
390
|
+
before { admin.create_topic(topic_name, 5, 1).wait }
|
391
|
+
|
392
|
+
it 'expect not to change number of partitions' do
|
393
|
+
expect { admin.create_partitions(topic_name, 2).wait }.to raise_error(Rdkafka::RdkafkaError, /invalid_partitions/)
|
394
|
+
expect(metadata[:partition_count]).to eq(5)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
context 'when topic has less then desired number of partitions' do
|
399
|
+
before { admin.create_topic(topic_name, 1, 1).wait }
|
400
|
+
|
401
|
+
it 'expect to change number of partitions' do
|
402
|
+
admin.create_partitions(topic_name, 10).wait
|
403
|
+
expect(metadata[:partition_count]).to eq(10)
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|
203
407
|
end
|
@@ -702,6 +702,15 @@ describe Rdkafka::Consumer do
|
|
702
702
|
consumer.poll(100)
|
703
703
|
}.to raise_error Rdkafka::RdkafkaError
|
704
704
|
end
|
705
|
+
|
706
|
+
it "expect to raise error when polling non-existing topic" do
|
707
|
+
missing_topic = SecureRandom.uuid
|
708
|
+
consumer.subscribe(missing_topic)
|
709
|
+
|
710
|
+
expect {
|
711
|
+
consumer.poll(1_000)
|
712
|
+
}.to raise_error Rdkafka::RdkafkaError, /Subscribed topic not available: #{missing_topic}/
|
713
|
+
end
|
705
714
|
end
|
706
715
|
|
707
716
|
describe "#poll with headers" do
|
@@ -834,41 +834,6 @@ describe Rdkafka::Producer do
|
|
834
834
|
expect(response.error.abortable?).to eq(false)
|
835
835
|
end
|
836
836
|
|
837
|
-
# This may not always crash, depends on load but no other way to check it
|
838
|
-
context 'when timeout is too short and error occurs and we can abort' do
|
839
|
-
let(:producer) do
|
840
|
-
rdkafka_producer_config(
|
841
|
-
'transactional.id': SecureRandom.uuid,
|
842
|
-
'transaction.timeout.ms': 1_000
|
843
|
-
).producer
|
844
|
-
end
|
845
|
-
|
846
|
-
it 'expect to allow to produce within a transaction, finalize and not ship data' do
|
847
|
-
producer.init_transactions
|
848
|
-
producer.begin_transaction
|
849
|
-
|
850
|
-
sleep(5)
|
851
|
-
|
852
|
-
handle1 = producer.produce(topic: 'produce_test_topic', payload: 'data1', partition: 1)
|
853
|
-
handle2 = producer.produce(topic: 'example_topic', payload: 'data2', partition: 0)
|
854
|
-
|
855
|
-
begin
|
856
|
-
producer.commit_transaction(15_000)
|
857
|
-
rescue Rdkafka::RdkafkaError => e
|
858
|
-
next unless e.abortable?
|
859
|
-
|
860
|
-
begin
|
861
|
-
producer.abort_transaction(15_000)
|
862
|
-
rescue Rdkafka::RdkafkaError => e
|
863
|
-
nil
|
864
|
-
end
|
865
|
-
|
866
|
-
expect { handle1.wait(max_wait_timeout: 15) }.to raise_error(Rdkafka::RdkafkaError)
|
867
|
-
expect { handle2.wait(max_wait_timeout: 15) }.to raise_error(Rdkafka::RdkafkaError)
|
868
|
-
end
|
869
|
-
end
|
870
|
-
end
|
871
|
-
|
872
837
|
context 'fencing against previous active producer with same transactional id' do
|
873
838
|
let(:transactional_id) { SecureRandom.uuid }
|
874
839
|
|
data/spec/spec_helper.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: karafka-rdkafka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.14.
|
4
|
+
version: 0.14.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thijs Cadier
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
AnG1dJU+yL2BK7vaVytLTstJME5mepSZ46qqIJXMuWob/YPDmVaBF39TDSG9e34s
|
36
36
|
msG3BiCqgOgHAnL23+CN3Rt8MsuRfEtoTKpJVcCfoEoNHOkc
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2023-
|
38
|
+
date: 2023-12-02 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: ffi
|
@@ -171,6 +171,7 @@ extensions:
|
|
171
171
|
- ext/Rakefile
|
172
172
|
extra_rdoc_files: []
|
173
173
|
files:
|
174
|
+
- ".github/FUNDING.yml"
|
174
175
|
- ".github/workflows/ci.yml"
|
175
176
|
- ".gitignore"
|
176
177
|
- ".rspec"
|
@@ -191,12 +192,21 @@ files:
|
|
191
192
|
- lib/rdkafka.rb
|
192
193
|
- lib/rdkafka/abstract_handle.rb
|
193
194
|
- lib/rdkafka/admin.rb
|
195
|
+
- lib/rdkafka/admin/acl_binding_result.rb
|
196
|
+
- lib/rdkafka/admin/create_acl_handle.rb
|
197
|
+
- lib/rdkafka/admin/create_acl_report.rb
|
194
198
|
- lib/rdkafka/admin/create_partitions_handle.rb
|
195
199
|
- lib/rdkafka/admin/create_partitions_report.rb
|
196
200
|
- lib/rdkafka/admin/create_topic_handle.rb
|
197
201
|
- lib/rdkafka/admin/create_topic_report.rb
|
202
|
+
- lib/rdkafka/admin/delete_acl_handle.rb
|
203
|
+
- lib/rdkafka/admin/delete_acl_report.rb
|
204
|
+
- lib/rdkafka/admin/delete_groups_handle.rb
|
205
|
+
- lib/rdkafka/admin/delete_groups_report.rb
|
198
206
|
- lib/rdkafka/admin/delete_topic_handle.rb
|
199
207
|
- lib/rdkafka/admin/delete_topic_report.rb
|
208
|
+
- lib/rdkafka/admin/describe_acl_handle.rb
|
209
|
+
- lib/rdkafka/admin/describe_acl_report.rb
|
200
210
|
- lib/rdkafka/bindings.rb
|
201
211
|
- lib/rdkafka/callbacks.rb
|
202
212
|
- lib/rdkafka/config.rb
|
@@ -215,10 +225,16 @@ files:
|
|
215
225
|
- lib/rdkafka/version.rb
|
216
226
|
- renovate.json
|
217
227
|
- spec/rdkafka/abstract_handle_spec.rb
|
228
|
+
- spec/rdkafka/admin/create_acl_handle_spec.rb
|
229
|
+
- spec/rdkafka/admin/create_acl_report_spec.rb
|
218
230
|
- spec/rdkafka/admin/create_topic_handle_spec.rb
|
219
231
|
- spec/rdkafka/admin/create_topic_report_spec.rb
|
232
|
+
- spec/rdkafka/admin/delete_acl_handle_spec.rb
|
233
|
+
- spec/rdkafka/admin/delete_acl_report_spec.rb
|
220
234
|
- spec/rdkafka/admin/delete_topic_handle_spec.rb
|
221
235
|
- spec/rdkafka/admin/delete_topic_report_spec.rb
|
236
|
+
- spec/rdkafka/admin/describe_acl_handle_spec.rb
|
237
|
+
- spec/rdkafka/admin/describe_acl_report_spec.rb
|
222
238
|
- spec/rdkafka/admin_spec.rb
|
223
239
|
- spec/rdkafka/bindings_spec.rb
|
224
240
|
- spec/rdkafka/callbacks_spec.rb
|
@@ -269,10 +285,16 @@ summary: The rdkafka gem is a modern Kafka client library for Ruby based on libr
|
|
269
285
|
and Ruby 2.4+.
|
270
286
|
test_files:
|
271
287
|
- spec/rdkafka/abstract_handle_spec.rb
|
288
|
+
- spec/rdkafka/admin/create_acl_handle_spec.rb
|
289
|
+
- spec/rdkafka/admin/create_acl_report_spec.rb
|
272
290
|
- spec/rdkafka/admin/create_topic_handle_spec.rb
|
273
291
|
- spec/rdkafka/admin/create_topic_report_spec.rb
|
292
|
+
- spec/rdkafka/admin/delete_acl_handle_spec.rb
|
293
|
+
- spec/rdkafka/admin/delete_acl_report_spec.rb
|
274
294
|
- spec/rdkafka/admin/delete_topic_handle_spec.rb
|
275
295
|
- spec/rdkafka/admin/delete_topic_report_spec.rb
|
296
|
+
- spec/rdkafka/admin/describe_acl_handle_spec.rb
|
297
|
+
- spec/rdkafka/admin/describe_acl_report_spec.rb
|
276
298
|
- spec/rdkafka/admin_spec.rb
|
277
299
|
- spec/rdkafka/bindings_spec.rb
|
278
300
|
- spec/rdkafka/callbacks_spec.rb
|
metadata.gz.sig
CHANGED
Binary file
|