Browse Source

[HLRC] Added support for CCR Get Auto Follow Pattern apis (#36049)

This change also adds documentation for the Get Auto Follow Pattern API.

Relates to #33824
Martijn van Groningen 6 years ago
parent
commit
579be9142e

+ 48 - 1
client/rest-high-level/src/main/java/org/elasticsearch/client/CcrClient.java

@@ -21,6 +21,8 @@ package org.elasticsearch.client;
 
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
+import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
+import org.elasticsearch.client.ccr.GetAutoFollowPatternResponse;
 import org.elasticsearch.client.ccr.PauseFollowRequest;
 import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest;
 import org.elasticsearch.client.ccr.PutFollowRequest;
@@ -291,7 +293,7 @@ public final class CcrClient {
     }
 
     /**
-     * Deletes an auto follow pattern.
+     * Asynchronously deletes an auto follow pattern.
      *
      * See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-delete-auto-follow-pattern.html">
      * the docs</a> for more.
@@ -313,4 +315,49 @@ public final class CcrClient {
         );
     }
 
+    /**
+     * Gets an auto follow pattern.
+     *
+     * See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-auto-follow-pattern.html">
+     * the docs</a> for more.
+     *
+     * @param request the request
+     * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+     * @return the response
+     * @throws IOException in case there is a problem sending the request or parsing back the response
+     */
+    public GetAutoFollowPatternResponse getAutoFollowPattern(GetAutoFollowPatternRequest request,
+                                                             RequestOptions options) throws IOException {
+        return restHighLevelClient.performRequestAndParseEntity(
+            request,
+            CcrRequestConverters::getAutoFollowPattern,
+            options,
+            GetAutoFollowPatternResponse::fromXContent,
+            Collections.emptySet()
+        );
+    }
+
+    /**
+     * Asynchronously gets an auto follow pattern.
+     *
+     * See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-auto-follow-pattern.html">
+     * the docs</a> for more.
+     *
+     * @param request the request
+     * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+     * @param listener the listener to be notified upon request completion
+     */
+    public void getAutoFollowPatternAsync(GetAutoFollowPatternRequest request,
+                                          RequestOptions options,
+                                          ActionListener<GetAutoFollowPatternResponse> listener) {
+        restHighLevelClient.performRequestAsyncAndParseEntity(
+            request,
+            CcrRequestConverters::getAutoFollowPattern,
+            options,
+            GetAutoFollowPatternResponse::fromXContent,
+            listener,
+            Collections.emptySet()
+        );
+    }
+
 }

+ 10 - 0
client/rest-high-level/src/main/java/org/elasticsearch/client/CcrRequestConverters.java

@@ -20,9 +20,11 @@
 package org.elasticsearch.client;
 
 import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpPut;
 import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
+import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
 import org.elasticsearch.client.ccr.PauseFollowRequest;
 import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest;
 import org.elasticsearch.client.ccr.PutFollowRequest;
@@ -90,4 +92,12 @@ final class CcrRequestConverters {
         return new Request(HttpDelete.METHOD_NAME, endpoint);
     }
 
+    static Request getAutoFollowPattern(GetAutoFollowPatternRequest getAutoFollowPatternRequest) {
+        String endpoint = new RequestConverters.EndpointBuilder()
+            .addPathPartAsIs("_ccr", "auto_follow")
+            .addPathPart(getAutoFollowPatternRequest.getName())
+            .build();
+        return new Request(HttpGet.METHOD_NAME, endpoint);
+    }
+
 }

+ 52 - 0
client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/GetAutoFollowPatternRequest.java

