logstash-integration-kafka 10.12.0-java → 11.1.0-java

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 (27) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/docs/index.asciidoc +1 -1
  4. data/docs/input-kafka.asciidoc +42 -8
  5. data/docs/output-kafka.asciidoc +8 -2
  6. data/lib/logstash/inputs/kafka.rb +19 -5
  7. data/lib/logstash/outputs/kafka.rb +3 -1
  8. data/lib/logstash/plugin_mixins/kafka/common.rb +8 -0
  9. data/lib/logstash-integration-kafka_jars.rb +8 -8
  10. data/logstash-integration-kafka.gemspec +2 -2
  11. data/spec/integration/inputs/kafka_spec.rb +96 -0
  12. data/spec/unit/inputs/kafka_spec.rb +15 -5
  13. data/spec/unit/outputs/kafka_spec.rb +8 -0
  14. data/vendor/jar-dependencies/io/confluent/common-config/{6.2.2/common-config-6.2.2.jar → 7.3.0/common-config-7.3.0.jar} +0 -0
  15. data/vendor/jar-dependencies/io/confluent/common-utils/{6.2.2/common-utils-6.2.2.jar → 7.3.0/common-utils-7.3.0.jar} +0 -0
  16. data/vendor/jar-dependencies/io/confluent/kafka-avro-serializer/7.3.0/kafka-avro-serializer-7.3.0.jar +0 -0
  17. data/vendor/jar-dependencies/io/confluent/kafka-schema-registry-client/7.3.0/kafka-schema-registry-client-7.3.0.jar +0 -0
  18. data/vendor/jar-dependencies/io/confluent/kafka-schema-serializer/7.3.0/kafka-schema-serializer-7.3.0.jar +0 -0
  19. data/vendor/jar-dependencies/org/apache/kafka/kafka-clients/{2.8.1/kafka-clients-2.8.1.jar → 3.3.1/kafka-clients-3.3.1.jar} +0 -0
  20. data/vendor/jar-dependencies/org/apache/kafka/kafka_2.12/3.3.1/kafka_2.12-3.3.1.jar +0 -0
  21. data/vendor/jar-dependencies/org/lz4/lz4-java/1.8.0/lz4-java-1.8.0.jar +0 -0
  22. metadata +12 -12
  23. data/vendor/jar-dependencies/io/confluent/kafka-avro-serializer/6.2.2/kafka-avro-serializer-6.2.2.jar +0 -0
  24. data/vendor/jar-dependencies/io/confluent/kafka-schema-registry-client/6.2.2/kafka-schema-registry-client-6.2.2.jar +0 -0
  25. data/vendor/jar-dependencies/io/confluent/kafka-schema-serializer/6.2.2/kafka-schema-serializer-6.2.2.jar +0 -0
  26. data/vendor/jar-dependencies/org/apache/kafka/kafka_2.12/2.8.1/kafka_2.12-2.8.1.jar +0 -0
  27. data/vendor/jar-dependencies/org/lz4/lz4-java/1.7.1/lz4-java-1.7.1.jar +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad714dd5a1201d57e98cc740560fb96fdeb999b500065ba5c5dcb0d950cab3fa
4
- data.tar.gz: 148938661749ae182a0ea2e2482d846bf7225390c2e418605cd83ad1242ba9b0
3
+ metadata.gz: c8f85bfdadbbd496495603c82ed577db4c23a168db59e6d0034549de6ebb66d1
4
+ data.tar.gz: 0b3b0bc33d6e64eebcb9e757fede56f747625c864160844ed2a3c76d0b22a155
5
5
  SHA512:
