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.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ElastomerClient
4
- VERSION = "6.2.1"
4
+ VERSION = "6.2.3"
5
5
 
6
6
  def self.version
7
7
  VERSION
@@ -22,7 +22,7 @@ class RestApiSpecGenerator
22
22
 
23
23
  attr_reader :version, :short_version, :class_version
24
24
 
25
- def initialize(version = "8.13")
25
+ def initialize(version = "8.18")
26
26
  @version = version
27
27
 
28
28
  sliced = @version.split(".").slice(0, 2)
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
@@ -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
@@ -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
- tasks = $client.tasks
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.wait_by_id(node_id, task_id, "30s")
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.1
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: 2024-12-11 00:00:00.000000000 Z
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.4.10
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