elastic_search_framework 2.0.0 → 2.3.1
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/elastic_search_framework.rb +1 -0
- data/lib/elastic_search_framework/index.rb +13 -10
- data/lib/elastic_search_framework/index_alias.rb +146 -0
- data/lib/elastic_search_framework/repository.rb +10 -7
- data/lib/elastic_search_framework/version.rb +1 -1
- data/spec/elastic_search_framework/index_alias_spec.rb +160 -0
- data/spec/elastic_search_framework/index_spec.rb +27 -5
- data/spec/elastic_search_framework/repository_spec.rb +34 -16
- data/spec/example_index.rb +2 -0
- data/spec/example_index_2.rb +31 -0
- data/spec/example_index_alias.rb +17 -0
- data/spec/example_index_alias_2.rb +8 -0
- data/spec/spec_helper.rb +3 -0
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 660bab65bf91d16e1788d6f43c47e979ab70d6367b6d964c5db5edb2fd94405e
|
4
|
+
data.tar.gz: 6132de6d0f951d36382e1d5023eb1b22240b66df004192f291434dae80284ff4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35187a0efc4484e04f90db902db59fe7f599e83986ff16621c8b554bcc35c0d54167fc8663e11bb53d8048088707e31bf3fc191f5dcb970eaa244ebe7daeed7b
|
7
|
+
data.tar.gz: 82da0e555366738552a4bb4c522e0c6a4d31d83e82e3f4774851d2fc0ac72f291bcf351aa0e2012e31cfaf3058be8b9b1d1cacf8750ec85da5b84db72b89e5f9
|
@@ -8,6 +8,7 @@ require_relative 'elastic_search_framework/logger'
|
|
8
8
|
require_relative 'elastic_search_framework/exceptions'
|
9
9
|
require_relative 'elastic_search_framework/repository'
|
10
10
|
require_relative 'elastic_search_framework/index'
|
11
|
+
require_relative 'elastic_search_framework/index_alias'
|
11
12
|
require_relative 'elastic_search_framework/query'
|
12
13
|
|
13
14
|
module ElasticSearchFramework
|
@@ -2,14 +2,19 @@ module ElasticSearchFramework
|
|
2
2
|
module Index
|
3
3
|
attr_accessor :index_settings
|
4
4
|
|
5
|
-
def index(name:)
|
5
|
+
def index(name:, version: nil)
|
6
6
|
unless instance_variable_defined?(:@elastic_search_index_def)
|
7
|
-
instance_variable_set(:@elastic_search_index_def, name: "#{name}")
|
7
|
+
instance_variable_set(:@elastic_search_index_def, name: "#{name}#{version}")
|
8
|
+
instance_variable_set(:@elastic_search_index_version, version: version) unless version.nil?
|
8
9
|
else
|
9
10
|
raise ElasticSearchFramework::Exceptions::IndexError.new("[#{self.class}] - Duplicate index description. Name: #{name}.")
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
14
|
+
def version
|
15
|
+
instance_variable_defined?(:@elastic_search_index_version) ? instance_variable_get(:@elastic_search_index_version) : 0
|
16
|
+
end
|
17
|
+
|
13
18
|
def id(field)
|
14
19
|
unless instance_variable_defined?(:@elastic_search_index_id)
|
15
20
|
instance_variable_set(:@elastic_search_index_id, field)
|
@@ -102,11 +107,9 @@ module ElasticSearchFramework
|
|
102
107
|
|
103
108
|
def settings(name:, type: nil, value:)
|
104
109
|
self.index_settings = {} if index_settings.nil?
|
105
|
-
index_settings[name] = if
|
106
|
-
|
107
|
-
|
108
|
-
value
|
109
|
-
end
|
110
|
+
index_settings[name] = {} if index_settings[name].nil?
|
111
|
+
return index_settings[name][type] = value if type
|
112
|
+
index_settings[name] = value
|
110
113
|
end
|
111
114
|
|
112
115
|
def create_payload
|
@@ -162,15 +165,15 @@ module ElasticSearchFramework
|
|
162
165
|
end
|
163
166
|
|
164
167
|
def repository
|
165
|
-
ElasticSearchFramework::Repository.new
|
168
|
+
@repository ||= ElasticSearchFramework::Repository.new
|
166
169
|
end
|
167
170
|
|
168
171
|
def get_item(id:, type: 'default')
|
169
172
|
repository.get(index: self, id: id, type: type)
|
170
173
|
end
|
171
174
|
|
172
|
-
def put_item(type: 'default', item:)
|
173
|
-
repository.set(entity: item, index: self, type: type)
|
175
|
+
def put_item(type: 'default', item:, op_type: 'index')
|
176
|
+
repository.set(entity: item, index: self, type: type, op_type: op_type)
|
174
177
|
end
|
175
178
|
|
176
179
|
def delete_item(id:, type: 'default')
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module ElasticSearchFramework
|
2
|
+
module IndexAlias
|
3
|
+
def index(klass, active:)
|
4
|
+
unless instance_variable_defined?(:@elastic_search_indexes)
|
5
|
+
instance_variable_set(:@elastic_search_indexes, [])
|
6
|
+
end
|
7
|
+
indexes = self.instance_variable_get(:@elastic_search_indexes)
|
8
|
+
indexes << {klass: klass, active: active}
|
9
|
+
instance_variable_set(:@elastic_search_indexes, indexes)
|
10
|
+
end
|
11
|
+
|
12
|
+
def indexes
|
13
|
+
self.instance_variable_get(:@elastic_search_indexes)
|
14
|
+
end
|
15
|
+
|
16
|
+
def name(name)
|
17
|
+
unless instance_variable_defined?(:@elastic_search_index_alias_name)
|
18
|
+
instance_variable_set(:@elastic_search_index_alias_name, "#{name}")
|
19
|
+
else
|
20
|
+
raise ElasticSearchFramework::Exceptions::IndexError.new("[#{self.class}] - Duplicate index alias name: #{name}.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid?
|
25
|
+
indexes.select { |i| i[:active] == true }.length == 1
|
26
|
+
end
|
27
|
+
|
28
|
+
def create
|
29
|
+
if !valid?
|
30
|
+
raise ElasticSearchFramework::Exceptions::IndexError.new("[#{self.class}] - Invalid Index alias.")
|
31
|
+
end
|
32
|
+
|
33
|
+
uri = URI("#{host}/_aliases")
|
34
|
+
|
35
|
+
payload = {
|
36
|
+
actions: [],
|
37
|
+
}
|
38
|
+
|
39
|
+
indexes.each do |index|
|
40
|
+
action = nil
|
41
|
+
if exists?(index: index[:klass])
|
42
|
+
action = "remove" if !index[:active]
|
43
|
+
else
|
44
|
+
action = "add" if index[:active]
|
45
|
+
end
|
46
|
+
next if action.nil?
|
47
|
+
|
48
|
+
payload[:actions] << {action => {index: index[:klass].full_name, alias: self.full_name}}
|
49
|
+
end
|
50
|
+
|
51
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
52
|
+
request.body = JSON.dump(payload)
|
53
|
+
request.content_type = "application/json"
|
54
|
+
|
55
|
+
response = repository.with_client do |client|
|
56
|
+
client.request(request)
|
57
|
+
end
|
58
|
+
|
59
|
+
is_valid_response?(response.code) || Integer(response.code) == 404
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete
|
63
|
+
uri = URI("#{host}/_all/_aliases/#{full_name}")
|
64
|
+
|
65
|
+
request = Net::HTTP::Delete.new(uri.request_uri)
|
66
|
+
|
67
|
+
response = repository.with_client do |client|
|
68
|
+
client.request(request)
|
69
|
+
end
|
70
|
+
|
71
|
+
is_valid_response?(response.code) || Integer(response.code) == 404
|
72
|
+
end
|
73
|
+
|
74
|
+
def exists?(index:)
|
75
|
+
uri = URI("#{host}/#{index.full_name}/_alias/#{full_name}")
|
76
|
+
|
77
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
78
|
+
|
79
|
+
response = repository.with_client do |client|
|
80
|
+
client.request(request)
|
81
|
+
end
|
82
|
+
|
83
|
+
return false if response.code == "404"
|
84
|
+
|
85
|
+
result = nil
|
86
|
+
if is_valid_response?(response.code)
|
87
|
+
result = JSON.parse(response.body)
|
88
|
+
end
|
89
|
+
|
90
|
+
return true if !result.nil? && result[index.full_name]["aliases"] != nil
|
91
|
+
return false
|
92
|
+
end
|
93
|
+
|
94
|
+
def is_valid_response?(code)
|
95
|
+
[200, 201, 202].include?(Integer(code))
|
96
|
+
end
|
97
|
+
|
98
|
+
def full_name
|
99
|
+
name = instance_variable_get(:@elastic_search_index_alias_name)
|
100
|
+
if ElasticSearchFramework.namespace != nil
|
101
|
+
"#{ElasticSearchFramework.namespace}#{ElasticSearchFramework.namespace_delimiter}#{name.downcase}"
|
102
|
+
else
|
103
|
+
name.downcase
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def description
|
108
|
+
index = indexes.last[:klass]
|
109
|
+
hash = index.instance_variable_get(:@elastic_search_index_def)
|
110
|
+
if index.instance_variable_defined?(:@elastic_search_index_id)
|
111
|
+
hash[:id] = index.instance_variable_get(:@elastic_search_index_id)
|
112
|
+
else
|
113
|
+
hash[:id] = :id
|
114
|
+
end
|
115
|
+
hash
|
116
|
+
end
|
117
|
+
|
118
|
+
def host
|
119
|
+
"#{ElasticSearchFramework.host}:#{ElasticSearchFramework.port}"
|
120
|
+
end
|
121
|
+
|
122
|
+
def repository
|
123
|
+
@repository ||= ElasticSearchFramework::Repository.new
|
124
|
+
end
|
125
|
+
|
126
|
+
def get_item(id:, type: "default")
|
127
|
+
repository.get(index: self, id: id, type: type)
|
128
|
+
end
|
129
|
+
|
130
|
+
def put_item(type: "default", item:, op_type: 'index')
|
131
|
+
indexes.each do |index|
|
132
|
+
repository.set(entity: item, index: index[:klass], type: type, op_type: op_type)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def delete_item(id:, type: "default")
|
137
|
+
indexes.each do |index|
|
138
|
+
repository.drop(index: index[:klass], id: id, type: type)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def query
|
143
|
+
ElasticSearchFramework::Query.new(index: self)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module ElasticSearchFramework
|
2
2
|
class Repository
|
3
3
|
|
4
|
-
def set(index:, entity:, type: 'default')
|
5
|
-
uri = URI("#{host}/#{index.full_name}/#{type.downcase}/#{get_id_value(index: index, entity: entity)}")
|
4
|
+
def set(index:, entity:, type: 'default', op_type: 'index')
|
5
|
+
uri = URI("#{host}/#{index.full_name}/#{type.downcase}/#{get_id_value(index: index, entity: entity)}?op_type=#{op_type}")
|
6
6
|
hash = hash_helper.to_hash(entity)
|
7
7
|
|
8
8
|
request = Net::HTTP::Put.new(uri.request_uri)
|
@@ -13,12 +13,15 @@ module ElasticSearchFramework
|
|
13
13
|
client.request(request)
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
if valid_response?(response.code)
|
17
|
+
return true
|
18
|
+
elsif op_type == 'create' && Integer(response.code) == 409
|
19
|
+
return true
|
20
|
+
else
|
17
21
|
raise ElasticSearchFramework::Exceptions::IndexError.new(
|
18
22
|
"An error occurred setting an index document. Response: #{response.body} | Code: #{response.code}"
|
19
23
|
)
|
20
24
|
end
|
21
|
-
return true
|
22
25
|
end
|
23
26
|
|
24
27
|
def get(index:, id:, type: 'default')
|
@@ -114,15 +117,15 @@ module ElasticSearchFramework
|
|
114
117
|
end
|
115
118
|
|
116
119
|
def idle_timeout
|
117
|
-
@idle_timeout ||= Integer(ENV['CONNECTION_IDLE_TIMEOUT'] ||
|
120
|
+
@idle_timeout ||= Integer(ENV['CONNECTION_IDLE_TIMEOUT'] || 5)
|
118
121
|
end
|
119
122
|
|
120
123
|
def read_timeout
|
121
|
-
@read_timeout ||= Integer(ENV['CONNECTION_READ_TIMEOUT'] ||
|
124
|
+
@read_timeout ||= Integer(ENV['CONNECTION_READ_TIMEOUT'] || 5)
|
122
125
|
end
|
123
126
|
|
124
127
|
def open_timeout
|
125
|
-
@
|
128
|
+
@open_timeout ||= Integer(ENV['CONNECTION_OPEN_TIMEOUT'] || 1)
|
126
129
|
end
|
127
130
|
|
128
131
|
def valid_response?(status)
|
@@ -0,0 +1,160 @@
|
|
1
|
+
RSpec.describe ElasticSearchFramework::Index do
|
2
|
+
describe '#full_name' do
|
3
|
+
let(:namespace) { 'uat' }
|
4
|
+
let(:namespace_delimiter) { '.' }
|
5
|
+
before do
|
6
|
+
ElasticSearchFramework.namespace = namespace
|
7
|
+
ElasticSearchFramework.namespace_delimiter = namespace_delimiter
|
8
|
+
end
|
9
|
+
it 'should return the full index name including namespace and delimiter' do
|
10
|
+
expect(ExampleIndexAlias.full_name).to eq "#{ElasticSearchFramework.namespace}#{ElasticSearchFramework.namespace_delimiter}example"
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when the namespace is nil' do
|
14
|
+
before { ElasticSearchFramework.namespace = nil }
|
15
|
+
|
16
|
+
it 'returns the description name downcased' do
|
17
|
+
expect(ExampleIndexAlias.full_name).to eq 'example'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#valid?' do
|
23
|
+
context 'for a valid index definition' do
|
24
|
+
it 'should return true' do
|
25
|
+
expect(ExampleIndexAlias.valid?).to be true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
context 'for an invalid index definition' do
|
29
|
+
it 'should return true' do
|
30
|
+
expect(InvalidIndexAlias.valid?).to be false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#create' do
|
36
|
+
context 'when alias is valid and does not exist' do
|
37
|
+
before do
|
38
|
+
ExampleIndexAlias.delete
|
39
|
+
ExampleIndex.delete if ExampleIndex.exists?
|
40
|
+
ExampleIndex.create
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'creates an alias for the active index' do
|
44
|
+
expect(ExampleIndexAlias.exists?(index: ExampleIndex)).to be false
|
45
|
+
ExampleIndexAlias.create
|
46
|
+
expect(ExampleIndexAlias.exists?(index: ExampleIndex)).to be true
|
47
|
+
end
|
48
|
+
|
49
|
+
after do
|
50
|
+
ExampleIndexAlias.delete
|
51
|
+
ExampleIndex.delete
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when alias is not valid' do
|
56
|
+
before { allow(ExampleIndexAlias).to receive(:valid?).and_return(false) }
|
57
|
+
|
58
|
+
it 'raises an error' do
|
59
|
+
expect(ExampleIndexAlias.exists?(index: ExampleIndex)).to be false
|
60
|
+
expect { ExampleIndexAlias.create }.to raise_error(
|
61
|
+
ElasticSearchFramework::Exceptions::IndexError
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when alias is valid but already exists' do
|
67
|
+
before do
|
68
|
+
ExampleIndex.delete if ExampleIndex.exists?
|
69
|
+
ExampleIndex.create
|
70
|
+
ExampleIndexAlias.create
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'does not try to create a new alias' do
|
74
|
+
ExampleIndexAlias.create
|
75
|
+
end
|
76
|
+
|
77
|
+
after do
|
78
|
+
ExampleIndexAlias.delete
|
79
|
+
ExampleIndex.delete
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when alias is valid and does not exist and requires updating' do
|
84
|
+
before do
|
85
|
+
ExampleIndexAlias.delete
|
86
|
+
ExampleIndex.delete if ExampleIndex.exists?
|
87
|
+
ExampleIndex2.delete if ExampleIndex2.exists?
|
88
|
+
ExampleIndex.create
|
89
|
+
ExampleIndex2.create
|
90
|
+
ExampleIndexAlias.create
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'modifies the alias to the active index' do
|
94
|
+
expect(ExampleIndexAlias.exists?(index: ExampleIndex)).to be true
|
95
|
+
ExampleIndexAlias2.create
|
96
|
+
expect(ExampleIndexAlias.exists?(index: ExampleIndex)).to be false
|
97
|
+
expect(ExampleIndexAlias2.exists?(index: ExampleIndex2)).to be true
|
98
|
+
end
|
99
|
+
|
100
|
+
after do
|
101
|
+
ExampleIndexAlias.delete
|
102
|
+
ExampleIndex.delete
|
103
|
+
ExampleIndex2.delete
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#get_item' do
|
109
|
+
let(:id) { 10 }
|
110
|
+
let(:type) { 'default' }
|
111
|
+
it 'should call get on the repository' do
|
112
|
+
expect(ExampleIndexAlias.repository).to receive(:get).with(index: ExampleIndexAlias, id: id, type: type).once
|
113
|
+
ExampleIndexAlias.get_item(id: id, type: type)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#put_item' do
|
118
|
+
let(:id) { 10 }
|
119
|
+
let(:type) { 'default' }
|
120
|
+
let(:item) do
|
121
|
+
TestItem.new.tap do |i|
|
122
|
+
i.id = id
|
123
|
+
i.name = 'abc'
|
124
|
+
i.timestamp = Time.now.to_i
|
125
|
+
i.number = 5
|
126
|
+
end
|
127
|
+
end
|
128
|
+
context 'without specifying op_type' do
|
129
|
+
it 'should call set on the repository for each index of the alias with default op_type (index)' do
|
130
|
+
expect(ExampleIndexAlias.repository).to receive(:set).with(entity: item, index: ExampleIndex, type: type, op_type: 'index').once
|
131
|
+
expect(ExampleIndexAlias.repository).to receive(:set).with(entity: item, index: ExampleIndex2, type: type, op_type: 'index').once
|
132
|
+
ExampleIndexAlias.put_item(type: type, item: item)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with specified op_type' do
|
137
|
+
it 'should call set on the repository for each index of the alias with supplied op_type (index)' do
|
138
|
+
expect(ExampleIndexAlias.repository).to receive(:set).with(entity: item, index: ExampleIndex, type: type, op_type: 'index').once
|
139
|
+
expect(ExampleIndexAlias.repository).to receive(:set).with(entity: item, index: ExampleIndex2, type: type, op_type: 'index').once
|
140
|
+
ExampleIndexAlias.put_item(type: type, item: item, op_type: 'index')
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should call set on the repository for each index of the alias with supplied op_type (create)' do
|
144
|
+
expect(ExampleIndexAlias.repository).to receive(:set).with(entity: item, index: ExampleIndex, type: type, op_type: 'create').once
|
145
|
+
expect(ExampleIndexAlias.repository).to receive(:set).with(entity: item, index: ExampleIndex2, type: type, op_type: 'create').once
|
146
|
+
ExampleIndexAlias.put_item(type: type, item: item, op_type: 'create')
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe '#delete_item' do
|
152
|
+
let(:id) { 10 }
|
153
|
+
let(:type) { 'default' }
|
154
|
+
it 'should call drop on the repository for each index of the alias' do
|
155
|
+
expect(ExampleIndexAlias.repository).to receive(:drop).with(index: ExampleIndex, id: id, type: type).once
|
156
|
+
expect(ExampleIndexAlias.repository).to receive(:drop).with(index: ExampleIndex2, id: id, type: type).once
|
157
|
+
ExampleIndexAlias.delete_item(id: id, type: type)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -82,6 +82,13 @@ RSpec.describe ElasticSearchFramework::Index do
|
|
82
82
|
'filter' => ['lowercase'],
|
83
83
|
'type' => 'custom'
|
84
84
|
}
|
85
|
+
},
|
86
|
+
'analyzer' => {
|
87
|
+
'custom_analyzer' => {
|
88
|
+
'filter' => ['lowercase'],
|
89
|
+
'type' => 'custom',
|
90
|
+
'tokenizer' => 'standard'
|
91
|
+
}
|
85
92
|
}
|
86
93
|
}
|
87
94
|
end
|
@@ -269,8 +276,8 @@ RSpec.describe ElasticSearchFramework::Index do
|
|
269
276
|
it 'should return a ElasticSearchFramework::Repository instance' do
|
270
277
|
expect(ExampleIndex.repository).to be_a(ElasticSearchFramework::Repository)
|
271
278
|
end
|
272
|
-
it 'should return
|
273
|
-
expect(ExampleIndex.repository).
|
279
|
+
it 'should return the same ElasticSearchFramework::Repository instance for multiple calls' do
|
280
|
+
expect(ExampleIndex.repository).to eq ExampleIndex.repository
|
274
281
|
end
|
275
282
|
end
|
276
283
|
|
@@ -294,9 +301,24 @@ RSpec.describe ElasticSearchFramework::Index do
|
|
294
301
|
i.number = 5
|
295
302
|
end
|
296
303
|
end
|
297
|
-
|
298
|
-
|
299
|
-
|
304
|
+
|
305
|
+
context 'without specifying op_type' do
|
306
|
+
it 'should call set on the repository with default op_type (index)' do
|
307
|
+
expect_any_instance_of(ElasticSearchFramework::Repository).to receive(:set).with(entity: item, index: ExampleIndex, op_type: 'index', type: type)
|
308
|
+
ExampleIndex.put_item(type: type, item: item)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context 'with specified op_type' do
|
313
|
+
it 'should call set on the repository with supplied op_type (index)' do
|
314
|
+
expect_any_instance_of(ElasticSearchFramework::Repository).to receive(:set).with(entity: item, index: ExampleIndex, op_type: 'index', type: type)
|
315
|
+
ExampleIndex.put_item(type: type, item: item, op_type: 'index')
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'should call set on the repository with supplied op_type (create)' do
|
319
|
+
expect_any_instance_of(ElasticSearchFramework::Repository).to receive(:set).with(entity: item, index: ExampleIndex, op_type: 'create', type: type)
|
320
|
+
ExampleIndex.put_item(type: type, item: item, op_type: 'create')
|
321
|
+
end
|
300
322
|
end
|
301
323
|
end
|
302
324
|
|
@@ -63,22 +63,40 @@ RSpec.describe ElasticSearchFramework::Repository do
|
|
63
63
|
ExampleIndexWithId.create
|
64
64
|
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
66
|
+
context 'PUT with op_type: index' do
|
67
|
+
it 'should create, read and delete an index document' do
|
68
|
+
subject.set(index: ExampleIndex, entity: item1)
|
69
|
+
subject.set(index: ExampleIndex, entity: item1.tap { |i| i.timestamp += 100 })
|
70
|
+
subject.set(index: ExampleIndex, entity: item1.tap { |i| i.timestamp += 100 }, op_type: 'index')
|
71
|
+
subject.set(index: ExampleIndex, entity: item2)
|
72
|
+
subject.set(index: ExampleIndex, entity: item5)
|
73
|
+
index_item1 = subject.get(index: ExampleIndex, id: item1.id)
|
74
|
+
expect(index_item1[:id]).to eq item1.id
|
75
|
+
expect(index_item1[:name]).to eq item1.name
|
76
|
+
expect(index_item1[:timestamp]).to eq item1.timestamp
|
77
|
+
expect(index_item1[:number]).to eq item1.number
|
78
|
+
index_item2 = subject.get(index: ExampleIndex, id: item2.id)
|
79
|
+
expect(index_item2[:id]).to eq item2.id
|
80
|
+
expect(index_item2[:name]).to eq item2.name
|
81
|
+
expect(index_item2[:timestamp]).to eq item2.timestamp
|
82
|
+
expect(index_item2[:number]).to eq item2.number
|
83
|
+
subject.drop(index: ExampleIndex, id: item1.id)
|
84
|
+
expect(subject.get(index: ExampleIndex, id: item1.id)).to be_nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'PUT with op_type: create' do
|
89
|
+
let!(:original_timestamp) { item1.timestamp }
|
90
|
+
|
91
|
+
it 'should not update item' do
|
92
|
+
subject.set(index: ExampleIndex, entity: item1)
|
93
|
+
subject.set(index: ExampleIndex, entity: item1.tap { |i| i.timestamp += 100 }, op_type: 'create')
|
94
|
+
index_item1 = subject.get(index: ExampleIndex, id: item1.id)
|
95
|
+
expect(index_item1[:id]).to eq item1.id
|
96
|
+
expect(index_item1[:name]).to eq item1.name
|
97
|
+
expect(index_item1[:timestamp]).to eq original_timestamp
|
98
|
+
expect(index_item1[:number]).to eq item1.number
|
99
|
+
end
|
82
100
|
end
|
83
101
|
|
84
102
|
after do
|
data/spec/example_index.rb
CHANGED
@@ -22,9 +22,11 @@ class ExampleIndexWithSettings
|
|
22
22
|
index name: 'example_index'
|
23
23
|
|
24
24
|
normalizer_value = { custom_normalizer: { type: 'custom', char_filter: [], filter: ['lowercase'] } }
|
25
|
+
analyzer_value = { custom_analyzer: { type: 'custom', tokenizer: 'standard', filter: %w(lowercase) } }
|
25
26
|
|
26
27
|
settings name: :number_of_shards, value: 1
|
27
28
|
settings name: :analysis, type: :normalizer, value: normalizer_value
|
29
|
+
settings name: :analysis, type: :analyzer, value: analyzer_value
|
28
30
|
mapping name: 'default', field: :name, type: :keyword, index: true
|
29
31
|
end
|
30
32
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class ExampleIndex2
|
2
|
+
extend ElasticSearchFramework::Index
|
3
|
+
|
4
|
+
index name: 'example_index', version: 2
|
5
|
+
|
6
|
+
mapping name: 'default', field: :name, type: :keyword, index: true
|
7
|
+
end
|
8
|
+
|
9
|
+
class ExampleIndexWithId2
|
10
|
+
extend ElasticSearchFramework::Index
|
11
|
+
|
12
|
+
index name: 'example_index', version: 2
|
13
|
+
|
14
|
+
id :number
|
15
|
+
|
16
|
+
mapping name: 'default', field: :name, type: :keyword, index: true
|
17
|
+
end
|
18
|
+
|
19
|
+
class ExampleIndexWithSettings2
|
20
|
+
extend ElasticSearchFramework::Index
|
21
|
+
|
22
|
+
index name: 'example_index', version: 2
|
23
|
+
|
24
|
+
normalizer_value = { custom_normalizer: { type: 'custom', char_filter: [], filter: ['lowercase'] } }
|
25
|
+
analyzer_value = { custom_analyzer: { type: 'custom', tokenizer: 'standard', filter: %w(lowercase) } }
|
26
|
+
|
27
|
+
settings name: :number_of_shards, value: 1
|
28
|
+
settings name: :analysis, type: :normalizer, value: normalizer_value
|
29
|
+
settings name: :analysis, type: :analyzer, value: analyzer_value
|
30
|
+
mapping name: 'default', field: :name, type: :keyword, index: true
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class ExampleIndexAlias
|
2
|
+
extend ElasticSearchFramework::IndexAlias
|
3
|
+
|
4
|
+
index ExampleIndex, active: true
|
5
|
+
index ExampleIndex2, active: false
|
6
|
+
|
7
|
+
name :example
|
8
|
+
end
|
9
|
+
|
10
|
+
class InvalidIndexAlias
|
11
|
+
extend ElasticSearchFramework::IndexAlias
|
12
|
+
|
13
|
+
index ExampleIndex, active: false
|
14
|
+
index ExampleIndex2, active: false
|
15
|
+
|
16
|
+
name :example
|
17
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -9,6 +9,9 @@ end
|
|
9
9
|
require 'elastic_search_framework'
|
10
10
|
require_relative '../spec/test_item.rb'
|
11
11
|
require_relative '../spec/example_index'
|
12
|
+
require_relative '../spec/example_index_2'
|
13
|
+
require_relative '../spec/example_index_alias'
|
14
|
+
require_relative '../spec/example_index_alias_2'
|
12
15
|
require 'pry'
|
13
16
|
|
14
17
|
RSpec.configure do |config|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic_search_framework
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vaughanbrittonsage
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -119,14 +119,19 @@ files:
|
|
119
119
|
- lib/elastic_search_framework/exceptions.rb
|
120
120
|
- lib/elastic_search_framework/exceptions/index_error.rb
|
121
121
|
- lib/elastic_search_framework/index.rb
|
122
|
+
- lib/elastic_search_framework/index_alias.rb
|
122
123
|
- lib/elastic_search_framework/logger.rb
|
123
124
|
- lib/elastic_search_framework/query.rb
|
124
125
|
- lib/elastic_search_framework/repository.rb
|
125
126
|
- lib/elastic_search_framework/version.rb
|
127
|
+
- spec/elastic_search_framework/index_alias_spec.rb
|
126
128
|
- spec/elastic_search_framework/index_spec.rb
|
127
129
|
- spec/elastic_search_framework/query_spec.rb
|
128
130
|
- spec/elastic_search_framework/repository_spec.rb
|
129
131
|
- spec/example_index.rb
|
132
|
+
- spec/example_index_2.rb
|
133
|
+
- spec/example_index_alias.rb
|
134
|
+
- spec/example_index_alias_2.rb
|
130
135
|
- spec/spec_helper.rb
|
131
136
|
- spec/test_item.rb
|
132
137
|
homepage: https://github.com/sage/elastic_search_framework
|
@@ -148,8 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
153
|
- !ruby/object:Gem::Version
|
149
154
|
version: '0'
|
150
155
|
requirements: []
|
151
|
-
|
152
|
-
rubygems_version: 2.7.7
|
156
|
+
rubygems_version: 3.0.8
|
153
157
|
signing_key:
|
154
158
|
specification_version: 4
|
155
159
|
summary: A lightweight framework to for working with elastic search.
|