logstash-input-http_poller 5.2.0 → 5.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 512535463aaa56747ba5e9d6a264887588966a6df43518955deccb19f2b7acae
4
- data.tar.gz: 6c9b5b63198545b35e019b8e4f70edcec9f74ea9e8b4e53d6982b3841f48598b
3
+ metadata.gz: 510ac72c358c306a8377a8cd714a1f58c867283b792e68f0374c79737f758126
4
+ data.tar.gz: 8c375ba083f4d8e6b8b20ced9d2b5c81c7f1322e36c0115dcbedcdc91087d16d
5
5
  SHA512:
6
- metadata.gz: 52a07cfe047ab7774d5ed1279ac9c5434031ccd86f57a6b93996345c8f7c1e6fe4792b8525dee40ef0be14832a2bfb85be192a80021f67a59adae507a0e01b5f
7
- data.tar.gz: e614b85fd0558f4bfda62c8cb5df8811249cd6ed2cfa9ebfeb67caab08feb133a00e29737e2a806c471b59bf4efd75ac5404f06be38488f8e70987ebe8441ef6
6
+ metadata.gz: 54b5171093fc938cb49e273cad550c6430179812b1c47d34b6fd1c307281612ad872a50aee10f420e39002a46e7a7b143162ae331a90bdc42fc4a534e2666762
7
+ data.tar.gz: 87bc152a391d0e76942ead58d80679ce5581275f89863e6e629248751713f17052ecef2d5ca7dcd778d776828be7f20e5fd9338ad4c181d0e5d9ec837faea775
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 5.3.1
2
+ - Fix: make sure plugin is closing the http client [#130](https://github.com/logstash-plugins/logstash-input-http_poller/pull/130)
3
+
4
+ ## 5.3.0
5
+ - Feat: added ssl_supported_protocols option [#133](https://github.com/logstash-plugins/logstash-input-http_poller/pull/133)
6
+
7
+ ## 5.2.1
8
+ - Deps: unpin rufus-scheduler dependency [#130](https://github.com/logstash-plugins/logstash-input-http_poller/pull/130)
9
+
1
10
  ## 5.2.0
2
11
  - Feat: support ssl_verification_mode option [#131](https://github.com/logstash-plugins/logstash-input-http_poller/pull/131)
3
12
 
data/Gemfile CHANGED
@@ -9,3 +9,5 @@ if Dir.exist?(logstash_path) && use_logstash_source
9
9
  gem 'logstash-core', :path => "#{logstash_path}/logstash-core"
10
10
  gem 'logstash-core-plugin-api', :path => "#{logstash_path}/logstash-core-plugin-api"
11
11
  end
12
+
13
+ gem 'rufus-scheduler', ENV['RUFUS_SCHEDULER_VERSION'] if ENV['RUFUS_SCHEDULER_VERSION']
data/docs/index.asciidoc CHANGED
@@ -146,6 +146,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
146
146
  | <<plugins-{type}s-{plugin}-retry_non_idempotent>> |<<boolean,boolean>>|No
147
147
  | <<plugins-{type}s-{plugin}-schedule>> |<<hash,hash>>|Yes
148
148
  | <<plugins-{type}s-{plugin}-socket_timeout>> |<<number,number>>|No
149
+ | <<plugins-{type}s-{plugin}-ssl_supported_protocols>> |<<string,string>>|No
149
150
  | <<plugins-{type}s-{plugin}-ssl_verification_mode>> |<<string,string>>|No
150
151
  | <<plugins-{type}s-{plugin}-target>> |<<string,string>>|No
151
152
  | <<plugins-{type}s-{plugin}-truststore>> |a valid filesystem path|No
@@ -414,6 +415,23 @@ See: rufus/scheduler for details about different schedule options and value stri
414
415
 
415
416
  Timeout (in seconds) to wait for data on the socket. Default is `10s`
416
417
 
418
+ [id="plugins-{type}s-{plugin}-ssl_supported_protocols"]
419
+ ===== `ssl_supported_protocols`
420
+
421
+ * Value type is <<string,string>>
422
+ * Allowed values are: `'TLSv1.1'`, `'TLSv1.2'`, `'TLSv1.3'`
423
+ * Default depends on the JDK being used. With up-to-date Logstash, the default is `['TLSv1.2', 'TLSv1.3']`.
424
+ `'TLSv1.1'` is not considered secure and is only provided for legacy applications.
425
+
426
+ List of allowed SSL/TLS versions to use when establishing a connection to the HTTP endpoint.
427
+
428
+ For Java 8 `'TLSv1.3'` is supported only since **8u262** (AdoptOpenJDK), but requires that you set the
429
+ `LS_JAVA_OPTS="-Djdk.tls.client.protocols=TLSv1.3"` system property in Logstash.
430
+
431
+ NOTE: If you configure the plugin to use `'TLSv1.1'` on any recent JVM, such as the one packaged with Logstash,
432
+ the protocol is disabled by default and needs to be enabled manually by changing `jdk.tls.disabledAlgorithms` in
433
+ the *$JDK_HOME/conf/security/java.security* configuration file. That is, `TLSv1.1` needs to be removed from the list.
434
+
417
435
  [id="plugins-{type}s-{plugin}-ssl_verification_mode"]
418
436
  ===== `ssl_verification_mode`
419
437
 
@@ -49,16 +49,35 @@ class LogStash::Inputs::HTTP_Poller < LogStash::Inputs::Base
49
49
  def register
50
50
  @host = Socket.gethostname.force_encoding(Encoding::UTF_8)
51
51
 
52
- @logger.info("Registering http_poller Input", :type => @type, :schedule => @schedule, :timeout => @timeout)
53
-
54
52
  setup_ecs_field!
55
53
  setup_requests!
56
54
  end
57
55
 
56
+ # @overload
58
57
  def stop
59
- Stud.stop!(@interval_thread) if @interval_thread
60
- @scheduler.stop if @scheduler
58
+ shutdown_scheduler_and_close_client(:wait)
59
+ end
60
+
61
+ # @overload
62
+ def close
63
+ shutdown_scheduler_and_close_client
64
+ end
65
+
66
+ def shutdown_scheduler_and_close_client(opt = nil)
67
+ @logger.debug("closing http client", client: client)
68
+ begin
69
+ client.close # since Manticore 0.9.0 this shuts-down/closes all resources
70
+ rescue => e
71
+ details = { exception: e.class, message: e.message }
72
+ details[:backtrace] = e.backtrace if @logger.debug?
73
+ @logger.warn "failed closing http client", details
74
+ end
75
+ if @scheduler
76
+ @logger.debug("shutting down scheduler", scheduler: @scheduler)
77
+ @scheduler.shutdown(opt) # on newer Rufus (3.8) this joins on the scheduler thread
78
+ end
61
79
  end
80
+ private :shutdown_scheduler_and_close_client
62
81
 
63
82
  private
64
83
  def setup_requests!
@@ -163,29 +182,31 @@ class LogStash::Inputs::HTTP_Poller < LogStash::Inputs::Base
163
182
  #schedule hash must contain exactly one of the allowed keys
164
183
  msg_invalid_schedule = "Invalid config. schedule hash must contain " +
165
184
  "exactly one of the following keys - cron, at, every or in"
166
- raise Logstash::ConfigurationError, msg_invalid_schedule if @schedule.keys.length !=1
185
+ raise Logstash::ConfigurationError, msg_invalid_schedule if @schedule.keys.length != 1
167
186
  schedule_type = @schedule.keys.first
168
187
  schedule_value = @schedule[schedule_type]
169
188
  raise LogStash::ConfigurationError, msg_invalid_schedule unless Schedule_types.include?(schedule_type)
170
189
 
171
190
  @scheduler = Rufus::Scheduler.new(:max_work_threads => 1)
172
- #as of v3.0.9, :first_in => :now doesn't work. Use the following workaround instead
173
191
  opts = schedule_type == "every" ? { :first_in => 0.01 } : {}
174
192
  @scheduler.send(schedule_type, schedule_value, opts) { run_once(queue) }
175
- @scheduler.join
193
+ @scheduler.thread.join # due newer rufus (3.8) doing a blocking operation on scheduler.join
176
194
  end
177
195
 
178
196
  def run_once(queue)
179
197
  @requests.each do |name, request|
198
+ # prevent executing a scheduler kick after the plugin has been stop-ed
199
+ # this could easily happen as the scheduler shutdown is not immediate
200
+ return if stop?
180
201
  request_async(queue, name, request)
181
202
  end
182
203
 
183
- client.execute!
204
+ client.execute! unless stop?
184
205
  end
185
206
 
186
207
  private
187
208
  def request_async(queue, name, request)
188
- @logger.debug? && @logger.debug("Fetching URL", :name => name, :url => request)
209
+ @logger.debug? && @logger.debug("async queueing fetching url", name: name, url: request)
189
210
  started = Time.now
190
211
 
191
212
  method, *request_opts = request
@@ -202,6 +223,7 @@ class LogStash::Inputs::HTTP_Poller < LogStash::Inputs::Base
202
223
 
203
224
  private
204
225
  def handle_success(queue, name, request, response, execution_time)
226
+ @logger.debug? && @logger.debug("success fetching url", name: name, url: request)
205
227
  body = response.body
206
228
  # If there is a usable response. HEAD requests are `nil` and empty get
207
229
  # responses come up as "" which will cause the codec to not yield anything
@@ -240,6 +262,7 @@ class LogStash::Inputs::HTTP_Poller < LogStash::Inputs::Base
240
262
  private
241
263
  # Beware, on old versions of manticore some uncommon failures are not handled
242
264
  def handle_failure(queue, name, request, exception, execution_time)
265
+ @logger.debug? && @logger.debug("failed fetching url", name: name, url: request)
243
266
  event = event_factory.new_event
244
267
  event.tag("_http_request_failure")
245
268
  apply_metadata(event, name, request, nil, execution_time)
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-input-http_poller'
3
- s.version = '5.2.0'
3
+ s.version = '5.3.1'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "Decodes the output of an HTTP API into events"
6
- s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
6
+ s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
7
7
  s.authors = [ "Elastic", "andrewvc"]
8
8
  s.email = 'info@elastic.co'
9
9
  s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
@@ -20,9 +20,8 @@ Gem::Specification.new do |s|
20
20
  # Gem dependencies
21
21
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
22
22
  s.add_runtime_dependency 'logstash-codec-plain'
23
- s.add_runtime_dependency "logstash-mixin-http_client", ">= 7.1.0"
24
- s.add_runtime_dependency 'stud', "~> 0.0.22"
25
- s.add_runtime_dependency 'rufus-scheduler', "~>3.0.9"
23
+ s.add_runtime_dependency "logstash-mixin-http_client", ">= 7.2.0"
24
+ s.add_runtime_dependency 'rufus-scheduler', ">= 3.0.9"
26
25
  s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~>1.3'
27
26
  s.add_runtime_dependency 'logstash-mixin-event_support', '~> 1.0', '>= 1.0.1'
28
27
  s.add_runtime_dependency 'logstash-mixin-validator_support', '~> 1.0'
@@ -7,6 +7,15 @@ require "timecop"
7
7
  require 'rspec/matchers/built_in/raise_error.rb'
8
8
  require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
9
9
 
10
+ begin
11
+ # TODO: CI work-around - will most likely be moved to the scheduler mixin
12
+ require 'et-orbi.rb' # a dependency of rufus-scheduler since 3.4
13
+ ::EtOrbi::EoTime.now # might take a long time to initialize - loading time zone
14
+ # data (from tz-info) and thus gets un-predictable on CI, since the scheduler worker
15
+ # thread might be stuck starting while we attempt to shutdown in a given time frame
16
+ rescue LoadError
17
+ end
18
+
10
19
  describe LogStash::Inputs::HTTP_Poller do
11
20
  let(:metadata_target) { "_http_poller_metadata" }
12
21
  let(:queue) { Queue.new }
@@ -25,18 +34,19 @@ describe LogStash::Inputs::HTTP_Poller do
25
34
  "schedule" => default_schedule,
26
35
  "urls" => default_urls,
27
36
  "codec" => "json",
28
- "metadata_target" => metadata_target
37
+ "metadata_target" => metadata_target,
38
+ "pool_max" => 3, "pool_max_per_route" => 1, 'keepalive' => false
29
39
  }
30
40
  }
31
- let(:klass) { LogStash::Inputs::HTTP_Poller }
41
+ let(:opts) { default_opts }
32
42
 
43
+ subject(:plugin) { described_class.new(opts) }
33
44
 
34
45
  describe "instances" do
35
- subject { klass.new(default_opts) }
46
+ subject { described_class.new(default_opts) }
36
47
 
37
- before do
38
- subject.register
39
- end
48
+ before { subject.register }
49
+ after { subject.stop }
40
50
 
41
51
  describe "#run" do
42
52
  it "should setup a scheduler" do
@@ -189,22 +199,21 @@ describe LogStash::Inputs::HTTP_Poller do
189
199
  "metadata_target" => metadata_target
190
200
  }
191
201
  }