@@ -0,0 +1,52 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.ccr;
+
+import org.elasticsearch.client.Validatable;
+
+import java.util.Objects;
+
+/**
+ * Request class for get auto follow pattern api.
+ */
+public final class GetAutoFollowPatternRequest implements Validatable {
+
+    private final String name;
+
+    /**
+     * Get all auto follow patterns
+     */
+    public GetAutoFollowPatternRequest() {
+        this.name = null;
+    }
+
+    /**
+     * Get auto follow pattern with the specified name
+     *
+     * @param name The name of the auto follow pattern to get
+     */
+    public GetAutoFollowPatternRequest(String name) {
+        this.name = Objects.requireNonNull(name);
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 159 - 0
client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/GetAutoFollowPatternResponse.java

@@ -0,0 +1,159 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.ccr;
+
+import org.elasticsearch.common.unit.ByteSizeValue;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.common.xcontent.ConstructingObjectParser;
+import org.elasticsearch.common.xcontent.ObjectParser;
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.common.xcontent.XContentParser.Token;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public final class GetAutoFollowPatternResponse {
+
+    public static GetAutoFollowPatternResponse fromXContent(final XContentParser parser) throws IOException {
+        final Map<String, Pattern> patterns = new HashMap<>();
+        for (Token token = parser.nextToken(); token != Token.END_OBJECT; token = parser.nextToken()) {
+            if (token == Token.FIELD_NAME) {
+                final String name = parser.currentName();
+                final Pattern pattern = Pattern.PARSER.parse(parser, null);
+                patterns.put(name, pattern);
+            }
+        }
+        return new GetAutoFollowPatternResponse(patterns);
+    }
+
+    private final Map<String, Pattern> patterns;
+
+    GetAutoFollowPatternResponse(Map<String, Pattern> patterns) {
+        this.patterns = Collections.unmodifiableMap(patterns);
+    }
+
+    public Map<String, Pattern> getPatterns() {
+        return patterns;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        GetAutoFollowPatternResponse that = (GetAutoFollowPatternResponse) o;
+        return Objects.equals(patterns, that.patterns);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(patterns);
+    }
+
+    public static class Pattern extends FollowConfig {
+
+        @SuppressWarnings("unchecked")
+        private static final ConstructingObjectParser<Pattern, Void> PARSER = new ConstructingObjectParser<>(
+            "pattern", args -> new Pattern((String) args[0], (List<String>) args[1], (String) args[2]));
+
+        static {
+            PARSER.declareString(ConstructingObjectParser.constructorArg(), PutFollowRequest.REMOTE_CLUSTER_FIELD);
+            PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), PutAutoFollowPatternRequest.LEADER_PATTERNS_FIELD);
+            PARSER.declareString(ConstructingObjectParser.optionalConstructorArg(), PutAutoFollowPatternRequest.FOLLOW_PATTERN_FIELD);
+            PARSER.declareInt(Pattern::setMaxReadRequestOperationCount, FollowConfig.MAX_READ_REQUEST_OPERATION_COUNT);
+            PARSER.declareField(
+                Pattern::setMaxReadRequestSize,
+                (p, c) -> ByteSizeValue.parseBytesSizeValue(p.text(), FollowConfig.MAX_READ_REQUEST_SIZE.getPreferredName()),
+                PutFollowRequest.MAX_READ_REQUEST_SIZE,
+                ObjectParser.ValueType.STRING);
+            PARSER.declareInt(Pattern::setMaxOutstandingReadRequests, FollowConfig.MAX_OUTSTANDING_READ_REQUESTS);
+            PARSER.declareInt(Pattern::setMaxWriteRequestOperationCount, FollowConfig.MAX_WRITE_REQUEST_OPERATION_COUNT);
+            PARSER.declareField(
+                Pattern::setMaxWriteRequestSize,
+                (p, c) -> ByteSizeValue.parseBytesSizeValue(p.text(), FollowConfig.MAX_WRITE_REQUEST_SIZE.getPreferredName()),
+                PutFollowRequest.MAX_WRITE_REQUEST_SIZE,
+                ObjectParser.ValueType.STRING);
+            PARSER.declareInt(Pattern::setMaxOutstandingWriteRequests, FollowConfig.MAX_OUTSTANDING_WRITE_REQUESTS);
+            PARSER.declareInt(Pattern::setMaxWriteBufferCount, FollowConfig.MAX_WRITE_BUFFER_COUNT);
+            PARSER.declareField(
+                Pattern::setMaxWriteBufferSize,
+                (p, c) -> ByteSizeValue.parseBytesSizeValue(p.text(), FollowConfig.MAX_WRITE_BUFFER_SIZE.getPreferredName()),
+                PutFollowRequest.MAX_WRITE_BUFFER_SIZE,
+                ObjectParser.ValueType.STRING);
+            PARSER.declareField(
+                Pattern::setMaxRetryDelay,
+                (p, c) -> TimeValue.parseTimeValue(p.text(), FollowConfig.MAX_RETRY_DELAY_FIELD.getPreferredName()),
+                PutFollowRequest.MAX_RETRY_DELAY_FIELD,
+                ObjectParser.ValueType.STRING);
+            PARSER.declareField(
+                Pattern::setReadPollTimeout,
+                (p, c) -> TimeValue.parseTimeValue(p.text(), FollowConfig.READ_POLL_TIMEOUT.getPreferredName()),
+                PutFollowRequest.READ_POLL_TIMEOUT,
+                ObjectParser.ValueType.STRING);
+        }
+
+        private final String remoteCluster;
+        private final List<String> leaderIndexPatterns;
+        private final String followIndexNamePattern;
+
+        Pattern(String remoteCluster, List<String> leaderIndexPatterns, String followIndexNamePattern) {
+            this.remoteCluster = remoteCluster;
+            this.leaderIndexPatterns = leaderIndexPatterns;
+            this.followIndexNamePattern = followIndexNamePattern;
+        }
+
+        public String getRemoteCluster() {
+            return remoteCluster;
+        }
+
+        public List<String> getLeaderIndexPatterns() {
+            return leaderIndexPatterns;
+        }
+
+        public String getFollowIndexNamePattern() {
+            return followIndexNamePattern;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            if (!super.equals(o)) return false;
+            Pattern pattern = (Pattern) o;
+            return Objects.equals(remoteCluster, pattern.remoteCluster) &&
+                Objects.equals(leaderIndexPatterns, pattern.leaderIndexPatterns) &&
+                Objects.equals(followIndexNamePattern, pattern.followIndexNamePattern);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(
+                super.hashCode(),
+                remoteCluster,
+                leaderIndexPatterns,
+                followIndexNamePattern
+            );
+        }
+    }
+
+}

