rdkafka 0.12.0 → 0.15.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/.github/workflows/ci.yml +57 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +155 -93
- data/Gemfile +2 -0
- data/{LICENSE → MIT-LICENSE} +2 -1
- data/README.md +76 -29
- data/Rakefile +2 -0
- data/certs/cert_chain.pem +26 -0
- data/docker-compose.yml +18 -15
- data/ext/README.md +1 -1
- data/ext/Rakefile +46 -27
- data/lib/rdkafka/abstract_handle.rb +41 -25
- data/lib/rdkafka/admin/acl_binding_result.rb +51 -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/create_partitions_handle.rb +27 -0
- data/lib/rdkafka/admin/create_partitions_report.rb +6 -0
- data/lib/rdkafka/admin/create_topic_handle.rb +2 -0
- data/lib/rdkafka/admin/create_topic_report.rb +2 -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/delete_topic_handle.rb +2 -0
- data/lib/rdkafka/admin/delete_topic_report.rb +2 -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 +494 -35
- data/lib/rdkafka/bindings.rb +180 -41
- data/lib/rdkafka/callbacks.rb +202 -1
- data/lib/rdkafka/config.rb +62 -25
- data/lib/rdkafka/consumer/headers.rb +24 -9
- data/lib/rdkafka/consumer/message.rb +3 -1
- data/lib/rdkafka/consumer/partition.rb +2 -0
- data/lib/rdkafka/consumer/topic_partition_list.rb +13 -8
- data/lib/rdkafka/consumer.rb +243 -111
- data/lib/rdkafka/error.rb +15 -0
- data/lib/rdkafka/helpers/time.rb +14 -0
- data/lib/rdkafka/metadata.rb +25 -2
- data/lib/rdkafka/native_kafka.rb +120 -0
- data/lib/rdkafka/producer/delivery_handle.rb +16 -2
- data/lib/rdkafka/producer/delivery_report.rb +22 -2
- data/lib/rdkafka/producer.rb +151 -21
- data/lib/rdkafka/version.rb +5 -3
- data/lib/rdkafka.rb +24 -2
- data/rdkafka.gemspec +21 -5
- data/renovate.json +6 -0
- data/spec/rdkafka/abstract_handle_spec.rb +1 -1
- 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/create_topic_handle_spec.rb +1 -1
- data/spec/rdkafka/admin/create_topic_report_spec.rb +1 -1
- data/spec/rdkafka/admin/delete_acl_handle_spec.rb +85 -0
- data/spec/rdkafka/admin/delete_acl_report_spec.rb +72 -0
- data/spec/rdkafka/admin/delete_topic_handle_spec.rb +1 -1
- data/spec/rdkafka/admin/delete_topic_report_spec.rb +1 -1
- data/spec/rdkafka/admin/describe_acl_handle_spec.rb +85 -0
- data/spec/rdkafka/admin/describe_acl_report_spec.rb +73 -0
- data/spec/rdkafka/admin_spec.rb +209 -5
- data/spec/rdkafka/bindings_spec.rb +2 -1
- data/spec/rdkafka/callbacks_spec.rb +1 -1
- data/spec/rdkafka/config_spec.rb +24 -3
- data/spec/rdkafka/consumer/headers_spec.rb +60 -0
- data/spec/rdkafka/consumer/message_spec.rb +1 -1
- data/spec/rdkafka/consumer/partition_spec.rb +1 -1
- data/spec/rdkafka/consumer/topic_partition_list_spec.rb +20 -1
- data/spec/rdkafka/consumer_spec.rb +352 -61
- data/spec/rdkafka/error_spec.rb +1 -1
- data/spec/rdkafka/metadata_spec.rb +4 -3
- data/spec/rdkafka/{producer/client_spec.rb → native_kafka_spec.rb} +13 -35
- data/spec/rdkafka/producer/delivery_handle_spec.rb +4 -1
- data/spec/rdkafka/producer/delivery_report_spec.rb +11 -3
- data/spec/rdkafka/producer_spec.rb +234 -22
- data/spec/spec_helper.rb +20 -2
- data.tar.gz.sig +0 -0
- metadata +81 -17
- metadata.gz.sig +0 -0
- data/.semaphore/semaphore.yml +0 -23
- data/bin/console +0 -11
- data/lib/rdkafka/producer/client.rb +0 -47
data/lib/rdkafka/admin.rb
CHANGED
@@ -1,43 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rdkafka
|
2
4
|
class Admin
|
3
5
|
# @private
|
4
6
|
def initialize(native_kafka)
|
5
7
|
@native_kafka = native_kafka
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
|
9
|
+
# Makes sure, that native kafka gets closed before it gets GCed by Ruby
|
10
|
+
ObjectSpace.define_finalizer(self, native_kafka.finalizer)
|
11
|
+
end
|
12
|
+
|
13
|
+
def finalizer
|
14
|
+
->(_) { close }
|
15
|
+
end
|
16
|
+
|
17
|
+
# Performs the metadata request using admin
|
18
|
+
#
|
19
|
+
# @param topic_name [String, nil] metadat about particular topic or all if nil
|
20
|
+
# @param timeout_ms [Integer] metadata request timeout
|
21
|
+
# @return [Metadata] requested metadata
|
22
|
+
def metadata(topic_name = nil, timeout_ms = 2_000)
|
23
|
+
closed_admin_check(__method__)
|
24
|
+
|
25
|
+
@native_kafka.with_inner do |inner|
|
26
|
+
Metadata.new(inner, topic_name, timeout_ms)
|
17
27
|
end
|
18
|
-
@polling_thread.abort_on_exception = true
|
19
28
|
end
|
20
29
|
|
21
30
|
# Close this admin instance
|
22
31
|
def close
|
23
|
-
return
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@native_kafka
|
32
|
+
return if closed?
|
33
|
+
ObjectSpace.undefine_finalizer(self)
|
34
|
+
@native_kafka.close
|
35
|
+
end
|
36
|
+
|
37
|
+
# Whether this admin has closed
|
38
|
+
def closed?
|
39
|
+
@native_kafka.closed?
|
31
40
|
end
|
32
41
|
|
33
42
|
# Create a topic with the given partition count and replication factor
|
34
43
|
#
|
44
|
+
# @return [CreateTopicHandle] Create topic handle that can be used to wait for the result of
|
45
|
+
# creating the topic
|
46
|
+
#
|
35
47
|
# @raise [ConfigError] When the partition count or replication factor are out of valid range
|
36
48
|
# @raise [RdkafkaError] When the topic name is invalid or the topic already exists
|
37
49
|
# @raise [RdkafkaError] When the topic configuration is invalid
|
38
|
-
#
|
39
|
-
# @return [CreateTopicHandle] Create topic handle that can be used to wait for the result of creating the topic
|
40
50
|
def create_topic(topic_name, partition_count, replication_factor, topic_config={})
|
51
|
+
closed_admin_check(__method__)
|
41
52
|
|
42
53
|
# Create a rd_kafka_NewTopic_t representing the new topic
|
43
54
|
error_buffer = FFI::MemoryPointer.from_string(" " * 256)
|
@@ -68,7 +79,9 @@ module Rdkafka
|
|
68
79
|
topics_array_ptr.write_array_of_pointer(pointer_array)
|
69
80
|
|
70
81
|
# Get a pointer to the queue that our request will be enqueued on
|
71
|
-
queue_ptr =
|
82
|
+
queue_ptr = @native_kafka.with_inner do |inner|
|
83
|
+
Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
|
84
|
+
end
|
72
85
|
if queue_ptr.null?
|
73
86
|
Rdkafka::Bindings.rd_kafka_NewTopic_destroy(new_topic_ptr)
|
74
87
|
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
@@ -79,17 +92,21 @@ module Rdkafka
|
|
79
92
|
create_topic_handle[:pending] = true
|
80
93
|
create_topic_handle[:response] = -1
|
81
94
|
CreateTopicHandle.register(create_topic_handle)
|
82
|
-
admin_options_ptr =
|
95
|
+
admin_options_ptr = @native_kafka.with_inner do |inner|
|
96
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_new(inner, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_CREATETOPICS)
|
97
|
+
end
|
83
98
|
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, create_topic_handle.to_ptr)
|
84
99
|
|
85
100
|
begin
|
86
|
-
|
87
|
-
|
101
|
+
@native_kafka.with_inner do |inner|
|
102
|
+
Rdkafka::Bindings.rd_kafka_CreateTopics(
|
103
|
+
inner,
|
88
104
|
topics_array_ptr,
|
89
105
|
1,
|
90
106
|
admin_options_ptr,
|
91
107
|
queue_ptr
|
92
|
-
|
108
|
+
)
|
109
|
+
end
|
93
110
|
rescue Exception
|
94
111
|
CreateTopicHandle.remove(create_topic_handle.to_ptr.address)
|
95
112
|
raise
|
@@ -102,12 +119,66 @@ module Rdkafka
|
|
102
119
|
create_topic_handle
|
103
120
|
end
|
104
121
|
|
105
|
-
|
122
|
+
def delete_group(group_id)
|
123
|
+
closed_admin_check(__method__)
|
124
|
+
|
125
|
+
# Create a rd_kafka_DeleteGroup_t representing the new topic
|
126
|
+
delete_groups_ptr = Rdkafka::Bindings.rd_kafka_DeleteGroup_new(
|
127
|
+
FFI::MemoryPointer.from_string(group_id)
|
128
|
+
)
|
129
|
+
|
130
|
+
pointer_array = [delete_groups_ptr]
|
131
|
+
groups_array_ptr = FFI::MemoryPointer.new(:pointer)
|
132
|
+
groups_array_ptr.write_array_of_pointer(pointer_array)
|
133
|
+
|
134
|
+
# Get a pointer to the queue that our request will be enqueued on
|
135
|
+
queue_ptr = @native_kafka.with_inner do |inner|
|
136
|
+
Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
|
137
|
+
end
|
138
|
+
if queue_ptr.null?
|
139
|
+
Rdkafka::Bindings.rd_kafka_DeleteTopic_destroy(delete_topic_ptr)
|
140
|
+
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
141
|
+
end
|
142
|
+
|
143
|
+
# Create and register the handle we will return to the caller
|
144
|
+
delete_groups_handle = DeleteGroupsHandle.new
|
145
|
+
delete_groups_handle[:pending] = true
|
146
|
+
delete_groups_handle[:response] = -1
|
147
|
+
DeleteGroupsHandle.register(delete_groups_handle)
|
148
|
+
admin_options_ptr = @native_kafka.with_inner do |inner|
|
149
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_new(inner, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_DELETETOPICS)
|
150
|
+
end
|
151
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, delete_groups_handle.to_ptr)
|
152
|
+
|
153
|
+
begin
|
154
|
+
@native_kafka.with_inner do |inner|
|
155
|
+
Rdkafka::Bindings.rd_kafka_DeleteGroups(
|
156
|
+
inner,
|
157
|
+
groups_array_ptr,
|
158
|
+
1,
|
159
|
+
admin_options_ptr,
|
160
|
+
queue_ptr
|
161
|
+
)
|
162
|
+
end
|
163
|
+
rescue Exception
|
164
|
+
DeleteGroupsHandle.remove(delete_groups_handle.to_ptr.address)
|
165
|
+
raise
|
166
|
+
ensure
|
167
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_destroy(admin_options_ptr)
|
168
|
+
Rdkafka::Bindings.rd_kafka_queue_destroy(queue_ptr)
|
169
|
+
Rdkafka::Bindings.rd_kafka_DeleteGroup_destroy(delete_groups_ptr)
|
170
|
+
end
|
171
|
+
|
172
|
+
delete_groups_handle
|
173
|
+
end
|
174
|
+
|
175
|
+
# Deletes the named topic
|
106
176
|
#
|
177
|
+
# @return [DeleteTopicHandle] Delete topic handle that can be used to wait for the result of
|
178
|
+
# deleting the topic
|
107
179
|
# @raise [RdkafkaError] When the topic name is invalid or the topic does not exist
|
108
|
-
#
|
109
|
-
# @return [DeleteTopicHandle] Delete topic handle that can be used to wait for the result of deleting the topic
|
110
180
|
def delete_topic(topic_name)
|
181
|
+
closed_admin_check(__method__)
|
111
182
|
|
112
183
|
# Create a rd_kafka_DeleteTopic_t representing the topic to be deleted
|
113
184
|
delete_topic_ptr = Rdkafka::Bindings.rd_kafka_DeleteTopic_new(FFI::MemoryPointer.from_string(topic_name))
|
@@ -118,7 +189,9 @@ module Rdkafka
|
|
118
189
|
topics_array_ptr.write_array_of_pointer(pointer_array)
|
119
190
|
|
120
191
|
# Get a pointer to the queue that our request will be enqueued on
|
121
|
-
queue_ptr =
|
192
|
+
queue_ptr = @native_kafka.with_inner do |inner|
|
193
|
+
Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
|
194
|
+
end
|
122
195
|
if queue_ptr.null?
|
123
196
|
Rdkafka::Bindings.rd_kafka_DeleteTopic_destroy(delete_topic_ptr)
|
124
197
|
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
@@ -129,17 +202,21 @@ module Rdkafka
|
|
129
202
|
delete_topic_handle[:pending] = true
|
130
203
|
delete_topic_handle[:response] = -1
|
131
204
|
DeleteTopicHandle.register(delete_topic_handle)
|
132
|
-
admin_options_ptr =
|
205
|
+
admin_options_ptr = @native_kafka.with_inner do |inner|
|
206
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_new(inner, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_DELETETOPICS)
|
207
|
+
end
|
133
208
|
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, delete_topic_handle.to_ptr)
|
134
209
|
|
135
210
|
begin
|
136
|
-
|
137
|
-
|
211
|
+
@native_kafka.with_inner do |inner|
|
212
|
+
Rdkafka::Bindings.rd_kafka_DeleteTopics(
|
213
|
+
inner,
|
138
214
|
topics_array_ptr,
|
139
215
|
1,
|
140
216
|
admin_options_ptr,
|
141
217
|
queue_ptr
|
142
|
-
|
218
|
+
)
|
219
|
+
end
|
143
220
|
rescue Exception
|
144
221
|
DeleteTopicHandle.remove(delete_topic_handle.to_ptr.address)
|
145
222
|
raise
|
@@ -151,5 +228,387 @@ module Rdkafka
|
|
151
228
|
|
152
229
|
delete_topic_handle
|
153
230
|
end
|
231
|
+
|
232
|
+
# Creates extra partitions for a given topic
|
233
|
+
#
|
234
|
+
# @param topic_name [String]
|
235
|
+
# @param partition_count [Integer] how many partitions we want to end up with for given topic
|
236
|
+
#
|
237
|
+
# @raise [ConfigError] When the partition count or replication factor are out of valid range
|
238
|
+
# @raise [RdkafkaError] When the topic name is invalid or the topic already exists
|
239
|
+
# @raise [RdkafkaError] When the topic configuration is invalid
|
240
|
+
#
|
241
|
+
# @return [CreateTopicHandle] Create topic handle that can be used to wait for the result of creating the topic
|
242
|
+
def create_partitions(topic_name, partition_count)
|
243
|
+
closed_admin_check(__method__)
|
244
|
+
|
245
|
+
@native_kafka.with_inner do |inner|
|
246
|
+
error_buffer = FFI::MemoryPointer.from_string(" " * 256)
|
247
|
+
new_partitions_ptr = Rdkafka::Bindings.rd_kafka_NewPartitions_new(
|
248
|
+
FFI::MemoryPointer.from_string(topic_name),
|
249
|
+
partition_count,
|
250
|
+
error_buffer,
|
251
|
+
256
|
252
|
+
)
|
253
|
+
if new_partitions_ptr.null?
|
254
|
+
raise Rdkafka::Config::ConfigError.new(error_buffer.read_string)
|
255
|
+
end
|
256
|
+
|
257
|
+
pointer_array = [new_partitions_ptr]
|
258
|
+
topics_array_ptr = FFI::MemoryPointer.new(:pointer)
|
259
|
+
topics_array_ptr.write_array_of_pointer(pointer_array)
|
260
|
+
|
261
|
+
# Get a pointer to the queue that our request will be enqueued on
|
262
|
+
queue_ptr = Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
|
263
|
+
if queue_ptr.null?
|
264
|
+
Rdkafka::Bindings.rd_kafka_NewPartitions_destroy(new_partitions_ptr)
|
265
|
+
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
266
|
+
end
|
267
|
+
|
268
|
+
# Create and register the handle we will return to the caller
|
269
|
+
create_partitions_handle = CreatePartitionsHandle.new
|
270
|
+
create_partitions_handle[:pending] = true
|
271
|
+
create_partitions_handle[:response] = -1
|
272
|
+
CreatePartitionsHandle.register(create_partitions_handle)
|
273
|
+
admin_options_ptr = Rdkafka::Bindings.rd_kafka_AdminOptions_new(inner, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_CREATEPARTITIONS)
|
274
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, create_partitions_handle.to_ptr)
|
275
|
+
|
276
|
+
begin
|
277
|
+
Rdkafka::Bindings.rd_kafka_CreatePartitions(
|
278
|
+
inner,
|
279
|
+
topics_array_ptr,
|
280
|
+
1,
|
281
|
+
admin_options_ptr,
|
282
|
+
queue_ptr
|
283
|
+
)
|
284
|
+
rescue Exception
|
285
|
+
CreatePartitionsHandle.remove(create_partitions_handle.to_ptr.address)
|
286
|
+
raise
|
287
|
+
ensure
|
288
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_destroy(admin_options_ptr)
|
289
|
+
Rdkafka::Bindings.rd_kafka_queue_destroy(queue_ptr)
|
290
|
+
Rdkafka::Bindings.rd_kafka_NewPartitions_destroy(new_partitions_ptr)
|
291
|
+
end
|
292
|
+
|
293
|
+
create_partitions_handle
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Create acl
|
298
|
+
# @param resource_type - values of type rd_kafka_ResourceType_t
|
299
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L7307
|
300
|
+
# valid values are:
|
301
|
+
# RD_KAFKA_RESOURCE_TOPIC = 2
|
302
|
+
# RD_KAFKA_RESOURCE_GROUP = 3
|
303
|
+
# RD_KAFKA_RESOURCE_BROKER = 4
|
304
|
+
# @param resource_pattern_type - values of type rd_kafka_ResourcePatternType_t
|
305
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L7320
|
306
|
+
# valid values are:
|
307
|
+
# RD_KAFKA_RESOURCE_PATTERN_MATCH = 2
|
308
|
+
# RD_KAFKA_RESOURCE_PATTERN_LITERAL = 3
|
309
|
+
# RD_KAFKA_RESOURCE_PATTERN_PREFIXED = 4
|
310
|
+
# @param operation - values of type rd_kafka_AclOperation_t
|
311
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L8403
|
312
|
+
# valid values are:
|
313
|
+
# RD_KAFKA_ACL_OPERATION_ALL = 2
|
314
|
+
# RD_KAFKA_ACL_OPERATION_READ = 3
|
315
|
+
# RD_KAFKA_ACL_OPERATION_WRITE = 4
|
316
|
+
# RD_KAFKA_ACL_OPERATION_CREATE = 5
|
317
|
+
# RD_KAFKA_ACL_OPERATION_DELETE = 6
|
318
|
+
# RD_KAFKA_ACL_OPERATION_ALTER = 7
|
319
|
+
# RD_KAFKA_ACL_OPERATION_DESCRIBE = 8
|
320
|
+
# RD_KAFKA_ACL_OPERATION_CLUSTER_ACTION = 9
|
321
|
+
# RD_KAFKA_ACL_OPERATION_DESCRIBE_CONFIGS = 10
|
322
|
+
# RD_KAFKA_ACL_OPERATION_ALTER_CONFIGS = 11
|
323
|
+
# RD_KAFKA_ACL_OPERATION_IDEMPOTENT_WRITE = 12
|
324
|
+
# @param permission_type - values of type rd_kafka_AclPermissionType_t
|
325
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L8435
|
326
|
+
# valid values are:
|
327
|
+
# RD_KAFKA_ACL_PERMISSION_TYPE_DENY = 2
|
328
|
+
# RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW = 3
|
329
|
+
#
|
330
|
+
# @return [CreateAclHandle] Create acl handle that can be used to wait for the result of creating the acl
|
331
|
+
#
|
332
|
+
# @raise [RdkafkaError]
|
333
|
+
def create_acl(resource_type:, resource_name:, resource_pattern_type:, principal:, host:, operation:, permission_type:)
|
334
|
+
closed_admin_check(__method__)
|
335
|
+
|
336
|
+
# Create a rd_kafka_AclBinding_t representing the new acl
|
337
|
+
error_buffer = FFI::MemoryPointer.from_string(" " * 256)
|
338
|
+
new_acl_ptr = Rdkafka::Bindings.rd_kafka_AclBinding_new(
|
339
|
+
resource_type,
|
340
|
+
FFI::MemoryPointer.from_string(resource_name),
|
341
|
+
resource_pattern_type,
|
342
|
+
FFI::MemoryPointer.from_string(principal),
|
343
|
+
FFI::MemoryPointer.from_string(host),
|
344
|
+
operation,
|
345
|
+
permission_type,
|
346
|
+
error_buffer,
|
347
|
+
256
|
348
|
+
)
|
349
|
+
if new_acl_ptr.null?
|
350
|
+
raise Rdkafka::Config::ConfigError.new(error_buffer.read_string)
|
351
|
+
end
|
352
|
+
|
353
|
+
# Note that rd_kafka_CreateAcls can create more than one acl at a time
|
354
|
+
pointer_array = [new_acl_ptr]
|
355
|
+
acls_array_ptr = FFI::MemoryPointer.new(:pointer)
|
356
|
+
acls_array_ptr.write_array_of_pointer(pointer_array)
|
357
|
+
|
358
|
+
# Get a pointer to the queue that our request will be enqueued on
|
359
|
+
queue_ptr = @native_kafka.with_inner do |inner|
|
360
|
+
Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
|
361
|
+
end
|
362
|
+
|
363
|
+
if queue_ptr.null?
|
364
|
+
Rdkafka::Bindings.rd_kafka_AclBinding_destroy(new_acl_ptr)
|
365
|
+
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
366
|
+
end
|
367
|
+
|
368
|
+
# Create and register the handle that we will return to the caller
|
369
|
+
create_acl_handle = CreateAclHandle.new
|
370
|
+
create_acl_handle[:pending] = true
|
371
|
+
create_acl_handle[:response] = -1
|
372
|
+
CreateAclHandle.register(create_acl_handle)
|
373
|
+
|
374
|
+
admin_options_ptr = @native_kafka.with_inner do |inner|
|
375
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_new(inner, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_CREATEACLS)
|
376
|
+
end
|
377
|
+
|
378
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, create_acl_handle.to_ptr)
|
379
|
+
|
380
|
+
begin
|
381
|
+
@native_kafka.with_inner do |inner|
|
382
|
+
Rdkafka::Bindings.rd_kafka_CreateAcls(
|
383
|
+
inner,
|
384
|
+
acls_array_ptr,
|
385
|
+
1,
|
386
|
+
admin_options_ptr,
|
387
|
+
queue_ptr
|
388
|
+
)
|
389
|
+
end
|
390
|
+
rescue Exception
|
391
|
+
CreateAclHandle.remove(create_acl_handle.to_ptr.address)
|
392
|
+
raise
|
393
|
+
ensure
|
394
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_destroy(admin_options_ptr)
|
395
|
+
Rdkafka::Bindings.rd_kafka_queue_destroy(queue_ptr)
|
396
|
+
Rdkafka::Bindings.rd_kafka_AclBinding_destroy(new_acl_ptr)
|
397
|
+
end
|
398
|
+
|
399
|
+
create_acl_handle
|
400
|
+
end
|
401
|
+
|
402
|
+
# Delete acl
|
403
|
+
#
|
404
|
+
# @param resource_type - values of type rd_kafka_ResourceType_t
|
405
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L7307
|
406
|
+
# valid values are:
|
407
|
+
# RD_KAFKA_RESOURCE_TOPIC = 2
|
408
|
+
# RD_KAFKA_RESOURCE_GROUP = 3
|
409
|
+
# RD_KAFKA_RESOURCE_BROKER = 4
|
410
|
+
# @param resource_pattern_type - values of type rd_kafka_ResourcePatternType_t
|
411
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L7320
|
412
|
+
# valid values are:
|
413
|
+
# RD_KAFKA_RESOURCE_PATTERN_MATCH = 2
|
414
|
+
# RD_KAFKA_RESOURCE_PATTERN_LITERAL = 3
|
415
|
+
# RD_KAFKA_RESOURCE_PATTERN_PREFIXED = 4
|
416
|
+
# @param operation - values of type rd_kafka_AclOperation_t
|
417
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L8403
|
418
|
+
# valid values are:
|
419
|
+
# RD_KAFKA_ACL_OPERATION_ALL = 2
|
420
|
+
# RD_KAFKA_ACL_OPERATION_READ = 3
|
421
|
+
# RD_KAFKA_ACL_OPERATION_WRITE = 4
|
422
|
+
# RD_KAFKA_ACL_OPERATION_CREATE = 5
|
423
|
+
# RD_KAFKA_ACL_OPERATION_DELETE = 6
|
424
|
+
# RD_KAFKA_ACL_OPERATION_ALTER = 7
|
425
|
+
# RD_KAFKA_ACL_OPERATION_DESCRIBE = 8
|
426
|
+
# RD_KAFKA_ACL_OPERATION_CLUSTER_ACTION = 9
|
427
|
+
# RD_KAFKA_ACL_OPERATION_DESCRIBE_CONFIGS = 10
|
428
|
+
# RD_KAFKA_ACL_OPERATION_ALTER_CONFIGS = 11
|
429
|
+
# RD_KAFKA_ACL_OPERATION_IDEMPOTENT_WRITE = 12
|
430
|
+
# @param permission_type - values of type rd_kafka_AclPermissionType_t
|
431
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L8435
|
432
|
+
# valid values are:
|
433
|
+
# RD_KAFKA_ACL_PERMISSION_TYPE_DENY = 2
|
434
|
+
# RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW = 3
|
435
|
+
# @return [DeleteAclHandle] Delete acl handle that can be used to wait for the result of deleting the acl
|
436
|
+
#
|
437
|
+
# @raise [RdkafkaError]
|
438
|
+
def delete_acl(resource_type:, resource_name:, resource_pattern_type:, principal:, host:, operation:, permission_type:)
|
439
|
+
closed_admin_check(__method__)
|
440
|
+
|
441
|
+
# Create a rd_kafka_AclBinding_t representing the acl to be deleted
|
442
|
+
error_buffer = FFI::MemoryPointer.from_string(" " * 256)
|
443
|
+
|
444
|
+
delete_acl_ptr = Rdkafka::Bindings.rd_kafka_AclBindingFilter_new(
|
445
|
+
resource_type,
|
446
|
+
resource_name ? FFI::MemoryPointer.from_string(resource_name) : nil,
|
447
|
+
resource_pattern_type,
|
448
|
+
principal ? FFI::MemoryPointer.from_string(principal) : nil,
|
449
|
+
host ? FFI::MemoryPointer.from_string(host) : nil,
|
450
|
+
operation,
|
451
|
+
permission_type,
|
452
|
+
error_buffer,
|
453
|
+
256
|
454
|
+
)
|
455
|
+
|
456
|
+
if delete_acl_ptr.null?
|
457
|
+
raise Rdkafka::Config::ConfigError.new(error_buffer.read_string)
|
458
|
+
end
|
459
|
+
|
460
|
+
# Note that rd_kafka_DeleteAcls can delete more than one acl at a time
|
461
|
+
pointer_array = [delete_acl_ptr]
|
462
|
+
acls_array_ptr = FFI::MemoryPointer.new(:pointer)
|
463
|
+
acls_array_ptr.write_array_of_pointer(pointer_array)
|
464
|
+
|
465
|
+
# Get a pointer to the queue that our request will be enqueued on
|
466
|
+
queue_ptr = @native_kafka.with_inner do |inner|
|
467
|
+
Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
|
468
|
+
end
|
469
|
+
|
470
|
+
if queue_ptr.null?
|
471
|
+
Rdkafka::Bindings.rd_kafka_AclBinding_destroy(new_acl_ptr)
|
472
|
+
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
473
|
+
end
|
474
|
+
|
475
|
+
# Create and register the handle that we will return to the caller
|
476
|
+
delete_acl_handle = DeleteAclHandle.new
|
477
|
+
delete_acl_handle[:pending] = true
|
478
|
+
delete_acl_handle[:response] = -1
|
479
|
+
DeleteAclHandle.register(delete_acl_handle)
|
480
|
+
|
481
|
+
admin_options_ptr = @native_kafka.with_inner do |inner|
|
482
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_new(inner, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_DELETEACLS)
|
483
|
+
end
|
484
|
+
|
485
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, delete_acl_handle.to_ptr)
|
486
|
+
|
487
|
+
begin
|
488
|
+
@native_kafka.with_inner do |inner|
|
489
|
+
Rdkafka::Bindings.rd_kafka_DeleteAcls(
|
490
|
+
inner,
|
491
|
+
acls_array_ptr,
|
492
|
+
1,
|
493
|
+
admin_options_ptr,
|
494
|
+
queue_ptr
|
495
|
+
)
|
496
|
+
end
|
497
|
+
rescue Exception
|
498
|
+
DeleteAclHandle.remove(delete_acl_handle.to_ptr.address)
|
499
|
+
raise
|
500
|
+
ensure
|
501
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_destroy(admin_options_ptr)
|
502
|
+
Rdkafka::Bindings.rd_kafka_queue_destroy(queue_ptr)
|
503
|
+
Rdkafka::Bindings.rd_kafka_AclBinding_destroy(delete_acl_ptr)
|
504
|
+
end
|
505
|
+
|
506
|
+
delete_acl_handle
|
507
|
+
end
|
508
|
+
|
509
|
+
# Describe acls
|
510
|
+
#
|
511
|
+
# @param resource_type - values of type rd_kafka_ResourceType_t
|
512
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L7307
|
513
|
+
# valid values are:
|
514
|
+
# RD_KAFKA_RESOURCE_TOPIC = 2
|
515
|
+
# RD_KAFKA_RESOURCE_GROUP = 3
|
516
|
+
# RD_KAFKA_RESOURCE_BROKER = 4
|
517
|
+
# @param resource_pattern_type - values of type rd_kafka_ResourcePatternType_t
|
518
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L7320
|
519
|
+
# valid values are:
|
520
|
+
# RD_KAFKA_RESOURCE_PATTERN_MATCH = 2
|
521
|
+
# RD_KAFKA_RESOURCE_PATTERN_LITERAL = 3
|
522
|
+
# RD_KAFKA_RESOURCE_PATTERN_PREFIXED = 4
|
523
|
+
# @param operation - values of type rd_kafka_AclOperation_t
|
524
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L8403
|
525
|
+
# valid values are:
|
526
|
+
# RD_KAFKA_ACL_OPERATION_ALL = 2
|
527
|
+
# RD_KAFKA_ACL_OPERATION_READ = 3
|
528
|
+
# RD_KAFKA_ACL_OPERATION_WRITE = 4
|
529
|
+
# RD_KAFKA_ACL_OPERATION_CREATE = 5
|
530
|
+
# RD_KAFKA_ACL_OPERATION_DELETE = 6
|
531
|
+
# RD_KAFKA_ACL_OPERATION_ALTER = 7
|
532
|
+
# RD_KAFKA_ACL_OPERATION_DESCRIBE = 8
|
533
|
+
# RD_KAFKA_ACL_OPERATION_CLUSTER_ACTION = 9
|
534
|
+
# RD_KAFKA_ACL_OPERATION_DESCRIBE_CONFIGS = 10
|
535
|
+
# RD_KAFKA_ACL_OPERATION_ALTER_CONFIGS = 11
|
536
|
+
# RD_KAFKA_ACL_OPERATION_IDEMPOTENT_WRITE = 12
|
537
|
+
# @param permission_type - values of type rd_kafka_AclPermissionType_t
|
538
|
+
# https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L8435
|
539
|
+
# valid values are:
|
540
|
+
# RD_KAFKA_ACL_PERMISSION_TYPE_DENY = 2
|
541
|
+
# RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW = 3
|
542
|
+
# @return [DescribeAclHandle] Describe acl handle that can be used to wait for the result of fetching acls
|
543
|
+
#
|
544
|
+
# @raise [RdkafkaError]
|
545
|
+
def describe_acl(resource_type:, resource_name:, resource_pattern_type:, principal:, host:, operation:, permission_type:)
|
546
|
+
closed_admin_check(__method__)
|
547
|
+
|
548
|
+
# Create a rd_kafka_AclBinding_t with the filters to fetch existing acls
|
549
|
+
error_buffer = FFI::MemoryPointer.from_string(" " * 256)
|
550
|
+
describe_acl_ptr = Rdkafka::Bindings.rd_kafka_AclBindingFilter_new(
|
551
|
+
resource_type,
|
552
|
+
resource_name ? FFI::MemoryPointer.from_string(resource_name) : nil,
|
553
|
+
resource_pattern_type,
|
554
|
+
principal ? FFI::MemoryPointer.from_string(principal) : nil,
|
555
|
+
host ? FFI::MemoryPointer.from_string(host) : nil,
|
556
|
+
operation,
|
557
|
+
permission_type,
|
558
|
+
error_buffer,
|
559
|
+
256
|
560
|
+
)
|
561
|
+
if describe_acl_ptr.null?
|
562
|
+
raise Rdkafka::Config::ConfigError.new(error_buffer.read_string)
|
563
|
+
end
|
564
|
+
|
565
|
+
# Get a pointer to the queue that our request will be enqueued on
|
566
|
+
queue_ptr = @native_kafka.with_inner do |inner|
|
567
|
+
Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
|
568
|
+
end
|
569
|
+
|
570
|
+
if queue_ptr.null?
|
571
|
+
Rdkafka::Bindings.rd_kafka_AclBinding_destroy(new_acl_ptr)
|
572
|
+
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
573
|
+
end
|
574
|
+
|
575
|
+
# Create and register the handle that we will return to the caller
|
576
|
+
describe_acl_handle = DescribeAclHandle.new
|
577
|
+
describe_acl_handle[:pending] = true
|
578
|
+
describe_acl_handle[:response] = -1
|
579
|
+
DescribeAclHandle.register(describe_acl_handle)
|
580
|
+
|
581
|
+
admin_options_ptr = @native_kafka.with_inner do |inner|
|
582
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_new(inner, Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_DESCRIBEACLS)
|
583
|
+
end
|
584
|
+
|
585
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, describe_acl_handle.to_ptr)
|
586
|
+
|
587
|
+
begin
|
588
|
+
@native_kafka.with_inner do |inner|
|
589
|
+
Rdkafka::Bindings.rd_kafka_DescribeAcls(
|
590
|
+
inner,
|
591
|
+
describe_acl_ptr,
|
592
|
+
admin_options_ptr,
|
593
|
+
queue_ptr
|
594
|
+
)
|
595
|
+
end
|
596
|
+
rescue Exception
|
597
|
+
DescribeAclHandle.remove(describe_acl_handle.to_ptr.address)
|
598
|
+
raise
|
599
|
+
ensure
|
600
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_destroy(admin_options_ptr)
|
601
|
+
Rdkafka::Bindings.rd_kafka_queue_destroy(queue_ptr)
|
602
|
+
Rdkafka::Bindings.rd_kafka_AclBinding_destroy(describe_acl_ptr)
|
603
|
+
end
|
604
|
+
|
605
|
+
describe_acl_handle
|
606
|
+
end
|
607
|
+
|
608
|
+
private
|
609
|
+
|
610
|
+
def closed_admin_check(method)
|
611
|
+
raise Rdkafka::ClosedAdminError.new(method) if closed?
|
612
|
+
end
|
154
613
|
end
|
155
614
|
end
|