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.CcrStatsRequest;
|
||||||
import org.elasticsearch.client.ccr.CcrStatsResponse;
|
import org.elasticsearch.client.ccr.CcrStatsResponse;
|
||||||
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
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.FollowStatsRequest;
|
||||||
import org.elasticsearch.client.ccr.FollowStatsResponse;
|
import org.elasticsearch.client.ccr.FollowStatsResponse;
|
||||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
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.apache.http.client.methods.HttpPut;
|
||||||
import org.elasticsearch.client.ccr.CcrStatsRequest;
|
import org.elasticsearch.client.ccr.CcrStatsRequest;
|
||||||
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
||||||
|
import org.elasticsearch.client.ccr.FollowInfoRequest;
|
||||||
import org.elasticsearch.client.ccr.FollowStatsRequest;
|
import org.elasticsearch.client.ccr.FollowStatsRequest;
|
||||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
||||||
import org.elasticsearch.client.ccr.PauseFollowRequest;
|
import org.elasticsearch.client.ccr.PauseFollowRequest;
|
||||||
|
@ -119,4 +120,12 @@ final class CcrRequestConverters {
|
||||||
return new Request(HttpGet.METHOD_NAME, endpoint);
|
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.ParseField;
|
||||||
import org.elasticsearch.common.unit.ByteSizeValue;
|
import org.elasticsearch.common.unit.ByteSizeValue;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
|
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
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 MAX_RETRY_DELAY_FIELD = new ParseField("max_retry_delay");
|
||||||
static final ParseField READ_POLL_TIMEOUT = new ParseField("read_poll_timeout");
|
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 maxReadRequestOperationCount;
|
||||||
private Integer maxOutstandingReadRequests;
|
private Integer maxOutstandingReadRequests;
|
||||||
private ByteSizeValue maxReadRequestSize;
|
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.CcrStatsRequest;
|
||||||
import org.elasticsearch.client.ccr.CcrStatsResponse;
|
import org.elasticsearch.client.ccr.CcrStatsResponse;
|
||||||
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
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.FollowStatsRequest;
|
||||||
import org.elasticsearch.client.ccr.FollowStatsResponse;
|
import org.elasticsearch.client.ccr.FollowStatsResponse;
|
||||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
||||||
|
@ -113,6 +115,15 @@ public class CCRIT extends ESRestHighLevelClientTestCase {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assertBusy(() -> {
|
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");
|
FollowStatsRequest followStatsRequest = new FollowStatsRequest("follower");
|
||||||
FollowStatsResponse followStatsResponse =
|
FollowStatsResponse followStatsResponse =
|
||||||
execute(followStatsRequest, ccrClient::getFollowStats, ccrClient::getFollowStatsAsync);
|
execute(followStatsRequest, ccrClient::getFollowStats, ccrClient::getFollowStatsAsync);
|
||||||
|
@ -170,6 +181,17 @@ public class CCRIT extends ESRestHighLevelClientTestCase {
|
||||||
pauseFollowResponse = execute(pauseFollowRequest, ccrClient::pauseFollow, ccrClient::pauseFollowAsync);
|
pauseFollowResponse = execute(pauseFollowRequest, ccrClient::pauseFollow, ccrClient::pauseFollowAsync);
|
||||||
assertThat(pauseFollowResponse.isAcknowledged(), is(true));
|
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:
|
// Need to close index prior to unfollowing it:
|
||||||
CloseIndexRequest closeIndexRequest = new CloseIndexRequest("follower");
|
CloseIndexRequest closeIndexRequest = new CloseIndexRequest("follower");
|
||||||
org.elasticsearch.action.support.master.AcknowledgedResponse closeIndexReponse =
|
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.CcrStatsRequest;
|
||||||
import org.elasticsearch.client.ccr.CcrStatsResponse;
|
import org.elasticsearch.client.ccr.CcrStatsResponse;
|
||||||
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
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.FollowStatsRequest;
|
||||||
import org.elasticsearch.client.ccr.FollowStatsResponse;
|
import org.elasticsearch.client.ccr.FollowStatsResponse;
|
||||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
||||||
|
@ -58,6 +60,7 @@ import org.junit.Before;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
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 {
|
static Map<String, Object> toMap(Response response) throws IOException {
|
||||||
return XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false);
|
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-auto-follow-pattern>>
|
||||||
* <<{upid}-ccr-get-stats>>
|
* <<{upid}-ccr-get-stats>>
|
||||||
* <<{upid}-ccr-get-follow-stats>>
|
* <<{upid}-ccr-get-follow-stats>>
|
||||||
|
* <<{upid}-ccr-get-follow-info>>
|
||||||
|
|
||||||
include::ccr/put_follow.asciidoc[]
|
include::ccr/put_follow.asciidoc[]
|
||||||
include::ccr/pause_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_auto_follow_pattern.asciidoc[]
|
||||||
include::ccr/get_stats.asciidoc[]
|
include::ccr/get_stats.asciidoc[]
|
||||||
include::ccr/get_follow_stats.asciidoc[]
|
include::ccr/get_follow_stats.asciidoc[]
|
||||||
|
include::ccr/get_follow_info.asciidoc[]
|
||||||
|
|
||||||
== Index Lifecycle Management APIs
|
== Index Lifecycle Management APIs
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue