logstash-input-http_poller 5.2.0 → 5.3.1

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