Add support for ccr follow info api to HLRC. (#39115)
This API was introduces after #33824 was closed.
This commit is contained in:
parent
48984f647d
commit
0594a467f2
|
@ -23,6 +23,8 @@ import org.elasticsearch.action.ActionListener;
|
|||
import org.elasticsearch.client.ccr.CcrStatsRequest;
|
||||
import org.elasticsearch.client.ccr.CcrStatsResponse;
|
||||
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.FollowInfoRequest;
|
||||
import org.elasticsearch.client.ccr.FollowInfoResponse;
|
||||
import org.elasticsearch.client.ccr.FollowStatsRequest;
|
||||
import org.elasticsearch.client.ccr.FollowStatsResponse;
|
||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
||||
|
@ -452,4 +454,46 @@ public final class CcrClient {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets follow info for specific indices.
|
||||
*
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.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 FollowInfoResponse getFollowInfo(FollowInfoRequest request, RequestOptions options) throws IOException {
|
||||
return restHighLevelClient.performRequestAndParseEntity(
|
||||
request,
|
||||
CcrRequestConverters::getFollowInfo,
|
||||
options,
|
||||
FollowInfoResponse::fromXContent,
|
||||
Collections.emptySet()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously gets follow info for specific indices.
|
||||
*
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.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
|
||||
*/
|
||||
public void getFollowInfoAsync(FollowInfoRequest request,
|
||||
RequestOptions options,
|
||||
ActionListener<FollowInfoResponse> listener) {
|
||||
restHighLevelClient.performRequestAsyncAndParseEntity(
|
||||
request,
|
||||
CcrRequestConverters::getFollowInfo,
|
||||
options,
|
||||
FollowInfoResponse::fromXContent,
|
||||
listener,
|
||||
Collections.emptySet()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.http.client.methods.HttpPost;
|
|||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.elasticsearch.client.ccr.CcrStatsRequest;
|
||||
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.FollowInfoRequest;
|
||||
import org.elasticsearch.client.ccr.FollowStatsRequest;
|
||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.PauseFollowRequest;
|
||||
|
@ -119,4 +120,12 @@ final class CcrRequestConverters {
|
|||
return new Request(HttpGet.METHOD_NAME, endpoint);
|
||||
}
|
||||
|
||||
static Request getFollowInfo(FollowInfoRequest followInfoRequest) {
|
||||
String endpoint = new RequestConverters.EndpointBuilder()
|
||||
.addPathPart(followInfoRequest.getFollowerIndex())
|
||||
.addPathPartAsIs("_ccr", "info")
|
||||
.build();
|
||||
return new Request(HttpGet.METHOD_NAME, endpoint);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,8 +22,10 @@ package org.elasticsearch.client.ccr;
|
|||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.unit.ByteSizeValue;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
@ -41,6 +43,44 @@ public class FollowConfig {
|
|||
static final ParseField MAX_RETRY_DELAY_FIELD = new ParseField("max_retry_delay");
|
||||
static final ParseField READ_POLL_TIMEOUT = new ParseField("read_poll_timeout");
|
||||
|
||||
private static final ObjectParser<FollowConfig, Void> PARSER = new ObjectParser<>(
|
||||
"follow_config",
|
||||
true,
|
||||
FollowConfig::new);
|
||||
|
||||
static {
|
||||
PARSER.declareInt(FollowConfig::setMaxReadRequestOperationCount, MAX_READ_REQUEST_OPERATION_COUNT);
|
||||
PARSER.declareInt(FollowConfig::setMaxOutstandingReadRequests, MAX_OUTSTANDING_READ_REQUESTS);
|
||||
PARSER.declareField(
|
||||
FollowConfig::setMaxReadRequestSize,
|
||||
(p, c) -> ByteSizeValue.parseBytesSizeValue(p.text(), MAX_READ_REQUEST_SIZE.getPreferredName()),
|
||||
MAX_READ_REQUEST_SIZE,
|
||||
ObjectParser.ValueType.STRING);
|
||||
PARSER.declareInt(FollowConfig::setMaxWriteRequestOperationCount, MAX_WRITE_REQUEST_OPERATION_COUNT);
|
||||
PARSER.declareField(
|
||||
FollowConfig::setMaxWriteRequestSize,
|
||||
(p, c) -> ByteSizeValue.parseBytesSizeValue(p.text(), MAX_WRITE_REQUEST_SIZE.getPreferredName()),
|
||||
MAX_WRITE_REQUEST_SIZE,
|
||||
ObjectParser.ValueType.STRING);
|
||||
PARSER.declareInt(FollowConfig::setMaxOutstandingWriteRequests, MAX_OUTSTANDING_WRITE_REQUESTS);
|
||||
PARSER.declareInt(FollowConfig::setMaxWriteBufferCount, MAX_WRITE_BUFFER_COUNT);
|
||||
PARSER.declareField(
|
||||
FollowConfig::setMaxWriteBufferSize,
|
||||
(p, c) -> ByteSizeValue.parseBytesSizeValue(p.text(), MAX_WRITE_BUFFER_SIZE.getPreferredName()),
|
||||
MAX_WRITE_BUFFER_SIZE,
|
||||
ObjectParser.ValueType.STRING);
|
||||
PARSER.declareField(FollowConfig::setMaxRetryDelay,
|
||||
(p, c) -> TimeValue.parseTimeValue(p.text(), MAX_RETRY_DELAY_FIELD.getPreferredName()),
|
||||
MAX_RETRY_DELAY_FIELD, ObjectParser.ValueType.STRING);
|
||||
PARSER.declareField(FollowConfig::setReadPollTimeout,
|
||||
(p, c) -> TimeValue.parseTimeValue(p.text(), READ_POLL_TIMEOUT.getPreferredName()),
|
||||
READ_POLL_TIMEOUT, ObjectParser.ValueType.STRING);
|
||||
}
|
||||
|
||||
static FollowConfig fromXContent(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
private Integer maxReadRequestOperationCount;
|
||||
private Integer maxOutstandingReadRequests;
|
||||
private ByteSizeValue maxReadRequestSize;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
public final class FollowInfoRequest implements Validatable {
|
||||
|
||||
private final String followerIndex;
|
||||
|
||||
public FollowInfoRequest(String followerIndex) {
|
||||
this.followerIndex = Objects.requireNonNull(followerIndex);
|
||||
}
|
||||
|
||||
public String getFollowerIndex() {
|
||||
return followerIndex;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* 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.ParseField;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class FollowInfoResponse {
|
||||
|
||||
static final ParseField FOLLOWER_INDICES_FIELD = new ParseField("follower_indices");
|
||||
|
||||
private static final ConstructingObjectParser<FollowInfoResponse, Void> PARSER = new ConstructingObjectParser<>(
|
||||
"indices",
|
||||
true,
|
||||
args -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<FollowerInfo> infos = (List<FollowerInfo>) args[0];
|
||||
return new FollowInfoResponse(infos);
|
||||
});
|
||||
|
||||
static {
|
||||
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), FollowerInfo.PARSER, FOLLOWER_INDICES_FIELD);
|
||||
}
|
||||
|
||||
public static FollowInfoResponse fromXContent(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
private final List<FollowerInfo> infos;
|
||||
|
||||
FollowInfoResponse(List<FollowerInfo> infos) {
|
||||
this.infos = infos;
|
||||
}
|
||||
|
||||
public List<FollowerInfo> getInfos() {
|
||||
return infos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FollowInfoResponse that = (FollowInfoResponse) o;
|
||||
return infos.equals(that.infos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(infos);
|
||||
}
|
||||
|
||||
public static final class FollowerInfo {
|
||||
|
||||
static final ParseField FOLLOWER_INDEX_FIELD = new ParseField("follower_index");
|
||||
static final ParseField REMOTE_CLUSTER_FIELD = new ParseField("remote_cluster");
|
||||
static final ParseField LEADER_INDEX_FIELD = new ParseField("leader_index");
|
||||
static final ParseField STATUS_FIELD = new ParseField("status");
|
||||
static final ParseField PARAMETERS_FIELD = new ParseField("parameters");
|
||||
|
||||
private static final ConstructingObjectParser<FollowerInfo, Void> PARSER = new ConstructingObjectParser<>(
|
||||
"follower_info",
|
||||
true,
|
||||
args -> {
|
||||
return new FollowerInfo((String) args[0], (String) args[1], (String) args[2],
|
||||
Status.fromString((String) args[3]), (FollowConfig) args[4]);
|
||||
});
|
||||
|
||||
static {
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), FOLLOWER_INDEX_FIELD);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), REMOTE_CLUSTER_FIELD);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), LEADER_INDEX_FIELD);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), STATUS_FIELD);
|
||||
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(),
|
||||
(p, c) -> FollowConfig.fromXContent(p), PARAMETERS_FIELD);
|
||||
}
|
||||
|
||||
private final String followerIndex;
|
||||
private final String remoteCluster;
|
||||
private final String leaderIndex;
|
||||
private final Status status;
|
||||
private final FollowConfig parameters;
|
||||
|
||||
FollowerInfo(String followerIndex, String remoteCluster, String leaderIndex, Status status,
|
||||
FollowConfig parameters) {
|
||||
this.followerIndex = followerIndex;
|
||||
this.remoteCluster = remoteCluster;
|
||||
this.leaderIndex = leaderIndex;
|
||||
this.status = status;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public String getFollowerIndex() {
|
||||
return followerIndex;
|
||||
}
|
||||
|
||||
public String getRemoteCluster() {
|
||||
return remoteCluster;
|
||||
}
|
||||
|
||||
public String getLeaderIndex() {
|
||||
return leaderIndex;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public FollowConfig getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FollowerInfo that = (FollowerInfo) o;
|
||||
return Objects.equals(followerIndex, that.followerIndex) &&
|
||||
Objects.equals(remoteCluster, that.remoteCluster) &&
|
||||
Objects.equals(leaderIndex, that.leaderIndex) &&
|
||||
status == that.status &&
|
||||
Objects.equals(parameters, that.parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(followerIndex, remoteCluster, leaderIndex, status, parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum Status {
|
||||
|
||||
ACTIVE("active"),
|
||||
PAUSED("paused");
|
||||
|
||||
private final String name;
|
||||
|
||||
Status(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static Status fromString(String value) {
|
||||
switch (value) {
|
||||
case "active":
|
||||
return Status.ACTIVE;
|
||||
case "paused":
|
||||
return Status.PAUSED;
|
||||
default:
|
||||
throw new IllegalArgumentException("unexpected status value [" + value + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,6 +32,8 @@ import org.elasticsearch.action.support.WriteRequest;
|
|||
import org.elasticsearch.client.ccr.CcrStatsRequest;
|
||||
import org.elasticsearch.client.ccr.CcrStatsResponse;
|
||||
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.FollowInfoRequest;
|
||||
import org.elasticsearch.client.ccr.FollowInfoResponse;
|
||||
import org.elasticsearch.client.ccr.FollowStatsRequest;
|
||||
import org.elasticsearch.client.ccr.FollowStatsResponse;
|
||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
||||
|
@ -113,6 +115,15 @@ public class CCRIT extends ESRestHighLevelClientTestCase {
|
|||
|
||||
try {
|
||||
assertBusy(() -> {
|
||||
FollowInfoRequest followInfoRequest = new FollowInfoRequest("follower");
|
||||
FollowInfoResponse followInfoResponse =
|
||||
execute(followInfoRequest, ccrClient::getFollowInfo, ccrClient::getFollowInfoAsync);
|
||||
assertThat(followInfoResponse.getInfos().size(), equalTo(1));
|
||||
assertThat(followInfoResponse.getInfos().get(0).getFollowerIndex(), equalTo("follower"));
|
||||
assertThat(followInfoResponse.getInfos().get(0).getLeaderIndex(), equalTo("leader"));
|
||||
assertThat(followInfoResponse.getInfos().get(0).getRemoteCluster(), equalTo("local_cluster"));
|
||||
assertThat(followInfoResponse.getInfos().get(0).getStatus(), equalTo(FollowInfoResponse.Status.ACTIVE));
|
||||
|
||||
FollowStatsRequest followStatsRequest = new FollowStatsRequest("follower");
|
||||
FollowStatsResponse followStatsResponse =
|
||||
execute(followStatsRequest, ccrClient::getFollowStats, ccrClient::getFollowStatsAsync);
|
||||
|
@ -170,6 +181,17 @@ public class CCRIT extends ESRestHighLevelClientTestCase {
|
|||
pauseFollowResponse = execute(pauseFollowRequest, ccrClient::pauseFollow, ccrClient::pauseFollowAsync);
|
||||
assertThat(pauseFollowResponse.isAcknowledged(), is(true));
|
||||
|
||||
assertBusy(() -> {
|
||||
FollowInfoRequest followInfoRequest = new FollowInfoRequest("follower");
|
||||
FollowInfoResponse followInfoResponse =
|
||||
execute(followInfoRequest, ccrClient::getFollowInfo, ccrClient::getFollowInfoAsync);
|
||||
assertThat(followInfoResponse.getInfos().size(), equalTo(1));
|
||||
assertThat(followInfoResponse.getInfos().get(0).getFollowerIndex(), equalTo("follower"));
|
||||
assertThat(followInfoResponse.getInfos().get(0).getLeaderIndex(), equalTo("leader"));
|
||||
assertThat(followInfoResponse.getInfos().get(0).getRemoteCluster(), equalTo("local_cluster"));
|
||||
assertThat(followInfoResponse.getInfos().get(0).getStatus(), equalTo(FollowInfoResponse.Status.PAUSED));
|
||||
});
|
||||
|
||||
// Need to close index prior to unfollowing it:
|
||||
CloseIndexRequest closeIndexRequest = new CloseIndexRequest("follower");
|
||||
org.elasticsearch.action.support.master.AcknowledgedResponse closeIndexReponse =
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester;
|
||||
|
||||
public class FollowConfigTests extends ESTestCase {
|
||||
|
||||
public void testFromXContent() throws IOException {
|
||||
xContentTester(this::createParser,
|
||||
FollowConfigTests::createTestInstance,
|
||||
(followConfig, xContentBuilder) -> {
|
||||
xContentBuilder.startObject();
|
||||
followConfig.toXContentFragment(xContentBuilder, ToXContent.EMPTY_PARAMS);
|
||||
xContentBuilder.endObject();
|
||||
},
|
||||
FollowConfig::fromXContent)
|
||||
.supportsUnknownFields(true)
|
||||
.test();
|
||||
}
|
||||
|
||||
static FollowConfig createTestInstance() {
|
||||
FollowConfig followConfig = new FollowConfig();
|
||||
if (randomBoolean()) {
|
||||
followConfig.setMaxOutstandingReadRequests(randomIntBetween(0, Integer.MAX_VALUE));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
followConfig.setMaxOutstandingWriteRequests(randomIntBetween(0, Integer.MAX_VALUE));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
followConfig.setMaxReadRequestOperationCount(randomIntBetween(0, Integer.MAX_VALUE));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
followConfig.setMaxReadRequestSize(new ByteSizeValue(randomNonNegativeLong()));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
followConfig.setMaxWriteBufferCount(randomIntBetween(0, Integer.MAX_VALUE));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
followConfig.setMaxWriteBufferSize(new ByteSizeValue(randomNonNegativeLong()));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
followConfig.setMaxWriteRequestOperationCount(randomIntBetween(0, Integer.MAX_VALUE));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
followConfig.setMaxWriteRequestSize(new ByteSizeValue(randomNonNegativeLong()));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
followConfig.setMaxRetryDelay(new TimeValue(randomNonNegativeLong()));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
followConfig.setReadPollTimeout(new TimeValue(randomNonNegativeLong()));
|
||||
}
|
||||
return followConfig;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.ccr.FollowInfoResponse.FollowerInfo;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester;
|
||||
|
||||
public class FollowInfoResponseTests extends ESTestCase {
|
||||
|
||||
public void testFromXContent() throws IOException {
|
||||
xContentTester(this::createParser,
|
||||
FollowInfoResponseTests::createTestInstance,
|
||||
FollowInfoResponseTests::toXContent,
|
||||
FollowInfoResponse::fromXContent)
|
||||
.supportsUnknownFields(true)
|
||||
.test();
|
||||
}
|
||||
|
||||
private static void toXContent(FollowInfoResponse response, XContentBuilder builder) throws IOException {
|
||||
builder.startObject();
|
||||
builder.startArray(FollowInfoResponse.FOLLOWER_INDICES_FIELD.getPreferredName());
|
||||
for (FollowerInfo info : response.getInfos()) {
|
||||
builder.startObject();
|
||||
builder.field(FollowerInfo.FOLLOWER_INDEX_FIELD.getPreferredName(), info.getFollowerIndex());
|
||||
builder.field(FollowerInfo.REMOTE_CLUSTER_FIELD.getPreferredName(), info.getRemoteCluster());
|
||||
builder.field(FollowerInfo.LEADER_INDEX_FIELD.getPreferredName(), info.getLeaderIndex());
|
||||
builder.field(FollowerInfo.STATUS_FIELD.getPreferredName(), info.getStatus().getName());
|
||||
if (info.getParameters() != null) {
|
||||
builder.startObject(FollowerInfo.PARAMETERS_FIELD.getPreferredName());
|
||||
{
|
||||
info.getParameters().toXContentFragment(builder, ToXContent.EMPTY_PARAMS);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
private static FollowInfoResponse createTestInstance() {
|
||||
int numInfos = randomIntBetween(0, 64);
|
||||
List<FollowerInfo> infos = new ArrayList<>(numInfos);
|
||||
for (int i = 0; i < numInfos; i++) {
|
||||
FollowInfoResponse.Status status = randomFrom(FollowInfoResponse.Status.values());
|
||||
FollowConfig followConfig = randomBoolean() ? FollowConfigTests.createTestInstance() : null;
|
||||
infos.add(new FollowerInfo(randomAlphaOfLength(4), randomAlphaOfLength(4), randomAlphaOfLength(4), status, followConfig));
|
||||
}
|
||||
return new FollowInfoResponse(infos);
|
||||
}
|
||||
|
||||
}
|
|
@ -36,6 +36,8 @@ import org.elasticsearch.client.ccr.AutoFollowStats;
|
|||
import org.elasticsearch.client.ccr.CcrStatsRequest;
|
||||
import org.elasticsearch.client.ccr.CcrStatsResponse;
|
||||
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.FollowInfoRequest;
|
||||
import org.elasticsearch.client.ccr.FollowInfoResponse;
|
||||
import org.elasticsearch.client.ccr.FollowStatsRequest;
|
||||
import org.elasticsearch.client.ccr.FollowStatsResponse;
|
||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
||||
|
@ -58,6 +60,7 @@ import org.junit.Before;
|
|||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -697,6 +700,74 @@ public class CCRDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testGetFollowInfos() throws Exception {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
{
|
||||
// Create leader index:
|
||||
CreateIndexRequest createIndexRequest = new CreateIndexRequest("leader");
|
||||
createIndexRequest.settings(Collections.singletonMap("index.soft_deletes.enabled", true));
|
||||
CreateIndexResponse response = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
|
||||
assertThat(response.isAcknowledged(), is(true));
|
||||
}
|
||||
{
|
||||
// Follow index, so that we can query for follow stats:
|
||||
PutFollowRequest putFollowRequest = new PutFollowRequest("local", "leader", "follower", ActiveShardCount.ONE);
|
||||
PutFollowResponse putFollowResponse = client.ccr().putFollow(putFollowRequest, RequestOptions.DEFAULT);
|
||||
assertThat(putFollowResponse.isFollowIndexCreated(), is(true));
|
||||
assertThat(putFollowResponse.isFollowIndexShardsAcked(), is(true));
|
||||
assertThat(putFollowResponse.isIndexFollowingStarted(), is(true));
|
||||
}
|
||||
|
||||
// tag::ccr-get-follow-info-request
|
||||
FollowInfoRequest request =
|
||||
new FollowInfoRequest("follower"); // <1>
|
||||
// end::ccr-get-follow-info-request
|
||||
|
||||
// tag::ccr-get-follow-info-execute
|
||||
FollowInfoResponse response = client.ccr()
|
||||
.getFollowInfo(request, RequestOptions.DEFAULT);
|
||||
// end::ccr-get-follow-info-execute
|
||||
|
||||
// tag::ccr-get-follow-info-response
|
||||
List<FollowInfoResponse.FollowerInfo> infos =
|
||||
response.getInfos(); // <1>
|
||||
// end::ccr-get-follow-info-response
|
||||
|
||||
// tag::ccr-get-follow-info-execute-listener
|
||||
ActionListener<FollowInfoResponse> listener =
|
||||
new ActionListener<FollowInfoResponse>() {
|
||||
@Override
|
||||
public void onResponse(FollowInfoResponse response) { // <1>
|
||||
List<FollowInfoResponse.FollowerInfo> infos =
|
||||
response.getInfos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
// <2>
|
||||
}
|
||||
};
|
||||
// end::ccr-get-follow-info-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-follow-info-execute-async
|
||||
client.ccr().getFollowInfoAsync(request,
|
||||
RequestOptions.DEFAULT, listener); // <1>
|
||||
// end::ccr-get-follow-info-execute-async
|
||||
|
||||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
|
||||
{
|
||||
PauseFollowRequest pauseFollowRequest = new PauseFollowRequest("follower");
|
||||
AcknowledgedResponse pauseFollowResponse = client.ccr().pauseFollow(pauseFollowRequest, RequestOptions.DEFAULT);
|
||||
assertThat(pauseFollowResponse.isAcknowledged(), is(true));
|
||||
}
|
||||
}
|
||||
|
||||
static Map<String, Object> toMap(Response response) throws IOException {
|
||||
return XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
--
|
||||
:api: ccr-get-follow-info
|
||||
:request: FollowInfoRequest
|
||||
:response: FollowInfoResponse
|
||||
--
|
||||
|
||||
[id="{upid}-{api}"]
|
||||
=== Get Follow Info API
|
||||
|
||||
|
||||
[id="{upid}-{api}-request"]
|
||||
==== Request
|
||||
|
||||
The Get Follow Info API allows you to get follow information (parameters and status) for specific follower indices.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests-file}[{api}-request]
|
||||
--------------------------------------------------
|
||||
<1> The follower index to get follow information for.
|
||||
|
||||
[id="{upid}-{api}-response"]
|
||||
==== Response
|
||||
|
||||
The returned +{response}+ includes follow information for the specified follower indices
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests-file}[{api}-response]
|
||||
--------------------------------------------------
|
||||
<1> The follow information for specified follower indices.
|
||||
|
||||
include::../execution.asciidoc[]
|
||||
|
||||
|
|
@ -507,6 +507,7 @@ The Java High Level REST Client supports the following CCR APIs:
|
|||
* <<{upid}-ccr-get-auto-follow-pattern>>
|
||||
* <<{upid}-ccr-get-stats>>
|
||||
* <<{upid}-ccr-get-follow-stats>>
|
||||
* <<{upid}-ccr-get-follow-info>>
|
||||
|
||||
include::ccr/put_follow.asciidoc[]
|
||||
include::ccr/pause_follow.asciidoc[]
|
||||
|
@ -517,6 +518,7 @@ include::ccr/delete_auto_follow_pattern.asciidoc[]
|
|||
include::ccr/get_auto_follow_pattern.asciidoc[]
|
||||
include::ccr/get_stats.asciidoc[]
|
||||
include::ccr/get_follow_stats.asciidoc[]
|
||||
include::ccr/get_follow_info.asciidoc[]
|
||||
|
||||
== Index Lifecycle Management APIs
|
||||
|
||||
|
|
Loading…
Reference in New Issue