6
- metadata.gz: afac318b49b8a489b3c0e7919067417eee1cc3f6097c1e71e86647a66c1383c9054f81742fe70cc8673f2c6ba377c2734a17426d2541abecb0f941465a037f0f
7
- data.tar.gz: c8f7c382bbb00680fdb4a2c9d72a31ddcd231644d683503ba3eb0996da7236ac5fdd55a7aaa40f01a8737b9d3b5419052f1fd2b054ee3f6da1c23b2e1631ce99
6
+ metadata.gz: '09e8814f1697c1d38d478881b35102a1e9885c23cdb0b9b2d8860c7577d4b2a40eb580b535afff46273e7139fbbaf603b0ea0de1fbeb68644bcea95b79d9e470'
7
+ data.tar.gz: 1b0c7ee3ffbcb589268174753db91d0ba7272fc44c04e7ceb2e17d43f9fe2ec31ed4eee7450390adc0bada77c36fedaf14d46bf9b09372a6b55a6e76047a56e4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
+ ## 11.1.0
2
+ - Added config `group_instance_id` to use the Kafka's consumer static membership feature [#135](https://github.com/logstash-plugins/logstash-integration-kafka/pull/135)
3
+
4
+ ## 11.0.0
5
+ - Changed Kafka client to 3.3.1, requires Logstash >= 8.3.0.
6
+ - Deprecated `default` value for setting `client_dns_lookup` forcing to `use_all_dns_ips` when explicitly used [#130](https://github.com/logstash-plugins/logstash-integration-kafka/pull/130)
7
+ - Changed the consumer's poll from using the one that blocks on metadata retrieval to the one that doesn't [#136](https://github.com/logstash-plugins/logstash-integration-kafka/pull/133)
8
+
1
9
  ## 10.12.0
2
- - bump kafka client to 2.8.1 [#115](https://api.github.com/repos/logstash-plugins/logstash-integration-kafka/pulls/115)
10
+ - bump kafka client to 2.8.1 [#115](https://github.com/logstash-plugins/logstash-integration-kafka/pull/115)
3
11
 
4
12
  ## 10.11.0
5
13
  - Feat: added connections_max_idle_ms setting for output [#118](https://github.com/logstash-plugins/logstash-integration-kafka/pull/118)
data/docs/index.asciidoc CHANGED
@@ -1,7 +1,7 @@
1
1
  :plugin: kafka
2
2
  :type: integration
3
3
  :no_codec:
4
- :kafka_client: 2.8.1
4
+ :kafka_client: 3.3.1
5
5
 
6
6
  ///////////////////////////////////////////
7
7
  START - GENERATED VARIABLES, DO NOT EDIT!
@@ -2,8 +2,8 @@
2
2
  :plugin: kafka
3
3
  :type: input
4
4
  :default_codec: plain
5
- :kafka_client: 2.8
6
- :kafka_client_doc: 25
5
+ :kafka_client: 3.3
6
+ :kafka_client_doc: 33
7
7
 
8
8
  ///////////////////////////////////////////
9
9
  START - GENERATED VARIABLES, DO NOT EDIT!
@@ -113,6 +113,7 @@ See the https://kafka.apache.org/{kafka_client_doc}/documentation for more detai
113
113
  | <<plugins-{type}s-{plugin}-fetch_max_wait_ms>> |<<number,number>>|No
114
114
  | <<plugins-{type}s-{plugin}-fetch_min_bytes>> |<<number,number>>|No
115
115
  | <<plugins-{type}s-{plugin}-group_id>> |<<string,string>>|No
116
+ | <<plugins-{type}s-{plugin}-group_instance_id>> |<<string,string>>|No
116
117
  | <<plugins-{type}s-{plugin}-heartbeat_interval_ms>> |<<number,number>>|No
117
118
  | <<plugins-{type}s-{plugin}-isolation_level>> |<<string,string>>|No
118
119
  | <<plugins-{type}s-{plugin}-jaas_path>> |a valid filesystem path|No
@@ -143,10 +144,10 @@ See the https://kafka.apache.org/{kafka_client_doc}/documentation for more detai
143
144
  | <<plugins-{type}s-{plugin}-ssl_key_password>> |<<password,password>>|No
144
145
  | <<plugins-{type}s-{plugin}-ssl_keystore_location>> |a valid filesystem path|No
145
146
  | <<plugins-{type}s-{plugin}-ssl_keystore_password>> |<<password,password>>|No
146
- | <<plugins-{type}s-{plugin}-ssl_keystore_type>> |<<string,string>>|No
147
+ | <<plugins-{type}s-{plugin}-ssl_keystore_type>> |<<string,string>>, one of `["jks", "PKCS12"]`|No
147
148
  | <<plugins-{type}s-{plugin}-ssl_truststore_location>> |a valid filesystem path|No
148
149
  | <<plugins-{type}s-{plugin}-ssl_truststore_password>> |<<password,password>>|No
149
- | <<plugins-{type}s-{plugin}-ssl_truststore_type>> |<<string,string>>|No
150
+ | <<plugins-{type}s-{plugin}-ssl_truststore_type>> |<<string,string>>, one of `["jks", "PKCS12"]`|No
150
151
  | <<plugins-{type}s-{plugin}-topics>> |<<array,array>>|No
151
152
  | <<plugins-{type}s-{plugin}-topics_pattern>> |<<string,string>>|No
152
153
  | <<plugins-{type}s-{plugin}-value_deserializer_class>> |<<string,string>>|No
@@ -211,6 +212,12 @@ IP addresses for a hostname, they will all be attempted to connect to before fai
211
212
  connection. If the value is `resolve_canonical_bootstrap_servers_only` each entry will be
212
213
  resolved and expanded into a list of canonical names.
213
214
 
215
+ [NOTE]
216
+ ====
217
+ Starting from Kafka 3 `default` value for `client.dns.lookup` value has been removed.
218
+ If explicitly configured it fallbacks to `use_all_dns_ips`.
219
+ ====
220
+
214
221
  [id="plugins-{type}s-{plugin}-client_id"]
215
222
  ===== `client_id`
216
223
 
@@ -338,6 +345,28 @@ NOTE: In cases when multiple inputs are being used in a single pipeline, reading
338
345
  it's essential to set a different `group_id => ...` for each input. Setting a unique `client_id => ...`
339
346
  is also recommended.
340
347
 
348
+ [id="plugins-{type}s-{plugin}-group_instance_id"]
349
+ ===== `group_instance_id`
350
+
351
+ * Value type is <<string,string>>
352
+ * There is no default value for this setting.
353
+
354
+ The static membership identifier for this Logstash Kafka consumer. Static membership feature was introduced in
355
+ https://cwiki.apache.org/confluence/display/KAFKA/KIP-345%3A+Introduce+static+membership+protocol+to+reduce+consumer+rebalances[KIP-345],
356
+ available under Kafka property `group.instance.id`.
357
+ Its purpose is to avoid rebalances in situations in which a lot of data
358
+ has to be forwarded after a consumer goes offline.
359
+ This feature mitigates cases where the service state is heavy and the rebalance of one topic partition from instance
360
+ A to B would cause a huge amount of data to be transferred.
361
+ A client that goes offline/online frequently can avoid frequent and heavy rebalances by using this option.
362
+
363
+ NOTE: The `group_instance_id` setting must be unique across all the clients belonging to the same <<plugins-{type}s-{plugin}-group_id>>.
364
+ Otherwise, another client connecting with same `group.instance.id` value would cause the oldest instance to be disconnected.
365
+ You can set this value to use information such as a hostname, an IP, or anything that uniquely identifies the client application.
366
+
367
+ NOTE: In cases when multiple threads are configured and `consumer_threads` is greater than one, a suffix is appended to
368
+ the `group_instance_id` to avoid collisions.
369
+
341
370
  [id="plugins-{type}s-{plugin}-heartbeat_interval_ms"]
342
371
  ===== `heartbeat_interval_ms`
343
372
 
@@ -659,7 +688,7 @@ If client authentication is required, this setting stores the keystore password
659
688
  * Value type is <<string,string>>
660
689
  * There is no default value for this setting.
661
690
 
662
- The keystore type.
691
+ The format of the keystore file. It must be either `jks` or `PKCS12`.
663
692
 
664
693
  [id="plugins-{type}s-{plugin}-ssl_truststore_location"]
665
694
  ===== `ssl_truststore_location`
@@ -683,7 +712,7 @@ The truststore password.
683
712
  * Value type is <<string,string>>
684
713
  * There is no default value for this setting.
685
714
 
686
- The truststore type.
715
+ The format of the truststore file. It must be either `jks` or `PKCS12`.
687
716
 
688
717
  [id="plugins-{type}s-{plugin}-topics"]
689
718
  ===== `topics`
@@ -699,8 +728,13 @@ A list of topics to subscribe to, defaults to ["logstash"].
699
728
  * Value type is <<string,string>>
700
729
  * There is no default value for this setting.
701
730
 
702
- A topic regex pattern to subscribe to.
703
- The topics configuration will be ignored when using this configuration.
731
+ A topic regular expression pattern to subscribe to.
732
+
733
+ Filtering by a regular expression is done by retrieving the full list of topic names from the broker and applying the pattern locally. When used with brokers with a lot of topics this operation could be very slow, especially if there are a lot of consumers.
734
+
735
+ NOTE: When the broker has some topics configured with ACL rules and they miss the DESCRIBE permission, then the subscription
736
+ happens but on the broker side it is logged that the subscription of some topics was denied to the configured user.
737
+
704
738
 
705
739
  [id="plugins-{type}s-{plugin}-value_deserializer_class"]
706
740
  ===== `value_deserializer_class`
@@ -2,8 +2,8 @@
2
2
  :plugin: kafka
3
3
  :type: output
4
4
  :default_codec: plain
5
- :kafka_client: 2.8
6
- :kafka_client_doc: 25
5
+ :kafka_client: 3.3
6
+ :kafka_client_doc: 33
7
7
 
8
8
  ///////////////////////////////////////////
9
9
  START - GENERATED VARIABLES, DO NOT EDIT!
@@ -181,6 +181,12 @@ all IP addresses returned for a hostname before failing the connection.
181
181
  If set to `resolve_canonical_bootstrap_servers_only`, each entry will be
182
182
  resolved and expanded into a list of canonical names.
183
183
 
184
+ [NOTE]
185
+ ====
186
+ Starting from Kafka 3 `default` value for `client.dns.lookup` value has been removed.
187
+ If explicitly configured it fallbacks to `use_all_dns_ips`.
188
+ ====
189
+
184
190
  [id="plugins-{type}s-{plugin}-client_id"]
185
191
  ===== `client_id`
186
192
 
@@ -92,7 +92,8 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
92
92
  # IP addresses for a hostname, they will all be attempted to connect to before failing the
93
93
  # connection. If the value is `resolve_canonical_bootstrap_servers_only` each entry will be
94
94
  # resolved and expanded into a list of canonical names.
95
- config :client_dns_lookup, :validate => ["default", "use_all_dns_ips", "resolve_canonical_bootstrap_servers_only"], :default => "default"
95
+ # Starting from Kafka 3 `default` value for `client.dns.lookup` value has been removed. If explicitly configured it fallbacks to `use_all_dns_ips`.
96
+ config :client_dns_lookup, :validate => ["default", "use_all_dns_ips", "resolve_canonical_bootstrap_servers_only"], :default => "use_all_dns_ips"
96
97
  # The id string to pass to the server when making requests. The purpose of this
97
98
  # is to be able to track the source of requests beyond just ip/port by allowing
98
99
  # a logical application name to be included.
@@ -123,6 +124,11 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
123
124
  # that happens to be made up of multiple processors. Messages in a topic will be distributed to all
124
125
  # Logstash instances with the same `group_id`
125
126
  config :group_id, :validate => :string, :default => "logstash"
127
+ # Set a static group instance id used in static membership feature to avoid rebalancing when a
128
+ # consumer goes offline. If set and `consumer_threads` is greater than 1 then for each
129
+ # consumer crated by each thread an artificial suffix is appended to the user provided `group_instance_id`
130
+ # to avoid clashing.
131
+ config :group_instance_id, :validate => :string
126
132
  # The expected time between heartbeats to the consumer coordinator. Heartbeats are used to ensure
127
133
  # that the consumer's session stays active and to facilitate rebalancing when new
128
134
  # consumers join or leave the group. The value must be set lower than
@@ -135,7 +141,7 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
135
141
  # been aborted. Non-transactional messages will be returned unconditionally in either mode.
136
142
  config :isolation_level, :validate => ["read_uncommitted", "read_committed"], :default => "read_uncommitted" # Kafka default
137
143
  # Java Class used to deserialize the record's key
138
- config :key_deserializer_class, :validate => :string, :default => "org.apache.kafka.common.serialization.StringDeserializer"
144
+ config :key_deserializer_class, :validate => :string, :default => DEFAULT_DESERIALIZER_CLASS
139
145
  # The maximum delay between invocations of poll() when using consumer group management. This places
140
146
  # an upper bound on the amount of time that the consumer can be idle before fetching more records.
141
147
  # If poll() is not called before expiration of this timeout, then the consumer is considered failed and
@@ -257,6 +263,7 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
257
263
  def register
258
264
  @runner_threads = []
259
265
  @metadata_mode = extract_metadata_level(@decorate_events)
266
+ reassign_dns_lookup
260
267
  @pattern ||= java.util.regex.Pattern.compile(@topics_pattern) unless @topics_pattern.nil?
261
268
  check_schema_registry_parameters
262
269
  end
@@ -285,7 +292,10 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
285
292
 
286
293
  public
287
294
  def run(logstash_queue)
288
- @runner_consumers = consumer_threads.times.map { |i| subscribe(create_consumer("#{client_id}-#{i}")) }
295
+ @runner_consumers = consumer_threads.times.map do |i|
296
+ thread_group_instance_id = consumer_threads > 1 && group_instance_id ? "#{group_instance_id}-#{i}" : group_instance_id
297
+ subscribe(create_consumer("#{client_id}-#{i}", thread_group_instance_id))
298
+ end
289
299
  @runner_threads = @runner_consumers.map.with_index { |consumer, i| thread_runner(logstash_queue, consumer,
290
300
  "kafka-input-worker-#{client_id}-#{i}") }
291
301
  @runner_threads.each(&:start)
@@ -329,10 +339,13 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
329
339
  def do_poll(consumer)
330
340
  records = []
331
341
  begin
332
- records = consumer.poll(poll_timeout_ms)
342
+ records = consumer.poll(java.time.Duration.ofMillis(poll_timeout_ms))
333
343
  rescue org.apache.kafka.common.errors.WakeupException => e
334
344
  logger.debug("Wake up from poll", :kafka_error_message => e)
335
345
  raise e unless stop?
346
+ rescue org.apache.kafka.common.errors.FencedInstanceIdException => e
347
+ logger.error("Another consumer with same group.instance.id has connected", :original_error_message => e.message)
348
+ raise e unless stop?
336
349
  rescue => e
337
350
  logger.error("Unable to poll Kafka consumer",
338
351
  :kafka_error_message => e,
@@ -387,7 +400,7 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
387
400
  end
388
401
 
389
402
  private
390
- def create_consumer(client_id)
403
+ def create_consumer(client_id, group_instance_id)
391
404
  begin
392
405
  props = java.util.Properties.new
393
406
  kafka = org.apache.kafka.clients.consumer.ConsumerConfig
@@ -405,6 +418,7 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
405
418
  props.put(kafka::FETCH_MAX_WAIT_MS_CONFIG, fetch_max_wait_ms.to_s) unless fetch_max_wait_ms.nil?
406
419
  props.put(kafka::FETCH_MIN_BYTES_CONFIG, fetch_min_bytes.to_s) unless fetch_min_bytes.nil?
407
420
  props.put(kafka::GROUP_ID_CONFIG, group_id)
421
+ props.put(kafka::GROUP_INSTANCE_ID_CONFIG, group_instance_id) unless group_instance_id.nil?
408
422
  props.put(kafka::HEARTBEAT_INTERVAL_MS_CONFIG, heartbeat_interval_ms.to_s) unless heartbeat_interval_ms.nil?
409
423
  props.put(kafka::ISOLATION_LEVEL_CONFIG, isolation_level)
410
424
  props.put(kafka::KEY_DESERIALIZER_CLASS_CONFIG, key_deserializer_class)
@@ -86,7 +86,8 @@ class LogStash::Outputs::Kafka < LogStash::Outputs::Base
86
86
  # IP addresses for a hostname, they will all be attempted to connect to before failing the
87
87
  # connection. If the value is `resolve_canonical_bootstrap_servers_only` each entry will be
88
88
  # resolved and expanded into a list of canonical names.
89
- config :client_dns_lookup, :validate => ["default", "use_all_dns_ips", "resolve_canonical_bootstrap_servers_only"], :default => "default"
89
+ # Starting from Kafka 3 `default` value for `client.dns.lookup` value has been removed. If explicitly configured it fallbacks to `use_all_dns_ips`.
90
+ config :client_dns_lookup, :validate => ["default", "use_all_dns_ips", "resolve_canonical_bootstrap_servers_only"], :default => "use_all_dns_ips"
90
91
  # The id string to pass to the server when making requests.
91
92
  # The purpose of this is to be able to track the source of requests beyond just
92
93
  # ip/port by allowing a logical application name to be included with the request
@@ -190,6 +191,7 @@ class LogStash::Outputs::Kafka < LogStash::Outputs::Base
190
191
  logger.warn("Kafka output is configured with finite retry. This instructs Logstash to LOSE DATA after a set number of send attempts fails. If you do not want to lose data if Kafka is down, then you must remove the retry setting.", :retries => @retries)
191
192
  end
192
193
 
194
+ reassign_dns_lookup
193
195
 
194
196
  @producer = create_producer
195
197
  if value_serializer == 'org.apache.kafka.common.serialization.StringSerializer'
@@ -43,5 +43,13 @@ module LogStash module PluginMixins module Kafka
43
43
  props.put("sasl.jaas.config", sasl_jaas_config) unless sasl_jaas_config.nil?
44
44
  end
45
45
 
46
+ def reassign_dns_lookup
47
+ if @client_dns_lookup == "default"
48
+ @client_dns_lookup = "use_all_dns_ips"
49
+ logger.warn("client_dns_lookup setting 'default' value is deprecated, forced to 'use_all_dns_ips', please update your configuration")
50
+ deprecation_logger.deprecated("Deprecated value `default` for `client_dns_lookup` option; use `use_all_dns_ips` instead.")
51
+ end
52
+ end
53
+
46
54
  end
47
55
  end end end
@@ -1,17 +1,17 @@
1
1
  # AUTOGENERATED BY THE GRADLE SCRIPT. DO NOT EDIT.
2
2
 
3
3
  require 'jar_dependencies'
4
- require_jar('io.confluent', 'kafka-avro-serializer', '6.2.2')
5
- require_jar('io.confluent', 'kafka-schema-serializer', '6.2.2')
6
- require_jar('io.confluent', 'common-config', '6.2.2')
4
+ require_jar('io.confluent', 'kafka-avro-serializer', '7.3.0')
5
+ require_jar('io.confluent', 'kafka-schema-serializer', '7.3.0')
6
+ require_jar('io.confluent', 'common-config', '7.3.0')
7
7
  require_jar('org.apache.avro', 'avro', '1.11.0')
8
- require_jar('io.confluent', 'kafka-schema-registry-client', '6.2.2')
9
- require_jar('org.apache.kafka', 'kafka_2.12', '2.8.1')
10
- require_jar('io.confluent', 'common-utils', '6.2.2')
8
+ require_jar('io.confluent', 'kafka-schema-registry-client', '7.3.0')
9
+ require_jar('org.apache.kafka', 'kafka_2.12', '3.3.1')
10
+ require_jar('io.confluent', 'common-utils', '7.3.0')
11
11
  require_jar('javax.ws.rs', 'javax.ws.rs-api', '2.1.1')
12
12
  require_jar('org.glassfish.jersey.core', 'jersey-common', '2.33')
13
- require_jar('org.apache.kafka', 'kafka-clients', '2.8.1')
13
+ require_jar('org.apache.kafka', 'kafka-clients', '3.3.1')
14
14
  require_jar('com.github.luben', 'zstd-jni', '1.5.2-2')
15
15
  require_jar('org.slf4j', 'slf4j-api', '1.7.36')
16
- require_jar('org.lz4', 'lz4-java', '1.7.1')
16
+ require_jar('org.lz4', 'lz4-java', '1.8.0')
17
17
  require_jar('org.xerial.snappy', 'snappy-java', '1.1.8.4')
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-integration-kafka'
3
- s.version = '10.12.0'
3
+ s.version = '11.1.0'
4
4
  s.licenses = ['Apache-2.0']
5
5
  s.summary = "Integration with Kafka - input and output plugins"
6
6
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline "+
@@ -41,7 +41,7 @@ Gem::Specification.new do |s|
41
41
 
42
42
  # Gem dependencies
43
43
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
44
- s.add_runtime_dependency "logstash-core", ">= 6.5.0"
44
+ s.add_runtime_dependency "logstash-core", ">= 8.3.0"
45
45
 
46
46
  s.add_runtime_dependency 'logstash-codec-json'
47
47
  s.add_runtime_dependency 'logstash-codec-plain'
@@ -79,6 +79,7 @@ describe "inputs/kafka", :integration => true do
79
79
  producer = org.apache.kafka.clients.producer.KafkaProducer.new(props)
80
80
 
81
81
  producer.send(record)
82
+ producer.flush
82
83
  producer.close
83
84
  end
84
85
 
@@ -185,10 +186,105 @@ describe "inputs/kafka", :integration => true do
185
186
  end
186
187
  end
187
188
  end
189
+
190
+ context "static membership 'group.instance.id' setting" do
191
+ let(:base_config) do
192
+ {
193
+ "topics" => ["logstash_integration_static_membership_topic"],
194
+ "group_id" => "logstash",
195
+ "consumer_threads" => 1,
196
+ # this is needed because the worker thread could be executed little after the producer sent the "up" message
197
+ "auto_offset_reset" => "earliest",
198
+ "group_instance_id" => "test_static_group_id"
199
+ }
200
+ end
201
+ let(:consumer_config) { base_config }
202
+ let(:logger) { double("logger") }
203
+ let(:queue) { java.util.concurrent.ArrayBlockingQueue.new(10) }
204
+ let(:kafka_input) { LogStash::Inputs::Kafka.new(consumer_config) }
205
+ before :each do
206
+ allow(LogStash::Inputs::Kafka).to receive(:logger).and_return(logger)
207
+ [:error, :warn, :info, :debug].each do |level|
208
+ allow(logger).to receive(level)
209
+ end
210
+
211
+ kafka_input.register
212
+ end
213
+
214
+ it "input plugin disconnects from the broker when another client with same static membership connects" do
215
+ expect(logger).to receive(:error).with("Another consumer with same group.instance.id has connected", anything)
216
+
217
+ input_worker = java.lang.Thread.new { kafka_input.run(queue) }
218
+ begin
219
+ input_worker.start
220
+ wait_kafka_input_is_ready("logstash_integration_static_membership_topic", queue)
221
+ saboteur_kafka_consumer = create_consumer_and_start_consuming("test_static_group_id")
222
+ saboteur_kafka_consumer.run # ask to be scheduled
223
+ saboteur_kafka_consumer.join
224
+
225
+ expect(saboteur_kafka_consumer.value).to eq("saboteur exited")
226
+ ensure
227
+ input_worker.join(30_000)
228
+ end
229
+ end
230
+
231
+ context "when the plugin is configured with multiple consumer threads" do
232
+ let(:consumer_config) { base_config.merge({"consumer_threads" => 2}) }
233
+
234
+ it "should avoid to connect with same 'group.instance.id'" do
235
+ expect(logger).to_not receive(:error).with("Another consumer with same group.instance.id has connected", anything)
236
+
237
+ input_worker = java.lang.Thread.new { kafka_input.run(queue) }
238
+ begin
239
+ input_worker.start
240
+ wait_kafka_input_is_ready("logstash_integration_static_membership_topic", queue)
241
+ ensure
242
+ kafka_input.stop
243
+ input_worker.join(1_000)
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+ # return consumer Ruby Thread
251
+ def create_consumer_and_start_consuming(static_group_id)
252
+ props = java.util.Properties.new
253
+ kafka = org.apache.kafka.clients.consumer.ConsumerConfig
254
+ props.put(kafka::BOOTSTRAP_SERVERS_CONFIG, "localhost:9092")
255
+ props.put(kafka::KEY_DESERIALIZER_CLASS_CONFIG, LogStash::Inputs::Kafka::DEFAULT_DESERIALIZER_CLASS)
256
+ props.put(kafka::VALUE_DESERIALIZER_CLASS_CONFIG, LogStash::Inputs::Kafka::DEFAULT_DESERIALIZER_CLASS)
257
+ props.put(kafka::GROUP_ID_CONFIG, "logstash")
258
+ props.put(kafka::GROUP_INSTANCE_ID_CONFIG, static_group_id)
259
+ consumer = org.apache.kafka.clients.consumer.KafkaConsumer.new(props)
260
+
261
+ Thread.new do
262
+ LogStash::Util::set_thread_name("integration_test_simple_consumer")
263
+ begin
264
+ consumer.subscribe(["logstash_integration_static_membership_topic"])
265
+ records = consumer.poll(java.time.Duration.ofSeconds(3))
266
+ "saboteur exited"
267
+ rescue => e
268
+ e # return the exception reached in thread.value
269
+ ensure
270
+ consumer.close
271
+ end
272
+ end
188
273
  end
189
274
 
190
275
  private
191
276
 
277
+ def wait_kafka_input_is_ready(topic, queue)
278
+ # this is needed to give time to the kafka input to be up and running
279
+ header = org.apache.kafka.common.header.internals.RecordHeader.new("name", "Ping Up".to_java_bytes)
280
+ record = org.apache.kafka.clients.producer.ProducerRecord.new(topic, 0, "key", "value", [header])
281
+ send_message(record)
282
+
283
+ # Wait the message is processed
284
+ message = queue.poll(1, java.util.concurrent.TimeUnit::MINUTES)
285
+ expect(message).to_not eq(nil)
286
+ end
287
+
192
288
  def consume_messages(config, queue: Queue.new, timeout:, event_count:)
193
289
  kafka_input = LogStash::Inputs::Kafka.new(config)
194
290
  kafka_input.register
@@ -83,6 +83,16 @@ describe LogStash::Inputs::Kafka do
83
83
  it "should register" do
84
84
  expect { subject.register }.to_not raise_error
85
85
  end
86
+
87
+ context "when the deprecated `default` is specified" do
88
+ let(:config) { common_config.merge('client_dns_lookup' => 'default') }
89
+
90
+ it 'should fallback `client_dns_lookup` to `use_all_dns_ips`' do
91
+ subject.register
92
+
93
+ expect(subject.client_dns_lookup).to eq('use_all_dns_ips')
94
+ end
95
+ end
86
96
  end
87
97
 
88
98
  describe '#running' do
@@ -287,7 +297,7 @@ describe LogStash::Inputs::Kafka do
287
297
  to receive(:new).with(hash_including('client.rack' => 'EU-R1')).
288
298
  and_return kafka_client = double('kafka-consumer')
289
299
 
290
- expect( subject.send(:create_consumer, 'sample_client-0') ).to be kafka_client
300
+ expect( subject.send(:create_consumer, 'sample_client-0', 'group_instance_id') ).to be kafka_client
291
301
  end
292
302
  end
293
303
 
@@ -299,7 +309,7 @@ describe LogStash::Inputs::Kafka do
299
309
  to receive(:new).with(hash_including('session.timeout.ms' => '25000', 'max.poll.interval.ms' => '345000')).
300
310
  and_return kafka_client = double('kafka-consumer')
301
311
 
302
- expect( subject.send(:create_consumer, 'sample_client-1') ).to be kafka_client
312
+ expect( subject.send(:create_consumer, 'sample_client-1', 'group_instance_id') ).to be kafka_client
303
313
  end
304
314
  end
305
315
 
@@ -311,7 +321,7 @@ describe LogStash::Inputs::Kafka do
311
321
  to receive(:new).with(hash_including('session.timeout.ms' => '25200', 'max.poll.interval.ms' => '123000')).
312
322
  and_return kafka_client = double('kafka-consumer')
313
323
 
314
- expect( subject.send(:create_consumer, 'sample_client-2') ).to be kafka_client
324
+ expect( subject.send(:create_consumer, 'sample_client-2', 'group_instance_id') ).to be kafka_client
315
325
  end
316
326
  end
317
327
 
@@ -323,7 +333,7 @@ describe LogStash::Inputs::Kafka do
323
333
  to receive(:new).with(hash_including('enable.auto.commit' => 'false', 'check.crcs' => 'true')).
324
334
  and_return kafka_client = double('kafka-consumer')
325
335
 
326
- expect( subject.send(:create_consumer, 'sample_client-3') ).to be kafka_client
336
+ expect( subject.send(:create_consumer, 'sample_client-3', 'group_instance_id') ).to be kafka_client
327
337
  expect( subject.enable_auto_commit ).to be false
328
338
  end
329
339
  end
@@ -336,7 +346,7 @@ describe LogStash::Inputs::Kafka do
336
346
  to receive(:new).with(hash_including('enable.auto.commit' => 'true', 'check.crcs' => 'false')).
337
347
  and_return kafka_client = double('kafka-consumer')
338
348
 
339
- expect( subject.send(:create_consumer, 'sample_client-4') ).to be kafka_client
349
+ expect( subject.send(:create_consumer, 'sample_client-4', 'group_instance_id') ).to be kafka_client
340
350
  expect( subject.enable_auto_commit ).to be true
341
351
  end
342
352
  end
@@ -22,6 +22,14 @@ describe "outputs/kafka" do
22
22
  expect(kafka.topic_id).to eql 'test'
23
23
  expect(kafka.key_serializer).to eql 'org.apache.kafka.common.serialization.StringSerializer'
24
24
  end
25
+
26
+ it 'should fallback `client_dns_lookup` to `use_all_dns_ips` when the deprecated `default` is specified' do
27
+ simple_kafka_config["client_dns_lookup"] = 'default'
28
+ kafka = LogStash::Outputs::Kafka.new(simple_kafka_config)
29
+ kafka.register
30
+
31
+ expect(kafka.client_dns_lookup).to eq('use_all_dns_ips')
32
+ end
25
33
  end
26
34
 
27
35
  context 'when outputting messages' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-integration-kafka
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.12.0
4
+ version: 11.1.0
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-09 00:00:00.000000000 Z
11
+ date: 2023-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -49,7 +49,7 @@ dependencies:
49
49
  requirements:
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: 6.5.0
52
+ version: 8.3.0
53
53
  name: logstash-core
54
54
  prerelease: false
55
55
  type: :runtime
@@ -57,7 +57,7 @@ dependencies:
57
57
  requirements:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: 6.5.0
60
+ version: 8.3.0
61
61
  - !ruby/object:Gem::Dependency
62
62
  requirement: !ruby/object:Gem::Requirement
63
63
  requirements:
@@ -258,17 +258,17 @@ files:
258
258
  - spec/unit/inputs/kafka_spec.rb
259
259
  - spec/unit/outputs/kafka_spec.rb
260
260
  - vendor/jar-dependencies/com/github/luben/zstd-jni/1.5.2-2/zstd-jni-1.5.2-2.jar
261
- - vendor/jar-dependencies/io/confluent/common-config/6.2.2/common-config-6.2.2.jar
262
- - vendor/jar-dependencies/io/confluent/common-utils/6.2.2/common-utils-6.2.2.jar
263
- - vendor/jar-dependencies/io/confluent/kafka-avro-serializer/6.2.2/kafka-avro-serializer-6.2.2.jar
264
- - vendor/jar-dependencies/io/confluent/kafka-schema-registry-client/6.2.2/kafka-schema-registry-client-6.2.2.jar
265
- - vendor/jar-dependencies/io/confluent/kafka-schema-serializer/6.2.2/kafka-schema-serializer-6.2.2.jar
261
+ - vendor/jar-dependencies/io/confluent/common-config/7.3.0/common-config-7.3.0.jar
262
+ - vendor/jar-dependencies/io/confluent/common-utils/7.3.0/common-utils-7.3.0.jar
263
+ - vendor/jar-dependencies/io/confluent/kafka-avro-serializer/7.3.0/kafka-avro-serializer-7.3.0.jar
264
+ - vendor/jar-dependencies/io/confluent/kafka-schema-registry-client/7.3.0/kafka-schema-registry-client-7.3.0.jar
265
+ - vendor/jar-dependencies/io/confluent/kafka-schema-serializer/7.3.0/kafka-schema-serializer-7.3.0.jar
266
266
  - vendor/jar-dependencies/javax/ws/rs/javax.ws.rs-api/2.1.1/javax.ws.rs-api-2.1.1.jar
267
267
  - vendor/jar-dependencies/org/apache/avro/avro/1.11.0/avro-1.11.0.jar
268
- - vendor/jar-dependencies/org/apache/kafka/kafka-clients/2.8.1/kafka-clients-2.8.1.jar
269
- - vendor/jar-dependencies/org/apache/kafka/kafka_2.12/2.8.1/kafka_2.12-2.8.1.jar
268
+ - vendor/jar-dependencies/org/apache/kafka/kafka-clients/3.3.1/kafka-clients-3.3.1.jar
269
+ - vendor/jar-dependencies/org/apache/kafka/kafka_2.12/3.3.1/kafka_2.12-3.3.1.jar
270
270
  - vendor/jar-dependencies/org/glassfish/jersey/core/jersey-common/2.33/jersey-common-2.33.jar
271
- - vendor/jar-dependencies/org/lz4/lz4-java/1.7.1/lz4-java-1.7.1.jar
271
+ - vendor/jar-dependencies/org/lz4/lz4-java/1.8.0/lz4-java-1.8.0.jar
272
272
  - vendor/jar-dependencies/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar
273
273
  - vendor/jar-dependencies/org/xerial/snappy/snappy-java/1.1.8.4/snappy-java-1.1.8.4.jar
274
274
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html