elasticsearch 5.0.3 → 7.17.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/elasticsearch.rb CHANGED
@@ -1,12 +1,116 @@
1
- require "elasticsearch/version"
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
2
17
 
18
+ require 'elasticsearch/version'
3
19
  require 'elasticsearch/transport'
4
20
  require 'elasticsearch/api'
5
21
 
6
22
  module Elasticsearch
7
- module Transport
8
- class Client
9
- include Elasticsearch::API
23
+ SECURITY_PRIVILEGES_VALIDATION_WARNING = 'The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.'.freeze
24
+ NOT_ELASTICSEARCH_WARNING = 'The client noticed that the server is not Elasticsearch and we do not support this unknown product.'.freeze
25
+ NOT_SUPPORTED_ELASTICSEARCH_WARNING = 'The client noticed that the server is not a supported distribution of Elasticsearch.'.freeze
26
+ YOU_KNOW_FOR_SEARCH = 'You Know, for Search'.freeze
27
+
28
+ class Client
29
+ include Elasticsearch::API
30
+ attr_accessor :transport
31
+
32
+ # See Elasticsearch::Transport::Client for initializer parameters
33
+ def initialize(arguments = {}, &block)
34
+ @verified = false
35
+ @transport = Elasticsearch::Transport::Client.new(arguments, &block)
36
+ end
37
+
38
+ def method_missing(name, *args, &block)
39
+ if name == :perform_request
40
+ verify_elasticsearch unless @verified
41
+ @transport.perform_request(*args, &block)
42
+ else
43
+ super
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def verify_elasticsearch
50
+ begin
51
+ response = elasticsearch_validation_request
52
+ rescue Elasticsearch::Transport::Transport::Errors::Unauthorized,
53
+ Elasticsearch::Transport::Transport::Errors::Forbidden,
54
+ Elasticsearch::Transport::Transport::Errors::RequestEntityTooLarge
55
+ @verified = true
56
+ warn(SECURITY_PRIVILEGES_VALIDATION_WARNING)
57
+ return
58
+ end
59
+
60
+ body = if response.headers['content-type'] == 'application/yaml'
61
+ require 'yaml'
62
+ YAML.safe_load(response.body)
63
+ else
64
+ response.body
65
+ end
66
+ version = body.dig('version', 'number')
67
+ verify_with_version_or_header(body, version, response.headers)
68
+ end
69
+
70
+ def verify_with_version_or_header(body, version, headers)
71
+ raise Elasticsearch::UnsupportedProductError if version.nil? || version < '6.0.0'
72
+
73
+ if version == '7.x-SNAPSHOT' || Gem::Version.new(version) >= Gem::Version.new('7.14-SNAPSHOT')
74
+ raise Elasticsearch::UnsupportedProductError unless headers['x-elastic-product'] == 'Elasticsearch'
75
+
76
+ @verified = true
77
+ elsif Gem::Version.new(version) > Gem::Version.new('6.0.0') &&
78
+ Gem::Version.new(version) < Gem::Version.new('7.0.0')
79
+ raise Elasticsearch::UnsupportedProductError unless
80
+ body['tagline'] == YOU_KNOW_FOR_SEARCH
81
+
82
+ @verified = true
83
+ elsif Gem::Version.new(version) >= Gem::Version.new('7.0.0') &&
84
+ Gem::Version.new(version) < Gem::Version.new('7.14-SNAPSHOT')
85
+ raise Elasticsearch::UnsupportedProductError unless body['tagline'] == YOU_KNOW_FOR_SEARCH
86
+ raise Elasticsearch::UnsupportedProductError.new(NOT_SUPPORTED_ELASTICSEARCH_WARNING) unless body.dig('version', 'build_flavor') == 'default'
87
+
88
+ @verified = true
89
+ end
90
+ end
91
+
92
+ def elasticsearch_validation_request
93
+ @transport.perform_request('GET', '/')
94
+ end
95
+ end
96
+
97
+ class UnsupportedProductError < StandardError
98
+ def initialize(message = NOT_ELASTICSEARCH_WARNING)
99
+ super(message)
10
100
  end
11
101
  end
12
102
  end