192
- it "should run at the schedule" do
193
- instance = klass.new(opts)
194
- instance.register
202
+
203
+ before do
195
204
  Timecop.travel(Time.new(2000,1,1,0,0,0,'+00:00'))
196
205
  Timecop.scale(60)
197
- queue = Queue.new
198
- runner = Thread.new do
199
- instance.run(queue)
200
- end
201
- sleep 3
202
- instance.stop
203
- runner.kill
204
- runner.join
205
- expect(queue.size).to eq(2)
206
+ end
207
+
208
+ after do
206
209
  Timecop.return
207
210
  end
211
+
212
+ it "should run at the schedule" do
213
+ run_plugin_and_yield_queue(plugin, sleep: 3.1) do |queue|
214
+ try(10) { expect(queue.size).to be >= 2 }
215
+ end
216
+ end
208
217
  end
209
218
 
210
219
  context "given 'at' expression" do
@@ -216,22 +225,21 @@ describe LogStash::Inputs::HTTP_Poller do
216
225
  "metadata_target" => metadata_target
217
226
  }
218
227
  }
219
- it "should run at the schedule" do
220
- instance = klass.new(opts)
221
- instance.register
228
+
229
+ before do
222
230
  Timecop.travel(Time.new(2000,1,1,0,0,0,'+00:00'))
