rdkafka 0.28.0-x86_64-linux-gnu → 0.29.0-x86_64-linux-gnu

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +1 -0
  4. data/docker-compose-ssl.yml +1 -1
  5. data/docker-compose.yml +1 -1
  6. data/ext/librdkafka.so +0 -0
  7. data/lib/rdkafka/abstract_handle.rb +31 -2
  8. data/lib/rdkafka/admin/config_binding_result.rb +2 -2
  9. data/lib/rdkafka/admin/create_acl_handle.rb +6 -5
  10. data/lib/rdkafka/admin/create_partitions_handle.rb +4 -6
  11. data/lib/rdkafka/admin/create_topic_handle.rb +4 -6
  12. data/lib/rdkafka/admin/delete_acl_handle.rb +5 -7
  13. data/lib/rdkafka/admin/delete_groups_handle.rb +4 -6
  14. data/lib/rdkafka/admin/delete_topic_handle.rb +4 -6
  15. data/lib/rdkafka/admin/describe_acl_handle.rb +5 -7
  16. data/lib/rdkafka/admin/describe_configs_handle.rb +4 -10
  17. data/lib/rdkafka/admin/describe_configs_report.rb +1 -5
  18. data/lib/rdkafka/admin/incremental_alter_configs_handle.rb +4 -10
  19. data/lib/rdkafka/admin/incremental_alter_configs_report.rb +1 -5
  20. data/lib/rdkafka/admin/list_offsets_handle.rb +5 -10
  21. data/lib/rdkafka/admin.rb +75 -43
  22. data/lib/rdkafka/bindings.rb +9 -4
  23. data/lib/rdkafka/callbacks/base_handler.rb +62 -0
  24. data/lib/rdkafka/callbacks/create_acl_handler.rb +37 -0
  25. data/lib/rdkafka/callbacks/create_partitions_handler.rb +37 -0
  26. data/lib/rdkafka/callbacks/create_topic_handler.rb +37 -0
  27. data/lib/rdkafka/callbacks/delete_acl_handler.rb +42 -0
  28. data/lib/rdkafka/callbacks/delete_groups_handler.rb +37 -0
  29. data/lib/rdkafka/callbacks/delete_topic_handler.rb +37 -0
  30. data/lib/rdkafka/callbacks/describe_acl_handler.rb +35 -0
  31. data/lib/rdkafka/callbacks/describe_configs_handler.rb +42 -0
  32. data/lib/rdkafka/callbacks/incremental_alter_configs_handler.rb +42 -0
  33. data/lib/rdkafka/callbacks/list_offsets_handler.rb +42 -0
  34. data/lib/rdkafka/callbacks.rb +50 -244
  35. data/lib/rdkafka/config.rb +45 -33
  36. data/lib/rdkafka/consumer/headers.rb +19 -5
  37. data/lib/rdkafka/consumer/partition.rb +8 -1
  38. data/lib/rdkafka/consumer/topic_partition_list.rb +44 -22
  39. data/lib/rdkafka/consumer.rb +111 -21
  40. data/lib/rdkafka/defaults.rb +19 -0
  41. data/lib/rdkafka/helpers/metadata.rb +29 -0
  42. data/lib/rdkafka/metadata.rb +86 -19
  43. data/lib/rdkafka/native_kafka.rb +2 -4
  44. data/lib/rdkafka/producer/delivery_handle.rb +3 -3
  45. data/lib/rdkafka/producer/partitions_count_cache.rb +24 -38
  46. data/lib/rdkafka/producer.rb +56 -44
  47. data/lib/rdkafka/version.rb +3 -3
  48. data/lib/rdkafka.rb +12 -0
  49. data/package-lock.json +3 -3
  50. data/rdkafka.gemspec +1 -0
  51. metadata +13 -4
  52. data/Gemfile +0 -13
  53. data/Gemfile.lint +0 -14
  54. data/Gemfile.lint.lock +0 -123
data/lib/rdkafka/admin.rb CHANGED
@@ -4,6 +4,7 @@ module Rdkafka
4
4
  # Admin client for Kafka administrative operations
