logstash-core 5.4.3-java → 5.5.0-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|