+ 14 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/CCRIT.java

@@ -30,6 +30,8 @@ import org.elasticsearch.action.search.SearchRequest;
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.action.support.WriteRequest;
 import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
+import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
+import org.elasticsearch.client.ccr.GetAutoFollowPatternResponse;
 import org.elasticsearch.client.ccr.PauseFollowRequest;
 import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest;
 import org.elasticsearch.client.ccr.PutFollowRequest;
@@ -48,6 +50,7 @@ import java.util.Map;
 
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
 
 public class CCRIT extends ESRestHighLevelClientTestCase {
 
@@ -148,6 +151,17 @@ public class CCRIT extends ESRestHighLevelClientTestCase {
             assertThat(indexExists("copy-logs-20200101"), is(true));
         });
 
+        GetAutoFollowPatternRequest getAutoFollowPatternRequest =
+            randomBoolean() ? new GetAutoFollowPatternRequest("pattern1") : new GetAutoFollowPatternRequest();
+        GetAutoFollowPatternResponse getAutoFollowPatternResponse =
+            execute(getAutoFollowPatternRequest, ccrClient::getAutoFollowPattern, ccrClient::getAutoFollowPatternAsync);
+        assertThat(getAutoFollowPatternResponse.getPatterns().size(), equalTo(1L));
+        GetAutoFollowPatternResponse.Pattern pattern = getAutoFollowPatternResponse.getPatterns().get("patterns1");
+        assertThat(pattern, notNullValue());
+        assertThat(pattern.getRemoteCluster(), equalTo(putAutoFollowPatternRequest.getRemoteCluster()));
+        assertThat(pattern.getLeaderIndexPatterns(), equalTo(putAutoFollowPatternRequest.getLeaderIndexPatterns()));
+        assertThat(pattern.getFollowIndexNamePattern(), equalTo(putAutoFollowPatternRequest.getFollowIndexNamePattern()));
+
         // Cleanup:
         final DeleteAutoFollowPatternRequest deleteAutoFollowPatternRequest = new DeleteAutoFollowPatternRequest("pattern1");
         AcknowledgedResponse deleteAutoFollowPatternResponse =

+ 107 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/ccr/GetAutoFollowPatternResponseTests.java