5
5
  class Admin
6
6
  include Helpers::OAuth
7
+ include Helpers::Metadata
7
8
 
8
9
  class << self
9
10
  # Allows us to retrieve librdkafka errors with descriptions
@@ -130,19 +131,6 @@ module Rdkafka
130
131
  end
131
132
  end
132
133
 
133
- # Performs the metadata request using admin
134
- #
135
- # @param topic_name [String, nil] metadat about particular topic or all if nil
136
- # @param timeout_ms [Integer] metadata request timeout
137
- # @return [Metadata] requested metadata
138
- def metadata(topic_name = nil, timeout_ms = Defaults::METADATA_TIMEOUT_MS)
139
- closed_admin_check(__method__)
140
-
141
- @native_kafka.with_inner do |inner|
142
- Metadata.new(inner, topic_name, timeout_ms)
143
- end
144
- end
145
-
146
134
  # Close this admin instance
147
135
  def close
148
136
  return if closed?
@@ -258,7 +246,7 @@ module Rdkafka
258
246
  Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
259
247
  end
260
248
  if queue_ptr.null?
261
- Rdkafka::Bindings.rd_kafka_DeleteTopic_destroy(delete_topic_ptr)
249
+ Rdkafka::Bindings.rd_kafka_DeleteGroup_destroy(delete_groups_ptr)
262
250
  raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
263
251
  end
264
252
 
@@ -581,7 +569,7 @@ module Rdkafka
581
569
  end
582
570
 
583
571
  if queue_ptr.null?
584
- Rdkafka::Bindings.rd_kafka_AclBinding_destroy(new_acl_ptr)
572
+ Rdkafka::Bindings.rd_kafka_AclBinding_destroy(delete_acl_ptr)
585
573
  raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
586
574
  end
587
575
 
@@ -677,7 +665,7 @@ module Rdkafka
677
665
  end
678
666
 
679
667
  if queue_ptr.null?
680
- Rdkafka::Bindings.rd_kafka_AclBinding_destroy(new_acl_ptr)
668
+ Rdkafka::Bindings.rd_kafka_AclBinding_destroy(describe_acl_ptr)
681
669
  raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
682
670
  end
683
671
 
@@ -728,6 +716,14 @@ module Rdkafka
728
716
  def describe_configs(resources)
729
717
  closed_admin_check(__method__)
730
718
 
719
+ # Parse user input before allocating any native resources or registering the handle, so a
720
+ # missing :resource_type / :resource_name key raises with nothing to clean up. Previously the
721
+ # KeyError leaked the background queue, the AdminOptions, the registered handle and any
722
+ # ConfigResources already built.
723
+ parsed_resources = resources.map do |resource_details|
724
+ [resource_details.fetch(:resource_type), resource_details.fetch(:resource_name)]
725
+ end
726
+
731
727
  handle = DescribeConfigsHandle.new
732
728
  handle[:pending] = true
733
729
  handle[:response] = Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
@@ -750,12 +746,10 @@ module Rdkafka
750
746
  DescribeConfigsHandle.register(handle)
751
747
  Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, handle.to_ptr)
752
748
 
753
- pointer_array = resources.map do |resource_details|
749
+ pointer_array = parsed_resources.map do |resource_type, resource_name|
754
750
  Rdkafka::Bindings.rd_kafka_ConfigResource_new(
755
- resource_details.fetch(:resource_type),
756
- FFI::MemoryPointer.from_string(
757
- resource_details.fetch(:resource_name)
758
- )
751
+ resource_type,
752
+ FFI::MemoryPointer.from_string(resource_name)
759
753
  )
760
754
  end
761
755
 
@@ -806,6 +800,19 @@ module Rdkafka
806
800
  def incremental_alter_configs(resources_with_configs)
807
801
  closed_admin_check(__method__)
808
802
 
