logstash-integration-elastic_enterprise_search 2.1.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d1202fb961af64675edfe8d9deb5a5496a6883a4ba4f73de08b8c53229a78d8
4
- data.tar.gz: a69156a70dd56f29ad1ba16330b31e81725f03679f5ec7ed2b4bf0e6d3220ad0
3
+ metadata.gz: 2f0c1374a08bc723fd7452e115e7372c8e0bb416c6e7e2e6d10769b15b571b7c
4
+ data.tar.gz: 53debfd033dae11b5d5c80809c51c8a6db5997c80f5eeb3901414932c0d48e17
5
5
  SHA512:
6
- metadata.gz: 19e16ac5f649cb599b67394558a998393adf9d84331af212d7567f614b290832669aab601378ad7ca48472f3ab6bce1167e1edfa53bdcb378ae9435413fa8964
7
- data.tar.gz: 5ce52eb632f0897c9af62e53a02db844142b8864908da08dd6937328a635ded2c4cb11e18d0f9a1861a2f8c9aa04acb0c29d93386647e81b612ac03ec9c151b8
6
+ metadata.gz: dcb96b16bafc1b85a0e4e375925b8d6ad5e6f3366044e1ea13b4318ab0c5b75b84d342fe76077ddcc30f4b0423f0e47028b474d2012e34570357a07ad9ff94e8
7
+ data.tar.gz: fab4c000386cca49902de6f11aa392d95032b4fd7897826fc7515dac40012315c2356d1c624485b4689faf229b7455176845ac40cdf3c298e596ad517a545a93
data/CHANGELOG.md CHANGED
@@ -1,11 +1,26 @@
1
+ ## 2.2.1
2
+ - Fix, change implementation of connectivity check method to be compatible with version `v8.0+` of Workplace Search [#16](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/16)
3
+
4
+ ## 2.2.0
5
+ - Feature, switch the connection library to elastic-enterprise-search [#3](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/3)
6
+ - [DOC] Added required parameters to Workplace Search example snippet and describe little better what's expected in url parameter [#11](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/11)
7
+
8
+ ## 2.1.2
9
+ - [DOC] Fix typos in App Search and Workplace Search [#9](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/9)
10
+ - [DOC] Add links to Elastic App Search and Elastic Workplace Search solution pages [#10](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/9)
11
+
12
+ ## 2.1.1
13
+ - [DOC] Added the integration attribute and include statement for the integration plugin header to finalize hooking up integration docs [#8](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/8)
14
+ - [DOC] Added live link to output-elastic_workplace_search doc [#6](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/6)
15
+
1
16
  ## 2.1.0
2
- - Addition of Workplace Search Output plugin [#4](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/4)
3
- - [DOC] Updates output-elastic_app_search documentation to add an integration attribute and include the integration plugin header [#5](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/5)
17
+ - Addition of Workplace Search Output plugin [#4](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/4)
18
+ - [DOC] Added the integration attribute and include statement for the integration plugin header to output-elastic_app_search doc [#5](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/5)
4
19
 
5
20
 
6
21
  ## 2.0.0
7
- - Initial release of the Elastic EnterpriseSearch Integration Plugin, which carries the
8
- previous AppSearch Output plugin codebase;
9
- independent changelogs for previous versions can be found:
10
- - [AppSearch Output Plugin @1.2.0](https://github.com/logstash-plugins/logstash-output-elastic_app_search/blob/v1.2.0/CHANGELOG.md)
22
+ - Initial release of the Elastic EnterpriseSearch Integration Plugin, which carries the
23
+ previous AppSearch Output plugin codebase;
24
+ independent changelogs for previous versions can be found:
25
+ - [AppSearch Output Plugin @1.2.0](https://github.com/logstash-plugins/logstash-output-elastic_app_search/blob/v1.2.0/CHANGELOG.md)
11
26
 
data/DEVELOPER.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # logstash-integration-elastic_enterprise_search
2
- Elastic Enterprise Search integration for Logstash, including AppSearch and WorkplaceSearch output plugins
2
+ Elastic Enterprise Search integration for Logstash, including App Search and Workplace Search output plugins
3
3
 
4
4
  # Dependencies
5
- * elastic-app-search
5
+ * elastic-enterprise-search
6
+ * elastic-app-search
6
7
  * elastic-workplace-search
@@ -1,8 +1,12 @@
1
1
  # encoding: utf-8
2
2
  require "logstash/outputs/base"
3
3
  require "elastic-app-search"
4
+ require "elastic-enterprise-search"
5
+ require 'logstash/plugin_mixins/deprecation_logger_support'
4
6
 
5
7
  class LogStash::Outputs::ElasticAppSearch < LogStash::Outputs::Base
8
+ include LogStash::PluginMixins::DeprecationLoggerSupport
9
+
6
10
  config_name "elastic_app_search"
7
11
 
8
12
  # The name of the search engine you created in App Search, an information
@@ -49,16 +53,25 @@ class LogStash::Outputs::ElasticAppSearch < LogStash::Outputs::Base
49
53
 
50
54
  public
51
55
  def register
56
+ @use_old_client = false
52
57
  if @host.nil? && @url.nil?
53
58
  raise ::LogStash::ConfigurationError.new("Please specify either \"url\" (for self-managed) or \"host\" (for SaaS).")
54
59
  elsif @host && @url
55
- raise ::LogStash::ConfigurationError.new("Both \"url\" or \"host\" can't be set simultaneously. Please specify either \"url\" (for self-managed) or \"host\" (for SaaS).")
60
+ raise ::LogStash::ConfigurationError.new("Both \"url\" or \"host\" can't be set simultaneously. Please specify either \"url\" (for self-managed ot Elastic Enterprise Search) or \"host\" (for SaaS).")
56
61
  elsif @host && path_is_set? # because path has a default value we need extra work to if the user set it
57
62
  raise ::LogStash::ConfigurationError.new("The setting \"path\" is not compatible with \"host\". Use \"path\" only with \"url\".")
58
63
  elsif @host
64
+ @deprecation_logger.deprecated("Deprecated service usage, the `host` setting will be removed when Swiftype AppSearch service is shutdown")
65
+ @use_old_client = true
59
66
  @client = Elastic::AppSearch::Client.new(:host_identifier => @host, :api_key => @api_key.value)
60
67
  elsif @url
61
- @client = Elastic::AppSearch::Client.new(:api_endpoint => @url + @path, :api_key => @api_key.value)
68
+ if path_is_set?
69
+ @deprecation_logger.deprecated("Deprecated service usage, the `path` setting will be removed when Swiftype AppSearch service is shutdown")
70
+ @use_old_client = true
71
+ @client = Elastic::AppSearch::Client.new(:api_endpoint => @url + @path, :api_key => @api_key.value)
72
+ else
73
+ @client = Elastic::EnterpriseSearch::AppSearch::Client.new(:host => @url, :http_auth => @api_key.value, :external_url => @url)
74
+ end
62
75
  end
63
76
  check_connection! unless @engine =~ ENGINE_WITH_SPRINTF_REGEX
64
77
  rescue => e
@@ -77,7 +90,7 @@ class LogStash::Outputs::ElasticAppSearch < LogStash::Outputs::Base
77
90
  events.each_slice(100) do |events|
78
91
  batch = format_batch(events)
79
92
  if @logger.trace?
80
- @logger.trace("Sending bulk to AppSearch", :size => batch.size, :data => batch.inspect)
93
+ @logger.trace("Sending bulk to App Search", :size => batch.size, :data => batch.inspect)
81
94
  end
82
95
  index(batch)
83
96
  end
@@ -117,11 +130,15 @@ class LogStash::Outputs::ElasticAppSearch < LogStash::Outputs::Base
117
130
  if resolved_engine =~ ENGINE_WITH_SPRINTF_REGEX || resolved_engine =~ /^\s*$/
118
131
  raise "Cannot resolve engine field name #{@engine} from event"
119
132
  end
120
- response = @client.index_documents(resolved_engine, documents)
133
+ if connected_to_swiftype?
134
+ response = @client.index_documents(resolved_engine, documents)
135
+ else
136
+ response = @client.index_documents(resolved_engine, {:documents => documents})
137
+ end
121
138
  report(documents, response)
122
139
  rescue => e
123
140
  @logger.error("Failed to execute index operation. Retrying..", :exception => e.class, :reason => e.message,
124
- :resolved_engine => resolved_engine)
141
+ :resolved_engine => resolved_engine, :backtrace => e.backtrace)
125
142
  sleep(1)
126
143
  retry
127
144
  end
@@ -130,7 +147,11 @@ class LogStash::Outputs::ElasticAppSearch < LogStash::Outputs::Base
130
147
 
131
148
  def report(documents, response)
132
149
  documents.each_with_index do |document, i|
133
- errors = response[i]["errors"]
150
+ if connected_to_swiftype?
151
+ errors = response[i]["errors"]
152
+ else
153
+ errors = response.body[i]["errors"]
154
+ end
134
155
  if errors.empty?
135
156
  @logger.trace? && @logger.trace("Document was indexed with no errors", :document => document)
136
157
  else
@@ -140,10 +161,19 @@ class LogStash::Outputs::ElasticAppSearch < LogStash::Outputs::Base
140
161
  end
141
162
 
142
163
  def check_connection!
143
- @client.get_engine(@engine)
164
+ if connected_to_swiftype?
165
+ @client.get_engine(@engine)
166
+ else
167
+ res = @client.list_engines({:page_size => 1})
168
+ raise "Received HTTP error code #{res.status}" unless res.status == 200
169
+ end
144
170
  end
145
171
 
146
172
  def path_is_set?
147
173
  original_params.key?("path")
148
174
  end
175
+
176
+ def connected_to_swiftype?
177
+ @use_old_client
178
+ end
149
179
  end
@@ -101,6 +101,7 @@ class LogStash::Outputs::ElasticWorkplaceSearch < LogStash::Outputs::Base
101
101
  end
102
102
 
103
103
  def check_connection!
104
- @client.list_all_permissions(@source)
104
+ # This is the preferred way to check compatibility across different versions of Workplace Search service.
105
+ @client.index_documents(@source, {:documents => []})
105
106
  end
106
107
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-integration-elastic_enterprise_search'
3
- s.version = '2.1.0'
3
+ s.version = '2.2.1'
4
4
  s.licenses = ['Apache-2.0']
5
5
  s.summary = "Integration with Elastic Enterprise Search - output plugins"
6
6
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline "+
@@ -27,6 +27,8 @@ Gem::Specification.new do |s|
27
27
  s.add_runtime_dependency "logstash-core-plugin-api", "~> 2.0"
28
28
  s.add_runtime_dependency "logstash-codec-plain"
29
29
  s.add_runtime_dependency "elastic-app-search", '~>7.8.0'
30
+ s.add_runtime_dependency "elastic-enterprise-search", '~>7.16.0'
30
31
  s.add_runtime_dependency "elastic-workplace-search", '~>0.4.1'
32
+ s.add_runtime_dependency "logstash-mixin-deprecation_logger_support", '~>1.0'
31
33
  s.add_development_dependency "logstash-devutils"
32
34
  end
@@ -5,7 +5,7 @@ require "logstash/codecs/plain"
5
5
  require "logstash/event"
6
6
  require "json"
7
7
 
8
- describe "indexing against running AppSearch", :integration => true do
8
+ describe "indexing against running App Search", :integration => true do
9
9
 
10
10
  let(:engine_name) do
11
11
  (0...10).map { ('a'..'z').to_a[rand(26)] }.join
@@ -13,16 +13,16 @@ describe "indexing against running AppSearch", :integration => true do
13
13
 
14
14
  let(:config) do
15
15
  {
16
- "api_key" => ENV['APPSEARCH_PRIVATE_KEY'],
16
+ "api_key" => ENV['APP_SEARCH_PRIVATE_KEY'],
17
17
  "engine" => engine_name,
18
- "url" => "http://appsearch:3002"
18
+ "url" => "http://enterprise_search:3002"
19
19
  }
20
20
  end
21
21
 
22
22
  subject(:app_search_output) { LogStash::Outputs::ElasticAppSearch.new(config) }
23
23
 
24
24
  before(:each) do
25
- create_engine(engine_name, "http://appsearch:3002", ENV['APPSEARCH_PRIVATE_KEY'])
25
+ create_engine(engine_name, "http://enterprise_search:3002", ENV['APP_SEARCH_PRIVATE_KEY'])
26
26
  end
27
27
 
28
28
  private
@@ -37,8 +37,8 @@ describe "indexing against running AppSearch", :integration => true do
37
37
  describe "search and private keys are configured" do
38
38
  let(:api_key_settings) do
39
39
  {
40
- :private => ENV['APPSEARCH_PRIVATE_KEY'],
41
- :search => ENV['APPSEARCH_SEARCH_KEY']
40
+ :private => ENV['APP_SEARCH_PRIVATE_KEY'],
41
+ :search => ENV['APP_SEARCH_SEARCH_KEY']
42
42
  }
43
43
  end
44
44
 
@@ -51,9 +51,9 @@ describe "indexing against running AppSearch", :integration => true do
51
51
  describe "register" do
52
52
  let(:config) do
53
53
  {
54
- "api_key" => ENV['APPSEARCH_PRIVATE_KEY'],
54
+ "api_key" => ENV['APP_SEARCH_PRIVATE_KEY'],
55
55
  "engine" => "%{engine_name_field}",
56
- "url" => "http://appsearch:3002"
56
+ "url" => "http://enterprise_search:3002"
57
57
  }
58
58
  end
59
59
 
@@ -89,9 +89,9 @@ describe "indexing against running AppSearch", :integration => true do
89
89
  context "using sprintf-ed engine" do
90
90
  let(:config) do
91
91
  {
92
- "api_key" => ENV['APPSEARCH_PRIVATE_KEY'],
92
+ "api_key" => ENV['APP_SEARCH_PRIVATE_KEY'],
93
93
  "engine" => "%{engine_name_field}",
94
- "url" => "http://appsearch:3002"
94
+ "url" => "http://enterprise_search:3002"
95
95
  }
96
96
  end
97
97
 
@@ -134,15 +134,15 @@ describe "indexing against running AppSearch", :integration => true do
134
134
  context "multiple sprintf engines" do
135
135
  let(:config) do
136
136
  {
137
- "api_key" => ENV['APPSEARCH_PRIVATE_KEY'],
137
+ "api_key" => ENV['APP_SEARCH_PRIVATE_KEY'],
138
138
  "engine" => "%{engine_name_field}",
139
- "url" => "http://appsearch:3002"
139
+ "url" => "http://enterprise_search:3002"
140
140
  }
141
141
  end
142
142
 
143
143
  it "all should be indexed" do
144
- create_engine('testengin1', "http://appsearch:3002", ENV['APPSEARCH_PRIVATE_KEY'])
145
- create_engine('testengin2', "http://appsearch:3002", ENV['APPSEARCH_PRIVATE_KEY'])
144
+ create_engine('testengin1', "http://enterprise_search:3002", ENV['APP_SEARCH_PRIVATE_KEY'])
145
+ create_engine('testengin2', "http://enterprise_search:3002", ENV['APP_SEARCH_PRIVATE_KEY'])
146
146
  events = generate_events(100, 'testengin1')
147
147
  events += generate_events(100, 'testengin2')
148
148
  events.shuffle!
@@ -8,25 +8,68 @@ require "base64"
8
8
 
9
9
  describe "indexing against running Workplace Search", :integration => true do
10
10
 
11
- let(:url) { ENV['APPSEARCH_URL'] }
12
- let(:auth) { Base64.strict_encode64("#{ENV['APPSEARCH_USERNAME']}:#{ENV['AS_PASSWORD']}") }
11
+ def is_version7?
12
+ ENV['ELASTIC_STACK_VERSION'].strip.start_with?("7")
13
+ end
14
+
15
+ let(:url) { ENV['ENTERPRISE_SEARCH_URL'] }
16
+ let(:auth) { Base64.strict_encode64("#{ENV['ENTERPRISE_SEARCH_USERNAME']}:#{ENV['ENTERPRISE_SEARCH_PASSWORD']}")}
13
17
  let(:source) do
18
+ if is_version7?
19
+ response = Faraday.get(
20
+ "#{url}/api/ws/v1/whoami",
21
+ {"get_token" => true},
22
+ {"Content-Type" => "application/json",
23
+ "Accept" => "application/json",
24
+ "Authorization" => "Basic #{auth}"}
25
+ )
26
+ JSON.load(response.body)
27
+ else
28
+ # Workplace Search v8.0+ provides the api_tokens API to create or retrieve
29
+ # the key to be use as access_token
30
+ conn = Faraday.new(url: url)
31
+ conn.basic_auth(ENV['ENTERPRISE_SEARCH_USERNAME'], ENV['ENTERPRISE_SEARCH_PASSWORD'])
32
+ response = conn.post('/ws/org/api_tokens',
33
+ '{"name":"ls-integration-test-key"}',
34
+ {"Content-Type" => "application/json", "Accept" => "application/json"})
35
+ create_response_json = JSON.load(response.body)
36
+ if create_response_json.has_key?("errors") && create_response_json["errors"].include?("Name is already taken")
37
+ # when a key with the name already exists, retrieve it
38
+ response = conn.get('/ws/org/api_tokens', nil, {"Content-Type" => "application/json", "Accept" => "application/json"})
39
+ retrieve_token_response_json = JSON.load(response.body)
40
+ response_json = retrieve_token_response_json["results"].find {|res| res["id"] == "ls-integration-test-key"}
41
+ else
42
+ response_json = create_response_json
43
+ end
44
+
45
+ conn.close
46
+ response_json
47
+ end
48
+ end
49
+ let(:access_token) do
50
+ if is_version7?
51
+ source.fetch("access_token")
52
+ else
53
+ source.fetch("key")
54
+ end
55
+ end
56
+ let(:source_id) do
14
57
  response = Faraday.post(
15
- "#{url}/ws/org/sources/form_create",
16
- JSON.dump("service_type" => "custom", "name" => "whatever"),
17
- "Content-Type" => "application/json",
18
- "Accept" => "application/json",
19
- "Authorization" => "Basic #{auth}"
20
- )
21
- JSON.load(response.body)
58
+ "#{url}/api/ws/v1/sources",
59
+ JSON.dump("service_type" => "custom", "name" => "whatever"),
60
+ {"Content-Type" => "application/json",
61
+ "Accept" => "application/json",
62
+ "Authorization" => "Bearer #{access_token}"}
63
+ )
64
+ source_response_json = JSON.load(response.body)
65
+ source_response_json.fetch("id")
22
66
  end
23
- let(:source_id) { source.fetch("id") }
24
67
 
25
68
  let(:config) do
26
69
  {
27
70
  "url" => url,
28
71
  "source" => source_id,
29
- "access_token" => source.fetch("accessToken")
72
+ "access_token" => access_token
30
73
  }
31
74
  end
32
75
 
@@ -3,6 +3,7 @@ require "logstash/devutils/rspec/spec_helper"
3
3
  require "logstash/outputs/elastic_app_search"
4
4
  require "logstash/codecs/plain"
5
5
  require "logstash/event"
6
+ require "elastic-app-search"
6
7
 
7
8
  describe LogStash::Outputs::ElasticAppSearch do
8
9
  let(:sample_event) { LogStash::Event.new }
@@ -20,6 +21,19 @@ describe LogStash::Outputs::ElasticAppSearch do
20
21
  it "does not raise an error" do
21
22
  expect { subject.register }.to_not raise_error
22
23
  end
24
+ it "configures the Swiftype client" do
25
+ subject.register
26
+ client = subject.instance_variable_get(:@client)
27
+ expect(client.class).to eq(Elastic::AppSearch::Client)
28
+ end
29
+ end
30
+ context "when path is configured" do
31
+ let(:config) { { "api_key" => api_key, "engine" => engine, "path" => "/v1", "url" => "http://localhost:9300" } }
32
+ it "configures the Swiftype client" do
33
+ subject.register
34
+ client = subject.instance_variable_get(:@client)
35
+ expect(client.class).to eq(Elastic::AppSearch::Client)
36
+ end
23
37
  end
24
38
  context "when host and path is configured" do
25
39
  let(:config) { { "host" => host, "api_key" => api_key, "engine" => engine, "path" => "/v1" } }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-integration-elastic_enterprise_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-18 00:00:00.000000000 Z
11
+ date: 2022-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 7.8.0
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 7.16.0
61
+ name: elastic-enterprise-search
62
+ prerelease: false
63
+ type: :runtime
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 7.16.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  requirement: !ruby/object:Gem::Requirement
57
71
  requirements:
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: 0.4.1
83
+ - !ruby/object:Gem::Dependency
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.0'
89
+ name: logstash-mixin-deprecation_logger_support
90
+ prerelease: false
91
+ type: :runtime
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  requirement: !ruby/object:Gem::Requirement
71
99
  requirements:
@@ -124,8 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
152
  - !ruby/object:Gem::Version
125
153
  version: '0'
126
154
  requirements: []
127
- rubyforge_project:
128
- rubygems_version: 2.6.13
155
+ rubygems_version: 3.1.6
129
156
  signing_key:
130
157
  specification_version: 4
131
158
  summary: Integration with Elastic Enterprise Search - output plugins