diff --git a/README.md b/README.md index 4d1c94b3..eb89fb0d 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,11 @@ ES 8 ES_PORT=9208 rake test ``` +CCR tests: +``` +ES_PORT=9208 ES_REPLICA_PORT=9209 rake test +``` + ES 5 ``` ES_PORT=9205 rake test diff --git a/lib/elastomer_client/client/ccr.rb b/lib/elastomer_client/client/ccr.rb new file mode 100644 index 00000000..f42a005c --- /dev/null +++ b/lib/elastomer_client/client/ccr.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module ElastomerClient + class Client + + # Returns a CCR instance + def ccr + Ccr.new(self) + end + + class Ccr + # Create a new Ccr for initiating requests for cross cluster replication. + # More context: https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-apis.html + # + # client - ElastomerClient::Client used for HTTP requests to the server + def initialize(client) + @client = client + end + + attr_reader :client + + # Creates a new follower index for the provided leader index on the remote cluster. + # + # follower_index - String name of the follower index to create + # body - Hash of the request body + # :remote_cluster - String name of the remote cluster. Required. + # :leader_index - String name of the leader index. Required. + # params - Hash of query parameters + # + # Examples + # + # ccr.follow("follower_index", { leader_index: "leader_index", remote_cluster: "leader" }) + # + # See https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-put-follow.html + def follow(follower_index, body, params = {}) + response = client.put "/#{follower_index}/_ccr/follow", params.merge(body:, action: "follow", rest_api: "ccr") + response.body + end + end + end +end diff --git a/script/setup-ccr b/script/setup-ccr index 3f721b05..140dec5c 100755 --- a/script/setup-ccr +++ b/script/setup-ccr @@ -65,7 +65,7 @@ case "$1" in "persistent": { "cluster": { "remote": { - "cluster_one": { + "leader": { "seeds": ["es8.13:9300"] } } diff --git a/test/client/ccr_test.rb b/test/client/ccr_test.rb new file mode 100644 index 00000000..dbee88f1 --- /dev/null +++ b/test/client/ccr_test.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require_relative "../test_helper" + +describe ElastomerClient::Client::Ccr do + before do + skip "Cannot test Ccr API without a replica cluster" unless $replica_client.available? + + @leader_index = $client.index("leader_index") + @follower_index = $replica_client.index("follower_index") + if @leader_index.exists? + @leader_index.delete + end + if @follower_index.exists? + @follower_index.delete + end + @leader_index.create(default_index_settings) + wait_for_index(@leader_index.name, "green") + + @leader_index.docs.index(document_wrapper("book", { _id: 1, title: "Book 1" })) + @leader_index.refresh + end + + after do + @leader_index.delete if @leader_index.exists? + @follower_index.delete if @follower_index.exists? + end + + it "successfully follows a leader index" do + ccr = $replica_client.ccr + + ccr.follow(@follower_index.name, { leader_index: @leader_index.name, remote_cluster: "leader" }) + wait_for_index(@follower_index.name, "green") + doc = @follower_index.docs.get(id: 1, type: "book") + + assert_equal "Book 1", doc["_source"]["title"] + end + +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 604ea16a..586dc004 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -46,6 +46,19 @@ puts "Elasticsearch version is #{$client.version}" +# Create client instance for replica cluster +$replica_client_params = { + port: ENV.fetch("ES_REPLICA_PORT", 9201), + read_timeout: 10, + open_timeout: 1, + opaque_id: false, + strict_params: true, + compress_body: true +} +$replica_client = ElastomerClient::Client.new(**$replica_client_params) + +puts "Replica server is unavailable at #{$replica_client.url}" unless $replica_client.available? + # remove any lingering test indices from the cluster Minitest.after_run do $client.cluster.indices.keys.each do |name|