803
+ # Parse user input before allocating native resources or registering the handle, so a missing
804
+ # key raises with nothing to clean up. Previously the KeyError leaked the background queue,
805
+ # the AdminOptions, the registered handle and any ConfigResources already built.
806
+ parsed_resources = resources_with_configs.map do |resource_details|
807
+ [
808
+ resource_details.fetch(:resource_type),
809
+ resource_details.fetch(:resource_name),
810
+ resource_details.fetch(:configs).map do |config|
811
+ [config.fetch(:name), config.fetch(:op_type), config.fetch(:value)]
812
+ end
813
+ ]
814
+ end
815
+
809
816
  handle = IncrementalAlterConfigsHandle.new
810
817
  handle[:pending] = true
811
818
  handle[:response] = Rdkafka::Bindings::RD_KAFKA_PARTITION_UA
@@ -828,23 +835,39 @@ module Rdkafka
828
835
  IncrementalAlterConfigsHandle.register(handle)
829
836
  Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, handle.to_ptr)
830
837
 
831
- # Tu poprawnie tworzyc
832
- pointer_array = resources_with_configs.map do |resource_details|
838
+ add_error = nil
839
+
840
+ pointer_array = parsed_resources.map do |resource_type, resource_name, configs|
833
841
  # First build the appropriate resource representation
834
842
  resource_ptr = Rdkafka::Bindings.rd_kafka_ConfigResource_new(
835
- resource_details.fetch(:resource_type),
836
- FFI::MemoryPointer.from_string(
837
- resource_details.fetch(:resource_name)
838
- )
843
+ resource_type,
844
+ FFI::MemoryPointer.from_string(resource_name)
839
845
  )
840
846
 
