rdkafka 0.14.0 → 0.15.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/FUNDING.yml +1 -0
  4. data/CHANGELOG.md +11 -0
  5. data/README.md +32 -22
  6. data/docker-compose.yml +2 -0
  7. data/lib/rdkafka/admin/acl_binding_result.rb +37 -0
  8. data/lib/rdkafka/admin/create_acl_handle.rb +28 -0
  9. data/lib/rdkafka/admin/create_acl_report.rb +24 -0
  10. data/lib/rdkafka/admin/create_partitions_handle.rb +27 -0
  11. data/lib/rdkafka/admin/create_partitions_report.rb +6 -0
  12. data/lib/rdkafka/admin/delete_acl_handle.rb +30 -0
  13. data/lib/rdkafka/admin/delete_acl_report.rb +23 -0
  14. data/lib/rdkafka/admin/delete_groups_handle.rb +28 -0
  15. data/lib/rdkafka/admin/delete_groups_report.rb +24 -0
  16. data/lib/rdkafka/admin/describe_acl_handle.rb +30 -0
  17. data/lib/rdkafka/admin/describe_acl_report.rb +23 -0
  18. data/lib/rdkafka/admin.rb +443 -0
  19. data/lib/rdkafka/bindings.rb +119 -0
  20. data/lib/rdkafka/callbacks.rb +187 -0
  21. data/lib/rdkafka/config.rb +24 -3
  22. data/lib/rdkafka/consumer/headers.rb +1 -1
  23. data/lib/rdkafka/consumer/topic_partition_list.rb +8 -7
  24. data/lib/rdkafka/consumer.rb +46 -10
  25. data/lib/rdkafka/producer.rb +2 -2
  26. data/lib/rdkafka/version.rb +3 -3
  27. data/lib/rdkafka.rb +11 -0
  28. data/spec/rdkafka/admin/create_acl_handle_spec.rb +56 -0
  29. data/spec/rdkafka/admin/create_acl_report_spec.rb +18 -0
  30. data/spec/rdkafka/admin/delete_acl_handle_spec.rb +85 -0
  31. data/spec/rdkafka/admin/delete_acl_report_spec.rb +71 -0
  32. data/spec/rdkafka/admin/describe_acl_handle_spec.rb +85 -0
  33. data/spec/rdkafka/admin/describe_acl_report_spec.rb +72 -0
  34. data/spec/rdkafka/admin_spec.rb +204 -0
  35. data/spec/rdkafka/config_spec.rb +8 -0
  36. data/spec/rdkafka/consumer_spec.rb +69 -0
  37. data/spec/spec_helper.rb +3 -1
  38. data.tar.gz.sig +0 -0
  39. metadata +26 -2
  40. metadata.gz.sig +0 -0
data/lib/rdkafka/admin.rb CHANGED
@@ -14,6 +14,19 @@ module Rdkafka
14
14
  ->(_) { close }
15
15
  end
16
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)
27
+ end
28
+ end
29
+
17
30
  # Close this admin instance
18
31
  def close
19
32
  return if closed?
@@ -106,6 +119,59 @@ module Rdkafka
106
119
  create_topic_handle
107
120
  end
108
121
 
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
+
109
175
  # Deletes the named topic
110
176
  #
111
177
  # @return [DeleteTopicHandle] Delete topic handle that can be used to wait for the result of
@@ -163,7 +229,384 @@ module Rdkafka
163
229
  delete_topic_handle
164
230
  end
165
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
+
166
608
  private
609
+
167
610
  def closed_admin_check(method)
168
611
  raise Rdkafka::ClosedAdminError.new(method) if closed?
169
612
  end
@@ -179,6 +179,7 @@ module Rdkafka
179
179
  attach_function :rd_kafka_incremental_assign, [:pointer, :pointer], :int, blocking: true
180
180
  attach_function :rd_kafka_incremental_unassign, [:pointer, :pointer], :int, blocking: true
181
181
  attach_function :rd_kafka_assignment, [:pointer, :pointer], :int, blocking: true
182
+ attach_function :rd_kafka_assignment_lost, [:pointer], :int, blocking: true
182
183
  attach_function :rd_kafka_committed, [:pointer, :pointer, :int], :int, blocking: true
183
184
  attach_function :rd_kafka_commit, [:pointer, :pointer, :bool], :int, blocking: true
184
185
  attach_function :rd_kafka_poll_set_consumer, [:pointer], :void, blocking: true
