org.opensearch.snapshots.SnapshotInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opensearch Show documentation
Show all versions of opensearch Show documentation
OpenSearch subproject :server
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
/*
* 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.
*/
/*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/
package org.opensearch.snapshots;
import org.opensearch.LegacyESVersion;
import org.opensearch.Version;
import org.opensearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
import org.opensearch.cluster.SnapshotsInProgress;
import org.opensearch.common.Nullable;
import org.opensearch.common.annotation.PublicApi;
import org.opensearch.common.time.DateFormatter;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.core.ParseField;
import org.opensearch.core.action.ShardOperationFailedException;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;
import org.opensearch.core.common.io.stream.Writeable;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.core.xcontent.ObjectParser;
import org.opensearch.core.xcontent.ToXContent;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.core.xcontent.XContentParser;
import org.opensearch.core.xcontent.XContentParserUtils;
import org.opensearch.repositories.IndexId;
import java.io.IOException;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Information about a snapshot
*
* @opensearch.api
*/
@PublicApi(since = "1.0.0")
public final class SnapshotInfo implements Comparable, ToXContent, Writeable {
public static final Version DATA_STREAMS_IN_SNAPSHOT = LegacyESVersion.V_7_9_0;
public static final String CONTEXT_MODE_PARAM = "context_mode";
public static final String CONTEXT_MODE_SNAPSHOT = "SNAPSHOT";
public static final Version METADATA_FIELD_INTRODUCED = LegacyESVersion.V_7_3_0;
private static final DateFormatter DATE_TIME_FORMATTER = DateFormatter.forPattern("strict_date_optional_time");
private static final String SNAPSHOT = "snapshot";
private static final String UUID = "uuid";
private static final String INDICES = "indices";
private static final String DATA_STREAMS = "data_streams";
private static final String STATE = "state";
private static final String REASON = "reason";
private static final String START_TIME = "start_time";
private static final String START_TIME_IN_MILLIS = "start_time_in_millis";
private static final String END_TIME = "end_time";
private static final String END_TIME_IN_MILLIS = "end_time_in_millis";
private static final String DURATION = "duration";
private static final String DURATION_IN_MILLIS = "duration_in_millis";
private static final String FAILURES = "failures";
private static final String SHARDS = "shards";
private static final String TOTAL = "total";
private static final String FAILED = "failed";
private static final String SUCCESSFUL = "successful";
private static final String VERSION_ID = "version_id";
private static final String VERSION = "version";
private static final String NAME = "name";
private static final String TOTAL_SHARDS = "total_shards";
private static final String SUCCESSFUL_SHARDS = "successful_shards";
private static final String INCLUDE_GLOBAL_STATE = "include_global_state";
private static final String REMOTE_STORE_INDEX_SHALLOW_COPY = "remote_store_index_shallow_copy";
private static final String USER_METADATA = "metadata";
private static final Comparator COMPARATOR = Comparator.comparing(SnapshotInfo::startTime)
.thenComparing(SnapshotInfo::snapshotId);
/**
* Builds snapshot information
*
* @opensearch.internal
*/
public static final class SnapshotInfoBuilder {
private String snapshotName = null;
private String snapshotUUID = null;
private String state = null;
private String reason = null;
private List indices = null;
private List dataStreams = null;
private long startTime = 0L;
private long endTime = 0L;
private ShardStatsBuilder shardStatsBuilder = null;
private Boolean includeGlobalState = null;
private Boolean remoteStoreIndexShallowCopy = null;
private Map userMetadata = null;
private int version = -1;
private List shardFailures = null;
private void setSnapshotName(String snapshotName) {
this.snapshotName = snapshotName;
}
private void setSnapshotUUID(String snapshotUUID) {
this.snapshotUUID = snapshotUUID;
}
private void setState(String state) {
this.state = state;
}
private void setReason(String reason) {
this.reason = reason;
}
private void setIndices(List indices) {
this.indices = indices;
}
private void setDataStreams(List dataStreams) {
this.dataStreams = dataStreams;
}
private void setStartTime(long startTime) {
this.startTime = startTime;
}
private void setEndTime(long endTime) {
this.endTime = endTime;
}
private void setShardStatsBuilder(ShardStatsBuilder shardStatsBuilder) {
this.shardStatsBuilder = shardStatsBuilder;
}
private void setIncludeGlobalState(Boolean includeGlobalState) {
this.includeGlobalState = includeGlobalState;
}
private void setUserMetadata(Map userMetadata) {
this.userMetadata = userMetadata;
}
private void setVersion(int version) {
this.version = version;
}
private void setRemoteStoreIndexShallowCopy(Boolean remoteStoreIndexShallowCopy) {
this.remoteStoreIndexShallowCopy = remoteStoreIndexShallowCopy;
}
private void setShardFailures(List shardFailures) {
this.shardFailures = shardFailures;
}
public SnapshotInfo build() {
SnapshotId snapshotId = new SnapshotId(snapshotName, snapshotUUID);
if (indices == null) {
indices = Collections.emptyList();
}
if (dataStreams == null) {
dataStreams = Collections.emptyList();
}
SnapshotState snapshotState = state == null ? null : SnapshotState.valueOf(state);
Version version = this.version == -1 ? Version.CURRENT : Version.fromId(this.version);
int totalShards = shardStatsBuilder == null ? 0 : shardStatsBuilder.getTotalShards();
int successfulShards = shardStatsBuilder == null ? 0 : shardStatsBuilder.getSuccessfulShards();
if (shardFailures == null) {
shardFailures = new ArrayList<>();
}
return new SnapshotInfo(
snapshotId,
indices,
dataStreams,
snapshotState,
reason,
version,
startTime,
endTime,
totalShards,
successfulShards,
shardFailures,
includeGlobalState,
userMetadata,
remoteStoreIndexShallowCopy
);
}
}
private static final class ShardStatsBuilder {
private int totalShards;
private int successfulShards;
private void setTotalShards(int totalShards) {
this.totalShards = totalShards;
}
int getTotalShards() {
return totalShards;
}
private void setSuccessfulShards(int successfulShards) {
this.successfulShards = successfulShards;
}
int getSuccessfulShards() {
return successfulShards;
}
}
public static final ObjectParser SNAPSHOT_INFO_PARSER = new ObjectParser<>(
SnapshotInfoBuilder.class.getName(),
true,
SnapshotInfoBuilder::new
);
private static final ObjectParser SHARD_STATS_PARSER = new ObjectParser<>(
ShardStatsBuilder.class.getName(),
true,
ShardStatsBuilder::new
);
static {
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setSnapshotName, new ParseField(SNAPSHOT));
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setSnapshotUUID, new ParseField(UUID));
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setState, new ParseField(STATE));
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setReason, new ParseField(REASON));
SNAPSHOT_INFO_PARSER.declareStringArray(SnapshotInfoBuilder::setIndices, new ParseField(INDICES));
SNAPSHOT_INFO_PARSER.declareStringArray(SnapshotInfoBuilder::setDataStreams, new ParseField(DATA_STREAMS));
SNAPSHOT_INFO_PARSER.declareLong(SnapshotInfoBuilder::setStartTime, new ParseField(START_TIME_IN_MILLIS));
SNAPSHOT_INFO_PARSER.declareLong(SnapshotInfoBuilder::setEndTime, new ParseField(END_TIME_IN_MILLIS));
SNAPSHOT_INFO_PARSER.declareObject(SnapshotInfoBuilder::setShardStatsBuilder, SHARD_STATS_PARSER, new ParseField(SHARDS));
SNAPSHOT_INFO_PARSER.declareBoolean(SnapshotInfoBuilder::setIncludeGlobalState, new ParseField(INCLUDE_GLOBAL_STATE));
SNAPSHOT_INFO_PARSER.declareObject(SnapshotInfoBuilder::setUserMetadata, (p, c) -> p.map(), new ParseField(USER_METADATA));
SNAPSHOT_INFO_PARSER.declareInt(SnapshotInfoBuilder::setVersion, new ParseField(VERSION_ID));
SNAPSHOT_INFO_PARSER.declareBoolean(
SnapshotInfoBuilder::setRemoteStoreIndexShallowCopy,
new ParseField(REMOTE_STORE_INDEX_SHALLOW_COPY)
);
SNAPSHOT_INFO_PARSER.declareObjectArray(
SnapshotInfoBuilder::setShardFailures,
SnapshotShardFailure.SNAPSHOT_SHARD_FAILURE_PARSER,
new ParseField(FAILURES)
);
SHARD_STATS_PARSER.declareInt(ShardStatsBuilder::setTotalShards, new ParseField(TOTAL));
SHARD_STATS_PARSER.declareInt(ShardStatsBuilder::setSuccessfulShards, new ParseField(SUCCESSFUL));
}
private final SnapshotId snapshotId;
@Nullable
private final SnapshotState state;
@Nullable
private final String reason;
private final List indices;
private final List dataStreams;
private final long startTime;
private final long endTime;
private final int totalShards;
private final int successfulShards;
@Nullable
private Boolean includeGlobalState;
@Nullable
private Boolean remoteStoreIndexShallowCopy;
@Nullable
private final Map userMetadata;
@Nullable
private final Version version;
private final List shardFailures;
public SnapshotInfo(SnapshotId snapshotId, List indices, List dataStreams, SnapshotState state) {
this(snapshotId, indices, dataStreams, state, null, null, 0L, 0L, 0, 0, Collections.emptyList(), null, null, null);
}
public SnapshotInfo(SnapshotId snapshotId, List indices, List dataStreams, SnapshotState state, Version version) {
this(snapshotId, indices, dataStreams, state, null, version, 0L, 0L, 0, 0, Collections.emptyList(), null, null, null);
}
public SnapshotInfo(SnapshotsInProgress.Entry entry) {
this(
entry.snapshot().getSnapshotId(),
entry.indices().stream().map(IndexId::getName).collect(Collectors.toList()),
entry.dataStreams(),
SnapshotState.IN_PROGRESS,
null,
Version.CURRENT,
entry.startTime(),
0L,
0,
0,
Collections.emptyList(),
entry.includeGlobalState(),
entry.userMetadata(),
entry.remoteStoreIndexShallowCopy()
);
}
public SnapshotInfo(
SnapshotId snapshotId,
List indices,
List dataStreams,
long startTime,
String reason,
long endTime,
int totalShards,
List shardFailures,
Boolean includeGlobalState,
Map userMetadata,
Boolean remoteStoreIndexShallowCopy
) {
this(
snapshotId,
indices,
dataStreams,
snapshotState(reason, shardFailures),
reason,
Version.CURRENT,
startTime,
endTime,
totalShards,
totalShards - shardFailures.size(),
shardFailures,
includeGlobalState,
userMetadata,
remoteStoreIndexShallowCopy
);
}
SnapshotInfo(
SnapshotId snapshotId,
List indices,
List dataStreams,
SnapshotState state,
String reason,
Version version,
long startTime,
long endTime,
int totalShards,
int successfulShards,
List shardFailures,
Boolean includeGlobalState,
Map userMetadata,
Boolean remoteStoreIndexShallowCopy
) {
this.snapshotId = Objects.requireNonNull(snapshotId);
this.indices = Collections.unmodifiableList(Objects.requireNonNull(indices));
this.dataStreams = Collections.unmodifiableList(Objects.requireNonNull(dataStreams));
this.state = state;
this.reason = reason;
this.version = version;
this.startTime = startTime;
this.endTime = endTime;
this.totalShards = totalShards;
this.successfulShards = successfulShards;
this.shardFailures = Objects.requireNonNull(shardFailures);
this.includeGlobalState = includeGlobalState;
this.userMetadata = userMetadata;
this.remoteStoreIndexShallowCopy = remoteStoreIndexShallowCopy;
}
/**
* Constructs snapshot information from stream input
*/
public SnapshotInfo(final StreamInput in) throws IOException {
snapshotId = new SnapshotId(in);
indices = Collections.unmodifiableList(in.readStringList());
state = in.readBoolean() ? SnapshotState.fromValue(in.readByte()) : null;
reason = in.readOptionalString();
startTime = in.readVLong();
endTime = in.readVLong();
totalShards = in.readVInt();
successfulShards = in.readVInt();
shardFailures = Collections.unmodifiableList(in.readList(SnapshotShardFailure::new));
version = in.readBoolean() ? in.readVersion() : null;
includeGlobalState = in.readOptionalBoolean();
if (in.getVersion().onOrAfter(METADATA_FIELD_INTRODUCED)) {
userMetadata = in.readMap();
} else {
userMetadata = null;
}
if (in.getVersion().onOrAfter(DATA_STREAMS_IN_SNAPSHOT)) {
dataStreams = in.readStringList();
} else {
dataStreams = Collections.emptyList();
}
if (in.getVersion().onOrAfter(Version.V_2_9_0)) {
remoteStoreIndexShallowCopy = in.readOptionalBoolean();
}
}
/**
* Gets a new {@link SnapshotInfo} instance from the given {@link SnapshotInfo} with
* all information stripped out except the snapshot id, state, and indices.
*/
public SnapshotInfo basic() {
return new SnapshotInfo(snapshotId, indices, Collections.emptyList(), state);
}
/**
* Returns snapshot id
*
* @return snapshot id
*/
public SnapshotId snapshotId() {
return snapshotId;
}
/**
* Returns snapshot state; {@code null} if the state is unknown.
*
* @return snapshot state
*/
@Nullable
public SnapshotState state() {
return state;
}
/**
* Returns snapshot failure reason; {@code null} if the snapshot succeeded.
*
* @return snapshot failure reason
*/
@Nullable
public String reason() {
return reason;
}
/**
* Returns indices that were included in this snapshot.
*
* @return list of indices
*/
public List indices() {
return indices;
}
/**
* @return list of data streams that were included in this snapshot.
*/
public List dataStreams() {
return dataStreams;
}
/**
* Returns time when snapshot started; a value of {@code 0L} will be returned if
* {@link #state()} returns {@code null}.
*
* @return snapshot start time
*/
public long startTime() {
return startTime;
}
/**
* Returns time when snapshot ended; a value of {@code 0L} will be returned if the
* snapshot is still running or if {@link #state()} returns {@code null}.
*
* @return snapshot end time
*/
public long endTime() {
return endTime;
}
/**
* Returns total number of shards that were snapshotted; a value of {@code 0} will
* be returned if {@link #state()} returns {@code null}.
*
* @return number of shards
*/
public int totalShards() {
return totalShards;
}
/**
* Number of failed shards; a value of {@code 0} will be returned if there were no
* failed shards, or if {@link #state()} returns {@code null}.
*
* @return number of failed shards
*/
public int failedShards() {
return totalShards - successfulShards;
}
/**
* Returns total number of shards that were successfully snapshotted; a value of
* {@code 0} will be returned if {@link #state()} returns {@code null}.
*
* @return number of successful shards
*/
public int successfulShards() {
return successfulShards;
}
public Boolean includeGlobalState() {
return includeGlobalState;
}
@Nullable
public Boolean isRemoteStoreIndexShallowCopyEnabled() {
return remoteStoreIndexShallowCopy;
}
/**
* Returns shard failures; an empty list will be returned if there were no shard
* failures, or if {@link #state()} returns {@code null}.
*
* @return shard failures
*/
public List shardFailures() {
return shardFailures;
}
/**
* Returns the version of opensearch that the snapshot was created with. Will only
* return {@code null} if {@link #state()} returns {@code null} or {@link SnapshotState#INCOMPATIBLE}.
*
* @return version of opensearch that the snapshot was created with
*/
@Nullable
public Version version() {
return version;
}
/**
* Returns the custom metadata that was attached to this snapshot at creation time.
* @return custom metadata
*/
@Nullable
public Map userMetadata() {
return userMetadata;
}
/**
* Compares two snapshots by their start time; if the start times are the same, then
* compares the two snapshots by their snapshot ids.
*/
@Override
public int compareTo(final SnapshotInfo o) {
return COMPARATOR.compare(this, o);
}
@Override
public String toString() {
return "SnapshotInfo{"
+ "snapshotId="
+ snapshotId
+ ", state="
+ state
+ ", reason='"
+ reason
+ '\''
+ ", indices="
+ indices
+ ", startTime="
+ startTime
+ ", endTime="
+ endTime
+ ", totalShards="
+ totalShards
+ ", successfulShards="
+ successfulShards
+ ", includeGlobalState="
+ includeGlobalState
+ ", version="
+ version
+ ", shardFailures="
+ shardFailures
+ ", isRemoteStoreInteropEnabled="
+ remoteStoreIndexShallowCopy
+ '}';
}
/**
* Returns snapshot REST status
*/
public RestStatus status() {
if (state == SnapshotState.FAILED) {
return RestStatus.INTERNAL_SERVER_ERROR;
}
if (shardFailures.size() == 0) {
return RestStatus.OK;
}
return RestStatus.status(
successfulShards,
totalShards,
shardFailures.toArray(new ShardOperationFailedException[shardFailures.size()])
);
}
@Override
public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException {
// write snapshot info to repository snapshot blob format
if (CONTEXT_MODE_SNAPSHOT.equals(params.param(CONTEXT_MODE_PARAM))) {
return toXContentInternal(builder, params);
}
final boolean verbose = params.paramAsBoolean("verbose", GetSnapshotsRequest.DEFAULT_VERBOSE_MODE);
// write snapshot info for the API and any other situations
builder.startObject();
builder.field(SNAPSHOT, snapshotId.getName());
builder.field(UUID, snapshotId.getUUID());
if (version != null) {
builder.field(VERSION_ID, version.id);
builder.field(VERSION, version.toString());
}
if (remoteStoreIndexShallowCopy != null) {
builder.field(REMOTE_STORE_INDEX_SHALLOW_COPY, remoteStoreIndexShallowCopy);
}
builder.startArray(INDICES);
for (String index : indices) {
builder.value(index);
}
builder.endArray();
builder.startArray(DATA_STREAMS);
for (String dataStream : dataStreams) {
builder.value(dataStream);
}
builder.endArray();
if (includeGlobalState != null) {
builder.field(INCLUDE_GLOBAL_STATE, includeGlobalState);
}
if (userMetadata != null) {
builder.field(USER_METADATA, userMetadata);
}
if (verbose || state != null) {
builder.field(STATE, state);
}
if (reason != null) {
builder.field(REASON, reason);
}
if (verbose || startTime != 0) {
builder.field(START_TIME, DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(startTime).atZone(ZoneOffset.UTC)));
builder.field(START_TIME_IN_MILLIS, startTime);
}
if (verbose || endTime != 0) {
builder.field(END_TIME, DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(endTime).atZone(ZoneOffset.UTC)));
builder.field(END_TIME_IN_MILLIS, endTime);
builder.humanReadableField(DURATION_IN_MILLIS, DURATION, new TimeValue(Math.max(0L, endTime - startTime)));
}
if (verbose || !shardFailures.isEmpty()) {
builder.startArray(FAILURES);
for (SnapshotShardFailure shardFailure : shardFailures) {
shardFailure.toXContent(builder, params);
}
builder.endArray();
}
if (verbose || totalShards != 0) {
builder.startObject(SHARDS);
builder.field(TOTAL, totalShards);
builder.field(FAILED, failedShards());
builder.field(SUCCESSFUL, successfulShards);
builder.endObject();
}
builder.endObject();
return builder;
}
private XContentBuilder toXContentInternal(final XContentBuilder builder, final ToXContent.Params params) throws IOException {
builder.startObject(SNAPSHOT);
builder.field(NAME, snapshotId.getName());
builder.field(UUID, snapshotId.getUUID());
assert version != null : "version must always be known when writing a snapshot metadata blob";
builder.field(VERSION_ID, version.id);
if (remoteStoreIndexShallowCopy != null) {
builder.field(REMOTE_STORE_INDEX_SHALLOW_COPY, remoteStoreIndexShallowCopy);
}
builder.startArray(INDICES);
for (String index : indices) {
builder.value(index);
}
builder.endArray();
builder.startArray(DATA_STREAMS);
for (String dataStream : dataStreams) {
builder.value(dataStream);
}
builder.endArray();
builder.field(STATE, state);
if (reason != null) {
builder.field(REASON, reason);
}
if (includeGlobalState != null) {
builder.field(INCLUDE_GLOBAL_STATE, includeGlobalState);
}
builder.field(USER_METADATA, userMetadata);
builder.field(START_TIME, startTime);
builder.field(END_TIME, endTime);
builder.field(TOTAL_SHARDS, totalShards);
builder.field(SUCCESSFUL_SHARDS, successfulShards);
builder.startArray(FAILURES);
for (SnapshotShardFailure shardFailure : shardFailures) {
shardFailure.toXContent(builder, params);
}
builder.endArray();
builder.endObject();
return builder;
}
/**
* This method creates a SnapshotInfo from internal x-content. It does not
* handle x-content written with the external version as external x-content
* is only for display purposes and does not need to be parsed.
*/
public static SnapshotInfo fromXContentInternal(final XContentParser parser) throws IOException {
String name = null;
String uuid = null;
Version version = Version.CURRENT;
SnapshotState state = SnapshotState.IN_PROGRESS;
String reason = null;
List indices = Collections.emptyList();
List dataStreams = Collections.emptyList();
long startTime = 0;
long endTime = 0;
int totalShards = 0;
int successfulShards = 0;
Boolean includeGlobalState = null;
Boolean remoteStoreIndexShallowCopy = null;
Map userMetadata = null;
List shardFailures = Collections.emptyList();
if (parser.currentToken() == null) { // fresh parser? move to the first token
parser.nextToken();
}
if (parser.currentToken() == XContentParser.Token.START_OBJECT) { // on a start object move to next token
parser.nextToken();
}
XContentParser.Token token;
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser);
String currentFieldName = parser.currentName();
if (SNAPSHOT.equals(currentFieldName)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
token = parser.nextToken();
if (token.isValue()) {
if (NAME.equals(currentFieldName)) {
name = parser.text();
} else if (UUID.equals(currentFieldName)) {
uuid = parser.text();
} else if (STATE.equals(currentFieldName)) {
state = SnapshotState.valueOf(parser.text());
} else if (REASON.equals(currentFieldName)) {
reason = parser.text();
} else if (START_TIME.equals(currentFieldName)) {
startTime = parser.longValue();
} else if (END_TIME.equals(currentFieldName)) {
endTime = parser.longValue();
} else if (TOTAL_SHARDS.equals(currentFieldName)) {
totalShards = parser.intValue();
} else if (SUCCESSFUL_SHARDS.equals(currentFieldName)) {
successfulShards = parser.intValue();
} else if (VERSION_ID.equals(currentFieldName)) {
version = Version.fromId(parser.intValue());
} else if (INCLUDE_GLOBAL_STATE.equals(currentFieldName)) {
includeGlobalState = parser.booleanValue();
} else if (REMOTE_STORE_INDEX_SHALLOW_COPY.equals(currentFieldName)) {
remoteStoreIndexShallowCopy = parser.booleanValue();
}
} else if (token == XContentParser.Token.START_ARRAY) {
if (DATA_STREAMS.equals(currentFieldName)) {
dataStreams = new ArrayList<>();
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
dataStreams.add(parser.text());
}
} else if (INDICES.equals(currentFieldName)) {
ArrayList indicesArray = new ArrayList<>();
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
indicesArray.add(parser.text());
}
indices = Collections.unmodifiableList(indicesArray);
} else if (FAILURES.equals(currentFieldName)) {
ArrayList shardFailureArrayList = new ArrayList<>();
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
shardFailureArrayList.add(SnapshotShardFailure.fromXContent(parser));
}
shardFailures = Collections.unmodifiableList(shardFailureArrayList);
} else {
// It was probably created by newer version - ignoring
parser.skipChildren();
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (USER_METADATA.equals(currentFieldName)) {
userMetadata = parser.map();
} else {
// It was probably created by newer version - ignoring
parser.skipChildren();
}
}
}
}
}
if (uuid == null) {
// the old format where there wasn't a UUID
uuid = name;
}
return new SnapshotInfo(
new SnapshotId(name, uuid),
indices,
dataStreams,
state,
reason,
version,
startTime,
endTime,
totalShards,
successfulShards,
shardFailures,
includeGlobalState,
userMetadata,
remoteStoreIndexShallowCopy
);
}
@Override
public void writeTo(final StreamOutput out) throws IOException {
snapshotId.writeTo(out);
out.writeStringCollection(indices);
if (state != null) {
out.writeBoolean(true);
out.writeByte(state.value());
} else {
out.writeBoolean(false);
}
out.writeOptionalString(reason);
out.writeVLong(startTime);
out.writeVLong(endTime);
out.writeVInt(totalShards);
out.writeVInt(successfulShards);
out.writeList(shardFailures);
if (version != null) {
out.writeBoolean(true);
out.writeVersion(version);
} else {
out.writeBoolean(false);
}
out.writeOptionalBoolean(includeGlobalState);
if (out.getVersion().onOrAfter(METADATA_FIELD_INTRODUCED)) {
out.writeMap(userMetadata);
if (out.getVersion().onOrAfter(DATA_STREAMS_IN_SNAPSHOT)) {
out.writeStringCollection(dataStreams);
}
}
if (out.getVersion().onOrAfter(Version.V_2_9_0)) {
out.writeOptionalBoolean(remoteStoreIndexShallowCopy);
}
}
private static SnapshotState snapshotState(final String reason, final List shardFailures) {
if (reason == null) {
if (shardFailures.isEmpty()) {
return SnapshotState.SUCCESS;
} else {
return SnapshotState.PARTIAL;
}
} else {
return SnapshotState.FAILED;
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SnapshotInfo that = (SnapshotInfo) o;
return startTime == that.startTime
&& endTime == that.endTime
&& totalShards == that.totalShards
&& successfulShards == that.successfulShards
&& Objects.equals(snapshotId, that.snapshotId)
&& state == that.state
&& Objects.equals(reason, that.reason)
&& Objects.equals(indices, that.indices)
&& Objects.equals(dataStreams, that.dataStreams)
&& Objects.equals(includeGlobalState, that.includeGlobalState)
&& Objects.equals(version, that.version)
&& Objects.equals(shardFailures, that.shardFailures)
&& Objects.equals(userMetadata, that.userMetadata)
&& Objects.equals(remoteStoreIndexShallowCopy, that.remoteStoreIndexShallowCopy);
}
@Override
public int hashCode() {
return Objects.hash(
snapshotId,
state,
reason,
indices,
dataStreams,
startTime,
endTime,
totalShards,
successfulShards,
includeGlobalState,
version,
shardFailures,
userMetadata,
remoteStoreIndexShallowCopy
);
}
}