@@ -0,0 +1,107 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.ccr;
+
+import org.elasticsearch.common.unit.ByteSizeValue;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.common.xcontent.ToXContent;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.test.ESTestCase;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.elasticsearch.client.ccr.PutAutoFollowPatternRequest.FOLLOW_PATTERN_FIELD;
+import static org.elasticsearch.client.ccr.PutAutoFollowPatternRequest.LEADER_PATTERNS_FIELD;
+import static org.elasticsearch.client.ccr.PutFollowRequest.REMOTE_CLUSTER_FIELD;
+import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester;
+
+public class GetAutoFollowPatternResponseTests extends ESTestCase {
+
+    public void testFromXContent() throws IOException {
+        xContentTester(this::createParser,
+            this::createTestInstance,
+            GetAutoFollowPatternResponseTests::toXContent,
+            GetAutoFollowPatternResponse::fromXContent)
+            .supportsUnknownFields(false)
+            .test();
+    }
+
+    private GetAutoFollowPatternResponse createTestInstance() {
+        int numPatterns = randomIntBetween(0, 16);
+        Map<String, GetAutoFollowPatternResponse.Pattern> patterns = new HashMap<>(numPatterns);
+        for (int i = 0; i < numPatterns; i++) {
+            GetAutoFollowPatternResponse.Pattern pattern = new GetAutoFollowPatternResponse.Pattern(
+                randomAlphaOfLength(4), Collections.singletonList(randomAlphaOfLength(4)), randomAlphaOfLength(4));
+            if (randomBoolean()) {
+                pattern.setMaxOutstandingReadRequests(randomIntBetween(0, Integer.MAX_VALUE));
+            }
+            if (randomBoolean()) {
+                pattern.setMaxOutstandingWriteRequests(randomIntBetween(0, Integer.MAX_VALUE));
+            }
+            if (randomBoolean()) {
+                pattern.setMaxReadRequestOperationCount(randomIntBetween(0, Integer.MAX_VALUE));
+            }
+            if (randomBoolean()) {
+                pattern.setMaxReadRequestSize(new ByteSizeValue(randomNonNegativeLong()));
+            }
+            if (randomBoolean()) {
+                pattern.setMaxWriteBufferCount(randomIntBetween(0, Integer.MAX_VALUE));
+            }
+            if (randomBoolean()) {
+                pattern.setMaxWriteBufferSize(new ByteSizeValue(randomNonNegativeLong()));
+            }
+            if (randomBoolean()) {
+                pattern.setMaxWriteRequestOperationCount(randomIntBetween(0, Integer.MAX_VALUE));
+            }
+            if (randomBoolean()) {
+                pattern.setMaxWriteRequestSize(new ByteSizeValue(randomNonNegativeLong()));
+            }
+            if (randomBoolean()) {
+                pattern.setMaxRetryDelay(new TimeValue(randomNonNegativeLong()));
+            }
+            if (randomBoolean()) {
+                pattern.setReadPollTimeout(new TimeValue(randomNonNegativeLong()));
+            }
+            patterns.put(randomAlphaOfLength(4), pattern);
+        }
+        return new GetAutoFollowPatternResponse(patterns);
+    }
+
+    public static void toXContent(GetAutoFollowPatternResponse response, XContentBuilder builder) throws IOException {
+        builder.startObject();
+        {
+            for (Map.Entry<String, GetAutoFollowPatternResponse.Pattern> entry : response.getPatterns().entrySet()) {
+                builder.startObject(entry.getKey());
+                GetAutoFollowPatternResponse.Pattern pattern = entry.getValue();
+                builder.field(REMOTE_CLUSTER_FIELD.getPreferredName(), pattern.getRemoteCluster());
+                builder.field(LEADER_PATTERNS_FIELD.getPreferredName(), pattern.getLeaderIndexPatterns());
+                if (pattern.getFollowIndexNamePattern()!= null) {
+                    builder.field(FOLLOW_PATTERN_FIELD.getPreferredName(), pattern.getFollowIndexNamePattern());
+                }
+                entry.getValue().toXContentFragment(builder, ToXContent.EMPTY_PARAMS);
+                builder.endObject();
+            }
+        }
+        builder.endObject();
+    }
+}

+ 60 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/CCRDocumentationIT.java

@@ -34,6 +34,9 @@ import org.elasticsearch.client.RequestOptions;
 import org.elasticsearch.client.Response;
 import org.elasticsearch.client.RestHighLevelClient;
 import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
+import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
+import org.elasticsearch.client.ccr.GetAutoFollowPatternResponse;
+import org.elasticsearch.client.ccr.GetAutoFollowPatternResponse.Pattern;
 import org.elasticsearch.client.ccr.PauseFollowRequest;
 import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest;
 import org.elasticsearch.client.ccr.PutFollowRequest;
@@ -501,6 +504,63 @@ public class CCRDocumentationIT extends ESRestHighLevelClientTestCase {
         assertTrue(latch.await(30L, TimeUnit.SECONDS));
     }
 
