@@ -14,6 +14,19 @@ def finalizer
1414 -> ( _ ) { close }
1515 end
1616
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+
1730 # Close this admin instance
1831 def close
1932 return if closed?
@@ -216,6 +229,71 @@ def delete_topic(topic_name)
216229 delete_topic_handle
217230 end
218231
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+
219297 # Create acl
220298 # @param resource_type - values of type rd_kafka_ResourceType_t
221299 # https://github.com/confluentinc/librdkafka/blob/292d2a66b9921b783f08147807992e603c7af059/src/rdkafka.h#L7307
@@ -528,6 +606,7 @@ def describe_acl(resource_type:, resource_name:, resource_pattern_type:, princip
528606 end
529607
530608 private
609+
531610 def closed_admin_check ( method )
532611 raise Rdkafka ::ClosedAdminError . new ( method ) if closed?
533612 end
0 commit comments