logstash-core 5.4.3-java → 5.5.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash/api/commands/hot_threads_reporter.rb +2 -2
- data/lib/logstash/api/commands/node.rb +0 -1
- data/lib/logstash/api/commands/stats.rb +0 -1
- data/lib/logstash/config/mixin.rb +5 -43
- data/lib/logstash/config/modules_common.rb +71 -0
- data/lib/logstash/elasticsearch_client.rb +120 -0
- data/lib/logstash/environment.rb +14 -3
- data/lib/logstash/errors.rb +1 -0
- data/lib/logstash/execution_context.rb +11 -3
- data/lib/logstash/inputs/base.rb +2 -0
- data/lib/logstash/instrument/global_metrics.rb +13 -0
- data/lib/logstash/instrument/metric_type/mean.rb +5 -0
- data/lib/logstash/instrument/periodic_poller/jvm.rb +5 -5
- data/lib/logstash/logging/logger.rb +26 -1
- data/lib/logstash/modules/cli_parser.rb +74 -0
- data/lib/logstash/modules/elasticsearch_config.rb +22 -0
- data/lib/logstash/modules/elasticsearch_resource.rb +10 -0
- data/lib/logstash/modules/file_reader.rb +36 -0
- data/lib/logstash/modules/importer.rb +37 -0
- data/lib/logstash/modules/kibana_base_resource.rb +10 -0
- data/lib/logstash/modules/kibana_config.rb +104 -0
- data/lib/logstash/modules/kibana_resource.rb +10 -0
- data/lib/logstash/modules/logstash_config.rb +48 -0
- data/lib/logstash/modules/resource_base.rb +37 -0
- data/lib/logstash/modules/scaffold.rb +44 -0
- data/lib/logstash/namespace.rb +1 -0
- data/lib/logstash/outputs/base.rb +2 -0
- data/lib/logstash/pipeline.rb +18 -4
- data/lib/logstash/plugin.rb +1 -0
- data/lib/logstash/plugins/registry.rb +5 -0
- data/lib/logstash/runner.rb +42 -2
- data/lib/logstash/settings.rb +7 -1
- data/lib/logstash/timestamp.rb +4 -0
- data/lib/logstash/util/dead_letter_queue_manager.rb +61 -0
- data/lib/logstash/util/safe_uri.rb +130 -11
- data/lib/logstash/util/thread_dump.rb +3 -1
- data/lib/logstash/util/wrapped_acked_queue.rb +24 -6
- data/lib/logstash/util/wrapped_synchronous_queue.rb +19 -5
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +46 -0
- data/logstash-core.gemspec +7 -2
- data/spec/{api/lib/commands/stats.rb → logstash/api/commands/stats_spec.rb} +7 -2
- data/spec/{api/lib → logstash/api}/errors_spec.rb +1 -1
- data/spec/{api/lib/api → logstash/api/modules}/logging_spec.rb +1 -10
- data/spec/{api/lib/api → logstash/api/modules}/node_plugins_spec.rb +2 -3
- data/spec/{api/lib/api → logstash/api/modules}/node_spec.rb +6 -7
- data/spec/{api/lib/api → logstash/api/modules}/node_stats_spec.rb +2 -2
- data/spec/{api/lib/api → logstash/api/modules}/plugins_spec.rb +4 -3
- data/spec/{api/lib/api → logstash/api/modules}/root_spec.rb +3 -3
- data/spec/{api/lib → logstash/api}/rack_app_spec.rb +0 -0
- data/spec/logstash/config/mixin_spec.rb +2 -2
- data/spec/logstash/execution_context_spec.rb +20 -1
- data/spec/logstash/filter_delegator_spec.rb +2 -1
- data/spec/logstash/inputs/base_spec.rb +1 -1
- data/spec/logstash/output_delegator_spec.rb +2 -1
- data/spec/logstash/outputs/base_spec.rb +1 -1
- data/spec/logstash/pipeline_dlq_commit_spec.rb +107 -0
- data/spec/logstash/pipeline_pq_file_spec.rb +1 -1
- data/spec/logstash/plugin_spec.rb +1 -1
- data/spec/logstash/plugins/registry_spec.rb +22 -5
- data/spec/logstash/runner_spec.rb +122 -19
- data/spec/logstash/settings_spec.rb +91 -0
- data/spec/logstash/timestamp_spec.rb +6 -0
- data/spec/support/helpers.rb +80 -1
- data/spec/support/matchers.rb +13 -0
- data/spec/support/shared_contexts.rb +38 -0
- data/spec/support/shared_examples.rb +1 -1
- metadata +95 -40
- data/spec/api/lib/api/support/resource_dsl_methods.rb +0 -87
- data/spec/api/spec_helper.rb +0 -111
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/logging"
|
4
|
+
require "erb"
|
5
|
+
|
6
|
+
require_relative "elasticsearch_config"
|
7
|
+
require_relative "kibana_config"
|
8
|
+
require_relative "logstash_config"
|
9
|
+
|
10
|
+
module LogStash module Modules class Scaffold
|
11
|
+
include LogStash::Util::Loggable
|
12
|
+
|
13
|
+
attr_reader :directory, :module_name, :logstash_configuration, :kibana_configuration, :elasticsearch_configuration
|
14
|
+
|
15
|
+
def initialize(name, directory)
|
16
|
+
@module_name = name
|
17
|
+
@directory = directory # this is the 'configuration folder in the GEM root.'
|
18
|
+
end
|
19
|
+
|
20
|
+
def import(import_engine)
|
21
|
+
@elasticsearch_configuration.resources.each do |resource|
|
22
|
+
import_engine.put(resource)
|
23
|
+
end
|
24
|
+
@kibana_configuration.resources.each do |resource|
|
25
|
+
import_engine.put(resource)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def with_settings(module_settings)
|
30
|
+
@logstash_configuration = LogStashConfig.new(self, module_settings)
|
31
|
+
@kibana_configuration = KibanaConfig.new(self, module_settings)
|
32
|
+
@elasticsearch_configuration = ElasticsearchConfig.new(self, module_settings)
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def config_string()
|
37
|
+
# settings should be set earlier by the caller.
|
38
|
+
# settings should be the subset from the YAML file with a structure like
|
39
|
+
# {"name" => "plugin name", "k1" => "v1", "k2" => "v2"}, etc.
|
40
|
+
return nil if @logstash_configuration.nil?
|
41
|
+
@logstash_configuration.config_string
|
42
|
+
end
|
43
|
+
end end end # class LogStash::Modules::Scaffold
|
44
|
+
|
data/lib/logstash/namespace.rb
CHANGED
@@ -109,6 +109,8 @@ class LogStash::Outputs::Base < LogStash::Plugin
|
|
109
109
|
super
|
110
110
|
# There is no easy way to propage an instance variable into the codec, because the codec
|
111
111
|
# are created at the class level
|
112
|
+
# TODO(talevy): Codecs should have their own execution_context, for now they will inherit their
|
113
|
+
# parent plugin's
|
112
114
|
@codec.execution_context = context
|
113
115
|
context
|
114
116
|
end
|
data/lib/logstash/pipeline.rb
CHANGED
@@ -18,11 +18,15 @@ require "logstash/instrument/null_metric"
|
|
18
18
|
require "logstash/instrument/namespaced_null_metric"
|
19
19
|
require "logstash/instrument/collector"
|
20
20
|
require "logstash/instrument/wrapped_write_client"
|
21
|
+
require "logstash/util/dead_letter_queue_manager"
|
21
22
|
require "logstash/output_delegator"
|
22
23
|
require "logstash/filter_delegator"
|
23
24
|
require "logstash/queue_factory"
|
24
25
|
require "logstash/execution_context"
|
25
26
|
|
27
|
+
java_import org.logstash.common.DeadLetterQueueFactory
|
28
|
+
java_import org.logstash.common.io.DeadLetterQueueWriter
|
29
|
+
|
26
30
|
module LogStash; class BasePipeline
|
27
31
|
include LogStash::Util::Loggable
|
28
32
|
|
@@ -43,7 +47,12 @@ module LogStash; class BasePipeline
|
|
43
47
|
@inputs = nil
|
44
48
|
@filters = nil
|
45
49
|
@outputs = nil
|
46
|
-
|
50
|
+
|
51
|
+
if settings.get_value("dead_letter_queue.enable")
|
52
|
+
@dlq_writer = DeadLetterQueueFactory.getWriter(pipeline_id, settings.get_value("path.dead_letter_queue"))
|
53
|
+
else
|
54
|
+
@dlq_writer = LogStash::Util::DummyDeadLetterQueueWriter.new
|
55
|
+
end
|
47
56
|
|
48
57
|
grammar = LogStashConfigParser.new
|
49
58
|
parsed_config = grammar.parse(config_str)
|
@@ -90,16 +99,18 @@ module LogStash; class BasePipeline
|
|
90
99
|
|
91
100
|
klass = Plugin.lookup(plugin_type, name)
|
92
101
|
|
102
|
+
execution_context = ExecutionContext.new(self, id, klass.config_name, @dlq_writer)
|
103
|
+
|
93
104
|
if plugin_type == "output"
|
94
|
-
OutputDelegator.new(@logger, klass, type_scoped_metric,
|
105
|
+
OutputDelegator.new(@logger, klass, type_scoped_metric, execution_context, OutputDelegatorStrategyRegistry.instance, args)
|
95
106
|
elsif plugin_type == "filter"
|
96
|
-
FilterDelegator.new(@logger, klass, type_scoped_metric,
|
107
|
+
FilterDelegator.new(@logger, klass, type_scoped_metric, execution_context, args)
|
97
108
|
else # input
|
98
109
|
input_plugin = klass.new(args)
|
99
110
|
scoped_metric = type_scoped_metric.namespace(id.to_sym)
|
100
111
|
scoped_metric.gauge(:name, input_plugin.config_name)
|
101
112
|
input_plugin.metric = scoped_metric
|
102
|
-
input_plugin.execution_context =
|
113
|
+
input_plugin.execution_context = execution_context
|
103
114
|
input_plugin
|
104
115
|
end
|
105
116
|
end
|
@@ -162,6 +173,7 @@ module LogStash; class Pipeline < BasePipeline
|
|
162
173
|
)
|
163
174
|
@drain_queue = @settings.get_value("queue.drain")
|
164
175
|
|
176
|
+
|
165
177
|
@events_filtered = Concurrent::AtomicFixnum.new(0)
|
166
178
|
@events_consumed = Concurrent::AtomicFixnum.new(0)
|
167
179
|
|
@@ -239,6 +251,7 @@ module LogStash; class Pipeline < BasePipeline
|
|
239
251
|
def close
|
240
252
|
@filter_queue_client.close
|
241
253
|
@queue.close
|
254
|
+
@dlq_writer.close
|
242
255
|
end
|
243
256
|
|
244
257
|
def transition_to_running
|
@@ -599,6 +612,7 @@ module LogStash; class Pipeline < BasePipeline
|
|
599
612
|
n.gauge(:page_capacity_in_bytes, queue.page_capacity)
|
600
613
|
n.gauge(:max_queue_size_in_bytes, queue.max_size_in_bytes)
|
601
614
|
n.gauge(:max_unread_events, queue.max_unread_events)
|
615
|
+
n.gauge(:queue_size_in_bytes, queue.persisted_size_in_bytes)
|
602
616
|
end
|
603
617
|
pipeline_metric.namespace([:data]).tap do |n|
|
604
618
|
n.gauge(:free_space_in_bytes, file_store.get_unallocated_space)
|
data/lib/logstash/plugin.rb
CHANGED
@@ -3,6 +3,7 @@ require "rubygems/package"
|
|
3
3
|
require "logstash/util/loggable"
|
4
4
|
require "logstash/plugin"
|
5
5
|
require "logstash/plugins/hooks_registry"
|
6
|
+
require "logstash/modules/scaffold"
|
6
7
|
|
7
8
|
module LogStash module Plugins
|
8
9
|
class Registry
|
@@ -109,6 +110,10 @@ module LogStash module Plugins
|
|
109
110
|
.each { |specification| specification.register(hooks, LogStash::SETTINGS) }
|
110
111
|
end
|
111
112
|
|
113
|
+
def plugins_with_type(type)
|
114
|
+
@registry.values.select { |specification| specification.type.to_sym == type.to_sym }.collect(&:klass)
|
115
|
+
end
|
116
|
+
|
112
117
|
def load_available_plugins
|
113
118
|
GemRegistry.logstash_plugins.each do |plugin_context|
|
114
119
|
# When a plugin has a HOOK_FILE defined, its the responsibility of the plugin
|
data/lib/logstash/runner.rb
CHANGED
@@ -9,11 +9,13 @@ require "net/http"
|
|
9
9
|
require "logstash/namespace"
|
10
10
|
require "logstash-core/logstash-core"
|
11
11
|
require "logstash/environment"
|
12
|
+
require "logstash/modules/cli_parser"
|
12
13
|
|
13
14
|
LogStash::Environment.load_locale!
|
14
15
|
|
15
16
|
require "logstash/agent"
|
16
17
|
require "logstash/config/defaults"
|
18
|
+
require "logstash/config/modules_common"
|
17
19
|
require "logstash/shutdown_watcher"
|
18
20
|
require "logstash/patches/clamp"
|
19
21
|
require "logstash/settings"
|
@@ -22,6 +24,17 @@ require "logstash/plugins/registry"
|
|
22
24
|
|
23
25
|
java_import 'org.logstash.FileLockFactory'
|
24
26
|
|
27
|
+
def register_local_modules(path)
|
28
|
+
modules_path = File.join(path, File::Separator, "modules")
|
29
|
+
Dir.foreach(modules_path) do |item|
|
30
|
+
# Ignore unix relative path ids
|
31
|
+
next if item == '.' or item == '..'
|
32
|
+
# Ignore non-directories
|
33
|
+
next if !File.directory?(File.join(modules_path, File::Separator, item))
|
34
|
+
LogStash::PLUGIN_REGISTRY.add(:modules, item, LogStash::Modules::Scaffold.new(item, File.join(modules_path, File::Separator, item, File::Separator, "configuration")))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
25
38
|
class LogStash::Runner < Clamp::StrictCommand
|
26
39
|
include LogStash::Util::Loggable
|
27
40
|
# The `path.settings` and `path.logs` need to be defined in the runner instead of the `logstash-core/lib/logstash/environment.rb`
|
@@ -49,6 +62,17 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
49
62
|
:default => LogStash::SETTINGS.get_default("config.string"),
|
50
63
|
:attribute_name => "config.string"
|
51
64
|
|
65
|
+
# Module settings
|
66
|
+
option ["--modules"], "MODULES",
|
67
|
+
I18n.t("logstash.runner.flag.modules"),
|
68
|
+
:multivalued => true,
|
69
|
+
:attribute_name => "modules_list"
|
70
|
+
|
71
|
+
option ["-M", "--modules.variable"], "MODULES_VARIABLE",
|
72
|
+
I18n.t("logstash.runner.flag.modules_variable"),
|
73
|
+
:multivalued => true,
|
74
|
+
:attribute_name => "modules_variable_list"
|
75
|
+
|
52
76
|
# Pipeline settings
|
53
77
|
option ["-w", "--pipeline.workers"], "COUNT",
|
54
78
|
I18n.t("logstash.runner.flag.pipeline-workers"),
|
@@ -190,7 +214,7 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
190
214
|
# We invoke post_process to apply extra logic to them.
|
191
215
|
# The post_process callbacks have been added in environment.rb
|
192
216
|
@settings.post_process
|
193
|
-
|
217
|
+
|
194
218
|
require "logstash/util"
|
195
219
|
require "logstash/util/java_version"
|
196
220
|
require "stud/task"
|
@@ -211,6 +235,9 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
211
235
|
logger.warn("--config.debug was specified, but log.level was not set to \'debug\'! No config info will be logged.")
|
212
236
|
end
|
213
237
|
|
238
|
+
# Add local modules to the registry before everything else
|
239
|
+
register_local_modules(LogStash::Environment::LOGSTASH_HOME)
|
240
|
+
|
214
241
|
# We configure the registry and load any plugin that can register hooks
|
215
242
|
# with logstash, this need to be done before any operation.
|
216
243
|
LogStash::PLUGIN_REGISTRY.setup!
|
@@ -230,6 +257,10 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
230
257
|
return 1
|
231
258
|
end
|
232
259
|
|
260
|
+
module_parser = LogStash::Modules::CLIParser.new(@modules_list, @modules_variable_list)
|
261
|
+
# Now populate Setting for modules.list with our parsed array.
|
262
|
+
@settings.set("modules.cli", module_parser.output)
|
263
|
+
|
233
264
|
LogStash::ShutdownWatcher.unsafe_shutdown = setting("pipeline.unsafe_shutdown")
|
234
265
|
|
235
266
|
configure_plugin_paths(setting("path.plugins"))
|
@@ -243,6 +274,15 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
243
274
|
|
244
275
|
@settings.format_settings.each {|line| logger.debug(line) }
|
245
276
|
|
277
|
+
module_configs = LogStash::Config::ModulesCommon.pipeline_configs(@settings)
|
278
|
+
module_config_hash = module_configs.first
|
279
|
+
if !module_config_hash.nil?
|
280
|
+
@settings.set_value("config.string", module_config_hash["config_string"])
|
281
|
+
end
|
282
|
+
if module_configs.size > 1
|
283
|
+
logger.warn "Multiple modules defined in logstash.yml - using the first one: #{module_config_hash["pipeline_id"]}"
|
284
|
+
end
|
285
|
+
|
246
286
|
if setting("config.string").nil? && setting("path.config").nil?
|
247
287
|
fail(I18n.t("logstash.runner.missing-configuration"))
|
248
288
|
end
|
@@ -434,7 +474,7 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
434
474
|
nil
|
435
475
|
end
|
436
476
|
end
|
437
|
-
|
477
|
+
|
438
478
|
# is the user asking for CLI help subcommand?
|
439
479
|
def cli_help?(args)
|
440
480
|
# I know, double negative
|
data/lib/logstash/settings.rb
CHANGED
@@ -2,11 +2,14 @@
|
|
2
2
|
require "logstash/util/loggable"
|
3
3
|
require "fileutils"
|
4
4
|
require "logstash/util/byte_value"
|
5
|
+
require "logstash/util/environment_variables"
|
5
6
|
require "logstash/util/time_value"
|
6
7
|
|
7
8
|
module LogStash
|
8
9
|
class Settings
|
9
10
|
|
11
|
+
include LogStash::Util::EnvironmentVariables
|
12
|
+
|
10
13
|
def initialize
|
11
14
|
@settings = {}
|
12
15
|
# Theses settings were loaded from the yaml file
|
@@ -107,7 +110,10 @@ module LogStash
|
|
107
110
|
|
108
111
|
def from_yaml(yaml_path)
|
109
112
|
settings = read_yaml(::File.join(yaml_path, "logstash.yml"))
|
110
|
-
self.merge(
|
113
|
+
self.merge(
|
114
|
+
deep_replace(flatten_hash(settings)),
|
115
|
+
true
|
116
|
+
)
|
111
117
|
self
|
112
118
|
end
|
113
119
|
|
data/lib/logstash/timestamp.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'logstash/environment'
|
2
|
+
|
3
|
+
module LogStash; module Util
|
4
|
+
class PluginDeadLetterQueueWriter
|
5
|
+
|
6
|
+
attr_reader :plugin_id, :plugin_type, :inner_writer
|
7
|
+
|
8
|
+
def initialize(inner_writer, plugin_id, plugin_type)
|
9
|
+
@plugin_id = plugin_id
|
10
|
+
@plugin_type = plugin_type
|
11
|
+
@inner_writer = inner_writer
|
12
|
+
end
|
13
|
+
|
14
|
+
def write(logstash_event, reason)
|
15
|
+
if @inner_writer && @inner_writer.is_open
|
16
|
+
@inner_writer.writeEntry(logstash_event.to_java, @plugin_type, @plugin_id, reason)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def close
|
21
|
+
if @inner_writer && @inner_writer.is_open
|
22
|
+
@inner_writer.close
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class DummyDeadLetterQueueWriter
|
28
|
+
# class uses to represent a writer when dead_letter_queue is disabled
|
29
|
+
def initialize
|
30
|
+
end
|
31
|
+
|
32
|
+
def write(logstash_event, reason)
|
33
|
+
# noop
|
34
|
+
end
|
35
|
+
|
36
|
+
def is_open
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
def close
|
41
|
+
# noop
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class DeadLetterQueueFactory
|
46
|
+
java_import org.logstash.common.DeadLetterQueueFactory
|
47
|
+
|
48
|
+
def self.get(pipeline_id)
|
49
|
+
if LogStash::SETTINGS.get("dead_letter_queue.enable")
|
50
|
+
return DeadLetterQueueWriter.new(
|
51
|
+
DeadLetterQueueFactory.getWriter(pipeline_id, LogStash::SETTINGS.get("path.dead_letter_queue")))
|
52
|
+
else
|
53
|
+
return DeadLetterQueueWriter.new(nil)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.close(pipeline_id)
|
58
|
+
DeadLetterQueueFactory.close(pipeline_id)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end end
|
@@ -11,20 +11,21 @@ class LogStash::Util::SafeURI
|
|
11
11
|
|
12
12
|
extend Forwardable
|
13
13
|
|
14
|
-
def_delegators :@uri, :coerce, :query=, :route_from, :port=, :default_port, :select, :normalize!, :absolute?, :registry=, :path, :password, :hostname, :merge, :normalize, :host, :component_ary, :userinfo=, :query, :set_opaque, :+, :merge!, :-, :password=, :parser, :port, :set_host, :set_path, :opaque=, :scheme, :fragment=, :set_query, :set_fragment, :userinfo, :hostname=, :set_port, :path=, :registry, :opaque, :route_to, :set_password, :hierarchical?, :set_user, :set_registry, :set_userinfo, :fragment, :component, :user=, :set_scheme, :absolute, :host=, :relative?, :scheme=, :user
|
15
14
|
|
16
15
|
attr_reader :uri
|
17
|
-
|
16
|
+
|
18
17
|
public
|
19
18
|
def initialize(arg)
|
20
19
|
@uri = case arg
|
21
20
|
when String
|
22
21
|
arg = "//#{arg}" if HOSTNAME_PORT_REGEX.match(arg)
|
23
|
-
URI.
|
24
|
-
when URI
|
22
|
+
java.net.URI.new(arg)
|
23
|
+
when java.net.URI
|
25
24
|
arg
|
25
|
+
when URI
|
26
|
+
java.net.URI.new(arg.to_s)
|
26
27
|
else
|
27
|
-
raise ArgumentError, "Expected a string or URI, got a #{arg.class} creating a URL"
|
28
|
+
raise ArgumentError, "Expected a string, java.net.URI, or URI, got a #{arg.class} creating a URL"
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
@@ -37,11 +38,11 @@ class LogStash::Util::SafeURI
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def sanitized
|
40
|
-
return uri unless
|
41
|
+
return uri unless password # nothing to sanitize here!
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
user_info = user ? "#{user}:#{PASS_PLACEHOLDER}" : nil
|
44
|
+
|
45
|
+
make_uri(scheme, user_info, host, port, path, query, fragment)
|
45
46
|
end
|
46
47
|
|
47
48
|
def ==(other)
|
@@ -49,8 +50,126 @@ class LogStash::Util::SafeURI
|
|
49
50
|
end
|
50
51
|
|
51
52
|
def clone
|
52
|
-
|
53
|
-
self.class.new(
|
53
|
+
# No need to clone the URI, in java its immutable
|
54
|
+
self.class.new(uri)
|
55
|
+
end
|
56
|
+
|
57
|
+
def update(field, value)
|
58
|
+
new_scheme = scheme
|
59
|
+
new_user = user
|
60
|
+
new_password = password
|
61
|
+
new_host = host
|
62
|
+
new_port = port
|
63
|
+
new_path = path
|
64
|
+
new_query = query
|
65
|
+
new_fragment = fragment
|
66
|
+
|
67
|
+
case field
|
68
|
+
when :scheme
|
69
|
+
new_scheme = value
|
70
|
+
when :user
|
71
|
+
new_user = value
|
72
|
+
when :password
|
73
|
+
new_password = value
|
74
|
+
when :host
|
75
|
+
new_host = value
|
76
|
+
when :port
|
77
|
+
new_port = value
|
78
|
+
when :path
|
79
|
+
new_path = value
|
80
|
+
when :query
|
81
|
+
new_query = value
|
82
|
+
when :fragment
|
83
|
+
new_fragment = value
|
84
|
+
end
|
85
|
+
|
86
|
+
user_info = new_user
|
87
|
+
if new_user && new_password
|
88
|
+
user_info += ":" + new_password
|
89
|
+
end
|
90
|
+
|
91
|
+
@uri = make_uri(new_scheme, user_info, new_host, new_port, new_path, new_query, new_fragment)
|
92
|
+
end
|
93
|
+
|
94
|
+
def user
|
95
|
+
if @uri.userInfo
|
96
|
+
@uri.userInfo.split(":")[0]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def user=(new_user)
|
101
|
+
update(:user, new_user)
|
102
|
+
end
|
103
|
+
|
104
|
+
def password
|
105
|
+
if @uri.userInfo
|
106
|
+
@uri.userInfo.split(":")[1]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def password=(new_password)
|
111
|
+
update(:password, new_password)
|
112
|
+
end
|
113
|
+
|
114
|
+
def hostname
|
115
|
+
# Alias from the ruby library
|
116
|
+
host
|
117
|
+
end
|
118
|
+
|
119
|
+
def host=(new_host)
|
120
|
+
update(:host, new_host)
|
121
|
+
end
|
122
|
+
|
123
|
+
def port
|
124
|
+
# In java this is an int
|
125
|
+
uri.port < 1 ? nil : uri.port
|
126
|
+
end
|
127
|
+
|
128
|
+
def port=(new_port)
|
129
|
+
update(:port, new_port)
|
130
|
+
end
|
131
|
+
|
132
|
+
def path=(new_path)
|
133
|
+
update(:path, new_path)
|
134
|
+
end
|
135
|
+
|
136
|
+
def query=(new_query)
|
137
|
+
update(:query, new_query)
|
138
|
+
end
|
139
|
+
|
140
|
+
def fragment=(new_fragment)
|
141
|
+
update(:fragment, new_fragment)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Same algorithm as Ruby's URI class uses
|
145
|
+
def normalize!
|
146
|
+
if path && path == ''
|
147
|
+
path = '/'
|
148
|
+
end
|
149
|
+
if scheme && scheme != scheme.downcase
|
150
|
+
scheme = self.scheme.downcase
|
151
|
+
end
|
152
|
+
if host && host != host.downcase
|
153
|
+
host = self.host.downcase
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def normalize
|
158
|
+
d = self.dup
|
159
|
+
d.normalize!
|
160
|
+
d
|
161
|
+
end
|
162
|
+
|
163
|
+
def_delegators :@uri, :absolute?, :scheme, :host, :path, :query, :fragment, :userinfo
|
164
|
+
|
165
|
+
private
|
166
|
+
|
167
|
+
# Jruby doesn't guess the constructor correctly if there are some nil things in place
|
168
|
+
# hence, this method
|
169
|
+
def make_uri(scheme, user_info, host, port, path, query, fragment)
|
170
|
+
# It is lot legal to have a path not starting with a /
|
171
|
+
prefixed_path = path && path[0] != "/" ? "/#{path}" : path
|
172
|
+
java.net.URI.new(scheme, user_info, host, port || -1, prefixed_path, query, fragment)
|
54
173
|
end
|
55
174
|
end
|
56
175
|
|