+    public void testGetAutoFollowPattern() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+
+        // Put auto follow pattern, so that we can get it:
+        {
+            final PutAutoFollowPatternRequest putRequest =
+                new PutAutoFollowPatternRequest("my_pattern", "local", Collections.singletonList("logs-*"));
+            AcknowledgedResponse putResponse = client.ccr().putAutoFollowPattern(putRequest, RequestOptions.DEFAULT);
+            assertThat(putResponse.isAcknowledged(), is(true));
+        }
+
+        // tag::ccr-get-auto-follow-pattern-request
+        GetAutoFollowPatternRequest request =
+            new GetAutoFollowPatternRequest("my_pattern"); // <1>
+        // end::ccr-get-auto-follow-pattern-request
+
+        // tag::ccr-get-auto-follow-pattern-execute
+        GetAutoFollowPatternResponse response = client.ccr()
+            .getAutoFollowPattern(request, RequestOptions.DEFAULT);
+        // end::ccr-get-auto-follow-pattern-execute
+
+        // tag::ccr-get-auto-follow-pattern-response
+        Map<String, Pattern> patterns = response.getPatterns();
+        Pattern pattern = patterns.get("my_pattern"); // <1>
+        pattern.getLeaderIndexPatterns();
+        // end::ccr-get-auto-follow-pattern-response
+
+        // tag::ccr-get-auto-follow-pattern-execute-listener
+        ActionListener<GetAutoFollowPatternResponse> listener =
+            new ActionListener<GetAutoFollowPatternResponse>() {
+                @Override
+                public void onResponse(GetAutoFollowPatternResponse
+                                           response) { // <1>
+                    Map<String, Pattern> patterns = response.getPatterns();
+                    Pattern pattern = patterns.get("my_pattern");
+                    pattern.getLeaderIndexPatterns();
+                }
+
+                @Override
+                public void onFailure(Exception e) {
+                    // <2>
+                }
+            };
+        // end::ccr-get-auto-follow-pattern-execute-listener
+
+        // Replace the empty listener by a blocking listener in test
+        final CountDownLatch latch = new CountDownLatch(1);
+        listener = new LatchedActionListener<>(listener, latch);
+
+        // tag::ccr-get-auto-follow-pattern-execute-async
+        client.ccr().getAutoFollowPatternAsync(request,
+            RequestOptions.DEFAULT, listener); // <1>
+        // end::ccr-get-auto-follow-pattern-execute-async
+
+        assertTrue(latch.await(30L, TimeUnit.SECONDS));
+    }
+
     static Map<String, Object> toMap(Response response) throws IOException {
         return XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false);
     }

+ 35 - 0
docs/java-rest/high-level/ccr/get_auto_follow_pattern.asciidoc

@@ -0,0 +1,35 @@
+--
+:api: ccr-get-auto-follow-pattern
+:request: GetAutoFollowPatternRequest
+:response: GetAutoFollowPatternResponse
+--
+
+[id="{upid}-{api}"]
+=== Get Auto Follow Pattern API
+
+[id="{upid}-{api}-request"]
+==== Request
+
+The Get Auto Follow Pattern API allows you to get a specified auto follow pattern
+or all auto follow patterns.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+<1> The name of the auto follow pattern to get.
+    Use the default constructor to get all auto follow patterns.
+
+[id="{upid}-{api}-response"]
+==== Response
+
+The returned +{response}+ includes the requested auto follow pattern or
+all auto follow patterns if default constructor or request class was used.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> Get the requested pattern from the list of returned patterns
+
+include::../execution.asciidoc[]

+ 2 - 0
docs/java-rest/high-level/supported-apis.asciidoc

@@ -472,6 +472,7 @@ The Java High Level REST Client supports the following CCR APIs:
 * <<{upid}-ccr-unfollow>>
 * <<{upid}-ccr-put-auto-follow-pattern>>
 * <<{upid}-ccr-delete-auto-follow-pattern>>
+* <<{upid}-ccr-get-auto-follow-pattern>>
 
 include::ccr/put_follow.asciidoc[]
 include::ccr/pause_follow.asciidoc[]
@@ -479,6 +480,7 @@ include::ccr/resume_follow.asciidoc[]
 include::ccr/unfollow.asciidoc[]
 include::ccr/put_auto_follow_pattern.asciidoc[]
 include::ccr/delete_auto_follow_pattern.asciidoc[]
+include::ccr/get_auto_follow_pattern.asciidoc[]
 
 == Index Lifecycle Management APIs