mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-24 17:09:48 +00:00
[HLRC] Added support for CCR Stats API (#36213)
This change also adds documentation for the CCR Stats API. Relates to #33824
This commit is contained in:
parent
11935cd480
commit
786697a4b2
@ -20,6 +20,8 @@
|
||||
package org.elasticsearch.client;
|
||||
|
||||
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.GetAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternResponse;
|
||||
@ -360,4 +362,48 @@ public final class CcrClient {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all CCR stats.
|
||||
*
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-stats.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 CcrStatsResponse getCcrStats(CcrStatsRequest request,
|
||||
RequestOptions options) throws IOException {
|
||||
return restHighLevelClient.performRequestAndParseEntity(
|
||||
request,
|
||||
CcrRequestConverters::getCcrStats,
|
||||
options,
|
||||
CcrStatsResponse::fromXContent,
|
||||
Collections.emptySet()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all CCR stats.
|
||||
*
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-stats.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 getCcrStatsAsync(CcrStatsRequest request,
|
||||
RequestOptions options,
|
||||
ActionListener<CcrStatsResponse> listener) {
|
||||
restHighLevelClient.performRequestAsyncAndParseEntity(
|
||||
request,
|
||||
CcrRequestConverters::getCcrStats,
|
||||
options,
|
||||
CcrStatsResponse::fromXContent,
|
||||
listener,
|
||||
Collections.emptySet()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ 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.CcrStatsRequest;
|
||||
import org.elasticsearch.client.ccr.DeleteAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.PauseFollowRequest;
|
||||
@ -100,4 +101,11 @@ final class CcrRequestConverters {
|
||||
return new Request(HttpGet.METHOD_NAME, endpoint);
|
||||
}
|
||||
|
||||
static Request getCcrStats(CcrStatsRequest ccrStatsRequest) {
|
||||
String endpoint = new RequestConverters.EndpointBuilder()
|
||||
.addPathPartAsIs("_ccr", "stats")
|
||||
.build();
|
||||
return new Request(HttpGet.METHOD_NAME, endpoint);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.ElasticsearchException;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class AutoFollowStats {
|
||||
|
||||
static final ParseField NUMBER_OF_SUCCESSFUL_INDICES_AUTO_FOLLOWED = new ParseField("number_of_successful_follow_indices");
|
||||
static final ParseField NUMBER_OF_FAILED_INDICES_AUTO_FOLLOWED = new ParseField("number_of_failed_follow_indices");
|
||||
static final ParseField NUMBER_OF_FAILED_REMOTE_CLUSTER_STATE_REQUESTS =
|
||||
new ParseField("number_of_failed_remote_cluster_state_requests");
|
||||
static final ParseField RECENT_AUTO_FOLLOW_ERRORS = new ParseField("recent_auto_follow_errors");
|
||||
static final ParseField LEADER_INDEX = new ParseField("leader_index");
|
||||
static final ParseField AUTO_FOLLOW_EXCEPTION = new ParseField("auto_follow_exception");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static final ConstructingObjectParser<AutoFollowStats, Void> STATS_PARSER = new ConstructingObjectParser<>("auto_follow_stats",
|
||||
args -> new AutoFollowStats(
|
||||
(Long) args[0],
|
||||
(Long) args[1],
|
||||
(Long) args[2],
|
||||
new TreeMap<>(
|
||||
((List<Map.Entry<String, ElasticsearchException>>) args[3])
|
||||
.stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)))
|
||||
));
|
||||
|
||||
private static final ConstructingObjectParser<Map.Entry<String, ElasticsearchException>, Void> AUTO_FOLLOW_EXCEPTIONS_PARSER =
|
||||
new ConstructingObjectParser<>(
|
||||
"auto_follow_stats_errors",
|
||||
args -> new AbstractMap.SimpleEntry<>((String) args[0], (ElasticsearchException) args[1]));
|
||||
|
||||
static {
|
||||
AUTO_FOLLOW_EXCEPTIONS_PARSER.declareString(ConstructingObjectParser.constructorArg(), LEADER_INDEX);
|
||||
AUTO_FOLLOW_EXCEPTIONS_PARSER.declareObject(
|
||||
ConstructingObjectParser.constructorArg(),
|
||||
(p, c) -> ElasticsearchException.fromXContent(p),
|
||||
AUTO_FOLLOW_EXCEPTION);
|
||||
|
||||
STATS_PARSER.declareLong(ConstructingObjectParser.constructorArg(), NUMBER_OF_FAILED_INDICES_AUTO_FOLLOWED);
|
||||
STATS_PARSER.declareLong(ConstructingObjectParser.constructorArg(), NUMBER_OF_FAILED_REMOTE_CLUSTER_STATE_REQUESTS);
|
||||
STATS_PARSER.declareLong(ConstructingObjectParser.constructorArg(), NUMBER_OF_SUCCESSFUL_INDICES_AUTO_FOLLOWED);
|
||||
STATS_PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), AUTO_FOLLOW_EXCEPTIONS_PARSER,
|
||||
RECENT_AUTO_FOLLOW_ERRORS);
|
||||
}
|
||||
|
||||
private final long numberOfFailedFollowIndices;
|
||||
private final long numberOfFailedRemoteClusterStateRequests;
|
||||
private final long numberOfSuccessfulFollowIndices;
|
||||
private final NavigableMap<String, ElasticsearchException> recentAutoFollowErrors;
|
||||
|
||||
AutoFollowStats(long numberOfFailedFollowIndices,
|
||||
long numberOfFailedRemoteClusterStateRequests,
|
||||
long numberOfSuccessfulFollowIndices,
|
||||
NavigableMap<String, ElasticsearchException> recentAutoFollowErrors) {
|
||||
this.numberOfFailedFollowIndices = numberOfFailedFollowIndices;
|
||||
this.numberOfFailedRemoteClusterStateRequests = numberOfFailedRemoteClusterStateRequests;
|
||||
this.numberOfSuccessfulFollowIndices = numberOfSuccessfulFollowIndices;
|
||||
this.recentAutoFollowErrors = recentAutoFollowErrors;
|
||||
}
|
||||
|
||||
public long getNumberOfFailedFollowIndices() {
|
||||
return numberOfFailedFollowIndices;
|
||||
}
|
||||
|
||||
public long getNumberOfFailedRemoteClusterStateRequests() {
|
||||
return numberOfFailedRemoteClusterStateRequests;
|
||||
}
|
||||
|
||||
public long getNumberOfSuccessfulFollowIndices() {
|
||||
return numberOfSuccessfulFollowIndices;
|
||||
}
|
||||
|
||||
public NavigableMap<String, ElasticsearchException> getRecentAutoFollowErrors() {
|
||||
return recentAutoFollowErrors;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public final class CcrStatsRequest implements Validatable {
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public final class CcrStatsResponse {
|
||||
|
||||
static final ParseField AUTO_FOLLOW_STATS_FIELD = new ParseField("auto_follow_stats");
|
||||
static final ParseField FOLLOW_STATS_FIELD = new ParseField("follow_stats");
|
||||
|
||||
private static final ConstructingObjectParser<CcrStatsResponse, Void> PARSER = new ConstructingObjectParser<>("indices",
|
||||
args -> {
|
||||
AutoFollowStats autoFollowStats = (AutoFollowStats) args[0];
|
||||
IndicesFollowStats indicesFollowStats = (IndicesFollowStats) args[1];
|
||||
return new CcrStatsResponse(autoFollowStats, indicesFollowStats);
|
||||
});
|
||||
|
||||
static {
|
||||
PARSER.declareObject(ConstructingObjectParser.constructorArg(), AutoFollowStats.STATS_PARSER, AUTO_FOLLOW_STATS_FIELD);
|
||||
PARSER.declareObject(ConstructingObjectParser.constructorArg(), IndicesFollowStats.PARSER, FOLLOW_STATS_FIELD);
|
||||
}
|
||||
|
||||
public static CcrStatsResponse fromXContent(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
private final AutoFollowStats autoFollowStats;
|
||||
private final IndicesFollowStats indicesFollowStats;
|
||||
|
||||
public CcrStatsResponse(AutoFollowStats autoFollowStats, IndicesFollowStats indicesFollowStats) {
|
||||
this.autoFollowStats = autoFollowStats;
|
||||
this.indicesFollowStats = indicesFollowStats;
|
||||
}
|
||||
|
||||
public AutoFollowStats getAutoFollowStats() {
|
||||
return autoFollowStats;
|
||||
}
|
||||
|
||||
public IndicesFollowStats getIndicesFollowStats() {
|
||||
return indicesFollowStats;
|
||||
}
|
||||
}
|
@ -0,0 +1,403 @@
|
||||
/*
|
||||
* 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.ElasticsearchException;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class IndicesFollowStats {
|
||||
|
||||
static final ParseField INDICES_FIELD = new ParseField("indices");
|
||||
static final ParseField INDEX_FIELD = new ParseField("index");
|
||||
static final ParseField SHARDS_FIELD = new ParseField("shards");
|
||||
|
||||
private static final ConstructingObjectParser<Tuple<String, List<ShardFollowStats>>, Void> ENTRY_PARSER =
|
||||
new ConstructingObjectParser<>(
|
||||
"entry",
|
||||
args -> {
|
||||
String index = (String) args[0];
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ShardFollowStats> shardFollowStats = (List<ShardFollowStats>) args[1];
|
||||
return new Tuple<>(index, shardFollowStats);
|
||||
}
|
||||
);
|
||||
|
||||
static {
|
||||
ENTRY_PARSER.declareString(ConstructingObjectParser.constructorArg(), INDEX_FIELD);
|
||||
ENTRY_PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), ShardFollowStats.PARSER, SHARDS_FIELD);
|
||||
}
|
||||
|
||||
static final ConstructingObjectParser<IndicesFollowStats, Void> PARSER = new ConstructingObjectParser<>("indices",
|
||||
args -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Tuple<String, List<ShardFollowStats>>> entries = (List<Tuple<String, List<ShardFollowStats>>>) args[0];
|
||||
Map<String, List<ShardFollowStats>> shardFollowStats = entries.stream().collect(Collectors.toMap(Tuple::v1, Tuple::v2));
|
||||
return new IndicesFollowStats(new TreeMap<>(shardFollowStats));
|
||||
});
|
||||
|
||||
static {
|
||||
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), ENTRY_PARSER, INDICES_FIELD);
|
||||
}
|
||||
|
||||
private final NavigableMap<String, List<ShardFollowStats>> shardFollowStats;
|
||||
|
||||
IndicesFollowStats(NavigableMap<String, List<ShardFollowStats>> shardFollowStats) {
|
||||
this.shardFollowStats = Collections.unmodifiableNavigableMap(shardFollowStats);
|
||||
}
|
||||
|
||||
public List<ShardFollowStats> getShardFollowStats(String index) {
|
||||
return shardFollowStats.get(index);
|
||||
}
|
||||
|
||||
public Map<String, List<ShardFollowStats>> getShardFollowStats() {
|
||||
return shardFollowStats;
|
||||
}
|
||||
|
||||
public static final class ShardFollowStats {
|
||||
|
||||
|
||||
static final ParseField LEADER_CLUSTER = new ParseField("remote_cluster");
|
||||
static final ParseField LEADER_INDEX = new ParseField("leader_index");
|
||||
static final ParseField FOLLOWER_INDEX = new ParseField("follower_index");
|
||||
static final ParseField SHARD_ID = new ParseField("shard_id");
|
||||
static final ParseField LEADER_GLOBAL_CHECKPOINT_FIELD = new ParseField("leader_global_checkpoint");
|
||||
static final ParseField LEADER_MAX_SEQ_NO_FIELD = new ParseField("leader_max_seq_no");
|
||||
static final ParseField FOLLOWER_GLOBAL_CHECKPOINT_FIELD = new ParseField("follower_global_checkpoint");
|
||||
static final ParseField FOLLOWER_MAX_SEQ_NO_FIELD = new ParseField("follower_max_seq_no");
|
||||
static final ParseField LAST_REQUESTED_SEQ_NO_FIELD = new ParseField("last_requested_seq_no");
|
||||
static final ParseField OUTSTANDING_READ_REQUESTS = new ParseField("outstanding_read_requests");
|
||||
static final ParseField OUTSTANDING_WRITE_REQUESTS = new ParseField("outstanding_write_requests");
|
||||
static final ParseField WRITE_BUFFER_OPERATION_COUNT_FIELD = new ParseField("write_buffer_operation_count");
|
||||
static final ParseField WRITE_BUFFER_SIZE_IN_BYTES_FIELD = new ParseField("write_buffer_size_in_bytes");
|
||||
static final ParseField FOLLOWER_MAPPING_VERSION_FIELD = new ParseField("follower_mapping_version");
|
||||
static final ParseField FOLLOWER_SETTINGS_VERSION_FIELD = new ParseField("follower_settings_version");
|
||||
static final ParseField TOTAL_READ_TIME_MILLIS_FIELD = new ParseField("total_read_time_millis");
|
||||
static final ParseField TOTAL_READ_REMOTE_EXEC_TIME_MILLIS_FIELD = new ParseField("total_read_remote_exec_time_millis");
|
||||
static final ParseField SUCCESSFUL_READ_REQUESTS_FIELD = new ParseField("successful_read_requests");
|
||||
static final ParseField FAILED_READ_REQUESTS_FIELD = new ParseField("failed_read_requests");
|
||||
static final ParseField OPERATIONS_READ_FIELD = new ParseField("operations_read");
|
||||
static final ParseField BYTES_READ = new ParseField("bytes_read");
|
||||
static final ParseField TOTAL_WRITE_TIME_MILLIS_FIELD = new ParseField("total_write_time_millis");
|
||||
static final ParseField SUCCESSFUL_WRITE_REQUESTS_FIELD = new ParseField("successful_write_requests");
|
||||
static final ParseField FAILED_WRITE_REQUEST_FIELD = new ParseField("failed_write_requests");
|
||||
static final ParseField OPERATIONS_WRITTEN = new ParseField("operations_written");
|
||||
static final ParseField READ_EXCEPTIONS = new ParseField("read_exceptions");
|
||||
static final ParseField TIME_SINCE_LAST_READ_MILLIS_FIELD = new ParseField("time_since_last_read_millis");
|
||||
static final ParseField FATAL_EXCEPTION = new ParseField("fatal_exception");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static final ConstructingObjectParser<ShardFollowStats, Void> PARSER =
|
||||
new ConstructingObjectParser<>(
|
||||
"shard-follow-stats",
|
||||
args -> new ShardFollowStats(
|
||||
(String) args[0],
|
||||
(String) args[1],
|
||||
(String) args[2],
|
||||
(int) args[3],
|
||||
(long) args[4],
|
||||
(long) args[5],
|
||||
(long) args[6],
|
||||
(long) args[7],
|
||||
(long) args[8],
|
||||
(int) args[9],
|
||||
(int) args[10],
|
||||
(int) args[11],
|
||||
(long) args[12],
|
||||
(long) args[13],
|
||||
(long) args[14],
|
||||
(long) args[15],
|
||||
(long) args[16],
|
||||
(long) args[17],
|
||||
(long) args[18],
|
||||
(long) args[19],
|
||||
(long) args[20],
|
||||
(long) args[21],
|
||||
(long) args[22],
|
||||
(long) args[23],
|
||||
(long) args[24],
|
||||
(long) args[25],
|
||||
new TreeMap<>(
|
||||
((List<Map.Entry<Long, Tuple<Integer, ElasticsearchException>>>) args[26])
|
||||
.stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))),
|
||||
(ElasticsearchException) args[27]));
|
||||
|
||||
static final ConstructingObjectParser<Map.Entry<Long, Tuple<Integer, ElasticsearchException>>, Void> READ_EXCEPTIONS_ENTRY_PARSER =
|
||||
new ConstructingObjectParser<>(
|
||||
"shard-follow-stats-read-exceptions-entry",
|
||||
args -> new AbstractMap.SimpleEntry<>((long) args[0], Tuple.tuple((Integer) args[1], (ElasticsearchException)args[2])));
|
||||
|
||||
static {
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), LEADER_CLUSTER);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), LEADER_INDEX);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), FOLLOWER_INDEX);
|
||||
PARSER.declareInt(ConstructingObjectParser.constructorArg(), SHARD_ID);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), LEADER_GLOBAL_CHECKPOINT_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), LEADER_MAX_SEQ_NO_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), FOLLOWER_GLOBAL_CHECKPOINT_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), FOLLOWER_MAX_SEQ_NO_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), LAST_REQUESTED_SEQ_NO_FIELD);
|
||||
PARSER.declareInt(ConstructingObjectParser.constructorArg(), OUTSTANDING_READ_REQUESTS);
|
||||
PARSER.declareInt(ConstructingObjectParser.constructorArg(), OUTSTANDING_WRITE_REQUESTS);
|
||||
PARSER.declareInt(ConstructingObjectParser.constructorArg(), WRITE_BUFFER_OPERATION_COUNT_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), WRITE_BUFFER_SIZE_IN_BYTES_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), FOLLOWER_MAPPING_VERSION_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), FOLLOWER_SETTINGS_VERSION_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), TOTAL_READ_TIME_MILLIS_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), TOTAL_READ_REMOTE_EXEC_TIME_MILLIS_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), SUCCESSFUL_READ_REQUESTS_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), FAILED_READ_REQUESTS_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), OPERATIONS_READ_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), BYTES_READ);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), TOTAL_WRITE_TIME_MILLIS_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), SUCCESSFUL_WRITE_REQUESTS_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), FAILED_WRITE_REQUEST_FIELD);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), OPERATIONS_WRITTEN);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), TIME_SINCE_LAST_READ_MILLIS_FIELD);
|
||||
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), READ_EXCEPTIONS_ENTRY_PARSER, READ_EXCEPTIONS);
|
||||
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(),
|
||||
(p, c) -> ElasticsearchException.fromXContent(p),
|
||||
FATAL_EXCEPTION);
|
||||
}
|
||||
|
||||
static final ParseField READ_EXCEPTIONS_ENTRY_FROM_SEQ_NO = new ParseField("from_seq_no");
|
||||
static final ParseField READ_EXCEPTIONS_RETRIES = new ParseField("retries");
|
||||
static final ParseField READ_EXCEPTIONS_ENTRY_EXCEPTION = new ParseField("exception");
|
||||
|
||||
static {
|
||||
READ_EXCEPTIONS_ENTRY_PARSER.declareLong(ConstructingObjectParser.constructorArg(), READ_EXCEPTIONS_ENTRY_FROM_SEQ_NO);
|
||||
READ_EXCEPTIONS_ENTRY_PARSER.declareInt(ConstructingObjectParser.constructorArg(), READ_EXCEPTIONS_RETRIES);
|
||||
READ_EXCEPTIONS_ENTRY_PARSER.declareObject(
|
||||
ConstructingObjectParser.constructorArg(),
|
||||
(p, c) -> ElasticsearchException.fromXContent(p),
|
||||
READ_EXCEPTIONS_ENTRY_EXCEPTION);
|
||||
}
|
||||
|
||||
private final String remoteCluster;
|
||||
private final String leaderIndex;
|
||||
private final String followerIndex;
|
||||
private final int shardId;
|
||||
private final long leaderGlobalCheckpoint;
|
||||
private final long leaderMaxSeqNo;
|
||||
private final long followerGlobalCheckpoint;
|
||||
private final long followerMaxSeqNo;
|
||||
private final long lastRequestedSeqNo;
|
||||
private final int outstandingReadRequests;
|
||||
private final int outstandingWriteRequests;
|
||||
private final int writeBufferOperationCount;
|
||||
private final long writeBufferSizeInBytes;
|
||||
private final long followerMappingVersion;
|
||||
private final long followerSettingsVersion;
|
||||
private final long totalReadTimeMillis;
|
||||
private final long totalReadRemoteExecTimeMillis;
|
||||
private final long successfulReadRequests;
|
||||
private final long failedReadRequests;
|
||||
private final long operationsReads;
|
||||
private final long bytesRead;
|
||||
private final long totalWriteTimeMillis;
|
||||
private final long successfulWriteRequests;
|
||||
private final long failedWriteRequests;
|
||||
private final long operationWritten;
|
||||
private final long timeSinceLastReadMillis;
|
||||
private final NavigableMap<Long, Tuple<Integer, ElasticsearchException>> readExceptions;
|
||||
private final ElasticsearchException fatalException;
|
||||
|
||||
ShardFollowStats(String remoteCluster,
|
||||
String leaderIndex,
|
||||
String followerIndex,
|
||||
int shardId,
|
||||
long leaderGlobalCheckpoint,
|
||||
long leaderMaxSeqNo,
|
||||
long followerGlobalCheckpoint,
|
||||
long followerMaxSeqNo,
|
||||
long lastRequestedSeqNo,
|
||||
int outstandingReadRequests,
|
||||
int outstandingWriteRequests,
|
||||
int writeBufferOperationCount,
|
||||
long writeBufferSizeInBytes,
|
||||
long followerMappingVersion,
|
||||
long followerSettingsVersion,
|
||||
long totalReadTimeMillis,
|
||||
long totalReadRemoteExecTimeMillis,
|
||||
long successfulReadRequests,
|
||||
long failedReadRequests,
|
||||
long operationsReads,
|
||||
long bytesRead,
|
||||
long totalWriteTimeMillis,
|
||||
long successfulWriteRequests,
|
||||
long failedWriteRequests,
|
||||
long operationWritten,
|
||||
long timeSinceLastReadMillis,
|
||||
NavigableMap<Long, Tuple<Integer, ElasticsearchException>> readExceptions,
|
||||
ElasticsearchException fatalException) {
|
||||
this.remoteCluster = remoteCluster;
|
||||
this.leaderIndex = leaderIndex;
|
||||
this.followerIndex = followerIndex;
|
||||
this.shardId = shardId;
|
||||
this.leaderGlobalCheckpoint = leaderGlobalCheckpoint;
|
||||
this.leaderMaxSeqNo = leaderMaxSeqNo;
|
||||
this.followerGlobalCheckpoint = followerGlobalCheckpoint;
|
||||
this.followerMaxSeqNo = followerMaxSeqNo;
|
||||
this.lastRequestedSeqNo = lastRequestedSeqNo;
|
||||
this.outstandingReadRequests = outstandingReadRequests;
|
||||
this.outstandingWriteRequests = outstandingWriteRequests;
|
||||
this.writeBufferOperationCount = writeBufferOperationCount;
|
||||
this.writeBufferSizeInBytes = writeBufferSizeInBytes;
|
||||
this.followerMappingVersion = followerMappingVersion;
|
||||
this.followerSettingsVersion = followerSettingsVersion;
|
||||
this.totalReadTimeMillis = totalReadTimeMillis;
|
||||
this.totalReadRemoteExecTimeMillis = totalReadRemoteExecTimeMillis;
|
||||
this.successfulReadRequests = successfulReadRequests;
|
||||
this.failedReadRequests = failedReadRequests;
|
||||
this.operationsReads = operationsReads;
|
||||
this.bytesRead = bytesRead;
|
||||
this.totalWriteTimeMillis = totalWriteTimeMillis;
|
||||
this.successfulWriteRequests = successfulWriteRequests;
|
||||
this.failedWriteRequests = failedWriteRequests;
|
||||
this.operationWritten = operationWritten;
|
||||
this.timeSinceLastReadMillis = timeSinceLastReadMillis;
|
||||
this.readExceptions = readExceptions;
|
||||
this.fatalException = fatalException;
|
||||
}
|
||||
|
||||
public String getRemoteCluster() {
|
||||
return remoteCluster;
|
||||
}
|
||||
|
||||
public String getLeaderIndex() {
|
||||
return leaderIndex;
|
||||
}
|
||||
|
||||
public String getFollowerIndex() {
|
||||
return followerIndex;
|
||||
}
|
||||
|
||||
public int getShardId() {
|
||||
return shardId;
|
||||
}
|
||||
|
||||
public long getLeaderGlobalCheckpoint() {
|
||||
return leaderGlobalCheckpoint;
|
||||
}
|
||||
|
||||
public long getLeaderMaxSeqNo() {
|
||||
return leaderMaxSeqNo;
|
||||
}
|
||||
|
||||
public long getFollowerGlobalCheckpoint() {
|
||||
return followerGlobalCheckpoint;
|
||||
}
|
||||
|
||||
public long getFollowerMaxSeqNo() {
|
||||
return followerMaxSeqNo;
|
||||
}
|
||||
|
||||
public long getLastRequestedSeqNo() {
|
||||
return lastRequestedSeqNo;
|
||||
}
|
||||
|
||||
public int getOutstandingReadRequests() {
|
||||
return outstandingReadRequests;
|
||||
}
|
||||
|
||||
public int getOutstandingWriteRequests() {
|
||||
return outstandingWriteRequests;
|
||||
}
|
||||
|
||||
public int getWriteBufferOperationCount() {
|
||||
return writeBufferOperationCount;
|
||||
}
|
||||
|
||||
public long getWriteBufferSizeInBytes() {
|
||||
return writeBufferSizeInBytes;
|
||||
}
|
||||
|
||||
public long getFollowerMappingVersion() {
|
||||
return followerMappingVersion;
|
||||
}
|
||||
|
||||
public long getFollowerSettingsVersion() {
|
||||
return followerSettingsVersion;
|
||||
}
|
||||
|
||||
public long getTotalReadTimeMillis() {
|
||||
return totalReadTimeMillis;
|
||||
}
|
||||
|
||||
public long getTotalReadRemoteExecTimeMillis() {
|
||||
return totalReadRemoteExecTimeMillis;
|
||||
}
|
||||
|
||||
public long getSuccessfulReadRequests() {
|
||||
return successfulReadRequests;
|
||||
}
|
||||
|
||||
public long getFailedReadRequests() {
|
||||
return failedReadRequests;
|
||||
}
|
||||
|
||||
public long getOperationsReads() {
|
||||
return operationsReads;
|
||||
}
|
||||
|
||||
public long getBytesRead() {
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
public long getTotalWriteTimeMillis() {
|
||||
return totalWriteTimeMillis;
|
||||
}
|
||||
|
||||
public long getSuccessfulWriteRequests() {
|
||||
return successfulWriteRequests;
|
||||
}
|
||||
|
||||
public long getFailedWriteRequests() {
|
||||
return failedWriteRequests;
|
||||
}
|
||||
|
||||
public long getOperationWritten() {
|
||||
return operationWritten;
|
||||
}
|
||||
|
||||
public long getTimeSinceLastReadMillis() {
|
||||
return timeSinceLastReadMillis;
|
||||
}
|
||||
|
||||
public NavigableMap<Long, Tuple<Integer, ElasticsearchException>> getReadExceptions() {
|
||||
return readExceptions;
|
||||
}
|
||||
|
||||
public ElasticsearchException getFatalException() {
|
||||
return fatalException;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -29,9 +29,12 @@ import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
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.GetAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.GetAutoFollowPatternResponse;
|
||||
import org.elasticsearch.client.ccr.IndicesFollowStats.ShardFollowStats;
|
||||
import org.elasticsearch.client.ccr.PauseFollowRequest;
|
||||
import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.PutFollowRequest;
|
||||
@ -39,7 +42,6 @@ import org.elasticsearch.client.ccr.PutFollowResponse;
|
||||
import org.elasticsearch.client.ccr.ResumeFollowRequest;
|
||||
import org.elasticsearch.client.ccr.UnfollowRequest;
|
||||
import org.elasticsearch.client.core.AcknowledgedResponse;
|
||||
import org.elasticsearch.common.xcontent.ObjectPath;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
@ -47,6 +49,7 @@ import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
@ -104,6 +107,15 @@ public class CCRIT extends ESRestHighLevelClientTestCase {
|
||||
assertThat(leaderSearchResponse.getHits().getTotalHits(), equalTo(1L));
|
||||
|
||||
assertBusy(() -> {
|
||||
CcrStatsRequest ccrStatsRequest = new CcrStatsRequest();
|
||||
CcrStatsResponse ccrStatsResponse = execute(ccrStatsRequest, ccrClient::getCcrStats, ccrClient::getCcrStatsAsync);
|
||||
List<ShardFollowStats> shardFollowStats = ccrStatsResponse.getIndicesFollowStats().getShardFollowStats("follower");
|
||||
long followerGlobalCheckpoint = shardFollowStats.stream()
|
||||
.mapToLong(ShardFollowStats::getFollowerGlobalCheckpoint)
|
||||
.max()
|
||||
.getAsLong();
|
||||
assertThat(followerGlobalCheckpoint, equalTo(0L));
|
||||
|
||||
SearchRequest followerSearchRequest = new SearchRequest("follower");
|
||||
SearchResponse followerSearchResponse = highLevelClient().search(followerSearchRequest, RequestOptions.DEFAULT);
|
||||
assertThat(followerSearchResponse.getHits().getTotalHits(), equalTo(1L));
|
||||
@ -120,6 +132,15 @@ public class CCRIT extends ESRestHighLevelClientTestCase {
|
||||
assertThat(resumeFollowResponse.isAcknowledged(), is(true));
|
||||
|
||||
assertBusy(() -> {
|
||||
CcrStatsRequest ccrStatsRequest = new CcrStatsRequest();
|
||||
CcrStatsResponse ccrStatsResponse = execute(ccrStatsRequest, ccrClient::getCcrStats, ccrClient::getCcrStatsAsync);
|
||||
List<ShardFollowStats> shardFollowStats = ccrStatsResponse.getIndicesFollowStats().getShardFollowStats("follower");
|
||||
long followerGlobalCheckpoint = shardFollowStats.stream()
|
||||
.mapToLong(ShardFollowStats::getFollowerGlobalCheckpoint)
|
||||
.max()
|
||||
.getAsLong();
|
||||
assertThat(followerGlobalCheckpoint, equalTo(1L));
|
||||
|
||||
SearchRequest followerSearchRequest = new SearchRequest("follower");
|
||||
SearchResponse followerSearchResponse = highLevelClient().search(followerSearchRequest, RequestOptions.DEFAULT);
|
||||
assertThat(followerSearchResponse.getHits().getTotalHits(), equalTo(2L));
|
||||
@ -156,15 +177,12 @@ public class CCRIT extends ESRestHighLevelClientTestCase {
|
||||
assertThat(response.isAcknowledged(), is(true));
|
||||
|
||||
assertBusy(() -> {
|
||||
assertThat(indexExists("copy-logs-20200101"), is(true));
|
||||
// TODO: replace with HLRC follow stats when available:
|
||||
Map<String, Object> rsp = toMap(client().performRequest(new Request("GET", "/copy-logs-20200101/_ccr/stats")));
|
||||
String index = null;
|
||||
try {
|
||||
index = ObjectPath.eval("indices.0.index", rsp);
|
||||
} catch (Exception e){ }
|
||||
assertThat(index, equalTo("copy-logs-20200101"));
|
||||
CcrStatsRequest ccrStatsRequest = new CcrStatsRequest();
|
||||
CcrStatsResponse ccrStatsResponse = execute(ccrStatsRequest, ccrClient::getCcrStats, ccrClient::getCcrStatsAsync);
|
||||
assertThat(ccrStatsResponse.getAutoFollowStats().getNumberOfSuccessfulFollowIndices(), equalTo(1L));
|
||||
assertThat(ccrStatsResponse.getIndicesFollowStats().getShardFollowStats("copy-logs-20200101"), notNullValue());
|
||||
});
|
||||
assertThat(indexExists("copy-logs-20200101"), is(true));
|
||||
|
||||
GetAutoFollowPatternRequest getAutoFollowPatternRequest =
|
||||
randomBoolean() ? new GetAutoFollowPatternRequest("pattern1") : new GetAutoFollowPatternRequest();
|
||||
|
@ -0,0 +1,376 @@
|
||||
/*
|
||||
* 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.ElasticsearchException;
|
||||
import org.elasticsearch.client.ccr.IndicesFollowStats.ShardFollowStats;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.unit.ByteSizeUnit;
|
||||
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.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester;
|
||||
import static org.hamcrest.Matchers.anyOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
||||
public class CcrStatsResponseTests extends ESTestCase {
|
||||
|
||||
public void testFromXContent() throws IOException {
|
||||
xContentTester(this::createParser,
|
||||
CcrStatsResponseTests::createTestInstance,
|
||||
CcrStatsResponseTests::toXContent,
|
||||
CcrStatsResponse::fromXContent)
|
||||
.supportsUnknownFields(false)
|
||||
.assertEqualsConsumer(CcrStatsResponseTests::assertEqualInstances)
|
||||
.assertToXContentEquivalence(false)
|
||||
.test();
|
||||
}
|
||||
|
||||
// Needed, because exceptions in IndicesFollowStats and AutoFollowStats cannot be compared
|
||||
private static void assertEqualInstances(CcrStatsResponse expectedInstance, CcrStatsResponse newInstance) {
|
||||
assertNotSame(expectedInstance, newInstance);
|
||||
|
||||
{
|
||||
AutoFollowStats newAutoFollowStats = newInstance.getAutoFollowStats();
|
||||
AutoFollowStats expectedAutoFollowStats = expectedInstance.getAutoFollowStats();
|
||||
assertThat(newAutoFollowStats.getNumberOfSuccessfulFollowIndices(),
|
||||
equalTo(expectedAutoFollowStats.getNumberOfSuccessfulFollowIndices()));
|
||||
assertThat(newAutoFollowStats.getNumberOfFailedRemoteClusterStateRequests(),
|
||||
equalTo(expectedAutoFollowStats.getNumberOfFailedRemoteClusterStateRequests()));
|
||||
assertThat(newAutoFollowStats.getNumberOfFailedFollowIndices(),
|
||||
equalTo(expectedAutoFollowStats.getNumberOfFailedFollowIndices()));
|
||||
assertThat(newAutoFollowStats.getRecentAutoFollowErrors().size(),
|
||||
equalTo(expectedAutoFollowStats.getRecentAutoFollowErrors().size()));
|
||||
assertThat(newAutoFollowStats.getRecentAutoFollowErrors().keySet(),
|
||||
equalTo(expectedAutoFollowStats.getRecentAutoFollowErrors().keySet()));
|
||||
for (final Map.Entry<String, ElasticsearchException> entry : newAutoFollowStats.getRecentAutoFollowErrors().entrySet()) {
|
||||
// x-content loses the exception
|
||||
final ElasticsearchException expected = expectedAutoFollowStats.getRecentAutoFollowErrors().get(entry.getKey());
|
||||
assertThat(entry.getValue().getMessage(), containsString(expected.getMessage()));
|
||||
assertNotNull(entry.getValue().getCause());
|
||||
assertThat(
|
||||
entry.getValue().getCause(),
|
||||
anyOf(instanceOf(ElasticsearchException.class), instanceOf(IllegalStateException.class)));
|
||||
assertThat(entry.getValue().getCause().getMessage(), containsString(expected.getCause().getMessage()));
|
||||
}
|
||||
}
|
||||
{
|
||||
IndicesFollowStats newIndicesFollowStats = newInstance.getIndicesFollowStats();
|
||||
IndicesFollowStats expectedIndicesFollowStats = expectedInstance.getIndicesFollowStats();
|
||||
assertThat(newIndicesFollowStats.getShardFollowStats().size(),
|
||||
equalTo(expectedIndicesFollowStats.getShardFollowStats().size()));
|
||||
assertThat(newIndicesFollowStats.getShardFollowStats().keySet(),
|
||||
equalTo(expectedIndicesFollowStats.getShardFollowStats().keySet()));
|
||||
for (Map.Entry<String, List<ShardFollowStats>> indexEntry : newIndicesFollowStats.getShardFollowStats().entrySet()) {
|
||||
List<ShardFollowStats> newStats = indexEntry.getValue();
|
||||
List<ShardFollowStats> expectedStats = expectedIndicesFollowStats.getShardFollowStats(indexEntry.getKey());
|
||||
assertThat(newStats.size(), equalTo(expectedStats.size()));
|
||||
for (int i = 0; i < newStats.size(); i++) {
|
||||
ShardFollowStats actualShardFollowStats = newStats.get(i);
|
||||
ShardFollowStats expectedShardFollowStats = expectedStats.get(i);
|
||||
|
||||
assertThat(actualShardFollowStats.getRemoteCluster(), equalTo(expectedShardFollowStats.getRemoteCluster()));
|
||||
assertThat(actualShardFollowStats.getLeaderIndex(), equalTo(expectedShardFollowStats.getLeaderIndex()));
|
||||
assertThat(actualShardFollowStats.getFollowerIndex(), equalTo(expectedShardFollowStats.getFollowerIndex()));
|
||||
assertThat(actualShardFollowStats.getShardId(), equalTo(expectedShardFollowStats.getShardId()));
|
||||
assertThat(actualShardFollowStats.getLeaderGlobalCheckpoint(),
|
||||
equalTo(expectedShardFollowStats.getLeaderGlobalCheckpoint()));
|
||||
assertThat(actualShardFollowStats.getLeaderMaxSeqNo(), equalTo(expectedShardFollowStats.getLeaderMaxSeqNo()));
|
||||
assertThat(actualShardFollowStats.getFollowerGlobalCheckpoint(),
|
||||
equalTo(expectedShardFollowStats.getFollowerGlobalCheckpoint()));
|
||||
assertThat(actualShardFollowStats.getLastRequestedSeqNo(), equalTo(expectedShardFollowStats.getLastRequestedSeqNo()));
|
||||
assertThat(actualShardFollowStats.getOutstandingReadRequests(),
|
||||
equalTo(expectedShardFollowStats.getOutstandingReadRequests()));
|
||||
assertThat(actualShardFollowStats.getOutstandingWriteRequests(),
|
||||
equalTo(expectedShardFollowStats.getOutstandingWriteRequests()));
|
||||
assertThat(actualShardFollowStats.getWriteBufferOperationCount(),
|
||||
equalTo(expectedShardFollowStats.getWriteBufferOperationCount()));
|
||||
assertThat(actualShardFollowStats.getFollowerMappingVersion(),
|
||||
equalTo(expectedShardFollowStats.getFollowerMappingVersion()));
|
||||
assertThat(actualShardFollowStats.getFollowerSettingsVersion(),
|
||||
equalTo(expectedShardFollowStats.getFollowerSettingsVersion()));
|
||||
assertThat(actualShardFollowStats.getTotalReadTimeMillis(),
|
||||
equalTo(expectedShardFollowStats.getTotalReadTimeMillis()));
|
||||
assertThat(actualShardFollowStats.getSuccessfulReadRequests(),
|
||||
equalTo(expectedShardFollowStats.getSuccessfulReadRequests()));
|
||||
assertThat(actualShardFollowStats.getFailedReadRequests(), equalTo(expectedShardFollowStats.getFailedReadRequests()));
|
||||
assertThat(actualShardFollowStats.getOperationsReads(), equalTo(expectedShardFollowStats.getOperationsReads()));
|
||||
assertThat(actualShardFollowStats.getBytesRead(), equalTo(expectedShardFollowStats.getBytesRead()));
|
||||
assertThat(actualShardFollowStats.getTotalWriteTimeMillis(),
|
||||
equalTo(expectedShardFollowStats.getTotalWriteTimeMillis()));
|
||||
assertThat(actualShardFollowStats.getSuccessfulWriteRequests(),
|
||||
equalTo(expectedShardFollowStats.getSuccessfulWriteRequests()));
|
||||
assertThat(actualShardFollowStats.getFailedWriteRequests(),
|
||||
equalTo(expectedShardFollowStats.getFailedWriteRequests()));
|
||||
assertThat(actualShardFollowStats.getOperationWritten(), equalTo(expectedShardFollowStats.getOperationWritten()));
|
||||
assertThat(actualShardFollowStats.getReadExceptions().size(),
|
||||
equalTo(expectedShardFollowStats.getReadExceptions().size()));
|
||||
assertThat(actualShardFollowStats.getReadExceptions().keySet(),
|
||||
equalTo(expectedShardFollowStats.getReadExceptions().keySet()));
|
||||
for (final Map.Entry<Long, Tuple<Integer, ElasticsearchException>> entry :
|
||||
actualShardFollowStats.getReadExceptions().entrySet()) {
|
||||
final Tuple<Integer, ElasticsearchException> expectedTuple =
|
||||
expectedShardFollowStats.getReadExceptions().get(entry.getKey());
|
||||
assertThat(entry.getValue().v1(), equalTo(expectedTuple.v1()));
|
||||
// x-content loses the exception
|
||||
final ElasticsearchException expected = expectedTuple.v2();
|
||||
assertThat(entry.getValue().v2().getMessage(), containsString(expected.getMessage()));
|
||||
assertNotNull(entry.getValue().v2().getCause());
|
||||
assertThat(
|
||||
entry.getValue().v2().getCause(),
|
||||
anyOf(instanceOf(ElasticsearchException.class), instanceOf(IllegalStateException.class)));
|
||||
assertThat(entry.getValue().v2().getCause().getMessage(), containsString(expected.getCause().getMessage()));
|
||||
}
|
||||
assertThat(actualShardFollowStats.getTimeSinceLastReadMillis(),
|
||||
equalTo(expectedShardFollowStats.getTimeSinceLastReadMillis()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void toXContent(CcrStatsResponse response, XContentBuilder builder) throws IOException {
|
||||
builder.startObject();
|
||||
{
|
||||
AutoFollowStats autoFollowStats = response.getAutoFollowStats();
|
||||
builder.startObject(CcrStatsResponse.AUTO_FOLLOW_STATS_FIELD.getPreferredName());
|
||||
{
|
||||
builder.field(AutoFollowStats.NUMBER_OF_SUCCESSFUL_INDICES_AUTO_FOLLOWED.getPreferredName(),
|
||||
autoFollowStats.getNumberOfSuccessfulFollowIndices());
|
||||
builder.field(AutoFollowStats.NUMBER_OF_FAILED_REMOTE_CLUSTER_STATE_REQUESTS.getPreferredName(),
|
||||
autoFollowStats.getNumberOfFailedRemoteClusterStateRequests());
|
||||
builder.field(AutoFollowStats.NUMBER_OF_FAILED_INDICES_AUTO_FOLLOWED.getPreferredName(),
|
||||
autoFollowStats.getNumberOfFailedFollowIndices());
|
||||
builder.startArray(AutoFollowStats.RECENT_AUTO_FOLLOW_ERRORS.getPreferredName());
|
||||
for (Map.Entry<String, ElasticsearchException> entry : autoFollowStats.getRecentAutoFollowErrors().entrySet()) {
|
||||
builder.startObject();
|
||||
{
|
||||
builder.field(AutoFollowStats.LEADER_INDEX.getPreferredName(), entry.getKey());
|
||||
builder.field(AutoFollowStats.AUTO_FOLLOW_EXCEPTION.getPreferredName());
|
||||
builder.startObject();
|
||||
{
|
||||
ElasticsearchException.generateThrowableXContent(builder, ToXContent.EMPTY_PARAMS, entry.getValue());
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
IndicesFollowStats indicesFollowStats = response.getIndicesFollowStats();
|
||||
builder.startObject(CcrStatsResponse.FOLLOW_STATS_FIELD.getPreferredName());
|
||||
{
|
||||
builder.startArray(IndicesFollowStats.INDICES_FIELD.getPreferredName());
|
||||
for (Map.Entry<String, List<ShardFollowStats>> indexEntry :
|
||||
indicesFollowStats.getShardFollowStats().entrySet()) {
|
||||
builder.startObject();
|
||||
{
|
||||
builder.field(IndicesFollowStats.INDEX_FIELD.getPreferredName(), indexEntry.getKey());
|
||||
builder.startArray(IndicesFollowStats.SHARDS_FIELD.getPreferredName());
|
||||
{
|
||||
for (ShardFollowStats stats : indexEntry.getValue()) {
|
||||
builder.startObject();
|
||||
{
|
||||
builder.field(ShardFollowStats.LEADER_CLUSTER.getPreferredName(), stats.getRemoteCluster());
|
||||
builder.field(ShardFollowStats.LEADER_INDEX.getPreferredName(), stats.getLeaderIndex());
|
||||
builder.field(ShardFollowStats.FOLLOWER_INDEX.getPreferredName(), stats.getFollowerIndex());
|
||||
builder.field(ShardFollowStats.SHARD_ID.getPreferredName(), stats.getShardId());
|
||||
builder.field(ShardFollowStats.LEADER_GLOBAL_CHECKPOINT_FIELD.getPreferredName(),
|
||||
stats.getLeaderGlobalCheckpoint());
|
||||
builder.field(ShardFollowStats.LEADER_MAX_SEQ_NO_FIELD.getPreferredName(), stats.getLeaderMaxSeqNo());
|
||||
builder.field(ShardFollowStats.FOLLOWER_GLOBAL_CHECKPOINT_FIELD.getPreferredName(),
|
||||
stats.getFollowerGlobalCheckpoint());
|
||||
builder.field(ShardFollowStats.FOLLOWER_MAX_SEQ_NO_FIELD.getPreferredName(),
|
||||
stats.getFollowerMaxSeqNo());
|
||||
builder.field(ShardFollowStats.LAST_REQUESTED_SEQ_NO_FIELD.getPreferredName(),
|
||||
stats.getLastRequestedSeqNo());
|
||||
builder.field(ShardFollowStats.OUTSTANDING_READ_REQUESTS.getPreferredName(),
|
||||
stats.getOutstandingReadRequests());
|
||||
builder.field(ShardFollowStats.OUTSTANDING_WRITE_REQUESTS.getPreferredName(),
|
||||
stats.getOutstandingWriteRequests());
|
||||
builder.field(ShardFollowStats.WRITE_BUFFER_OPERATION_COUNT_FIELD.getPreferredName(),
|
||||
stats.getWriteBufferOperationCount());
|
||||
builder.humanReadableField(
|
||||
ShardFollowStats.WRITE_BUFFER_SIZE_IN_BYTES_FIELD.getPreferredName(),
|
||||
"write_buffer_size",
|
||||
new ByteSizeValue(stats.getWriteBufferSizeInBytes()));
|
||||
builder.field(ShardFollowStats.FOLLOWER_MAPPING_VERSION_FIELD.getPreferredName(),
|
||||
stats.getFollowerMappingVersion());
|
||||
builder.field(ShardFollowStats.FOLLOWER_SETTINGS_VERSION_FIELD.getPreferredName(),
|
||||
stats.getFollowerSettingsVersion());
|
||||
builder.humanReadableField(
|
||||
ShardFollowStats.TOTAL_READ_TIME_MILLIS_FIELD.getPreferredName(),
|
||||
"total_read_time",
|
||||
new TimeValue(stats.getTotalReadTimeMillis(), TimeUnit.MILLISECONDS));
|
||||
builder.humanReadableField(
|
||||
ShardFollowStats.TOTAL_READ_REMOTE_EXEC_TIME_MILLIS_FIELD.getPreferredName(),
|
||||
"total_read_remote_exec_time",
|
||||
new TimeValue(stats.getTotalReadRemoteExecTimeMillis(), TimeUnit.MILLISECONDS));
|
||||
builder.field(ShardFollowStats.SUCCESSFUL_READ_REQUESTS_FIELD.getPreferredName(),
|
||||
stats.getSuccessfulReadRequests());
|
||||
builder.field(ShardFollowStats.FAILED_READ_REQUESTS_FIELD.getPreferredName(),
|
||||
stats.getFailedReadRequests());
|
||||
builder.field(ShardFollowStats.OPERATIONS_READ_FIELD.getPreferredName(), stats.getOperationsReads());
|
||||
builder.humanReadableField(
|
||||
ShardFollowStats.BYTES_READ.getPreferredName(),
|
||||
"total_read",
|
||||
new ByteSizeValue(stats.getBytesRead(), ByteSizeUnit.BYTES));
|
||||
builder.humanReadableField(
|
||||
ShardFollowStats.TOTAL_WRITE_TIME_MILLIS_FIELD.getPreferredName(),
|
||||
"total_write_time",
|
||||
new TimeValue(stats.getTotalWriteTimeMillis(), TimeUnit.MILLISECONDS));
|
||||
builder.field(ShardFollowStats.SUCCESSFUL_WRITE_REQUESTS_FIELD.getPreferredName(),
|
||||
stats.getSuccessfulWriteRequests());
|
||||
builder.field(ShardFollowStats.FAILED_WRITE_REQUEST_FIELD.getPreferredName(),
|
||||
stats.getFailedWriteRequests());
|
||||
builder.field(ShardFollowStats.OPERATIONS_WRITTEN.getPreferredName(), stats.getOperationWritten());
|
||||
builder.startArray(ShardFollowStats.READ_EXCEPTIONS.getPreferredName());
|
||||
{
|
||||
for (final Map.Entry<Long, Tuple<Integer, ElasticsearchException>> entry :
|
||||
stats.getReadExceptions().entrySet()) {
|
||||
builder.startObject();
|
||||
{
|
||||
builder.field(ShardFollowStats.READ_EXCEPTIONS_ENTRY_FROM_SEQ_NO.getPreferredName(),
|
||||
entry.getKey());
|
||||
builder.field(ShardFollowStats.READ_EXCEPTIONS_RETRIES.getPreferredName(),
|
||||
entry.getValue().v1());
|
||||
builder.field(ShardFollowStats.READ_EXCEPTIONS_ENTRY_EXCEPTION.getPreferredName());
|
||||
builder.startObject();
|
||||
{
|
||||
ElasticsearchException.generateThrowableXContent(builder, ToXContent.EMPTY_PARAMS,
|
||||
entry.getValue().v2());
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
builder.humanReadableField(
|
||||
ShardFollowStats.TIME_SINCE_LAST_READ_MILLIS_FIELD.getPreferredName(),
|
||||
"time_since_last_read",
|
||||
new TimeValue(stats.getTimeSinceLastReadMillis(), TimeUnit.MILLISECONDS));
|
||||
if (stats.getFatalException() != null) {
|
||||
builder.field(ShardFollowStats.FATAL_EXCEPTION.getPreferredName());
|
||||
builder.startObject();
|
||||
{
|
||||
ElasticsearchException.generateThrowableXContent(builder, ToXContent.EMPTY_PARAMS,
|
||||
stats.getFatalException());
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
private static CcrStatsResponse createTestInstance() {
|
||||
return new CcrStatsResponse(randomAutoFollowStats(), randomIndicesFollowStats());
|
||||
}
|
||||
|
||||
private static AutoFollowStats randomAutoFollowStats() {
|
||||
final int count = randomIntBetween(0, 16);
|
||||
final NavigableMap<String, ElasticsearchException> readExceptions = new TreeMap<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
readExceptions.put("" + i, new ElasticsearchException(new IllegalStateException("index [" + i + "]")));
|
||||
}
|
||||
return new AutoFollowStats(
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
readExceptions
|
||||
);
|
||||
}
|
||||
|
||||
private static IndicesFollowStats randomIndicesFollowStats() {
|
||||
int numIndices = randomIntBetween(0, 16);
|
||||
NavigableMap<String, List<ShardFollowStats>> shardFollowStats = new TreeMap<>();
|
||||
for (int i = 0; i < numIndices; i++) {
|
||||
String index = randomAlphaOfLength(4);
|
||||
int numShards = randomIntBetween(0, 5);
|
||||
List<ShardFollowStats> stats = new ArrayList<>(numShards);
|
||||
shardFollowStats.put(index, stats);
|
||||
for (int j = 0; j < numShards; j++) {
|
||||
final int count = randomIntBetween(0, 16);
|
||||
final NavigableMap<Long, Tuple<Integer, ElasticsearchException>> readExceptions = new TreeMap<>();
|
||||
for (long k = 0; k < count; k++) {
|
||||
readExceptions.put(k, new Tuple<>(randomIntBetween(0, Integer.MAX_VALUE),
|
||||
new ElasticsearchException(new IllegalStateException("index [" + k + "]"))));
|
||||
}
|
||||
|
||||
stats.add(new ShardFollowStats(
|
||||
randomAlphaOfLength(4),
|
||||
randomAlphaOfLength(4),
|
||||
randomAlphaOfLength(4),
|
||||
randomInt(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomIntBetween(0, Integer.MAX_VALUE),
|
||||
randomIntBetween(0, Integer.MAX_VALUE),
|
||||
randomIntBetween(0, Integer.MAX_VALUE),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomNonNegativeLong(),
|
||||
randomLong(),
|
||||
readExceptions,
|
||||
randomBoolean() ? new ElasticsearchException("fatal error") : null));
|
||||
}
|
||||
}
|
||||
return new IndicesFollowStats(shardFollowStats);
|
||||
}
|
||||
|
||||
}
|
@ -33,10 +33,14 @@ import org.elasticsearch.client.Request;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
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.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.PauseFollowRequest;
|
||||
import org.elasticsearch.client.ccr.PutAutoFollowPatternRequest;
|
||||
import org.elasticsearch.client.ccr.PutFollowRequest;
|
||||
@ -568,6 +572,57 @@ public class CCRDocumentationIT extends ESRestHighLevelClientTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetCCRStats() throws Exception {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
// tag::ccr-get-stats-request
|
||||
CcrStatsRequest request =
|
||||
new CcrStatsRequest(); // <1>
|
||||
// end::ccr-get-stats-request
|
||||
|
||||
// tag::ccr-get-stats-execute
|
||||
CcrStatsResponse response = client.ccr()
|
||||
.getCcrStats(request, RequestOptions.DEFAULT);
|
||||
// end::ccr-get-stats-execute
|
||||
|
||||
// tag::ccr-get-stats-response
|
||||
IndicesFollowStats indicesFollowStats =
|
||||
response.getIndicesFollowStats(); // <1>
|
||||
AutoFollowStats autoFollowStats =
|
||||
response.getAutoFollowStats(); // <2>
|
||||
// end::ccr-get-stats-response
|
||||
|
||||
// tag::ccr-get-stats-execute-listener
|
||||
ActionListener<CcrStatsResponse> listener =
|
||||
new ActionListener<CcrStatsResponse>() {
|
||||
@Override
|
||||
public void onResponse(CcrStatsResponse response) { // <1>
|
||||
IndicesFollowStats indicesFollowStats =
|
||||
response.getIndicesFollowStats();
|
||||
AutoFollowStats autoFollowStats =
|
||||
response.getAutoFollowStats();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
// <2>
|
||||
}
|
||||
};
|
||||
// end::ccr-get-stats-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-stats-execute-async
|
||||
client.ccr().getCcrStatsAsync(request,
|
||||
RequestOptions.DEFAULT, listener); // <1>
|
||||
// end::ccr-get-stats-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);
|
||||
}
|
||||
|
37
docs/java-rest/high-level/ccr/get_stats.asciidoc
Normal file
37
docs/java-rest/high-level/ccr/get_stats.asciidoc
Normal file
@ -0,0 +1,37 @@
|
||||
--
|
||||
:api: ccr-get-stats
|
||||
:request: CcrStatsRequest
|
||||
:response: CcrStatsResponse
|
||||
--
|
||||
|
||||
[id="{upid}-{api}"]
|
||||
=== Get CCR Stats API
|
||||
|
||||
|
||||
[id="{upid}-{api}-request"]
|
||||
==== Request
|
||||
|
||||
The Get CCR Stats API allows you to get statistics about index following and auto following.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests-file}[{api}-request]
|
||||
--------------------------------------------------
|
||||
<1> The request accepts no parameters.
|
||||
|
||||
[id="{upid}-{api}-response"]
|
||||
==== Response
|
||||
|
||||
The returned +{response}+ always includes index follow statistics of all follow indices and
|
||||
auto follow statistics.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests-file}[{api}-response]
|
||||
--------------------------------------------------
|
||||
<1> The follow stats of active follower indices.
|
||||
<2> The auto follow stats of the cluster that has been queried.
|
||||
|
||||
include::../execution.asciidoc[]
|
||||
|
||||
|
@ -473,6 +473,7 @@ 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-get-stats>>
|
||||
|
||||
include::ccr/put_follow.asciidoc[]
|
||||
include::ccr/pause_follow.asciidoc[]
|
||||
@ -481,6 +482,7 @@ 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[]
|
||||
include::ccr/get_stats.asciidoc[]
|
||||
|
||||
== Index Lifecycle Management APIs
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user