logstash-integration-rabbitmq 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2 -0
  3. data/CONTRIBUTORS +26 -0
  4. data/Gemfile +11 -0
  5. data/LICENSE +13 -0
  6. data/NOTICE.TXT +5 -0
  7. data/README.md +98 -0
  8. data/docs/index-input.asciidoc +395 -0
  9. data/docs/index-output.asciidoc +266 -0
  10. data/lib/logstash/inputs/rabbitmq.rb +317 -0
  11. data/lib/logstash/outputs/rabbitmq.rb +100 -0
  12. data/lib/logstash/plugin_mixins/rabbitmq_connection.rb +235 -0
  13. data/lib/logstash_registry.rb +7 -0
  14. data/logstash-integration-rabbitmq.gemspec +37 -0
  15. data/spec/fixtures/README.md +150 -0
  16. data/spec/fixtures/client/cert.pem +69 -0
  17. data/spec/fixtures/client/key.pem +27 -0
  18. data/spec/fixtures/client/keycert.p12 +0 -0
  19. data/spec/fixtures/client/req.pem +15 -0
  20. data/spec/fixtures/client_untrusted/cert.pem +19 -0
  21. data/spec/fixtures/client_untrusted/key.pem +28 -0
  22. data/spec/fixtures/client_untrusted/keycert.p12 +0 -0
  23. data/spec/fixtures/server/cert.pem +69 -0
  24. data/spec/fixtures/server/key.pem +27 -0
  25. data/spec/fixtures/server/key_password +1 -0
  26. data/spec/fixtures/server/keycert.p12 +0 -0
  27. data/spec/fixtures/server/rabbitmq.config +10 -0
  28. data/spec/fixtures/server/req.pem +15 -0
  29. data/spec/fixtures/testca/cacert.cer +0 -0
  30. data/spec/fixtures/testca/cacert.pem +17 -0
  31. data/spec/fixtures/testca/certs/01.pem +18 -0
  32. data/spec/fixtures/testca/certs/02.pem +18 -0
  33. data/spec/fixtures/testca/certs/05.pem +69 -0
  34. data/spec/fixtures/testca/certs/06.pem +69 -0
  35. data/spec/fixtures/testca/index.txt +4 -0
  36. data/spec/fixtures/testca/index.txt.attr +1 -0
  37. data/spec/fixtures/testca/index.txt.attr.old +1 -0
  38. data/spec/fixtures/testca/index.txt.old +3 -0
  39. data/spec/fixtures/testca/openssl.cnf +53 -0
  40. data/spec/fixtures/testca/private/cakey.pem +27 -0
  41. data/spec/fixtures/testca/serial +1 -0
  42. data/spec/fixtures/testca/serial.old +1 -0
  43. data/spec/inputs/rabbitmq_spec.rb +278 -0
  44. data/spec/outputs/rabbitmq_spec.rb +228 -0
  45. data/spec/plugin_mixins/rabbitmq_connection_spec.rb +175 -0
  46. metadata +241 -0