@@ -302,6 +303,27 @@ module Rdkafka
302
303
  attach_function :rd_kafka_event_DeleteTopics_result, [:pointer], :pointer, blocking: true
303
304
  attach_function :rd_kafka_DeleteTopics_result_topics, [:pointer, :pointer], :pointer, blocking: true
304
305
 
306
+ # Create partitions
307
+ RD_KAFKA_ADMIN_OP_CREATEPARTITIONS = 3
308
+ RD_KAFKA_ADMIN_OP_CREATEPARTITIONS_RESULT = 102
309
+
310
+ attach_function :rd_kafka_CreatePartitions, [:pointer, :pointer, :size_t, :pointer, :pointer], :void
311
+ attach_function :rd_kafka_NewPartitions_new, %i[pointer size_t pointer size_t], :pointer
312
+ attach_function :rd_kafka_NewPartitions_destroy, [:pointer], :void
313
+ attach_function :rd_kafka_event_CreatePartitions_result, [:pointer], :pointer
314
+ attach_function :rd_kafka_CreatePartitions_result_topics, [:pointer, :pointer], :pointer
315
+
316
+ # Delete Group
317
+
318
+ RD_KAFKA_ADMIN_OP_DELETEGROUPS = 7 # rd_kafka_admin_op_t
319
+ RD_KAFKA_EVENT_DELETEGROUPS_RESULT = 106 # rd_kafka_event_type_t
320
+
321
+ attach_function :rd_kafka_DeleteGroups, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
322
+ attach_function :rd_kafka_DeleteGroup_new, [:pointer], :pointer, blocking: true
323
+ attach_function :rd_kafka_DeleteGroup_destroy, [:pointer], :void, blocking: true
324
+ attach_function :rd_kafka_event_DeleteGroups_result, [:pointer], :pointer, blocking: true # rd_kafka_event_t* => rd_kafka_DeleteGroups_result_t*
325
+ attach_function :rd_kafka_DeleteGroups_result_groups, [:pointer, :pointer], :pointer, blocking: true # rd_kafka_DeleteGroups_result_t*, size_t* => rd_kafka_group_result_t**
326
+
305
327
  # Background Queue and Callback
306
328
 
307
329
  attach_function :rd_kafka_queue_get_background, [:pointer], :pointer
@@ -324,5 +346,102 @@ module Rdkafka
324
346
  attach_function :rd_kafka_topic_result_error, [:pointer], :int32
325
347
  attach_function :rd_kafka_topic_result_error_string, [:pointer], :pointer
326
348
  attach_function :rd_kafka_topic_result_name, [:pointer], :pointer