223
- Timecop.scale(60 * 5)
224
- queue = Queue.new
225
- runner = Thread.new do
226
- instance.run(queue)
227
- end
228
- sleep 2
229
- instance.stop
230
- runner.kill
231
- runner.join
232
- expect(queue.size).to eq(1)
231
+ Timecop.scale (60 * 5) / 2
232
+ end
233
+
234
+ after do
233
235
  Timecop.return
234
236
  end
237
+
238
+ it "should run at the schedule" do
239
+ run_plugin_and_yield_queue(plugin, sleep: 4.1) do |queue|
240
+ try(10) { expect(queue.size).to eq(1) }
241
+ end
242
+ end
235
243
  end
236
244
 
237
245
  context "given 'every' expression" do
@@ -244,48 +252,47 @@ describe LogStash::Inputs::HTTP_Poller do
244
252
  }
245
253
  }
246
254
  it "should run at the schedule" do
247
- instance = klass.new(opts)
248
- instance.register
249
- queue = Queue.new
250
- runner = Thread.new do
251
- instance.run(queue)
255
+ run_plugin_and_yield_queue(plugin, sleep: 5) do |queue|
256
+ #T 0123456
257
+ #events x x x x
258
+ #expects 3 events at T=5
259
+ try(10) { expect(queue.size).to be_between(2, 3) }
252
260
  end
