From 92acd76ba1429e473dd2c8f2e8ada9239925df9f Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Wed, 6 Jun 2018 17:31:05 -0700 Subject: [PATCH 01/13] Progress on parsers. --- .../create/CreateSnapshotResponse.java | 9 + .../blobstore/BlobStoreRepository.java | 2 +- .../elasticsearch/snapshots/SnapshotInfo.java | 171 +++++++++++++++++- .../create/CreateSnapshotResponseTests.java | 71 ++++++++ 4 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java index 1f9f77f9ed3df..5a0b4389613f8 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.snapshots.SnapshotInfo; @@ -45,6 +46,10 @@ public class CreateSnapshotResponse extends ActionResponse implements ToXContent CreateSnapshotResponse() { } + void setSnapshotInfo(SnapshotInfo snapshotInfo) { + this.snapshotInfo = snapshotInfo; + } + /** * Returns snapshot information if snapshot was completed by the time this method returned or null otherwise. * @@ -93,4 +98,8 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.endObject(); return builder; } + + public static CreateSnapshotResponse fromXContent(XContentParser parser) throws IOException { + return new CreateSnapshotResponse(SnapshotInfo.fromXContent(parser)); + } } diff --git a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java index 618dd3b8bc3b9..893fd79f2d3ca 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -257,7 +257,7 @@ protected void doStart() { indexMetaDataFormat = new ChecksumBlobStoreFormat<>(INDEX_METADATA_CODEC, METADATA_NAME_FORMAT, IndexMetaData::fromXContent, namedXContentRegistry, isCompress()); snapshotFormat = new ChecksumBlobStoreFormat<>(SNAPSHOT_CODEC, SNAPSHOT_NAME_FORMAT, - SnapshotInfo::fromXContent, namedXContentRegistry, isCompress()); + SnapshotInfo::fromXContentInternal, namedXContentRegistry, isCompress()); } @Override diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java index 073007f4225df..1477a3ea3b26b 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java @@ -23,18 +23,23 @@ import org.elasticsearch.action.ShardOperationFailedException; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.ParseField; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.Joda; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.xcontent.ObjectParser; +import org.elasticsearch.common.xcontent.ObjectParser.ValueType; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParser.Token; import org.elasticsearch.rest.RestStatus; import java.io.IOException; +import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -79,6 +84,165 @@ public final class SnapshotInfo implements Comparable, ToXContent, private static final Comparator COMPARATOR = Comparator.comparing(SnapshotInfo::startTime).thenComparing(SnapshotInfo::snapshotId); + private 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 long startTime = 0L; + private long endTime = 0L; + private ShardStatsBuilder shardStatsBuilder = null; + private Boolean includeGlobalState = 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 setStartTime(long startTime) { + this.startTime = startTime; + } + + private void setEndTime(long endTime) { + this.startTime = endTime; + } + + private void setShardStatsBuilder(ShardStatsBuilder shardStatsBuilder) { + this.shardStatsBuilder = shardStatsBuilder; + } + + private void setIncludeGlobalState(Boolean includeGlobalState) { + this.includeGlobalState = includeGlobalState; + } + + private void setVersion(int version) { + this.version = version; + } + + private void setShardFailures(XContentParser parser) { + try { + if (parser.currentToken() == Token.START_ARRAY) { + parser.nextToken(); + } + + while (parser.currentToken() != Token.END_ARRAY) { + shardFailures.add(SnapshotShardFailure.fromXContent(parser)); + } + } catch (IOException exception) { + throw new UncheckedIOException(exception); + } + } + + private void ignoreVersion(String version) { + // ignore extra field + } + + private void ignoreStartTime(String startTime) { + // ignore extra field + } + + private void ignoreEndTime(String endTime) { + // ignore extra field + } + + private void ignoreDurationInMillis(long durationInMillis) { + // ignore extra field + } + + private SnapshotInfo build() { + SnapshotId snapshotId = new SnapshotId(snapshotName, snapshotUUID); + + if (indices == null) { + indices = 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, snapshotState, reason, version, startTime, endTime, + totalShards, successfulShards, shardFailures, includeGlobalState); + } + } + + 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; + } + + private void ignoreFailedShards(int failedShards) { + // ignore extra field + } + } + + private static final ObjectParser SNAPSHOT_INFO_PARSER = + new ObjectParser<>(SnapshotInfoBuilder.class.getName(), SnapshotInfoBuilder::new); + + private static final ObjectParser SHARD_STATS_PARSER = + new ObjectParser<>(ShardStatsBuilder.class.getName(), 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.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.declareInt(SnapshotInfoBuilder::setVersion, new ParseField(VERSION_ID)); + SNAPSHOT_INFO_PARSER.declareField( + SnapshotInfoBuilder::setShardFailures, parser -> parser, new ParseField(FAILURES), ValueType.OBJECT_ARRAY); + SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::ignoreVersion, new ParseField(VERSION)); + SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::ignoreStartTime, new ParseField(START_TIME)); + SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::ignoreEndTime, new ParseField(END_TIME)); + SNAPSHOT_INFO_PARSER.declareLong(SnapshotInfoBuilder::ignoreDurationInMillis, new ParseField(DURATION_IN_MILLIS)); + + SHARD_STATS_PARSER.declareInt(ShardStatsBuilder::setTotalShards, new ParseField(TOTAL)); + SHARD_STATS_PARSER.declareInt(ShardStatsBuilder::setSuccessfulShards, new ParseField(SUCCESSFUL)); + SHARD_STATS_PARSER.declareInt(ShardStatsBuilder::ignoreFailedShards, new ParseField(FAILED)); + } + private final SnapshotId snapshotId; @Nullable @@ -448,12 +612,17 @@ private XContentBuilder toXContentSnapshot(final XContentBuilder builder, final return builder; } + public static SnapshotInfo fromXContent(final XContentParser parser) throws IOException { + parser.nextToken(); + return SNAPSHOT_INFO_PARSER.apply(parser, null).build(); + } + /** * 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 fromXContent(final XContentParser parser) throws IOException { + public static SnapshotInfo fromXContentInternal(final XContentParser parser) throws IOException { String name = null; String uuid = null; Version version = Version.CURRENT; diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java new file mode 100644 index 0000000000000..91e6fd2455f55 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java @@ -0,0 +1,71 @@ +/* + * 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.action.admin.cluster.snapshots.create; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.snapshots.SnapshotId; +import org.elasticsearch.snapshots.SnapshotInfo; +import org.elasticsearch.snapshots.SnapshotShardFailure; +import org.elasticsearch.test.AbstractXContentTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class CreateSnapshotResponseTests extends AbstractXContentTestCase { + + @Override + protected CreateSnapshotResponse doParseInstance(XContentParser parser) throws IOException { + return CreateSnapshotResponse.fromXContent(parser); + } + + @Override + protected boolean supportsUnknownFields() { + return false; + } + + @Override + protected CreateSnapshotResponse createTestInstance() { + SnapshotId snapshotId = new SnapshotId("test", UUID.randomUUID().toString()); + List indices = new ArrayList<>(); + indices.add("test0"); + indices.add("test1"); + String reason = "reason"; + long startTime = System.currentTimeMillis(); + long endTime = startTime + 10000; + int totalShards = randomIntBetween(1, 15); + int successfulShards = randomIntBetween(14, 15); + List shardFailures = new ArrayList<>(); + + for (int count = successfulShards; count < totalShards; ++count) { + shardFailures.add(new SnapshotShardFailure( + "node-id", new ShardId("index", UUID.randomUUID().toString(), randomInt()), "reason")); + } + + boolean globalState = randomBoolean(); + + CreateSnapshotResponse response = new CreateSnapshotResponse(); + response.setSnapshotInfo( + new SnapshotInfo(snapshotId, indices, startTime, reason, endTime, totalShards, shardFailures, globalState)); + return response; + } +} From 77cb270c2138b9eb09d0ff7c2e12f5e9a007f208 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Wed, 6 Jun 2018 17:45:43 -0700 Subject: [PATCH 02/13] Parsing successful with tests. --- .../create/CreateSnapshotResponse.java | 31 ++++++++- .../elasticsearch/snapshots/SnapshotInfo.java | 65 ++++++++++++------- .../snapshots/SnapshotShardFailure.java | 25 ++++++- 3 files changed, 96 insertions(+), 25 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java index 5a0b4389613f8..8b9dced2fddff 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java @@ -30,6 +30,7 @@ import org.elasticsearch.snapshots.SnapshotInfo; import java.io.IOException; +import java.util.Objects; /** * Create snapshot response @@ -100,6 +101,34 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws } public static CreateSnapshotResponse fromXContent(XContentParser parser) throws IOException { - return new CreateSnapshotResponse(SnapshotInfo.fromXContent(parser)); + CreateSnapshotResponse createSnapshotResponse = new CreateSnapshotResponse(); + + parser.nextToken(); + parser.nextToken(); + createSnapshotResponse.snapshotInfo = SnapshotInfo.fromXContent(parser); + parser.nextToken(); + + return createSnapshotResponse; + } + + @Override + public String toString() { + return "CreateSnapshotResponse{" + + "snapshotInfo=" + snapshotInfo + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CreateSnapshotResponse that = (CreateSnapshotResponse) o; + return Objects.equals(snapshotInfo, that.snapshotInfo); + } + + @Override + public int hashCode() { + + return Objects.hash(snapshotInfo); } } diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java index 1477a3ea3b26b..e18006ebb3917 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java @@ -122,7 +122,7 @@ private void setStartTime(long startTime) { } private void setEndTime(long endTime) { - this.startTime = endTime; + this.endTime = endTime; } private void setShardStatsBuilder(ShardStatsBuilder shardStatsBuilder) { @@ -481,29 +481,21 @@ public int compareTo(final SnapshotInfo o) { return COMPARATOR.compare(this, o); } - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - final SnapshotInfo that = (SnapshotInfo) o; - return startTime == that.startTime && snapshotId.equals(that.snapshotId); - } - - @Override - public int hashCode() { - int result = snapshotId.hashCode(); - result = 31 * result + Long.hashCode(startTime); - return result; - } - @Override public String toString() { - return "SnapshotInfo[snapshotId=" + snapshotId + ", state=" + state + ", indices=" + indices + "]"; + return "SnapshotInfo{" + + "snapshotId=" + snapshotId + + ", state=" + state + + ", reason='" + reason + '\'' + + ", indices=" + indices + + ", startTime=" + startTime + + ", endTime=" + endTime + + ", totalShards=" + totalShards + + ", successfulShards=" + successfulShards + + ", includeGlobalState=" + includeGlobalState + + ", version=" + version + + ", shardFailures=" + shardFailures + + '}'; } /** @@ -614,7 +606,10 @@ private XContentBuilder toXContentSnapshot(final XContentBuilder builder, final public static SnapshotInfo fromXContent(final XContentParser parser) throws IOException { parser.nextToken(); - return SNAPSHOT_INFO_PARSER.apply(parser, null).build(); + SnapshotInfo snapshotInfo = SNAPSHOT_INFO_PARSER.apply(parser, null).build(); + parser.nextToken(); + + return snapshotInfo; } /** @@ -776,4 +771,28 @@ private static SnapshotState snapshotState(final String reason, final List Date: Thu, 7 Jun 2018 12:51:31 -0700 Subject: [PATCH 03/13] More progress. --- .../client/RequestConverters.java | 15 ++ .../elasticsearch/client/SnapshotClient.java | 26 ++++ .../client/RequestConvertersTests.java | 16 ++ .../org/elasticsearch/client/SnapshotIT.java | 19 +++ .../SnapshotClientDocumentationIT.java | 39 +++++ .../snapshot/create_snapshot.asciidoc | 139 ++++++++++++++++++ .../create/CreateSnapshotRequest.java | 8 +- .../create/CreateSnapshotResponse.java | 12 +- 8 files changed, 269 insertions(+), 5 deletions(-) create mode 100644 docs/java-rest/high-level/snapshot/create_snapshot.asciidoc diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index e5a45e19fe0d3..a048200043110 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -35,6 +35,7 @@ import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest; import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest; @@ -803,6 +804,20 @@ static Request verifyRepository(VerifyRepositoryRequest verifyRepositoryRequest) return request; } + static Request createSnapshot(CreateSnapshotRequest createSnapshotRequest) { + String endpoint = new EndpointBuilder().addPathPart("_snapshot") + .addPathPart(createSnapshotRequest.repository()) + .addPathPart(createSnapshotRequest.snapshot()) + .build(); + Request request = new Request(HttpPut.METHOD_NAME, endpoint); + + Params params = new Params(request); + params.withMasterTimeout(createSnapshotRequest.masterNodeTimeout()); + params.withWaitForCompletion(createSnapshotRequest.waitForCompletion()); + request.setEntity(createEntity(createSnapshotRequest, REQUEST_BODY_CONTENT_TYPE)); + return request; + } + static Request putTemplate(PutIndexTemplateRequest putIndexTemplateRequest) throws IOException { String endpoint = new EndpointBuilder().addPathPartAsIs("_template").addPathPart(putIndexTemplateRequest.name()).build(); Request request = new Request(HttpPut.METHOD_NAME, endpoint); diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java index 104bc91271148..41c19c2938ea6 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java @@ -29,6 +29,8 @@ import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse; import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest; import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse; +import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import java.io.IOException; @@ -142,4 +144,28 @@ public void verifyRepositoryAsync(VerifyRepositoryRequest verifyRepositoryReques restHighLevelClient.performRequestAsyncAndParseEntity(verifyRepositoryRequest, RequestConverters::verifyRepository, VerifyRepositoryResponse::fromXContent, listener, emptySet(), headers); } + + /** + * Creates a snapshot. + *

+ * See Snapshot and Restore + * API on elastic.co + */ + public CreateSnapshotResponse createSnapshot(CreateSnapshotRequest createSnapshotRequest, Header... headers) + throws IOException { + return restHighLevelClient.performRequestAndParseEntity(createSnapshotRequest, RequestConverters::createSnapshot, + CreateSnapshotResponse::fromXContent, emptySet(), headers); + } + + /** + * Asynchronously creates a snapshot. + *

+ * See Snapshot and Restore + * API on elastic.co + */ + public void createSnapshotAsync(CreateSnapshotRequest createSnapshotRequest, + ActionListener listener, Header... headers) { + restHighLevelClient.performRequestAsyncAndParseEntity(createSnapshotRequest, RequestConverters::createSnapshot, + CreateSnapshotResponse::fromXContent, listener, emptySet(), headers); + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java index ee372e255e70a..9b2e18a1832c7 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java @@ -35,6 +35,7 @@ import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest; import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; @@ -1721,6 +1722,21 @@ public void testVerifyRepository() { assertThat(expectedParams, equalTo(request.getParameters())); } + public void testCreateSnapshot() { + Map expectedParams = new HashMap<>(); + String repository = randomIndicesNames(1, 1)[0]; + String snapshot = "snapshot-" + generateRandomStringArray(1, randomInt(10), false, false)[0]; + String endpoint = "/_snapshot/" + repository + "/" + snapshot; + + CreateSnapshotRequest createSnapshotRequest = new CreateSnapshotRequest(repository, snapshot); + setRandomMasterTimeout(createSnapshotRequest, expectedParams); + + Request request = RequestConverters.createSnapshot(createSnapshotRequest); + assertThat(endpoint, equalTo(request.getEndpoint())); + assertThat(HttpPut.METHOD_NAME, equalTo(request.getMethod())); + assertThat(expectedParams, equalTo(request.getParameters())); + } + public void testPutTemplateRequest() throws Exception { Map names = new HashMap<>(); names.put("log", "log"); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java index aaba5da820613..21c7b26ff0a10 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java @@ -30,9 +30,13 @@ import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse; import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest; import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse; +import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.repositories.fs.FsRepository; import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.snapshots.SnapshotInfo; +import org.elasticsearch.snapshots.SnapshotState; import java.io.IOException; import java.util.Collections; @@ -111,4 +115,19 @@ public void testVerifyRepository() throws IOException { highLevelClient().snapshot()::verifyRepositoryAsync); assertThat(response.getNodes().size(), equalTo(1)); } + + private CreateSnapshotResponse createTestSnapshot(String repository, String snapshot, String settings) throws IOException { + // assumes the repository already exists + CreateSnapshotRequest request = new CreateSnapshotRequest(repository, snapshot); + request.settings(settings, XContentType.JSON); + return execute(request, highLevelClient().snapshot()::createSnapshot, + highLevelClient().snapshot()::createSnapshotAsync); + } + + public void testCreateSnapshot() throws IOException { + assertTrue(createTestRepository("test", FsRepository.TYPE, "{\"location\": \".\"}").isAcknowledged()); + + CreateSnapshotResponse response = createTestSnapshot("test", "snapshot-test", "{}"); + assertEquals(response.status(), RestStatus.ACCEPTED); + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java index 2890ad50c2666..19bfea61a187e 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -29,6 +29,8 @@ import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse; import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest; import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse; +import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.client.ESRestHighLevelClientTestCase; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.cluster.metadata.RepositoryMetaData; @@ -36,6 +38,7 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.repositories.fs.FsRepository; +import org.elasticsearch.rest.RestStatus; import java.io.IOException; import java.util.HashMap; @@ -365,4 +368,40 @@ private void createTestRepositories() throws IOException { request.settings("{\"location\": \".\"}", XContentType.JSON); assertTrue(highLevelClient().snapshot().createRepository(request).isAcknowledged()); } + + private static final String snapshotName = "test_snapshot"; + + public void testSnapshotCreateSnapshot() throws IOException { + createTestRepositories(); + + RestHighLevelClient client = highLevelClient(); + + // tag::create-snapshot-request + CreateSnapshotRequest request = new CreateSnapshotRequest(); + // end::create-snapshot-request + + // tag::create-snapshot-request-repositoryName + request.repository(repositoryName); // <1> + // end::create-snapshot-request-repositoryName + // tag::create-snapshot-request-snapshotName + request.snapshot(snapshotName); // <1> + // end::create-snapshot-request-snapshotName + + // tag::create-snapshot-request-masterTimeout + request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1> + request.masterNodeTimeout("1m"); // <2> + // end::create-snapshot-request-masterTimeout + // tag::create-snapshot-request-waitForCompletion + request.waitForCompletion(false); // <1> + // end::create-snapshot-request-WaitForCompletion + + // tag::create-snapshot-execute + CreateSnapshotResponse response = client.snapshot().createSnapshot(request); + // end::create-snapshot-execute + + // tag::create-repository-response + RestStatus status = response.status(); + // end::create-repository-response + assertEquals(RestStatus.ACCEPTED, status); + } } diff --git a/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc new file mode 100644 index 0000000000000..5c54529209720 --- /dev/null +++ b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc @@ -0,0 +1,139 @@ +[[java-rest-high-snapshot-create-repository]] +=== Snapshot Create RepositoryAPI + +The Snapshot Create RepositoryAPI allows to register a snapshot repository. + +[[java-rest-high-snapshot-create-repository-request]] +==== Snapshot Create RepositoryRequest + +A `PutRepositoryRequest`: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request] +-------------------------------------------------- + +==== Repository Settings +Settings requirements will differ based on the repository backend chosen. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-repository-settings] +-------------------------------------------------- +<1> Sets the repository settings + +==== Providing the Settings +The settings to be applied can be provided in different ways: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-create-settings] +-------------------------------------------------- +<1> Settings provided as `Settings` + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-settings-builder] +-------------------------------------------------- +<1> Settings provided as `Settings.Builder` + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-settings-source] +-------------------------------------------------- +<1> Settings provided as `String` + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-settings-map] +-------------------------------------------------- +<1> Settings provided as a `Map` + +==== Required Arguments +The following arguments must be provided: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-name] +-------------------------------------------------- +<1> The name of the repository + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-type] +-------------------------------------------------- +<1> The type of the repository + +==== Optional Arguments +The following arguments can optionally be provided: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-timeout] +-------------------------------------------------- +<1> Timeout to wait for the all the nodes to acknowledge the settings were applied +as a `TimeValue` +<2> Timeout to wait for the all the nodes to acknowledge the settings were applied +as a `String` + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-masterTimeout] +-------------------------------------------------- +<1> Timeout to connect to the master node as a `TimeValue` +<2> Timeout to connect to the master node as a `String` + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-verify] +-------------------------------------------------- +<1> Verify after creation as a `Boolean` + +[[java-rest-high-snapshot-create-repository-sync]] +==== Synchronous Execution + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-execute] +-------------------------------------------------- + +[[java-rest-high-snapshot-create-repository-async]] +==== Asynchronous Execution + +The asynchronous execution of a repository put settings requires both the +`PutRepositoryRequest` instance and an `ActionListener` instance to be +passed to the asynchronous method: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-execute-async] +-------------------------------------------------- +<1> The `PutRepositoryRequest` to execute and the `ActionListener` +to use when the execution completes + +The asynchronous method does not block and returns immediately. Once it is +completed the `ActionListener` is called back using the `onResponse` method +if the execution successfully completed or using the `onFailure` method if +it failed. + +A typical listener for `PutRepositoryResponse` looks like: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-execute-listener] +-------------------------------------------------- +<1> Called when the execution is successfully completed. The response is +provided as an argument +<2> Called in case of a failure. The raised exception is provided as an argument + +[[java-rest-high-snapshot-create-repository-response]] +==== Snapshot Create RepositoryResponse + +The returned `PutRepositoryResponse` allows to retrieve information about the +executed operation as follows: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-response] +-------------------------------------------------- +<1> Indicates the node has acknowledged the request diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java index 5d5f4685f03d2..db846371cde35 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; @@ -58,7 +59,7 @@ *

  • must not contain invalid file name characters {@link org.elasticsearch.common.Strings#INVALID_FILENAME_CHARS}
  • * */ -public class CreateSnapshotRequest extends MasterNodeRequest implements IndicesRequest.Replaceable { +public class CreateSnapshotRequest extends MasterNodeRequest implements IndicesRequest.Replaceable, ToXContent { private String snapshot; @@ -407,6 +408,11 @@ public CreateSnapshotRequest source(Map source) { return this; } + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + return null; + } + @Override public void readFrom(StreamInput in) throws IOException { throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java index 8b9dced2fddff..23325af2eded0 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java @@ -103,10 +103,14 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws public static CreateSnapshotResponse fromXContent(XContentParser parser) throws IOException { CreateSnapshotResponse createSnapshotResponse = new CreateSnapshotResponse(); - parser.nextToken(); - parser.nextToken(); - createSnapshotResponse.snapshotInfo = SnapshotInfo.fromXContent(parser); - parser.nextToken(); + parser.nextToken(); // '{' + parser.nextToken(); // 'snapshot' || 'accepted' + + if ("snapshot".equals(parser.currentName())) { + createSnapshotResponse.snapshotInfo = SnapshotInfo.fromXContent(parser); + } + + parser.nextToken(); // '}' return createSnapshotResponse; } From 13144c94f0df716ea2d8e65540f094852a2b56da Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Thu, 7 Jun 2018 13:58:15 -0700 Subject: [PATCH 04/13] More progress. --- .../client/RequestConverters.java | 3 +-- .../client/RequestConvertersTests.java | 3 ++- .../SnapshotClientDocumentationIT.java | 6 +++++ .../snapshot/create_snapshot.asciidoc | 14 +++++------ .../create/CreateSnapshotRequest.java | 23 ++++++++++++++++--- .../action/support/IndicesOptions.java | 17 +++++++++++++- 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index a048200043110..a184e733ecdb1 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -804,13 +804,12 @@ static Request verifyRepository(VerifyRepositoryRequest verifyRepositoryRequest) return request; } - static Request createSnapshot(CreateSnapshotRequest createSnapshotRequest) { + static Request createSnapshot(CreateSnapshotRequest createSnapshotRequest) throws IOException { String endpoint = new EndpointBuilder().addPathPart("_snapshot") .addPathPart(createSnapshotRequest.repository()) .addPathPart(createSnapshotRequest.snapshot()) .build(); Request request = new Request(HttpPut.METHOD_NAME, endpoint); - Params params = new Params(request); params.withMasterTimeout(createSnapshotRequest.masterNodeTimeout()); params.withWaitForCompletion(createSnapshotRequest.waitForCompletion()); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java index 9b2e18a1832c7..c383925b0c053 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java @@ -1722,7 +1722,7 @@ public void testVerifyRepository() { assertThat(expectedParams, equalTo(request.getParameters())); } - public void testCreateSnapshot() { + public void testCreateSnapshot() throws IOException { Map expectedParams = new HashMap<>(); String repository = randomIndicesNames(1, 1)[0]; String snapshot = "snapshot-" + generateRandomStringArray(1, randomInt(10), false, false)[0]; @@ -1735,6 +1735,7 @@ public void testCreateSnapshot() { assertThat(endpoint, equalTo(request.getEndpoint())); assertThat(HttpPut.METHOD_NAME, equalTo(request.getMethod())); assertThat(expectedParams, equalTo(request.getParameters())); + assertToXContentBody(createSnapshotRequest, request.getEntity()); } public void testPutTemplateRequest() throws Exception { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java index 19bfea61a187e..418159ddd5181 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -31,6 +31,7 @@ import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; +import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.ESRestHighLevelClientTestCase; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.cluster.metadata.RepositoryMetaData; @@ -387,6 +388,10 @@ public void testSnapshotCreateSnapshot() throws IOException { request.snapshot(snapshotName); // <1> // end::create-snapshot-request-snapshotName + request.indices("test-index0, test-index1"); + + request.indicesOptions(new IndicesOptions()) + // tag::create-snapshot-request-masterTimeout request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1> request.masterNodeTimeout("1m"); // <2> @@ -402,6 +407,7 @@ public void testSnapshotCreateSnapshot() throws IOException { // tag::create-repository-response RestStatus status = response.status(); // end::create-repository-response + assertEquals(RestStatus.ACCEPTED, status); } } diff --git a/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc index 5c54529209720..f11213705e44f 100644 --- a/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc +++ b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc @@ -1,16 +1,16 @@ -[[java-rest-high-snapshot-create-repository]] -=== Snapshot Create RepositoryAPI +[[java-rest-high-snapshot-create-snapshot]] +=== Create Snapshot API -The Snapshot Create RepositoryAPI allows to register a snapshot repository. +Use the Create Snapshot API to create a new snapshot. -[[java-rest-high-snapshot-create-repository-request]] -==== Snapshot Create RepositoryRequest +[[java-rest-high-snapshot-create-snapshot-request]] +==== Create Snapshot Request -A `PutRepositoryRequest`: +A `CreateSnapshotRequest`: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request] -------------------------------------------------- ==== Repository Settings diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java index db846371cde35..c809835448dd3 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java @@ -28,7 +28,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; @@ -59,7 +59,7 @@ *
  • must not contain invalid file name characters {@link org.elasticsearch.common.Strings#INVALID_FILENAME_CHARS}
  • * */ -public class CreateSnapshotRequest extends MasterNodeRequest implements IndicesRequest.Replaceable, ToXContent { +public class CreateSnapshotRequest extends MasterNodeRequest implements IndicesRequest.Replaceable, ToXContentObject { private String snapshot; @@ -410,7 +410,24 @@ public CreateSnapshotRequest source(Map source) { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - return null; + builder.startObject(); + builder.field("repository", repository); + builder.field("snapshot", snapshot); + builder.startArray("indices"); + for (String index : indices) { + builder.value(index); + } + builder.endArray(); + builder.field("partial", partial); + if (settings != null) { + settings.toXContent(builder, params); + } + builder.field("include_global_state", includeGlobalState); + if (indicesOptions != null) { + indicesOptions.toXContent(builder, params); + } + builder.endObject(); + return builder; } @Override diff --git a/server/src/main/java/org/elasticsearch/action/support/IndicesOptions.java b/server/src/main/java/org/elasticsearch/action/support/IndicesOptions.java index b284ec87dd42c..93641574bde12 100644 --- a/server/src/main/java/org/elasticsearch/action/support/IndicesOptions.java +++ b/server/src/main/java/org/elasticsearch/action/support/IndicesOptions.java @@ -22,12 +22,15 @@ import org.elasticsearch.Version; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.ToXContentFragment; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.rest.RestRequest; import java.io.IOException; import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -38,7 +41,7 @@ * Controls how to deal with unavailable concrete indices (closed or missing), how wildcard expressions are expanded * to actual indices (all, closed or open indices) and how to deal with wildcard expressions that resolve to no indices. */ -public class IndicesOptions { +public class IndicesOptions implements ToXContentFragment { public enum WildcardStates { OPEN, @@ -313,6 +316,18 @@ public static IndicesOptions fromMap(Map map, IndicesOptions def defaultSettings); } + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startArray("expand_wildcards"); + for (WildcardStates expandWildcard : expandWildcards) { + builder.value(expandWildcard.toString().toLowerCase(Locale.ROOT)); + } + builder.endArray(); + builder.field("ignore_unavailable", ignoreUnavailable()); + builder.field("allow_no_indices", allowNoIndices()); + return builder; + } + /** * Returns true if the name represents a valid name for one of the indices option * false otherwise From baa4d49dd21651e9f82a74f4d2e1117c6eca51da Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Thu, 7 Jun 2018 14:18:17 -0700 Subject: [PATCH 05/13] More progress. --- .../documentation/SnapshotClientDocumentationIT.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java index 4da9003f70de2..54adc587a49fb 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -388,10 +388,12 @@ public void testSnapshotCreateSnapshot() throws IOException { // tag::create-snapshot-request-snapshotName request.snapshot(snapshotName); // <1> // end::create-snapshot-request-snapshotName - - request.indices("test-index0, test-index1"); - - request.indicesOptions(new IndicesOptions()) + // tag::create-snapshot-request-indices + request.indices("test-index0, test-index1"); // <1> + // end::create-snapshot-request-indices + // tag::create-snapshot-request-indices-options + request.indicesOptions(IndicesOptions.fromOptions(false, false, true, true)); // <1> + // end::create-snapshot-request-indices-options // tag::create-snapshot-request-masterTimeout request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1> From 84b6e40b81b132fcbd30fcf37c46253b2469df59 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Thu, 7 Jun 2018 16:55:46 -0700 Subject: [PATCH 06/13] More progress. --- .../elasticsearch/client/SnapshotClient.java | 12 +-- .../SnapshotClientDocumentationIT.java | 45 ++++++++++- .../snapshot/create_snapshot.asciidoc | 81 ++++++------------- 3 files changed, 71 insertions(+), 67 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java index 2a25fa3ac4e00..158d6ff1e0bf6 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java @@ -170,10 +170,10 @@ public void verifyRepositoryAsync(VerifyRepositoryRequest verifyRepositoryReques * See Snapshot and Restore * API on elastic.co */ - public CreateSnapshotResponse createSnapshot(CreateSnapshotRequest createSnapshotRequest, Header... headers) + public CreateSnapshotResponse createSnapshot(CreateSnapshotRequest createSnapshotRequest, RequestOptions options) throws IOException { - return restHighLevelClient.performRequestAndParseEntity(createSnapshotRequest, RequestConverters::createSnapshot, - CreateSnapshotResponse::fromXContent, emptySet(), headers); + return restHighLevelClient.performRequestAndParseEntity(createSnapshotRequest, RequestConverters::createSnapshot, options, + CreateSnapshotResponse::fromXContent, emptySet()); } /** @@ -183,8 +183,8 @@ public CreateSnapshotResponse createSnapshot(CreateSnapshotRequest createSnapsho * API on elastic.co */ public void createSnapshotAsync(CreateSnapshotRequest createSnapshotRequest, - ActionListener listener, Header... headers) { - restHighLevelClient.performRequestAsyncAndParseEntity(createSnapshotRequest, RequestConverters::createSnapshot, - CreateSnapshotResponse::fromXContent, listener, emptySet(), headers); + ActionListener listener, RequestOptions options) { + restHighLevelClient.performRequestAsyncAndParseEntity(createSnapshotRequest, RequestConverters::createSnapshot, options, + CreateSnapshotResponse::fromXContent, listener, emptySet()); } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java index 54adc587a49fb..b14d6bb44df8c 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -394,6 +394,12 @@ public void testSnapshotCreateSnapshot() throws IOException { // tag::create-snapshot-request-indices-options request.indicesOptions(IndicesOptions.fromOptions(false, false, true, true)); // <1> // end::create-snapshot-request-indices-options + // tag::create-snapshot-request-partial + request.partial(false); // <1> + // end::create-snapshot-request-partial + // tag::create-snapshot-request-include-global-state + request.includeGlobalState(true); // <1> + // end::create-snapshot-request-include-global-state // tag::create-snapshot-request-masterTimeout request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1> @@ -404,13 +410,46 @@ public void testSnapshotCreateSnapshot() throws IOException { // end::create-snapshot-request-WaitForCompletion // tag::create-snapshot-execute - CreateSnapshotResponse response = client.snapshot().createSnapshot(request); + CreateSnapshotResponse response = client.snapshot().createSnapshot(request, RequestOptions.DEFAULT); // end::create-snapshot-execute - // tag::create-repository-response + // tag::create-snapshot-response RestStatus status = response.status(); - // end::create-repository-response + // end::create-snapshot-response assertEquals(RestStatus.ACCEPTED, status); } + + + public void testCreateSnapshotRepositoryAsync() throws InterruptedException { + RestHighLevelClient client = highLevelClient(); + { + CreateSnapshotRequest request = new CreateSnapshotRequest(repositoryName, snapshotName); + + // tag::create-snapshot-execute-listener + ActionListener listener = + new ActionListener() { + @Override + public void onResponse(CreateSnapshotResponse createSnapshotResponse) { + // <1> + } + + @Override + public void onFailure(Exception exception) { + // <2> + } + }; + // end::create-snapshot-execute-listener + + // Replace the empty listener by a blocking listener in test + final CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + + // tag::create-snapshot-execute-async + client.snapshot().createSnapshotAsync(request, listener, RequestOptions.DEFAULT); // <1> + // end::create-snapshot-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } + } } diff --git a/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc index f11213705e44f..3f373212ca401 100644 --- a/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc +++ b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc @@ -13,56 +13,20 @@ A `CreateSnapshotRequest`: include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request] -------------------------------------------------- -==== Repository Settings -Settings requirements will differ based on the repository backend chosen. - -["source","java",subs="attributes,callouts,macros"] --------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-repository-settings] --------------------------------------------------- -<1> Sets the repository settings - -==== Providing the Settings -The settings to be applied can be provided in different ways: - -["source","java",subs="attributes,callouts,macros"] --------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-create-settings] --------------------------------------------------- -<1> Settings provided as `Settings` - -["source","java",subs="attributes,callouts,macros"] --------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-settings-builder] --------------------------------------------------- -<1> Settings provided as `Settings.Builder` - -["source","java",subs="attributes,callouts,macros"] --------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-settings-source] --------------------------------------------------- -<1> Settings provided as `String` - -["source","java",subs="attributes,callouts,macros"] --------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-settings-map] --------------------------------------------------- -<1> Settings provided as a `Map` - ==== Required Arguments The following arguments must be provided: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-name] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-repository-name] -------------------------------------------------- -<1> The name of the repository +<1> The name of the repository. ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-type] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-snapshot-name] -------------------------------------------------- -<1> The type of the repository +<1> The name of the snapshot. ==== Optional Arguments The following arguments can optionally be provided: @@ -97,43 +61,44 @@ include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-execute] -------------------------------------------------- -[[java-rest-high-snapshot-create-repository-async]] +[[java-rest-high-snapshot-create-snapshot-async]] ==== Asynchronous Execution -The asynchronous execution of a repository put settings requires both the -`PutRepositoryRequest` instance and an `ActionListener` instance to be -passed to the asynchronous method: +The asynchronous execution of a create snapshot request requires both the +`CreateSnapshotRequest` instance and an `ActionListener` instance to be +passed as arguments to the asynchronous method: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-execute-async] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-execute-async] -------------------------------------------------- -<1> The `PutRepositoryRequest` to execute and the `ActionListener` -to use when the execution completes +<1> The `CreateSnapshotRequest` to execute and the `ActionListener` to use when +the execution completes. The asynchronous method does not block and returns immediately. Once it is -completed the `ActionListener` is called back using the `onResponse` method -if the execution successfully completed or using the `onFailure` method if -it failed. +completed the `ActionListener` is called back with the `onResponse` method +if the execution is successful or the `onFailure` method if the execution +failed. -A typical listener for `PutRepositoryResponse` looks like: +A typical listener for `CreateSnapshotResponse` looks like: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-execute-listener] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-execute-listener] -------------------------------------------------- <1> Called when the execution is successfully completed. The response is -provided as an argument -<2> Called in case of a failure. The raised exception is provided as an argument +provided as an argument. +<2> Called in case of a failure. The raised exception is provided as an +argument. [[java-rest-high-snapshot-create-repository-response]] ==== Snapshot Create RepositoryResponse -The returned `PutRepositoryResponse` allows to retrieve information about the -executed operation as follows: +Use the `PutRepositoryResponse` to retrieve information about the evaluated +request: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-response] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-response] -------------------------------------------------- -<1> Indicates the node has acknowledged the request +<1> Indicates the node has started the request. From 2a7665c38bf7d3b8465822255ffeb09185886dc6 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 8 Jun 2018 10:55:56 -0700 Subject: [PATCH 07/13] Added docs tests. --- .../SnapshotClientDocumentationIT.java | 8 ++-- .../snapshot/create_snapshot.asciidoc | 41 +++++++++++++------ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java index b14d6bb44df8c..094c7bae1018c 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -391,15 +391,15 @@ public void testSnapshotCreateSnapshot() throws IOException { // tag::create-snapshot-request-indices request.indices("test-index0, test-index1"); // <1> // end::create-snapshot-request-indices - // tag::create-snapshot-request-indices-options + // tag::create-snapshot-request-indicesOptions request.indicesOptions(IndicesOptions.fromOptions(false, false, true, true)); // <1> - // end::create-snapshot-request-indices-options + // end::create-snapshot-request-indicesOptions // tag::create-snapshot-request-partial request.partial(false); // <1> // end::create-snapshot-request-partial - // tag::create-snapshot-request-include-global-state + // tag::create-snapshot-request-includeGlobalState request.includeGlobalState(true); // <1> - // end::create-snapshot-request-include-global-state + // end::create-snapshot-request-includeGlobalState // tag::create-snapshot-request-masterTimeout request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1> diff --git a/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc index 3f373212ca401..5ffd1b12638c0 100644 --- a/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc +++ b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc @@ -14,7 +14,7 @@ include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-r -------------------------------------------------- ==== Required Arguments -The following arguments must be provided: +The following arguments are mandatory: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- @@ -29,29 +29,46 @@ include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-r <1> The name of the snapshot. ==== Optional Arguments -The following arguments can optionally be provided: +The following arguments are optional: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-timeout] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-indices] -------------------------------------------------- -<1> Timeout to wait for the all the nodes to acknowledge the settings were applied -as a `TimeValue` -<2> Timeout to wait for the all the nodes to acknowledge the settings were applied -as a `String` +<1> A list of indices the snapshot is applied to. ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-masterTimeout] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-indicesOptions] -------------------------------------------------- -<1> Timeout to connect to the master node as a `TimeValue` -<2> Timeout to connect to the master node as a `String` +<1> Options applied to the indices. ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-verify] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-partial] -------------------------------------------------- -<1> Verify after creation as a `Boolean` +<1> Set `partial` to `true` to allow a successful snapshot without the +availability of all the indices primary shards. Defaults to `false`. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-includeGlobalState] +-------------------------------------------------- +<1> Set `includeGlobalState` to `false` to prevent writing the cluster's global +state as part of the snapshot. Defaults to `true`. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-masterTimeout] +-------------------------------------------------- +<1> Timeout to connect to the master node as a `TimeValue`. +<2> Timeout to connect to the master node as a `String`. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-waitForCompletion] +-------------------------------------------------- +<1> Waits for the snapshot to be completed before a response is returned. [[java-rest-high-snapshot-create-repository-sync]] ==== Synchronous Execution From 9879a2811494fd297c0edaa9ac5ab075eaa020c0 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 8 Jun 2018 11:19:40 -0700 Subject: [PATCH 08/13] Docs fixes. --- .../SnapshotClientDocumentationIT.java | 4 ++-- .../high-level/snapshot/create_snapshot.asciidoc | 14 +++++++------- docs/java-rest/high-level/supported-apis.asciidoc | 2 ++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java index 094c7bae1018c..53e30f4400a7d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -407,14 +407,14 @@ public void testSnapshotCreateSnapshot() throws IOException { // end::create-snapshot-request-masterTimeout // tag::create-snapshot-request-waitForCompletion request.waitForCompletion(false); // <1> - // end::create-snapshot-request-WaitForCompletion + // end::create-snapshot-request-waitForCompletion // tag::create-snapshot-execute CreateSnapshotResponse response = client.snapshot().createSnapshot(request, RequestOptions.DEFAULT); // end::create-snapshot-execute // tag::create-snapshot-response - RestStatus status = response.status(); + RestStatus status = response.status(); // <1> // end::create-snapshot-response assertEquals(RestStatus.ACCEPTED, status); diff --git a/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc index 5ffd1b12638c0..dbd31380a9b4b 100644 --- a/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc +++ b/docs/java-rest/high-level/snapshot/create_snapshot.asciidoc @@ -18,13 +18,13 @@ The following arguments are mandatory: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-repository-name] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-repositoryName] -------------------------------------------------- <1> The name of the repository. ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-snapshot-name] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-snapshotName] -------------------------------------------------- <1> The name of the snapshot. @@ -70,12 +70,12 @@ include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-r -------------------------------------------------- <1> Waits for the snapshot to be completed before a response is returned. -[[java-rest-high-snapshot-create-repository-sync]] +[[java-rest-high-snapshot-create-snapshot-sync]] ==== Synchronous Execution ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-execute] +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-execute] -------------------------------------------------- [[java-rest-high-snapshot-create-snapshot-async]] @@ -108,10 +108,10 @@ provided as an argument. <2> Called in case of a failure. The raised exception is provided as an argument. -[[java-rest-high-snapshot-create-repository-response]] -==== Snapshot Create RepositoryResponse +[[java-rest-high-snapshot-create-snapshot-response]] +==== Snapshot Create Response -Use the `PutRepositoryResponse` to retrieve information about the evaluated +Use the `CreateSnapshotResponse` to retrieve information about the evaluated request: ["source","java",subs="attributes,callouts,macros"] diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 783cc773e961d..669dfc751fdd7 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -129,11 +129,13 @@ The Java High Level REST Client supports the following Snapshot APIs: * <> * <> * <> +* <> include::snapshot/get_repository.asciidoc[] include::snapshot/create_repository.asciidoc[] include::snapshot/delete_repository.asciidoc[] include::snapshot/verify_repository.asciidoc[] +include::snapshot/create_snapshot.asciidoc[] == Tasks APIs From 891b2a04ea3497c6f9959b318cf6fbc74422d891 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 8 Jun 2018 11:35:35 -0700 Subject: [PATCH 09/13] Style violation. --- .../admin/cluster/snapshots/create/CreateSnapshotRequest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java index c809835448dd3..9346bafa0a0eb 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java @@ -59,7 +59,8 @@ *
  • must not contain invalid file name characters {@link org.elasticsearch.common.Strings#INVALID_FILENAME_CHARS}
  • * */ -public class CreateSnapshotRequest extends MasterNodeRequest implements IndicesRequest.Replaceable, ToXContentObject { +public class CreateSnapshotRequest extends MasterNodeRequest + implements IndicesRequest.Replaceable, ToXContentObject { private String snapshot; From 04b568e95969cc725a0bac8523d29d5053dcdd71 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 8 Jun 2018 12:58:04 -0700 Subject: [PATCH 10/13] Fix test failure. --- .../elasticsearch/client/SnapshotClient.java | 4 ++-- .../org/elasticsearch/client/SnapshotIT.java | 5 ++--- .../SnapshotClientDocumentationIT.java | 18 ++++++++++++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java index 158d6ff1e0bf6..c854ff8986f6b 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java @@ -182,8 +182,8 @@ public CreateSnapshotResponse createSnapshot(CreateSnapshotRequest createSnapsho * See Snapshot and Restore * API on elastic.co */ - public void createSnapshotAsync(CreateSnapshotRequest createSnapshotRequest, - ActionListener listener, RequestOptions options) { + public void createSnapshotAsync(CreateSnapshotRequest createSnapshotRequest, RequestOptions options, + ActionListener listener) { restHighLevelClient.performRequestAsyncAndParseEntity(createSnapshotRequest, RequestConverters::createSnapshot, options, CreateSnapshotResponse::fromXContent, listener, emptySet()); } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java index 21c7b26ff0a10..c02e3b404b53d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java @@ -116,10 +116,9 @@ public void testVerifyRepository() throws IOException { assertThat(response.getNodes().size(), equalTo(1)); } - private CreateSnapshotResponse createTestSnapshot(String repository, String snapshot, String settings) throws IOException { + private CreateSnapshotResponse createTestSnapshot(String repository, String snapshot) throws IOException { // assumes the repository already exists CreateSnapshotRequest request = new CreateSnapshotRequest(repository, snapshot); - request.settings(settings, XContentType.JSON); return execute(request, highLevelClient().snapshot()::createSnapshot, highLevelClient().snapshot()::createSnapshotAsync); } @@ -127,7 +126,7 @@ private CreateSnapshotResponse createTestSnapshot(String repository, String snap public void testCreateSnapshot() throws IOException { assertTrue(createTestRepository("test", FsRepository.TYPE, "{\"location\": \".\"}").isAcknowledged()); - CreateSnapshotResponse response = createTestSnapshot("test", "snapshot-test", "{}"); + CreateSnapshotResponse response = createTestSnapshot("test", "snapshot-test"); assertEquals(response.status(), RestStatus.ACCEPTED); } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java index 53e30f4400a7d..4e42b159e5847 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -31,6 +31,7 @@ import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.ESRestHighLevelClientTestCase; import org.elasticsearch.client.RequestOptions; @@ -374,10 +375,15 @@ private void createTestRepositories() throws IOException { private static final String snapshotName = "test_snapshot"; public void testSnapshotCreateSnapshot() throws IOException { - createTestRepositories(); - RestHighLevelClient client = highLevelClient(); + CreateIndexRequest createIndexRequest = new CreateIndexRequest("test-index0"); + client.indices().create(createIndexRequest, RequestOptions.DEFAULT); + createIndexRequest = new CreateIndexRequest("test-index1"); + client.indices().create(createIndexRequest, RequestOptions.DEFAULT); + + createTestRepositories(); + // tag::create-snapshot-request CreateSnapshotRequest request = new CreateSnapshotRequest(); // end::create-snapshot-request @@ -389,7 +395,7 @@ public void testSnapshotCreateSnapshot() throws IOException { request.snapshot(snapshotName); // <1> // end::create-snapshot-request-snapshotName // tag::create-snapshot-request-indices - request.indices("test-index0, test-index1"); // <1> + request.indices("test-index0", "test-index1"); // <1> // end::create-snapshot-request-indices // tag::create-snapshot-request-indicesOptions request.indicesOptions(IndicesOptions.fromOptions(false, false, true, true)); // <1> @@ -406,7 +412,7 @@ public void testSnapshotCreateSnapshot() throws IOException { request.masterNodeTimeout("1m"); // <2> // end::create-snapshot-request-masterTimeout // tag::create-snapshot-request-waitForCompletion - request.waitForCompletion(false); // <1> + request.waitForCompletion(true); // <1> // end::create-snapshot-request-waitForCompletion // tag::create-snapshot-execute @@ -417,7 +423,7 @@ public void testSnapshotCreateSnapshot() throws IOException { RestStatus status = response.status(); // <1> // end::create-snapshot-response - assertEquals(RestStatus.ACCEPTED, status); + assertEquals(RestStatus.OK, status); } @@ -446,7 +452,7 @@ public void onFailure(Exception exception) { listener = new LatchedActionListener<>(listener, latch); // tag::create-snapshot-execute-async - client.snapshot().createSnapshotAsync(request, listener, RequestOptions.DEFAULT); // <1> + client.snapshot().createSnapshotAsync(request, RequestOptions.DEFAULT, listener); // <1> // end::create-snapshot-execute-async assertTrue(latch.await(30L, TimeUnit.SECONDS)); From c664596badd21a999c380a18768ebae502ebde46 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 8 Jun 2018 16:22:37 -0700 Subject: [PATCH 11/13] Fix discrepanices in equals method for ShardId related to uuid of index incosistency. --- .../java/org/elasticsearch/snapshots/SnapshotInfo.java | 7 ++++++- .../elasticsearch/snapshots/SnapshotShardFailure.java | 10 ++++++---- .../snapshots/create/CreateSnapshotResponseTests.java | 6 +++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java index e18006ebb3917..ab25156d79b22 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java @@ -138,6 +138,10 @@ private void setVersion(int version) { } private void setShardFailures(XContentParser parser) { + if (shardFailures == null) { + shardFailures = new ArrayList<>(); + } + try { if (parser.currentToken() == Token.START_ARRAY) { parser.nextToken(); @@ -145,6 +149,7 @@ private void setShardFailures(XContentParser parser) { while (parser.currentToken() != Token.END_ARRAY) { shardFailures.add(SnapshotShardFailure.fromXContent(parser)); + parser.nextToken(); } } catch (IOException exception) { throw new UncheckedIOException(exception); @@ -232,7 +237,7 @@ private void ignoreFailedShards(int failedShards) { SNAPSHOT_INFO_PARSER.declareBoolean(SnapshotInfoBuilder::setIncludeGlobalState, new ParseField(INCLUDE_GLOBAL_STATE)); SNAPSHOT_INFO_PARSER.declareInt(SnapshotInfoBuilder::setVersion, new ParseField(VERSION_ID)); SNAPSHOT_INFO_PARSER.declareField( - SnapshotInfoBuilder::setShardFailures, parser -> parser, new ParseField(FAILURES), ValueType.OBJECT_ARRAY); + SnapshotInfoBuilder::setShardFailures, parser -> parser, new ParseField(FAILURES), ValueType.OBJECT_ARRAY_OR_STRING); SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::ignoreVersion, new ParseField(VERSION)); SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::ignoreStartTime, new ParseField(START_TIME)); SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::ignoreEndTime, new ParseField(END_TIME)); diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotShardFailure.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotShardFailure.java index 42fa7b74ce62b..30057a6220dcb 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotShardFailure.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotShardFailure.java @@ -250,15 +250,17 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SnapshotShardFailure that = (SnapshotShardFailure) o; - return Objects.equals(shardId, that.shardId) && + // customized to account for discrepancies in shardId/Index toXContent/fromXContent related to uuid + return shardId.id() == that.shardId.id() && + shardId.getIndexName().equals(shardId.getIndexName()) && Objects.equals(reason, that.reason) && Objects.equals(nodeId, that.nodeId) && - status == that.status; + status.getStatus() == that.status.getStatus(); } @Override public int hashCode() { - - return Objects.hash(shardId, reason, nodeId, status); + // customized to account for discrepancies in shardId/Index toXContent/fromXContent related to uuid + return Objects.hash(shardId.id(), shardId.getIndexName(), reason, nodeId, status.getStatus()); } } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java index 91e6fd2455f55..bbfc9755bf215 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java @@ -52,13 +52,13 @@ protected CreateSnapshotResponse createTestInstance() { String reason = "reason"; long startTime = System.currentTimeMillis(); long endTime = startTime + 10000; - int totalShards = randomIntBetween(1, 15); - int successfulShards = randomIntBetween(14, 15); + int totalShards = randomIntBetween(1, 3); + int successfulShards = randomIntBetween(0, totalShards); List shardFailures = new ArrayList<>(); for (int count = successfulShards; count < totalShards; ++count) { shardFailures.add(new SnapshotShardFailure( - "node-id", new ShardId("index", UUID.randomUUID().toString(), randomInt()), "reason")); + "node-id", new ShardId("index-" + count, UUID.randomUUID().toString(), randomInt()), "reason")); } boolean globalState = randomBoolean(); From 7aaaf9554ab02e687dfebc5d2aac0953387aebc1 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Tue, 26 Jun 2018 16:33:14 -0700 Subject: [PATCH 12/13] Response to PR feedback. --- .../org/elasticsearch/client/SnapshotIT.java | 37 +++--- .../SnapshotClientDocumentationIT.java | 4 +- .../create/CreateSnapshotRequest.java | 48 +++++++- .../create/CreateSnapshotResponse.java | 27 ++++- .../elasticsearch/snapshots/SnapshotInfo.java | 14 ++- .../create/CreateSnapshotRequestTests.java | 105 ++++++++++++++++++ 6 files changed, 209 insertions(+), 26 deletions(-) create mode 100644 server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequestTests.java diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java index 455544da24177..aacb2f5025ee4 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java @@ -37,7 +37,6 @@ import org.elasticsearch.rest.RestStatus; import java.io.IOException; -import java.util.Locale; import static org.hamcrest.Matchers.equalTo; @@ -51,10 +50,11 @@ private PutRepositoryResponse createTestRepository(String repository, String typ highLevelClient().snapshot()::createRepositoryAsync); } - private Response createTestSnapshot(String repository, String snapshot) throws IOException { - Request createSnapshot = new Request("put", String.format(Locale.ROOT, "_snapshot/%s/%s", repository, snapshot)); - createSnapshot.addParameter("wait_for_completion", "true"); - return highLevelClient().getLowLevelClient().performRequest(createSnapshot); + private CreateSnapshotResponse createTestSnapshot(CreateSnapshotRequest createSnapshotRequest) throws IOException { + // assumes the repository already exists + + return execute(createSnapshotRequest, highLevelClient().snapshot()::createSnapshot, + highLevelClient().snapshot()::createSnapshotAsync); } public void testCreateRepository() throws IOException { @@ -120,18 +120,19 @@ public void testVerifyRepository() throws IOException { assertThat(response.getNodes().size(), equalTo(1)); } - private CreateSnapshotResponse createTestSnapshotChange(String repository, String snapshot) throws IOException { - // assumes the repository already exists - CreateSnapshotRequest request = new CreateSnapshotRequest(repository, snapshot); - return execute(request, highLevelClient().snapshot()::createSnapshot, - highLevelClient().snapshot()::createSnapshotAsync); - } - public void testCreateSnapshot() throws IOException { - assertTrue(createTestRepository("test", FsRepository.TYPE, "{\"location\": \".\"}").isAcknowledged()); + String repository = "test_repository"; + assertTrue(createTestRepository(repository, FsRepository.TYPE, "{\"location\": \".\"}").isAcknowledged()); + + String snapshot = "test_snapshot"; + CreateSnapshotRequest request = new CreateSnapshotRequest(repository, snapshot); + boolean waitForCompletion = randomBoolean(); + request.waitForCompletion(waitForCompletion); + request.partial(randomBoolean()); + request.includeGlobalState(randomBoolean()); - CreateSnapshotResponse response = createTestSnapshotChange("test", "snapshot-test"); - assertEquals(response.status(), RestStatus.ACCEPTED); + CreateSnapshotResponse response = createTestSnapshot(request); + assertEquals(waitForCompletion ? RestStatus.OK : RestStatus.ACCEPTED, response.status()); } public void testDeleteSnapshot() throws IOException { @@ -141,9 +142,11 @@ public void testDeleteSnapshot() throws IOException { PutRepositoryResponse putRepositoryResponse = createTestRepository(repository, FsRepository.TYPE, "{\"location\": \".\"}"); assertTrue(putRepositoryResponse.isAcknowledged()); - Response putSnapshotResponse = createTestSnapshot(repository, snapshot); + CreateSnapshotRequest createSnapshotRequest = new CreateSnapshotRequest(repository, snapshot); + createSnapshotRequest.waitForCompletion(true); + CreateSnapshotResponse createSnapshotResponse = createTestSnapshot(createSnapshotRequest); // check that the request went ok without parsing JSON here. When using the high level client, check acknowledgement instead. - assertEquals(200, putSnapshotResponse.getStatusLine().getStatusCode()); + assertEquals(RestStatus.OK, createSnapshotResponse.status()); DeleteSnapshotRequest request = new DeleteSnapshotRequest(repository, snapshot); DeleteSnapshotResponse response = execute(request, highLevelClient().snapshot()::delete, highLevelClient().snapshot()::deleteAsync); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java index 01545e7c7d84f..9c0e31bdcfb70 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -372,7 +372,7 @@ public void onFailure(Exception e) { } } - public void testSnapshotCreateSnapshot() throws IOException { + public void testSnapshotCreate() throws IOException { RestHighLevelClient client = highLevelClient(); CreateIndexRequest createIndexRequest = new CreateIndexRequest("test-index0"); @@ -424,7 +424,7 @@ public void testSnapshotCreateSnapshot() throws IOException { assertEquals(RestStatus.OK, status); } - public void testCreateSnapshotRepositoryAsync() throws InterruptedException { + public void testSnapshotCreateAsync() throws InterruptedException { RestHighLevelClient client = highLevelClient(); { CreateSnapshotRequest request = new CreateSnapshotRequest(repositoryName, snapshotName); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java index 9346bafa0a0eb..2ff01ab01ed1f 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java @@ -35,8 +35,10 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Objects; import static org.elasticsearch.action.ValidateActions.addValidationError; import static org.elasticsearch.common.Strings.EMPTY_ARRAY; @@ -421,12 +423,18 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.endArray(); builder.field("partial", partial); if (settings != null) { - settings.toXContent(builder, params); + builder.startObject("settings"); + if (settings.isEmpty() == false) { + settings.toXContent(builder, params); + } + builder.endObject(); } builder.field("include_global_state", includeGlobalState); if (indicesOptions != null) { indicesOptions.toXContent(builder, params); } + builder.field("wait_for_completion", waitForCompletion); + builder.field("master_node_timeout", masterNodeTimeout.toString()); builder.endObject(); return builder; } @@ -440,4 +448,42 @@ public void readFrom(StreamInput in) throws IOException { public String getDescription() { return "snapshot [" + repository + ":" + snapshot + "]"; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CreateSnapshotRequest that = (CreateSnapshotRequest) o; + return partial == that.partial && + includeGlobalState == that.includeGlobalState && + waitForCompletion == that.waitForCompletion && + Objects.equals(snapshot, that.snapshot) && + Objects.equals(repository, that.repository) && + Arrays.equals(indices, that.indices) && + Objects.equals(indicesOptions, that.indicesOptions) && + Objects.equals(settings, that.settings) && + Objects.equals(masterNodeTimeout, that.masterNodeTimeout); + } + + @Override + public int hashCode() { + int result = Objects.hash(snapshot, repository, indicesOptions, partial, settings, includeGlobalState, waitForCompletion); + result = 31 * result + Arrays.hashCode(indices); + return result; + } + + @Override + public String toString() { + return "CreateSnapshotRequest{" + + "snapshot='" + snapshot + '\'' + + ", repository='" + repository + '\'' + + ", indices=" + (indices == null ? null : Arrays.asList(indices)) + + ", indicesOptions=" + indicesOptions + + ", partial=" + partial + + ", settings=" + settings + + ", includeGlobalState=" + includeGlobalState + + ", waitForCompletion=" + waitForCompletion + + ", masterNodeTimeout=" + masterNodeTimeout + + '}'; + } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java index 23325af2eded0..a2dc02c5c8299 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java @@ -26,6 +26,7 @@ import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParser.Token; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.snapshots.SnapshotInfo; @@ -103,14 +104,33 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws public static CreateSnapshotResponse fromXContent(XContentParser parser) throws IOException { CreateSnapshotResponse createSnapshotResponse = new CreateSnapshotResponse(); - parser.nextToken(); // '{' - parser.nextToken(); // 'snapshot' || 'accepted' + parser.nextToken(); // move to '{' + + if (parser.currentToken() != Token.START_OBJECT) { + throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "], expected ['{']"); + } + + parser.nextToken(); // move to 'snapshot' || 'accepted' if ("snapshot".equals(parser.currentName())) { createSnapshotResponse.snapshotInfo = SnapshotInfo.fromXContent(parser); + } else if ("accepted".equals(parser.currentName())) { + parser.nextToken(); // move to 'accepted' field value + + if (parser.booleanValue()) { + // ensure accepted is a boolean value + } + + parser.nextToken(); // move past 'true'/'false' + } else { + throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "] expected ['snapshot', 'accepted']"); + } + + if (parser.currentToken() != Token.END_OBJECT) { + throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "], expected ['}']"); } - parser.nextToken(); // '}' + parser.nextToken(); // move past '}' return createSnapshotResponse; } @@ -132,7 +152,6 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(snapshotInfo); } } diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java index ab25156d79b22..ddd7385056d55 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java @@ -610,9 +610,19 @@ private XContentBuilder toXContentSnapshot(final XContentBuilder builder, final } public static SnapshotInfo fromXContent(final XContentParser parser) throws IOException { - parser.nextToken(); + parser.nextToken(); // // move to '{' + + if (parser.currentToken() != Token.START_OBJECT) { + throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "], expected ['{']"); + } + SnapshotInfo snapshotInfo = SNAPSHOT_INFO_PARSER.apply(parser, null).build(); - parser.nextToken(); + + if (parser.currentToken() != Token.END_OBJECT) { + throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "], expected ['}']"); + } + + parser.nextToken(); // move past '}' return snapshotInfo; } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequestTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequestTests.java new file mode 100644 index 0000000000000..e55724c892c0c --- /dev/null +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequestTests.java @@ -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.action.admin.cluster.snapshots.create; + +import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.test.ESTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CreateSnapshotRequestTests extends ESTestCase { + + // tests creating XContent and parsing with source(Map) equivalency + public void testToXContent() throws IOException { + String repo = randomAlphaOfLength(5); + String snap = randomAlphaOfLength(10); + + CreateSnapshotRequest original = new CreateSnapshotRequest(repo, snap); + + if (randomBoolean()) { // replace + List indices = new ArrayList<>(); + int count = randomInt(3) + 1; + + for (int i = 0; i < count; ++i) { + indices.add(randomAlphaOfLength(randomInt(3) + 2)); + } + + original.indices(indices); + } + + if (randomBoolean()) { // replace + original.partial(randomBoolean()); + } + + if (randomBoolean()) { // replace + Map settings = new HashMap<>(); + int count = randomInt(3) + 1; + + for (int i = 0; i < count; ++i) { + settings.put(randomAlphaOfLength(randomInt(3) + 2), randomAlphaOfLength(randomInt(3) + 2)); + } + + } + + if (randomBoolean()) { // replace + original.includeGlobalState(randomBoolean()); + } + + if (randomBoolean()) { // replace + IndicesOptions[] indicesOptions = new IndicesOptions[] { + IndicesOptions.STRICT_EXPAND_OPEN, + IndicesOptions.STRICT_EXPAND_OPEN_CLOSED, + IndicesOptions.LENIENT_EXPAND_OPEN, + IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED, + IndicesOptions.STRICT_SINGLE_INDEX_NO_EXPAND_FORBID_CLOSED}; + + original.indicesOptions(randomFrom(indicesOptions)); + } + + if (randomBoolean()) { // replace + original.waitForCompletion(randomBoolean()); + } + + if (randomBoolean()) { // replace + original.masterNodeTimeout("60s"); + } + + XContentBuilder builder = original.toXContent(XContentFactory.jsonBuilder(), null); + XContentParser parser = XContentType.JSON.xContent().createParser( + NamedXContentRegistry.EMPTY, null, BytesReference.bytes(builder).streamInput()); + Map map = parser.mapOrdered(); + CreateSnapshotRequest processed = new CreateSnapshotRequest((String)map.get("repository"), (String)map.get("snapshot")); + processed.waitForCompletion((boolean)map.getOrDefault("wait_for_completion", false)); + processed.masterNodeTimeout((String)map.getOrDefault("master_node_timeout", "30s")); + processed.source(map); + + assertEquals(original, processed); + } +} From ffbf58d4fbfa2fa6cb852dc16e3b694152828248 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Wed, 27 Jun 2018 07:18:03 -0700 Subject: [PATCH 13/13] Added waitForCompletion to RequestConvertTests. --- .../org/elasticsearch/client/RequestConvertersTests.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java index 440e2a4981356..954dd77b07c01 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java @@ -1997,6 +1997,12 @@ public void testCreateSnapshot() throws IOException { CreateSnapshotRequest createSnapshotRequest = new CreateSnapshotRequest(repository, snapshot); setRandomMasterTimeout(createSnapshotRequest, expectedParams); + Boolean waitForCompletion = randomBoolean(); + createSnapshotRequest.waitForCompletion(waitForCompletion); + + if (waitForCompletion) { + expectedParams.put("wait_for_completion", waitForCompletion.toString()); + } Request request = RequestConverters.createSnapshot(createSnapshotRequest); assertThat(endpoint, equalTo(request.getEndpoint()));