Skip to content

Commit

Permalink
Merge pull request #12 from Sage/allow_use_of_mapping_options
Browse files Browse the repository at this point in the history
Allow use of mapping options
  • Loading branch information
vaughanbrittonsage authored May 25, 2018
2 parents 4bdaad5 + f150d3c commit 999bb08
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 27 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## v1.4.0
* Resolve JSON query to work with ES6 by adding the request content type.
* Make the mapping method more flexible to allow more than just type and index to be passed for the mapping parameters/options.

## v1.3.0
* 1.3.0 was pushed and yanked from gem server.
* Code did contain: Resolve JSON query to work with ES6 by adding the request content type.

## v1.2.0
* Added a json_query method to provide the ability to query ElasticSearch with a json object.

Expand Down
22 changes: 6 additions & 16 deletions lib/elastic_search_framework/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,21 @@ def id(field)
end
end

def mapping(name:, field:, type:, index:)

def mapping(name:, field:, **options)
unless instance_variable_defined?(:@elastic_search_index_mappings)
instance_variable_set(:@elastic_search_index_mappings, {})
end

mappings = instance_variable_get(:@elastic_search_index_mappings)

if mappings[name] == nil
mappings[name] = {}
end
mappings[name] = {} if mappings[name].nil?

mappings[name][field] = { type: type, index: index}
mappings[name][field] = options

instance_variable_set(:@elastic_search_index_mappings, mappings)

end

def create

if !valid?
raise ElasticSearchFramework::Exceptions::IndexError.new("[#{self.class}] - Invalid Index description specified.")
end
Expand All @@ -50,7 +45,6 @@ def create
payload = create_payload(description: description, mappings: mappings)

put(payload: payload)

end

def put(payload:)
Expand All @@ -65,7 +59,7 @@ def put(payload:)
end

unless is_valid_response?(response.code)
if response.body.dig(:error, :root_cause, 0, :type) == 'index_already_exists_exception'
if JSON.parse(response.body, symbolize_names: true).dig(:error, :root_cause, 0, :type) == 'index_already_exists_exception'
# We get here because the `exists?` check in #create is non-atomic
ElasticSearchFramework.logger.warn "[#{self.class}] - Failed to create preexisting index. | Response: #{response.body}"
else
Expand Down Expand Up @@ -112,23 +106,19 @@ def create_payload(description:, mappings:)

if description[:shards] != nil
payload[:settings] = {
number_of_shards: Integer(description[:shards])
number_of_shards: Integer(description[:shards])
}
end

if mappings.keys.length > 0

payload[:mappings] = {}

mappings.keys.each do |name|
payload[:mappings][name] = {
properties: {}
}
mappings[name].keys.each do |field|
payload[:mappings][name][:properties][field] = {
type: mappings[name][field][:type],
index: mappings[name][field][:index]
}
payload[:mappings][name][:properties][field] = mappings[name][field]
end
end

Expand Down
1 change: 1 addition & 0 deletions lib/elastic_search_framework/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def json_query(index_name:, json_query:, type: 'default')
uri = URI("#{host}/#{index_name}/#{type}/_search")

request = Net::HTTP::Get.new(uri.request_uri)
request.content_type = 'application/json'
request.body = json_query

response = with_client do |client|
Expand Down
2 changes: 1 addition & 1 deletion lib/elastic_search_framework/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module ElasticSearchFramework
VERSION = '1.2.0'
VERSION = '1.4.0'
end
115 changes: 105 additions & 10 deletions spec/elastic_search_framework/index_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
RSpec.describe ElasticSearchFramework::Index do

describe '#description' do
it 'should return the index details' do
expect(ExampleIndex.description).to be_a(Hash)
Expand All @@ -10,6 +9,31 @@
end
end

describe '#index' do
before { ExampleIndex.create unless ExampleIndex.exists? }
context 'when the instance variable is not defined' do
before { allow(ExampleIndex).to receive(:instance_variable_defined?).and_return(true) }
it 'raises an index error' do
expect { ExampleIndex.index(name: 'test') }.to raise_error(
ElasticSearchFramework::Exceptions::IndexError,
"[Class] - Duplicate index description. Name: test | Shards: ."
)
end
end
end