253
- #T 0123456
254
- #events x x x x
255
- #expects 3 events at T=5
256
- sleep 5
257
- instance.stop
258
- runner.kill
259
- runner.join
260
- expect(queue.size).to be_between(2, 3)
261
261
  end
262
262
  end
263
263
 
264
264
  context "given 'in' expression" do
265
265
  let(:opts) {
266
266
  {
267
- "schedule" => { "in" => "2s"},
267
+ "schedule" => { "in" => "1s"},
268
268
  "urls" => default_urls,
269
269
  "codec" => "json",
270
270
  "metadata_target" => metadata_target
271
271
  }
272
272
  }
273
273
  it "should run at the schedule" do
274
- instance = klass.new(opts)
275
- instance.register
276
- queue = Queue.new
277
- runner = Thread.new do
278
- instance.run(queue)
274
+ run_plugin_and_yield_queue(plugin, sleep: 2.05) do |queue|
275
+ try(10) { expect(queue.size).to eq(1) }
279
276
  end
280
- sleep 3
281
- instance.stop
282
- runner.kill
283
- runner.join
284
- expect(queue.size).to eq(1)
285
277
  end
286
278
  end
287
279
  end
288
280
 
281
+ def run_plugin_and_yield_queue(plugin, sleep: nil)
282
+ plugin.register
283
+ queue = Queue.new
284
+ begin
285
+ runner = Thread.new do
286
+ plugin.run(queue)
287
+ end
288
+ sleep(sleep) if sleep
289
+ yield(queue)
290
+ ensure
291
+ plugin.stop
292
+ runner.join if runner
293
+ end
294
+ end
295
+
289
296
  describe "events", :ecs_compatibility_support, :aggregate_failures do
290
297
  ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do |ecs_select|
291
298
  before do
@@ -339,6 +346,8 @@ describe LogStash::Inputs::HTTP_Poller do
339
346
  event # materialize the subject