349
+
350
+ # Create Acls
351
+
352
+ RD_KAFKA_ADMIN_OP_CREATEACLS = 9
353
+ RD_KAFKA_EVENT_CREATEACLS_RESULT = 1024
354
+
355
+ attach_function :rd_kafka_CreateAcls, [:pointer, :pointer, :size_t, :pointer, :pointer], :void
356
+ attach_function :rd_kafka_event_CreateAcls_result, [:pointer], :pointer
357
+ attach_function :rd_kafka_CreateAcls_result_acls, [:pointer, :pointer], :pointer
358
+
359
+ # Delete Acls
360
+
361
+ RD_KAFKA_ADMIN_OP_DELETEACLS = 11
362
+ RD_KAFKA_EVENT_DELETEACLS_RESULT = 4096
363
+
364
+ attach_function :rd_kafka_DeleteAcls, [:pointer, :pointer, :size_t, :pointer, :pointer], :void
365
+ attach_function :rd_kafka_event_DeleteAcls_result, [:pointer], :pointer
366
+ attach_function :rd_kafka_DeleteAcls_result_responses, [:pointer, :pointer], :pointer
367
+ attach_function :rd_kafka_DeleteAcls_result_response_error, [:pointer], :pointer
368
+ attach_function :rd_kafka_DeleteAcls_result_response_matching_acls, [:pointer, :pointer], :pointer
369
+
370
+ # Describe Acls
371
+
372
+ RD_KAFKA_ADMIN_OP_DESCRIBEACLS = 10
373
+ RD_KAFKA_EVENT_DESCRIBEACLS_RESULT = 2048
374
+
375
+ attach_function :rd_kafka_DescribeAcls, [:pointer, :pointer, :pointer, :pointer], :void
376
+ attach_function :rd_kafka_event_DescribeAcls_result, [:pointer], :pointer
377
+ attach_function :rd_kafka_DescribeAcls_result_acls, [:pointer, :pointer], :pointer
378
+
379
+ # Acl Bindings
380
+
381
+ attach_function :rd_kafka_AclBinding_restype, [:pointer], :int32
382
+ attach_function :rd_kafka_AclBinding_name, [:pointer], :pointer
383
+ attach_function :rd_kafka_AclBinding_resource_pattern_type, [:pointer], :int32
384
+ attach_function :rd_kafka_AclBinding_principal, [:pointer], :pointer
385
+ attach_function :rd_kafka_AclBinding_host, [:pointer], :pointer
386
+ attach_function :rd_kafka_AclBinding_operation, [:pointer], :int32
387
+ attach_function :rd_kafka_AclBinding_permission_type, [:pointer], :int32
388
+ attach_function :rd_kafka_AclBinding_new, [:int32, :pointer, :int32, :pointer, :pointer, :int32, :int32, :pointer, :size_t ], :pointer
389
+ attach_function :rd_kafka_AclBindingFilter_new, [:int32, :pointer, :int32, :pointer, :pointer, :int32, :int32, :pointer, :size_t ], :pointer
390
+ attach_function :rd_kafka_AclBinding_destroy, [:pointer], :void
391
+
392
+ # rd_kafka_ResourceType_t - https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L7307
393
+
394
+ RD_KAFKA_RESOURCE_ANY = 1
395
+ RD_KAFKA_RESOURCE_TOPIC = 2
396
+ RD_KAFKA_RESOURCE_GROUP = 3
397
+
398
+ # rd_kafka_ResourcePatternType_t - https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L7320
399
+
400
+ RD_KAFKA_RESOURCE_PATTERN_ANY = 1
401
+ RD_KAFKA_RESOURCE_PATTERN_MATCH = 2
402
+ RD_KAFKA_RESOURCE_PATTERN_LITERAL = 3
403
+ RD_KAFKA_RESOURCE_PATTERN_PREFIXED = 4
404
+
405
+ # rd_kafka_AclOperation_t - https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L8403
406
+
407
+ RD_KAFKA_ACL_OPERATION_ANY = 1
408
+ RD_KAFKA_ACL_OPERATION_ALL = 2
409
+ RD_KAFKA_ACL_OPERATION_READ = 3
410
+ RD_KAFKA_ACL_OPERATION_WRITE = 4
411
+ RD_KAFKA_ACL_OPERATION_CREATE = 5
412
+ RD_KAFKA_ACL_OPERATION_DELETE = 6
413
+ RD_KAFKA_ACL_OPERATION_ALTER = 7
414
+ RD_KAFKA_ACL_OPERATION_DESCRIBE = 8
415
+ RD_KAFKA_ACL_OPERATION_CLUSTER_ACTION = 9
416
+ RD_KAFKA_ACL_OPERATION_DESCRIBE_CONFIGS = 10
417
+ RD_KAFKA_ACL_OPERATION_ALTER_CONFIGS = 11
418
+ RD_KAFKA_ACL_OPERATION_IDEMPOTENT_WRITE = 12
419
+
420
+ # rd_kafka_AclPermissionType_t - https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L8435
421
+
422
+ RD_KAFKA_ACL_PERMISSION_TYPE_ANY = 1
423
+ RD_KAFKA_ACL_PERMISSION_TYPE_DENY = 2
424
+ RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW = 3
425
+
426
+ # Extracting error details from Acl results
427
+ attach_function :rd_kafka_acl_result_error, [:pointer], :pointer
428
+ attach_function :rd_kafka_error_code, [:pointer], :int32
429
+ attach_function :rd_kafka_error_string, [:pointer], :pointer
430
+ attach_function :rd_kafka_event_error, [:pointer], :int32
431
+ attach_function :rd_kafka_event_error_string, [:pointer], :pointer
432
+ attach_function :rd_kafka_AclBinding_error, [:pointer], :pointer
433
+
434
+
435
+ # Extracting data from group results
436
+ class NativeError < FFI::Struct # rd_kafka_error_t
437
+ layout :code, :int32,
438
+ :errstr, :pointer,
439
+ :fatal, :uint8_t,
440
+ :retriable, :uint8_t,
441
+ :txn_requires_abort, :uint8_t
442
+ end
443
+
444
+ attach_function :rd_kafka_group_result_error, [:pointer], NativeError.by_ref # rd_kafka_group_result_t* => rd_kafka_error_t*
445
+ attach_function :rd_kafka_group_result_name, [:pointer], :pointer
327
446
  end
328
447
  end