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

Sign up to get free protection for your applications and to get access to all the features.
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