describe '#id' do
context 'when the instance variable is not defined' do
before { allow(ExampleIndex).to receive(:instance_variable_defined?).and_return(true) }
it 'raises an index error' do
expect { ExampleIndex.id('name') }.to raise_error(
ElasticSearchFramework::Exceptions::IndexError,
"[Class] - Duplicate index id. Field: name."
)
end
end
end

describe '#full_name' do
let(:namespace) { 'uat' }
let(:namespace_delimiter) { '.' }
Expand All @@ -20,6 +44,14 @@
it 'should return the full index name including namespace and delimiter' do
expect(ExampleIndex.full_name).to eq "#{ElasticSearchFramework.namespace}#{ElasticSearchFramework.namespace_delimiter}#{ExampleIndex.description[:name]}"
end

context 'when the namespace is nil' do
before { ElasticSearchFramework.namespace = nil }

it 'returns the description name downcased' do
expect(ExampleIndex.full_name).to eq 'example_index'
end
end
end

describe '#mapping' do
Expand All @@ -46,18 +78,40 @@
end

describe '#create' do
before do
if ExampleIndex.exists?
context 'when index is valid and does not exist' do
before { ExampleIndex.delete if ExampleIndex.exists? }

it 'should create an index' do
expect(ExampleIndex.exists?).to be false
ExampleIndex.create
expect(ExampleIndex.exists?).to be true
end

after do
ExampleIndex.delete
end
end
it 'should create an index' do
expect(ExampleIndex.exists?).to be false
ExampleIndex.create
expect(ExampleIndex.exists?).to be true

context 'when index is not valid' do
before { allow(ExampleIndex).to receive(:valid?).and_return(false) }

it 'raises an error' do
expect(ExampleIndex.exists?).to be false
expect { ExampleIndex.create }.to raise_error(
ElasticSearchFramework::Exceptions::IndexError,
'[Class] - Invalid Index description specified.'
)
end
end
after do
ExampleIndex.delete

context 'when index is valid but already exists' do
before { ExampleIndex.delete if ExampleIndex.exists? }

it 'does not try to create a new index' do
allow(ExampleIndex).to receive(:exists?).and_return(true)
expect(ExampleIndex).not_to receive(:put)
ExampleIndex.create
end
end
end

Expand Down Expand Up @@ -94,6 +148,48 @@
end
end

describe '#put' do
let(:payload) { {} }
context 'when there is a valid response' do
before { allow(ExampleIndex).to receive(:is_valid_response?).and_return(true) }

it 'returns true' do
ExampleIndex.create
expect(ExampleIndex.put(payload: payload)).to eq true
end
end

context 'when there is not a valid response' do
before { allow(ExampleIndex).to receive(:is_valid_response?).and_return(false) }

context 'when the error is "index_already_exists_exception"' do
let(:response_body) { { error: { root_cause: [{ type: 'index_already_exists_exception' }] } } }
let(:request) { double }

before { ExampleIndex.delete if ExampleIndex.exists? }
it 'returns true' do
allow(request).to receive(:body).and_return(response_body.to_json)
allow(request).to receive(:code).and_return(404)
allow_any_instance_of(Net::HTTP).to receive(:request).and_return(request)
expect(ExampleIndex.put(payload: payload)).to eq true
end
end

context 'when the error is not "index_already_exists_exception"' do
let(:response_body) { { error: { root_cause: [{ type: 'foo' }] } } }
let(:request) { double }
it 'raises an IndexError' do
allow(request).to receive(:body).and_return(response_body.to_json)
allow(request).to receive(:code).and_return(404)
allow_any_instance_of(Net::HTTP).to receive(:request).and_return(request)
expect { ExampleIndex.put(payload: payload) }.to raise_error(
ElasticSearchFramework::Exceptions::IndexError
)
end
end
end
end

describe '#is_valid_response?' do
let(:code) { 200 }
context 'when a 200 response code is returned' do
Expand Down Expand Up @@ -182,5 +278,4 @@
ExampleIndex.delete_item(id: id, type: type)
end
end

end

0 comments on commit 999bb08

Please sign in to comment.