elastomer-client 6.2.1 → 6.2.3
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/main.yml +3 -3
- data/CHANGELOG.md +7 -0
- data/README.md +14 -1
- data/docker/compose.yaml +33 -5
- data/docker/elasticsearch-follow.yml +14 -0
- data/docker/elasticsearch8plus.yml +1 -0
- data/lib/elastomer_client/client/ccr.rb +139 -0
- data/lib/elastomer_client/client/reindex.rb +2 -2
- data/lib/elastomer_client/client/rest_api_spec/api_spec_v8_17.rb +8161 -0
- data/lib/elastomer_client/client/rest_api_spec/api_spec_v8_18.rb +8456 -0
- data/lib/elastomer_client/version.rb +1 -1
- data/script/generate-rest-api-spec +1 -1
- data/script/setup-ccr +89 -0
- data/test/client/ccr_test.rb +149 -0
- data/test/client/cluster_test.rb +2 -1
- data/test/client/reindex_test.rb +6 -5
- data/test/test_helper.rb +13 -0
- metadata +10 -3
data/script/setup-ccr
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# Function to display help
|
4
|
+
show_help() {
|
5
|
+
echo "Usage: $0 [option] [license]"
|
6
|
+
echo "Options:"
|
7
|
+
echo " up - Start the clusters and apply the license"
|
8
|
+
echo " down - Shut down the clusters"
|
9
|
+
echo " help - Display this help message"
|
10
|
+
}
|
11
|
+
|
12
|
+
# Function to apply the license to a cluster
|
13
|
+
apply_license() {
|
14
|
+
local port=$1
|
15
|
+
local license="$2"
|
16
|
+
local response_file=$(mktemp)
|
17
|
+
local http_code
|
18
|
+
http_code=$(curl -s -o "$response_file" -w "%{http_code}" -X PUT "http://localhost:$port/_license?pretty" -H "Content-Type: application/json" -d "$license")
|
19
|
+
|
20
|
+
if [ "$http_code" -ne 200 ]; then
|
21
|
+
echo "Failed to apply license to cluster on port $port. HTTP status code: $http_code"
|
22
|
+
echo "Error response: $(cat "$response_file")"
|
23
|
+
rm "$response_file"
|
24
|
+
exit 1
|
25
|
+
fi
|
26
|
+
}
|
27
|
+
|
28
|
+
# Function to shut down the clusters
|
29
|
+
shutdown_clusters() {
|
30
|
+
docker compose --project-directory docker --profile ccr down
|
31
|
+
echo "Clusters shut down."
|
32
|
+
}
|
33
|
+
|
34
|
+
# Check for options
|
35
|
+
case "$1" in
|
36
|
+
up)
|
37
|
+
|
38
|
+
# Get the directory of the current script
|
39
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
40
|
+
|
41
|
+
# Start the clusters
|
42
|
+
docker compose --project-directory docker --profile ccr up -d
|
43
|
+
|
44
|
+
# Wait for both clusters to be online
|
45
|
+
export ES_PORT=9208
|
46
|
+
"$SCRIPT_DIR/poll-for-es"
|
47
|
+
export ES_PORT=9209
|
48
|
+
"$SCRIPT_DIR/poll-for-es"
|
49
|
+
|
50
|
+
# Apply the license to both clusters
|
51
|
+
LICENSE=$2
|
52
|
+
if [ -z "$LICENSE" ]; then
|
53
|
+
echo "License key is required as the second argument."
|
54
|
+
exit 1
|
55
|
+
fi
|
56
|
+
|
57
|
+
echo "Applying license to cluster on port 9208..."
|
58
|
+
apply_license 9208 "$LICENSE"
|
59
|
+
echo "Applying license to cluster on port 9209..."
|
60
|
+
apply_license 9209 "$LICENSE"
|
61
|
+
echo "License applied to both clusters."
|
62
|
+
|
63
|
+
# Set up the remote connection between the clusters
|
64
|
+
curl -X PUT "http://localhost:9209/_cluster/settings" -H "Content-Type: application/json" -d '{
|
65
|
+
"persistent": {
|
66
|
+
"cluster": {
|
67
|
+
"remote": {
|
68
|
+
"leader": {
|
69
|
+
"seeds": ["es8.18:9300"]
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}'
|
75
|
+
|
76
|
+
echo "Clusters setup completed."
|
77
|
+
;;
|
78
|
+
down)
|
79
|
+
shutdown_clusters
|
80
|
+
;;
|
81
|
+
help)
|
82
|
+
show_help
|
83
|
+
;;
|
84
|
+
*)
|
85
|
+
echo "Invalid option: $1"
|
86
|
+
show_help
|
87
|
+
exit 1
|
88
|
+
;;
|
89
|
+
esac
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../test_helper"
|
4
|
+
|
5
|
+
describe ElastomerClient::Client::Ccr do
|
6
|
+
before do
|
7
|
+
skip "Cannot test Ccr API without a replica cluster" unless $replica_client.available?
|
8
|
+
|
9
|
+
begin
|
10
|
+
ccr.delete_auto_follow("follower_pattern")
|
11
|
+
rescue StandardError
|
12
|
+
puts "No auto-follow pattern to delete"
|
13
|
+
end
|
14
|
+
|
15
|
+
@leader_index = $client.index("leader_index")
|
16
|
+
@follower_index = $replica_client.index("follower_index")
|
17
|
+
@auto_followed_index = $client.index("followed_index")
|
18
|
+
@auto_follower_index = $replica_client.index("followed_index-follower")
|
19
|
+
|
20
|
+
if @leader_index.exists?
|
21
|
+
@leader_index.delete
|
22
|
+
end
|
23
|
+
if @auto_followed_index.exists?
|
24
|
+
@auto_followed_index.delete
|
25
|
+
end
|
26
|
+
if @follower_index.exists?
|
27
|
+
@follower_index.delete
|
28
|
+
end
|
29
|
+
if @auto_follower_index.exists?
|
30
|
+
@auto_follower_index.delete
|
31
|
+
end
|
32
|
+
|
33
|
+
@leader_index.create(default_index_settings)
|
34
|
+
wait_for_index(@leader_index.name, "green")
|
35
|
+
end
|
36
|
+
|
37
|
+
after do
|
38
|
+
@leader_index.delete if @leader_index.exists?
|
39
|
+
@follower_index.delete if @follower_index.exists?
|
40
|
+
@auto_followed_index.delete if @auto_followed_index.exists?
|
41
|
+
@auto_follower_index.delete if @auto_follower_index.exists?
|
42
|
+
|
43
|
+
begin
|
44
|
+
ccr.delete_auto_follow("follower_pattern")
|
45
|
+
rescue StandardError
|
46
|
+
puts "No auto-follow pattern to delete"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def follow_index(follower_index_name, leader_index_name)
|
51
|
+
ccr = $replica_client.ccr
|
52
|
+
response = ccr.follow(follower_index_name, { leader_index: leader_index_name, remote_cluster: "leader" })
|
53
|
+
wait_for_index(follower_index_name, "green")
|
54
|
+
response
|
55
|
+
end
|
56
|
+
|
57
|
+
def pause_follow(follower_index_name)
|
58
|
+
ccr = $replica_client.ccr
|
59
|
+
response = ccr.pause_follow(follower_index_name)
|
60
|
+
wait_for_index(follower_index_name, "green")
|
61
|
+
response
|
62
|
+
end
|
63
|
+
|
64
|
+
def unfollow_index(follower_index_name)
|
65
|
+
ccr = $replica_client.ccr
|
66
|
+
response = ccr.unfollow(follower_index_name)
|
67
|
+
wait_for_index(follower_index_name, "green")
|
68
|
+
response
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_document(index, type, document)
|
72
|
+
response = index.docs.index(document_wrapper(type, document))
|
73
|
+
index.refresh
|
74
|
+
response
|
75
|
+
end
|
76
|
+
|
77
|
+
it "successfully follows a leader index" do
|
78
|
+
create_document(@leader_index, "book", { _id: 1, title: "Book 1" })
|
79
|
+
follow_index(@follower_index.name, @leader_index.name)
|
80
|
+
|
81
|
+
doc = @follower_index.docs.get(id: 1, type: "book")
|
82
|
+
|
83
|
+
assert_equal "Book 1", doc["_source"]["title"]
|
84
|
+
end
|
85
|
+
|
86
|
+
it "successfully gets info for all follower indices" do
|
87
|
+
follow_index(@follower_index.name, @leader_index.name)
|
88
|
+
|
89
|
+
response = $replica_client.ccr.get_follower_info("*")
|
90
|
+
|
91
|
+
assert_equal response["follower_indices"][0]["follower_index"], @follower_index.name
|
92
|
+
assert_equal response["follower_indices"][0]["leader_index"], @leader_index.name
|
93
|
+
end
|
94
|
+
|
95
|
+
it "successfully pauses a follower index" do
|
96
|
+
follow_index(@follower_index.name, @leader_index.name)
|
97
|
+
|
98
|
+
response = pause_follow(@follower_index.name)
|
99
|
+
|
100
|
+
assert response["acknowledged"]
|
101
|
+
|
102
|
+
create_document(@leader_index, "book", { _id: 2, title: "Book 2" })
|
103
|
+
|
104
|
+
doc = @follower_index.docs.get(id: 2, type: "book")
|
105
|
+
|
106
|
+
refute doc["found"]
|
107
|
+
end
|
108
|
+
|
109
|
+
it "successfully unfollow a leader index" do
|
110
|
+
follow_index(@follower_index.name, @leader_index.name)
|
111
|
+
|
112
|
+
pause_follow(@follower_index.name)
|
113
|
+
|
114
|
+
@follower_index.close
|
115
|
+
|
116
|
+
response = unfollow_index(@follower_index.name)
|
117
|
+
|
118
|
+
assert response["acknowledged"]
|
119
|
+
|
120
|
+
@follower_index.open
|
121
|
+
|
122
|
+
wait_for_index(@follower_index.name, "green")
|
123
|
+
|
124
|
+
create_document(@leader_index, "book", { _id: 2, title: "Book 2" })
|
125
|
+
|
126
|
+
doc = @follower_index.docs.get(id: 2, type: "book")
|
127
|
+
|
128
|
+
refute doc["found"]
|
129
|
+
end
|
130
|
+
|
131
|
+
it "successfully implements an auto-follow policy" do
|
132
|
+
ccr = $replica_client.ccr
|
133
|
+
|
134
|
+
ccr.auto_follow("follower_pattern", { remote_cluster: "leader", leader_index_patterns: ["*"], follow_index_pattern: "{{leader_index}}-follower" })
|
135
|
+
|
136
|
+
@auto_followed_index.create(default_index_settings)
|
137
|
+
wait_for_index(@auto_followed_index.name, "green")
|
138
|
+
|
139
|
+
@auto_follower_index = $replica_client.index("followed_index-follower")
|
140
|
+
wait_for_index(@auto_follower_index.name, "green")
|
141
|
+
|
142
|
+
resp = ccr.get_auto_follow(pattern_name: "follower_pattern")
|
143
|
+
|
144
|
+
assert_equal "follower_pattern", resp["patterns"].first["name"]
|
145
|
+
|
146
|
+
assert_predicate @auto_follower_index, :exists?
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
data/test/client/cluster_test.rb
CHANGED
@@ -79,7 +79,8 @@ describe ElastomerClient::Client::Cluster do
|
|
79
79
|
|
80
80
|
it "returns cluster stats" do
|
81
81
|
h = @cluster.stats
|
82
|
-
expected = $client.version_support.es_version_8_plus? ? %w[cluster_name cluster_uuid indices nodes snapshots status timestamp] : %w[cluster_name indices nodes status timestamp]
|
82
|
+
expected = $client.version_support.es_version_8_plus? ? %w[ccs cluster_name cluster_uuid indices nodes repositories snapshots status timestamp] : %w[cluster_name indices nodes status timestamp]
|
83
|
+
|
83
84
|
expected.unshift("_nodes")
|
84
85
|
|
85
86
|
assert_equal expected, h.keys.sort
|
data/test/client/reindex_test.rb
CHANGED
@@ -57,15 +57,16 @@ describe ElastomerClient::Client::Reindex do
|
|
57
57
|
}
|
58
58
|
response = reindex.reindex(body, requests_per_second: 0.01, wait_for_completion: false)
|
59
59
|
task_id = response["task"]
|
60
|
+
node_id = task_id.split(":").first
|
61
|
+
task_number = task_id.split(":").last.to_i
|
60
62
|
|
61
|
-
reindex.rethrottle(task_id, requests_per_second: 1)
|
63
|
+
response = reindex.rethrottle(task_id, requests_per_second: 1)
|
62
64
|
|
63
|
-
|
64
|
-
node_id = task_id.split(":").first
|
65
|
-
task_id = task_id.split(":").last.to_i
|
65
|
+
assert_equal 1, response["nodes"][node_id]["tasks"][task_id]["status"]["requests_per_second"]
|
66
66
|
|
67
67
|
# wait for the task to complete
|
68
|
-
tasks
|
68
|
+
tasks = $client.tasks
|
69
|
+
tasks.wait_by_id(node_id, task_number, "30s")
|
69
70
|
|
70
71
|
# Verify that the document has been reindexed
|
71
72
|
doc = @dest_index.docs.get(id: 1, type: "book")
|
data/test/test_helper.rb
CHANGED
@@ -46,6 +46,19 @@ raise "No server available at #{$client.url}" unless $client.available?
|
|
46
46
|
|
47
47
|
puts "Elasticsearch version is #{$client.version}"
|
48
48
|
|
49
|
+
# Create client instance for replica cluster
|
50
|
+
$replica_client_params = {
|
51
|
+
port: ENV.fetch("ES_REPLICA_PORT", 9201),
|
52
|
+
read_timeout: 10,
|
53
|
+
open_timeout: 1,
|
54
|
+
opaque_id: false,
|
55
|
+
strict_params: true,
|
56
|
+
compress_body: true
|
57
|
+
}
|
58
|
+
$replica_client = ElastomerClient::Client.new(**$replica_client_params)
|
59
|
+
|
60
|
+
puts "Replica server is unavailable at #{$replica_client.url}" unless $replica_client.available?
|
61
|
+
|
49
62
|
# remove any lingering test indices from the cluster
|
50
63
|
Minitest.after_run do
|
51
64
|
$client.cluster.indices.keys.each do |name|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastomer-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.2.
|
4
|
+
version: 6.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Pease
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-06-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: addressable
|
@@ -105,6 +105,7 @@ files:
|
|
105
105
|
- README.md
|
106
106
|
- Rakefile
|
107
107
|
- docker/compose.yaml
|
108
|
+
- docker/elasticsearch-follow.yml
|
108
109
|
- docker/elasticsearch.yml
|
109
110
|
- docker/elasticsearch8plus.yml
|
110
111
|
- docs/README.md
|
@@ -121,6 +122,7 @@ files:
|
|
121
122
|
- elastomer-client.gemspec
|
122
123
|
- lib/elastomer_client/client.rb
|
123
124
|
- lib/elastomer_client/client/bulk.rb
|
125
|
+
- lib/elastomer_client/client/ccr.rb
|
124
126
|
- lib/elastomer_client/client/cluster.rb
|
125
127
|
- lib/elastomer_client/client/delete_by_query.rb
|
126
128
|
- lib/elastomer_client/client/docs.rb
|
@@ -137,6 +139,8 @@ files:
|
|
137
139
|
- lib/elastomer_client/client/rest_api_spec/api_spec.rb
|
138
140
|
- lib/elastomer_client/client/rest_api_spec/api_spec_v5_6.rb
|
139
141
|
- lib/elastomer_client/client/rest_api_spec/api_spec_v8_13.rb
|
142
|
+
- lib/elastomer_client/client/rest_api_spec/api_spec_v8_17.rb
|
143
|
+
- lib/elastomer_client/client/rest_api_spec/api_spec_v8_18.rb
|
140
144
|
- lib/elastomer_client/client/rest_api_spec/api_spec_v8_7.rb
|
141
145
|
- lib/elastomer_client/client/rest_api_spec/rest_api.rb
|
142
146
|
- lib/elastomer_client/client/scroller.rb
|
@@ -157,8 +161,10 @@ files:
|
|
157
161
|
- script/console
|
158
162
|
- script/generate-rest-api-spec
|
159
163
|
- script/poll-for-es
|
164
|
+
- script/setup-ccr
|
160
165
|
- test/assertions.rb
|
161
166
|
- test/client/bulk_test.rb
|
167
|
+
- test/client/ccr_test.rb
|
162
168
|
- test/client/cluster_test.rb
|
163
169
|
- test/client/docs_test.rb
|
164
170
|
- test/client/errors_test.rb
|
@@ -206,13 +212,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
212
|
- !ruby/object:Gem::Version
|
207
213
|
version: '0'
|
208
214
|
requirements: []
|
209
|
-
rubygems_version: 3.
|
215
|
+
rubygems_version: 3.0.3.1
|
210
216
|
signing_key:
|
211
217
|
specification_version: 4
|
212
218
|
summary: A library for interacting with Elasticsearch
|
213
219
|
test_files:
|
214
220
|
- test/assertions.rb
|
215
221
|
- test/client/bulk_test.rb
|
222
|
+
- test/client/ccr_test.rb
|
216
223
|
- test/client/cluster_test.rb
|
217
224
|
- test/client/docs_test.rb
|
218
225
|
- test/client/errors_test.rb
|