karafka-rdkafka 0.14.10 → 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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/workflows/ci.yml +2 -4
- data/.gitignore +2 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +11 -0
- data/README.md +19 -9
- data/docker-compose.yml +1 -1
- data/ext/Rakefile +8 -0
- data/lib/rdkafka/abstract_handle.rb +44 -20
- data/lib/rdkafka/admin/config_binding_result.rb +30 -0
- data/lib/rdkafka/admin/config_resource_binding_result.rb +18 -0
- data/lib/rdkafka/admin/create_topic_report.rb +1 -1
- data/lib/rdkafka/admin/delete_groups_report.rb +1 -1
- data/lib/rdkafka/admin/delete_topic_report.rb +1 -1
- data/lib/rdkafka/admin/describe_acl_report.rb +1 -0
- data/lib/rdkafka/admin/describe_configs_handle.rb +33 -0
- data/lib/rdkafka/admin/describe_configs_report.rb +48 -0
- data/lib/rdkafka/admin/incremental_alter_configs_handle.rb +33 -0
- data/lib/rdkafka/admin/incremental_alter_configs_report.rb +48 -0
- data/lib/rdkafka/admin.rb +174 -0
- data/lib/rdkafka/bindings.rb +75 -3
- data/lib/rdkafka/callbacks.rb +103 -19
- data/lib/rdkafka/config.rb +46 -9
- data/lib/rdkafka/consumer.rb +7 -0
- data/lib/rdkafka/helpers/oauth.rb +58 -0
- data/lib/rdkafka/native_kafka.rb +32 -19
- data/lib/rdkafka/producer.rb +7 -0
- data/lib/rdkafka/version.rb +1 -1
- data/lib/rdkafka.rb +7 -0
- data/spec/rdkafka/abstract_handle_spec.rb +34 -21
- data/spec/rdkafka/admin_spec.rb +328 -3
- data/spec/rdkafka/bindings_spec.rb +97 -0
- data/spec/rdkafka/config_spec.rb +33 -0
- data/spec/rdkafka/consumer_spec.rb +50 -1
- data/spec/rdkafka/native_kafka_spec.rb +8 -1
- data/spec/rdkafka/producer_spec.rb +43 -0
- data/spec/spec_helper.rb +16 -1
- data.tar.gz.sig +0 -0
- metadata +10 -3
- metadata.gz.sig +0 -0
data/lib/rdkafka/admin.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Rdkafka
|
4
4
|
class Admin
|
5
|
+
include Helpers::OAuth
|
6
|
+
|
5
7
|
# @private
|
6
8
|
def initialize(native_kafka)
|
7
9
|
@native_kafka = native_kafka
|
@@ -10,6 +12,19 @@ module Rdkafka
|
|
10
12
|
ObjectSpace.define_finalizer(self, native_kafka.finalizer)
|
11
13
|
end
|
12
14
|
|
15
|
+
# Starts the native Kafka polling thread and kicks off the init polling
|
16
|
+
# @note Not needed to run unless explicit start was disabled
|
17
|
+
def start
|
18
|
+
@native_kafka.start
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [String] admin name
|
22
|
+
def name
|
23
|
+
@name ||= @native_kafka.with_inner do |inner|
|
24
|
+
::Rdkafka::Bindings.rd_kafka_name(inner)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
13
28
|
def finalizer
|
14
29
|
->(_) { close }
|
15
30
|
end
|
@@ -605,6 +620,165 @@ module Rdkafka
|
|
605
620
|
describe_acl_handle
|
606
621
|
end
|
607
622
|
|
623
|
+
# Describe configs
|
624
|
+
#
|
625
|
+
# @param resources [Array<Hash>] Array where elements are hashes with two keys:
|
626
|
+
# - `:resource_type` - numerical resource type based on Kafka API
|
627
|
+
# - `:resource_name` - string with resource name
|
628
|
+
# @return [DescribeConfigsHandle] Describe config handle that can be used to wait for the
|
629
|
+
# result of fetching resources with their appropriate configs
|
630
|
+
#
|
631
|
+
# @raise [RdkafkaError]
|
632
|
+
#
|
633
|
+
# @note Several resources can be requested at one go, but only one broker at a time
|
634
|
+
def describe_configs(resources)
|
635
|
+
closed_admin_check(__method__)
|
636
|
+
|
637
|
+
handle = DescribeConfigsHandle.new
|
638
|
+
handle[:pending] = true
|
639
|
+
handle[:response] = -1
|
640
|
+
|
641
|
+
queue_ptr = @native_kafka.with_inner do |inner|
|
642
|
+
Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
|
643
|
+
end
|
644
|
+
|
645
|
+
if queue_ptr.null?
|
646
|
+
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
647
|
+
end
|
648
|
+
|
649
|
+
admin_options_ptr = @native_kafka.with_inner do |inner|
|
650
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_new(
|
651
|
+
inner,
|
652
|
+
Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_DESCRIBECONFIGS
|
653
|
+
)
|
654
|
+
end
|
655
|
+
|
656
|
+
DescribeConfigsHandle.register(handle)
|
657
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, handle.to_ptr)
|
658
|
+
|
659
|
+
pointer_array = resources.map do |resource_details|
|
660
|
+
Rdkafka::Bindings.rd_kafka_ConfigResource_new(
|
661
|
+
resource_details.fetch(:resource_type),
|
662
|
+
FFI::MemoryPointer.from_string(
|
663
|
+
resource_details.fetch(:resource_name)
|
664
|
+
)
|
665
|
+
)
|
666
|
+
end
|
667
|
+
|
668
|
+
configs_array_ptr = FFI::MemoryPointer.new(:pointer, pointer_array.size)
|
669
|
+
configs_array_ptr.write_array_of_pointer(pointer_array)
|
670
|
+
|
671
|
+
begin
|
672
|
+
@native_kafka.with_inner do |inner|
|
673
|
+
Rdkafka::Bindings.rd_kafka_DescribeConfigs(
|
674
|
+
inner,
|
675
|
+
configs_array_ptr,
|
676
|
+
pointer_array.size,
|
677
|
+
admin_options_ptr,
|
678
|
+
queue_ptr
|
679
|
+
)
|
680
|
+
end
|
681
|
+
rescue Exception
|
682
|
+
DescribeConfigsHandle.remove(handle.to_ptr.address)
|
683
|
+
|
684
|
+
raise
|
685
|
+
ensure
|
686
|
+
Rdkafka::Bindings.rd_kafka_ConfigResource_destroy_array(
|
687
|
+
configs_array_ptr,
|
688
|
+
pointer_array.size
|
689
|
+
) if configs_array_ptr
|
690
|
+
end
|
691
|
+
|
692
|
+
handle
|
693
|
+
end
|
694
|
+
|
695
|
+
# Alters in an incremental way all the configs provided for given resources
|
696
|
+
#
|
697
|
+
# @param resources_with_configs [Array<Hash>] resources with the configs key that contains
|
698
|
+
# name, value and the proper op_type to perform on this value.
|
699
|
+
#
|
700
|
+
# @return [IncrementalAlterConfigsHandle] Incremental alter configs handle that can be used to
|
701
|
+
# wait for the result of altering resources with their appropriate configs
|
702
|
+
#
|
703
|
+
# @raise [RdkafkaError]
|
704
|
+
#
|
705
|
+
# @note Several resources can be requested at one go, but only one broker at a time
|
706
|
+
# @note The results won't contain altered values but only the altered resources
|
707
|
+
def incremental_alter_configs(resources_with_configs)
|
708
|
+
closed_admin_check(__method__)
|
709
|
+
|
710
|
+
handle = IncrementalAlterConfigsHandle.new
|
711
|
+
handle[:pending] = true
|
712
|
+
handle[:response] = -1
|
713
|
+
|
714
|
+
queue_ptr = @native_kafka.with_inner do |inner|
|
715
|
+
Rdkafka::Bindings.rd_kafka_queue_get_background(inner)
|
716
|
+
end
|
717
|
+
|
718
|
+
if queue_ptr.null?
|
719
|
+
raise Rdkafka::Config::ConfigError.new("rd_kafka_queue_get_background was NULL")
|
720
|
+
end
|
721
|
+
|
722
|
+
admin_options_ptr = @native_kafka.with_inner do |inner|
|
723
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_new(
|
724
|
+
inner,
|
725
|
+
Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_INCREMENTALALTERCONFIGS
|
726
|
+
)
|
727
|
+
end
|
728
|
+
|
729
|
+
IncrementalAlterConfigsHandle.register(handle)
|
730
|
+
Rdkafka::Bindings.rd_kafka_AdminOptions_set_opaque(admin_options_ptr, handle.to_ptr)
|
731
|
+
|
732
|
+
# Tu poprawnie tworzyc
|
733
|
+
pointer_array = resources_with_configs.map do |resource_details|
|
734
|
+
# First build the appropriate resource representation
|
735
|
+
resource_ptr = Rdkafka::Bindings.rd_kafka_ConfigResource_new(
|
736
|
+
resource_details.fetch(:resource_type),
|
737
|
+
FFI::MemoryPointer.from_string(
|
738
|
+
resource_details.fetch(:resource_name)
|
739
|
+
)
|
740
|
+
)
|
741
|
+
|
742
|
+
resource_details.fetch(:configs).each do |config|
|
743
|
+
Bindings.rd_kafka_ConfigResource_add_incremental_config(
|
744
|
+
resource_ptr,
|
745
|
+
config.fetch(:name),
|
746
|
+
config.fetch(:op_type),
|
747
|
+
config.fetch(:value)
|
748
|
+
)
|
749
|
+
end
|
750
|
+
|
751
|
+
resource_ptr
|
752
|
+
end
|
753
|
+
|
754
|
+
configs_array_ptr = FFI::MemoryPointer.new(:pointer, pointer_array.size)
|
755
|
+
configs_array_ptr.write_array_of_pointer(pointer_array)
|
756
|
+
|
757
|
+
|
758
|
+
begin
|
759
|
+
@native_kafka.with_inner do |inner|
|
760
|
+
Rdkafka::Bindings.rd_kafka_IncrementalAlterConfigs(
|
761
|
+
inner,
|
762
|
+
configs_array_ptr,
|
763
|
+
pointer_array.size,
|
764
|
+
admin_options_ptr,
|
765
|
+
queue_ptr
|
766
|
+
)
|
767
|
+
end
|
768
|
+
rescue Exception
|
769
|
+
IncrementalAlterConfigsHandle.remove(handle.to_ptr.address)
|
770
|
+
|
771
|
+
raise
|
772
|
+
ensure
|
773
|
+
Rdkafka::Bindings.rd_kafka_ConfigResource_destroy_array(
|
774
|
+
configs_array_ptr,
|
775
|
+
pointer_array.size
|
776
|
+
) if configs_array_ptr
|
777
|
+
end
|
778
|
+
|
779
|
+
handle
|
780
|
+
end
|
781
|
+
|
608
782
|
private
|
609
783
|
|
610
784
|
def closed_admin_check(method)
|
data/lib/rdkafka/bindings.rb
CHANGED
@@ -26,6 +26,7 @@ module Rdkafka
|
|
26
26
|
|
27
27
|
RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS = -175
|
28
28
|
RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS = -174
|
29
|
+
RD_KAFKA_RESP_ERR__STATE = -172
|
29
30
|
RD_KAFKA_RESP_ERR__NOENT = -156
|
30
31
|
RD_KAFKA_RESP_ERR_NO_ERROR = 0
|
31
32
|
|
@@ -97,6 +98,48 @@ module Rdkafka
|
|
97
98
|
attach_function :rd_kafka_topic_partition_list_destroy, [:pointer], :void
|
98
99
|
attach_function :rd_kafka_topic_partition_list_copy, [:pointer], :pointer
|
99
100
|
|
101
|
+
# Configs management
|
102
|
+
#
|
103
|
+
# Structs for management of configurations
|
104
|
+
# Each configuration is attached to a resource and one resource can have many configuration
|
105
|
+
# details. Each resource will also have separate errors results if obtaining configuration
|
106
|
+
# was not possible for any reason
|
107
|
+
class ConfigResource < FFI::Struct
|
108
|
+
layout :type, :int,
|
109
|
+
:name, :string
|
110
|
+
end
|
111
|
+
|
112
|
+
attach_function :rd_kafka_DescribeConfigs, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
|
113
|
+
attach_function :rd_kafka_ConfigResource_new, [:int32, :pointer], :pointer
|
114
|
+
attach_function :rd_kafka_ConfigResource_destroy_array, [:pointer, :int32], :void
|
115
|
+
attach_function :rd_kafka_event_DescribeConfigs_result, [:pointer], :pointer
|
116
|
+
attach_function :rd_kafka_DescribeConfigs_result_resources, [:pointer, :pointer], :pointer
|
117
|
+
attach_function :rd_kafka_ConfigResource_configs, [:pointer, :pointer], :pointer
|
118
|
+
attach_function :rd_kafka_ConfigEntry_name, [:pointer], :string
|
119
|
+
attach_function :rd_kafka_ConfigEntry_value, [:pointer], :string
|
120
|
+
attach_function :rd_kafka_ConfigEntry_is_read_only, [:pointer], :int
|
121
|
+
attach_function :rd_kafka_ConfigEntry_is_default, [:pointer], :int
|
122
|
+
attach_function :rd_kafka_ConfigEntry_is_sensitive, [:pointer], :int
|
123
|
+
attach_function :rd_kafka_ConfigEntry_is_synonym, [:pointer], :int
|
124
|
+
attach_function :rd_kafka_ConfigEntry_synonyms, [:pointer, :pointer], :pointer
|
125
|
+
attach_function :rd_kafka_ConfigResource_error, [:pointer], :int
|
126
|
+
attach_function :rd_kafka_ConfigResource_error_string, [:pointer], :string
|
127
|
+
attach_function :rd_kafka_IncrementalAlterConfigs, [:pointer, :pointer, :size_t, :pointer, :pointer], :void, blocking: true
|
128
|
+
attach_function :rd_kafka_IncrementalAlterConfigs_result_resources, [:pointer, :pointer], :pointer
|
129
|
+
attach_function :rd_kafka_ConfigResource_add_incremental_config, [:pointer, :string, :int32, :string], :pointer
|
130
|
+
attach_function :rd_kafka_event_IncrementalAlterConfigs_result, [:pointer], :pointer
|
131
|
+
|
132
|
+
RD_KAFKA_ADMIN_OP_DESCRIBECONFIGS = 5
|
133
|
+
RD_KAFKA_EVENT_DESCRIBECONFIGS_RESULT = 104
|
134
|
+
|
135
|
+
RD_KAFKA_ADMIN_OP_INCREMENTALALTERCONFIGS = 16
|
136
|
+
RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT = 131072
|
137
|
+
|
138
|
+
RD_KAFKA_ALTER_CONFIG_OP_TYPE_SET = 0
|
139
|
+
RD_KAFKA_ALTER_CONFIG_OP_TYPE_DELETE = 1
|
140
|
+
RD_KAFKA_ALTER_CONFIG_OP_TYPE_APPEND = 2
|
141
|
+
RD_KAFKA_ALTER_CONFIG_OP_TYPE_SUBTRACT = 3
|
142
|
+
|
100
143
|
# Errors
|
101
144
|
|
102
145
|
attach_function :rd_kafka_err2name, [:int], :string
|
@@ -125,7 +168,10 @@ module Rdkafka
|
|
125
168
|
callback :error_cb, [:pointer, :int, :string, :pointer], :void
|
126
169
|
attach_function :rd_kafka_conf_set_error_cb, [:pointer, :error_cb], :void
|
127
170
|
attach_function :rd_kafka_rebalance_protocol, [:pointer], :string
|
128
|
-
|
171
|
+
callback :oauthbearer_token_refresh_cb, [:pointer, :string, :pointer], :void
|
172
|
+
attach_function :rd_kafka_conf_set_oauthbearer_token_refresh_cb, [:pointer, :oauthbearer_token_refresh_cb], :void
|
173
|
+
attach_function :rd_kafka_oauthbearer_set_token, [:pointer, :string, :int64, :pointer, :pointer, :int, :pointer, :int], :int
|
174
|
+
attach_function :rd_kafka_oauthbearer_set_token_failure, [:pointer, :string], :int
|
129
175
|
# Log queue
|
130
176
|
attach_function :rd_kafka_set_log_queue, [:pointer, :pointer], :void
|
131
177
|
attach_function :rd_kafka_queue_get_main, [:pointer], :pointer
|
@@ -134,13 +180,13 @@ module Rdkafka
|
|
134
180
|
:void, [:pointer, :int, :string, :string]
|
135
181
|
) do |_client_ptr, level, _level_string, line|
|
136
182
|
severity = case level
|
137
|
-
when 0
|
183
|
+
when 0, 1, 2
|
138
184
|
Logger::FATAL
|
139
185
|
when 3
|
140
186
|
Logger::ERROR
|
141
187
|
when 4
|
142
188
|
Logger::WARN
|
143
|
-
when 5
|
189
|
+
when 5, 6
|
144
190
|
Logger::INFO
|
145
191
|
when 7
|
146
192
|
Logger::DEBUG
|
@@ -175,6 +221,32 @@ module Rdkafka
|
|
175
221
|
end
|
176
222
|
end
|
177
223
|
|
224
|
+
# The OAuth callback is currently global and contextless.
|
225
|
+
# This means that the callback will be called for all instances, and the callback must be able to determine to which instance it is associated.
|
226
|
+
# The instance name will be provided in the callback, allowing the callback to reference the correct instance.
|
227
|
+
#
|
228
|
+
# An example of how to use the instance name in the callback is given below.
|
229
|
+
# The `refresh_token` is configured as the `oauthbearer_token_refresh_callback`.
|
230
|
+
# `instances` is a map of client names to client instances, maintained by the user.
|
231
|
+
#
|
232
|
+
# ```
|
233
|
+
# def refresh_token(config, client_name)
|
234
|
+
# client = instances[client_name]
|
235
|
+
# client.oauthbearer_set_token(
|
236
|
+
# token: 'new-token-value',
|
237
|
+
# lifetime_ms: token-lifetime-ms,
|
238
|
+
# principal_name: 'principal-name'
|
239
|
+
# )
|
240
|
+
# end
|
241
|
+
# ```
|
242
|
+
OAuthbearerTokenRefreshCallback = FFI::Function.new(
|
243
|
+
:void, [:pointer, :string, :pointer]
|
244
|
+
) do |client_ptr, config, _opaque|
|
245
|
+
if Rdkafka::Config.oauthbearer_token_refresh_callback
|
246
|
+
Rdkafka::Config.oauthbearer_token_refresh_callback.call(config, Rdkafka::Bindings.rd_kafka_name(client_ptr))
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
178
250
|
# Handle
|
179
251
|
|
180
252
|
enum :kafka_type, [
|
data/lib/rdkafka/callbacks.rb
CHANGED
@@ -113,6 +113,42 @@ module Rdkafka
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
+
class DescribeConfigsResult
|
117
|
+
attr_reader :result_error, :error_string, :results, :results_count
|
118
|
+
|
119
|
+
def initialize(event_ptr)
|
120
|
+
@results=[]
|
121
|
+
@result_error = Rdkafka::Bindings.rd_kafka_event_error(event_ptr)
|
122
|
+
@error_string = Rdkafka::Bindings.rd_kafka_event_error_string(event_ptr)
|
123
|
+
|
124
|
+
if @result_error == 0
|
125
|
+
configs_describe_result = Rdkafka::Bindings.rd_kafka_event_DescribeConfigs_result(event_ptr)
|
126
|
+
# Get the number of matching acls
|
127
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
128
|
+
@results = Rdkafka::Bindings.rd_kafka_DescribeConfigs_result_resources(configs_describe_result, pointer_to_size_t)
|
129
|
+
@results_count = pointer_to_size_t.read_int
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class IncrementalAlterConfigsResult
|
135
|
+
attr_reader :result_error, :error_string, :results, :results_count
|
136
|
+
|
137
|
+
def initialize(event_ptr)
|
138
|
+
@results=[]
|
139
|
+
@result_error = Rdkafka::Bindings.rd_kafka_event_error(event_ptr)
|
140
|
+
@error_string = Rdkafka::Bindings.rd_kafka_event_error_string(event_ptr)
|
141
|
+
|
142
|
+
if @result_error == 0
|
143
|
+
incremental_alter_result = Rdkafka::Bindings.rd_kafka_event_IncrementalAlterConfigs_result(event_ptr)
|
144
|
+
# Get the number of matching acls
|
145
|
+
pointer_to_size_t = FFI::MemoryPointer.new(:int32)
|
146
|
+
@results = Rdkafka::Bindings.rd_kafka_IncrementalAlterConfigs_result_resources(incremental_alter_result, pointer_to_size_t)
|
147
|
+
@results_count = pointer_to_size_t.read_int
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
116
152
|
# FFI Function used for Create Topic and Delete Topic callbacks
|
117
153
|
BackgroundEventCallbackFunction = FFI::Function.new(
|
118
154
|
:void, [:pointer, :pointer, :pointer]
|
@@ -123,20 +159,24 @@ module Rdkafka
|
|
123
159
|
# @private
|
124
160
|
class BackgroundEventCallback
|
125
161
|
def self.call(_, event_ptr, _)
|
126
|
-
|
127
|
-
|
162
|
+
case Rdkafka::Bindings.rd_kafka_event_type(event_ptr)
|
163
|
+
when Rdkafka::Bindings::RD_KAFKA_EVENT_CREATETOPICS_RESULT
|
128
164
|
process_create_topic(event_ptr)
|
129
|
-
|
165
|
+
when Rdkafka::Bindings::RD_KAFKA_EVENT_DESCRIBECONFIGS_RESULT
|
166
|
+
process_describe_configs(event_ptr)
|
167
|
+
when Rdkafka::Bindings::RD_KAFKA_EVENT_INCREMENTALALTERCONFIGS_RESULT
|
168
|
+
process_incremental_alter_configs(event_ptr)
|
169
|
+
when Rdkafka::Bindings::RD_KAFKA_EVENT_DELETETOPICS_RESULT
|
130
170
|
process_delete_topic(event_ptr)
|
131
|
-
|
171
|
+
when Rdkafka::Bindings::RD_KAFKA_ADMIN_OP_CREATEPARTITIONS_RESULT
|
132
172
|
process_create_partitions(event_ptr)
|
133
|
-
|
173
|
+
when Rdkafka::Bindings::RD_KAFKA_EVENT_CREATEACLS_RESULT
|
134
174
|
process_create_acl(event_ptr)
|
135
|
-
|
175
|
+
when Rdkafka::Bindings::RD_KAFKA_EVENT_DELETEACLS_RESULT
|
136
176
|
process_delete_acl(event_ptr)
|
137
|
-
|
177
|
+
when Rdkafka::Bindings::RD_KAFKA_EVENT_DESCRIBEACLS_RESULT
|
138
178
|
process_describe_acl(event_ptr)
|
139
|
-
|
179
|
+
when Rdkafka::Bindings::RD_KAFKA_EVENT_DELETEGROUPS_RESULT
|
140
180
|
process_delete_groups(event_ptr)
|
141
181
|
end
|
142
182
|
end
|
@@ -156,7 +196,44 @@ module Rdkafka
|
|
156
196
|
create_topic_handle[:response] = create_topic_results[0].result_error
|
157
197
|
create_topic_handle[:error_string] = create_topic_results[0].error_string
|
158
198
|
create_topic_handle[:result_name] = create_topic_results[0].result_name
|
159
|
-
|
199
|
+
|
200
|
+
create_topic_handle.unlock
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def self.process_describe_configs(event_ptr)
|
205
|
+
describe_configs = DescribeConfigsResult.new(event_ptr)
|
206
|
+
describe_configs_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
207
|
+
|
208
|
+
if describe_configs_handle = Rdkafka::Admin::DescribeConfigsHandle.remove(describe_configs_handle_ptr.address)
|
209
|
+
describe_configs_handle[:response] = describe_configs.result_error
|
210
|
+
describe_configs_handle[:response_string] = describe_configs.error_string
|
211
|
+
describe_configs_handle[:pending] = false
|
212
|
+
|
213
|
+
if describe_configs.result_error == 0
|
214
|
+
describe_configs_handle[:config_entries] = describe_configs.results
|
215
|
+
describe_configs_handle[:entry_count] = describe_configs.results_count
|
216
|
+
end
|
217
|
+
|
218
|
+
describe_configs_handle.unlock
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def self.process_incremental_alter_configs(event_ptr)
|
223
|
+
incremental_alter = IncrementalAlterConfigsResult.new(event_ptr)
|
224
|
+
incremental_alter_handle_ptr = Rdkafka::Bindings.rd_kafka_event_opaque(event_ptr)
|
225
|
+
|
226
|
+
if incremental_alter_handle = Rdkafka::Admin::IncrementalAlterConfigsHandle.remove(incremental_alter_handle_ptr.address)
|
227
|
+
incremental_alter_handle[:response] = incremental_alter.result_error
|
228
|
+
incremental_alter_handle[:response_string] = incremental_alter.error_string
|
229
|
+
incremental_alter_handle[:pending] = false
|
230
|
+
|
231
|
+
if incremental_alter.result_error == 0
|
232
|
+
incremental_alter_handle[:config_entries] = incremental_alter.results
|
233
|
+
incremental_alter_handle[:entry_count] = incremental_alter.results_count
|
234
|
+
end
|
235
|
+
|
236
|
+
incremental_alter_handle.unlock
|
160
237
|
end
|
161
238
|
end
|
162
239
|
|
@@ -173,7 +250,8 @@ module Rdkafka
|
|
173
250
|
delete_group_handle[:response] = delete_group_results[0].result_error
|
174
251
|
delete_group_handle[:error_string] = delete_group_results[0].error_string
|
175
252
|
delete_group_handle[:result_name] = delete_group_results[0].result_name
|
176
|
-
|
253
|
+
|
254
|
+
delete_group_handle.unlock
|
177
255
|
end
|
178
256
|
end
|
179
257
|
|
@@ -190,7 +268,8 @@ module Rdkafka
|
|
190
268
|
delete_topic_handle[:response] = delete_topic_results[0].result_error
|
191
269
|
delete_topic_handle[:error_string] = delete_topic_results[0].error_string
|
192
270
|
delete_topic_handle[:result_name] = delete_topic_results[0].result_name
|
193
|
-
|
271
|
+
|
272
|
+
delete_topic_handle.unlock
|
194
273
|
end
|
195
274
|
end
|
196
275
|
|
@@ -207,7 +286,8 @@ module Rdkafka
|
|
207
286
|
create_partitions_handle[:response] = create_partitions_results[0].result_error
|
208
287
|
create_partitions_handle[:error_string] = create_partitions_results[0].error_string
|
209
288
|
create_partitions_handle[:result_name] = create_partitions_results[0].result_name
|
210
|
-
|
289
|
+
|
290
|
+
create_partitions_handle.unlock
|
211
291
|
end
|
212
292
|
end
|
213
293
|
|
@@ -223,7 +303,8 @@ module Rdkafka
|
|
223
303
|
if create_acl_handle = Rdkafka::Admin::CreateAclHandle.remove(create_acl_handle_ptr.address)
|
224
304
|
create_acl_handle[:response] = create_acl_results[0].result_error
|
225
305
|
create_acl_handle[:response_string] = create_acl_results[0].error_string
|
226
|
-
|
306
|
+
|
307
|
+
create_acl_handle.unlock
|
227
308
|
end
|
228
309
|
end
|
229
310
|
|
@@ -239,11 +320,13 @@ module Rdkafka
|
|
239
320
|
if delete_acl_handle = Rdkafka::Admin::DeleteAclHandle.remove(delete_acl_handle_ptr.address)
|
240
321
|
delete_acl_handle[:response] = delete_acl_results[0].result_error
|
241
322
|
delete_acl_handle[:response_string] = delete_acl_results[0].error_string
|
242
|
-
|
323
|
+
|
243
324
|
if delete_acl_results[0].result_error == 0
|
244
325
|
delete_acl_handle[:matching_acls] = delete_acl_results[0].matching_acls
|
245
326
|
delete_acl_handle[:matching_acls_count] = delete_acl_results[0].matching_acls_count
|
246
327
|
end
|
328
|
+
|
329
|
+
delete_acl_handle.unlock
|
247
330
|
end
|
248
331
|
end
|
249
332
|
|
@@ -254,17 +337,18 @@ module Rdkafka
|
|
254
337
|
if describe_acl_handle = Rdkafka::Admin::DescribeAclHandle.remove(describe_acl_handle_ptr.address)
|
255
338
|
describe_acl_handle[:response] = describe_acl.result_error
|
256
339
|
describe_acl_handle[:response_string] = describe_acl.error_string
|
257
|
-
|
340
|
+
|
258
341
|
if describe_acl.result_error == 0
|
259
|
-
describe_acl_handle[:acls]
|
342
|
+
describe_acl_handle[:acls] = describe_acl.matching_acls
|
260
343
|
describe_acl_handle[:acls_count] = describe_acl.matching_acls_count
|
261
344
|
end
|
345
|
+
|
346
|
+
describe_acl_handle.unlock
|
262
347
|
end
|
263
348
|
end
|
264
349
|
end
|
265
350
|
|
266
351
|
# FFI Function used for Message Delivery callbacks
|
267
|
-
|
268
352
|
DeliveryCallbackFunction = FFI::Function.new(
|
269
353
|
:void, [:pointer, :pointer, :pointer]
|
270
354
|
) do |client_ptr, message_ptr, opaque_ptr|
|
@@ -284,7 +368,6 @@ module Rdkafka
|
|
284
368
|
delivery_handle[:partition] = message[:partition]
|
285
369
|
delivery_handle[:offset] = message[:offset]
|
286
370
|
delivery_handle[:topic_name] = FFI::MemoryPointer.from_string(topic_name)
|
287
|
-
delivery_handle[:pending] = false
|
288
371
|
|
289
372
|
# Call delivery callback on opaque
|
290
373
|
if opaque = Rdkafka::Config.opaques[opaque_ptr.to_i]
|
@@ -299,9 +382,10 @@ module Rdkafka
|
|
299
382
|
delivery_handle
|
300
383
|
)
|
301
384
|
end
|
385
|
+
|
386
|
+
delivery_handle.unlock
|
302
387
|
end
|
303
388
|
end
|
304
389
|
end
|
305
|
-
|
306
390
|
end
|
307
391
|
end
|
data/lib/rdkafka/config.rb
CHANGED
@@ -15,12 +15,13 @@ module Rdkafka
|
|
15
15
|
@@opaques = ObjectSpace::WeakMap.new
|
16
16
|
# @private
|
17
17
|
@@log_queue = Queue.new
|
18
|
-
# @private
|
19
18
|
# We memoize thread on the first log flush
|
20
19
|
# This allows us also to restart logger thread on forks
|
21
20
|
@@log_thread = nil
|
22
21
|
# @private
|
23
22
|
@@log_mutex = Mutex.new
|
23
|
+
# @private
|
24
|
+
@@oauthbearer_token_refresh_callback = nil
|
24
25
|
|
25
26
|
# Returns the current logger, by default this is a logger to stdout.
|
26
27
|
#
|
@@ -104,6 +105,24 @@ module Rdkafka
|
|
104
105
|
@@error_callback
|
105
106
|
end
|
106
107
|
|
108
|
+
# Sets the SASL/OAUTHBEARER token refresh callback.
|
109
|
+
# This callback will be triggered when it is time to refresh the client's OAUTHBEARER token
|
110
|
+
#
|
111
|
+
# @param callback [Proc, #call] The callback
|
112
|
+
#
|
113
|
+
# @return [nil]
|
114
|
+
def self.oauthbearer_token_refresh_callback=(callback)
|
115
|
+
raise TypeError.new("Callback has to be callable") unless callback.respond_to?(:call) || callback == nil
|
116
|
+
@@oauthbearer_token_refresh_callback = callback
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns the current oauthbearer_token_refresh_callback callback, by default this is nil.
|
120
|
+
#
|
121
|
+
# @return [Proc, nil]
|
122
|
+
def self.oauthbearer_token_refresh_callback
|
123
|
+
@@oauthbearer_token_refresh_callback
|
124
|
+
end
|
125
|
+
|
107
126
|
# @private
|
108
127
|
def self.opaques
|
109
128
|
@@opaques
|
@@ -176,11 +195,13 @@ module Rdkafka
|
|
176
195
|
|
177
196
|
# Creates a consumer with this configuration.
|
178
197
|
#
|
198
|
+
# @param native_kafka_auto_start [Boolean] should the native kafka operations be started
|
199
|
+
# automatically. Defaults to true. Set to false only when doing complex initialization.
|
179
200
|
# @return [Consumer] The created consumer
|
180
201
|
#
|
181
202
|
# @raise [ConfigError] When the configuration contains invalid options
|
182
203
|
# @raise [ClientCreationError] When the native client cannot be created
|
183
|
-
def consumer
|
204
|
+
def consumer(native_kafka_auto_start: true)
|
184
205
|
opaque = Opaque.new
|
185
206
|
config = native_config(opaque)
|
186
207
|
|
@@ -200,18 +221,21 @@ module Rdkafka
|
|
200
221
|
Rdkafka::NativeKafka.new(
|
201
222
|
kafka,
|
202
223
|
run_polling_thread: false,
|
203
|
-
opaque: opaque
|
224
|
+
opaque: opaque,
|
225
|
+
auto_start: native_kafka_auto_start
|
204
226
|
)
|
205
227
|
)
|
206
228
|
end
|
207
229
|
|
208
230
|
# Create a producer with this configuration.
|
209
231
|
#
|
232
|
+
# @param native_kafka_auto_start [Boolean] should the native kafka operations be started
|
233
|
+
# automatically. Defaults to true. Set to false only when doing complex initialization.
|
210
234
|
# @return [Producer] The created producer
|
211
235
|
#
|
212
236
|
# @raise [ConfigError] When the configuration contains invalid options
|
213
237
|
# @raise [ClientCreationError] When the native client cannot be created
|
214
|
-
def producer
|
238
|
+
def producer(native_kafka_auto_start: true)
|
215
239
|
# Create opaque
|
216
240
|
opaque = Opaque.new
|
217
241
|
# Create Kafka config
|
@@ -220,11 +244,15 @@ module Rdkafka
|
|
220
244
|
Rdkafka::Bindings.rd_kafka_conf_set_dr_msg_cb(config, Rdkafka::Callbacks::DeliveryCallbackFunction)
|
221
245
|
# Return producer with Kafka client
|
222
246
|
partitioner_name = self[:partitioner] || self["partitioner"]
|
247
|
+
|
248
|
+
kafka = native_kafka(config, :rd_kafka_producer)
|
249
|
+
|
223
250
|
Rdkafka::Producer.new(
|
224
251
|
Rdkafka::NativeKafka.new(
|
225
|
-
|
252
|
+
kafka,
|
226
253
|
run_polling_thread: true,
|
227
|
-
opaque: opaque
|
254
|
+
opaque: opaque,
|
255
|
+
auto_start: native_kafka_auto_start
|
228
256
|
),
|
229
257
|
partitioner_name
|
230
258
|
).tap do |producer|
|
@@ -234,19 +262,25 @@ module Rdkafka
|
|
234
262
|
|
235
263
|
# Creates an admin instance with this configuration.
|
236
264
|
#
|
265
|
+
# @param native_kafka_auto_start [Boolean] should the native kafka operations be started
|
266
|
+
# automatically. Defaults to true. Set to false only when doing complex initialization.
|
237
267
|
# @return [Admin] The created admin instance
|
238
268
|
#
|
239
269
|
# @raise [ConfigError] When the configuration contains invalid options
|
240
270
|
# @raise [ClientCreationError] When the native client cannot be created
|
241
|
-
def admin
|
271
|
+
def admin(native_kafka_auto_start: true)
|
242
272
|
opaque = Opaque.new
|
243
273
|
config = native_config(opaque)
|
244
274
|
Rdkafka::Bindings.rd_kafka_conf_set_background_event_cb(config, Rdkafka::Callbacks::BackgroundEventCallbackFunction)
|
275
|
+
|
276
|
+
kafka = native_kafka(config, :rd_kafka_producer)
|
277
|
+
|
245
278
|
Rdkafka::Admin.new(
|
246
279
|
Rdkafka::NativeKafka.new(
|
247
|
-
|
280
|
+
kafka,
|
248
281
|
run_polling_thread: true,
|
249
|
-
opaque: opaque
|
282
|
+
opaque: opaque,
|
283
|
+
auto_start: native_kafka_auto_start
|
250
284
|
)
|
251
285
|
)
|
252
286
|
end
|
@@ -300,6 +334,9 @@ module Rdkafka
|
|
300
334
|
|
301
335
|
# Set error callback
|
302
336
|
Rdkafka::Bindings.rd_kafka_conf_set_error_cb(config, Rdkafka::Bindings::ErrorCallback)
|
337
|
+
|
338
|
+
# Set oauth callback
|
339
|
+
Rdkafka::Bindings.rd_kafka_conf_set_oauthbearer_token_refresh_cb(config, Rdkafka::Bindings::OAuthbearerTokenRefreshCallback)
|
303
340
|
end
|
304
341
|
end
|
305
342
|
|
data/lib/rdkafka/consumer.rb
CHANGED
@@ -13,12 +13,19 @@ module Rdkafka
|
|
13
13
|
class Consumer
|
14
14
|
include Enumerable
|
15
15
|
include Helpers::Time
|
16
|
+
include Helpers::OAuth
|
16
17
|
|
17
18
|
# @private
|
18
19
|
def initialize(native_kafka)
|
19
20
|
@native_kafka = native_kafka
|
20
21
|
end
|
21
22
|
|
23
|
+
# Starts the native Kafka polling thread and kicks off the init polling
|
24
|
+
# @note Not needed to run unless explicit start was disabled
|
25
|
+
def start
|
26
|
+
@native_kafka.start
|
27
|
+
end
|
28
|
+
|
22
29
|
# @return [String] consumer name
|
23
30
|
def name
|
24
31
|
@name ||= @native_kafka.with_inner do |inner|
|