All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.elasticsearch.xpack.core.ilm.WaitForFollowShardTasksStep Maven / Gradle / Ivy
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.core.ilm;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.ccr.ShardFollowNodeTaskStatus;
import org.elasticsearch.xpack.core.ccr.action.FollowStatsAction;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static org.elasticsearch.xpack.core.ilm.UnfollowAction.CCR_METADATA_KEY;
final class WaitForFollowShardTasksStep extends AsyncWaitStep {
static final String NAME = "wait-for-follow-shard-tasks";
WaitForFollowShardTasksStep(StepKey key, StepKey nextStepKey, Client client) {
super(key, nextStepKey, client);
}
@Override
public boolean isRetryable() {
return true;
}
@Override
public void evaluateCondition(Metadata metadata, Index index, Listener listener, TimeValue masterTimeout) {
IndexMetadata indexMetadata = metadata.index(index);
Map customIndexMetadata = indexMetadata.getCustomData(CCR_METADATA_KEY);
if (customIndexMetadata == null) {
listener.onResponse(true, null);
return;
}
FollowStatsAction.StatsRequest request = new FollowStatsAction.StatsRequest();
request.setIndices(new String[]{index.getName()});
getClient().execute(FollowStatsAction.INSTANCE, request,
ActionListener.wrap(r -> handleResponse(r, listener), listener::onFailure));
}
void handleResponse(FollowStatsAction.StatsResponses responses, Listener listener) {
List unSyncedShardFollowStatuses = responses.getStatsResponses()
.stream()
.map(FollowStatsAction.StatsResponse::status)
.filter(shardFollowStatus -> shardFollowStatus.leaderGlobalCheckpoint() != shardFollowStatus.followerGlobalCheckpoint())
.collect(Collectors.toList());
// Follow stats api needs to return stats for follower index and all shard follow tasks should be synced:
boolean conditionMet = responses.getStatsResponses().size() > 0 && unSyncedShardFollowStatuses.isEmpty();
if (conditionMet) {
listener.onResponse(true, null);
} else {
List shardFollowTaskInfos = unSyncedShardFollowStatuses
.stream()
.map(status -> new Info.ShardFollowTaskInfo(status.followerIndex(), status.getShardId(),
status.leaderGlobalCheckpoint(), status.followerGlobalCheckpoint()))
.collect(Collectors.toList());
listener.onResponse(false, new Info(shardFollowTaskInfos));
}
}
static final class Info implements ToXContentObject {
static final ParseField SHARD_FOLLOW_TASKS = new ParseField("shard_follow_tasks");
static final ParseField MESSAGE = new ParseField("message");
private final List shardFollowTaskInfos;
Info(List shardFollowTaskInfos) {
this.shardFollowTaskInfos = shardFollowTaskInfos;
}
List getShardFollowTaskInfos() {
return shardFollowTaskInfos;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(SHARD_FOLLOW_TASKS.getPreferredName(), shardFollowTaskInfos);
String message;
if (shardFollowTaskInfos.size() > 0) {
message = "Waiting for [" + shardFollowTaskInfos.size() + "] shard follow tasks to be in sync";
} else {
message = "Waiting for following to be unpaused and all shard follow tasks to be up to date";
}
builder.field(MESSAGE.getPreferredName(), message);
builder.endObject();
return builder;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Info info = (Info) o;
return Objects.equals(shardFollowTaskInfos, info.shardFollowTaskInfos);
}
@Override
public int hashCode() {
return Objects.hash(shardFollowTaskInfos);
}
@Override
public String toString() {
return Strings.toString(this);
}
static final class ShardFollowTaskInfo implements ToXContentObject {
static final ParseField FOLLOWER_INDEX_FIELD = new ParseField("follower_index");
static final ParseField SHARD_ID_FIELD = new ParseField("shard_id");
static final ParseField LEADER_GLOBAL_CHECKPOINT_FIELD = new ParseField("leader_global_checkpoint");
static final ParseField FOLLOWER_GLOBAL_CHECKPOINT_FIELD = new ParseField("follower_global_checkpoint");
private final String followerIndex;
private final int shardId;
private final long leaderGlobalCheckpoint;
private final long followerGlobalCheckpoint;
ShardFollowTaskInfo(String followerIndex, int shardId, long leaderGlobalCheckpoint, long followerGlobalCheckpoint) {
this.followerIndex = followerIndex;
this.shardId = shardId;
this.leaderGlobalCheckpoint = leaderGlobalCheckpoint;
this.followerGlobalCheckpoint = followerGlobalCheckpoint;
}
String getFollowerIndex() {
return followerIndex;
}
int getShardId() {
return shardId;
}
long getLeaderGlobalCheckpoint() {
return leaderGlobalCheckpoint;
}
long getFollowerGlobalCheckpoint() {
return followerGlobalCheckpoint;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(FOLLOWER_INDEX_FIELD.getPreferredName(), followerIndex);
builder.field(SHARD_ID_FIELD.getPreferredName(), shardId);
builder.field(LEADER_GLOBAL_CHECKPOINT_FIELD.getPreferredName(), leaderGlobalCheckpoint);
builder.field(FOLLOWER_GLOBAL_CHECKPOINT_FIELD.getPreferredName(), followerGlobalCheckpoint);
builder.endObject();
return builder;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ShardFollowTaskInfo that = (ShardFollowTaskInfo) o;
return shardId == that.shardId &&
leaderGlobalCheckpoint == that.leaderGlobalCheckpoint &&
followerGlobalCheckpoint == that.followerGlobalCheckpoint &&
Objects.equals(followerIndex, that.followerIndex);
}
@Override
public int hashCode() {
return Objects.hash(followerIndex, shardId, leaderGlobalCheckpoint, followerGlobalCheckpoint);
}
}
}
}