From e4ea8b46b60e5e4dc7715d781ee0b35a5cf436b7 Mon Sep 17 00:00:00 2001 From: Tanguy Leroux Date: Mon, 14 Oct 2019 18:25:53 +0200 Subject: [PATCH] Add Pause/Resume Auto-Follower APIs to High Level REST Client (#48004) This commit adds support for Pause/Resume Auto-Follower APIs to the HLRC, with the documentation. Relates #47510 --- .../org/elasticsearch/client/CcrClient.java | 88 +++++++++++++ .../client/CcrRequestConverters.java | 20 +++ .../ccr/PauseAutoFollowPatternRequest.java | 45 +++++++ .../ccr/ResumeAutoFollowPatternRequest.java | 45 +++++++ .../client/CcrRequestConvertersTests.java | 22 ++++ .../documentation/CCRDocumentationIT.java | 120 ++++++++++++++++++ .../ccr/pause_auto_follow_pattern.asciidoc | 32 +++++ .../ccr/resume_auto_follow_pattern.asciidoc | 33 +++++ .../high-level/supported-apis.asciidoc | 4 + 9 files changed, 409 insertions(+) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/PauseAutoFollowPatternRequest.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/ResumeAutoFollowPatternRequest.java create mode 100644 docs/java-rest/high-level/ccr/pause_auto_follow_pattern.asciidoc create mode 100644 docs/java-rest/high-level/ccr/resume_auto_follow_pattern.asciidoc diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/CcrClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/CcrClient.java index daa7c54b7fe..6064da69265 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/CcrClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/CcrClient.java @@ -30,10 +30,12 @@ import org.elasticsearch.client.ccr.FollowStatsResponse; import org.elasticsearch.client.ccr.ForgetFollowerRequest; import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest; import org.elasticsearch.client.ccr.GetAutoFollowPatternResponse; +import org.elasticsearch.client.ccr.PauseAutoFollowPatternRequest; import org.elasticsearch.client.ccr.PauseFollowRequest; import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest; import org.elasticsearch.client.ccr.PutFollowRequest; import org.elasticsearch.client.ccr.PutFollowResponse; +import org.elasticsearch.client.ccr.ResumeAutoFollowPatternRequest; import org.elasticsearch.client.ccr.ResumeFollowRequest; import org.elasticsearch.client.ccr.UnfollowRequest; import org.elasticsearch.client.core.AcknowledgedResponse; @@ -410,6 +412,92 @@ public final class CcrClient { ); } + /** + * Pauses an auto follow pattern. + * + * See + * the docs 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 AcknowledgedResponse pauseAutoFollowPattern(PauseAutoFollowPatternRequest request, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity( + request, + CcrRequestConverters::pauseAutoFollowPattern, + options, + AcknowledgedResponse::fromXContent, + Collections.emptySet() + ); + } + + /** + * Asynchronously pauses an auto follow pattern. + * + * See + * the docs 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 + * @return cancellable that may be used to cancel the request + */ + public Cancellable pauseAutoFollowPatternAsync(PauseAutoFollowPatternRequest request, + RequestOptions options, + ActionListener listener) { + return restHighLevelClient.performRequestAsyncAndParseEntity( + request, + CcrRequestConverters::pauseAutoFollowPattern, + options, + AcknowledgedResponse::fromXContent, + listener, + Collections.emptySet()); + } + + /** + * Resumes an auto follow pattern. + * + * See + * the docs 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 AcknowledgedResponse resumeAutoFollowPattern(ResumeAutoFollowPatternRequest request, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity( + request, + CcrRequestConverters::resumeAutoFollowPattern, + options, + AcknowledgedResponse::fromXContent, + Collections.emptySet() + ); + } + + /** + * Asynchronously resumes an auto follow pattern. + * + * See + * the docs 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 + * @return cancellable that may be used to cancel the request + */ + public Cancellable resumeAutoFollowPatternAsync(ResumeAutoFollowPatternRequest request, + RequestOptions options, + ActionListener listener) { + return restHighLevelClient.performRequestAsyncAndParseEntity( + request, + CcrRequestConverters::resumeAutoFollowPattern, + options, + AcknowledgedResponse::fromXContent, + listener, + Collections.emptySet()); + } + /** * Gets all CCR stats. * diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/CcrRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/CcrRequestConverters.java index 8272e5d73bb..efcb5b8073b 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/CcrRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/CcrRequestConverters.java @@ -29,9 +29,11 @@ import org.elasticsearch.client.ccr.FollowInfoRequest; import org.elasticsearch.client.ccr.FollowStatsRequest; import org.elasticsearch.client.ccr.ForgetFollowerRequest; import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest; +import org.elasticsearch.client.ccr.PauseAutoFollowPatternRequest; import org.elasticsearch.client.ccr.PauseFollowRequest; import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest; import org.elasticsearch.client.ccr.PutFollowRequest; +import org.elasticsearch.client.ccr.ResumeAutoFollowPatternRequest; import org.elasticsearch.client.ccr.ResumeFollowRequest; import org.elasticsearch.client.ccr.UnfollowRequest; @@ -118,6 +120,24 @@ final class CcrRequestConverters { return new Request(HttpGet.METHOD_NAME, endpoint); } + static Request pauseAutoFollowPattern(PauseAutoFollowPatternRequest pauseAutoFollowPatternRequest) throws IOException { + String endpoint = new RequestConverters.EndpointBuilder() + .addPathPartAsIs("_ccr", "auto_follow") + .addPathPart(pauseAutoFollowPatternRequest.getName()) + .addPathPartAsIs("pause") + .build(); + return new Request(HttpPost.METHOD_NAME, endpoint); + } + + static Request resumeAutoFollowPattern(ResumeAutoFollowPatternRequest resumeAutoFollowPatternRequest) throws IOException { + String endpoint = new RequestConverters.EndpointBuilder() + .addPathPartAsIs("_ccr", "auto_follow") + .addPathPart(resumeAutoFollowPatternRequest.getName()) + .addPathPartAsIs("resume") + .build(); + return new Request(HttpPost.METHOD_NAME, endpoint); + } + static Request getCcrStats(CcrStatsRequest ccrStatsRequest) { String endpoint = new RequestConverters.EndpointBuilder() .addPathPartAsIs("_ccr", "stats") diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/PauseAutoFollowPatternRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/PauseAutoFollowPatternRequest.java new file mode 100644 index 00000000000..e713e16566d --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/PauseAutoFollowPatternRequest.java @@ -0,0 +1,45 @@ +/* + * 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 pause auto follow pattern api. + */ +public final class PauseAutoFollowPatternRequest implements Validatable { + + private final String name; + + /** + * Pause auto follow pattern with the specified name + * + * @param name The name of the auto follow pattern to pause + */ + public PauseAutoFollowPatternRequest(String name) { + this.name = Objects.requireNonNull(name); + } + + public String getName() { + return name; + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/ResumeAutoFollowPatternRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/ResumeAutoFollowPatternRequest.java new file mode 100644 index 00000000000..642763a1c3f --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/ResumeAutoFollowPatternRequest.java @@ -0,0 +1,45 @@ +/* + * 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 resume auto follow pattern api. + */ +public final class ResumeAutoFollowPatternRequest implements Validatable { + + private final String name; + + /** + * Resume auto follow pattern with the specified name + * + * @param name The name of the auto follow pattern to resume + */ + public ResumeAutoFollowPatternRequest(String name) { + this.name = Objects.requireNonNull(name); + } + + public String getName() { + return name; + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/CcrRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/CcrRequestConvertersTests.java index 393b7b9ba6f..ef506466b25 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/CcrRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/CcrRequestConvertersTests.java @@ -31,9 +31,11 @@ import org.elasticsearch.client.ccr.FollowInfoRequest; import org.elasticsearch.client.ccr.FollowStatsRequest; import org.elasticsearch.client.ccr.ForgetFollowerRequest; import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest; +import org.elasticsearch.client.ccr.PauseAutoFollowPatternRequest; import org.elasticsearch.client.ccr.PauseFollowRequest; import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest; import org.elasticsearch.client.ccr.PutFollowRequest; +import org.elasticsearch.client.ccr.ResumeAutoFollowPatternRequest; import org.elasticsearch.client.ccr.ResumeFollowRequest; import org.elasticsearch.client.ccr.UnfollowRequest; import org.elasticsearch.common.unit.ByteSizeValue; @@ -143,6 +145,26 @@ public class CcrRequestConvertersTests extends ESTestCase { assertThat(result.getEntity(), nullValue()); } + public void testPauseAutofollowPattern() throws Exception { + PauseAutoFollowPatternRequest pauseAutoFollowPatternRequest = new PauseAutoFollowPatternRequest(randomAlphaOfLength(4)); + + Request result = CcrRequestConverters.pauseAutoFollowPattern(pauseAutoFollowPatternRequest); + assertThat(result.getMethod(), equalTo(HttpPost.METHOD_NAME)); + assertThat(result.getEndpoint(), equalTo("/_ccr/auto_follow/" + pauseAutoFollowPatternRequest.getName() + "/pause")); + assertThat(result.getParameters().size(), equalTo(0)); + assertThat(result.getEntity(), nullValue()); + } + + public void testResumeAutofollowPattern() throws Exception { + ResumeAutoFollowPatternRequest resumeAutoFollowPatternRequest = new ResumeAutoFollowPatternRequest(randomAlphaOfLength(4)); + + Request result = CcrRequestConverters.resumeAutoFollowPattern(resumeAutoFollowPatternRequest); + assertThat(result.getMethod(), equalTo(HttpPost.METHOD_NAME)); + assertThat(result.getEndpoint(), equalTo("/_ccr/auto_follow/" + resumeAutoFollowPatternRequest.getName() + "/resume")); + assertThat(result.getParameters().size(), equalTo(0)); + assertThat(result.getEntity(), nullValue()); + } + public void testGetCcrStats() throws Exception { CcrStatsRequest ccrStatsRequest = new CcrStatsRequest(); Request result = CcrRequestConverters.getCcrStats(ccrStatsRequest); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/CCRDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/CCRDocumentationIT.java index b78507112b7..8595675792b 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/CCRDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/CCRDocumentationIT.java @@ -44,10 +44,12 @@ import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest; import org.elasticsearch.client.ccr.GetAutoFollowPatternResponse; import org.elasticsearch.client.ccr.GetAutoFollowPatternResponse.Pattern; import org.elasticsearch.client.ccr.IndicesFollowStats; +import org.elasticsearch.client.ccr.PauseAutoFollowPatternRequest; import org.elasticsearch.client.ccr.PauseFollowRequest; import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest; import org.elasticsearch.client.ccr.PutFollowRequest; import org.elasticsearch.client.ccr.PutFollowResponse; +import org.elasticsearch.client.ccr.ResumeAutoFollowPatternRequest; import org.elasticsearch.client.ccr.ResumeFollowRequest; import org.elasticsearch.client.ccr.UnfollowRequest; import org.elasticsearch.client.core.AcknowledgedResponse; @@ -681,6 +683,124 @@ public class CCRDocumentationIT extends ESRestHighLevelClientTestCase { } } + public void testPauseAutoFollowPattern() throws Exception { + final RestHighLevelClient client = highLevelClient(); + { + 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-pause-auto-follow-pattern-request + PauseAutoFollowPatternRequest request = + new PauseAutoFollowPatternRequest("my_pattern"); // <1> + // end::ccr-pause-auto-follow-pattern-request + + // tag::ccr-pause-auto-follow-pattern-execute + AcknowledgedResponse response = client.ccr() + .pauseAutoFollowPattern(request, RequestOptions.DEFAULT); + // end::ccr-pause-auto-follow-pattern-execute + + // tag::ccr-pause-auto-follow-pattern-response + boolean acknowledged = response.isAcknowledged(); // <1> + // end::ccr-pause-auto-follow-pattern-response + + // tag::ccr-pause-auto-follow-pattern-execute-listener + ActionListener listener = + new ActionListener() { + @Override + public void onResponse(AcknowledgedResponse response) { // <1> + boolean paused = response.isAcknowledged(); + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::ccr-pause-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-pause-auto-follow-pattern-execute-async + client.ccr().pauseAutoFollowPatternAsync(request, + RequestOptions.DEFAULT, listener); // <1> + // end::ccr-pause-auto-follow-pattern-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + + // Cleanup: + { + DeleteAutoFollowPatternRequest deleteRequest = new DeleteAutoFollowPatternRequest("my_pattern"); + AcknowledgedResponse deleteResponse = client.ccr().deleteAutoFollowPattern(deleteRequest, RequestOptions.DEFAULT); + assertThat(deleteResponse.isAcknowledged(), is(true)); + } + } + + public void testResumeAutoFollowPattern() throws Exception { + final RestHighLevelClient client = highLevelClient(); + { + final PutAutoFollowPatternRequest putRequest = + new PutAutoFollowPatternRequest("my_pattern", "local", Collections.singletonList("logs-*")); + AcknowledgedResponse putResponse = client.ccr().putAutoFollowPattern(putRequest, RequestOptions.DEFAULT); + assertThat(putResponse.isAcknowledged(), is(true)); + + final PauseAutoFollowPatternRequest pauseRequest = new PauseAutoFollowPatternRequest("my_pattern"); + AcknowledgedResponse pauseResponse = client.ccr().pauseAutoFollowPattern(pauseRequest, RequestOptions.DEFAULT); + assertThat(pauseResponse.isAcknowledged(), is(true)); + } + + // tag::ccr-resume-auto-follow-pattern-request + ResumeAutoFollowPatternRequest request = + new ResumeAutoFollowPatternRequest("my_pattern"); // <1> + // end::ccr-resume-auto-follow-pattern-request + + // tag::ccr-resume-auto-follow-pattern-execute + AcknowledgedResponse response = client.ccr() + .resumeAutoFollowPattern(request, RequestOptions.DEFAULT); + // end::ccr-resume-auto-follow-pattern-execute + + // tag::ccr-resume-auto-follow-pattern-response + boolean acknowledged = response.isAcknowledged(); // <1> + // end::ccr-resume-auto-follow-pattern-response + + // tag::ccr-resume-auto-follow-pattern-execute-listener + ActionListener listener = + new ActionListener() { + @Override + public void onResponse(AcknowledgedResponse response) { // <1> + boolean resumed = response.isAcknowledged(); + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::ccr-resume-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-resume-auto-follow-pattern-execute-async + client.ccr().resumeAutoFollowPatternAsync(request, + RequestOptions.DEFAULT, listener); // <1> + // end::ccr-resume-auto-follow-pattern-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + + // Cleanup: + { + DeleteAutoFollowPatternRequest deleteRequest = new DeleteAutoFollowPatternRequest("my_pattern"); + AcknowledgedResponse deleteResponse = client.ccr().deleteAutoFollowPattern(deleteRequest, RequestOptions.DEFAULT); + assertThat(deleteResponse.isAcknowledged(), is(true)); + } + } + public void testGetCCRStats() throws Exception { RestHighLevelClient client = highLevelClient(); diff --git a/docs/java-rest/high-level/ccr/pause_auto_follow_pattern.asciidoc b/docs/java-rest/high-level/ccr/pause_auto_follow_pattern.asciidoc new file mode 100644 index 00000000000..2d40e4e9c4a --- /dev/null +++ b/docs/java-rest/high-level/ccr/pause_auto_follow_pattern.asciidoc @@ -0,0 +1,32 @@ +-- +:api: ccr-pause-auto-follow-pattern +:request: PauseAutoFollowPatternRequest +:response: AcknowledgedResponse +-- +[role="xpack"] +[id="{upid}-{api}"] +=== Pause Auto Follow Pattern API + +[id="{upid}-{api}-request"] +==== Request + +The Pause Auto Follow Pattern API allows you to pause an existing auto follow pattern. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-request] +-------------------------------------------------- +<1> The name of the auto follow pattern. + +[id="{upid}-{api}-response"] +==== Response + +The returned +{response}+ indicates if the pause auto follow pattern request was received. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-response] +-------------------------------------------------- +<1> Whether or not the pause auto follow pattern request was acknowledged. + +include::../execution.asciidoc[] diff --git a/docs/java-rest/high-level/ccr/resume_auto_follow_pattern.asciidoc b/docs/java-rest/high-level/ccr/resume_auto_follow_pattern.asciidoc new file mode 100644 index 00000000000..8bc24ead277 --- /dev/null +++ b/docs/java-rest/high-level/ccr/resume_auto_follow_pattern.asciidoc @@ -0,0 +1,33 @@ +-- +:api: ccr-resume-auto-follow-pattern +:request: ResumeAutoFollowPatternRequest +:response: AcknowledgedResponse +-- +[role="xpack"] +[id="{upid}-{api}"] +=== Resume Auto Follow Pattern API + +[id="{upid}-{api}-request"] +==== Request + +The Resume Auto Follow Pattern API allows you to resume the activity + for a pause auto follow pattern. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-request] +-------------------------------------------------- +<1> The name of the auto follow pattern. + +[id="{upid}-{api}-response"] +==== Response + +The returned +{response}+ indicates if the resume auto follow pattern request was received. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-response] +-------------------------------------------------- +<1> Whether or not the resume auto follow pattern request was acknowledged. + +include::../execution.asciidoc[] diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 2bb1dc9da88..de5570e22d5 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -529,6 +529,8 @@ The Java High Level REST Client supports the following CCR APIs: * <<{upid}-ccr-put-auto-follow-pattern>> * <<{upid}-ccr-delete-auto-follow-pattern>> * <<{upid}-ccr-get-auto-follow-pattern>> +* <<{upid}-ccr-pause-auto-follow-pattern>> +* <<{upid}-ccr-resume-auto-follow-pattern>> * <<{upid}-ccr-get-stats>> * <<{upid}-ccr-get-follow-stats>> * <<{upid}-ccr-get-follow-info>> @@ -541,6 +543,8 @@ include::ccr/forget_follower.asciidoc[] include::ccr/put_auto_follow_pattern.asciidoc[] include::ccr/delete_auto_follow_pattern.asciidoc[] include::ccr/get_auto_follow_pattern.asciidoc[] +include::ccr/pause_auto_follow_pattern.asciidoc[] +include::ccr/resume_auto_follow_pattern.asciidoc[] include::ccr/get_stats.asciidoc[] include::ccr/get_follow_stats.asciidoc[] include::ccr/get_follow_info.asciidoc[]