logstash-core 6.0.0.alpha2-java → 6.0.0.beta1-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.
Files changed (110) hide show
  1. checksums.yaml +5 -5
  2. data/gemspec_jars.rb +6 -4
  3. data/lib/logstash-core/logstash-core.jar +0 -0
  4. data/lib/logstash-core/logstash-core.rb +2 -2
  5. data/lib/logstash-core/version.rb +1 -1
  6. data/lib/logstash-core_jars.rb +14 -10
  7. data/lib/logstash/agent.rb +4 -2
  8. data/lib/logstash/api/commands/default_metadata.rb +1 -1
  9. data/lib/logstash/api/commands/hot_threads_reporter.rb +8 -2
  10. data/lib/logstash/api/commands/node.rb +2 -2
  11. data/lib/logstash/api/commands/stats.rb +2 -2
  12. data/lib/logstash/bootstrap_check/bad_ruby.rb +2 -2
  13. data/lib/logstash/bootstrap_check/default_config.rb +2 -3
  14. data/lib/logstash/compiler.rb +12 -12
  15. data/lib/logstash/compiler/lscl.rb +17 -7
  16. data/lib/logstash/compiler/treetop_monkeypatches.rb +1 -0
  17. data/lib/logstash/config/config_ast.rb +11 -1
  18. data/lib/logstash/config/mixin.rb +5 -0
  19. data/lib/logstash/config/modules_common.rb +101 -0
  20. data/lib/logstash/config/source/base.rb +75 -0
  21. data/lib/logstash/config/source/local.rb +52 -50
  22. data/lib/logstash/config/source/modules.rb +55 -0
  23. data/lib/logstash/config/source/multi_local.rb +54 -10
  24. data/lib/logstash/config/source_loader.rb +1 -0
  25. data/lib/logstash/config/string_escape.rb +27 -0
  26. data/lib/logstash/elasticsearch_client.rb +142 -0
  27. data/lib/logstash/environment.rb +5 -1
  28. data/lib/logstash/event.rb +0 -1
  29. data/lib/logstash/instrument/global_metrics.rb +13 -0
  30. data/lib/logstash/instrument/metric_store.rb +16 -13
  31. data/lib/logstash/instrument/metric_type/counter.rb +6 -18
  32. data/lib/logstash/instrument/metric_type/gauge.rb +6 -12
  33. data/lib/logstash/instrument/periodic_poller/dlq.rb +19 -0
  34. data/lib/logstash/instrument/periodic_pollers.rb +3 -1
  35. data/lib/logstash/logging/logger.rb +43 -14
  36. data/lib/logstash/modules/cli_parser.rb +74 -0
  37. data/lib/logstash/modules/elasticsearch_config.rb +22 -0
  38. data/lib/logstash/modules/elasticsearch_importer.rb +37 -0
  39. data/lib/logstash/modules/elasticsearch_resource.rb +10 -0
  40. data/lib/logstash/modules/file_reader.rb +36 -0
  41. data/lib/logstash/modules/kibana_base.rb +24 -0
  42. data/lib/logstash/modules/kibana_client.rb +122 -0
  43. data/lib/logstash/modules/kibana_config.rb +125 -0
  44. data/lib/logstash/modules/kibana_dashboards.rb +36 -0
  45. data/lib/logstash/modules/kibana_importer.rb +17 -0
  46. data/lib/logstash/modules/kibana_resource.rb +10 -0
  47. data/lib/logstash/modules/kibana_settings.rb +40 -0
  48. data/lib/logstash/modules/logstash_config.rb +120 -0
  49. data/lib/logstash/modules/resource_base.rb +38 -0
  50. data/lib/logstash/modules/scaffold.rb +50 -0
  51. data/lib/logstash/modules/settings_merger.rb +23 -0
  52. data/lib/logstash/modules/util.rb +17 -0
  53. data/lib/logstash/namespace.rb +1 -0
  54. data/lib/logstash/pipeline.rb +66 -27
  55. data/lib/logstash/pipeline_settings.rb +1 -0
  56. data/lib/logstash/plugins/registry.rb +1 -0
  57. data/lib/logstash/runner.rb +47 -3
  58. data/lib/logstash/settings.rb +20 -1
  59. data/lib/logstash/util/dead_letter_queue_manager.rb +1 -1
  60. data/lib/logstash/util/safe_uri.rb +146 -11
  61. data/lib/logstash/util/thread_dump.rb +4 -3
  62. data/lib/logstash/util/wrapped_acked_queue.rb +28 -24
  63. data/lib/logstash/util/wrapped_synchronous_queue.rb +19 -20
  64. data/lib/logstash/version.rb +1 -1
  65. data/locales/en.yml +56 -1
  66. data/logstash-core.gemspec +6 -4
  67. data/spec/logstash/agent/converge_spec.rb +2 -2
  68. data/spec/logstash/agent_spec.rb +11 -3
  69. data/spec/logstash/api/modules/logging_spec.rb +13 -7
  70. data/spec/logstash/api/modules/node_plugins_spec.rb +23 -5
  71. data/spec/logstash/api/modules/node_spec.rb +17 -15
  72. data/spec/logstash/api/modules/node_stats_spec.rb +0 -1
  73. data/spec/logstash/api/modules/plugins_spec.rb +40 -9
  74. data/spec/logstash/api/modules/root_spec.rb +0 -1
  75. data/spec/logstash/api/rack_app_spec.rb +2 -1
  76. data/spec/logstash/compiler/compiler_spec.rb +54 -7
  77. data/spec/logstash/config/config_ast_spec.rb +47 -8
  78. data/spec/logstash/config/mixin_spec.rb +14 -2
  79. data/spec/logstash/config/pipeline_config_spec.rb +7 -7
  80. data/spec/logstash/config/source/local_spec.rb +5 -2
  81. data/spec/logstash/config/source/multi_local_spec.rb +56 -10
  82. data/spec/logstash/config/source_loader_spec.rb +1 -1
  83. data/spec/logstash/config/string_escape_spec.rb +24 -0
  84. data/spec/logstash/event_spec.rb +9 -0
  85. data/spec/logstash/filters/base_spec.rb +1 -1
  86. data/spec/logstash/instrument/metric_store_spec.rb +2 -3
  87. data/spec/logstash/instrument/metric_type/counter_spec.rb +0 -12
  88. data/spec/logstash/instrument/metric_type/gauge_spec.rb +1 -8
  89. data/spec/logstash/instrument/periodic_poller/dlq_spec.rb +17 -0
  90. data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +1 -1
  91. data/spec/logstash/legacy_ruby_event_spec.rb +0 -9
  92. data/spec/logstash/legacy_ruby_timestamp_spec.rb +19 -14
  93. data/spec/logstash/modules/cli_parser_spec.rb +129 -0
  94. data/spec/logstash/modules/logstash_config_spec.rb +56 -0
  95. data/spec/logstash/modules/scaffold_spec.rb +239 -0
  96. data/spec/logstash/pipeline_dlq_commit_spec.rb +1 -1
  97. data/spec/logstash/pipeline_spec.rb +87 -20
  98. data/spec/logstash/runner_spec.rb +122 -5
  99. data/spec/logstash/setting_spec.rb +2 -2
  100. data/spec/logstash/settings/splittable_string_array_spec.rb +51 -0
  101. data/spec/logstash/timestamp_spec.rb +8 -2
  102. data/spec/logstash/util/safe_uri_spec.rb +16 -0
  103. data/spec/logstash/util/wrapped_acked_queue_spec.rb +63 -0
  104. data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +0 -22
  105. data/spec/support/helpers.rb +1 -1
  106. data/spec/support/matchers.rb +21 -4
  107. metadata +102 -19
  108. data/lib/logstash/instrument/metric_type/base.rb +0 -31
  109. data/lib/logstash/program.rb +0 -14
  110. data/lib/logstash/string_interpolation.rb +0 -18
