search_flip 4.0.0.beta7 → 4.0.0.beta10
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/.github/workflows/test.yml +3 -2
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +19 -0
- data/README.md +12 -1
- data/docker-compose.yml +1 -0
- data/lib/search_flip/connection.rb +5 -5
- data/lib/search_flip/criteria.rb +36 -9
- data/lib/search_flip/http_client.rb +30 -5
- data/lib/search_flip/index.rb +8 -4
- data/lib/search_flip/version.rb +1 -1
- data/lib/search_flip.rb +8 -3
- data/spec/search_flip/aws_sigv4_plugin_spec.rb +6 -4
- data/spec/search_flip/bulk_spec.rb +5 -8
- data/spec/search_flip/connection_spec.rb +12 -5
- data/spec/search_flip/criteria_spec.rb +44 -9
- data/spec/search_flip/http_client_spec.rb +7 -3
- data/spec/search_flip/index_spec.rb +12 -4
- data/spec/spec_helper.rb +3 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef717835cd3022f20a81919662e6fa217d2ec51ba038dbf47adb8c306263cecd
|
4
|
+
data.tar.gz: d4b7809f264bea9b0fa2b2f620bbe017798dc188078d76822baf55f42663ff07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a03decbd40819248b0ed6c873f5fd876e97fc1fe2fca501ba71bffe833bcf9ba907360de08b10409fc8d59ff1859ad333ebb7c9e7f6533992baa61c91166221
|
7
|
+
data.tar.gz: 9933d1b3f3eca29cee34f2145967b2cd9fe84d313caf95927bd1ec0ac3cdd438dc4b1f0ee04dbada71682a70274b595e422141d8b5e4a4a74677f2119e7fd225
|
data/.github/workflows/test.yml
CHANGED
@@ -12,15 +12,17 @@ jobs:
|
|
12
12
|
- docker.elastic.co/elasticsearch/elasticsearch:6.7.0
|
13
13
|
- docker.elastic.co/elasticsearch/elasticsearch:7.0.0
|
14
14
|
- docker.elastic.co/elasticsearch/elasticsearch:7.11.2
|
15
|
+
- docker.elastic.co/elasticsearch/elasticsearch:8.1.1
|
15
16
|
ruby:
|
16
|
-
- 2.5
|
17
17
|
- 2.6
|
18
18
|
- 2.7
|
19
|
+
- 3.0
|
19
20
|
services:
|
20
21
|
elasticsearch:
|
21
22
|
image: ${{ matrix.elasticsearch }}
|
22
23
|
env:
|
23
24
|
discovery.type: single-node
|
25
|
+
xpack.security.enabled: false
|
24
26
|
ports:
|
25
27
|
- 9200:9200
|
26
28
|
steps:
|
@@ -30,6 +32,5 @@ jobs:
|
|
30
32
|
ruby-version: ${{ matrix.ruby }}
|
31
33
|
- run: gem install bundler
|
32
34
|
- run: bundle
|
33
|
-
- run: sleep 10
|
34
35
|
- run: bundle exec rspec
|
35
36
|
- run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -11,6 +11,25 @@
|
|
11
11
|
* Added `SearchFlip::Connection#get_cluster_settings` and
|
12
12
|
`#update_cluster_settings`
|
13
13
|
|
14
|
+
## v3.6.0
|
15
|
+
|
16
|
+
* Support Elasticsearch v8
|
17
|
+
|
18
|
+
## v3.5.0
|
19
|
+
|
20
|
+
* Add `SearchFlip::Criteria#http_timeout` to allow specifying timeouts on
|
21
|
+
a query level
|
22
|
+
|
23
|
+
## v3.4.0
|
24
|
+
|
25
|
+
* Expose `Http#timeout` via `SearchFlip::HTTPClient`
|
26
|
+
|
27
|
+
## v3.3.0
|
28
|
+
|
29
|
+
* Update httprb
|
30
|
+
* Changed oj default options
|
31
|
+
* Allow to set oj json options
|
32
|
+
|
14
33
|
## v3.2.1
|
15
34
|
|
16
35
|
* Fix `refresh` having a empty body breaking in elasticsearch 7.11
|
data/README.md
CHANGED
@@ -698,6 +698,14 @@ Specify a timeout to limit query processing time:
|
|
698
698
|
CommentIndex.timeout("3s").execute
|
699
699
|
```
|
700
700
|
|
701
|
+
* `http_timeout`
|
702
|
+
|
703
|
+
Specify a http timeout for the request which will be send to Elasticsearch:
|
704
|
+
|
705
|
+
```ruby
|
706
|
+
CommentIndex.http_timeout(3).execute
|
707
|
+
```
|
708
|
+
|
701
709
|
* `terminate_after`
|
702
710
|
|
703
711
|
Activate early query termination to stop query processing after the specified
|
@@ -756,7 +764,7 @@ end
|
|
756
764
|
This allows to use different clusters per index e.g. when migrating indices to
|
757
765
|
new versions of Elasticsearch.
|
758
766
|
|
759
|
-
You can specify basic auth, additional headers, etc via:
|
767
|
+
You can specify basic auth, additional headers, request timeouts, etc via:
|
760
768
|
|
761
769
|
```ruby
|
762
770
|
http_client = SearchFlip::HTTPClient.new
|
@@ -773,6 +781,9 @@ http_client = http_client.via("proxy.host", 8080)
|
|
773
781
|
# Custom headers
|
774
782
|
http_client = http_client.headers(key: "value")
|
775
783
|
|
784
|
+
# Timeouts
|
785
|
+
http_client = http_client.timeout(20)
|
786
|
+
|
776
787
|
SearchFlip::Connection.new(base_url: "...", http_client: http_client)
|
777
788
|
```
|
778
789
|
|
data/docker-compose.yml
CHANGED
@@ -93,7 +93,7 @@ module SearchFlip
|
|
93
93
|
def msearch(criterias)
|
94
94
|
payload = criterias.flat_map do |criteria|
|
95
95
|
[
|
96
|
-
SearchFlip::JSON.generate(index: criteria.target.index_name_with_prefix, type: criteria.target.type_name),
|
96
|
+
SearchFlip::JSON.generate(index: criteria.target.index_name_with_prefix, **(version.to_i < 8 ? { type: criteria.target.type_name } : {})),
|
97
97
|
SearchFlip::JSON.generate(criteria.request)
|
98
98
|
]
|
99
99
|
end
|
@@ -329,8 +329,8 @@ module SearchFlip
|
|
329
329
|
# @return [Boolean] Returns true or raises SearchFlip::ResponseError
|
330
330
|
|
331
331
|
def update_mapping(index_name, mapping, type_name: nil)
|
332
|
-
url = type_name ? type_url(index_name, type_name) : index_url(index_name)
|
333
|
-
params = type_name && version.to_f >= 6.7 ? { include_type_name: true } : {}
|
332
|
+
url = type_name && version.to_i < 8 ? type_url(index_name, type_name) : index_url(index_name)
|
333
|
+
params = type_name && version.to_f >= 6.7 && version.to_i < 8 ? { include_type_name: true } : {}
|
334
334
|
|
335
335
|
http_client.put("#{url}/_mapping", params: params, json: mapping)
|
336
336
|
|
@@ -347,8 +347,8 @@ module SearchFlip
|
|
347
347
|
# @return [Hash] The current type mapping
|
348
348
|
|
349
349
|
def get_mapping(index_name, type_name: nil)
|
350
|
-
url = type_name ? type_url(index_name, type_name) : index_url(index_name)
|
351
|
-
params = type_name && version.to_f >= 6.7 ? { include_type_name: true } : {}
|
350
|
+
url = type_name && version.to_i < 8 ? type_url(index_name, type_name) : index_url(index_name)
|
351
|
+
params = type_name && version.to_f >= 6.7 && version.to_i < 8 ? { include_type_name: true } : {}
|
352
352
|
|
353
353
|
response = http_client.headers(accept: "application/json").get("#{url}/_mapping", params: params)
|
354
354
|
|
data/lib/search_flip/criteria.rb
CHANGED
@@ -26,7 +26,8 @@ module SearchFlip
|
|
26
26
|
|
27
27
|
attr_accessor :target, :profile_value, :source_value, :suggest_values, :includes_values,
|
28
28
|
:eager_load_values, :preload_values, :failsafe_value, :scroll_args, :terminate_after_value,
|
29
|
-
:timeout_value, :preference_value, :search_type_value, :routing_value, :track_total_hits_value
|
29
|
+
:timeout_value, :preference_value, :search_type_value, :routing_value, :track_total_hits_value,
|
30
|
+
:http_timeout_value
|
30
31
|
|
31
32
|
# Creates a new criteria while merging the attributes (constraints,
|
32
33
|
# settings, etc) of the current criteria with the attributes of another one
|
@@ -47,7 +48,7 @@ module SearchFlip
|
|
47
48
|
[
|
48
49
|
:profile_value, :failsafe_value, :terminate_after_value, :timeout_value, :offset_value,
|
49
50
|
:limit_value, :scroll_args, :source_value, :preference_value, :search_type_value,
|
50
|
-
:routing_value, :track_total_hits_value, :explain_value
|
51
|
+
:routing_value, :track_total_hits_value, :explain_value, :http_timeout_value
|
51
52
|
].each do |name|
|
52
53
|
criteria.send(:"#{name}=", other.send(name)) unless other.send(name).nil?
|
53
54
|
end
|
@@ -148,6 +149,22 @@ module SearchFlip
|
|
148
149
|
end
|
149
150
|
end
|
150
151
|
|
152
|
+
# Specifies a http timeout, such that a SearchFlip::TimeoutError will be
|
153
|
+
# thrown when the request times out.
|
154
|
+
#
|
155
|
+
# @example
|
156
|
+
# ProductIndex.http_timeout(3).search("hello world")
|
157
|
+
#
|
158
|
+
# @param value [Fixnum] The timeout value
|
159
|
+
#
|
160
|
+
# @return [SearchFlip::Criteria] A newly created extended criteria
|
161
|
+
|
162
|
+
def http_timeout(value)
|
163
|
+
fresh.tap do |criteria|
|
164
|
+
criteria.http_timeout_value = value
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
151
168
|
# Specifies early query termination, such that the processing will be
|
152
169
|
# stopped after the specified number of results has been accumulated.
|
153
170
|
#
|
@@ -330,10 +347,15 @@ module SearchFlip
|
|
330
347
|
dupped_request.delete(:from)
|
331
348
|
dupped_request.delete(:size)
|
332
349
|
|
350
|
+
http_request = connection.http_client
|
351
|
+
http_request = http_request.timeout(http_timeout_value) if http_timeout_value
|
352
|
+
|
333
353
|
if connection.version.to_i >= 5
|
334
|
-
connection.
|
354
|
+
url = connection.version.to_i < 8 ? target.type_url : target.index_url
|
355
|
+
|
356
|
+
http_request.post("#{url}/_delete_by_query", params: request_params.merge(params), json: dupped_request)
|
335
357
|
else
|
336
|
-
|
358
|
+
http_request.delete("#{target.type_url}/_query", params: request_params.merge(params), json: dupped_request)
|
337
359
|
end
|
338
360
|
|
339
361
|
target.refresh if SearchFlip::Config[:auto_refresh]
|
@@ -501,8 +523,8 @@ module SearchFlip
|
|
501
523
|
end
|
502
524
|
|
503
525
|
# Executes the search request for the current criteria, ie sends the
|
504
|
-
# request to Elasticsearch and returns the response. Connection
|
505
|
-
# response errors will be rescued if you specify the criteria to be
|
526
|
+
# request to Elasticsearch and returns the response. Connection, timeout
|
527
|
+
# and response errors will be rescued if you specify the criteria to be
|
506
528
|
# #failsafe, such that an empty response is returned instead.
|
507
529
|
#
|
508
530
|
# @example
|
@@ -590,6 +612,7 @@ module SearchFlip
|
|
590
612
|
|
591
613
|
def execute!
|
592
614
|
http_request = connection.http_client.headers(accept: "application/json")
|
615
|
+
http_request = http_request.timeout(http_timeout_value) if http_timeout_value
|
593
616
|
|
594
617
|
http_response =
|
595
618
|
if scroll_args && scroll_args[:id]
|
@@ -599,17 +622,21 @@ module SearchFlip
|
|
599
622
|
json: { scroll: scroll_args[:timeout], scroll_id: scroll_args[:id] }
|
600
623
|
)
|
601
624
|
elsif scroll_args
|
625
|
+
url = connection.version.to_i < 8 ? target.type_url : target.index_url
|
626
|
+
|
602
627
|
http_request.post(
|
603
|
-
"#{
|
628
|
+
"#{url}/_search",
|
604
629
|
params: request_params.merge(scroll: scroll_args[:timeout]),
|
605
630
|
json: request
|
606
631
|
)
|
607
632
|
else
|
608
|
-
|
633
|
+
url = connection.version.to_i < 8 ? target.type_url : target.index_url
|
634
|
+
|
635
|
+
http_request.post("#{url}/_search", params: request_params, json: request)
|
609
636
|
end
|
610
637
|
|
611
638
|
SearchFlip::Response.new(self, SearchFlip::JSON.parse(http_response.to_s))
|
612
|
-
rescue SearchFlip::ConnectionError, SearchFlip::ResponseError => e
|
639
|
+
rescue SearchFlip::ConnectionError, SearchFlip::TimeoutError, SearchFlip::ResponseError => e
|
613
640
|
raise e unless failsafe_value
|
614
641
|
|
615
642
|
SearchFlip::Response.new(self, "took" => 0, "hits" => { "total" => 0, "hits" => [] })
|
@@ -1,7 +1,28 @@
|
|
1
1
|
module SearchFlip
|
2
|
-
# The SearchFlip::HTTPClient class wraps the http gem
|
3
|
-
#
|
4
|
-
# with
|
2
|
+
# The SearchFlip::HTTPClient class wraps the http gem and responsible for the
|
3
|
+
# http request/response handling, ie communicating with Elasticsearch. You
|
4
|
+
# only need to use it directly if you need authentication to communicate with
|
5
|
+
# Elasticsearch or if you want to set some custom http settings.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# http_client = SearchFlip::HTTPClient.new
|
9
|
+
#
|
10
|
+
# # Basic Auth
|
11
|
+
# http_client = http_client.basic_auth(user: "username", pass: "password")
|
12
|
+
#
|
13
|
+
# # Raw Auth Header
|
14
|
+
# http_client = http_client.auth("Bearer VGhlIEhUVFAgR2VtLCBST0NLUw")
|
15
|
+
#
|
16
|
+
# # Proxy Settings
|
17
|
+
# http_client = http_client.via("proxy.host", 8080)
|
18
|
+
#
|
19
|
+
# # Custom headers
|
20
|
+
# http_client = http_client.headers(key: "value")
|
21
|
+
#
|
22
|
+
# # Timeouts
|
23
|
+
# http_client = http_client.timeout(20)
|
24
|
+
#
|
25
|
+
# SearchFlip::Connection.new(base_url: "...", http_client: http_client)
|
5
26
|
|
6
27
|
class HTTPClient
|
7
28
|
attr_accessor :request, :plugins
|
@@ -14,11 +35,11 @@ module SearchFlip
|
|
14
35
|
class << self
|
15
36
|
extend Forwardable
|
16
37
|
|
17
|
-
def_delegators :new, :headers, :via, :basic_auth, :auth
|
38
|
+
def_delegators :new, :headers, :via, :basic_auth, :auth, :timeout
|
18
39
|
def_delegators :new, :get, :post, :put, :delete, :head
|
19
40
|
end
|
20
41
|
|
21
|
-
[:headers, :via, :basic_auth, :auth].each do |method|
|
42
|
+
[:headers, :via, :basic_auth, :auth, :timeout].each do |method|
|
22
43
|
define_method method do |*args|
|
23
44
|
dup.tap do |client|
|
24
45
|
client.request = request.send(method, *args)
|
@@ -45,6 +66,10 @@ module SearchFlip
|
|
45
66
|
response
|
46
67
|
rescue HTTP::ConnectionError => e
|
47
68
|
raise SearchFlip::ConnectionError, e.message
|
69
|
+
rescue HTTP::TimeoutError => e
|
70
|
+
raise SearchFlip::TimeoutError, e.message
|
71
|
+
rescue HTTP::Error => e
|
72
|
+
raise SearchFlip::HttpError, e.message
|
48
73
|
end
|
49
74
|
end
|
50
75
|
end
|
data/lib/search_flip/index.rb
CHANGED
@@ -254,7 +254,7 @@ module SearchFlip
|
|
254
254
|
:page, :per, :search, :highlight, :suggest, :custom, :find_in_batches, :find_results_in_batches,
|
255
255
|
:find_each, :find_each_result, :failsafe, :total_entries, :total_count, :timeout, :terminate_after,
|
256
256
|
:records, :results, :must, :must_not, :should, :preference, :search_type, :routing,
|
257
|
-
:track_total_hits, :explain
|
257
|
+
:track_total_hits, :explain, :http_timeout
|
258
258
|
|
259
259
|
# Override to specify the type name used within Elasticsearch. Recap,
|
260
260
|
# this gem uses an individual index for each index class, because
|
@@ -455,7 +455,8 @@ module SearchFlip
|
|
455
455
|
# @return [Hash] The specified document
|
456
456
|
|
457
457
|
def get(id, params = {})
|
458
|
-
|
458
|
+
url = connection.version.to_i < 8 ? type_url : "#{index_url}/_doc"
|
459
|
+
response = connection.http_client.headers(accept: "application/json").get("#{url}/#{id}", params: params)
|
459
460
|
|
460
461
|
SearchFlip::JSON.parse(response.to_s)
|
461
462
|
end
|
@@ -473,7 +474,8 @@ module SearchFlip
|
|
473
474
|
# @return [Hash] The raw response
|
474
475
|
|
475
476
|
def mget(request, params = {})
|
476
|
-
|
477
|
+
url = connection.version.to_i < 8 ? type_url : index_url
|
478
|
+
response = connection.http_client.headers(accept: "application/json").post("#{url}/_mget", json: request, params: params)
|
477
479
|
|
478
480
|
SearchFlip::JSON.parse(response.to_s)
|
479
481
|
end
|
@@ -631,7 +633,9 @@ module SearchFlip
|
|
631
633
|
bulk_max_mb: connection.bulk_max_mb
|
632
634
|
}
|
633
635
|
|
634
|
-
|
636
|
+
url = connection.version.to_i < 8 ? type_url : index_url
|
637
|
+
|
638
|
+
SearchFlip::Bulk.new("#{url}/_bulk", default_options.merge(options)) do |indexer|
|
635
639
|
yield indexer
|
636
640
|
end
|
637
641
|
|
data/lib/search_flip/version.rb
CHANGED
data/lib/search_flip.rb
CHANGED
@@ -32,10 +32,15 @@ require "search_flip/index"
|
|
32
32
|
require "search_flip/model"
|
33
33
|
|
34
34
|
module SearchFlip
|
35
|
-
class
|
36
|
-
class ConnectionError < StandardError; end
|
35
|
+
class Error < StandardError; end
|
37
36
|
|
38
|
-
class
|
37
|
+
class NotSupportedError < Error; end
|
38
|
+
|
39
|
+
class HttpError < Error; end
|
40
|
+
class ConnectionError < HttpError; end
|
41
|
+
class TimeoutError < HttpError; end
|
42
|
+
|
43
|
+
class ResponseError < Error
|
39
44
|
attr_reader :code, :body
|
40
45
|
|
41
46
|
def initialize(code:, body:)
|
@@ -16,10 +16,12 @@ RSpec.describe SearchFlip::AwsSigv4Plugin do
|
|
16
16
|
it "adds the signed headers to the request" do
|
17
17
|
Timecop.freeze Time.parse("2020-01-01 12:00:00 UTC") do
|
18
18
|
expect(client).to receive(:headers).with(
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
an_object_matching(
|
20
|
+
"host" => "localhost",
|
21
|
+
"authorization" => /.*/,
|
22
|
+
"x-amz-content-sha256" => /.*/,
|
23
|
+
"x-amz-date" => /20200101T120000Z/
|
24
|
+
)
|
23
25
|
)
|
24
26
|
|
25
27
|
plugin.call(client, :get, "http://localhost/index")
|
@@ -60,18 +60,15 @@ RSpec.describe SearchFlip::Bulk do
|
|
60
60
|
|
61
61
|
it "uses the specified http_client" do
|
62
62
|
product = create(:product)
|
63
|
+
url = ProductIndex.connection.version.to_i < 8 ? ProductIndex.type_url : ProductIndex.index_url
|
63
64
|
|
64
|
-
stub_request(:put, "#{
|
65
|
-
.with(headers: { "X-Header" => "Value" })
|
66
|
-
.to_return(status: 500)
|
65
|
+
stub_request(:put, "#{url}/_bulk").with(headers: { "X-Header" => "Value" }).to_return(status: 200, body: "{}")
|
67
66
|
|
68
|
-
|
69
|
-
|
70
|
-
bulk.index product.id, ProductIndex.serialize(product)
|
71
|
-
end
|
67
|
+
ProductIndex.bulk http_client: ProductIndex.connection.http_client.headers("X-Header" => "Value") do |bulk|
|
68
|
+
bulk.index product.id, ProductIndex.serialize(product)
|
72
69
|
end
|
73
70
|
|
74
|
-
expect(
|
71
|
+
expect(WebMock).to have_requested(:put, "#{url}/_bulk").with(headers: { "X-Header" => "Value" })
|
75
72
|
end
|
76
73
|
|
77
74
|
it "transmits up to bulk_max_mb only" do
|
@@ -199,7 +199,7 @@ RSpec.describe SearchFlip::Connection do
|
|
199
199
|
it "freezes the specified index" do
|
200
200
|
connection = SearchFlip::Connection.new
|
201
201
|
|
202
|
-
if connection.version.to_f >= 6.6
|
202
|
+
if connection.version.to_f >= 6.6 && connection.version.to_i < 8
|
203
203
|
begin
|
204
204
|
connection.create_index("index_name")
|
205
205
|
connection.freeze_index("index_name")
|
@@ -216,7 +216,7 @@ RSpec.describe SearchFlip::Connection do
|
|
216
216
|
it "unfreezes the specified index" do
|
217
217
|
connection = SearchFlip::Connection.new
|
218
218
|
|
219
|
-
if connection.version.to_f >= 6.6
|
219
|
+
if connection.version.to_f >= 6.6 && connection.version.to_i < 8
|
220
220
|
begin
|
221
221
|
connection.create_index("index_name")
|
222
222
|
connection.freeze_index("index_name")
|
@@ -291,12 +291,19 @@ RSpec.describe SearchFlip::Connection do
|
|
291
291
|
begin
|
292
292
|
connection = SearchFlip::Connection.new
|
293
293
|
|
294
|
-
mapping = { "
|
294
|
+
mapping = { "properties" => { "id" => { "type" => "long" } } }
|
295
295
|
|
296
296
|
connection.create_index("index_name")
|
297
|
-
connection.update_mapping("index_name", mapping, type_name: "type_name")
|
298
297
|
|
299
|
-
|
298
|
+
if connection.version.to_i < 8
|
299
|
+
connection.update_mapping("index_name", { "type_name" => mapping }, type_name: "type_name")
|
300
|
+
|
301
|
+
expect(connection.get_mapping("index_name", type_name: "type_name")).to eq("index_name" => { "mappings" => { "type_name" => mapping } })
|
302
|
+
else
|
303
|
+
connection.update_mapping("index_name", mapping)
|
304
|
+
|
305
|
+
expect(connection.get_mapping("index_name")).to eq("index_name" => { "mappings" => mapping })
|
306
|
+
end
|
300
307
|
ensure
|
301
308
|
connection.delete_index("index_name") if connection.index_exists?("index_name")
|
302
309
|
end
|
@@ -97,7 +97,8 @@ RSpec.describe SearchFlip::Criteria do
|
|
97
97
|
methods = [
|
98
98
|
:profile_value, :failsafe_value, :terminate_after_value, :timeout_value,
|
99
99
|
:offset_value, :limit_value, :scroll_args, :source_value, :preference_value,
|
100
|
-
:search_type_value, :routing_value, :track_total_hits_value, :explain_value
|
100
|
+
:search_type_value, :routing_value, :track_total_hits_value, :explain_value,
|
101
|
+
:http_timeout_value
|
101
102
|
]
|
102
103
|
|
103
104
|
methods.each do |method|
|
@@ -191,6 +192,22 @@ RSpec.describe SearchFlip::Criteria do
|
|
191
192
|
end
|
192
193
|
end
|
193
194
|
|
195
|
+
describe "#http_timeout" do
|
196
|
+
it "sets the query timeout" do
|
197
|
+
http_client = double("client").as_null_object
|
198
|
+
allow(http_client).to receive(:timeout).and_return(http_client)
|
199
|
+
allow(http_client).to receive(:post).and_raise(SearchFlip::TimeoutError)
|
200
|
+
allow(ProductIndex.connection).to receive(:http_client).and_return(http_client)
|
201
|
+
|
202
|
+
expect { ProductIndex.http_timeout(1).execute }.to raise_error(SearchFlip::TimeoutError)
|
203
|
+
expect(http_client).to have_received(:timeout).with(1)
|
204
|
+
end
|
205
|
+
|
206
|
+
it "executes without errors" do
|
207
|
+
expect { ProductIndex.http_timeout(1).execute }.not_to raise_error
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
194
211
|
describe "#terminate_after" do
|
195
212
|
it "sets the terminate after value" do
|
196
213
|
query = ProductIndex.terminate_after(1)
|
@@ -1204,13 +1221,19 @@ RSpec.describe SearchFlip::Criteria do
|
|
1204
1221
|
end
|
1205
1222
|
|
1206
1223
|
describe "#failsafe" do
|
1207
|
-
|
1208
|
-
|
1224
|
+
[SearchFlip::ConnectionError, SearchFlip::TimeoutError, SearchFlip::ResponseError.new(code: "code", body: "body")].each do |error|
|
1225
|
+
it "prevents #{error}" do
|
1226
|
+
http_client = double("client").as_null_object
|
1227
|
+
allow(http_client).to receive(:post).and_raise(error)
|
1228
|
+
allow(ProductIndex.connection).to receive(:http_client).and_return(http_client)
|
1229
|
+
|
1230
|
+
expect { ProductIndex.all.execute }.to raise_error(error)
|
1209
1231
|
|
1210
|
-
|
1232
|
+
query = ProductIndex.failsafe(true)
|
1211
1233
|
|
1212
|
-
|
1213
|
-
|
1234
|
+
expect(query.records).to eq([])
|
1235
|
+
expect(query.total_entries).to eq(0)
|
1236
|
+
end
|
1214
1237
|
end
|
1215
1238
|
end
|
1216
1239
|
|
@@ -1327,28 +1350,40 @@ RSpec.describe SearchFlip::Criteria do
|
|
1327
1350
|
|
1328
1351
|
describe "#preference" do
|
1329
1352
|
it "sets the preference" do
|
1330
|
-
|
1353
|
+
url = ProductIndex.connection.version.to_i < 8 ? "products/products" : "products"
|
1354
|
+
|
1355
|
+
stub_request(:post, "http://127.0.0.1:9200/#{url}/_search?preference=value")
|
1331
1356
|
.to_return(status: 200, headers: { content_type: "application/json" }, body: "{}")
|
1332
1357
|
|
1333
1358
|
ProductIndex.preference("value").execute
|
1359
|
+
|
1360
|
+
expect(WebMock).to have_requested(:post, "http://127.0.0.1:9200/#{url}/_search?preference=value")
|
1334
1361
|
end
|
1335
1362
|
end
|
1336
1363
|
|
1337
1364
|
describe "#search_type" do
|
1338
1365
|
it "sets the search_type" do
|
1339
|
-
|
1366
|
+
url = ProductIndex.connection.version.to_i < 8 ? "products/products" : "products"
|
1367
|
+
|
1368
|
+
stub_request(:post, "http://127.0.0.1:9200/#{url}/_search?search_type=value")
|
1340
1369
|
.to_return(status: 200, headers: { content_type: "application/json" }, body: "{}")
|
1341
1370
|
|
1342
1371
|
ProductIndex.search_type("value").execute
|
1372
|
+
|
1373
|
+
expect(WebMock).to have_requested(:post, "http://127.0.0.1:9200/#{url}/_search?search_type=value")
|
1343
1374
|
end
|
1344
1375
|
end
|
1345
1376
|
|
1346
1377
|
describe "#routing" do
|
1347
1378
|
it "sets the search_type" do
|
1348
|
-
|
1379
|
+
url = ProductIndex.connection.version.to_i < 8 ? "products/products" : "products"
|
1380
|
+
|
1381
|
+
stub_request(:post, "http://127.0.0.1:9200/#{url}/_search?routing=value")
|
1349
1382
|
.to_return(status: 200, headers: { content_type: "application/json" }, body: "{}")
|
1350
1383
|
|
1351
1384
|
ProductIndex.routing("value").execute
|
1385
|
+
|
1386
|
+
expect(WebMock).to have_requested(:post, "http://127.0.0.1:9200/#{url}/_search?routing=value")
|
1352
1387
|
end
|
1353
1388
|
end
|
1354
1389
|
end
|
@@ -7,7 +7,7 @@ class HttpTestRequest
|
|
7
7
|
self.calls = []
|
8
8
|
end
|
9
9
|
|
10
|
-
[:via, :basic_auth, :auth].each do |method|
|
10
|
+
[:headers, :via, :basic_auth, :auth, :timeout].each do |method|
|
11
11
|
define_method method do |*args|
|
12
12
|
dup.tap do |request|
|
13
13
|
request.calls = calls + [[method, args]]
|
@@ -20,7 +20,7 @@ RSpec.describe SearchFlip::HTTPClient do
|
|
20
20
|
describe "delegation" do
|
21
21
|
subject { SearchFlip::HTTPClient }
|
22
22
|
|
23
|
-
[:headers, :via, :basic_auth, :auth].each do |method|
|
23
|
+
[:headers, :via, :basic_auth, :auth, :timeout].each do |method|
|
24
24
|
it { should delegate(method).to(:new) }
|
25
25
|
end
|
26
26
|
|
@@ -56,8 +56,12 @@ RSpec.describe SearchFlip::HTTPClient do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
[:via, :basic_auth, :auth].each do |method|
|
59
|
+
[:headers, :via, :basic_auth, :auth, :timeout].each do |method|
|
60
60
|
describe "##{method}" do
|
61
|
+
it "is understood by HTTP" do
|
62
|
+
expect(HTTP.respond_to?(method)).to eq(true)
|
63
|
+
end
|
64
|
+
|
61
65
|
it "creates a dupped instance" do
|
62
66
|
client = SearchFlip::HTTPClient.new
|
63
67
|
client.request = HttpTestRequest.new
|
@@ -14,7 +14,7 @@ RSpec.describe SearchFlip::Index do
|
|
14
14
|
:total_entries, :total_count, :terminate_after, :timeout, :records, :results,
|
15
15
|
:must, :must_not, :should, :find_each_result,
|
16
16
|
:find_results_in_batches, :preference, :search_type, :routing,
|
17
|
-
:track_total_hits, :explain
|
17
|
+
:track_total_hits, :explain, :http_timeout
|
18
18
|
]
|
19
19
|
|
20
20
|
methods.each do |method|
|
@@ -215,7 +215,11 @@ RSpec.describe SearchFlip::Index do
|
|
215
215
|
|
216
216
|
TestIndex.update_mapping
|
217
217
|
|
218
|
-
|
218
|
+
if TestIndex.connection.version.to_i < 8
|
219
|
+
expect(TestIndex.connection).to have_received(:update_mapping).with("test", { "test" => mapping }, type_name: "test")
|
220
|
+
else
|
221
|
+
expect(TestIndex.connection).to have_received(:update_mapping).with("test", mapping)
|
222
|
+
end
|
219
223
|
end
|
220
224
|
|
221
225
|
it "updates the mapping" do
|
@@ -268,7 +272,11 @@ RSpec.describe SearchFlip::Index do
|
|
268
272
|
|
269
273
|
TestIndex.get_mapping
|
270
274
|
|
271
|
-
|
275
|
+
if TestIndex.connection.version.to_i < 8
|
276
|
+
expect(TestIndex.connection).to have_received(:get_mapping).with("test", type_name: "test")
|
277
|
+
else
|
278
|
+
expect(TestIndex.connection).to have_received(:get_mapping).with("test")
|
279
|
+
end
|
272
280
|
end
|
273
281
|
|
274
282
|
it "returns the mapping" do
|
@@ -332,7 +340,7 @@ RSpec.describe SearchFlip::Index do
|
|
332
340
|
|
333
341
|
TestIndex.type_url
|
334
342
|
|
335
|
-
expect(TestIndex.connection).to have_received(:type_url).with("test", "test")
|
343
|
+
expect(TestIndex.connection).to have_received(:type_url).with("test", TestIndex.connection.version.to_i < 8 ? "test" : "_doc")
|
336
344
|
end
|
337
345
|
end
|
338
346
|
|
data/spec/spec_helper.rb
CHANGED
@@ -84,7 +84,7 @@ class CommentIndex
|
|
84
84
|
include SearchFlip::Index
|
85
85
|
|
86
86
|
def self.type_name
|
87
|
-
"comments"
|
87
|
+
connection.version.to_i < 8 ? "comments" : "_doc"
|
88
88
|
end
|
89
89
|
|
90
90
|
def self.index_name
|
@@ -134,7 +134,7 @@ class ProductIndex
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def self.type_name
|
137
|
-
"products"
|
137
|
+
connection.version.to_i < 8 ? "products" : "_doc"
|
138
138
|
end
|
139
139
|
|
140
140
|
def self.index_name
|
@@ -175,7 +175,7 @@ class TestIndex
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def self.type_name
|
178
|
-
"test"
|
178
|
+
connection.version.to_i < 8 ? "test" : "_doc"
|
179
179
|
end
|
180
180
|
|
181
181
|
def self.index_name
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: search_flip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.0.
|
4
|
+
version: 4.0.0.beta10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Vetter
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -288,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
288
288
|
version: 1.3.1
|
289
289
|
requirements: []
|
290
290
|
rubygems_version: 3.2.3
|
291
|
-
signing_key:
|
291
|
+
signing_key:
|
292
292
|
specification_version: 4
|
293
293
|
summary: Full-Featured Elasticsearch Ruby Client with a Chainable DSL
|
294
294
|
test_files:
|