340
347
  end
341
348
 
349
+ after { poller.stop }
350
+
342
351
  it "should enqueue a message" do
343
352
  expect(event).to be_a(LogStash::Event)
344
353
  end
@@ -399,9 +408,6 @@ describe LogStash::Inputs::HTTP_Poller do
399
408
  let(:payload) { {"a" => 2, "hello" => ["a", "b", "c"]} }
400
409
  let(:response_body) { LogStash::Json.dump(payload) }
401
410
  let(:opts) { default_opts }
402
- let(:instance) {
403
- klass.new(opts)
404
- }
405
411
  let(:name) { default_name }
406
412
  let(:url) { default_url }
407
413
  let(:code) { 202 }
@@ -411,14 +417,15 @@ describe LogStash::Inputs::HTTP_Poller do
411
417
  }
412
418
 
413
419
  before do
414
- instance.register
420
+ plugin.register
415
421
  u = url.is_a?(Hash) ? url["url"] : url # handle both complex specs and simple string URLs
416
- instance.client.stub(u,
417
- :body => response_body,
418
- :code => code
419
- )
420
- allow(instance).to receive(:decorate)
421
- instance.send(:run_once, queue)
422
+ plugin.client.stub(u, :body => response_body, :code => code)
423
+ allow(plugin).to receive(:decorate)
424
+ plugin.send(:run_once, queue)
425
+ end
426
+
427
+ after do
428
+ plugin.close
422
429
  end
423
430
 
424
431
  it "should have a matching message" do
@@ -426,7 +433,7 @@ describe LogStash::Inputs::HTTP_Poller do
426
433
  end
427
434
 
428
435
  it "should decorate the event" do
429
- expect(instance).to have_received(:decorate).once
436
+ expect(plugin).to have_received(:decorate).once
430
437
  end
431
438
 
432
439
  include_examples("matching metadata")
@@ -434,7 +441,7 @@ describe LogStash::Inputs::HTTP_Poller do
434
441
  context "with an empty body" do
435
442
  let(:response_body) { "" }
436
443
  it "should return an empty event" do
437
- instance.send(:run_once, queue)
444
+ plugin.send(:run_once, queue)
438
445
  headers_field = ecs_select[disabled: "[#{metadata_target}][response_headers]",
439
446
  v1: "[#{metadata_target}][input][http_poller][response][headers]"]
440
447
  expect(event.get("#{headers_field}[content-length]")).to eql("0")
@@ -449,7 +456,7 @@ describe LogStash::Inputs::HTTP_Poller do
449
456
  }
450
457
 
451
458
  it "should not have any metadata on the event" do
452
- instance.send(:run_once, queue)
459
+ plugin.send(:run_once, queue)
453
460
  expect(event.get(metadata_target)).to be_nil
454
461
  end
455
462
  end
@@ -555,6 +562,8 @@ describe LogStash::Inputs::HTTP_Poller do
555
562
 
556
563
  describe "stopping" do
557
564
  let(:config) { default_opts }
558
- it_behaves_like "an interruptible input plugin"
565
+ it_behaves_like "an interruptible input plugin" do
566
+ let(:allowed_lag) { 10 } # CI: wait till scheduler shuts down
567
+ end
559
568
  end
560
569
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-http_poller
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.0
4
+ version: 5.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-02-01 00:00:00.000000000 Z
12
+ date: 2022-06-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  requirement: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: 7.1.0
53
+ version: 7.2.0
54
54
  name: logstash-mixin-http_client
55
55
  prerelease: false
56
56
  type: :runtime
@@ -58,25 +58,11 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 7.1.0
61
+ version: 7.2.0
62
62
  - !ruby/object:Gem::Dependency
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: 0.0.22
68
- name: stud
69
- prerelease: false
70
- type: :runtime
71
- version_requirements: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 0.0.22
76
- - !ruby/object:Gem::Dependency
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
65
+ - - ">="
80
66
  - !ruby/object:Gem::Version
81
67
  version: 3.0.9
82
68
  name: rufus-scheduler
@@ -84,7 +70,7 @@ dependencies:
84
70
  type: :runtime
85
71
  version_requirements: !ruby/object:Gem::Requirement
86
72
  requirements:
87
- - - "~>"
73
+ - - ">="
88
74
  - !ruby/object:Gem::Version
89
75
  version: 3.0.9
90
76
  - !ruby/object:Gem::Dependency