@@ -1,8 +1,11 @@
1
1
  # encoding: utf-8
2
2
  module LogStash module Config module Source
3
3
  class Base
4
+ attr_reader :conflict_messages
5
+
4
6
  def initialize(settings)
5
7
  @settings = settings
8
+ @conflict_messages = []
6
9
  end
7
10
 
8
11
  def pipeline_configs
@@ -12,5 +15,77 @@ module LogStash module Config module Source
12
15
  def match?
13
16
  raise NotImplementedError, "`match?` must be implemented!"
14
17
  end
18
+
19
+ def config_conflict?
20
+ raise NotImplementedError, "`config_conflict?` must be implemented!"
21
+ end
22
+
23
+ def config_reload_automatic_setting
24
+ @settings.get_setting("config.reload.automatic")
25
+ end
26
+
27
+ def config_reload_automatic
28
+ config_reload_automatic_setting.value
29
+ end
30
+
31
+ def config_reload_automatic?
32
+ config_reload_automatic_setting.set?
33
+ end
34
+
35
+ def config_string_setting
36
+ @settings.get_setting("config.string")
37
+ end
38
+
39
+ def config_string
40
+ config_string_setting.value
41
+ end
42
+
43
+ def config_string?
44
+ !config_string.nil?
45
+ end
46
+
47
+ def config_path_setting
48
+ @settings.get_setting("path.config")
49
+ end
50
+
51
+ def config_path
52
+ config_path_setting.value
53
+ end
54
+
55
+ def config_path?
56
+ !(config_path.nil? || config_path.empty?)
57
+ end
58
+
59
+ def modules_cli_setting
60
+ @settings.get_setting("modules.cli")
61
+ end
62
+
63
+ def modules_cli
64
+ modules_cli_setting.value
65
+ end
66
+
67
+ def modules_cli?
68
+ !(modules_cli.nil? || modules_cli.empty?)
69
+ end
70
+
71
+ def modules_setting
72
+ @settings.get_setting("modules")
73
+ end
74
+
75
+ def modules
76
+ modules_setting.value
77
+ end
78
+
79
+ def modules?
80
+ !(modules.nil? || modules.empty?)
81
+ end
82
+
83
+ def both_module_configs?
84
+ modules_cli? && modules?
85
+ end
86
+
87
+ def modules_defined?
88
+ modules_cli? || modules?
89
+ end
15
90
  end
