Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions lib/elastic_record/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ def initialize(servers, options = {})
end

def head(path)
http_request_with_retry(:head, path).code
http_request_with_retry(:head, path, nil, [404]).code
end

def json_get(path, json = nil)
json_request :get, path, json
json_request :get, path, json, ok_statuses: [404]
end

def json_post(path, json = nil)
Expand All @@ -34,25 +34,30 @@ def json_put(path, json = nil)
end

def json_delete(path, json = nil)
json_request :delete, path, json
json_request :delete, path, json, ok_statuses: [404]
end

def json_request(method, path, payload)
def json_request(method, path, payload, ok_statuses: [])
payload = ActiveSupport::JSON.encode(payload) if payload.is_a?(Hash)

response = http_request_with_retry(method, path, payload)
response = http_request_with_retry(method, path, payload, ok_statuses)

response_body = ActiveSupport::JSON.decode(response.body)
response_body['error'] ? raise_connection_error(response, payload) : response_body
end

def http_request_with_retry(method, path, payload = nil)
STATUS_200 = (200..299).freeze

def http_request_with_retry(method, path, payload = nil, ok_statuses = [])
with_retry do
response = http_request(method, path, payload)
code = response.code.to_i

raise_connection_error(response, payload) if response.code.to_i >= 500

response
if STATUS_200.cover?(code) || ok_statuses.include?(code)
response
else
raise_connection_error(response, payload)
end
end
end

Expand Down
59 changes: 59 additions & 0 deletions test/elastic_record/connection_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,65 @@ def test_json_requests
assert_equal expected, connection.json_put("/test")
end

def test_json_get_413_no_error
stub_es_request(:get, '/test').to_return(status: 413, body: 'client intended to send too large a body')

error =
assert_raises ElasticRecord::ConnectionError do
connection.json_get('/test')
end

assert_equal '413', error.status_code
end

def test_json_get_404_with_error
response = { error: { type: 'index_not_found_exception' } }

stub_es_request(:get, '/test').to_return(status: 404, body: response.to_json)

error =
assert_raises ElasticRecord::ConnectionError do
connection.json_get('/test')
end

expected = {
elasticsearch_response: response,
request_payload: nil,
}.to_json
assert_equal expected, error.message
end

def test_json_get_404_without_error
response = { '_index' => 'places', '_id' => '123', 'found' => false }

stub_es_request(:get, '/places/_doc/123').to_return(status: 404, body: response.to_json)

result =
begin
connection.json_get('/places/_doc/123')
rescue ElasticRecord::ConnectionError
flunk('404 GET without error should not raise')
end

assert_equal response, result
end

def test_json_delete_404_without_error
request = { 'id' => 'expired_pit' }
response = { 'succeeded' => false, 'num_freed' => 0 }

stub_es_request(:delete, '/_pit').to_return(status: 404, body: response.to_json)

result =
begin
connection.json_delete('/_pit', request.to_json)
rescue ElasticRecord::ConnectionError
flunk('404 DELETE without error should not raise')
end

assert_equal response, result
end

def test_json_request_with_valid_error_status
request = { 'some' => 'payload' }
response = { 'error' => 'Doing it wrong' }
Expand Down
Loading