841
- resource_details.fetch(:configs).each do |config|
842
- Bindings.rd_kafka_ConfigResource_add_incremental_config(
847
+ configs.each do |name, op_type, value|
848
+ # rd_kafka_ConfigResource_add_incremental_config returns a non-NULL rd_kafka_error_t for
849
+ # an invalid op_type, an empty/nil name, or a nil value on a non-delete op. The result
850
+ # used to be ignored: the entry was silently dropped, the alter request still reported
851
+ # success, and the error object leaked. Capture the first error (always destroying the
852
+ # native error object) and raise it below, before the request is sent.
853
+ error_ptr = Bindings.rd_kafka_ConfigResource_add_incremental_config(
843
854
  resource_ptr,
844
- config.fetch(:name),
845
- config.fetch(:op_type),
846
- config.fetch(:value)
855
+ name,
856
+ op_type,
857
+ value
847
858
  )
859
+
860
+ unless error_ptr.null?
861
+ code = Rdkafka::Bindings.rd_kafka_error_code(error_ptr)
862
+ Rdkafka::Bindings.rd_kafka_error_destroy(error_ptr)
863
+
864
+ unless code == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
865
+ add_error ||= Rdkafka::RdkafkaError.new(
866
+ code,
867
+ "rd_kafka_ConfigResource_add_incremental_config"
868
+ )
869
+ end
870
+ end
848
871
  end
849
872
 
850
873
  resource_ptr
@@ -854,6 +877,10 @@ module Rdkafka
854
877
  configs_array_ptr.write_array_of_pointer(pointer_array)
855
878
 
856
879
  begin
880
+ # Raise only after the full array is built so the ensure below frees every ConfigResource
881
+ # we created, and before the request is sent so a rejected entry can't report success.
882
+ raise add_error if add_error
883
+
857
884
  @native_kafka.with_inner do |inner|
858
885
  Rdkafka::Bindings.rd_kafka_IncrementalAlterConfigs(
859
886
  inner,
@@ -912,15 +939,12 @@ module Rdkafka
912
939
  def list_offsets(topic_partition_offsets, isolation_level: nil)
913
940
  closed_admin_check(__method__)
914
941
 
915
- # Count total partitions for pre-allocation
916
- total = topic_partition_offsets.sum { |_, partitions| partitions.size }
917
-
918
- # Build native topic partition list
919
- tpl = Rdkafka::Bindings.rd_kafka_topic_partition_list_new(total)
920
-
921
- topic_partition_offsets.each do |topic, partitions|
922
- partitions.each do |spec|
923
- partition = spec.fetch(:partition)
942
+ # Parse and validate every offset spec before allocating the native list, so a missing key or
943
+ # an unknown offset specification raises with nothing to clean up. Previously the
944
+ # ArgumentError (or KeyError) was raised after `rd_kafka_topic_partition_list_new`, leaking
945
+ # the native list.
946
+ parsed = topic_partition_offsets.flat_map do |topic, partitions|
947
+ partitions.map do |spec|
924
948
  offset = spec.fetch(:offset)
925
949
 
926
950
  native_offset = case offset
@@ -932,11 +956,18 @@ module Rdkafka
932
956
  raise ArgumentError, "Unknown offset specification: #{offset.inspect}"
933
957
  end
934
958
 
935
- Rdkafka::Bindings.rd_kafka_topic_partition_list_add(tpl, topic, partition)
936
- Rdkafka::Bindings.rd_kafka_topic_partition_list_set_offset(tpl, topic, partition, native_offset)
959
+ [topic, spec.fetch(:partition), native_offset]
937
960
  end
938
961
  end
939
962
 
963
+ # Build native topic partition list
964
+ tpl = Rdkafka::Bindings.rd_kafka_topic_partition_list_new(parsed.size)
965
+
966
+ parsed.each do |topic, partition, native_offset|
967
+ Rdkafka::Bindings.rd_kafka_topic_partition_list_add(tpl, topic, partition)
968
+ Rdkafka::Bindings.rd_kafka_topic_partition_list_set_offset(tpl, topic, partition, native_offset)
969
+ end
970
+
940
971
  # Get a pointer to the queue that our request will be enqueued on
941
972
  queue_ptr = @native_kafka.with_inner do |inner|
942
973
  Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
@@ -995,5 +1026,6 @@ module Rdkafka
995
1026
  def closed_admin_check(method)
996
1027
  raise Rdkafka::ClosedAdminError.new(method) if closed?
997
1028
  end
1029
+ alias_method :closed_check, :closed_admin_check
998
1030
  end
999
1031
  end
@@ -99,8 +99,9 @@ module Rdkafka
99
99
  # Metadata
100
100
 
101
101
  attach_function :rd_kafka_name, [:pointer], :string
102
- attach_function :rd_kafka_memberid, [:pointer], :string, blocking: true
103
- attach_function :rd_kafka_clusterid, [:pointer], :string, blocking: true
102
+ attach_function :rd_kafka_memberid, [:pointer], :pointer, blocking: true
103
+ attach_function :rd_kafka_clusterid, [:pointer, :int], :pointer, blocking: true
104
+ attach_function :rd_kafka_mem_free, [:pointer, :pointer], :void
104
105
  attach_function :rd_kafka_metadata, [:pointer, :int, :pointer, :pointer, :int], :int, blocking: true
105
106
  attach_function :rd_kafka_metadata_destroy, [:pointer], :void, blocking: true
106
107
 
@@ -263,6 +264,7 @@ module Rdkafka
263
264
  attach_function :rd_kafka_queue_io_event_enable, [:pointer, :int, :pointer, :size_t], :void
264
265
  # Per topic configs
265
266
  attach_function :rd_kafka_topic_conf_new, [], :pointer
267
+ attach_function :rd_kafka_topic_conf_destroy, [:pointer], :void
266
268
  attach_function :rd_kafka_topic_conf_set, [:pointer, :string, :string, :pointer, :int], :kafka_config_response
267
269
 
268
270
  LogCallback = FFI::Function.new(
@@ -354,7 +356,9 @@ module Rdkafka
354
356
  OAuthbearerTokenRefreshCallback = FFI::Function.new(
355
357
  :void, [:pointer, :string, :pointer]
356
358
  ) do |client_ptr, config, _opaque|
357
- Rdkafka::Config.oauthbearer_token_refresh_callback&.call(config, Rdkafka::Bindings.rd_kafka_name(client_ptr))
359
+ if Rdkafka::Config.oauthbearer_token_refresh_callback && !client_ptr.null?
360
+ Rdkafka::Config.oauthbearer_token_refresh_callback.call(config, Rdkafka::Bindings.rd_kafka_name(client_ptr))
361
+ end
358
362
  end
359
363
 
360
364
  # Handle
@@ -444,7 +448,7 @@ module Rdkafka
444
448
 
445
449
  # Stats
446
450
 
447
- attach_function :rd_kafka_query_watermark_offsets, [:pointer, :string, :int, :pointer, :pointer, :int], :int
451
+ attach_function :rd_kafka_query_watermark_offsets, [:pointer, :string, :int, :pointer, :pointer, :int], :int, blocking: true
448
452
 
449
453
  # Producer
450
454
  RD_KAFKA_VTYPE_END = 0
@@ -552,6 +556,7 @@ module Rdkafka
552
556
 
553
557
  attach_function :rd_kafka_event_type, [:pointer], :int32
554
558
  attach_function :rd_kafka_event_opaque, [:pointer], :pointer
559
+ attach_function :rd_kafka_event_destroy, [:pointer], :void
555
560
 
556
561
  # Extracting data from topic results
557
562
 
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ module Callbacks
5
+ # Base class for admin background-event result handlers.
6
+ #
7
+ # Each subclass handles one librdkafka admin result event type: it extracts the result from
8
+ # the event, looks up the matching {AbstractHandle} in the registry and resolves it (sets the
9
+ # response, builds the report, copies the broker message, then unlocks it).
10
+ #
11
+ # The event is owned by the application and destroyed by {BackgroundEventCallback} right after
12
+ # dispatch, so handlers must copy everything they need out of event-owned memory into Ruby
13
+ # objects before returning.
14
+ #
15
+ # @private
16
+ class BaseHandler
17
+ class << self
18
+ # Processes a background event for the operation this handler is responsible for.
19
+ # @param event_ptr [FFI::Pointer] pointer to the event
20
+ # @return [void]
21
+ def call(event_ptr)
22
+ raise NotImplementedError, "#{name} must implement .call"
23
+ end
24
+
25
+ private
26
+
27
+ # Copies an event-owned C string into a Ruby string
28
+ # @param ptr [FFI::Pointer] pointer to the C string
29
+ # @return [String, nil] copied string or nil when NULL
30
+ def read_event_string(ptr)
31
+ ptr.null? ? nil : ptr.read_string
32
+ end
33
+
34
+ # Resolves a handle directly from an operation-level event error and unlocks it.
35
+ #
36
+ # librdkafka signals a failure of the whole admin operation (e.g. `_TIMED_OUT` when the
37
+ # brokers are unreachable, or `_DESTROY` when the client is closed with the request in
38
+ # flight) by setting the event error and delivering an *empty* results array. The
39
+ # per-element result handlers must not index into that empty array; they call this first
40
+ # and skip results parsing when it returns true. Without this, indexing `results[0]`
41
+ # raises inside the FFI callback, the handle is never unlocked, and the caller's `wait`
42
+ # blocks until its own timeout and raises `WaitTimeoutError`, losing the real error code.
43
+ #
44
+ # @param event_ptr [FFI::Pointer] pointer to the event
45
+ # @param handle [Rdkafka::AbstractHandle] the handle to resolve
46
+ # @return [Boolean] true when the event carried an operation-level error and the handle
47
+ # was resolved here
48
+ def resolve_operation_error(event_ptr, handle)
49
+ error_code = Rdkafka::Bindings.rd_kafka_event_error(event_ptr)
50
+
51
+ return false if error_code == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
52
+
53
+ handle[:response] = error_code
54
+ handle.broker_message = read_event_string(Rdkafka::Bindings.rd_kafka_event_error_string(event_ptr))
55
+ handle.unlock
56
+
57
+ true
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ module Callbacks
5
+ # Handles `RD_KAFKA_EVENT_CREATEACLS_RESULT` events
6
+ # @private
7
+ class CreateAclHandler < BaseHandler
8
+ class << self
9
+ # Resolves the create-ACL handle from its result event
10
+ # @param event_ptr [FFI::Pointer] pointer to the event
11
+ # @return [void]
12
+ def call(event_ptr)
13
+ create_acls_result = Rdkafka::Bindings.rd_kafka_event_CreateAcls_result(event_ptr)
14
+
15
+ # Get the number of acl results
16
+ pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
17
+ create_acl_result_array = Rdkafka::Bindings.rd_kafka_CreateAcls_result_acls(create_acls_result, pointer_to_size_t)
18
+ create_acl_results = CreateAclResult.create_acl_results_from_array(pointer_to_size_t.read_int, create_acl_result_array)
19
+ create_acl_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
20
+
21
+ if create_acl_handle = Rdkafka::Admin::CreateAclHandle.remove(create_acl_handle_ptr.address)
22
+ unless resolve_operation_error(event_ptr, create_acl_handle)
23
+ create_acl_handle[:response] = create_acl_results[0].result_error
24
+ create_acl_handle.result = Rdkafka::Admin::CreateAclReport.new(
25
+ rdkafka_response: create_acl_results[0].result_error,
26
+ rdkafka_response_string: create_acl_results[0].error_string
27
+ )
28
+ create_acl_handle.broker_message = create_acl_handle.result.rdkafka_response_string
29
+
30
+ create_acl_handle.unlock
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ module Callbacks
5
+ # Handles `RD_KAFKA_ADMIN_OP_CREATEPARTITIONS_RESULT` events
6
+ # @private
7
+ class CreatePartitionsHandler < BaseHandler
8
+ class << self
9
+ # Resolves the create-partitions handle from its result event
10
+ # @param event_ptr [FFI::Pointer] pointer to the event
11
+ # @return [void]
12
+ def call(event_ptr)
13
+ create_partitionss_result = Rdkafka::Bindings.rd_kafka_event_CreatePartitions_result(event_ptr)
14
+
15
+ # Get the number of create topic results
16
+ pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
17
+ create_partitions_result_array = Rdkafka::Bindings.rd_kafka_CreatePartitions_result_topics(create_partitionss_result, pointer_to_size_t)
18
+ create_partitions_results = TopicResult.create_topic_results_from_array(pointer_to_size_t.read_int, create_partitions_result_array)
19
+ create_partitions_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
20
+
21
+ if create_partitions_handle = Rdkafka::Admin::CreatePartitionsHandle.remove(create_partitions_handle_ptr.address)
22
+ unless resolve_operation_error(event_ptr, create_partitions_handle)
23
+ create_partitions_handle[:response] = create_partitions_results[0].result_error
24
+ create_partitions_handle.result = Rdkafka::Admin::CreatePartitionsReport.new(
25
+ create_partitions_results[0].error_string,
26
+ create_partitions_results[0].result_name
27
+ )
28
+ create_partitions_handle.broker_message = create_partitions_handle.result.error_string
29
+
30
+ create_partitions_handle.unlock
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ module Callbacks
5
+ # Handles `RD_KAFKA_EVENT_CREATETOPICS_RESULT` events
6
+ # @private
7
+ class CreateTopicHandler < BaseHandler
8
+ class << self
9
+ # Resolves the create-topic handle from its result event
10
+ # @param event_ptr [FFI::Pointer] pointer to the event
11
+ # @return [void]
12
+ def call(event_ptr)
13
+ create_topics_result = Rdkafka::Bindings.rd_kafka_event_CreateTopics_result(event_ptr)
14
+
15
+ # Get the number of create topic results
16
+ pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
17
+ create_topic_result_array = Rdkafka::Bindings.rd_kafka_CreateTopics_result_topics(create_topics_result, pointer_to_size_t)
18
+ create_topic_results = TopicResult.create_topic_results_from_array(pointer_to_size_t.read_int, create_topic_result_array)
19
+ create_topic_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
20
+
21
+ if create_topic_handle = Rdkafka::Admin::CreateTopicHandle.remove(create_topic_handle_ptr.address)
22
+ unless resolve_operation_error(event_ptr, create_topic_handle)
23
+ create_topic_handle[:response] = create_topic_results[0].result_error
24
+ create_topic_handle.result = Rdkafka::Admin::CreateTopicReport.new(
25
+ create_topic_results[0].error_string,
26
+ create_topic_results[0].result_name
27
+ )
28
+ create_topic_handle.broker_message = create_topic_handle.result.error_string
29
+
30
+ create_topic_handle.unlock
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ module Callbacks
5
+ # Handles `RD_KAFKA_EVENT_DELETEACLS_RESULT` events
6
+ # @private
7
+ class DeleteAclHandler < BaseHandler
8
+ class << self
9
+ # Resolves the delete-ACL handle from its result event
10
+ # @param event_ptr [FFI::Pointer] pointer to the event
11
+ # @return [void]
12
+ def call(event_ptr)
13
+ delete_acls_result = Rdkafka::Bindings.rd_kafka_event_DeleteAcls_result(event_ptr)
14
+
15
+ # Get the number of acl results
16
+ pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
17
+ delete_acl_result_responses = Rdkafka::Bindings.rd_kafka_DeleteAcls_result_responses(delete_acls_result, pointer_to_size_t)
18
+ delete_acl_results = DeleteAclResult.delete_acl_results_from_array(pointer_to_size_t.read_int, delete_acl_result_responses)
19
+ delete_acl_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
20
+
21
+ if delete_acl_handle = Rdkafka::Admin::DeleteAclHandle.remove(delete_acl_handle_ptr.address)
22
+ unless resolve_operation_error(event_ptr, delete_acl_handle)
23
+ delete_acl_handle[:response] = delete_acl_results[0].result_error
24
+ delete_acl_handle.broker_message = read_event_string(delete_acl_results[0].error_string)
25
+
26
+ delete_acl_handle.result = if delete_acl_results[0].result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
27
+ Rdkafka::Admin::DeleteAclReport.new(
28
+ matching_acls: delete_acl_results[0].matching_acls,
29
+ matching_acls_count: delete_acl_results[0].matching_acls_count
30
+ )
31
+ else
32
+ Rdkafka::Admin::DeleteAclReport.new(matching_acls: FFI::Pointer::NULL, matching_acls_count: 0)
33
+ end
34
+
35
+ delete_acl_handle.unlock
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ module Callbacks
5
+ # Handles `RD_KAFKA_EVENT_DELETEGROUPS_RESULT` events
6
+ # @private
7
+ class DeleteGroupsHandler < BaseHandler
8
+ class << self
9
+ # Resolves the delete-groups handle from its result event
10
+ # @param event_ptr [FFI::Pointer] pointer to the event
11
+ # @return [void]
12
+ def call(event_ptr)
13
+ delete_groups_result = Rdkafka::Bindings.rd_kafka_event_DeleteGroups_result(event_ptr)
14
+
15
+ # Get the number of delete group results
16
+ pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
17
+ delete_group_result_array = Rdkafka::Bindings.rd_kafka_DeleteGroups_result_groups(delete_groups_result, pointer_to_size_t)
18
+ delete_group_results = GroupResult.create_group_results_from_array(pointer_to_size_t.read_int, delete_group_result_array)
19
+ delete_group_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
20
+
21
+ if (delete_group_handle = Rdkafka::Admin::DeleteGroupsHandle.remove(delete_group_handle_ptr.address))
22
+ unless resolve_operation_error(event_ptr, delete_group_handle)
23
+ delete_group_handle[:response] = delete_group_results[0].result_error
24
+ delete_group_handle.result = Rdkafka::Admin::DeleteGroupsReport.new(
25
+ delete_group_results[0].error_string,
26
+ delete_group_results[0].result_name
27
+ )
28
+ delete_group_handle.broker_message = delete_group_handle.result.error_string
29
+
30
+ delete_group_handle.unlock
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ module Callbacks
5
+ # Handles `RD_KAFKA_EVENT_DELETETOPICS_RESULT` events
6
+ # @private
7
+ class DeleteTopicHandler < BaseHandler
8
+ class << self
9
+ # Resolves the delete-topic handle from its result event
10
+ # @param event_ptr [FFI::Pointer] pointer to the event
11
+ # @return [void]
12
+ def call(event_ptr)
13
+ delete_topics_result = Rdkafka::Bindings.rd_kafka_event_DeleteTopics_result(event_ptr)
14
+
15
+ # Get the number of topic results
16
+ pointer_to_size_t = FFI::MemoryPointer.new(:size_t)
17
+ delete_topic_result_array = Rdkafka::Bindings.rd_kafka_DeleteTopics_result_topics(delete_topics_result, pointer_to_size_t)
18
+ delete_topic_results = TopicResult.create_topic_results_from_array(pointer_to_size_t.read_int, delete_topic_result_array)
19
+ delete_topic_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
20
+
21
+ if delete_topic_handle = Rdkafka::Admin::DeleteTopicHandle.remove(delete_topic_handle_ptr.address)
22
+ unless resolve_operation_error(event_ptr, delete_topic_handle)
23
+ delete_topic_handle[:response] = delete_topic_results[0].result_error
24
+ delete_topic_handle.result = Rdkafka::Admin::DeleteTopicReport.new(
25
+ delete_topic_results[0].error_string,
26
+ delete_topic_results[0].result_name
27
+ )
28
+ delete_topic_handle.broker_message = delete_topic_handle.result.error_string
29
+
30
+ delete_topic_handle.unlock
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ module Callbacks
5
+ # Handles `RD_KAFKA_EVENT_DESCRIBEACLS_RESULT` events
6
+ # @private
7
+ class DescribeAclHandler < BaseHandler
8
+ class << self
9
+ # Resolves the describe-ACL handle from its result event
10
+ # @param event_ptr [FFI::Pointer] pointer to the event
11
+ # @return [void]
12
+ def call(event_ptr)
13
+ describe_acl = DescribeAclResult.new(event_ptr)
14
+ describe_acl_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
15
+
16
+ if describe_acl_handle = Rdkafka::Admin::DescribeAclHandle.remove(describe_acl_handle_ptr.address)
17
+ describe_acl_handle[:response] = describe_acl.result_error
18
+ describe_acl_handle.broker_message = read_event_string(describe_acl.error_string)
19
+
20
+ describe_acl_handle.result = if describe_acl.result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
21
+ Rdkafka::Admin::DescribeAclReport.new(
22
+ acls: describe_acl.matching_acls,
23
+ acls_count: describe_acl.matching_acls_count
24
+ )
25
+ else
26
+ Rdkafka::Admin::DescribeAclReport.new(acls: FFI::Pointer::NULL, acls_count: 0)
27
+ end
28
+
29
+ describe_acl_handle.unlock
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ module Callbacks
5
+ # Handles `RD_KAFKA_EVENT_DESCRIBECONFIGS_RESULT` events
6
+ # @private
7
+ class DescribeConfigsHandler < BaseHandler
8
+ class << self
9
+ # Resolves the describe-configs handle from its result event
10
+ # @param event_ptr [FFI::Pointer] pointer to the event
11
+ # @return [void]
12
+ def call(event_ptr)
13
+ describe_configs = DescribeConfigsResult.new(event_ptr)
14
+ describe_configs_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
15
+
16
+ if describe_configs_handle = Rdkafka::Admin::DescribeConfigsHandle.remove(describe_configs_handle_ptr.address)
17
+ describe_configs_handle[:response] = describe_configs.result_error
18
+ describe_configs_handle.broker_message = read_event_string(describe_configs.error_string)
19
+
20
+ # Parsing can raise on per-resource errors. The exception is captured and re-raised on
21
+ # the waiting thread, since an exception leaving this callback would unwind through
22
+ # librdkafka native frames.
23
+ describe_configs_handle.result = begin
24
+ if describe_configs.result_error == Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR
25
+ Rdkafka::Admin::DescribeConfigsReport.new(
26
+ config_entries: describe_configs.results,
27
+ entry_count: describe_configs.results_count
28
+ )
29
+ else
30
+ Rdkafka::Admin::DescribeConfigsReport.new(config_entries: FFI::Pointer::NULL, entry_count: 0)
31
+ end
32
+ rescue => e
33
+ e
34
+ end
35
+
36
+ describe_configs_handle.unlock
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end