16
91
  end end end
@@ -18,8 +18,27 @@ module LogStash module Config module Source
18
18
  #
19
19
  class Local < Base
20
20
  class ConfigStringLoader
21
+ INPUT_BLOCK_RE = /input *{/
22
+ OUTPUT_BLOCK_RE = /output *{/
23
+ EMPTY_RE = /^\s*$/
24
+
21
25
  def self.read(config_string)
22
- [org.logstash.common.SourceWithMetadata.new("string", "config_string", config_string)]
26
+ config_parts = [org.logstash.common.SourceWithMetadata.new("string", "config_string", 0, 0, config_string)]
27
+
28
+ # Make sure we have an input and at least 1 output
29
+ # if its not the case we will add stdin and stdout
30
+ # this is for backward compatibility reason
31
+ if !INPUT_BLOCK_RE.match(config_string)
32
+ config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default input", 0, 0, LogStash::Config::Defaults.input)
33
+
34
+ end
35
+
36
+ # include a default stdout output if no outputs given
37
+ if !OUTPUT_BLOCK_RE.match(config_string)
38
+ config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default output", 0, 0, LogStash::Config::Defaults.output)
39
+ end
40
+
41
+ config_parts
23
42
  end
24
43
  end
25
44
 
@@ -53,8 +72,8 @@ module LogStash module Config module Source
53
72
 
54
73
  config_string = ::File.read(file)
55
74
 
56
- if valid_encoding?(config_string)
57
- part = org.logstash.common.SourceWithMetadata.new("file", file, config_string)
75
+ if config_string.valid_encoding?
76
+ part = org.logstash.common.SourceWithMetadata.new("file", file, 0, 0, config_string)
58
77
  config_parts << part
59
78
  else
60
79
  encoding_issue_files << file
@@ -101,10 +120,6 @@ module LogStash module Config module Source
101
120
  all_files - get_matched_files
102
121
  end
103
122
 
104
- def valid_encoding?(content)
105
- content.ascii_only? && content.valid_encoding?
106
- end
107
-
108
123
  def temporary_file?(filepath)
109
124
  filepath.match(TEMPORARY_FILE_RE)
110
125
  end
@@ -121,7 +136,7 @@ module LogStash module Config module Source
121
136
  # since we have fetching config we wont follow any redirection.
122
137
  case response.code.to_i
123
138
  when 200
124
- [org.logstash.common.SourceWithMetadata.new(uri.scheme, uri.to_s, response.body)]
139
+ [org.logstash.common.SourceWithMetadata.new(uri.scheme, uri.to_s, 0, 0, response.body)]
125
140
  when 302
126
141
  raise LogStash::ConfigLoadingError, I18n.t("logstash.runner.configuration.fetch-failed", :path => uri.to_s, :message => "We don't follow redirection for remote configuration")
127
142
  when 404
@@ -139,17 +154,37 @@ module LogStash module Config module Source
139
154
 
140
155
  PIPELINE_ID = LogStash::SETTINGS.get("pipeline.id").to_sym
141
156
  HTTP_RE = /^http(s)?/
142
- INPUT_BLOCK_RE = /input *{/
143
- OUTPUT_BLOCK_RE = /output *{/
144
157
 
145
158
  def pipeline_configs
159
+ if config_conflict?
160
+ raise ConfigurationError, @conflict_messages.join(", ")
161
+ end
162
+ local_pipeline_configs
163
+ end
164
+
165
+ def match?
166
+ # see basic settings predicates and getters defined in the base class
167
+ (config_string? || config_path?) && !(modules_cli? || modules?) && !automatic_reload_with_config_string?
168
+ end
146
169
 
147
- if config_path? && config_string?
148
- raise ConfigurationError.new("Settings 'config.string' and 'path.config' can't be used simultaneously.")
149
- elsif !config_path? && !config_string?
150
- raise ConfigurationError.new("Either 'config.string' or 'path.config' must be set.")
170
+ def config_conflict?
171
+ @conflict_messages.clear
172
+
173
+ # Check if configuration auto-reload is used that -f is specified
174
+ if automatic_reload_with_config_string?
175
+ @conflict_messages << I18n.t("logstash.runner.reload-with-config-string")
176
+ end
177
+ # Check if both -f and -e are present
178
+ if config_string? && config_path?
179
+ @conflict_messages << I18n.t("logstash.runner.config-string-path-exclusive")
151
180
  end
152
181
 
182
+ @conflict_messages.any?
183
+ end
184
+
185
+ private
186
+
187
+ def local_pipeline_configs
153
188
  config_parts = if config_string?
154
189
  ConfigStringLoader.read(config_string)
155
190
  elsif local_config?
@@ -160,46 +195,13 @@ module LogStash module Config module Source
160
195
  []
161
196
  end
162
197
 
163
- return if config_parts.empty?
164
-
165
- add_missing_default_inputs_or_outputs(config_parts) if config_string?
198
+ return [] if config_parts.empty?
166
199
 
167
200
  [PipelineConfig.new(self.class, @settings.get("pipeline.id").to_sym, config_parts, @settings)]
168
201
  end
169
202
 
170
- def match?
171
- config_string? || config_path?
172
- end
173
-
174
- private
175
- # Make sure we have an input and at least 1 output
176
- # if its not the case we will add stdin and stdout
177
- # this is for backward compatibility reason
178
- def add_missing_default_inputs_or_outputs(config_parts)
179
- if !config_parts.any? { |part| INPUT_BLOCK_RE.match(part.text) }
180
- config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default input", LogStash::Config::Defaults.input)
181
- end
182
-
183
- # include a default stdout output if no outputs given
184
- if !config_parts.any? { |part| OUTPUT_BLOCK_RE.match(part.text) }
185
- config_parts << org.logstash.common.SourceWithMetadata.new(self.class.name, "default output", LogStash::Config::Defaults.output)
186
- end
187
- end
188
-
189
- def config_string
190
- @settings.get("config.string")
191
- end
192
-
193
- def config_string?
194
- !config_string.nil?
195
- end
196
-
197
- def config_path
198
- @settings.get("path.config")
199
- end
200
-
201
- def config_path?
202
- !config_path.nil? && !config_path.empty?
203
+ def automatic_reload_with_config_string?
204
+ config_reload_automatic? && !config_path? && config_string?
203
205
  end
204
206
 
205
207
  def local_config?
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ require "logstash/config/source/base"
3
+ require "logstash/config/modules_common"
4
+ require "logstash/config/pipeline_config"
5
+ require "logstash/util/loggable"
6
+ require "logstash/errors"
7
+
8
+ module LogStash module Config module Source
9
+ class Modules < Base
10
+ include LogStash::Util::Loggable
11
+ def pipeline_configs
12
+ if config_conflict? # double check
13
+ raise ConfigurationError, @conflict_messages.join(", ")
14
+ end
15
+
16
+ pipelines = LogStash::Config::ModulesCommon.pipeline_configs(@settings)
17
+ pipelines.map do |hash|
18
+ PipelineConfig.new(self, hash["pipeline_id"].to_sym,
19
+ org.logstash.common.SourceWithMetadata.new("module", hash["alt_name"], 0, 0, hash["config_string"]),
20
+ hash["settings"])
21
+ end
22
+ end
23
+
24
+ def match?
25
+ # see basic settings predicates and getters defined in the base class
26
+ (modules_cli? || modules?) && !(config_string? || config_path?) && !automatic_reload_with_modules?
27
+ end
28
+
29
+ def config_conflict?
30
+ @conflict_messages.clear
31
+ # Make note that if modules are configured in both cli and logstash.yml that cli module
32
+ # settings will overwrite the logstash.yml modules settings
33
+ if modules_cli? && modules?
34
+ logger.info(I18n.t("logstash.runner.cli-module-override"))
35
+ end
36
+
37
+ if automatic_reload_with_modules?
38
+ @conflict_messages << I18n.t("logstash.runner.reload-with-modules")
39
+ end
40
+
41
+ # Check if config (-f or -e) and modules are configured
42
+ if (modules_cli? || modules?) && (config_string? || config_path?)
43
+ @conflict_messages << I18n.t("logstash.runner.config-module-exclusive")
44
+ end
45
+
46
+ @conflict_messages.any?
47
+ end
48
+
49
+ private
50
+
51
+ def automatic_reload_with_modules?
52
+ (modules_cli? || modules?) && config_reload_automatic?
53
+ end
54
+ end
55
+ end end end
@@ -10,6 +10,7 @@ module LogStash module Config module Source
10
10
  def initialize(settings)
11
11
  @original_settings = settings
12
12
  super(settings)
13
+ @match_warning_done = false
13
14
  end
14
15
 
15
16
  def pipeline_configs
@@ -18,28 +19,48 @@ module LogStash module Config module Source
18
19
  ::LogStash::PipelineSettings.from_settings(@original_settings.clone).merge(pipeline_settings)
19
20
  end
20
21
  detect_duplicate_pipelines(pipelines_settings)
21
- pipelines_settings.map do |pipeline_settings|
22
+ pipeline_configs = pipelines_settings.map do |pipeline_settings|
22
23
  @settings = pipeline_settings
23
24
  # this relies on instance variable @settings and the parent class' pipeline_configs
24
25
  # method. The alternative is to refactor most of the Local source methods to accept
25
26
  # a settings object instead of relying on @settings.
26
- super # create a PipelineConfig object based on @settings
27
+ local_pipeline_configs # create a PipelineConfig object based on @settings
27
28
  end.flatten
29
+ @settings = @original_settings
30
+ pipeline_configs
28
31
  end
29
32
 
30
33
  def match?
31
- uses_config_string = @original_settings.get_setting("config.string").set?
32
- uses_path_config = @original_settings.get_setting("path.config").set?
33
- return true if !uses_config_string && !uses_path_config
34
- if uses_path_config
35
- logger.warn("Ignoring the 'pipelines.yml' file because 'path.config' (-f) is being used.")
36
- elsif uses_config_string
37
- logger.warn("Ignoring the 'pipelines.yml' file because 'config.string' (-e) is being used.")
34
+ detect_pipelines if !@detect_pipelines_called
35
+ # see basic settings predicates and getters defined in the base class
36
+ return !(invalid_pipelines_detected? || modules_cli? || modules? || config_string? || config_path?)
37
+ end
38
+
39
+ def invalid_pipelines_detected?
40
+ !@detected_marker || @detected_marker.is_a?(Class)
41
+ end
42
+
43
+ def config_conflict?
44
+ detect_pipelines if !@detect_pipelines_called
45
+ @conflict_messages.clear
46
+ # are there any auto-reload conflicts?
47
+ if !(modules_cli? || modules? || config_string? || config_path?)
48
+ if @detected_marker.nil?
49
+ @conflict_messages << I18n.t("logstash.runner.config-pipelines-failed-read", :path => pipelines_yaml_location)
50
+ elsif @detected_marker == false
51
+ @conflict_messages << I18n.t("logstash.runner.config-pipelines-empty", :path => pipelines_yaml_location)
52
+ elsif @detected_marker.is_a?(Class)
53
+ @conflict_messages << I18n.t("logstash.runner.config-pipelines-invalid", :invalid_class => @detected_marker, :path => pipelines_yaml_location)
54
+ end
55
+ else
56
+ do_warning? && logger.warn("Ignoring the 'pipelines.yml' file because modules or command line options are specified")
38
57
  end
39
- false
58
+ @conflict_messages.any?
40
59
  end
41
60
 
42
61
  def retrieve_yaml_pipelines
62
+ # by now, either the config_conflict? or the match? should have ruled out any config problems
63
+ # but we don't rely on this, we can still get IO errors or
43
64
  result = read_pipelines_from_yaml(pipelines_yaml_location)
44
65
  case result
45
66
  when Array
@@ -68,5 +89,28 @@ module LogStash module Config module Source
68
89
  raise ConfigurationError.new("Pipelines YAML file contains duplicate pipeline ids: #{duplicate_ids.inspect}. Location: #{pipelines_yaml_location}")
69
90
  end
70
91
  end
92
+
93
+ def detect_pipelines
94
+ result = read_pipelines_from_yaml(pipelines_yaml_location) rescue nil
95
+ if result.is_a?(Array)
96
+ @detected_marker = true
97
+ elsif result.nil?
98
+ @detected_marker = nil
99
+ elsif !result
100
+ @detected_marker = false
101
+ else
102
+ @detected_marker = result.class
103
+ end
104
+ @detect_pipelines_called = true
105
+ end
106
+
107
+ private
108
+
109
+ def do_warning?
110
+ if !(done = true && @match_warning_done)
111
+ @match_warning_done = true
112
+ end
113
+ !done
114
+ end
71
115
  end
72
116
  end end end
@@ -1,5 +1,6 @@
1
1
  # encoding: utf-8
2
2
  require "logstash/config/source/local"
3
+ require "logstash/config/source/modules"
3
4
  require "logstash/config/source/multi_local"
4
5
  require "logstash/errors"
5
6
  require "thread"
@@ -0,0 +1,27 @@
1
+
2
+
3
+ module LogStash; module Config; module StringEscape
4
+ class << self
5
+ def process_escapes(input)
6
+ input.gsub(/\\./) do |value|
7
+ process(value)
8
+ end
9
+ end
10
+
11
+ private
12
+ def process(value)
13
+ case value[1]
14
+ when '"', "'", "\\"
15
+ value[1]
16
+ when "n"
17
+ "\n"
18
+ when "r"
19
+ "\r"
20
+ when "t"
21
+ "\t"
22
+ else
23
+ value
24
+ end
25
+ end
26
+ end
27
+ end end end
@@ -0,0 +1,142 @@
1
+ # encoding: utf-8
2
+ require "logstash/namespace"
3
+ require "logstash/logging"
4
+ require "elasticsearch"
5
+ require "elasticsearch/transport/transport/http/manticore"
6
+
7
+ module LogStash class ElasticsearchClient
8
+ include LogStash::Util::Loggable
9
+
10
+ class Response
11
+ # duplicated here from Elasticsearch::Transport::Transport::Response
12
+ # to create a normalised response across different client IMPL
13
+ attr_reader :status, :body, :headers
14
+ def initialize(status, body, headers={})
15
+ @status, @body, @headers = status, body, headers
16
+ @body = body.force_encoding('UTF-8') if body.respond_to?(:force_encoding)
17
+ end
18
+ end
19
+
20
+ def self.build(settings)
21
+ new(RubyClient.new(settings, logger))
22
+ end
23
+
24
+ class RubyClient
25
+ def initialize(settings, logger)
26
+ @settings = settings
27
+ @logger = logger
28
+ @client_args = client_args
29
+
30
+ ssl_options = {}
31
+
32
+ if @settings["var.elasticsearch.ssl.enabled"] == "true"
33
+ ssl_options[:verify] = @settings.fetch("var.elasticsearch.ssl.verification_mode", true)
34
+ ssl_options[:ca_file] = @settings.fetch("var.elasticsearch.ssl.certificate_authority", nil)
35
+ ssl_options[:client_cert] = @settings.fetch("var.elasticsearch.ssl.certificate", nil)
36
+ ssl_options[:client_key] = @settings.fetch("var.elasticsearch.ssl.key", nil)
37
+ end
38
+
39
+ @client_args[:ssl] = ssl_options
40
+
41
+ username = @settings["var.elasticsearch.username"]
42
+ password = @settings["var.elasticsearch.password"]
43
+ if username
44
+ @client_args[:transport_options] = { :headers => { "Authorization" => 'Basic ' + Base64.encode64( "#{username}:#{password}" ).chomp } }
45
+ end
46
+
47
+ @client = Elasticsearch::Client.new(@client_args)
48
+ end
49
+
50
+ def can_connect?
51
+ begin
52
+ head(SecureRandom.hex(32).prepend('_'))
53
+ rescue Elasticsearch::Transport::Transport::Errors::BadRequest
54
+ true
55
+ rescue Manticore::SocketException
56
+ false
57
+ end
58
+ end
59
+
60
+ def host_settings
61
+ @client_args[:hosts]
62
+ end
63
+
64
+ def delete(path)
65
+ begin
66
+ normalize_response(@client.perform_request('DELETE', path, {}, nil))
67
+ rescue Exception => e
68
+ if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found|404/i
69
+ Response.new(404, "", {})
70
+ else
71
+ raise e
72
+ end
73
+ end
74
+ end
75
+
76
+ def put(path, content)
77
+ normalize_response(@client.perform_request('PUT', path, {}, content))
78
+ end
79
+
80
+ def head(path)
81
+ begin
82
+ normalize_response(@client.perform_request('HEAD', path, {}, nil))
83
+ rescue Exception => e
84
+ if is_404_error?(e)
85
+ Response.new(404, "", {})
86
+ else
87
+ raise e
88
+ end
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def is_404_error?(error)
95
+ error.class.to_s =~ /NotFound/ || error.message =~ /Not\s*Found|404/i
96
+ end
97
+
98
+ def normalize_response(response)
99
+ Response.new(response.status, response.body, response.headers)
100
+ end
101
+
102
+ def client_args
103
+ {
104
+ :transport_class => Elasticsearch::Transport::Transport::HTTP::Manticore,
105
+ :hosts => [*unpack_hosts],
106
+ # :logger => @logger, # silence the client logging
107
+ }
108
+ end
109
+
110
+ def unpack_hosts
111
+ setting = @settings.fetch("var.elasticsearch.hosts", "localhost:9200")
112
+ if setting.is_a?(String)
113
+ return setting.split(',').map(&:strip)
114
+ end
115
+ setting
116
+ end
117
+ end
118
+
119
+ def initialize(client)
120
+ @client = client
121
+ end
122
+
123
+ def delete(path)
124
+ @client.delete(path)
125
+ end
126
+
127
+ def put(path, content)
128
+ @client.put(path, content)
129
+ end
130
+
131
+ def head(path)
132
+ @client.head(path)
133
+ end
134
+
135
+ def can_connect?
136
+ @client.can_connect?
137
+ end
138
+
139
+ def host_settings
140
+ @client.host_settings
141
+ end
142
+ end end