103
+
104
+ module Elastic
105
+ # If the version is X.X.X.pre/alpha/beta, use X.X.Xp for the meta-header:
106
+ def self.client_meta_version
107
+ regexp = /^([0-9]+\.[0-9]+\.[0-9]+)\.?([a-z0-9.-]+)?$/
108
+ match = Elasticsearch::VERSION.match(regexp)
109
+ return "#{match[1]}p" if match[2]
110
+
111
+ Elasticsearch::VERSION
112
+ end
113
+
114
+ # Constant for elasticsearch-transport meta-header
115
+ ELASTICSEARCH_SERVICE_VERSION = [:es, client_meta_version].freeze
116
+ end
@@ -0,0 +1,94 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+ ELASTICSEARCH_URL = ENV['TEST_ES_SERVER'] || "http://localhost:#{(ENV['PORT'] || 9200)}"
18
+ raise URI::InvalidURIError unless ELASTICSEARCH_URL =~ /\A#{URI::DEFAULT_PARSER.make_regexp}\z/
19
+
20
+ require 'spec_helper'
21
+
22
+ context 'Elasticsearch client' do
23
+ let(:client) do
24
+ Elasticsearch::Client.new(host: ELASTICSEARCH_URL, user: 'elastic', password: 'changeme')
25
+ end
26
+ let(:index) { 'tvs' }
27
+
28
+ after do
29
+ client.indices.delete(index: index)
30
+ end
31
+
32
+ context 'escaping spaces in ids' do
33
+ it 'escapes spaces for id when using index' do
34
+ response = client.index(index: index, id: 'a test 1', body: { name: 'A test 1' }, refresh: true)
35
+ expect(response['_id']).to eq 'a test 1'
36
+
37
+ response = client.search(index: index)
38
+ expect(response['hits']['hits'].first['_id']).to eq 'a test 1'
39
+
40
+ # Raises exception, _id is unrecognized
41
+ expect do
42
+ client.index(index: index, _id: 'a test 2', body: { name: 'A test 2' })
43
+ end.to raise_exception ArgumentError
44
+
45
+ # Raises exception, id is a query parameter
46
+ expect do
47
+ client.index(index: index, body: { name: 'A test 3', _id: 'a test 3' })
48
+ end.to raise_exception Elasticsearch::Transport::Transport::Errors::BadRequest
49
+ end
50
+
51
+ it 'escapes spaces for id when using create' do
52
+ # Works with create
53
+ response = client.create(index: index, id: 'a test 4', body: { name: 'A test 4' })
54
+ expect(response['_id']).to eq 'a test 4'
55
+ end
56
+
57
+ it 'escapes spaces for id when using bulk' do
58
+ body = [
59
+ { create: { _index: index, _id: 'a test 5', data: { name: 'A test 5' } } }
60
+ ]
61
+ expect(client.bulk(body: body, refresh: true))
62
+
63
+ response = client.search(index: index)
64
+ expect(
65
+ response['hits']['hits'].select { |a| a['_id'] == 'a test 5' }.size
66
+ ).to eq 1
67
+ end
68
+ end
69
+
70
+ context 'it doesnae escape plus signs in id' do
71
+ it 'escapes spaces for id when using index' do
72
+ response = client.index(index: index, id: 'a+test+1', body: { name: 'A test 1' })
73
+ expect(response['_id']).to eq 'a+test+1'
74
+ end
75
+
76
+ it 'escapes spaces for id when using create' do
77
+ # Works with create
78
+ response = client.create(index: index, id: 'a+test+2', body: { name: 'A test 2' })
79
+ expect(response['_id']).to eq 'a+test+2'
80
+ end
81
+
82
+ it 'escapes spaces for id when using bulk' do
83
+ body = [
84
+ { create: { _index: index, _id: 'a+test+3', data: { name: 'A test 3' } } }
85
+ ]
86
+ expect(client.bulk(body: body, refresh: true))
87
+
88
+ response = client.search(index: index)
89
+ expect(
90
+ response['hits']['hits'].select { |a| a['_id'] == 'a+test+3' }.size
91
+ ).to eq 1
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,57 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+ require 'spec_helper'
18
+ require 'logger'
19
+
20
+ context 'Elasticsearch client' do
21
+ let(:logger) { Logger.new($stderr) }
22
+
23
+ let(:client) do
24
+ Elasticsearch::Client.new(
25
+ host: ELASTICSEARCH_URL,
26
+ logger: logger
27
+ )
28
+ end
29
+
30
+ context 'Integrates with elasticsearch API' do
31
+ it 'should perform the API methods' do
32
+ expect do
33
+ # Index a document
34
+ client.index(index: 'test-index', id: '1', body: { title: 'Test' })
35
+
36
+ # Refresh the index
37
+ client.indices.refresh(index: 'test-index')
38
+
39
+ # Search
40
+ response = client.search(index: 'test-index', body: { query: { match: { title: 'test' } } })
41
+
42
+ expect(response['hits']['total']['value']).to eq 1
43
+ expect(response['hits']['hits'][0]['_source']['title']).to eq 'Test'
44
+
45
+ # Delete the index
46
+ client.indices.delete(index: 'test-index')
47
+ end.not_to raise_error
48
+ end
49
+ end
50
+
51
+ context 'Reports the right meta header' do
52
+ it 'Reports es service name and gem version' do
53
+ headers = client.transport.transport.connections.first.connection.headers
54
+ expect(headers['x-elastic-client-meta']).to match Elastic.client_meta_version
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,30 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+ require 'spec_helper'
18
+ require 'logger'
19
+
20
+ describe 'Elasticsearch validation integration' do
21
+ it 'Validates for Elasticsearch > 7.14' do
22
+ client = Elasticsearch::Client.new(
23
+ host: ELASTICSEARCH_URL,
24
+ logger: Logger.new($stderr)
25
+ )
26
+ expect(client.instance_variable_get('@verified')).to be false
27
+ client.count
28
+ expect(client.instance_variable_get('@verified')).to be true
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ require 'elasticsearch'
19
+ require 'rspec'
20
+
21
+ ELASTICSEARCH_URL = ENV['TEST_ES_SERVER'] || "http://localhost:#{(ENV['PORT'] || 9200)}"
22
+ raise URI::InvalidURIError unless ELASTICSEARCH_URL =~ /\A#{URI::DEFAULT_PARSER.make_regexp}\z/
23
+
24
+ RSpec.configure do |config|
25
+ config.formatter = :documentation
26
+ end