@@ -0,0 +1,100 @@
1
+ # encoding: UTF-8
2
+ require "logstash/pipeline"
3
+ require "logstash/plugin_mixins/rabbitmq_connection"
4
+ java_import java.util.concurrent.TimeoutException
5
+ java_import com.rabbitmq.client.AlreadyClosedException
6
+
7
+ # Push events to a RabbitMQ exchange. Requires RabbitMQ 2.x
8
+ # or later version (3.x is recommended).
9
+ #
10
+ # Relevant links:
11
+ #
12
+ # * http://www.rabbitmq.com/[RabbitMQ]
13
+ # * http://rubymarchhare.info[March Hare]
14
+ module LogStash
15
+ module Outputs
16
+ class RabbitMQ < LogStash::Outputs::Base
17
+ include LogStash::PluginMixins::RabbitMQConnection
18
+
19
+ config_name "rabbitmq"
20
+
21
+ concurrency :shared
22
+
23
+ # The default codec for this plugin is JSON. You can override this to suit your particular needs however.
24
+ default :codec, "json"
25
+
26
+ # Key to route to by default. Defaults to 'logstash'
27
+ #
28
+ # * Routing keys are ignored on fanout exchanges.
29
+ config :key, :validate => :string, :default => "logstash"
30
+
31
+ # The name of the exchange
32
+ config :exchange, :validate => :string, :required => true
33
+
34
+ # The exchange type (fanout, topic, direct)
35
+ config :exchange_type, :validate => EXCHANGE_TYPES, :required => true
36
+
37
+ # Is this exchange durable? (aka; Should it survive a broker restart?)
38
+ config :durable, :validate => :boolean, :default => true
39
+
40
+ # Should RabbitMQ persist messages to disk?
41
+ config :persistent, :validate => :boolean, :default => true
42
+
43
+ # Properties to be passed along with the message
44
+ config :message_properties, :validate => :hash, :default => {}
45
+
46
+ def register
47
+ connect!
48
+ @hare_info.exchange = declare_exchange!(@hare_info.channel, @exchange, @exchange_type, @durable)
49
+ # The connection close should close all channels, so it is safe to store thread locals here without closing them
50
+ @thread_local_channel = java.lang.ThreadLocal.new
51
+ @thread_local_exchange = java.lang.ThreadLocal.new
52
+ end
53
+
54
+ def symbolize(myhash)
55
+ Hash[myhash.map{|(k,v)| [k.to_sym,v]}]
56
+ end
57
+
58
+ def multi_receive_encoded(events_and_data)
59
+ events_and_data.each do |event, data|
60
+ publish(event, data)
61
+ end
62
+ end
63
+
64
+ def publish(event, message)
65
+ raise ArgumentError, "No exchange set in HareInfo!!!" unless @hare_info.exchange
66
+ local_exchange.publish(message, :routing_key => event.sprintf(@key), :properties => symbolize(@message_properties.merge(:persistent => @persistent)))
67
+ rescue MarchHare::Exception, IOError, AlreadyClosedException, TimeoutException => e
68
+ @logger.error("Error while publishing. Will retry.",
69
+ :message => e.message,
70
+ :exception => e.class,
71
+ :backtrace => e.backtrace)
72
+
73
+ sleep_for_retry
74
+ retry
75
+ end
76
+
77
+ def local_exchange
78
+ exchange = @thread_local_exchange.get
79
+ if !exchange
80
+ exchange = declare_exchange!(local_channel, @exchange, @exchange_type, @durable)
81
+ @thread_local_exchange.set(exchange)
82
+ end
83
+ exchange
84
+ end
85
+
86
+ def local_channel
87
+ channel = @thread_local_channel.get
88
+ if !channel
89
+ channel = @hare_info.connection.create_channel
90
+ @thread_local_channel.set(channel)
91
+ end
92
+ channel
93
+ end
94
+
95
+ def close
96
+ close_connection
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,235 @@
1
+ # encoding: utf-8
2
+ require "logstash/outputs/base"
3
+ require "logstash/namespace"
4
+ require "march_hare"
5
+ require "java"
6
+
7
+ # Common functionality for the rabbitmq input/output
8
+ module LogStash
9
+ module PluginMixins
10
+ module RabbitMQConnection
11
+ EXCHANGE_TYPES = ["fanout", "direct", "topic", "x-consistent-hash", "x-modulus-hash"]
12
+
13
+ HareInfo = Struct.new(:connection, :channel, :exchange, :queue)
14
+
15
+ def self.included(base)
16
+ base.extend(self)
17
+ base.setup_rabbitmq_connection_config
18
+ end
19
+
20
+ def setup_rabbitmq_connection_config
21
+ # RabbitMQ server address(es)
22
+ # host can either be a single host, or a list of hosts
23
+ # i.e.
24
+ # host => "localhost"
25
+ # or
26
+ # host => ["host01", "host02]
27
+ #
28
+ # if multiple hosts are provided on the initial connection and any subsequent
29
+ # recovery attempts of the hosts is chosen at random and connected to.
30
+ # Note that only one host connection is active at a time.
31
+ config :host, :validate => :string, :required => true , :list => true
32
+
33
+ # RabbitMQ port to connect on
34
+ config :port, :validate => :number, :default => 5672
35
+
36
+ # RabbitMQ username
37
+ config :user, :validate => :string, :default => "guest"
38
+
39
+ # RabbitMQ password
40
+ config :password, :validate => :password, :default => "guest"
41
+
42
+ # The vhost (virtual host) to use. If you don't know what this
43
+ # is, leave the default. With the exception of the default
44
+ # vhost ("/"), names of vhosts should not begin with a forward
45
+ # slash.
46
+ config :vhost, :validate => :string, :default => "/"
47
+
48
+ # Enable or disable SSL.
49
+ # Note that by default remote certificate verification is off.
50
+ # Specify ssl_certificate_path and ssl_certificate_password if you need
51
+ # certificate verification
52
+ config :ssl, :validate => :boolean
53
+
54
+ # Version of the SSL protocol to use.
55
+ config :ssl_version, :validate => :string, :default => "TLSv1.2"
56
+
57
+ config :verify_ssl, :validate => :boolean, :default => false,
58
+ :obsolete => "This function did not actually function correctly and was removed." +
59
+ "If you wish to validate SSL certs use the ssl_certificate_path and ssl_certificate_password options."
60
+
61
+ # Path to an SSL certificate in PKCS12 (.p12) format used for verifying the remote host
62
+ config :ssl_certificate_path, :validate => :path
63
+
64
+ # Password for the encrypted PKCS12 (.p12) certificate file specified in ssl_certificate_path
65
+ config :ssl_certificate_password, :validate => :password
66
+
67
+ config :debug, :validate => :boolean, :obsolete => "Use the logstash --debug flag for this instead."
68
+
69
+ # Set this to automatically recover from a broken connection. You almost certainly don't want to override this!!!
70
+ config :automatic_recovery, :validate => :boolean, :default => true
71
+
72
+ # Time in seconds to wait before retrying a connection
73
+ config :connect_retry_interval, :validate => :number, :default => 1
74
+
75
+ # The default connection timeout in milliseconds. If not specified the timeout is infinite.
76
+ config :connection_timeout, :validate => :number
77
+
78
+ # Heartbeat delay in seconds. If unspecified no heartbeats will be sent
79
+ config :heartbeat, :validate => :number
80
+
81
+ # Passive queue creation? Useful for checking queue existance without modifying server state
82
+ config :passive, :validate => :boolean, :default => false
83
+
84
+ # TLS certifcate path
85
+ config :tls_certificate_path, :validate => :path, :obsolete => "This setting is obsolete. Use ssl_certificate_path instead"
86
+
87
+ # TLS certificate password
88
+ config :tls_certificate_password, :validate => :string, :obsolete => "This setting is obsolete. Use ssl_certificate_password instead"
89
+
90
+ # Extra queue arguments as an array.
91
+ # To make a RabbitMQ queue mirrored, use: `{"x-ha-policy" => "all"}`
92
+ config :arguments, :validate => :array, :default => {}
93
+ end
94
+
95
+ def conn_str
96
+ "amqp://#{@user}@#{@host}:#{@port}#{@vhost}"
97
+ end
98
+
99
+ def close_connection
100
+ @rabbitmq_connection_stopping = true
101
+ @hare_info.channel.close if channel_open?
102
+ @hare_info.connection.close if connection_open?
103
+ end
104
+
105
+ def rabbitmq_settings
106
+ return @rabbitmq_settings if @rabbitmq_settings
107
+
108
+ s = {
109
+ :vhost => @vhost,
110
+ :hosts => @host,
111
+ :port => @port,
112
+ :user => @user,
113
+ :automatic_recovery => @automatic_recovery,
114
+ :pass => @password ? @password.value : "guest",
115
+ }
116
+
117
+ s[:timeout] = @connection_timeout || 0
118
+ s[:heartbeat] = @heartbeat || 0
119
+
120
+ if @ssl
121
+ s[:tls] = @ssl_version
122
+
123
+ cert_path = @ssl_certificate_path
124
+ cert_pass = @ssl_certificate_password.value if @ssl_certificate_password
125
+
126
+ if !!cert_path ^ !!cert_pass
127
+ raise LogStash::ConfigurationError, "RabbitMQ requires both ssl_certificate_path AND ssl_certificate_password to be set!"
128
+ end
129
+
130
+ s[:tls_certificate_path] = cert_path
131
+ s[:tls_certificate_password] = cert_pass
132
+ end
133
+
134
+ @rabbitmq_settings = s
135
+ end
136
+
137
+ def connect!
138
+ @hare_info = connect() unless @hare_info # Don't duplicate the conn!
139
+ rescue MarchHare::Exception, java.io.IOException => e
140
+ error_message = if e.message.empty? && e.is_a?(java.io.IOException)
141
+ # IOException with an empty message is probably an instance of
142
+ # these problems:
143
+ # https://github.com/logstash-plugins/logstash-output-rabbitmq/issues/52
144
+ # https://github.com/rabbitmq/rabbitmq-java-client/issues/100
145
+ #
146
+ # Best guess is to help the user understand that there is probably
147
+ # some kind of configuration problem causing the error, but we
148
+ # can't really offer any more detailed hints :\
149
+ "An unknown error occurred. RabbitMQ gave no hints as to the cause. Maybe this is a configuration error (invalid vhost, for example). I recommend checking the RabbitMQ server logs for clues about this failure."
150
+ else
151
+ e.message
152
+ end
153
+
154
+ if @logger.debug?
155
+ @logger.error("RabbitMQ connection error, will retry.",
156
+ :error_message => error_message,
157
+ :exception => e.class.name,
158
+ :backtrace => e.backtrace)
159
+ else
160
+ @logger.error("RabbitMQ connection error, will retry.",
161
+ :error_message => error_message,
162
+ :exception => e.class.name)
163
+ end
164
+
165
+ sleep_for_retry
166
+ retry
167
+ end
168
+
169
+ def channel_open?
170
+ @hare_info && @hare_info.channel && @hare_info.channel.open?
171
+ end
172
+
173
+ def connection_open?
174
+ @hare_info && @hare_info.connection && @hare_info.connection.open?
175
+ end
176
+
177
+ def connected?
178
+ return nil unless @hare_info && @hare_info.connection
179
+ @hare_info.connection.connected?
180
+ end
181
+
182
+ private
183
+
184
+ def declare_exchange!(channel, exchange, exchange_type, durable)
185
+ @logger.debug? && @logger.debug("Declaring an exchange", :name => exchange,
186
+ :type => exchange_type, :durable => durable)
187
+ exchange = channel.exchange(exchange, :type => exchange_type.to_sym, :durable => durable)
188
+ @logger.debug? && @logger.debug("Exchange declared")
189
+ exchange
190
+ rescue StandardError => e
191
+ @logger.error("Could not declare exchange!",
192
+ :exchange => exchange, :type => exchange_type,
193
+ :durable => durable, :error_class => e.class.name,
194
+ :error_message => e.message, :backtrace => e.backtrace)
195
+ raise e
196
+ end
197
+
198
+ def connect
199
+ @logger.debug? && @logger.debug("Connecting to RabbitMQ. Settings: #{rabbitmq_settings.inspect}")
200
+
201
+ connection = MarchHare.connect(rabbitmq_settings)
202
+
203
+ connection.on_shutdown do |conn, cause|
204
+ @logger.warn("RabbitMQ connection was closed!",
205
+ :url => connection_url(conn),
206
+ :automatic_recovery => @automatic_recovery,
207
+ :cause => cause)
208
+ end
209
+ connection.on_blocked do
210
+ @logger.warn("RabbitMQ connection blocked! Check your RabbitMQ instance!",
211
+ :url => connection_url(connection))
212
+ end
213
+ connection.on_unblocked do
214
+ @logger.warn("RabbitMQ connection unblocked!", :url => connection_url(connection))
215
+ end
216
+
217
+ channel = connection.create_channel
218
+ @logger.info("Connected to RabbitMQ at #{rabbitmq_settings[:host]}")
219
+
220
+ HareInfo.new(connection, channel)
221
+ end
222
+
223
+ # Mostly used for printing debug logs
224
+ def connection_url(connection)
225
+ user_pass = connection.user ? "#{connection.user}:XXXXXX@" : ""
226
+ protocol = params["ssl"] ? "amqps" : "amqp"
227
+ "#{protocol}://#{user_pass}#{connection.host}:#{connection.port}#{connection.vhost}"
228
+ end
229
+
230
+ def sleep_for_retry
231
+ Stud.stoppable_sleep(@connect_retry_interval) { @rabbitmq_connection_stopping }
232
+ end
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+ require "logstash/plugins/registry"
3
+ require "logstash/inputs/rabbitmq"
4
+ require "logstash/outputs/rabbitmq"
5
+
6
+ LogStash::PLUGIN_REGISTRY.add(:input, "rabbitmq", LogStash::Inputs::RabbitMQ)
7
+ LogStash::PLUGIN_REGISTRY.add(:output, "rabbitmq", LogStash::Outputs::RabbitMQ)
@@ -0,0 +1,37 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'logstash-integration-rabbitmq'
3
+ s.version = '0.0.1'
4
+ s.licenses = ['Apache License (2.0)']
5
+ s.summary = "Integration with RabbitMQ - input and output plugins"
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
+ s.authors = ["Elastic"]
8
+ s.email = 'info@elastic.co'
9
+ s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
10
+ s.require_paths = ["lib"]
11
+
12
+ # Files
13
+ s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "docs/**/*"]
14
+
15
+ # Tests
16
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
+
18
+ # Special flag to let us know this is actually a logstash plugin
19
+ s.metadata = {
20
+ "logstash_plugin" => "true",
21
+ "logstash_group" => "integration",
22
+ "integration_plugins" => "logstash-input-rabbitmq,logstash-output-rabbitmq"
23
+ }
24
+
25
+ # Gem dependencies
26
+ s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
27
+ s.add_runtime_dependency "logstash-core"
28
+
29
+ s.add_runtime_dependency 'logstash-codec-json'
30
+
31
+ s.add_runtime_dependency 'march_hare', ['~> 3.0'] #(MIT license)
32
+ s.add_runtime_dependency 'stud', '~> 0.0.22'
33
+
34
+ s.add_development_dependency 'logstash-devutils'
35
+ s.add_development_dependency 'logstash-input-generator'
36
+ s.add_development_dependency 'logstash-codec-plain'
37
+ end
@@ -0,0 +1,150 @@
1
+ # TLS Testing notes
2
+
3
+ Currently all TLS integration style testing is manual. This fixture may be used to help test.
4
+
5
+ * client - has the key store with client public/private key and the server public key
6
+ * server - has the key store with server public/private key and the client public key
7
+ * client_untrusted - has a keystore with public/private key that is self signed
8
+
9
+ logstash config
10
+ ---------
11
+ ```
12
+ input {
13
+ rabbitmq {
14
+ host => "localhost"
15
+ port => 5671
16
+ queue => "hello"
17
+ codec => plain
18
+ ssl => true
19
+ ssl_certificate_path => "/Users/jake/workspace/plugins/logstash-mixin-rabbitmq_connection/spec/fixtures/client/keycert.p12"
20
+ ssl_certificate_password => "MySecretPassword"
21
+ }
22
+ }
23
+
24
+ output{ stdout { codec => rubydebug } }
25
+ ```
26
+
27
+ rabbit mq install
28
+ --------
29
+ (mac)
30
+
31
+ ```
32
+ brew install rabbitmq
33
+ export PATH=$PATH:/usr/local/sbin
34
+ vim /usr/local/etc/rabbitmq/rabbitmq.config
35
+
36
+ ```
37
+ ```
38
+ [
39
+ {rabbit, [
40
+ {ssl_listeners, [5671]},
41
+ {ssl_options, [{cacertfile,"/Users/jake/workspace/plugins/logstash-mixin-rabbitmq_connection/spec/fixtures/testca/cacert.pem"},
42
+ {certfile,"/Users/jake/workspace/plugins/logstash-mixin-rabbitmq_connection/spec/fixtures/server/cert.pem"},
43
+ {keyfile,"/Users/jake/workspace/plugins/logstash-mixin-rabbitmq_connection/spec/fixtures/server/key.pem"},
44
+ {verify,verify_peer},
45
+ {fail_if_no_peer_cert,false}]}
46
+ ]}
47
+ ].
48
+ ```
49
+ ```
50
+ export PATH=$PATH:/usr/local/sbin
51
+ rabbitmq-server
52
+ tail -f /usr/local/var/log/rabbitmq/rabbit@localhost.log
53
+ ```
54
+
55
+ sending a test message with ruby
56
+ ----------
57
+ https://www.rabbitmq.com/tutorials/tutorial-one-ruby.html
58
+
59
+ ```
60
+ gem install bunny --version ">= 2.6.4"
61
+ ```
62
+ Create a file called send.rb
63
+ ```
64
+ #!/usr/bin/env ruby
65
+ # encoding: utf-8
66
+
67
+ require "bunny"
68
+
69
+ conn = Bunny.new(:automatically_recover => false)
70
+ conn.start
71
+
72
+ ch = conn.create_channel
73
+ q = ch.queue("hello")
74
+
75
+ ch.default_exchange.publish("Test message", :routing_key => q.name)
76
+ puts "Message sent'"
77
+
78
+ conn.close
79
+ ```
80
+ Send the message with Logstash running as the consumer
81
+ ```
82
+ ruby send.rb
83
+ ```
84
+
85
+ password for all files
86
+ --------
87
+ MySecretPassword
88
+
89
+ start from testca dir
90
+ ---------
91
+ ```
92
+ cd testca
93
+ ```
94
+
95
+ client
96
+ -------
97
+ ```
98
+ openssl genrsa -out ../client/key.pem 2048
99
+ openssl req -config openssl.cnf -key ../client/key.pem -new -sha256 -out ../client/req.pem
100
+ # for hostname use localhost, O=client
101
+ openssl ca -config openssl.cnf -in ../client/req.pem -out ../client/cert.pem
102
+ openssl x509 -in ../client/cert.pem -text -noout
103
+ openssl pkcs12 -export -out ../client/keycert.p12 -inkey ../client/key.pem -in ../client/cert.pem
104
+ ```
105
+
106
+ server
107
+ -------
108
+ ```
109
+ openssl genrsa -out ../server/key.pem 2048
110
+ openssl req -config openssl.cnf -key ../server/key.pem -new -sha256 -out ../server/req.pem
111
+ # for hostname use localhost, O=server
112
+ openssl ca -config openssl.cnf -in ../server/req.pem -out ../server/cert.pem
113
+ openssl x509 -in ../server/cert.pem -text -noout
114
+ openssl pkcs12 -export -out ../server/keycert.p12 -inkey ../server/key.pem -in ../server/cert.pem
115
+ ```
116
+
117
+ establish trust
118
+ ----------
119
+ ```
120
+ cd server
121
+ keytool -import -file ../client/cert.pem -alias client_cert -keystore keycert.p12
122
+ cd client
123
+ keytool -import -file ../server/cert.pem -alias server_cert -keystore keycert.p12
124
+ ```
125
+
126
+ reading
127
+ -----------
128
+ ```
129
+ openssl x509 -in cert.pem -text -noout
130
+ keytool -list -v -keystore keycert.p12
131
+ ```
132
+
133
+ self signed cert (untrusted)
134
+ -------
135
+ ```
136
+ openssl req -x509 -batch -nodes -newkey rsa:2048 -keyout key.pem -out cert.pem -subj "/CN=localhost, O=client" -days 10000
137
+ openssl pkcs12 -export -out keycert.p12 -inkey key.pem -in cert.pem
138
+
139
+ ```
140
+
141
+ Issue [44](https://github.com/logstash-plugins/logstash-mixin-rabbitmq_connection/issues/44) validation
142
+ ---------
143
+ configure Logstash to the untrusted cert :`ssl_certificate_path => "/Users/jake/workspace/plugins/logstash-mixin-rabbitmq_connection/spec/fixtures/client_untrusted/keycert.p12"`
144
+
145
+ This _SHOULD_ fail an error like the following:
146
+ ```
147
+ Using TLS/SSL version TLSv1.2
148
+ [2017-12-19T12:47:12,891][ERROR][logstash.inputs.rabbitmq ] RabbitMQ connection error, will retry. {:error_message=>"sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target", :exception=>"Java::JavaxNetSsl::SSLHandshakeException"}
149
+ ```
150
+ There should _NOT_ be any warnings about a NullTrustManager or disabling verification, and you should _NOT_ be able to send messages.