logstash-input-jms 3.1.2-java → 3.2.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/README.md +1 -1
- data/docs/index.asciidoc +99 -13
- data/lib/logstash/inputs/jms.rb +193 -24
- data/logstash-input-jms.gemspec +8 -5
- data/spec/inputs/integration/jms_spec.rb +134 -44
- data/spec/inputs/unit/jms_spec.rb +66 -10
- metadata +50 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a40f29ee0db67e912d547f5fa74a74bcd08466c3f2594dd9edd5f82669ea494
|
4
|
+
data.tar.gz: c8fa0a986cea0a588b8b68fbd8618f24122ee42abb21ad3cf7f5e7cbb0f3484c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a121b9359ff97942888218bb1f2553f469940574e7f8421f7e910980bf37b973fd73cb2e0739a7525c0b71c5e8b4891765f70e505a798d1d9263f0bedbb13eee
|
7
|
+
data.tar.gz: d10f028310928b17f41f48cc50e8393022171d2c2fa4d25502f428f3d2bfbfc6172eee75d527d0ebb9b66f5a3790b6fe9c50fc3de5355dd71a907be33d5f9c5c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 3.2.0
|
2
|
+
- Feat: event_factory support + targets to aid ECS [#49](https://github.com/logstash-plugins/logstash-input-jms/pull/49)
|
3
|
+
- Fix: when configured to add JMS headers to the event, headers whose value is not set no longer result in nil entries on the event
|
4
|
+
- Fix: when adding the `jms_reply_to` header to an event, a string representation is set instead of an opaque object.
|
5
|
+
|
1
6
|
## 3.1.2
|
2
7
|
- Docs: Added additional troubleshooting information [#38](https://github.com/logstash-plugins/logstash-input-jms/pull/38)
|
3
8
|
|
@@ -45,7 +50,7 @@
|
|
45
50
|
- New dependency requirements for logstash-core for the 5.0 release
|
46
51
|
|
47
52
|
## 2.0.0
|
48
|
-
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
|
53
|
+
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
|
49
54
|
instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
|
50
55
|
- Dependency on logstash-core update to 2.0
|
51
56
|
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Logstash Plugin
|
2
2
|
|
3
|
-
[![Travis Build Status](https://travis-ci.
|
3
|
+
[![Travis Build Status](https://travis-ci.com/logstash-plugins/logstash-input-jms.svg)](https://travis-ci.com/logstash-plugins/logstash-input-jms)
|
4
4
|
|
5
5
|
This is a plugin for [Logstash](https://github.com/elastic/logstash).
|
6
6
|
|
data/docs/index.asciidoc
CHANGED
@@ -33,6 +33,14 @@ JMS configurations can be done either entirely in the Logstash configuration fil
|
|
33
33
|
configurations, should also use the combination of yaml file and Logstash configuration.
|
34
34
|
|
35
35
|
|
36
|
+
[id="plugins-{type}s-{plugin}-ecs"]
|
37
|
+
==== Compatibility with the Elastic Common Schema (ECS)
|
38
|
+
|
39
|
+
JMS data is application specific. ECS compliance for fields depends on the use case.
|
40
|
+
The plugin includes sensible defaults that change based on <<plugins-{type}s-{plugin}-ecs_compatibility,ECS compatibility mode>>.
|
41
|
+
When ECS compatibility is disabled, headers, properties, and payload are targeted at the root level of the event to maintain compatibility with legacy usage of this plugin.
|
42
|
+
When targeting an ECS version, headers and properties target `@metadata` sub-fields unless configured otherwise in order to avoid conflict with ECS fields.
|
43
|
+
See <<plugins-{type}s-{plugin}-headers_target>>, <<plugins-{type}s-{plugin}-properties_target>> and <<plugins-{type}s-{plugin}-target>>.
|
36
44
|
|
37
45
|
==== Sample Configuration using Logstash Configuration Only
|
38
46
|
|
@@ -60,7 +68,7 @@ The JMS plugin can also be configured using JNDI if desired.
|
|
60
68
|
truststore => '/Users/logstash-user/security/truststore.jks'
|
61
69
|
truststore_password => 'yet_another_secret'
|
62
70
|
# Parts of the JMS message to be included <8>
|
63
|
-
|
71
|
+
include_headers => false
|
64
72
|
include_properties => false
|
65
73
|
include_body => true
|
66
74
|
# Message selector
|
@@ -98,7 +106,7 @@ The JMS plugin can also be configured using JNDI if desired.
|
|
98
106
|
input {
|
99
107
|
jms {
|
100
108
|
# Logstash Configuration Settings. <1>
|
101
|
-
|
109
|
+
include_headers => false
|
102
110
|
include_properties => false
|
103
111
|
include_body => true
|
104
112
|
use_jms_timestamp => false
|
@@ -144,7 +152,7 @@ This section contains sample configurations for connecting to a JMS provider tha
|
|
144
152
|
input {
|
145
153
|
jms {
|
146
154
|
# Logstash Configuration File Settings <1>
|
147
|
-
|
155
|
+
include_headers => false
|
148
156
|
include_properties => false
|
149
157
|
include_body => true
|
150
158
|
use_jms_timestamp => false
|
@@ -205,7 +213,7 @@ This section contains sample configurations for connecting to a JMS provider tha
|
|
205
213
|
input {
|
206
214
|
jms {
|
207
215
|
# Logstash specific configuration settings <1>
|
208
|
-
|
216
|
+
include_headers => false
|
209
217
|
include_properties => false
|
210
218
|
include_body => true
|
211
219
|
use_jms_timestamp => false
|
@@ -379,10 +387,13 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
379
387
|
| <<plugins-{type}s-{plugin}-durable_subscriber>> |<<boolean,boolean>>|No
|
380
388
|
| <<plugins-{type}s-{plugin}-durable_subscriber_client_id>> |<<string,string>>|No
|
381
389
|
| <<plugins-{type}s-{plugin}-durable_subscriber_name>> |<<string,string>>|No
|
390
|
+
| <<plugins-{type}s-{plugin}-ecs_compatibility>> |<<string,string>>|No
|
382
391
|
| <<plugins-{type}s-{plugin}-factory>> |<<string,string>>|No
|
383
392
|
| <<plugins-{type}s-{plugin}-factory_settings>> |<<hash,hash>>|No
|
393
|
+
| <<plugins-{type}s-{plugin}-headers_target>> |<<string,string>>|No
|
384
394
|
| <<plugins-{type}s-{plugin}-include_body>> |<<boolean,boolean>>|No
|
385
395
|
| <<plugins-{type}s-{plugin}-include_header>> |<<boolean,boolean>>|No
|
396
|
+
| <<plugins-{type}s-{plugin}-include_headers>> |<<boolean,boolean>>|No
|
386
397
|
| <<plugins-{type}s-{plugin}-include_properties>> |<<boolean,boolean>>|No
|
387
398
|
| <<plugins-{type}s-{plugin}-interval>> |<<number,number>>|No
|
388
399
|
| <<plugins-{type}s-{plugin}-jndi_context>> |<<hash,hash>>|No
|
@@ -391,6 +402,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
391
402
|
| <<plugins-{type}s-{plugin}-keystore_password>> |<<password,password>>|No
|
392
403
|
| <<plugins-{type}s-{plugin}-oracle_aq_buffered_messages>> |<<boolean,boolean>>|No
|
393
404
|
| <<plugins-{type}s-{plugin}-password>> |<<string,string>>|No
|
405
|
+
| <<plugins-{type}s-{plugin}-properties_target>> |<<string,string>>|No
|
394
406
|
| <<plugins-{type}s-{plugin}-pub_sub>> |<<boolean,boolean>>|No
|
395
407
|
| <<plugins-{type}s-{plugin}-require_jars>> |<<array,array>>|No
|
396
408
|
| <<plugins-{type}s-{plugin}-runner>> |<<string,string>>|__Deprecated__
|
@@ -398,6 +410,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
398
410
|
| <<plugins-{type}s-{plugin}-skip_headers>> |<<array,array>>|No
|
399
411
|
| <<plugins-{type}s-{plugin}-skip_properties>> |<<array,array>>|No
|
400
412
|
| <<plugins-{type}s-{plugin}-system_properties>> |<<hash,hash>>|No
|
413
|
+
| <<plugins-{type}s-{plugin}-target>> |<<string,string>>|No
|
401
414
|
| <<plugins-{type}s-{plugin}-threads>> |<<number,number>>|No
|
402
415
|
| <<plugins-{type}s-{plugin}-timeout>> |<<number,number>>|No
|
403
416
|
| <<plugins-{type}s-{plugin}-truststore>> |a valid filesystem path|No
|
@@ -430,6 +443,8 @@ Url to use when connecting to the JMS provider. This is only relevant for non-JN
|
|
430
443
|
|
431
444
|
Name of the destination queue or topic to use.
|
432
445
|
|
446
|
+
TIP: If the destination setting doesn't appear to be working properly, try this format: `<JMS module name>!<JMS queue name>`.
|
447
|
+
|
433
448
|
[id="plugins-{type}s-{plugin}-durable_subscriber"]
|
434
449
|
===== `durable_subscriber`
|
435
450
|
|
@@ -466,6 +481,21 @@ This represents the value of the client ID for a durable subscribtion, and is on
|
|
466
481
|
This represents the value of the subscriber name for a durable subscribtion, and is only used if `durable_subscriber`
|
467
482
|
is set to `true`. Please consult your JMS Provider documentation for constraints and requirements for this setting.
|
468
483
|
|
484
|
+
[id="plugins-{type}s-{plugin}-ecs_compatibility"]
|
485
|
+
===== `ecs_compatibility`
|
486
|
+
|
487
|
+
* Value type is <<string,string>>
|
488
|
+
* Supported values are:
|
489
|
+
** `disabled`: does not use ECS-compatible field names (fields might be set at the root of the event)
|
490
|
+
** `v1`, `v8`: avoids field names that might conflict with Elastic Common Schema (for example, JMS specific properties)
|
491
|
+
* Default value depends on which version of Logstash is running:
|
492
|
+
** When Logstash provides a `pipeline.ecs_compatibility` setting, its value is used as the default
|
493
|
+
** Otherwise, the default value is `disabled`.
|
494
|
+
|
495
|
+
Controls this plugin's compatibility with the {ecs-ref}[Elastic Common Schema (ECS)].
|
496
|
+
The value of this setting affects the _default_ value of <<plugins-{type}s-{plugin}-headers_target>> and
|
497
|
+
<<plugins-{type}s-{plugin}-properties_target>>.
|
498
|
+
|
469
499
|
[id="plugins-{type}s-{plugin}-factory"]
|
470
500
|
===== `factory`
|
471
501
|
|
@@ -486,6 +516,16 @@ Hash of implementation specific configuration values to set on the connection fa
|
|
486
516
|
`exclusive_consumer => true` would call `setExclusiveConsumer(true)` on the supplied connection factory.
|
487
517
|
See your JMS provider documentation for implementation specific details.
|
488
518
|
|
519
|
+
[id="plugins-{type}s-{plugin}-headers_target"]
|
520
|
+
===== `headers_target`
|
521
|
+
|
522
|
+
* Value type is <<string,string>>
|
523
|
+
* Default value depends on whether <<plugins-{type}s-{plugin}-ecs_compatibility>> is enabled:
|
524
|
+
** ECS Compatibility disabled: no default value for this setting
|
525
|
+
** ECS Compatibility enabled: `"[@metadata][input][jms][headers]"
|
526
|
+
|
527
|
+
The name of the field under which JMS headers will be added, if <<plugins-{type}s-{plugin}-include_headers>> is set.
|
528
|
+
|
489
529
|
[id="plugins-{type}s-{plugin}-include_body"]
|
490
530
|
===== `include_body`
|
491
531
|
|
@@ -493,29 +533,54 @@ Hash of implementation specific configuration values to set on the connection fa
|
|
493
533
|
* Default value is `true`
|
494
534
|
|
495
535
|
Include JMS Message Body in the event.
|
496
|
-
Supports TextMessage, MapMessage and
|
536
|
+
Supports TextMessage, MapMessage and BytesMessage.
|
497
537
|
|
498
|
-
If the JMS Message is a TextMessage or
|
538
|
+
If the JMS Message is a TextMessage or BytesMessage, then the value will be in
|
499
539
|
the "message" field of the event. If the JMS Message is a MapMessage, then all
|
500
|
-
the key/value pairs will be added
|
540
|
+
the key/value pairs will be added at the top-level of the event by default.
|
541
|
+
To avoid pollution of the top-level namespace, when receiving a MapMessage, use the <<plugins-{type}s-{plugin}-target>>.
|
501
542
|
|
502
543
|
StreamMessage and ObjectMessage are not supported.
|
503
544
|
|
504
545
|
[id="plugins-{type}s-{plugin}-include_header"]
|
505
546
|
===== `include_header`
|
506
547
|
|
548
|
+
* Value type is <<boolean,boolean>>
|
549
|
+
* This option is deprecated
|
550
|
+
|
551
|
+
Note: This option is deprecated and it will be removed in the next major version of Logstash.
|
552
|
+
Use `include_headers` instead.
|
553
|
+
|
554
|
+
[id="plugins-{type}s-{plugin}-include_headers"]
|
555
|
+
===== `include_headers`
|
556
|
+
|
507
557
|
* Value type is <<boolean,boolean>>
|
508
558
|
* Default value is `true`
|
509
559
|
|
510
560
|
A JMS message has three parts:
|
511
561
|
|
512
|
-
* Message Headers (required)
|
513
|
-
* Message Properties (optional)
|
514
|
-
* Message
|
562
|
+
* Message Headers (required)
|
563
|
+
* Message Properties (optional)
|
564
|
+
* Message Body (optional)
|
515
565
|
|
516
566
|
You can tell the input plugin which parts should be included in the event produced by Logstash.
|
517
567
|
|
518
|
-
Include JMS
|
568
|
+
Include standard JMS message header field values in the event.
|
569
|
+
Example headers:
|
570
|
+
[source,ruby]
|
571
|
+
-----
|
572
|
+
{
|
573
|
+
"jms_message_id" => "ID:amqhost-39547-1636977297920-71:1:1:1:1",
|
574
|
+
"jms_timestamp" => 1636977329102,
|
575
|
+
"jms_expiration" => 0,
|
576
|
+
"jms_delivery_mode" => "persistent",
|
577
|
+
"jms_redelivered" => false,
|
578
|
+
"jms_destination" => "topic://41ad5342149901ad",
|
579
|
+
"jms_priority" => 4,
|
580
|
+
"jms_type" => "sample",
|
581
|
+
"jms_correlation_id" => "28d975cb-14ff-4285-841e-05ef1e0a7ab2"
|
582
|
+
}
|
583
|
+
-----
|
519
584
|
|
520
585
|
[id="plugins-{type}s-{plugin}-include_properties"]
|
521
586
|
===== `include_properties`
|
@@ -588,6 +653,16 @@ Only for use with Oracle AQ
|
|
588
653
|
|
589
654
|
Password to use when connecting to the JMS provider.
|
590
655
|
|
656
|
+
[id="plugins-{type}s-{plugin}-properties_target"]
|
657
|
+
===== `properties_target`
|
658
|
+
|
659
|
+
* Value type is <<string,string>>
|
660
|
+
* Default value depends on whether <<plugins-{type}s-{plugin}-ecs_compatibility>> is enabled:
|
661
|
+
** ECS Compatibility disabled: no default value for this setting
|
662
|
+
** ECS Compatibility enabled: `"[@metadata][input][jms][properties]"
|
663
|
+
|
664
|
+
The name of the field under which JMS properties will be added, if <<plugins-{type}s-{plugin}-include_properties>> is set.
|
665
|
+
|
591
666
|
[id="plugins-{type}s-{plugin}-pub_sub"]
|
592
667
|
===== `pub_sub`
|
593
668
|
|
@@ -648,6 +723,17 @@ If `include_properties` is set, a list of properties to skip processing on can b
|
|
648
723
|
|
649
724
|
Any System properties that the JMS provider requires can be set either in a Hash here, or in `jvm.options`
|
650
725
|
|
726
|
+
[id="plugins-{type}s-{plugin}-target"]
|
727
|
+
===== `target`
|
728
|
+
|
729
|
+
* Value type is <<string,string>>
|
730
|
+
* There is no default value for this setting.
|
731
|
+
|
732
|
+
The name of the field to assign MapMessage data into.
|
733
|
+
If not specified data will be stored in the root of the event.
|
734
|
+
|
735
|
+
NOTE: For TextMessage and BytesMessage the `target` has no effect. Use the codec setting instead
|
736
|
+
e.g. `codec => json { target => "[jms]" }`.
|
651
737
|
|
652
738
|
[id="plugins-{type}s-{plugin}-threads"]
|
653
739
|
===== `threads`
|
@@ -655,7 +741,7 @@ Any System properties that the JMS provider requires can be set either in a Hash
|
|
655
741
|
* Value type is <<number,number>>
|
656
742
|
* Default value is `1`
|
657
743
|
|
658
|
-
|
744
|
+
NOTE: If pub_sub is set to `true`, this value *must* be `1`. A configuration error will be thrown otherwise!
|
659
745
|
|
660
746
|
[id="plugins-{type}s-{plugin}-timeout"]
|
661
747
|
===== `timeout`
|
@@ -722,4 +808,4 @@ For some known examples, see https://github.com/reidmorrison/jruby-jms/blob/mast
|
|
722
808
|
[id="plugins-{type}s-{plugin}-common-options"]
|
723
809
|
include::{include_path}/{type}.asciidoc[]
|
724
810
|
|
725
|
-
:default_codec!:
|
811
|
+
:default_codec!:
|
data/lib/logstash/inputs/jms.rb
CHANGED
@@ -4,13 +4,18 @@ require "logstash/inputs/threadable"
|
|
4
4
|
require 'java'
|
5
5
|
require "logstash/namespace"
|
6
6
|
|
7
|
+
require 'logstash/plugin_mixins/ecs_compatibility_support'
|
8
|
+
require 'logstash/plugin_mixins/ecs_compatibility_support/target_check'
|
9
|
+
require 'logstash/plugin_mixins/event_support/event_factory_adapter'
|
10
|
+
require 'logstash/plugin_mixins/validator_support/field_reference_validation_adapter'
|
11
|
+
|
7
12
|
# Read events from a Jms Broker. Supports both Jms Queues and Topics.
|
8
13
|
#
|
9
14
|
# For more information about Jms, see <http://docs.oracle.com/javaee/6/tutorial/doc/bncdq.html>
|
10
15
|
# For more information about the Ruby Gem used, see <http://github.com/reidmorrison/jruby-jms>
|
11
16
|
# Here is a config example to pull from a queue:
|
12
17
|
# jms {
|
13
|
-
#
|
18
|
+
# include_headers => false
|
14
19
|
# include_properties => false
|
15
20
|
# include_body => true
|
16
21
|
# use_jms_timestamp => false
|
@@ -23,6 +28,12 @@ require "logstash/namespace"
|
|
23
28
|
#
|
24
29
|
#
|
25
30
|
class LogStash::Inputs::Jms < LogStash::Inputs::Threadable
|
31
|
+
|
32
|
+
include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1, :v8 => :v1)
|
33
|
+
include LogStash::PluginMixins::EventSupport::EventFactoryAdapter
|
34
|
+
|
35
|
+
extend LogStash::PluginMixins::ValidatorSupport::FieldReferenceValidationAdapter
|
36
|
+
|
26
37
|
config_name "jms"
|
27
38
|
|
28
39
|
# A JMS message has three parts :
|
@@ -32,7 +43,8 @@ class LogStash::Inputs::Jms < LogStash::Inputs::Threadable
|
|
32
43
|
# You can tell the input plugin which parts should be included in the event produced by Logstash
|
33
44
|
#
|
34
45
|
# Include JMS Message Header Field values in the event
|
35
|
-
config :include_header, :validate => :boolean, :
|
46
|
+
config :include_header, :validate => :boolean, :deprecated => "Set 'include_headers => ...' instead"
|
47
|
+
config :include_headers, :validate => :boolean, :default => true
|
36
48
|
# Include JMS Message Properties Field values in the event
|
37
49
|
config :include_properties, :validate => :boolean, :default => true
|
38
50
|
|
@@ -48,12 +60,12 @@ class LogStash::Inputs::Jms < LogStash::Inputs::Threadable
|
|
48
60
|
# If the JMS Message is a MapMessage, then all the key/value pairs will be added in the Hashmap of the event
|
49
61
|
# StreamMessage and ObjectMessage are not supported
|
50
62
|
|
51
|
-
# Receive Oracle AQ buffered messages.
|
63
|
+
# Receive Oracle AQ buffered messages.
|
52
64
|
# In this mode persistent Oracle AQ JMS messages will not be received.
|
53
65
|
config :oracle_aq_buffered_messages, :validate => :boolean, :default => false
|
54
66
|
|
55
67
|
config :include_body, :validate => :boolean, :default => true
|
56
|
-
|
68
|
+
|
57
69
|
# Convert the JMSTimestamp header field to the @timestamp value of the event
|
58
70
|
config :use_jms_timestamp, :validate => :boolean, :default => false
|
59
71
|
|
@@ -122,6 +134,15 @@ class LogStash::Inputs::Jms < LogStash::Inputs::Threadable
|
|
122
134
|
config :truststore, :validate => :path
|
123
135
|
config :truststore_password, :validate => :password
|
124
136
|
|
137
|
+
# Defines a target field for placing fields.
|
138
|
+
# If this setting is omitted, data gets stored at the root (top level) of the event.
|
139
|
+
# The target is only relevant while decoding data into a new event.
|
140
|
+
#
|
141
|
+
# NOTE: this is only relevant for map messages; byte[] and string use the codec!
|
142
|
+
config :target, :validate => :field_reference
|
143
|
+
|
144
|
+
config :headers_target, :validate => :field_reference # ECS default: [@metadata][input][jms][headers]
|
145
|
+
config :properties_target, :validate => :field_reference # ECS default: [@metadata][input][jms][properties]
|
125
146
|
|
126
147
|
# :yaml_file, :factory and :jndi_name are mutually exclusive, both cannot be supplied at the
|
127
148
|
# same time. The priority order is :yaml_file, then :jndi_name, then :factory
|
@@ -132,10 +153,25 @@ class LogStash::Inputs::Jms < LogStash::Inputs::Threadable
|
|
132
153
|
# For some known examples, see: [Example jms.yml](https://github.com/reidmorrison/jruby-jms/blob/master/examples/jms.yml)
|
133
154
|
|
134
155
|
public
|
156
|
+
|
157
|
+
def initialize(*params)
|
158
|
+
super
|
159
|
+
|
160
|
+
if ecs_compatibility != :disabled # set ECS target defaults
|
161
|
+
@headers_target = '[@metadata][input][jms][headers]' unless original_params.include?('headers_target')
|
162
|
+
@properties_target = '[@metadata][input][jms][properties]' unless original_params.include?('properties_target')
|
163
|
+
end
|
164
|
+
|
165
|
+
@headers_setter = event_setter_for(@headers_target)
|
166
|
+
@properties_setter = event_setter_for(@properties_target)
|
167
|
+
|
168
|
+
@headers_mapper = ecs_compatibility == :disabled ? LegacyHeadersMapper::INSTANCE : HeadersMapper::INSTANCE
|
169
|
+
end
|
170
|
+
|
135
171
|
def register
|
136
172
|
require "jms"
|
137
173
|
|
138
|
-
check_config
|
174
|
+
check_config!
|
139
175
|
load_ssl_properties
|
140
176
|
load_system_properties if @system_properties
|
141
177
|
@jms_config = jms_config
|
@@ -208,7 +244,15 @@ class LogStash::Inputs::Jms < LogStash::Inputs::Threadable
|
|
208
244
|
@system_properties.each { |k,v| java.lang.System.set_property(k,v.to_s) }
|
209
245
|
end
|
210
246
|
|
211
|
-
def check_config
|
247
|
+
def check_config!
|
248
|
+
if original_params.include?('include_header')
|
249
|
+
if original_params.include?('include_headers')
|
250
|
+
raise(LogStash::ConfigurationError, "Both `include_headers => #{include_headers}` and `include_header => #{include_header}`" +
|
251
|
+
" options are specified, please only set one")
|
252
|
+
end
|
253
|
+
@include_headers = include_header # only `include_header => ...` was set
|
254
|
+
end
|
255
|
+
|
212
256
|
check_durable_subscription_config
|
213
257
|
raise(LogStash::ConfigurationError, "Threads cannot be > 1 if pub_sub is set") if @threads > 1 && @pub_sub
|
214
258
|
end
|
@@ -252,43 +296,35 @@ class LogStash::Inputs::Jms < LogStash::Inputs::Threadable
|
|
252
296
|
end
|
253
297
|
end # def run_consumer
|
254
298
|
|
255
|
-
|
256
299
|
def queue_event(msg, output_queue)
|
257
300
|
begin
|
258
301
|
if @include_body
|
259
302
|
if msg.java_kind_of?(JMS::MapMessage)
|
260
|
-
event =
|
261
|
-
msg.data.each do |field, value|
|
262
|
-
event.set(field.to_s, value) # TODO(claveau): needs codec.decode or converter.convert ?
|
263
|
-
end
|
303
|
+
event = process_map_message(msg)
|
264
304
|
elsif msg.java_kind_of?(JMS::TextMessage) || msg.java_kind_of?(JMS::BytesMessage)
|
265
|
-
|
266
|
-
@codec.decode(msg.to_s) do |event_message|
|
267
|
-
event = event_message
|
268
|
-
end
|
269
|
-
end
|
305
|
+
event = decode_message(msg)
|
270
306
|
else
|
271
307
|
@logger.error( "Unsupported message type #{msg.data.class.to_s}" )
|
272
308
|
end
|
273
309
|
end
|
274
310
|
|
275
|
-
event ||=
|
311
|
+
event ||= event_factory.new_event
|
276
312
|
|
277
313
|
# Here, we can use the JMS Enqueue timestamp as the @timestamp
|
278
314
|
if @use_jms_timestamp && msg.jms_timestamp
|
279
315
|
event.set("@timestamp", LogStash::Timestamp.at(msg.jms_timestamp / 1000, (msg.jms_timestamp % 1000) * 1000))
|
280
316
|
end
|
281
317
|
|
282
|
-
if @
|
283
|
-
|
284
|
-
|
285
|
-
|
318
|
+
if @include_headers
|
319
|
+
headers = map_headers(msg)
|
320
|
+
@skip_headers.each { |key| headers.delete(key) }
|
321
|
+
@headers_setter.call(event, headers)
|
286
322
|
end
|
287
323
|
|
288
324
|
if @include_properties
|
289
|
-
|
290
|
-
|
291
|
-
|
325
|
+
properties = to_string_keyed_hash(msg.properties)
|
326
|
+
@skip_properties.each { |key| properties.delete(key) }
|
327
|
+
@properties_setter.call(event, properties)
|
292
328
|
end
|
293
329
|
|
294
330
|
decorate(event)
|
@@ -300,6 +336,41 @@ class LogStash::Inputs::Jms < LogStash::Inputs::Threadable
|
|
300
336
|
end
|
301
337
|
end
|
302
338
|
|
339
|
+
def to_string_keyed_hash(hash)
|
340
|
+
hash.inject({}) { |h, (key, val)| h[key.to_s] = val; h }
|
341
|
+
end
|
342
|
+
private :to_string_keyed_hash
|
343
|
+
|
344
|
+
# @param msg [JMS::MapMessage]
|
345
|
+
# @return [LogStash::Event]
|
346
|
+
def process_map_message(msg)
|
347
|
+
data = to_string_keyed_hash(msg.data)
|
348
|
+
do_target_check_once_and_get_event_factory.new_event(data)
|
349
|
+
end
|
350
|
+
|
351
|
+
def do_target_check_once_and_get_event_factory
|
352
|
+
@target_checked ||= begin
|
353
|
+
do_target_check
|
354
|
+
targeted_event_factory
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
TARGET_NOT_SET_MESSAGE = LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck::TARGET_NOT_SET_MESSAGE
|
359
|
+
|
360
|
+
def do_target_check
|
361
|
+
return true unless target.nil?
|
362
|
+
return nil if ecs_compatibility == :disabled
|
363
|
+
logger.info(TARGET_NOT_SET_MESSAGE) # target isn't set in ECS mode
|
364
|
+
end
|
365
|
+
|
366
|
+
# @param msg [JMS::TextMessage, JMS::BytesMessage]
|
367
|
+
# @return [LogStash::Event, nil]
|
368
|
+
def decode_message(msg)
|
369
|
+
text = msg.to_s # javax.jms.TextMessage#getText (e.g. JSON payload)
|
370
|
+
event = nil
|
371
|
+
@codec.decode(text) { |e| event = e } unless text.nil?
|
372
|
+
event
|
373
|
+
end
|
303
374
|
|
304
375
|
def subscriber(session, params)
|
305
376
|
destination_key = @pub_sub ? :topic_name : :queue_name
|
@@ -347,4 +418,102 @@ class LogStash::Inputs::Jms < LogStash::Inputs::Threadable
|
|
347
418
|
end
|
348
419
|
{:exception => cause.class.name, :exception_message => cause.message }
|
349
420
|
end
|
421
|
+
|
422
|
+
private
|
423
|
+
|
424
|
+
def normalize_field_ref(target)
|
425
|
+
# so we can later event.set("#{target}[#{name}]", ...)
|
426
|
+
target.match?(/\A[^\[\]]+\z/) ? "[#{target}]" : target
|
427
|
+
end
|
428
|
+
|
429
|
+
def event_setter_for(target)
|
430
|
+
if target.nil? || target.empty?
|
431
|
+
TOP_LEVEL_EVENT_SETTER
|
432
|
+
else
|
433
|
+
TargetEventSetter.new normalize_field_ref(target)
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
TOP_LEVEL_EVENT_SETTER = lambda { |event, data| data.each { |key, val| event.set(key, val) } }
|
438
|
+
private_constant :TOP_LEVEL_EVENT_SETTER
|
439
|
+
|
440
|
+
class TargetEventSetter
|
441
|
+
|
442
|
+
def initialize(target)
|
443
|
+
@target = target
|
444
|
+
end
|
445
|
+
|
446
|
+
def call(event, data)
|
447
|
+
data.each { |key, val| event.set("#{@target}[#{key}]", val) }
|
448
|
+
end
|
449
|
+
|
450
|
+
end
|
451
|
+
private_constant :TargetEventSetter
|
452
|
+
|
453
|
+
def map_headers(msg)
|
454
|
+
@headers_mapper.call(msg)
|
455
|
+
end
|
456
|
+
|
457
|
+
# Maps JMS headers names
|
458
|
+
# (similar to JMS gem's Message#attributes extension)
|
459
|
+
class HeadersMapper
|
460
|
+
|
461
|
+
# @param msg [javax.jms.Message]
|
462
|
+
# @return [Hash]
|
463
|
+
def call(msg)
|
464
|
+
map = {
|
465
|
+
'jms_message_id' => msg.getJMSMessageID, # String
|
466
|
+
'jms_timestamp' => msg.getJMSTimestamp, # long
|
467
|
+
'jms_expiration' => msg.getJMSExpiration, # long
|
468
|
+
'jms_priority' => msg.getJMSPriority, # int (0-9)
|
469
|
+
'jms_type' => msg.getJMSType, # String
|
470
|
+
'jms_redelivered' => msg.getJMSRedelivered, # boolean
|
471
|
+
}
|
472
|
+
|
473
|
+
correlation_id = msg.getJMSCorrelationID # String
|
474
|
+
map['jms_correlation_id'] = correlation_id unless correlation_id.nil?
|
475
|
+
|
476
|
+
delivery_mode = jms_delivery_mode(msg)
|
477
|
+
map['jms_delivery_mode'] = delivery_mode unless delivery_mode.nil?
|
478
|
+
|
479
|
+
destination = msg.getJMSDestination # javax.jms.Destination
|
480
|
+
map['jms_destination'] = destination.to_string unless destination.nil?
|
481
|
+
|
482
|
+
reply_to = msg.getJMSReplyTo # javax.jms.Destination
|
483
|
+
map['jms_reply_to'] = reply_to.to_string unless reply_to.nil?
|
484
|
+
|
485
|
+
map
|
486
|
+
end
|
487
|
+
|
488
|
+
private
|
489
|
+
|
490
|
+
def jms_delivery_mode(msg)
|
491
|
+
case msg.getJMSDeliveryMode
|
492
|
+
when javax.jms.DeliveryMode::PERSISTENT
|
493
|
+
'persistent'
|
494
|
+
when javax.jms.DeliveryMode::NON_PERSISTENT
|
495
|
+
'non_persistent'
|
496
|
+
else
|
497
|
+
nil
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
INSTANCE = self.new
|
502
|
+
|
503
|
+
end
|
504
|
+
|
505
|
+
# For plugin compatibility due the use of JMS gem's Message#attributes.
|
506
|
+
class LegacyHeadersMapper < HeadersMapper
|
507
|
+
|
508
|
+
def call(msg)
|
509
|
+
map = super(msg)
|
510
|
+
delivery_mode = jms_delivery_mode(msg)
|
511
|
+
map['jms_delivery_mode_sym'] = delivery_mode ? delivery_mode.to_sym : nil
|
512
|
+
map
|
513
|
+
end
|
514
|
+
|
515
|
+
INSTANCE = self.new
|
516
|
+
|
517
|
+
end
|
518
|
+
|
350
519
|
end # class LogStash::Inputs::Jms
|
data/logstash-input-jms.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-input-jms'
|
4
|
-
s.version = '3.
|
4
|
+
s.version = '3.2.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Reads events from a Jms Broker"
|
7
7
|
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"
|
@@ -19,15 +19,18 @@ Gem::Specification.new do |s|
|
|
19
19
|
# Special flag to let us know this is actually a logstash plugin
|
20
20
|
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "input" }
|
21
21
|
|
22
|
+
s.platform = RUBY_PLATFORM
|
23
|
+
|
22
24
|
# Gem dependencies
|
23
25
|
s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
|
24
26
|
s.add_runtime_dependency 'logstash-codec-json', '~> 3.0'
|
25
27
|
s.add_runtime_dependency 'logstash-codec-plain', '~> 3.0'
|
28
|
+
s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~> 1.3'
|
29
|
+
s.add_runtime_dependency "logstash-mixin-event_support", '~> 1.0'
|
30
|
+
s.add_runtime_dependency 'logstash-mixin-validator_support', '~> 1.0'
|
31
|
+
|
32
|
+
s.add_runtime_dependency "jruby-jms", ">= 1.2.0" #(Apache 2.0 license)
|
26
33
|
s.add_runtime_dependency 'semantic_logger', '< 4.0.0'
|
27
34
|
|
28
|
-
if RUBY_PLATFORM == 'java'
|
29
|
-
s.platform = RUBY_PLATFORM
|
30
|
-
s.add_runtime_dependency "jruby-jms", ">= 1.2.0" #(Apache 2.0 license)
|
31
|
-
end
|
32
35
|
s.add_development_dependency 'logstash-devutils'
|
33
36
|
end
|
@@ -1,11 +1,8 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
2
|
require 'logstash/inputs/jms'
|
3
|
-
require '
|
4
|
-
require 'json'
|
3
|
+
require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
|
5
4
|
require 'securerandom'
|
6
5
|
|
7
|
-
|
8
|
-
|
9
6
|
shared_examples_for "a JMS input" do
|
10
7
|
context 'when inputting messages' do
|
11
8
|
let (:destination) { "#{pub_sub ? 'topic' : 'queue'}://#{queue_name}"}
|
@@ -15,7 +12,7 @@ shared_examples_for "a JMS input" do
|
|
15
12
|
let(:message) { "Hello There" }
|
16
13
|
|
17
14
|
context 'when properties are skipped' do
|
18
|
-
let (:
|
15
|
+
let (:config) { super().merge({'skip_properties' => ['this', 'that']})}
|
19
16
|
|
20
17
|
it 'should skip the specified property and process other properties, headers and the message' do
|
21
18
|
send_message do |session|
|
@@ -25,7 +22,7 @@ shared_examples_for "a JMS input" do
|
|
25
22
|
msg.set_string_property('the_other', 'the_other_prop')
|
26
23
|
msg
|
27
24
|
end
|
28
|
-
expect(queue.first.get('message')).to eql
|
25
|
+
expect(queue.first.get('message')).to eql(message)
|
29
26
|
expect(queue.first.get('jms_destination')).to_not be_nil
|
30
27
|
expect(queue.first.get('jms_timestamp')).to_not be_nil
|
31
28
|
expect(queue.first.get('this')).to be_nil
|
@@ -35,7 +32,7 @@ shared_examples_for "a JMS input" do
|
|
35
32
|
end
|
36
33
|
|
37
34
|
context 'when using message selectors' do
|
38
|
-
let (:
|
35
|
+
let (:config) { super().merge({'selector' => selector }) }
|
39
36
|
|
40
37
|
context 'with multiple selector query parameter' do
|
41
38
|
let (:selector) { "this = 3 OR this = 4" }
|
@@ -47,7 +44,7 @@ shared_examples_for "a JMS input" do
|
|
47
44
|
msg.set_int_property('this', 4)
|
48
45
|
msg
|
49
46
|
end
|
50
|
-
expect(queue.first.get('message')).to eql
|
47
|
+
expect(queue.first.get('message')).to eql(message)
|
51
48
|
expect(queue.first.get('this')).to eql(4)
|
52
49
|
expect(queue.first.get('that')).to eql('that_prop')
|
53
50
|
end
|
@@ -73,7 +70,7 @@ shared_examples_for "a JMS input" do
|
|
73
70
|
msg.set_int_property('this', 3)
|
74
71
|
msg
|
75
72
|
end
|
76
|
-
expect(queue.first.get('message')).to eql
|
73
|
+
expect(queue.first.get('message')).to eql(message)
|
77
74
|
expect(queue.first.get('this')).to eql(3)
|
78
75
|
expect(queue.first.get('that')).to eql('that_prop')
|
79
76
|
end
|
@@ -126,7 +123,7 @@ shared_examples_for "a JMS input" do
|
|
126
123
|
msg.set_string_property('that', 'that_prop')
|
127
124
|
msg
|
128
125
|
end
|
129
|
-
expect(queue.first.get('message')).to eql
|
126
|
+
expect(queue.first.get('message')).to eql(message)
|
130
127
|
expect(queue.first.get('this')).to eql('this_prop')
|
131
128
|
expect(queue.first.get('that')).to eql('that_prop')
|
132
129
|
end
|
@@ -145,7 +142,8 @@ shared_examples_for "a JMS input" do
|
|
145
142
|
end
|
146
143
|
|
147
144
|
context 'when headers are skipped' do
|
148
|
-
let (:
|
145
|
+
let (:config) { super().merge('skip_headers' => ['jms_destination', 'jms_reply_to']) }
|
146
|
+
|
149
147
|
it 'should skip the specified header and process other headers, properties and the message' do
|
150
148
|
send_message do |session|
|
151
149
|
msg = session.message(message)
|
@@ -155,7 +153,7 @@ shared_examples_for "a JMS input" do
|
|
155
153
|
msg.set_string_property('the_other', 'the_other_prop')
|
156
154
|
msg
|
157
155
|
end
|
158
|
-
expect(queue.first.get('message')).to eql
|
156
|
+
expect(queue.first.get('message')).to eql(message)
|
159
157
|
expect(queue.first.get('jms_destination')).to be_nil
|
160
158
|
expect(queue.first.get('jms_timestamp')).to_not be_nil
|
161
159
|
expect(queue.first.get('this')).to eq('this_prop')
|
@@ -164,33 +162,124 @@ shared_examples_for "a JMS input" do
|
|
164
162
|
end
|
165
163
|
end
|
166
164
|
|
167
|
-
context 'when
|
168
|
-
|
165
|
+
context 'when include_headers => false' do
|
166
|
+
let (:config) { super().merge('include_headers' => 'false') }
|
167
|
+
|
168
|
+
it 'should skip all headers' do
|
169
169
|
send_message do |session|
|
170
170
|
msg = session.message(message)
|
171
|
-
msg.
|
172
|
-
msg.set_string_property('
|
173
|
-
msg.set_string_property('the_other', 'the_other_prop')
|
171
|
+
msg.reply_to = session.create_destination(:topic_name => SecureRandom.hex(8))
|
172
|
+
msg.set_string_property('some', 'property')
|
174
173
|
msg
|
175
174
|
end
|
176
|
-
|
177
|
-
expect(
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
175
|
+
event = queue.first.to_hash_with_metadata
|
176
|
+
expect( event.keys.find { |name| name.start_with?('jms_') } ).to be nil
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'when include_header => false (deprecated)' do
|
181
|
+
let (:config) { super().merge('include_header' => 'false') }
|
182
|
+
|
183
|
+
it 'should skip all headers' do
|
184
|
+
send_message do |session|
|
185
|
+
msg = session.message(message)
|
186
|
+
msg.reply_to = session.create_destination(:topic_name => SecureRandom.hex(8))
|
187
|
+
msg.set_string_property('some', 'property')
|
188
|
+
msg
|
189
|
+
end
|
190
|
+
event = queue.first.to_hash_with_metadata
|
191
|
+
expect( event.keys.find { |name| name.start_with?('jms_') } ).to be nil
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'when neither header nor property is skipped', :ecs_compatibility_support do
|
196
|
+
ecs_compatibility_matrix(:disabled, :v1, :v8) do |ecs_select|
|
197
|
+
|
198
|
+
let(:ecs_compatibility?) { ecs_select.active_mode != :disabled }
|
199
|
+
|
200
|
+
let (:config) { super().merge('ecs_compatibility' => ecs_select.active_mode) }
|
201
|
+
|
202
|
+
it 'should process properties, headers and the message' do
|
203
|
+
send_message do |session|
|
204
|
+
msg = session.message(message)
|
205
|
+
msg.set_string_property('this', 'this_prop')
|
206
|
+
msg.set_int_property('camelCase', 42)
|
207
|
+
msg.set_boolean_property('JMSFlag', true)
|
208
|
+
msg
|
209
|
+
end
|
210
|
+
|
211
|
+
event = queue.first
|
212
|
+
|
213
|
+
expect(event.get('message')).to eql(message)
|
214
|
+
|
215
|
+
# headers
|
216
|
+
if ecs_compatibility?
|
217
|
+
expect(event.include?('jms_timestamp')).to be false
|
218
|
+
expect(event.include?('jms_destination')).to be false
|
219
|
+
expect(event.get('[@metadata][input][jms][headers][jms_timestamp]')).to be_a Integer
|
220
|
+
expect(event.get('[@metadata][input][jms][headers][jms_destination]')).to_not be nil
|
221
|
+
expect(event.include?("[@metadata][input][jms][headers][jms_delivery_mode_sym]")).to be false
|
222
|
+
expect(event.include?("[@metadata][input][jms][headers][jms_delivery_mode]")).to be true
|
223
|
+
else
|
224
|
+
expect(event.get('jms_timestamp')).to be_a Integer
|
225
|
+
expect(event.get('jms_destination')).to_not be nil
|
226
|
+
expect(event.include?("jms_delivery_mode_sym")).to be true
|
227
|
+
end
|
228
|
+
|
229
|
+
# properties
|
230
|
+
if ecs_compatibility?
|
231
|
+
expect(event.include?('this')).to be false
|
232
|
+
expect(event.get('[@metadata][input][jms][properties][this]')).to eq 'this_prop'
|
233
|
+
expect(event.get('[@metadata][input][jms][properties][camelCase]')).to eq 42
|
234
|
+
expect(event.get('[@metadata][input][jms][properties][JMSFlag]')).to be true
|
235
|
+
else
|
236
|
+
expect(event.get('this')).to eq 'this_prop'
|
237
|
+
expect(event.get('camelCase')).to eq 42
|
238
|
+
expect(event.get('JMSFlag')).to be true
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
182
242
|
end
|
183
243
|
end
|
184
244
|
end
|
185
245
|
|
186
|
-
context 'when the message is map message' do
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
246
|
+
context 'when the message is map message', :ecs_compatibility_support do
|
247
|
+
|
248
|
+
ecs_compatibility_matrix(:disabled, :v1, :v8) do |ecs_select|
|
249
|
+
|
250
|
+
let(:ecs_compatibility?) { ecs_select.active_mode != :disabled }
|
251
|
+
|
252
|
+
let (:config) { super().merge('ecs_compatibility' => ecs_select.active_mode) }
|
253
|
+
|
254
|
+
let(:message) { {:one => 1} }
|
255
|
+
|
256
|
+
before do
|
257
|
+
if ecs_compatibility?
|
258
|
+
expect(subject.logger).to receive(:info).once.with /ECS compatibility is enabled but `target` option was not specified/i
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'should read the message' do
|
263
|
+
send_message
|
264
|
+
|
265
|
+
expect(queue.size).to eql 1
|
266
|
+
event = queue.first
|
267
|
+
expect(event.get('one')).to eql 1
|
268
|
+
|
269
|
+
if ecs_compatibility?
|
270
|
+
expect(event.get('[@metadata][input][jms][headers][jms_destination]')).to eql(destination)
|
271
|
+
expect(event.get('[@metadata][input][jms][headers][jms_delivery_mode]')).to eql 'persistent'
|
272
|
+
expect(event.include?('[@metadata][input][jms][headers][jms_delivery_mode_sym]')).to be false
|
273
|
+
else
|
274
|
+
expect(event.get("jms_destination")).to eql(destination)
|
275
|
+
expect(event.get("jms_delivery_mode_sym")).to eql :persistent
|
276
|
+
end
|
277
|
+
|
278
|
+
send_message # should not log the ECS warning again
|
279
|
+
end
|
280
|
+
|
193
281
|
end
|
282
|
+
|
194
283
|
end
|
195
284
|
|
196
285
|
context 'when the message is a bytes message' do
|
@@ -203,17 +292,26 @@ shared_examples_for "a JMS input" do
|
|
203
292
|
jms_message
|
204
293
|
end
|
205
294
|
expect(queue.size).to eql 1
|
206
|
-
expect(queue.first.get('message')).to eql
|
295
|
+
expect(queue.first.get('message')).to eql 'hello world'
|
207
296
|
expect(queue.first.get("jms_destination")).to eql(destination)
|
208
297
|
end
|
209
298
|
end
|
210
299
|
end
|
211
300
|
end
|
212
301
|
|
213
|
-
describe
|
302
|
+
describe LogStash::Inputs::Jms, :integration => true do
|
214
303
|
let (:message) { "hello World" }
|
215
304
|
let (:queue_name) { SecureRandom.hex(8)}
|
216
305
|
|
306
|
+
let (:yaml_section) { 'activemq' }
|
307
|
+
let (:config) {{'yaml_file' => fixture_path("jms.yml"),
|
308
|
+
'yaml_section' => yaml_section,
|
309
|
+
'destination' => queue_name,
|
310
|
+
'pub_sub' => pub_sub,
|
311
|
+
'interval' => 2}}
|
312
|
+
|
313
|
+
subject(:input) { described_class.new(config) }
|
314
|
+
|
217
315
|
before :each do
|
218
316
|
allow(input).to receive(:jms_config_from_yaml) do |yaml_file, section|
|
219
317
|
settings = YAML.load_file(yaml_file)[section]
|
@@ -222,14 +320,6 @@ describe "input/jms", :integration => true do
|
|
222
320
|
end
|
223
321
|
end
|
224
322
|
|
225
|
-
let (:yaml_section) { 'activemq' }
|
226
|
-
let (:jms_config) {{'yaml_file' => fixture_path("jms.yml"),
|
227
|
-
'yaml_section' => yaml_section,
|
228
|
-
'destination' => queue_name,
|
229
|
-
'pub_sub' => pub_sub,
|
230
|
-
'interval' => 2}}
|
231
|
-
let(:input) { LogStash::Plugin.lookup("input", "jms").new(jms_config) }
|
232
|
-
|
233
323
|
after :each do
|
234
324
|
input.close unless input.nil?
|
235
325
|
end
|
@@ -241,7 +331,7 @@ describe "input/jms", :integration => true do
|
|
241
331
|
end
|
242
332
|
|
243
333
|
context 'with pub_sub true and durable subscriber' do
|
244
|
-
let (:
|
334
|
+
let (:config) { super().merge({'durable_subscriber' => true,
|
245
335
|
'durable_subscriber_client_id' => SecureRandom.hex(8),
|
246
336
|
'durable_subscriber_name' => SecureRandom.hex(8) } ) }
|
247
337
|
|
@@ -258,8 +348,8 @@ describe "input/jms", :integration => true do
|
|
258
348
|
|
259
349
|
context 'with tls', :tls => true do
|
260
350
|
let (:yaml_section) { 'activemq_tls' }
|
261
|
-
let (:
|
262
|
-
|
351
|
+
let (:config) { super().merge({"keystore" => fixture_path("keystore.jks"), "keystore_password" => "changeit",
|
352
|
+
"truststore" => fixture_path("keystore.jks"), "truststore_password" => "changeit"})}
|
263
353
|
|
264
354
|
context 'with pub_sub true' do
|
265
355
|
let (:pub_sub) { true }
|
@@ -267,7 +357,7 @@ describe "input/jms", :integration => true do
|
|
267
357
|
end
|
268
358
|
|
269
359
|
context 'with pub_sub true and durable subscriber' do
|
270
|
-
let (:
|
360
|
+
let (:config) { super().merge({'durable_subscriber' => true,
|
271
361
|
'durable_subscriber_client_id' => SecureRandom.hex(8),
|
272
362
|
'durable_subscriber_name' => SecureRandom.hex(8) } ) }
|
273
363
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
2
|
require 'logstash/inputs/jms'
|
3
|
-
require '
|
4
|
-
require '
|
3
|
+
require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
|
4
|
+
require 'securerandom'
|
5
5
|
|
6
|
-
describe
|
6
|
+
describe LogStash::Inputs::Jms do
|
7
7
|
let (:queue_name) {SecureRandom.hex(8)}
|
8
8
|
let (:jms_config) {{'destination' => queue_name}}
|
9
9
|
|
@@ -37,10 +37,10 @@ describe "inputs/jms" do
|
|
37
37
|
context 'configuration check' do
|
38
38
|
context 'if threads is > 1' do
|
39
39
|
let(:thread_count) { 2 }
|
40
|
-
let(:jms_config) { super.merge({'threads' => thread_count})}
|
40
|
+
let(:jms_config) { super().merge({'threads' => thread_count})}
|
41
41
|
|
42
42
|
context 'with pub_sub set to true' do
|
43
|
-
let(:jms_config) { super.merge({'pub_sub' => true})}
|
43
|
+
let(:jms_config) { super().merge({'pub_sub' => true})}
|
44
44
|
|
45
45
|
it 'should raise a configuration error' do
|
46
46
|
expect { plugin.register }.to raise_error(LogStash::ConfigurationError)
|
@@ -48,7 +48,7 @@ describe "inputs/jms" do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
context 'with pub_sub set to false' do
|
51
|
-
let(:jms_config) { super.merge({'pub_sub' => false})}
|
51
|
+
let(:jms_config) { super().merge({'pub_sub' => false})}
|
52
52
|
|
53
53
|
it 'should not raise a configuration error' do
|
54
54
|
plugin.register
|
@@ -58,13 +58,13 @@ describe "inputs/jms" do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
context 'with durable_subscriber set' do
|
61
|
-
let(:jms_config) { super.merge({ 'pub_sub' => true,
|
61
|
+
let(:jms_config) { super().merge({ 'pub_sub' => true,
|
62
62
|
'durable_subscriber' => true,
|
63
63
|
'durable_subscriber_name' => SecureRandom.hex(8),
|
64
64
|
'durable_subscriber_client_id' => SecureRandom.hex(8)})}
|
65
65
|
|
66
66
|
context 'if durable_subscriber_client_id is not set' do
|
67
|
-
let(:jms_config) { super.tap { |h| h.delete('durable_subscriber_client_id') } }
|
67
|
+
let(:jms_config) { super().tap { |h| h.delete('durable_subscriber_client_id') } }
|
68
68
|
|
69
69
|
it 'should set client_id to Logstash' do
|
70
70
|
plugin.register
|
@@ -73,7 +73,7 @@ describe "inputs/jms" do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
context 'if durable_subscriber_name is not set' do
|
76
|
-
let(:jms_config) { super.tap { |h| h.delete('durable_subscriber_name') } }
|
76
|
+
let(:jms_config) { super().tap { |h| h.delete('durable_subscriber_name') } }
|
77
77
|
|
78
78
|
it 'should set name to the topic name' do
|
79
79
|
plugin.register
|
@@ -83,7 +83,7 @@ describe "inputs/jms" do
|
|
83
83
|
|
84
84
|
|
85
85
|
context 'if pub_sub is set to false' do
|
86
|
-
let(:jms_config) { super.merge({'pub_sub' => false})}
|
86
|
+
let(:jms_config) { super().merge({'pub_sub' => false})}
|
87
87
|
it 'should raise a configuration error' do
|
88
88
|
expect { plugin.register }.to raise_error(LogStash::ConfigurationError)
|
89
89
|
end
|
@@ -253,4 +253,60 @@ describe "inputs/jms" do
|
|
253
253
|
end
|
254
254
|
end
|
255
255
|
end
|
256
|
+
|
257
|
+
context 'invalid configuration' do
|
258
|
+
let (:jms_config) { super().merge('include_headers' => true, 'include_header' => false) }
|
259
|
+
|
260
|
+
it 'should raise a configuration error' do
|
261
|
+
expect { subject.register }.to raise_error LogStash::ConfigurationError,
|
262
|
+
/Both `include_headers => true` and `include_header => false` options are specified/i
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
context 'targets', :ecs_compatibility_support do
|
267
|
+
|
268
|
+
ecs_compatibility_matrix(:disabled, :v1, :v8) do |ecs_select|
|
269
|
+
|
270
|
+
let (:jms_config) do
|
271
|
+
super().merge(
|
272
|
+
'include_body' => false,
|
273
|
+
'include_headers' => true, 'headers_target' => '@metadata',
|
274
|
+
'include_properties' => true, 'properties_target' => '[@metadata]'
|
275
|
+
)
|
276
|
+
end
|
277
|
+
|
278
|
+
let(:jms_timestamp) { 1 }
|
279
|
+
|
280
|
+
let(:jms_message_double) do
|
281
|
+
message = double('jms-message-stub')
|
282
|
+
allow(message).to receive(:jms_timestamp).and_return(jms_timestamp)
|
283
|
+
allow_any_instance_of(described_class).to receive(:map_headers).and_return(
|
284
|
+
'jms_message_id' => 'id1', 'jms_timestamp' => jms_timestamp, 'jms_expiration' => nil
|
285
|
+
)
|
286
|
+
allow(message).to receive(:properties).and_return(:foo => 'bar', 'the-baz' => 42)
|
287
|
+
message
|
288
|
+
end
|
289
|
+
|
290
|
+
before(:each) do
|
291
|
+
allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
|
292
|
+
|
293
|
+
plugin.register
|
294
|
+
plugin.queue_event(jms_message_double, queue = [])
|
295
|
+
expect(queue.size).to eql 1
|
296
|
+
@event = queue.first
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'sets headers into meta-data' do
|
300
|
+
expect( @event.get('[@metadata][jms_timestamp]') ).to eql jms_timestamp
|
301
|
+
expect( @event.get('[@metadata][jms_message_id]') ).to_not be nil
|
302
|
+
end
|
303
|
+
|
304
|
+
it 'sets properties as meta-data' do
|
305
|
+
expect( @event.get('[@metadata][foo]') ).to eql 'bar'
|
306
|
+
expect( @event.get('[@metadata][the-baz]') ).to eql 42
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
|
311
|
+
end
|
256
312
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-jms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elasticsearch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -61,17 +61,45 @@ dependencies:
|
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
|
-
- - "
|
64
|
+
- - "~>"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version:
|
67
|
-
name:
|
66
|
+
version: '1.3'
|
67
|
+
name: logstash-mixin-ecs_compatibility_support
|
68
68
|
prerelease: false
|
69
69
|
type: :runtime
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- - "
|
72
|
+
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
74
|
+
version: '1.3'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '1.0'
|
81
|
+
name: logstash-mixin-event_support
|
82
|
+
prerelease: false
|
83
|
+
type: :runtime
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '1.0'
|
95
|
+
name: logstash-mixin-validator_support
|
96
|
+
prerelease: false
|
97
|
+
type: :runtime
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '1.0'
|
75
103
|
- !ruby/object:Gem::Dependency
|
76
104
|
requirement: !ruby/object:Gem::Requirement
|
77
105
|
requirements:
|
@@ -86,6 +114,20 @@ dependencies:
|
|
86
114
|
- - ">="
|
87
115
|
- !ruby/object:Gem::Version
|
88
116
|
version: 1.2.0
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
requirement: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - "<"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 4.0.0
|
123
|
+
name: semantic_logger
|
124
|
+
prerelease: false
|
125
|
+
type: :runtime
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "<"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: 4.0.0
|
89
131
|
- !ruby/object:Gem::Dependency
|
90
132
|
requirement: !ruby/object:Gem::Requirement
|
91
133
|
requirements:
|
@@ -144,8 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
186
|
- !ruby/object:Gem::Version
|
145
187
|
version: '0'
|
146
188
|
requirements: []
|
147
|
-
|
148
|
-
rubygems_version: 2.6.13
|
189
|
+
rubygems_version: 3.1.6
|
149
190
|
signing_key:
|
150
191
|
specification_version: 4
|
151
192
|
summary: Reads events from a Jms Broker
|