From 540ff1de306a07e08e1dac41d69a570cb1f2838f Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Thu, 28 Nov 2019 10:09:42 +0100 Subject: [PATCH 01/45] bck --- .../repositories/Repository.java | 7 +- .../repositories/RepositoryData.java | 50 ++++++------ .../blobstore/BlobStoreRepository.java | 79 ++++++++++--------- .../repositories/RepositoryDataTests.java | 6 +- .../blobstore/BlobStoreRepositoryTests.java | 2 +- 5 files changed, 79 insertions(+), 65 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/repositories/Repository.java b/server/src/main/java/org/elasticsearch/repositories/Repository.java index 800d1b0c19a95..e02fd8a95a701 100644 --- a/server/src/main/java/org/elasticsearch/repositories/Repository.java +++ b/server/src/main/java/org/elasticsearch/repositories/Repository.java @@ -35,6 +35,7 @@ import org.elasticsearch.snapshots.SnapshotShardFailure; import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -131,14 +132,14 @@ void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenerations, boolean writeShardGens, ActionListener listener); /** - * Deletes snapshot + * Deletes snapshots * - * @param snapshotId snapshot id + * @param snapshotIds snapshot ids to delete * @param repositoryStateId the unique id identifying the state of the repository when the snapshot deletion began * @param writeShardGens if shard generations should be written to the repository * @param listener completion listener */ - void deleteSnapshot(SnapshotId snapshotId, long repositoryStateId, boolean writeShardGens, ActionListener listener); + void deleteSnapshot(Collection snapshotIds, long repositoryStateId, boolean writeShardGens, ActionListener listener); /** * Returns snapshot throttle time in nanoseconds diff --git a/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java b/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java index 20dcdc2371805..c97d33b541487 100644 --- a/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java +++ b/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java @@ -34,6 +34,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -139,13 +140,22 @@ public Map getIndices() { * Returns the list of {@link IndexId} that have their snapshots updated but not removed (because they are still referenced by other * snapshots) after removing the given snapshot from the repository. * - * @param snapshotId SnapshotId to remove + * @param snapshotIds SnapshotId to remove * @return List of indices that are changed but not removed */ - public List indicesToUpdateAfterRemovingSnapshot(SnapshotId snapshotId) { + public List indicesToUpdateAfterRemovingSnapshot(Collection snapshotIds) { return indexSnapshots.entrySet().stream() - .filter(entry -> entry.getValue().size() > 1 && entry.getValue().contains(snapshotId)) - .map(Map.Entry::getKey) + .filter(entry -> { + if (entry.getValue().containsAll(snapshotIds)) { + return false; + } + for (SnapshotId snapshotId : snapshotIds) { + if (entry.getValue().contains(snapshotId)) { + return true; + } + } + return false; + }).map(Map.Entry::getKey) .collect(Collectors.toList()); } @@ -195,37 +205,33 @@ public RepositoryData withGenId(long newGeneration) { /** * Remove a snapshot and remove any indices that no longer exist in the repository due to the deletion of the snapshot. * - * @param snapshotId Snapshot Id + * @param snapshots Snapshot ids to remove * @param updatedShardGenerations Shard generations that changed as a result of removing the snapshot. * The {@code String[]} passed for each {@link IndexId} contains the new shard generation id for each * changed shard indexed by its shardId */ - public RepositoryData removeSnapshot(final SnapshotId snapshotId, final ShardGenerations updatedShardGenerations) { - Map newSnapshotIds = snapshotIds.values().stream() - .filter(id -> !snapshotId.equals(id)) + public RepositoryData removeSnapshot(final Collection snapshots, final ShardGenerations updatedShardGenerations) { + Map newSnapshotIds = snapshotIds.values().stream().filter(snapshots::contains) .collect(Collectors.toMap(SnapshotId::getUUID, Function.identity())); - if (newSnapshotIds.size() == snapshotIds.size()) { - throw new ResourceNotFoundException("Attempting to remove non-existent snapshot [{}] from repository data", snapshotId); + if (newSnapshotIds.size() != snapshotIds.size() - snapshots.size()) { + final Collection notFound = new HashSet<>(snapshots); + notFound.removeAll(snapshotIds.values()); + throw new ResourceNotFoundException("Attempting to remove non-existent snapshots {} from repository data", notFound); } Map newSnapshotStates = new HashMap<>(snapshotStates); - newSnapshotStates.remove(snapshotId.getUUID()); + for (SnapshotId snapshotId : snapshots) { + newSnapshotStates.remove(snapshotId.getUUID()); + } Map> indexSnapshots = new HashMap<>(); for (final IndexId indexId : indices.values()) { Set set; Set snapshotIds = this.indexSnapshots.get(indexId); assert snapshotIds != null; - if (snapshotIds.contains(snapshotId)) { - if (snapshotIds.size() == 1) { - // removing the snapshot will mean no more snapshots - // have this index, so just skip over it - continue; - } - set = new LinkedHashSet<>(snapshotIds); - set.remove(snapshotId); - } else { - set = snapshotIds; + set = new LinkedHashSet<>(snapshotIds); + set.removeAll(snapshots); + if (set.isEmpty() == false) { + indexSnapshots.put(indexId, set); } - indexSnapshots.put(indexId, set); } return new RepositoryData(genId, newSnapshotIds, newSnapshotStates, indexSnapshots, 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 e2a2d1be4ef07..2a9cc4df712b2 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -73,7 +73,6 @@ import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.snapshots.IndexShardRestoreFailedException; -import org.elasticsearch.index.snapshots.IndexShardSnapshotException; import org.elasticsearch.index.snapshots.IndexShardSnapshotFailedException; import org.elasticsearch.index.snapshots.IndexShardSnapshotStatus; import org.elasticsearch.index.snapshots.blobstore.BlobStoreIndexShardSnapshot; @@ -92,7 +91,6 @@ import org.elasticsearch.repositories.RepositoryVerificationException; import org.elasticsearch.repositories.ShardGenerations; import org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException; -import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotException; import org.elasticsearch.snapshots.SnapshotId; import org.elasticsearch.snapshots.SnapshotInfo; @@ -364,14 +362,16 @@ public RepositoryMetaData getMetadata() { } @Override - public void deleteSnapshot(SnapshotId snapshotId, long repositoryStateId, boolean writeShardGens, ActionListener listener) { + public void deleteSnapshot(Collection snapshotIds, long repositoryStateId, boolean writeShardGens, + ActionListener listener) { if (isReadOnly()) { listener.onFailure(new RepositoryException(metadata.name(), "cannot delete snapshot from a readonly repository")); } else { final long latestKnownGen = latestKnownRepoGen.get(); if (latestKnownGen > repositoryStateId) { + // TODO: Nicer exception listener.onFailure(new ConcurrentSnapshotExecutionException( - new Snapshot(metadata.name(), snapshotId), "Another concurrent operation moved repo generation to [ " + latestKnownGen + metadata.name(), snapshotIds.toString(), "Another concurrent operation moved repo generation to [ " + latestKnownGen + "] but this delete assumed generation [" + repositoryStateId + "]")); return; } @@ -381,9 +381,9 @@ public void deleteSnapshot(SnapshotId snapshotId, long repositoryStateId, boolea // Cache the indices that were found before writing out the new index-N blob so that a stuck master will never // delete an index that was created by another master node after writing this index-N blob. final Map foundIndices = blobStore().blobContainer(indicesPath()).children(); - doDeleteShardSnapshots(snapshotId, repositoryStateId, foundIndices, rootBlobs, repositoryData, writeShardGens, listener); + doDeleteShardSnapshots(snapshotIds, repositoryStateId, foundIndices, rootBlobs, repositoryData, writeShardGens, listener); } catch (Exception ex) { - listener.onFailure(new RepositoryException(metadata.name(), "failed to delete snapshot [" + snapshotId + "]", ex)); + listener.onFailure(new RepositoryException(metadata.name(), "failed to delete snapshots " + snapshotIds, ex)); } } } @@ -416,7 +416,7 @@ private RepositoryData safeRepositoryData(long repositoryStateId, Map foundIndices, + private void doDeleteShardSnapshots(Collection snapshotIds, long repositoryStateId, Map foundIndices, Map rootBlobs, RepositoryData repositoryData, boolean writeShardGens, ActionListener listener) { if (writeShardGens) { // First write the new shard state metadata (with the removed snapshot) and compute deletion targets final StepListener> writeShardMetaDataAndComputeDeletesStep = new StepListener<>(); - writeUpdatedShardMetaDataAndComputeDeletes(snapshotId, repositoryData, true, writeShardMetaDataAndComputeDeletesStep); + writeUpdatedShardMetaDataAndComputeDeletes(snapshotIds, repositoryData, true, writeShardMetaDataAndComputeDeletesStep); // Once we have put the new shard-level metadata into place, we can update the repository metadata as follows: // 1. Remove the snapshot from the list of existing snapshots // 2. Update the index shard generations of all updated shard folders @@ -446,7 +446,7 @@ private void doDeleteShardSnapshots(SnapshotId snapshotId, long repositoryStateI for (ShardSnapshotMetaDeleteResult newGen : deleteResults) { builder.put(newGen.indexId, newGen.shardId, newGen.newGeneration); } - final RepositoryData updatedRepoData = repositoryData.removeSnapshot(snapshotId, builder.build()); + final RepositoryData updatedRepoData = repositoryData.removeSnapshot(snapshotIds, builder.build()); writeIndexGen(updatedRepoData, repositoryStateId, true, ActionListener.wrap(v -> writeUpdatedRepoDataStep.onResponse(updatedRepoData), listener::onFailure)); }, listener::onFailure); @@ -456,20 +456,20 @@ private void doDeleteShardSnapshots(SnapshotId snapshotId, long repositoryStateI final ActionListener afterCleanupsListener = new GroupedActionListener<>(ActionListener.wrap(() -> listener.onResponse(null)), 2); asyncCleanupUnlinkedRootAndIndicesBlobs(foundIndices, rootBlobs, updatedRepoData, afterCleanupsListener); - asyncCleanupUnlinkedShardLevelBlobs(snapshotId, writeShardMetaDataAndComputeDeletesStep.result(), afterCleanupsListener); + asyncCleanupUnlinkedShardLevelBlobs(snapshotIds, writeShardMetaDataAndComputeDeletesStep.result(), afterCleanupsListener); }, listener::onFailure); } else { // Write the new repository data first (with the removed snapshot), using no shard generations - final RepositoryData updatedRepoData = repositoryData.removeSnapshot(snapshotId, ShardGenerations.EMPTY); + final RepositoryData updatedRepoData = repositoryData.removeSnapshot(snapshotIds, ShardGenerations.EMPTY); writeIndexGen(updatedRepoData, repositoryStateId, false, ActionListener.wrap(v -> { // Run unreferenced blobs cleanup in parallel to shard-level snapshot deletion final ActionListener afterCleanupsListener = new GroupedActionListener<>(ActionListener.wrap(() -> listener.onResponse(null)), 2); asyncCleanupUnlinkedRootAndIndicesBlobs(foundIndices, rootBlobs, updatedRepoData, afterCleanupsListener); final StepListener> writeMetaAndComputeDeletesStep = new StepListener<>(); - writeUpdatedShardMetaDataAndComputeDeletes(snapshotId, repositoryData, false, writeMetaAndComputeDeletesStep); + writeUpdatedShardMetaDataAndComputeDeletes(snapshotIds, repositoryData, false, writeMetaAndComputeDeletesStep); writeMetaAndComputeDeletesStep.whenComplete(deleteResults -> - asyncCleanupUnlinkedShardLevelBlobs(snapshotId, deleteResults, afterCleanupsListener), + asyncCleanupUnlinkedShardLevelBlobs(snapshotIds, deleteResults, afterCleanupsListener), afterCleanupsListener::onFailure); }, listener::onFailure)); } @@ -482,17 +482,18 @@ private void asyncCleanupUnlinkedRootAndIndicesBlobs(Map l -> cleanupStaleBlobs(foundIndices, rootBlobs, updatedRepoData, ActionListener.map(l, ignored -> null)))); } - private void asyncCleanupUnlinkedShardLevelBlobs(SnapshotId snapshotId, Collection deleteResults, + private void asyncCleanupUnlinkedShardLevelBlobs(Collection snapshotIds, + Collection deleteResults, ActionListener listener) { threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(ActionRunnable.wrap( listener, l -> { try { - blobContainer().deleteBlobsIgnoringIfNotExists(resolveFilesToDelete(snapshotId, deleteResults)); + blobContainer().deleteBlobsIgnoringIfNotExists(resolveFilesToDelete(snapshotIds, deleteResults)); l.onResponse(null); } catch (Exception e) { logger.warn( - () -> new ParameterizedMessage("[{}] Failed to delete some blobs during snapshot delete", snapshotId), + () -> new ParameterizedMessage("{} Failed to delete some blobs during snapshot delete", snapshotIds), e); throw e; } @@ -500,11 +501,11 @@ private void asyncCleanupUnlinkedShardLevelBlobs(SnapshotId snapshotId, Collecti } // updates the shard state metadata for shards of a snapshot that is to be deleted. Also computes the files to be cleaned up. - private void writeUpdatedShardMetaDataAndComputeDeletes(SnapshotId snapshotId, RepositoryData oldRepositoryData, + private void writeUpdatedShardMetaDataAndComputeDeletes(Collection snapshotIds, RepositoryData oldRepositoryData, boolean useUUIDs, ActionListener> onAllShardsCompleted) { final Executor executor = threadPool.executor(ThreadPool.Names.SNAPSHOT); - final List indices = oldRepositoryData.indicesToUpdateAfterRemovingSnapshot(snapshotId); + final List indices = oldRepositoryData.indicesToUpdateAfterRemovingSnapshot(snapshotIds); if (indices.isEmpty()) { onAllShardsCompleted.onResponse(Collections.emptyList()); @@ -518,7 +519,7 @@ private void writeUpdatedShardMetaDataAndComputeDeletes(SnapshotId snapshotId, R for (IndexId indexId : indices) { final Set survivingSnapshots = oldRepositoryData.getSnapshots(indexId).stream() - .filter(id -> id.equals(snapshotId) == false).collect(Collectors.toSet()); + .filter(id -> snapshotIds.contains(id) == false).collect(Collectors.toSet()); executor.execute(ActionRunnable.wrap(deleteIndexMetaDataListener, deleteIdxMetaListener -> { final IndexMetaData indexMetaData; try { @@ -541,32 +542,33 @@ private void writeUpdatedShardMetaDataAndComputeDeletes(SnapshotId snapshotId, R final Index index = indexMetaData.getIndex(); for (int shardId = 0; shardId < indexMetaData.getNumberOfShards(); shardId++) { final ShardId shard = new ShardId(index, shardId); + final int finalShardId = shardId; executor.execute(new AbstractRunnable() { @Override protected void doRun() throws Exception { - final BlobContainer shardContainer = shardContainer(indexId, shard); - final Set blobs = getShardBlobs(shard, shardContainer); + final BlobContainer shardContainer = shardContainer(indexId, finalShardId); + final Set blobs = getShardBlobs(shardContainer); final BlobStoreIndexShardSnapshots blobStoreIndexShardSnapshots; final String newGen; if (useUUIDs) { newGen = UUIDs.randomBase64UUID(); blobStoreIndexShardSnapshots = buildBlobStoreIndexShardSnapshots(blobs, shardContainer, - oldRepositoryData.shardGenerations().getShardGen(indexId, shard.getId())).v1(); + oldRepositoryData.shardGenerations().getShardGen(indexId, finalShardId)).v1(); } else { Tuple tuple = buildBlobStoreIndexShardSnapshots(blobs, shardContainer); newGen = Long.toString(tuple.v2() + 1); blobStoreIndexShardSnapshots = tuple.v1(); } - allShardsListener.onResponse(deleteFromShardSnapshotMeta(survivingSnapshots, indexId, shard, snapshotId, - shardContainer, blobs, blobStoreIndexShardSnapshots, newGen)); + allShardsListener.onResponse(deleteFromShardSnapshotMeta(survivingSnapshots, indexId, finalShardId, + snapshotIds, shardContainer, blobs, blobStoreIndexShardSnapshots, newGen)); } @Override public void onFailure(Exception ex) { logger.warn( () -> new ParameterizedMessage("[{}] failed to delete shard data for shard [{}][{}]", - snapshotId, indexId.getName(), shard.id()), ex); + snapshotIds, indexId.getName(), finalShardId), ex); // Just passing null here to count down the listener instead of failing it, the stale data left behind // here will be retried in the next delete or repository cleanup allShardsListener.onResponse(null); @@ -577,7 +579,8 @@ public void onFailure(Exception ex) { } } - private List resolveFilesToDelete(SnapshotId snapshotId, Collection deleteResults) { + private List resolveFilesToDelete(Collection snapshotIds, + Collection deleteResults) { final String basePath = basePath().buildAsString(); final int basePathLen = basePath.length(); return Stream.concat( @@ -586,8 +589,9 @@ private List resolveFilesToDelete(SnapshotId snapshotId, Collection shardPath + blob); }), - deleteResults.stream().map(shardResult -> shardResult.indexId).distinct().map(indexId -> - indexContainer(indexId).path().buildAsString() + globalMetaDataFormat.blobName(snapshotId.getUUID())) + deleteResults.stream().map(shardResult -> shardResult.indexId).distinct().flatMap(indexId -> + snapshotIds.stream().map(snapshotId -> // TODO: Add filter via RepositoryData + indexContainer(indexId).path().buildAsString() + globalMetaDataFormat.blobName(snapshotId.getUUID()))) ).map(absolutePath -> { assert absolutePath.startsWith(basePath); return absolutePath.substring(basePathLen); @@ -1452,9 +1456,10 @@ public String toString() { * Delete snapshot from shard level metadata. */ private ShardSnapshotMetaDeleteResult deleteFromShardSnapshotMeta(Set survivingSnapshots, IndexId indexId, - ShardId snapshotShardId, SnapshotId snapshotId, + int snapshotShardId, Collection snapshotIds, BlobContainer shardContainer, Set blobs, - BlobStoreIndexShardSnapshots snapshots, String indexGeneration) { + BlobStoreIndexShardSnapshots snapshots, + String indexGeneration) throws IOException { // Build a list of snapshots that should be preserved List newSnapshotsList = new ArrayList<>(); final Set survivingSnapshotNames = survivingSnapshots.stream().map(SnapshotId::getName).collect(Collectors.toSet()); @@ -1465,17 +1470,17 @@ private ShardSnapshotMetaDeleteResult deleteFromShardSnapshotMeta(Set survivingSnapshotUUIDs = survivingSnapshots.stream().map(SnapshotId::getUUID).collect(Collectors.toSet()); - return new ShardSnapshotMetaDeleteResult(indexId, snapshotShardId.id(), indexGeneration, + return new ShardSnapshotMetaDeleteResult(indexId, snapshotShardId, indexGeneration, unusedBlobs(blobs, survivingSnapshotUUIDs, updatedSnapshots)); } } catch (IOException e) { - throw new IndexShardSnapshotFailedException(snapshotShardId, - "Failed to finalize snapshot deletion [" + snapshotId + "] with shard index [" + throw new IOException( + "Failed to finalize snapshot deletion " + snapshotIds + " with shard index [" + indexShardSnapshotsFormat.blobName(indexGeneration) + "]", e); } } @@ -1487,12 +1492,12 @@ private void writeShardIndexBlob(BlobContainer shardContainer, String indexGener indexShardSnapshotsFormat.writeAtomic(updatedSnapshots, shardContainer, indexGeneration); } - private static Set getShardBlobs(final ShardId snapshotShardId, final BlobContainer shardContainer) { + private static Set getShardBlobs(BlobContainer shardContainer) throws IOException { final Set blobs; try { blobs = shardContainer.listBlobs().keySet(); } catch (IOException e) { - throw new IndexShardSnapshotException(snapshotShardId, "Failed to list content of shard directory", e); + throw new IOException("Failed to list content of shard directory", e); } return blobs; } diff --git a/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java b/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java index 12adfb49120a7..82e50ebcece1d 100644 --- a/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.UUIDs; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.common.xcontent.XContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; @@ -66,7 +67,8 @@ public void testIndicesToUpdateAfterRemovingSnapshot() { final Set snapshotIds = repositoryData.getSnapshots(index); return snapshotIds.contains(randomSnapshot) && snapshotIds.size() > 1; }).toArray(IndexId[]::new); - assertThat(repositoryData.indicesToUpdateAfterRemovingSnapshot(randomSnapshot), containsInAnyOrder(indicesToUpdate)); + assertThat(repositoryData.indicesToUpdateAfterRemovingSnapshot( + Collections.singleton(randomSnapshot)), containsInAnyOrder(indicesToUpdate)); } public void testXContent() throws IOException { @@ -148,7 +150,7 @@ public void testRemoveSnapshot() { List snapshotIds = new ArrayList<>(repositoryData.getSnapshotIds()); assertThat(snapshotIds.size(), greaterThan(0)); SnapshotId removedSnapshotId = snapshotIds.remove(randomIntBetween(0, snapshotIds.size() - 1)); - RepositoryData newRepositoryData = repositoryData.removeSnapshot(removedSnapshotId, ShardGenerations.EMPTY); + RepositoryData newRepositoryData = repositoryData.removeSnapshot(Collections.singleton(removedSnapshotId), ShardGenerations.EMPTY); // make sure the repository data's indices no longer contain the removed snapshot for (final IndexId indexId : newRepositoryData.getIndices().values()) { assertFalse(newRepositoryData.getSnapshots(indexId).contains(removedSnapshotId)); diff --git a/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryTests.java b/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryTests.java index 425ccdfe8ccc2..017cf34fca4a0 100644 --- a/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryTests.java @@ -179,7 +179,7 @@ public void testIndexGenerationalFiles() throws Exception { // removing a snapshot and writing to a new index generational file repositoryData = ESBlobStoreRepositoryIntegTestCase.getRepositoryData(repository).removeSnapshot( - repositoryData.getSnapshotIds().iterator().next(), ShardGenerations.EMPTY); + Collections.singleton(repositoryData.getSnapshotIds().iterator().next()), ShardGenerations.EMPTY); writeIndexGen(repository, repositoryData, repositoryData.getGenId()); assertEquals(ESBlobStoreRepositoryIntegTestCase.getRepositoryData(repository), repositoryData); assertThat(repository.latestIndexBlobId(), equalTo(2L)); From 3067bc5585e3e47866b8121605e4afbb7151845d Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 2 Dec 2019 13:25:02 +0100 Subject: [PATCH 02/45] works --- .../repositories/FilterRepository.java | 4 ++- .../repositories/RepositoryData.java | 10 ++++-- .../blobstore/BlobStoreRepository.java | 33 ++++++++++--------- .../snapshots/SnapshotsService.java | 3 +- .../RepositoriesServiceTests.java | 4 ++- .../repositories/RepositoryDataTests.java | 1 - .../index/shard/RestoreOnlyRepository.java | 4 ++- .../xpack/ccr/repository/CcrRepository.java | 4 ++- 8 files changed, 39 insertions(+), 24 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/repositories/FilterRepository.java b/server/src/main/java/org/elasticsearch/repositories/FilterRepository.java index 76645834fb112..821e2496de678 100644 --- a/server/src/main/java/org/elasticsearch/repositories/FilterRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/FilterRepository.java @@ -37,6 +37,7 @@ import org.elasticsearch.snapshots.SnapshotShardFailure; import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -83,7 +84,8 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera } @Override - public void deleteSnapshot(SnapshotId snapshotId, long repositoryStateId, boolean writeShardGens, ActionListener listener) { + public void deleteSnapshot(Collection snapshotId, long repositoryStateId, boolean writeShardGens, + ActionListener listener) { in.deleteSnapshot(snapshotId, repositoryStateId, writeShardGens, listener); } diff --git a/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java b/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java index c97d33b541487..aa99f8867ad8a 100644 --- a/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java +++ b/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java @@ -41,6 +41,7 @@ import java.util.Objects; import java.util.Set; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; /** @@ -146,7 +147,12 @@ public Map getIndices() { public List indicesToUpdateAfterRemovingSnapshot(Collection snapshotIds) { return indexSnapshots.entrySet().stream() .filter(entry -> { - if (entry.getValue().containsAll(snapshotIds)) { + final Collection existingIds = entry.getValue(); + final boolean containsAll = existingIds.containsAll(snapshotIds); + if (containsAll && existingIds.size() > snapshotIds.size()) { + return true; + } + if (snapshotIds.containsAll(existingIds)) { return false; } for (SnapshotId snapshotId : snapshotIds) { @@ -211,7 +217,7 @@ public RepositoryData withGenId(long newGeneration) { * changed shard indexed by its shardId */ public RepositoryData removeSnapshot(final Collection snapshots, final ShardGenerations updatedShardGenerations) { - Map newSnapshotIds = snapshotIds.values().stream().filter(snapshots::contains) + Map newSnapshotIds = snapshotIds.values().stream().filter(Predicate.not(snapshots::contains)) .collect(Collectors.toMap(SnapshotId::getUUID, Function.identity())); if (newSnapshotIds.size() != snapshotIds.size() - snapshots.size()) { final Collection notFound = new HashSet<>(snapshots); 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 716d7cf3589a3..31b00d87cad1c 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -74,7 +74,6 @@ import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.Index; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.snapshots.IndexShardRestoreFailedException; @@ -563,27 +562,15 @@ private void writeUpdatedShardMetaDataAndComputeDeletes(Collection s final Set survivingSnapshots = oldRepositoryData.getSnapshots(indexId).stream() .filter(id -> snapshotIds.contains(id) == false).collect(Collectors.toSet()); executor.execute(ActionRunnable.wrap(deleteIndexMetaDataListener, deleteIdxMetaListener -> { - final IndexMetaData indexMetaData; - try { - indexMetaData = getSnapshotIndexMetaData(snapshotId, indexId); - } catch (Exception ex) { - logger.warn(() -> - new ParameterizedMessage("[{}] [{}] failed to read metadata for index", snapshotId, indexId.getName()), ex); - // Just invoke the listener without any shard generations to count it down, this index will be cleaned up - // by the stale data cleanup in the end. - // TODO: Getting here means repository corruption. We should find a way of dealing with this instead of just ignoring - // it and letting the cleanup deal with it. + final int shardCount = findMaxShardCount(snapshotIds, indexId); + if (shardCount == 0) { deleteIdxMetaListener.onResponse(null); return; } - final int shardCount = indexMetaData.getNumberOfShards(); - assert shardCount > 0 : "index did not have positive shard count, get [" + shardCount + "]"; // Listener for collecting the results of removing the snapshot from each shard's metadata in the current index final ActionListener allShardsListener = new GroupedActionListener<>(deleteIdxMetaListener, shardCount); - final Index index = indexMetaData.getIndex(); - for (int shardId = 0; shardId < indexMetaData.getNumberOfShards(); shardId++) { - final ShardId shard = new ShardId(index, shardId); + for (int shardId = 0; shardId < shardCount; shardId++) { final int finalShardId = shardId; executor.execute(new AbstractRunnable() { @Override @@ -621,6 +608,20 @@ public void onFailure(Exception ex) { } } + private int findMaxShardCount(Collection snapshotIds, IndexId indexId) { + int maxShardCount = 0; + // TODO: parallelize this + for (SnapshotId snapshotId : snapshotIds) { + try { + maxShardCount = Math.max(maxShardCount, getSnapshotIndexMetaData(snapshotId, indexId).getNumberOfShards()); + } catch (Exception e) { + // TODO: Getting here means repository corruption. We should find a way of dealing with this instead of just ignoring + // it and letting the cleanup deal with it. + } + } + return maxShardCount; + } + private List resolveFilesToDelete(Collection snapshotIds, Collection deleteResults) { final String basePath = basePath().buildAsString(); diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index c38462e240747..ea15521cae56b 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -1380,7 +1380,8 @@ private void deleteSnapshotFromRepository(Snapshot snapshot, @Nullable ActionLis Version version) { threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(ActionRunnable.wrap(listener, l -> { Repository repository = repositoriesService.repository(snapshot.getRepository()); - repository.deleteSnapshot(snapshot.getSnapshotId(), repositoryStateId, version.onOrAfter(SHARD_GEN_IN_REPO_DATA_VERSION), + repository.deleteSnapshot(Collections.singleton(snapshot.getSnapshotId()), repositoryStateId, + version.onOrAfter(SHARD_GEN_IN_REPO_DATA_VERSION), ActionListener.wrap(v -> { logger.info("snapshot [{}] deleted", snapshot); removeSnapshotDeletionFromClusterState(snapshot, null, l); diff --git a/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java b/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java index 2daa4afe3e149..1402e5ec19207 100644 --- a/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java @@ -47,6 +47,7 @@ import org.elasticsearch.transport.TransportService; import java.io.IOException; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -163,7 +164,8 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations indices, lo } @Override - public void deleteSnapshot(SnapshotId snapshotId, long repositoryStateId, boolean writeShardGens, ActionListener listener) { + public void deleteSnapshot(Collection snapshotId, long repositoryStateId, boolean writeShardGens, + ActionListener listener) { listener.onResponse(null); } diff --git a/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java b/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java index 82e50ebcece1d..9a63aa610a02b 100644 --- a/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java @@ -22,7 +22,6 @@ import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.UUIDs; import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.common.xcontent.XContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; diff --git a/test/framework/src/main/java/org/elasticsearch/index/shard/RestoreOnlyRepository.java b/test/framework/src/main/java/org/elasticsearch/index/shard/RestoreOnlyRepository.java index f0118d3c0b699..41a5994367ba0 100644 --- a/test/framework/src/main/java/org/elasticsearch/index/shard/RestoreOnlyRepository.java +++ b/test/framework/src/main/java/org/elasticsearch/index/shard/RestoreOnlyRepository.java @@ -38,6 +38,7 @@ import org.elasticsearch.snapshots.SnapshotShardFailure; import java.io.IOException; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -101,7 +102,8 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera } @Override - public void deleteSnapshot(SnapshotId snapshotId, long repositoryStateId, boolean writeShardGens, ActionListener listener) { + public void deleteSnapshot(Collection snapshotId, long repositoryStateId, boolean writeShardGens, + ActionListener listener) { listener.onResponse(null); } diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java index 20c098ee7f82a..f82c050356624 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java @@ -82,6 +82,7 @@ import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; @@ -255,7 +256,8 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera } @Override - public void deleteSnapshot(SnapshotId snapshotId, long repositoryStateId, boolean writeShardGens, ActionListener listener) { + public void deleteSnapshot(Collection snapshotId, long repositoryStateId, boolean writeShardGens, + ActionListener listener) { throw new UnsupportedOperationException("Unsupported for repository of type: " + TYPE); } From ce320745ee5fbf2b16f240e9f3342242d5f4a6e0 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 3 Dec 2019 13:53:36 +0100 Subject: [PATCH 03/45] bck --- .../delete/TransportDeleteSnapshotAction.java | 2 +- .../snapshots/SnapshotsService.java | 33 +++++++++++-------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java index 5c3395012d30d..407108175a30b 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java @@ -71,7 +71,7 @@ protected ClusterBlockException checkBlock(DeleteSnapshotRequest request, Cluste @Override protected void masterOperation(Task task, final DeleteSnapshotRequest request, ClusterState state, final ActionListener listener) { - snapshotsService.deleteSnapshot(request.repository(), request.snapshot(), + snapshotsService.deleteSnapshots(request.repository(), request.snapshot(), ActionListener.map(listener, v -> new AcknowledgedResponse(true)), false); } } diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index ea15521cae56b..6509482c26ca4 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -78,6 +78,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -842,7 +843,7 @@ public ClusterState execute(ClusterState currentState) { entries.add(updatedSnapshot); // Clean up the snapshot that failed to start from the old master - deleteSnapshot(snapshot.snapshot(), new ActionListener<>() { + deleteSnapshots(snapshot.snapshot(), new ActionListener<>() { @Override public void onResponse(Void aVoid) { logger.debug("cleaned up abandoned snapshot {} in INIT state", snapshot.snapshot()); @@ -1146,7 +1147,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS * @param snapshotName snapshotName * @param listener listener */ - public void deleteSnapshot(final String repositoryName, final String snapshotName, final ActionListener listener, + public void deleteSnapshots(final String repositoryName, final String snapshotName, final ActionListener listener, final boolean immediatePriority) { // First, look for the snapshot in the repository final Repository repository = repositoriesService.repository(repositoryName); @@ -1169,7 +1170,7 @@ public void deleteSnapshot(final String repositoryName, final String snapshotNam if (matchedEntry.isPresent() == false) { throw new SnapshotMissingException(repositoryName, snapshotName); } - deleteSnapshot(new Snapshot(repositoryName, matchedEntry.get()), listener, repoGenId, immediatePriority); + deleteSnapshots(new Snapshot(repositoryName, matchedEntry.get()), listener, repoGenId, immediatePriority); }, listener::onFailure)); } @@ -1178,13 +1179,13 @@ public void deleteSnapshot(final String repositoryName, final String snapshotNam *

* If the snapshot is still running cancels the snapshot first and then deletes it from the repository. * - * @param snapshot snapshot + * @param snapshots snapshots * @param listener listener * @param repositoryStateId the unique id for the state of the repository */ - private void deleteSnapshot(final Snapshot snapshot, final ActionListener listener, final long repositoryStateId, - final boolean immediatePriority) { - logger.info("deleting snapshot [{}]", snapshot); + private void deleteSnapshots(Collection snapshots, ActionListener listener, String repository, + long repositoryStateId, boolean immediatePriority) { + logger.info("deleting snapshots {} from [{}]", snapshots, repository); Priority priority = immediatePriority ? Priority.IMMEDIATE : Priority.NORMAL; clusterService.submitStateUpdateTask("delete snapshot", new ClusterStateUpdateTask(priority) { @@ -1192,14 +1193,15 @@ private void deleteSnapshot(final Snapshot snapshot, final ActionListener @Override public ClusterState execute(ClusterState currentState) { + final String snapshotExName = "multiple"; SnapshotDeletionsInProgress deletionsInProgress = currentState.custom(SnapshotDeletionsInProgress.TYPE); if (deletionsInProgress != null && deletionsInProgress.hasDeletionsInProgress()) { - throw new ConcurrentSnapshotExecutionException(snapshot, + throw new ConcurrentSnapshotExecutionException(repository, snapshotExName, "cannot delete - another snapshot is currently being deleted in [" + deletionsInProgress + "]"); } final RepositoryCleanupInProgress repositoryCleanupInProgress = currentState.custom(RepositoryCleanupInProgress.TYPE); if (repositoryCleanupInProgress != null && repositoryCleanupInProgress.hasCleanupInProgress()) { - throw new ConcurrentSnapshotExecutionException(snapshot.getRepository(), snapshot.getSnapshotId().getName(), + throw new ConcurrentSnapshotExecutionException(repository, snapshotExName, "cannot delete snapshot while a repository cleanup is in-progress in [" + repositoryCleanupInProgress + "]"); } RestoreInProgress restoreInProgress = currentState.custom(RestoreInProgress.TYPE); @@ -1208,13 +1210,18 @@ public ClusterState execute(ClusterState currentState) { // otherwise we could end up deleting a snapshot that is being restored // and the files the restore depends on would all be gone if (restoreInProgress.isEmpty() == false) { - throw new ConcurrentSnapshotExecutionException(snapshot, + throw new ConcurrentSnapshotExecutionException(repository, snapshotExName, "cannot delete snapshot during a restore in progress in [" + restoreInProgress + "]"); } } ClusterState.Builder clusterStateBuilder = ClusterState.builder(currentState); SnapshotsInProgress snapshots = currentState.custom(SnapshotsInProgress.TYPE); - SnapshotsInProgress.Entry snapshotEntry = snapshots != null ? snapshots.snapshot(snapshot) : null; + final SnapshotsInProgress.Entry snapshotEntry; + if (snapshots != null) { + snapshotEntry = snapshots.snapshot(snapshot); + } else { + snapshotEntry = null; + } if (snapshotEntry == null) { // This snapshot is not running - delete if (snapshots != null && !snapshots.entries().isEmpty()) { @@ -1302,7 +1309,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS logger.debug("deleted snapshot completed - deleting files"); threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(() -> { try { - deleteSnapshot(snapshot.getRepository(), snapshot.getSnapshotId().getName(), listener, true); + deleteSnapshots(snapshot.getRepository(), snapshot.getSnapshotId().getName(), listener, true); } catch (Exception ex) { logger.warn(() -> new ParameterizedMessage("[{}] failed to delete snapshot", snapshot), ex); } @@ -1313,7 +1320,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS logger.warn("deleted snapshot failed - deleting files", e); threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(() -> { try { - deleteSnapshot(snapshot.getRepository(), snapshot.getSnapshotId().getName(), listener, true); + deleteSnapshots(snapshot.getRepository(), snapshot.getSnapshotId().getName(), listener, true); } catch (SnapshotMissingException smex) { logger.info(() -> new ParameterizedMessage( "Tried deleting in-progress snapshot [{}], but it could not be found after failing to abort.", From 7ff185109d46d6937502e23ca2bb95f32858f384 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 3 Dec 2019 15:29:05 +0100 Subject: [PATCH 04/45] bck --- .../delete/TransportDeleteSnapshotAction.java | 2 +- .../ConcurrentSnapshotExecutionException.java | 5 + .../snapshots/SnapshotsService.java | 126 ++++++++++-------- 3 files changed, 75 insertions(+), 58 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java index 407108175a30b..f5a7d46a01acf 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java @@ -71,7 +71,7 @@ protected ClusterBlockException checkBlock(DeleteSnapshotRequest request, Cluste @Override protected void masterOperation(Task task, final DeleteSnapshotRequest request, ClusterState state, final ActionListener listener) { - snapshotsService.deleteSnapshots(request.repository(), request.snapshot(), + snapshotsService.deleteSnapshots(request.repository(), new String[]{request.snapshot()}, ActionListener.map(listener, v -> new AcknowledgedResponse(true)), false); } } diff --git a/server/src/main/java/org/elasticsearch/snapshots/ConcurrentSnapshotExecutionException.java b/server/src/main/java/org/elasticsearch/snapshots/ConcurrentSnapshotExecutionException.java index 91a40fea09ffb..b90a0319646d1 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/ConcurrentSnapshotExecutionException.java +++ b/server/src/main/java/org/elasticsearch/snapshots/ConcurrentSnapshotExecutionException.java @@ -23,12 +23,17 @@ import org.elasticsearch.rest.RestStatus; import java.io.IOException; +import java.util.Collection; /** * Thrown when a user tries to multiple conflicting snapshot/restore operations at the same time. */ public class ConcurrentSnapshotExecutionException extends SnapshotException { + public ConcurrentSnapshotExecutionException(String repositoryName, Collection snapshots, String msg) { + super(repositoryName, snapshots.size() == 1 ? snapshots.iterator().next().getName() : snapshots.toString(), msg); + } + public ConcurrentSnapshotExecutionException(final String repositoryName, final String snapshotName, final String msg) { super(repositoryName, snapshotName, msg); } diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index 6509482c26ca4..e01c04ed9b0d1 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -783,8 +783,8 @@ private void finalizeSnapshotDeletionFromPreviousMaster(ClusterState state) { if (deletionsInProgress != null && deletionsInProgress.hasDeletionsInProgress()) { assert deletionsInProgress.getEntries().size() == 1 : "only one in-progress deletion allowed per cluster"; SnapshotDeletionsInProgress.Entry entry = deletionsInProgress.getEntries().get(0); - deleteSnapshotFromRepository(entry.getSnapshot(), null, entry.repositoryStateId(), - state.nodes().getMinNodeVersion()); + deleteSnapshotsFromRepository(Collections.singletonList(entry.getSnapshot().getSnapshotId()), null, entry.repositoryStateId(), + entry.repository(), state.nodes().getMinNodeVersion()); } } @@ -843,7 +843,7 @@ public ClusterState execute(ClusterState currentState) { entries.add(updatedSnapshot); // Clean up the snapshot that failed to start from the old master - deleteSnapshots(snapshot.snapshot(), new ActionListener<>() { + deleteSnapshots(Collections.singletonList(snapshot.snapshot().getSnapshotId()), new ActionListener<>() { @Override public void onResponse(Void aVoid) { logger.debug("cleaned up abandoned snapshot {} in INIT state", snapshot.snapshot()); @@ -853,7 +853,7 @@ public void onResponse(Void aVoid) { public void onFailure(Exception e) { logger.warn("failed to clean up abandoned snapshot {} in INIT state", snapshot.snapshot()); } - }, updatedSnapshot.repositoryStateId(), false); + }, snapshot.repository(), updatedSnapshot.repositoryStateId(), false); } assert updatedSnapshot.shards().size() == snapshot.shards().size() : "Shard count changed during snapshot status update from [" + snapshot + "] to [" + updatedSnapshot + "]"; @@ -1144,33 +1144,34 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS * If the snapshot is still running cancels the snapshot first and then deletes it from the repository. * * @param repositoryName repositoryName - * @param snapshotName snapshotName + * @param snapshotNames snapshot names * @param listener listener */ - public void deleteSnapshots(final String repositoryName, final String snapshotName, final ActionListener listener, - final boolean immediatePriority) { + public void deleteSnapshots(final String repositoryName, final String[] snapshotNames, final ActionListener listener, + final boolean immediatePriority) { // First, look for the snapshot in the repository final Repository repository = repositoriesService.repository(repositoryName); + final Set snNames = Set.of(snapshotNames); repository.getRepositoryData(ActionListener.wrap(repositoryData -> { - Optional matchedEntry = repositoryData.getSnapshotIds() + Collection matchedEntry = new ArrayList<>(repositoryData.getSnapshotIds() .stream() - .filter(s -> s.getName().equals(snapshotName)) - .findFirst(); + .filter(s -> snNames.contains(s.getName())) + .collect(Collectors.toList())); // if nothing found by the same name, then look in the cluster state for current in progress snapshots long repoGenId = repositoryData.getGenId(); - if (matchedEntry.isPresent() == false) { + Optional matchedInProgress = currentSnapshots(repositoryName, Collections.emptyList()).stream() - .filter(s -> s.snapshot().getSnapshotId().getName().equals(snapshotName)).findFirst(); + .filter(s -> snNames.contains(s.snapshot().getSnapshotId().getName())).findAny(); if (matchedInProgress.isPresent()) { - matchedEntry = matchedInProgress.map(s -> s.snapshot().getSnapshotId()); + matchedEntry.add(matchedInProgress.map(s -> s.snapshot().getSnapshotId()).get()); // Derive repository generation if a snapshot is in progress because it will increment the generation when it finishes repoGenId = matchedInProgress.get().repositoryStateId() + 1L; } + + if (matchedEntry.isEmpty()) { + throw new SnapshotMissingException(repositoryName, snNames.toString()); } - if (matchedEntry.isPresent() == false) { - throw new SnapshotMissingException(repositoryName, snapshotName); - } - deleteSnapshots(new Snapshot(repositoryName, matchedEntry.get()), listener, repoGenId, immediatePriority); + deleteSnapshots(matchedEntry, listener, repositoryName, repoGenId, immediatePriority); }, listener::onFailure)); } @@ -1189,19 +1190,18 @@ private void deleteSnapshots(Collection snapshots, ActionListener snapshotsInProgress.snapshot(new Snapshot(repository, sn)) != null) + .findFirst().map(sn -> snapshotsInProgress.snapshot(new Snapshot(repository, sn))) + .orElse(null); } else { snapshotEntry = null; } if (snapshotEntry == null) { // This snapshot is not running - delete - if (snapshots != null && !snapshots.entries().isEmpty()) { + if (snapshotsInProgress != null && !snapshotsInProgress.entries().isEmpty()) { // However other snapshots are running - cannot continue - throw new ConcurrentSnapshotExecutionException(snapshot, "another snapshot is currently running cannot delete"); + throw new ConcurrentSnapshotExecutionException(repository, snapshots, + "another snapshot is currently running cannot delete"); } - // add the snapshot deletion to the cluster state - SnapshotDeletionsInProgress.Entry entry = new SnapshotDeletionsInProgress.Entry( - snapshot, - threadPool.absoluteTimeInMillis(), - repositoryStateId - ); - if (deletionsInProgress != null) { - deletionsInProgress = deletionsInProgress.withAddedEntry(entry); - } else { - deletionsInProgress = SnapshotDeletionsInProgress.newInstance(entry); + for (SnapshotId snapshot : snapshots) { + // add the snapshot deletion to the cluster state + SnapshotDeletionsInProgress.Entry entry = new SnapshotDeletionsInProgress.Entry( + new Snapshot(repository, snapshot), + threadPool.absoluteTimeInMillis(), + repositoryStateId + ); + if (deletionsInProgress != null) { + deletionsInProgress = deletionsInProgress.withAddedEntry(entry); + } else { + deletionsInProgress = SnapshotDeletionsInProgress.newInstance(entry); + } } clusterStateBuilder.putCustom(SnapshotDeletionsInProgress.TYPE, deletionsInProgress); } else { // This snapshot is currently running - stopping shards first - waitForSnapshot = true; + waitForSnapshot = snapshotEntry.snapshot(); final ImmutableOpenMap shards; @@ -1302,16 +1310,17 @@ public void onFailure(String source, Exception e) { @Override public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - if (waitForSnapshot) { + if (waitForSnapshot != null) { logger.trace("adding snapshot completion listener to wait for deleted snapshot to finish"); - addListener(snapshot, ActionListener.wrap( + addListener(waitForSnapshot, ActionListener.wrap( snapshotInfo -> { logger.debug("deleted snapshot completed - deleting files"); threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(() -> { try { - deleteSnapshots(snapshot.getRepository(), snapshot.getSnapshotId().getName(), listener, true); + deleteSnapshots(waitForSnapshot.getRepository(), + snapshots.stream().map(SnapshotId::getName).toArray(String[]::new), listener, true); } catch (Exception ex) { - logger.warn(() -> new ParameterizedMessage("[{}] failed to delete snapshot", snapshot), ex); + logger.warn(() -> new ParameterizedMessage("[{}] failed to delete snapshot", waitForSnapshot), ex); } } ); @@ -1320,12 +1329,14 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS logger.warn("deleted snapshot failed - deleting files", e); threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(() -> { try { - deleteSnapshots(snapshot.getRepository(), snapshot.getSnapshotId().getName(), listener, true); + deleteSnapshots( + waitForSnapshot.getRepository(), + snapshots.stream().map(SnapshotId::getName).toArray(String[]::new), listener, true); } catch (SnapshotMissingException smex) { logger.info(() -> new ParameterizedMessage( "Tried deleting in-progress snapshot [{}], but it could not be found after failing to abort.", smex.getSnapshotName()), e); - listener.onFailure(new SnapshotException(snapshot, + listener.onFailure(new SnapshotException(waitForSnapshot, "Tried deleting in-progress snapshot [" + smex.getSnapshotName() + "], but it " + "could not be found after failing to abort.", smex)); } @@ -1334,7 +1345,8 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS )); } else { logger.debug("deleted snapshot is not running - deleting files"); - deleteSnapshotFromRepository(snapshot, listener, repositoryStateId, newState.nodes().getMinNodeVersion()); + deleteSnapshotsFromRepository( + snapshots, listener, repositoryStateId, repository, newState.nodes().getMinNodeVersion()); } } }); @@ -1378,21 +1390,21 @@ public static boolean isRepositoryInUse(ClusterState clusterState, String reposi /** * Deletes snapshot from repository * - * @param snapshot snapshot - * @param listener listener + * @param snapshots snapshot + * @param listener listener * @param repositoryStateId the unique id representing the state of the repository at the time the deletion began * @param version minimum ES version the repository should be readable by */ - private void deleteSnapshotFromRepository(Snapshot snapshot, @Nullable ActionListener listener, long repositoryStateId, - Version version) { + private void deleteSnapshotsFromRepository(Collection snapshots, @Nullable ActionListener listener, + long repositoryStateId, String repositoryName, Version version) { threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(ActionRunnable.wrap(listener, l -> { - Repository repository = repositoriesService.repository(snapshot.getRepository()); - repository.deleteSnapshot(Collections.singleton(snapshot.getSnapshotId()), repositoryStateId, + Repository repository = repositoriesService.repository(repositoryName); + repository.deleteSnapshot(snapshots, repositoryStateId, version.onOrAfter(SHARD_GEN_IN_REPO_DATA_VERSION), ActionListener.wrap(v -> { - logger.info("snapshot [{}] deleted", snapshot); - removeSnapshotDeletionFromClusterState(snapshot, null, l); - }, ex -> removeSnapshotDeletionFromClusterState(snapshot, ex, l) + logger.info("snapshots {} deleted", snapshots); + removeSnapshotDeletionFromClusterState(snapshots, null, l); + }, ex -> removeSnapshotDeletionFromClusterState(snapshots, ex, l) )); })); } @@ -1400,8 +1412,8 @@ private void deleteSnapshotFromRepository(Snapshot snapshot, @Nullable ActionLis /** * Removes the snapshot deletion from {@link SnapshotDeletionsInProgress} in the cluster state. */ - private void removeSnapshotDeletionFromClusterState(final Snapshot snapshot, @Nullable final Exception failure, - @Nullable final ActionListener listener) { + private void removeSnapshotDeletionFromClusterState(Collection snapshots, @Nullable Exception failure, + @Nullable ActionListener listener) { clusterService.submitStateUpdateTask("remove snapshot deletion metadata", new ClusterStateUpdateTask() { @Override public ClusterState execute(ClusterState currentState) { @@ -1423,7 +1435,7 @@ public ClusterState execute(ClusterState currentState) { @Override public void onFailure(String source, Exception e) { - logger.warn(() -> new ParameterizedMessage("[{}] failed to remove snapshot deletion metadata", snapshot), e); + logger.warn(() -> new ParameterizedMessage("{} failed to remove snapshot deletion metadata", snapshots), e); if (listener != null) { listener.onFailure(e); } From e7428e5f4ba630a9ec9df72f329f87184f958c20 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 3 Dec 2019 15:43:13 +0100 Subject: [PATCH 05/45] bck --- .../elasticsearch/client/SnapshotClient.java | 14 ++--- .../client/SnapshotRequestConverters.java | 10 ++-- .../org/elasticsearch/client/SnapshotIT.java | 6 +- .../SnapshotRequestConvertersTests.java | 12 ++-- .../SnapshotClientDocumentationIT.java | 7 +-- .../delete/DeleteSnapshotRequestBuilder.java | 12 ++-- ...quest.java => DeleteSnapshotsRequest.java} | 55 ++++++++++++++----- .../delete/TransportDeleteSnapshotAction.java | 10 ++-- .../client/ClusterAdminClient.java | 6 +- .../org/elasticsearch/client/Requests.java | 6 +- .../client/support/AbstractClient.java | 6 +- .../cluster/RestDeleteSnapshotAction.java | 8 +-- .../snapshots/SnapshotResiliencyTests.java | 8 +-- .../AbstractThirdPartyRepositoryTestCase.java | 4 +- 14 files changed, 94 insertions(+), 70 deletions(-) rename server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/{DeleteSnapshotRequest.java => DeleteSnapshotsRequest.java} (64%) 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 134dc921c450d..e4221bb2737f2 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 @@ -30,7 +30,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.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; @@ -335,13 +335,13 @@ public Cancellable restoreAsync(RestoreSnapshotRequest restoreSnapshotRequest, R * See Snapshot and Restore * API on elastic.co * - * @param deleteSnapshotRequest the request + * @param deleteSnapshotsRequest the request * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized * @return the response * @throws IOException in case there is a problem sending the request or parsing back the response */ - public AcknowledgedResponse delete(DeleteSnapshotRequest deleteSnapshotRequest, RequestOptions options) throws IOException { - return restHighLevelClient.performRequestAndParseEntity(deleteSnapshotRequest, + public AcknowledgedResponse delete(DeleteSnapshotsRequest deleteSnapshotsRequest, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(deleteSnapshotsRequest, SnapshotRequestConverters::deleteSnapshot, options, AcknowledgedResponse::fromXContent, emptySet()); } @@ -351,14 +351,14 @@ public AcknowledgedResponse delete(DeleteSnapshotRequest deleteSnapshotRequest, * See Snapshot and Restore * API on elastic.co * - * @param deleteSnapshotRequest the request + * @param deleteSnapshotsRequest the request * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized * @param listener the listener to be notified upon request completion * @return cancellable that may be used to cancel the request */ - public Cancellable deleteAsync(DeleteSnapshotRequest deleteSnapshotRequest, RequestOptions options, + public Cancellable deleteAsync(DeleteSnapshotsRequest deleteSnapshotsRequest, RequestOptions options, ActionListener listener) { - return restHighLevelClient.performRequestAsyncAndParseEntity(deleteSnapshotRequest, + return restHighLevelClient.performRequestAsyncAndParseEntity(deleteSnapshotsRequest, SnapshotRequestConverters::deleteSnapshot, options, AcknowledgedResponse::fromXContent, listener, emptySet()); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java index 703aa0d672555..e5ffe037eba96 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java @@ -29,7 +29,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.snapshots.create.CreateSnapshotRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; @@ -173,15 +173,15 @@ static Request restoreSnapshot(RestoreSnapshotRequest restoreSnapshotRequest) th return request; } - static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) { + static Request deleteSnapshot(DeleteSnapshotsRequest deleteSnapshotsRequest) { String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_snapshot") - .addPathPart(deleteSnapshotRequest.repository()) - .addPathPart(deleteSnapshotRequest.snapshot()) + .addPathPart(deleteSnapshotsRequest.repository()) + .addCommaSeparatedPathParts(deleteSnapshotsRequest.snapshots()) .build(); Request request = new Request(HttpDelete.METHOD_NAME, endpoint); RequestConverters.Params parameters = new RequestConverters.Params(); - parameters.withMasterTimeout(deleteSnapshotRequest.masterNodeTimeout()); + parameters.withMasterTimeout(deleteSnapshotsRequest.masterNodeTimeout()); request.addParameters(parameters.asMap()); return request; } 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 f9679cf5eb61c..200cfad9a46a2 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,7 +30,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.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; @@ -165,7 +165,7 @@ public void testCreateSnapshot() throws IOException { if (waitForCompletion == false) { // If we don't wait for the snapshot to complete we have to cancel it to not leak the snapshot task AcknowledgedResponse deleteResponse = execute( - new DeleteSnapshotRequest(repository, snapshot), + new DeleteSnapshotsRequest(repository, snapshot), highLevelClient().snapshot()::delete, highLevelClient().snapshot()::deleteAsync ); assertTrue(deleteResponse.isAcknowledged()); @@ -301,7 +301,7 @@ public void testDeleteSnapshot() throws IOException { // check that the request went ok without parsing JSON here. When using the high level client, check acknowledgement instead. assertEquals(RestStatus.OK, createSnapshotResponse.status()); - DeleteSnapshotRequest request = new DeleteSnapshotRequest(repository, snapshot); + DeleteSnapshotsRequest request = new DeleteSnapshotsRequest(repository, snapshot); AcknowledgedResponse response = execute(request, highLevelClient().snapshot()::delete, highLevelClient().snapshot()::deleteAsync); assertTrue(response.isAcknowledged()); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java index 23789d390357b..6bb5bfec903b5 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java @@ -28,7 +28,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.snapshots.create.CreateSnapshotRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; @@ -267,12 +267,12 @@ public void testDeleteSnapshot() { String endpoint = String.format(Locale.ROOT, "/_snapshot/%s/%s", repository, snapshot); - DeleteSnapshotRequest deleteSnapshotRequest = new DeleteSnapshotRequest(); - deleteSnapshotRequest.repository(repository); - deleteSnapshotRequest.snapshot(snapshot); - RequestConvertersTests.setRandomMasterTimeout(deleteSnapshotRequest, expectedParams); + DeleteSnapshotsRequest deleteSnapshotsRequest = new DeleteSnapshotsRequest(); + deleteSnapshotsRequest.repository(repository); + deleteSnapshotsRequest.snapshots(new String[]{snapshot}); + RequestConvertersTests.setRandomMasterTimeout(deleteSnapshotsRequest, expectedParams); - Request request = SnapshotRequestConverters.deleteSnapshot(deleteSnapshotRequest); + Request request = SnapshotRequestConverters.deleteSnapshot(deleteSnapshotsRequest); assertThat(request.getEndpoint(), equalTo(endpoint)); assertThat(request.getMethod(), equalTo(HttpDelete.METHOD_NAME)); assertThat(request.getParameters(), equalTo(expectedParams)); 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 1bc3e3f040af6..97f1caba62bcf 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,7 +29,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.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; @@ -752,8 +752,7 @@ public void testSnapshotDeleteSnapshot() throws IOException { createTestSnapshots(); // tag::delete-snapshot-request - DeleteSnapshotRequest request = new DeleteSnapshotRequest(repositoryName); - request.snapshot(snapshotName); + DeleteSnapshotsRequest request = new DeleteSnapshotsRequest(repositoryName, snapshotName); // end::delete-snapshot-request // tag::delete-snapshot-request-masterTimeout @@ -774,7 +773,7 @@ public void testSnapshotDeleteSnapshot() throws IOException { public void testSnapshotDeleteSnapshotAsync() throws InterruptedException { RestHighLevelClient client = highLevelClient(); { - DeleteSnapshotRequest request = new DeleteSnapshotRequest(); + DeleteSnapshotsRequest request = new DeleteSnapshotsRequest(); // tag::delete-snapshot-execute-listener ActionListener listener = diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java index 1e47160903c85..921e8a2614f89 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java @@ -26,21 +26,21 @@ /** * Delete snapshot request builder */ -public class DeleteSnapshotRequestBuilder extends MasterNodeOperationRequestBuilder { /** * Constructs delete snapshot request builder */ public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAction action) { - super(client, action, new DeleteSnapshotRequest()); + super(client, action, new DeleteSnapshotsRequest()); } /** * Constructs delete snapshot request builder with specified repository and snapshot names */ public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAction action, String repository, String snapshot) { - super(client, action, new DeleteSnapshotRequest(repository, snapshot)); + super(client, action, new DeleteSnapshotsRequest(repository, new String[] {snapshot})); } /** @@ -57,11 +57,11 @@ public DeleteSnapshotRequestBuilder setRepository(String repository) { /** * Sets the snapshot name * - * @param snapshot snapshot name + * @param snapshots snapshot names * @return this builder */ - public DeleteSnapshotRequestBuilder setSnapshot(String snapshot) { - request.snapshot(snapshot); + public DeleteSnapshotRequestBuilder setSnapshots(String... snapshots) { + request.snapshots(snapshots); return this; } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java similarity index 64% rename from server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java rename to server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java index 93581c937c50e..9e79ed3807f0c 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.snapshots.delete; +import org.elasticsearch.Version; import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.support.master.MasterNodeRequest; import org.elasticsearch.common.io.stream.StreamInput; @@ -35,16 +36,18 @@ * files that are associated with this particular snapshot. All files that are shared with * at least one other existing snapshot are left intact. */ -public class DeleteSnapshotRequest extends MasterNodeRequest { +public class DeleteSnapshotsRequest extends MasterNodeRequest { + + public static final Version MULTI_DELETE_VERSION = Version.V_8_0_0; private String repository; - private String snapshot; + private String[] snapshots; /** * Constructs a new delete snapshots request */ - public DeleteSnapshotRequest() { + public DeleteSnapshotsRequest() { } /** @@ -53,9 +56,19 @@ public DeleteSnapshotRequest() { * @param repository repository name * @param snapshot snapshot name */ - public DeleteSnapshotRequest(String repository, String snapshot) { + public DeleteSnapshotsRequest(String repository, String snapshot) { + this(repository, new String[]{snapshot}); + } + + /** + * Constructs a new delete snapshots request with repository and snapshot name + * + * @param repository repository name + * @param snapshots snapshot names + */ + public DeleteSnapshotsRequest(String repository, String[] snapshots) { this.repository = repository; - this.snapshot = snapshot; + this.snapshots = snapshots; } /** @@ -63,21 +76,33 @@ public DeleteSnapshotRequest(String repository, String snapshot) { * * @param repository repository name */ - public DeleteSnapshotRequest(String repository) { + public DeleteSnapshotsRequest(String repository) { this.repository = repository; } - public DeleteSnapshotRequest(StreamInput in) throws IOException { + public DeleteSnapshotsRequest(StreamInput in) throws IOException { super(in); repository = in.readString(); - snapshot = in.readString(); + if (in.getVersion().onOrAfter(MULTI_DELETE_VERSION)) { + snapshots = in.readStringArray(); + } else { + snapshots = new String[] {in.readString()}; + } } @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); out.writeString(repository); - out.writeString(snapshot); + if (out.getVersion().onOrAfter(MULTI_DELETE_VERSION)) { + out.writeStringArray(snapshots); + } else { + if (snapshots.length != 1) { + throw new IllegalArgumentException( + "Can't write snapshot delete with more than one snapshot to version [" + out.getVersion() + "]"); + } + out.writeString(snapshots[0]); + } } @Override @@ -86,14 +111,14 @@ public ActionRequestValidationException validate() { if (repository == null) { validationException = addValidationError("repository is missing", validationException); } - if (snapshot == null) { + if (snapshots == null || snapshots.length == 0) { validationException = addValidationError("snapshot is missing", validationException); } return validationException; } - public DeleteSnapshotRequest repository(String repository) { + public DeleteSnapshotsRequest repository(String repository) { this.repository = repository; return this; } @@ -112,8 +137,8 @@ public String repository() { * * @return repository name */ - public String snapshot() { - return this.snapshot; + public String[] snapshots() { + return this.snapshots; } /** @@ -121,8 +146,8 @@ public String snapshot() { * * @return this request */ - public DeleteSnapshotRequest snapshot(String snapshot) { - this.snapshot = snapshot; + public DeleteSnapshotsRequest snapshots(String[] snapshots) { + this.snapshots = snapshots; return this; } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java index f5a7d46a01acf..8b0746312fa49 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java @@ -40,7 +40,7 @@ /** * Transport action for delete snapshot operation */ -public class TransportDeleteSnapshotAction extends TransportMasterNodeAction { +public class TransportDeleteSnapshotAction extends TransportMasterNodeAction { private final SnapshotsService snapshotsService; @Inject @@ -48,7 +48,7 @@ public TransportDeleteSnapshotAction(TransportService transportService, ClusterS ThreadPool threadPool, SnapshotsService snapshotsService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { super(DeleteSnapshotAction.NAME, transportService, clusterService, threadPool, actionFilters, - DeleteSnapshotRequest::new,indexNameExpressionResolver); + DeleteSnapshotsRequest::new,indexNameExpressionResolver); this.snapshotsService = snapshotsService; } @@ -63,15 +63,15 @@ protected AcknowledgedResponse read(StreamInput in) throws IOException { } @Override - protected ClusterBlockException checkBlock(DeleteSnapshotRequest request, ClusterState state) { + protected ClusterBlockException checkBlock(DeleteSnapshotsRequest request, ClusterState state) { // Cluster is not affected but we look up repositories in metadata return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ); } @Override - protected void masterOperation(Task task, final DeleteSnapshotRequest request, ClusterState state, + protected void masterOperation(Task task, final DeleteSnapshotsRequest request, ClusterState state, final ActionListener listener) { - snapshotsService.deleteSnapshots(request.repository(), new String[]{request.snapshot()}, + snapshotsService.deleteSnapshots(request.repository(), request.snapshots(), ActionListener.map(listener, v -> new AcknowledgedResponse(true)), false); } } diff --git a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index fdee39fdb1f93..bd058b0a1d33f 100644 --- a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -74,7 +74,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequestBuilder; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequestBuilder; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequestBuilder; @@ -519,12 +519,12 @@ public interface ClusterAdminClient extends ElasticsearchClient { /** * Delete snapshot. */ - ActionFuture deleteSnapshot(DeleteSnapshotRequest request); + ActionFuture deleteSnapshot(DeleteSnapshotsRequest request); /** * Delete snapshot. */ - void deleteSnapshot(DeleteSnapshotRequest request, ActionListener listener); + void deleteSnapshot(DeleteSnapshotsRequest request, ActionListener listener); /** * Delete snapshot. diff --git a/server/src/main/java/org/elasticsearch/client/Requests.java b/server/src/main/java/org/elasticsearch/client/Requests.java index 01d04c64ae1b1..dbfd71ae1c4e0 100644 --- a/server/src/main/java/org/elasticsearch/client/Requests.java +++ b/server/src/main/java/org/elasticsearch/client/Requests.java @@ -35,7 +35,7 @@ import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; import org.elasticsearch.action.admin.cluster.shards.ClusterSearchShardsRequest; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; @@ -520,8 +520,8 @@ public static RestoreSnapshotRequest restoreSnapshotRequest(String repository, S * @param repository repository name * @return delete snapshot request */ - public static DeleteSnapshotRequest deleteSnapshotRequest(String repository, String snapshot) { - return new DeleteSnapshotRequest(repository, snapshot); + public static DeleteSnapshotsRequest deleteSnapshotRequest(String repository, String snapshot) { + return new DeleteSnapshotsRequest(repository, new String[]{snapshot}); } /** diff --git a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java index 5bb480d8c23c3..189ac47b8d8d1 100644 --- a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java +++ b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java @@ -99,7 +99,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequestBuilder; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotAction; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequestBuilder; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsAction; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; @@ -943,12 +943,12 @@ public GetSnapshotsRequestBuilder prepareGetSnapshots(String... repositories) { @Override - public ActionFuture deleteSnapshot(DeleteSnapshotRequest request) { + public ActionFuture deleteSnapshot(DeleteSnapshotsRequest request) { return execute(DeleteSnapshotAction.INSTANCE, request); } @Override - public void deleteSnapshot(DeleteSnapshotRequest request, ActionListener listener) { + public void deleteSnapshot(DeleteSnapshotsRequest request, ActionListener listener) { execute(DeleteSnapshotAction.INSTANCE, request, listener); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java index 81a3ddd31c59a..c649f6508d96b 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java @@ -19,7 +19,7 @@ package org.elasticsearch.rest.action.admin.cluster; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestController; @@ -47,8 +47,8 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { - DeleteSnapshotRequest deleteSnapshotRequest = deleteSnapshotRequest(request.param("repository"), request.param("snapshot")); - deleteSnapshotRequest.masterNodeTimeout(request.paramAsTime("master_timeout", deleteSnapshotRequest.masterNodeTimeout())); - return channel -> client.admin().cluster().deleteSnapshot(deleteSnapshotRequest, new RestToXContentListener<>(channel)); + DeleteSnapshotsRequest deleteSnapshotsRequest = deleteSnapshotRequest(request.param("repository"), request.param("snapshot")); + deleteSnapshotsRequest.masterNodeTimeout(request.paramAsTime("master_timeout", deleteSnapshotsRequest.masterNodeTimeout())); + return channel -> client.admin().cluster().deleteSnapshot(deleteSnapshotsRequest, new RestToXContentListener<>(channel)); } } diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index 28d2beb2efcc4..75bbc1cb06119 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -40,7 +40,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.create.TransportCreateSnapshotAction; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotAction; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.delete.TransportDeleteSnapshotAction; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotAction; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; @@ -409,7 +409,7 @@ public void testConcurrentSnapshotCreateAndDelete() { final StepListener deleteSnapshotStepListener = new StepListener<>(); continueOrDie(createSnapshotResponseStepListener, createSnapshotResponse -> client().admin().cluster().deleteSnapshot( - new DeleteSnapshotRequest(repoName, snapshotName), deleteSnapshotStepListener)); + new DeleteSnapshotsRequest(repoName, snapshotName), deleteSnapshotStepListener)); final StepListener createAnotherSnapshotResponseStepListener = new StepListener<>(); @@ -461,7 +461,7 @@ public void testConcurrentSnapshotCreateAndDeleteOther() { continueOrDie(createOtherSnapshotResponseStepListener, createSnapshotResponse -> client().admin().cluster().deleteSnapshot( - new DeleteSnapshotRequest(repoName, snapshotName), ActionListener.wrap( + new DeleteSnapshotsRequest(repoName, snapshotName), ActionListener.wrap( resp -> deleteSnapshotStepListener.onResponse(true), e -> { final Throwable unwrapped = @@ -547,7 +547,7 @@ public void run() { .execute(ActionListener.wrap(() -> { createdSnapshot.set(true); testClusterNodes.randomDataNodeSafe().client.admin().cluster().deleteSnapshot( - new DeleteSnapshotRequest(repoName, snapshotName), noopListener()); + new DeleteSnapshotsRequest(repoName, snapshotName), noopListener()); })); scheduleNow( () -> testClusterNodes.randomMasterNodeSafe().client.admin().cluster().reroute( diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java index c6e76ac7174ed..27bc7756ac620 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java @@ -21,7 +21,7 @@ import org.elasticsearch.action.ActionRunnable; import org.elasticsearch.action.admin.cluster.repositories.cleanup.CleanupRepositoryResponse; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.common.Strings; import org.elasticsearch.common.blobstore.BlobMetaData; @@ -216,7 +216,7 @@ public void testCleanup() throws Exception { createDanglingIndex(repo, genericExec); logger.info("--> deleting a snapshot to trigger repository cleanup"); - client().admin().cluster().deleteSnapshot(new DeleteSnapshotRequest("test-repo", snapshotName)).actionGet(); + client().admin().cluster().deleteSnapshot(new DeleteSnapshotsRequest("test-repo", snapshotName)).actionGet(); assertConsistentRepository(repo, genericExec); From 7588a93c2b18a1534fdf484e2d11eb682d2349b9 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 3 Dec 2019 16:16:53 +0100 Subject: [PATCH 06/45] bck --- .../url/URLSnapshotRestoreTests.java | 2 +- .../client/ClusterAdminClient.java | 6 ++-- .../client/support/AbstractClient.java | 6 ++-- .../cluster/RestDeleteSnapshotAction.java | 2 +- .../cluster/snapshots/SnapshotBlocksIT.java | 2 +- .../DedicatedClusterSnapshotRestoreIT.java | 4 +-- ...etadataLoadingDuringSnapshotRestoreIT.java | 2 +- .../MinThreadsSnapshotRestoreIT.java | 10 +++---- .../SharedClusterSnapshotRestoreIT.java | 28 +++++++++---------- .../snapshots/SnapshotResiliencyTests.java | 6 ++-- .../AbstractThirdPartyRepositoryTestCase.java | 4 +-- .../ESBlobStoreRepositoryIntegTestCase.java | 10 +++---- ...ESMockAPIBasedRepositoryIntegTestCase.java | 2 +- .../xpack/slm/SnapshotRetentionTask.java | 2 +- .../slm/SLMSnapshotBlockingIntegTests.java | 4 +-- .../authz/SnapshotUserRoleIntegTests.java | 2 +- .../snapshots/AbstractCleanupTests.java | 4 +-- 17 files changed, 48 insertions(+), 48 deletions(-) diff --git a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java index 2cc1d0992fafc..3f8685b4b7640 100644 --- a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java +++ b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java @@ -120,7 +120,7 @@ public void testUrlRepository() throws Exception { assertThat(getSnapshotsResponse.getSnapshots("url-repo").size(), equalTo(1)); logger.info("--> delete snapshot"); - AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").get(); + AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap").get(); assertAcked(deleteSnapshotResponse); logger.info("--> list available shapshot again, no snapshots should be returned"); diff --git a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index bd058b0a1d33f..303745b81a8e1 100644 --- a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -519,17 +519,17 @@ public interface ClusterAdminClient extends ElasticsearchClient { /** * Delete snapshot. */ - ActionFuture deleteSnapshot(DeleteSnapshotsRequest request); + ActionFuture deleteSnapshots(DeleteSnapshotsRequest request); /** * Delete snapshot. */ - void deleteSnapshot(DeleteSnapshotsRequest request, ActionListener listener); + void deleteSnapshots(DeleteSnapshotsRequest request, ActionListener listener); /** * Delete snapshot. */ - DeleteSnapshotRequestBuilder prepareDeleteSnapshot(String repository, String snapshot); + DeleteSnapshotRequestBuilder prepareDeleteSnapshots(String repository, String... snapshot); /** * Restores a snapshot. diff --git a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java index 189ac47b8d8d1..0c528af7fdb0b 100644 --- a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java +++ b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java @@ -943,17 +943,17 @@ public GetSnapshotsRequestBuilder prepareGetSnapshots(String... repositories) { @Override - public ActionFuture deleteSnapshot(DeleteSnapshotsRequest request) { + public ActionFuture deleteSnapshots(DeleteSnapshotsRequest request) { return execute(DeleteSnapshotAction.INSTANCE, request); } @Override - public void deleteSnapshot(DeleteSnapshotsRequest request, ActionListener listener) { + public void deleteSnapshots(DeleteSnapshotsRequest request, ActionListener listener) { execute(DeleteSnapshotAction.INSTANCE, request, listener); } @Override - public DeleteSnapshotRequestBuilder prepareDeleteSnapshot(String repository, String name) { + public DeleteSnapshotRequestBuilder prepareDeleteSnapshots(String repository, String name) { return new DeleteSnapshotRequestBuilder(this, DeleteSnapshotAction.INSTANCE, repository, name); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java index c649f6508d96b..f2dd972c5cb58 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java @@ -49,6 +49,6 @@ public String getName() { public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { DeleteSnapshotsRequest deleteSnapshotsRequest = deleteSnapshotRequest(request.param("repository"), request.param("snapshot")); deleteSnapshotsRequest.masterNodeTimeout(request.paramAsTime("master_timeout", deleteSnapshotsRequest.masterNodeTimeout())); - return channel -> client.admin().cluster().deleteSnapshot(deleteSnapshotsRequest, new RestToXContentListener<>(channel)); + return channel -> client.admin().cluster().deleteSnapshots(deleteSnapshotsRequest, new RestToXContentListener<>(channel)); } } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java index 05ff6567aa58d..3805f3a6fd7f2 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java @@ -124,7 +124,7 @@ public void testDeleteSnapshotWithBlocks() { logger.info("--> deleting a snapshot is allowed when the cluster is read only"); try { setClusterReadOnly(true); - assertTrue(client().admin().cluster().prepareDeleteSnapshot(REPOSITORY_NAME, SNAPSHOT_NAME).get().isAcknowledged()); + assertTrue(client().admin().cluster().prepareDeleteSnapshots(REPOSITORY_NAME, SNAPSHOT_NAME).get().isAcknowledged()); } finally { setClusterReadOnly(false); } diff --git a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java index a11fb9d13bc04..7cd2db9219292 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java @@ -474,7 +474,7 @@ public void testSnapshotWithStuckNode() throws Exception { logger.info("--> execution was blocked on node [{}], aborting snapshot", blockedNode); ActionFuture deleteSnapshotResponseFuture = internalCluster().client(nodes.get(0)) - .admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").execute(); + .admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap").execute(); // Make sure that abort makes some progress Thread.sleep(100); unblockNode("test-repo", blockedNode); @@ -1157,7 +1157,7 @@ public void testSnapshotTotalAndIncrementalSizes() throws IOException { // drop 1st one to avoid miscalculation as snapshot reuses some files of prev snapshot assertTrue(client.admin().cluster() - .prepareDeleteSnapshot(repositoryName, snapshot0) + .prepareDeleteSnapshots(repositoryName, snapshot0) .get().isAcknowledged()); response = client.admin().cluster().prepareSnapshotStatus(repositoryName) diff --git a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java index 3d65782d4824d..3c656dac2f519 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java @@ -139,7 +139,7 @@ public void testWhenMetadataAreLoaded() throws Exception { assertIndexMetadataLoads("snap", "others", 3); // Deleting a snapshot does not load the global metadata state but loads each index metadata - assertAcked(client().admin().cluster().prepareDeleteSnapshot("repository", "snap").get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots("repository", "snap").get()); assertGlobalMetadataLoads("snap", 1); assertIndexMetadataLoads("snap", "docs", 4); assertIndexMetadataLoads("snap", "others", 3); diff --git a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java index e93bb00d3d09e..6180d865f8a93 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java @@ -84,13 +84,13 @@ public void testConcurrentSnapshotDeletionsNotAllowed() throws Exception { ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of first snapshot"); ActionFuture future = - client().admin().cluster().prepareDeleteSnapshot(repo, snapshot2).execute(); + client().admin().cluster().prepareDeleteSnapshots(repo, snapshot2).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); logger.info("--> try deleting the second snapshot, should fail because the first deletion is in progress"); try { - client().admin().cluster().prepareDeleteSnapshot(repo, snapshot1).get(); + client().admin().cluster().prepareDeleteSnapshots(repo, snapshot1).get(); fail("should not be able to delete snapshots concurrently"); } catch (ConcurrentSnapshotExecutionException e) { assertThat(e.getMessage(), containsString("cannot delete - another snapshot is currently being deleted")); @@ -103,7 +103,7 @@ public void testConcurrentSnapshotDeletionsNotAllowed() throws Exception { assertAcked(future.actionGet()); logger.info("--> delete second snapshot, which should now work"); - client().admin().cluster().prepareDeleteSnapshot(repo, snapshot1).get(); + client().admin().cluster().prepareDeleteSnapshots(repo, snapshot1).get(); assertTrue(client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots(repo).isEmpty()); } @@ -129,7 +129,7 @@ public void testSnapshottingWithInProgressDeletionNotAllowed() throws Exception String blockedNode = internalCluster().getMasterName(); ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of snapshot"); - ActionFuture future = client().admin().cluster().prepareDeleteSnapshot(repo, snapshot1).execute(); + ActionFuture future = client().admin().cluster().prepareDeleteSnapshots(repo, snapshot1).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); @@ -184,7 +184,7 @@ public void testRestoreWithInProgressDeletionsNotAllowed() throws Exception { String blockedNode = internalCluster().getMasterName(); ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of snapshot"); - ActionFuture future = client().admin().cluster().prepareDeleteSnapshot(repo, snapshot2).execute(); + ActionFuture future = client().admin().cluster().prepareDeleteSnapshots(repo, snapshot2).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 0ec69bdaa0424..08025d79da1c3 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -1301,7 +1301,7 @@ public void testDeleteSnapshot() throws Exception { logger.info("--> delete all snapshots except the first one and last one"); for (int i = 1; i < numberOfSnapshots - 1; i++) { - client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-" + i).get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap-" + i).get(); } int numberOfFilesAfterDeletion = numberOfFiles(repo); @@ -1320,7 +1320,7 @@ public void testDeleteSnapshot() throws Exception { assertThat(client.prepareSearch("test-idx").setSize(0).get().getHits().getTotalHits().value, equalTo(10L * numberOfSnapshots)); logger.info("--> delete the last snapshot"); - client.admin().cluster().prepareDeleteSnapshot("test-repo", lastSnapshot).get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", lastSnapshot).get(); logger.info("--> make sure that number of files is back to what it was when the first snapshot was made, " + "plus one because one backup index-N file should remain"); assertFileCount(repo, numberOfFiles[0] + 1); @@ -1466,7 +1466,7 @@ public void testDeleteSnapshotWithMissingIndexAndShardMetadata() throws Exceptio } logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-1").get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap-1").get(); logger.info("--> make sure snapshot doesn't exist"); @@ -1507,7 +1507,7 @@ public void testDeleteSnapshotWithMissingMetadata() throws Exception { Files.delete(metadata); logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-1").get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap-1").get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareGetSnapshots("test-repo") @@ -1544,7 +1544,7 @@ public void testDeleteSnapshotWithCorruptedSnapshotFile() throws Exception { outChan.truncate(randomInt(10)); } logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-1").get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap-1").get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, @@ -1605,7 +1605,7 @@ public void testDeleteSnapshotWithCorruptedGlobalState() throws Exception { assertThat(snapshotStatusResponse.getSnapshots(), hasSize(1)); assertThat(snapshotStatusResponse.getSnapshots().get(0).getSnapshot().getSnapshotId().getName(), equalTo("test-snap")); - assertAcked(client().admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap").get()); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster() .prepareGetSnapshots("test-repo").addSnapshots("test-snap").get().getSnapshots("test-repo")); assertThrows(client().admin().cluster().prepareSnapshotStatus("test-repo").addSnapshots("test-snap"), @@ -2019,7 +2019,7 @@ public void testReadonlyRepository() throws Exception { assertThat(getSnapshotsResponse.getSnapshots("readonly-repo").size(), equalTo(1)); logger.info("--> try deleting snapshot"); - assertThrows(client.admin().cluster().prepareDeleteSnapshot("readonly-repo", "test-snap"), RepositoryException.class, + assertThrows(client.admin().cluster().prepareDeleteSnapshots("readonly-repo", "test-snap"), RepositoryException.class, "cannot delete snapshot from a readonly repository"); logger.info("--> try making another snapshot"); @@ -2714,14 +2714,14 @@ public void testDeleteSnapshotWhileRestoringFails() throws Exception { logger.info("--> try deleting the snapshot while the restore is in progress (should throw an error)"); ConcurrentSnapshotExecutionException e = expectThrows(ConcurrentSnapshotExecutionException.class, () -> - client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); + client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName).get()); assertEquals(repoName, e.getRepositoryName()); assertEquals(snapshotName, e.getSnapshotName()); assertThat(e.getMessage(), containsString("cannot delete snapshot during a restore")); logger.info("-- try deleting another snapshot while the restore is in progress (should throw an error)"); e = expectThrows(ConcurrentSnapshotExecutionException.class, () -> - client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName2).get()); + client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName2).get()); assertEquals(repoName, e.getRepositoryName()); assertEquals(snapshotName2, e.getSnapshotName()); assertThat(e.getMessage(), containsString("cannot delete snapshot during a restore")); @@ -2760,7 +2760,7 @@ public void testSnapshotName() throws Exception { () -> client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("_foo") .get().getSnapshots("test-repo")); expectThrows(SnapshotMissingException.class, - () -> client.admin().cluster().prepareDeleteSnapshot("test-repo", "_foo").get()); + () -> client.admin().cluster().prepareDeleteSnapshots("test-repo", "_foo").get()); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareSnapshotStatus("test-repo").setSnapshots("_foo").get()); } @@ -2959,7 +2959,7 @@ public void testRestoreSnapshotWithCorruptedIndexMetadata() throws Exception { } } - assertAcked(client().admin().cluster().prepareDeleteSnapshot("test-repo", snapshotInfo.snapshotId().getName()).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots("test-repo", snapshotInfo.snapshotId().getName()).get()); } /** @@ -3104,7 +3104,7 @@ public void testCannotCreateSnapshotsWithSameName() throws Exception { } logger.info("--> delete the first snapshot"); - client.admin().cluster().prepareDeleteSnapshot(repositoryName, snapshotName).get(); + client.admin().cluster().prepareDeleteSnapshots(repositoryName, snapshotName).get(); logger.info("--> try creating a snapshot with the same name, now it should work because the first one was deleted"); createSnapshotResponse = client.admin() @@ -3173,7 +3173,7 @@ public void testGetSnapshotsRequest() throws Exception { assertEquals("snap-on-empty-repo", getSnapshotsResponse.getSnapshots("test-repo").get(0).snapshotId().getName()); unblockNode(repositoryName, initialBlockedNode); // unblock node responseListener.actionGet(TimeValue.timeValueMillis(10000L)); // timeout after 10 seconds - client.admin().cluster().prepareDeleteSnapshot(repositoryName, "snap-on-empty-repo").get(); + client.admin().cluster().prepareDeleteSnapshots(repositoryName, "snap-on-empty-repo").get(); final int numSnapshots = randomIntBetween(1, 3) + 1; logger.info("--> take {} snapshot(s)", numSnapshots - 1); @@ -3840,7 +3840,7 @@ public void testSnapshotDifferentIndicesBySameName() { expectedCount = docCount; } logger.info("--> deleting snapshot [{}]", snapshotToDelete); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotToDelete).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotToDelete).get()); logger.info("--> restoring snapshot [{}]", snapshotToRestore); client().admin().cluster().prepareRestoreSnapshot(repoName, snapshotToRestore).setIndices(indexName).setRenamePattern(indexName) .setRenameReplacement("restored-3").setWaitForCompletion(true).get(); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index 75bbc1cb06119..3a8ed1203273f 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -408,7 +408,7 @@ public void testConcurrentSnapshotCreateAndDelete() { final StepListener deleteSnapshotStepListener = new StepListener<>(); - continueOrDie(createSnapshotResponseStepListener, createSnapshotResponse -> client().admin().cluster().deleteSnapshot( + continueOrDie(createSnapshotResponseStepListener, createSnapshotResponse -> client().admin().cluster().deleteSnapshots( new DeleteSnapshotsRequest(repoName, snapshotName), deleteSnapshotStepListener)); final StepListener createAnotherSnapshotResponseStepListener = new StepListener<>(); @@ -460,7 +460,7 @@ public void testConcurrentSnapshotCreateAndDeleteOther() { final StepListener deleteSnapshotStepListener = new StepListener<>(); continueOrDie(createOtherSnapshotResponseStepListener, - createSnapshotResponse -> client().admin().cluster().deleteSnapshot( + createSnapshotResponse -> client().admin().cluster().deleteSnapshots( new DeleteSnapshotsRequest(repoName, snapshotName), ActionListener.wrap( resp -> deleteSnapshotStepListener.onResponse(true), e -> { @@ -546,7 +546,7 @@ public void run() { testClusterNodes.randomDataNodeSafe().client.admin().cluster().prepareCreateSnapshot(repoName, snapshotName) .execute(ActionListener.wrap(() -> { createdSnapshot.set(true); - testClusterNodes.randomDataNodeSafe().client.admin().cluster().deleteSnapshot( + testClusterNodes.randomDataNodeSafe().client.admin().cluster().deleteSnapshots( new DeleteSnapshotsRequest(repoName, snapshotName), noopListener()); })); scheduleNow( diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java index 27bc7756ac620..05f0942997a19 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java @@ -131,7 +131,7 @@ public void testCreateSnapshot() { assertTrue(client().admin() .cluster() - .prepareDeleteSnapshot("test-repo", snapshotName) + .prepareDeleteSnapshots("test-repo", snapshotName) .get() .isAcknowledged()); } @@ -216,7 +216,7 @@ public void testCleanup() throws Exception { createDanglingIndex(repo, genericExec); logger.info("--> deleting a snapshot to trigger repository cleanup"); - client().admin().cluster().deleteSnapshot(new DeleteSnapshotsRequest("test-repo", snapshotName)).actionGet(); + client().admin().cluster().deleteSnapshots(new DeleteSnapshotsRequest("test-repo", snapshotName)).actionGet(); assertConsistentRepository(repo, genericExec); diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java index ccf3853ebe64b..26d12fc402036 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java @@ -151,13 +151,13 @@ public void testSnapshotAndRestore() throws Exception { } logger.info("--> delete snapshot {}:{}", repoName, snapshotName); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName).get()); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster().prepareGetSnapshots(repoName).setSnapshots(snapshotName).get().getSnapshots(repoName)); expectThrows(SnapshotMissingException.class, () -> - client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); + client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName).get()); expectThrows(SnapshotRestoreException.class, () -> client().admin().cluster().prepareRestoreSnapshot(repoName, snapshotName).setWaitForCompletion(randomBoolean()).get()); @@ -214,7 +214,7 @@ public void testMultipleSnapshotAndRollback() throws Exception { for (int i = 0; i < iterationCount; i++) { logger.info("--> delete snapshot {}:{}", repoName, snapshotName + "-" + i); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName + "-" + i).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName + "-" + i).get()); } } @@ -252,7 +252,7 @@ public void testIndicesDeletedFromRepository() throws Exception { assertEquals(createSnapshotResponse.getSnapshotInfo().successfulShards(), createSnapshotResponse.getSnapshotInfo().totalShards()); logger.info("--> delete a snapshot"); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, "test-snap").get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, "test-snap").get()); logger.info("--> verify index folder deleted from blob container"); RepositoriesService repositoriesSvc = internalCluster().getInstance(RepositoriesService.class, internalCluster().getMasterName()); @@ -272,7 +272,7 @@ public void testIndicesDeletedFromRepository() throws Exception { } } - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, "test-snap2").get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, "test-snap2").get()); } protected void addRandomDocuments(String name, int numDocs) throws InterruptedException { diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java index 03f89125ad979..2c341700153d4 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java @@ -150,7 +150,7 @@ public final void testSnapshotWithLargeSegmentFiles() throws Exception { ensureGreen(index); assertHitCount(client().prepareSearch(index).setSize(0).setTrackTotalHits(true).get(), nbDocs); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repository, snapshot).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repository, snapshot).get()); } protected static String httpServerUrl() { diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java index 25de192e76d04..e18ff7ba21847 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java @@ -388,7 +388,7 @@ void deleteSnapshot(String slmPolicy, String repo, SnapshotId snapshot, Snapshot ActionListener listener) { logger.info("[{}] snapshot retention deleting snapshot [{}]", repo, snapshot); CountDownLatch latch = new CountDownLatch(1); - client.admin().cluster().prepareDeleteSnapshot(repo, snapshot.getName()) + client.admin().cluster().prepareDeleteSnapshots(repo, snapshot.getName()) .execute(new LatchedActionListener<>(new ActionListener<>() { @Override public void onResponse(AcknowledgedResponse acknowledgedResponse) { diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java index 7c7a555a8d5d9..9d335e3023f74 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java @@ -119,7 +119,7 @@ public void testSnapshotInProgress() throws Exception { // Cancel/delete the snapshot try { - client().admin().cluster().prepareDeleteSnapshot(REPO, snapshotName).get(); + client().admin().cluster().prepareDeleteSnapshots(REPO, snapshotName).get(); } catch (SnapshotMissingException e) { // ignore } @@ -223,7 +223,7 @@ public void testRetentionWhileSnapshotInProgress() throws Exception { assertBusy(() -> { try { logger.info("--> cancelling snapshot {}", secondSnapName); - client().admin().cluster().prepareDeleteSnapshot(REPO, secondSnapName).get(); + client().admin().cluster().prepareDeleteSnapshots(REPO, secondSnapName).get(); } catch (ConcurrentSnapshotExecutionException e) { logger.info("--> attempted to stop second snapshot", e); // just wait and retry diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java index 520d495101fdc..65dfb68efccf9 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java @@ -126,7 +126,7 @@ public void testSnapshotUserRoleUnathorizedForDestructiveActions() { () -> client.admin().cluster().prepareRestoreSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(), "cluster:admin/snapshot/restore", "snapshot_user"); assertThrowsAuthorizationException( - () -> client.admin().cluster().prepareDeleteSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(), + () -> client.admin().cluster().prepareDeleteSnapshots("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(), "cluster:admin/snapshot/delete", "snapshot_user"); // try destructive/revealing actions on all indices for (final String indexToTest : Arrays.asList(INTERNAL_SECURITY_MAIN_INDEX_7, SECURITY_MAIN_ALIAS, ordinaryIndex)) { diff --git a/x-pack/snapshot-tool/src/test/java/org/elasticsearch/snapshots/AbstractCleanupTests.java b/x-pack/snapshot-tool/src/test/java/org/elasticsearch/snapshots/AbstractCleanupTests.java index f51ee07ce56ed..f5c292dcbd7e3 100644 --- a/x-pack/snapshot-tool/src/test/java/org/elasticsearch/snapshots/AbstractCleanupTests.java +++ b/x-pack/snapshot-tool/src/test/java/org/elasticsearch/snapshots/AbstractCleanupTests.java @@ -262,12 +262,12 @@ public void testCleanup() throws Throwable { logger.info("--> perform cleanup by removing snapshots"); assertTrue(client().admin() .cluster() - .prepareDeleteSnapshot("test-repo", "snap1") + .prepareDeleteSnapshots("test-repo", "snap1") .get() .isAcknowledged()); assertTrue(client().admin() .cluster() - .prepareDeleteSnapshot("test-repo", "snap2") + .prepareDeleteSnapshots("test-repo", "snap2") .get() .isAcknowledged()); } From 1984cc02c4bdd8ec0704b71411da8130bdbbf6a5 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 3 Dec 2019 16:57:02 +0100 Subject: [PATCH 07/45] more multi --- .../url/URLSnapshotRestoreTests.java | 3 +- .../delete/DeleteSnapshotRequestBuilder.java | 4 +-- .../client/ClusterAdminClient.java | 2 +- .../client/support/AbstractClient.java | 4 +-- .../snapshots/SnapshotsService.java | 5 ++- .../cluster/snapshots/SnapshotBlocksIT.java | 3 +- .../DedicatedClusterSnapshotRestoreIT.java | 4 +-- ...etadataLoadingDuringSnapshotRestoreIT.java | 2 +- .../MinThreadsSnapshotRestoreIT.java | 12 ++++--- .../SharedClusterSnapshotRestoreIT.java | 31 ++++++++++--------- .../AbstractThirdPartyRepositoryTestCase.java | 2 +- .../ESBlobStoreRepositoryIntegTestCase.java | 10 +++--- ...ESMockAPIBasedRepositoryIntegTestCase.java | 2 +- .../xpack/slm/SnapshotRetentionTask.java | 2 +- .../slm/SLMSnapshotBlockingIntegTests.java | 4 +-- .../authz/SnapshotUserRoleIntegTests.java | 3 +- .../snapshots/AbstractCleanupTests.java | 4 +-- 17 files changed, 53 insertions(+), 44 deletions(-) diff --git a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java index 3f8685b4b7640..45f77b3ed3663 100644 --- a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java +++ b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java @@ -120,7 +120,8 @@ public void testUrlRepository() throws Exception { assertThat(getSnapshotsResponse.getSnapshots("url-repo").size(), equalTo(1)); logger.info("--> delete snapshot"); - AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap").get(); + AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshots("test-repo", + new String[]{"test-snap"}).get(); assertAcked(deleteSnapshotResponse); logger.info("--> list available shapshot again, no snapshots should be returned"); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java index 921e8a2614f89..2efbb52049aea 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java @@ -39,8 +39,8 @@ public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAc /** * Constructs delete snapshot request builder with specified repository and snapshot names */ - public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAction action, String repository, String snapshot) { - super(client, action, new DeleteSnapshotsRequest(repository, new String[] {snapshot})); + public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAction action, String repository, String[] snapshots) { + super(client, action, new DeleteSnapshotsRequest(repository, snapshots)); } /** diff --git a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index 303745b81a8e1..16c66cfc829c4 100644 --- a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -529,7 +529,7 @@ public interface ClusterAdminClient extends ElasticsearchClient { /** * Delete snapshot. */ - DeleteSnapshotRequestBuilder prepareDeleteSnapshots(String repository, String... snapshot); + DeleteSnapshotRequestBuilder prepareDeleteSnapshots(String repository, String[] snapshot); /** * Restores a snapshot. diff --git a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java index 0c528af7fdb0b..a41577308a61d 100644 --- a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java +++ b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java @@ -953,8 +953,8 @@ public void deleteSnapshots(DeleteSnapshotsRequest request, ActionListener e.getSnapshot().getSnapshotId().equals(snapshot))) { + deletionsInProgress = deletionsInProgress.withAddedEntry(entry); + } } else { deletionsInProgress = SnapshotDeletionsInProgress.newInstance(entry); } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java index 3805f3a6fd7f2..797826203057e 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java @@ -124,7 +124,8 @@ public void testDeleteSnapshotWithBlocks() { logger.info("--> deleting a snapshot is allowed when the cluster is read only"); try { setClusterReadOnly(true); - assertTrue(client().admin().cluster().prepareDeleteSnapshots(REPOSITORY_NAME, SNAPSHOT_NAME).get().isAcknowledged()); + assertTrue( + client().admin().cluster().prepareDeleteSnapshots(REPOSITORY_NAME, new String[]{SNAPSHOT_NAME}).get().isAcknowledged()); } finally { setClusterReadOnly(false); } diff --git a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java index 7cd2db9219292..5d3aa01978fed 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java @@ -474,7 +474,7 @@ public void testSnapshotWithStuckNode() throws Exception { logger.info("--> execution was blocked on node [{}], aborting snapshot", blockedNode); ActionFuture deleteSnapshotResponseFuture = internalCluster().client(nodes.get(0)) - .admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap").execute(); + .admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap"}).execute(); // Make sure that abort makes some progress Thread.sleep(100); unblockNode("test-repo", blockedNode); @@ -1157,7 +1157,7 @@ public void testSnapshotTotalAndIncrementalSizes() throws IOException { // drop 1st one to avoid miscalculation as snapshot reuses some files of prev snapshot assertTrue(client.admin().cluster() - .prepareDeleteSnapshots(repositoryName, snapshot0) + .prepareDeleteSnapshots(repositoryName, new String[]{snapshot0}) .get().isAcknowledged()); response = client.admin().cluster().prepareSnapshotStatus(repositoryName) diff --git a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java index 3c656dac2f519..3bb6f24f46abb 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java @@ -139,7 +139,7 @@ public void testWhenMetadataAreLoaded() throws Exception { assertIndexMetadataLoads("snap", "others", 3); // Deleting a snapshot does not load the global metadata state but loads each index metadata - assertAcked(client().admin().cluster().prepareDeleteSnapshots("repository", "snap").get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots("repository", new String[]{"snap"}).get()); assertGlobalMetadataLoads("snap", 1); assertIndexMetadataLoads("snap", "docs", 4); assertIndexMetadataLoads("snap", "others", 3); diff --git a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java index 6180d865f8a93..9ef7800303442 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java @@ -84,13 +84,13 @@ public void testConcurrentSnapshotDeletionsNotAllowed() throws Exception { ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of first snapshot"); ActionFuture future = - client().admin().cluster().prepareDeleteSnapshots(repo, snapshot2).execute(); + client().admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot2}).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); logger.info("--> try deleting the second snapshot, should fail because the first deletion is in progress"); try { - client().admin().cluster().prepareDeleteSnapshots(repo, snapshot1).get(); + client().admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot1}).get(); fail("should not be able to delete snapshots concurrently"); } catch (ConcurrentSnapshotExecutionException e) { assertThat(e.getMessage(), containsString("cannot delete - another snapshot is currently being deleted")); @@ -103,7 +103,7 @@ public void testConcurrentSnapshotDeletionsNotAllowed() throws Exception { assertAcked(future.actionGet()); logger.info("--> delete second snapshot, which should now work"); - client().admin().cluster().prepareDeleteSnapshots(repo, snapshot1).get(); + client().admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot1}).get(); assertTrue(client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots(repo).isEmpty()); } @@ -129,7 +129,8 @@ public void testSnapshottingWithInProgressDeletionNotAllowed() throws Exception String blockedNode = internalCluster().getMasterName(); ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of snapshot"); - ActionFuture future = client().admin().cluster().prepareDeleteSnapshots(repo, snapshot1).execute(); + ActionFuture future = + client().admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot1}).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); @@ -184,7 +185,8 @@ public void testRestoreWithInProgressDeletionsNotAllowed() throws Exception { String blockedNode = internalCluster().getMasterName(); ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of snapshot"); - ActionFuture future = client().admin().cluster().prepareDeleteSnapshots(repo, snapshot2).execute(); + ActionFuture future = + client().admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot2}).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 08025d79da1c3..eec32645aacd1 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -1301,7 +1301,7 @@ public void testDeleteSnapshot() throws Exception { logger.info("--> delete all snapshots except the first one and last one"); for (int i = 1; i < numberOfSnapshots - 1; i++) { - client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap-" + i).get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-" + i}).get(); } int numberOfFilesAfterDeletion = numberOfFiles(repo); @@ -1320,7 +1320,7 @@ public void testDeleteSnapshot() throws Exception { assertThat(client.prepareSearch("test-idx").setSize(0).get().getHits().getTotalHits().value, equalTo(10L * numberOfSnapshots)); logger.info("--> delete the last snapshot"); - client.admin().cluster().prepareDeleteSnapshots("test-repo", lastSnapshot).get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{lastSnapshot}).get(); logger.info("--> make sure that number of files is back to what it was when the first snapshot was made, " + "plus one because one backup index-N file should remain"); assertFileCount(repo, numberOfFiles[0] + 1); @@ -1466,7 +1466,7 @@ public void testDeleteSnapshotWithMissingIndexAndShardMetadata() throws Exceptio } logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap-1").get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-1"}).get(); logger.info("--> make sure snapshot doesn't exist"); @@ -1507,7 +1507,7 @@ public void testDeleteSnapshotWithMissingMetadata() throws Exception { Files.delete(metadata); logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap-1").get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-1"}).get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareGetSnapshots("test-repo") @@ -1544,7 +1544,7 @@ public void testDeleteSnapshotWithCorruptedSnapshotFile() throws Exception { outChan.truncate(randomInt(10)); } logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap-1").get(); + client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-1"}).get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, @@ -1605,7 +1605,7 @@ public void testDeleteSnapshotWithCorruptedGlobalState() throws Exception { assertThat(snapshotStatusResponse.getSnapshots(), hasSize(1)); assertThat(snapshotStatusResponse.getSnapshots().get(0).getSnapshot().getSnapshotId().getName(), equalTo("test-snap")); - assertAcked(client().admin().cluster().prepareDeleteSnapshots("test-repo", "test-snap").get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap"}).get()); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster() .prepareGetSnapshots("test-repo").addSnapshots("test-snap").get().getSnapshots("test-repo")); assertThrows(client().admin().cluster().prepareSnapshotStatus("test-repo").addSnapshots("test-snap"), @@ -2019,8 +2019,8 @@ public void testReadonlyRepository() throws Exception { assertThat(getSnapshotsResponse.getSnapshots("readonly-repo").size(), equalTo(1)); logger.info("--> try deleting snapshot"); - assertThrows(client.admin().cluster().prepareDeleteSnapshots("readonly-repo", "test-snap"), RepositoryException.class, - "cannot delete snapshot from a readonly repository"); + assertThrows(client.admin().cluster().prepareDeleteSnapshots("readonly-repo", new String[]{"test-snap"}), + RepositoryException.class, "cannot delete snapshot from a readonly repository"); logger.info("--> try making another snapshot"); assertThrows(client.admin().cluster().prepareCreateSnapshot("readonly-repo", "test-snap-2") @@ -2714,14 +2714,14 @@ public void testDeleteSnapshotWhileRestoringFails() throws Exception { logger.info("--> try deleting the snapshot while the restore is in progress (should throw an error)"); ConcurrentSnapshotExecutionException e = expectThrows(ConcurrentSnapshotExecutionException.class, () -> - client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName).get()); + client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshotName}).get()); assertEquals(repoName, e.getRepositoryName()); assertEquals(snapshotName, e.getSnapshotName()); assertThat(e.getMessage(), containsString("cannot delete snapshot during a restore")); logger.info("-- try deleting another snapshot while the restore is in progress (should throw an error)"); e = expectThrows(ConcurrentSnapshotExecutionException.class, () -> - client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName2).get()); + client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshotName2}).get()); assertEquals(repoName, e.getRepositoryName()); assertEquals(snapshotName2, e.getSnapshotName()); assertThat(e.getMessage(), containsString("cannot delete snapshot during a restore")); @@ -2760,7 +2760,7 @@ public void testSnapshotName() throws Exception { () -> client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("_foo") .get().getSnapshots("test-repo")); expectThrows(SnapshotMissingException.class, - () -> client.admin().cluster().prepareDeleteSnapshots("test-repo", "_foo").get()); + () -> client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[] {"_foo"}).get()); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareSnapshotStatus("test-repo").setSnapshots("_foo").get()); } @@ -2959,7 +2959,8 @@ public void testRestoreSnapshotWithCorruptedIndexMetadata() throws Exception { } } - assertAcked(client().admin().cluster().prepareDeleteSnapshots("test-repo", snapshotInfo.snapshotId().getName()).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots("test-repo", + new String[]{snapshotInfo.snapshotId().getName()}).get()); } /** @@ -3104,7 +3105,7 @@ public void testCannotCreateSnapshotsWithSameName() throws Exception { } logger.info("--> delete the first snapshot"); - client.admin().cluster().prepareDeleteSnapshots(repositoryName, snapshotName).get(); + client.admin().cluster().prepareDeleteSnapshots(repositoryName, new String[]{snapshotName}).get(); logger.info("--> try creating a snapshot with the same name, now it should work because the first one was deleted"); createSnapshotResponse = client.admin() @@ -3173,7 +3174,7 @@ public void testGetSnapshotsRequest() throws Exception { assertEquals("snap-on-empty-repo", getSnapshotsResponse.getSnapshots("test-repo").get(0).snapshotId().getName()); unblockNode(repositoryName, initialBlockedNode); // unblock node responseListener.actionGet(TimeValue.timeValueMillis(10000L)); // timeout after 10 seconds - client.admin().cluster().prepareDeleteSnapshots(repositoryName, "snap-on-empty-repo").get(); + client.admin().cluster().prepareDeleteSnapshots(repositoryName, new String[]{"snap-on-empty-repo"}).get(); final int numSnapshots = randomIntBetween(1, 3) + 1; logger.info("--> take {} snapshot(s)", numSnapshots - 1); @@ -3840,7 +3841,7 @@ public void testSnapshotDifferentIndicesBySameName() { expectedCount = docCount; } logger.info("--> deleting snapshot [{}]", snapshotToDelete); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotToDelete).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshotToDelete}).get()); logger.info("--> restoring snapshot [{}]", snapshotToRestore); client().admin().cluster().prepareRestoreSnapshot(repoName, snapshotToRestore).setIndices(indexName).setRenamePattern(indexName) .setRenameReplacement("restored-3").setWaitForCompletion(true).get(); diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java index 05f0942997a19..276350adc23f4 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java @@ -131,7 +131,7 @@ public void testCreateSnapshot() { assertTrue(client().admin() .cluster() - .prepareDeleteSnapshots("test-repo", snapshotName) + .prepareDeleteSnapshots("test-repo", new String[]{snapshotName}) .get() .isAcknowledged()); } diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java index 26d12fc402036..68a17c913b29f 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java @@ -151,13 +151,13 @@ public void testSnapshotAndRestore() throws Exception { } logger.info("--> delete snapshot {}:{}", repoName, snapshotName); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshotName}).get()); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster().prepareGetSnapshots(repoName).setSnapshots(snapshotName).get().getSnapshots(repoName)); expectThrows(SnapshotMissingException.class, () -> - client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName).get()); + client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshotName}).get()); expectThrows(SnapshotRestoreException.class, () -> client().admin().cluster().prepareRestoreSnapshot(repoName, snapshotName).setWaitForCompletion(randomBoolean()).get()); @@ -214,7 +214,7 @@ public void testMultipleSnapshotAndRollback() throws Exception { for (int i = 0; i < iterationCount; i++) { logger.info("--> delete snapshot {}:{}", repoName, snapshotName + "-" + i); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, snapshotName + "-" + i).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[] {snapshotName + "-" + i}).get()); } } @@ -252,7 +252,7 @@ public void testIndicesDeletedFromRepository() throws Exception { assertEquals(createSnapshotResponse.getSnapshotInfo().successfulShards(), createSnapshotResponse.getSnapshotInfo().totalShards()); logger.info("--> delete a snapshot"); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, "test-snap").get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{"test-snap"}).get()); logger.info("--> verify index folder deleted from blob container"); RepositoriesService repositoriesSvc = internalCluster().getInstance(RepositoriesService.class, internalCluster().getMasterName()); @@ -272,7 +272,7 @@ public void testIndicesDeletedFromRepository() throws Exception { } } - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, "test-snap2").get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{"test-snap2"}).get()); } protected void addRandomDocuments(String name, int numDocs) throws InterruptedException { diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java index 2c341700153d4..d1bea24c05ea8 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java @@ -150,7 +150,7 @@ public final void testSnapshotWithLargeSegmentFiles() throws Exception { ensureGreen(index); assertHitCount(client().prepareSearch(index).setSize(0).setTrackTotalHits(true).get(), nbDocs); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repository, snapshot).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repository, new String[]{snapshot}).get()); } protected static String httpServerUrl() { diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java index e18ff7ba21847..ef58295863582 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java @@ -388,7 +388,7 @@ void deleteSnapshot(String slmPolicy, String repo, SnapshotId snapshot, Snapshot ActionListener listener) { logger.info("[{}] snapshot retention deleting snapshot [{}]", repo, snapshot); CountDownLatch latch = new CountDownLatch(1); - client.admin().cluster().prepareDeleteSnapshots(repo, snapshot.getName()) + client.admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot.getName()}) .execute(new LatchedActionListener<>(new ActionListener<>() { @Override public void onResponse(AcknowledgedResponse acknowledgedResponse) { diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java index 9d335e3023f74..20fd6c6745c4d 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java @@ -119,7 +119,7 @@ public void testSnapshotInProgress() throws Exception { // Cancel/delete the snapshot try { - client().admin().cluster().prepareDeleteSnapshots(REPO, snapshotName).get(); + client().admin().cluster().prepareDeleteSnapshots(REPO, new String[]{snapshotName}).get(); } catch (SnapshotMissingException e) { // ignore } @@ -223,7 +223,7 @@ public void testRetentionWhileSnapshotInProgress() throws Exception { assertBusy(() -> { try { logger.info("--> cancelling snapshot {}", secondSnapName); - client().admin().cluster().prepareDeleteSnapshots(REPO, secondSnapName).get(); + client().admin().cluster().prepareDeleteSnapshots(REPO, new String[]{secondSnapName}).get(); } catch (ConcurrentSnapshotExecutionException e) { logger.info("--> attempted to stop second snapshot", e); // just wait and retry diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java index 65dfb68efccf9..34a7350d029fe 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java @@ -126,7 +126,8 @@ public void testSnapshotUserRoleUnathorizedForDestructiveActions() { () -> client.admin().cluster().prepareRestoreSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(), "cluster:admin/snapshot/restore", "snapshot_user"); assertThrowsAuthorizationException( - () -> client.admin().cluster().prepareDeleteSnapshots("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(), + () -> client.admin().cluster().prepareDeleteSnapshots("repo", + new String[]{randomAlphaOfLength(4).toLowerCase(Locale.ROOT)}).get(), "cluster:admin/snapshot/delete", "snapshot_user"); // try destructive/revealing actions on all indices for (final String indexToTest : Arrays.asList(INTERNAL_SECURITY_MAIN_INDEX_7, SECURITY_MAIN_ALIAS, ordinaryIndex)) { diff --git a/x-pack/snapshot-tool/src/test/java/org/elasticsearch/snapshots/AbstractCleanupTests.java b/x-pack/snapshot-tool/src/test/java/org/elasticsearch/snapshots/AbstractCleanupTests.java index f5c292dcbd7e3..f065307ca1355 100644 --- a/x-pack/snapshot-tool/src/test/java/org/elasticsearch/snapshots/AbstractCleanupTests.java +++ b/x-pack/snapshot-tool/src/test/java/org/elasticsearch/snapshots/AbstractCleanupTests.java @@ -262,12 +262,12 @@ public void testCleanup() throws Throwable { logger.info("--> perform cleanup by removing snapshots"); assertTrue(client().admin() .cluster() - .prepareDeleteSnapshots("test-repo", "snap1") + .prepareDeleteSnapshots("test-repo", new String[]{"snap1"}) .get() .isAcknowledged()); assertTrue(client().admin() .cluster() - .prepareDeleteSnapshots("test-repo", "snap2") + .prepareDeleteSnapshots("test-repo", new String[]{"snap2"}) .get() .isAcknowledged()); } From e91a873b4a048718e972fbd243affa8b285cc001 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 3 Dec 2019 17:37:45 +0100 Subject: [PATCH 08/45] works --- .../org/elasticsearch/snapshots/SnapshotsService.java | 9 +++++---- .../snapshots/SharedClusterSnapshotRestoreIT.java | 10 ++++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index 8d5f5ff161c66..435f324fa8810 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -1424,10 +1424,11 @@ public ClusterState execute(ClusterState currentState) { if (deletions != null) { boolean changed = false; if (deletions.hasDeletionsInProgress()) { - assert deletions.getEntries().size() == 1 : "should have exactly one deletion in progress"; - SnapshotDeletionsInProgress.Entry entry = deletions.getEntries().get(0); - deletions = deletions.withRemovedEntry(entry); - changed = true; + for (SnapshotDeletionsInProgress.Entry entry : deletions.getEntries().stream() + .filter(e -> snapshots.contains(e.getSnapshot().getSnapshotId())).collect(Collectors.toList())) { + changed = true; + deletions = deletions.withRemovedEntry(entry); + } } if (changed) { return ClusterState.builder(currentState).putCustom(SnapshotDeletionsInProgress.TYPE, deletions).build(); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index eec32645aacd1..80221c8be50fe 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -1300,8 +1300,14 @@ public void testDeleteSnapshot() throws Exception { int numberOfFilesBeforeDeletion = numberOfFiles(repo); logger.info("--> delete all snapshots except the first one and last one"); - for (int i = 1; i < numberOfSnapshots - 1; i++) { - client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-" + i}).get(); + + if (randomBoolean()) { + for (int i = 1; i < numberOfSnapshots - 1; i++) { + client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-" + i}).get(); + } + } else { + client.admin().cluster().prepareDeleteSnapshots( + "test-repo", IntStream.range(1, numberOfSnapshots - 1).mapToObj(i -> "test-snap-" + i).toArray(String[]::new)).get(); } int numberOfFilesAfterDeletion = numberOfFiles(repo); From e88145918b480ab6c919e336cb81a975904b9521 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 3 Dec 2019 19:34:02 +0100 Subject: [PATCH 09/45] bck --- .../snapshots/SnapshotResiliencyTests.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index 3a8ed1203273f..0ccf23846df9b 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -389,6 +389,72 @@ public void testSnapshotWithNodeDisconnects() { assertThat(snapshotIds, hasSize(1)); } + public void testSnapshotDeletesWithNodeDisconnects() { + final int dataNodes = randomIntBetween(2, 10); + final int masterNodes = randomFrom(1, 3, 5); + setupTestCluster(masterNodes, dataNodes); + + String repoName = "repo"; + String snapshotNamePrefix = "snapshot-"; + final String index = "test"; + final int shards = randomIntBetween(1, 10); + + TestClusterNodes.TestClusterNode masterNode = + testClusterNodes.currentMaster(testClusterNodes.nodes.values().iterator().next().clusterService.state()); + + final StepListener createSnapshotResponseStepListener = new StepListener<>(); + + continueOrDie(createRepoAndIndex(repoName, index, shards), + createIndexResponse -> client().admin().cluster().prepareCreateSnapshot(repoName, snapshotNamePrefix + "1") + .setWaitForCompletion(true).execute(createSnapshotResponseStepListener)); + + final StepListener createAnotherSnapshotResponseStepListener = new StepListener<>(); + + continueOrDie(createSnapshotResponseStepListener, acknowledgedResponse -> client().admin().cluster() + .prepareCreateSnapshot(repoName, snapshotNamePrefix + "2"). + setWaitForCompletion(true).execute(createAnotherSnapshotResponseStepListener)); + continueOrDie(createAnotherSnapshotResponseStepListener, createSnapshotResponse -> + assertEquals(createSnapshotResponse.getSnapshotInfo().state(), SnapshotState.SUCCESS)); + + final StepListener deleteStepListener = new StepListener<>(); + + continueOrDie(createAnotherSnapshotResponseStepListener, createSnapshotResponse -> { + client().admin().cluster().deleteSnapshots( + new DeleteSnapshotsRequest(repoName, new String[]{snapshotNamePrefix + "1", snapshotNamePrefix + "2"}), + ActionListener.wrap( + resp -> deleteStepListener.onResponse(true), + e -> { + final Throwable unwrapped = + ExceptionsHelper.unwrap(e, ConcurrentSnapshotExecutionException.class); + assertThat(unwrapped, instanceOf(ConcurrentSnapshotExecutionException.class)); + deleteStepListener.onResponse(false); + })); + + for (int i = 0; i < randomIntBetween(0, dataNodes); ++i) { + scheduleNow(this::disconnectOrRestartDataNode); + } + // Only disconnect master if we have more than a single master and can simulate a failover + final boolean disconnectedMaster = randomBoolean() && masterNodes > 1; + if (disconnectedMaster) { + scheduleNow(this::disconnectOrRestartMasterNode); + } + if (disconnectedMaster || randomBoolean()) { + scheduleSoon(() -> testClusterNodes.clearNetworkDisruptions()); + } else if (randomBoolean()) { + scheduleNow(() -> testClusterNodes.clearNetworkDisruptions()); + } + }); + + deterministicTaskQueue.runAllRunnableTasks(); + + assertNotNull(createAnotherSnapshotResponseStepListener.result()); + SnapshotsInProgress finalSnapshotsInProgress = masterNode.clusterService.state().custom(SnapshotsInProgress.TYPE); + assertFalse(finalSnapshotsInProgress.entries().stream().anyMatch(entry -> entry.state().completed() == false)); + final Repository repository = masterNode.repositoriesService.repository(repoName); + Collection snapshotIds = getRepositoryData(repository).getSnapshotIds(); + //assertThat(snapshotIds, hasSize(0)); + } + public void testConcurrentSnapshotCreateAndDelete() { setupTestCluster(randomFrom(1, 3, 5), randomIntBetween(2, 10)); From 92ab9d575ba06021e3afea6863305c84e64e7b03 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Thu, 12 Dec 2019 12:09:46 +0100 Subject: [PATCH 10/45] bck --- .../snapshots/SnapshotResiliencyTests.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index 0ccf23846df9b..4872681862258 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -92,6 +92,7 @@ import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ESAllocationTestCase; import org.elasticsearch.cluster.NodeConnectionsService; +import org.elasticsearch.cluster.SnapshotDeletionsInProgress; import org.elasticsearch.cluster.SnapshotsInProgress; import org.elasticsearch.cluster.action.index.MappingUpdatedAction; import org.elasticsearch.cluster.action.index.NodeMappingRefreshAction; @@ -445,14 +446,17 @@ public void testSnapshotDeletesWithNodeDisconnects() { } }); - deterministicTaskQueue.runAllRunnableTasks(); + runUntil(() -> testClusterNodes.randomMasterNode().map(master -> { + final ClusterState state = master.clusterService.state(); + final SnapshotsInProgress snapshotsInProgress = state.custom(SnapshotsInProgress.TYPE); + final SnapshotDeletionsInProgress snapshotDeletionsInProgress = state.custom(SnapshotDeletionsInProgress.TYPE); + return snapshotsInProgress != null && snapshotsInProgress.entries().isEmpty() && snapshotDeletionsInProgress != null + && snapshotDeletionsInProgress.getEntries().isEmpty(); + }).orElse(false), TimeUnit.MINUTES.toMillis(1L)); assertNotNull(createAnotherSnapshotResponseStepListener.result()); SnapshotsInProgress finalSnapshotsInProgress = masterNode.clusterService.state().custom(SnapshotsInProgress.TYPE); assertFalse(finalSnapshotsInProgress.entries().stream().anyMatch(entry -> entry.state().completed() == false)); - final Repository repository = masterNode.repositoriesService.repository(repoName); - Collection snapshotIds = getRepositoryData(repository).getSnapshotIds(); - //assertThat(snapshotIds, hasSize(0)); } public void testConcurrentSnapshotCreateAndDelete() { From 821c36ae3b96f4c0b736b6c58dbc180029b97eb8 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Thu, 12 Dec 2019 16:21:34 +0100 Subject: [PATCH 11/45] bck --- .../elasticsearch/snapshots/SnapshotResiliencyTests.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index 4872681862258..fec4c5bc90a80 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -390,6 +390,7 @@ public void testSnapshotWithNodeDisconnects() { assertThat(snapshotIds, hasSize(1)); } + @AwaitsFix(bugUrl = "still working on making this pass") public void testSnapshotDeletesWithNodeDisconnects() { final int dataNodes = randomIntBetween(2, 10); final int masterNodes = randomFrom(1, 3, 5); @@ -414,12 +415,11 @@ public void testSnapshotDeletesWithNodeDisconnects() { continueOrDie(createSnapshotResponseStepListener, acknowledgedResponse -> client().admin().cluster() .prepareCreateSnapshot(repoName, snapshotNamePrefix + "2"). setWaitForCompletion(true).execute(createAnotherSnapshotResponseStepListener)); - continueOrDie(createAnotherSnapshotResponseStepListener, createSnapshotResponse -> - assertEquals(createSnapshotResponse.getSnapshotInfo().state(), SnapshotState.SUCCESS)); final StepListener deleteStepListener = new StepListener<>(); continueOrDie(createAnotherSnapshotResponseStepListener, createSnapshotResponse -> { + assertEquals(createSnapshotResponse.getSnapshotInfo().state(), SnapshotState.SUCCESS); client().admin().cluster().deleteSnapshots( new DeleteSnapshotsRequest(repoName, new String[]{snapshotNamePrefix + "1", snapshotNamePrefix + "2"}), ActionListener.wrap( @@ -446,6 +446,10 @@ public void testSnapshotDeletesWithNodeDisconnects() { } }); + continueOrDie(deleteStepListener, r -> { + logger.info("done"); + }); + runUntil(() -> testClusterNodes.randomMasterNode().map(master -> { final ClusterState state = master.clusterService.state(); final SnapshotsInProgress snapshotsInProgress = state.custom(SnapshotsInProgress.TYPE); From 522b6fa1350e4768a5d14134916677e8ee733086 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Thu, 12 Dec 2019 16:28:19 +0100 Subject: [PATCH 12/45] drop it for now --- .../snapshots/SnapshotResiliencyTests.java | 74 ------------------- 1 file changed, 74 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index fec4c5bc90a80..3a8ed1203273f 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -92,7 +92,6 @@ import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ESAllocationTestCase; import org.elasticsearch.cluster.NodeConnectionsService; -import org.elasticsearch.cluster.SnapshotDeletionsInProgress; import org.elasticsearch.cluster.SnapshotsInProgress; import org.elasticsearch.cluster.action.index.MappingUpdatedAction; import org.elasticsearch.cluster.action.index.NodeMappingRefreshAction; @@ -390,79 +389,6 @@ public void testSnapshotWithNodeDisconnects() { assertThat(snapshotIds, hasSize(1)); } - @AwaitsFix(bugUrl = "still working on making this pass") - public void testSnapshotDeletesWithNodeDisconnects() { - final int dataNodes = randomIntBetween(2, 10); - final int masterNodes = randomFrom(1, 3, 5); - setupTestCluster(masterNodes, dataNodes); - - String repoName = "repo"; - String snapshotNamePrefix = "snapshot-"; - final String index = "test"; - final int shards = randomIntBetween(1, 10); - - TestClusterNodes.TestClusterNode masterNode = - testClusterNodes.currentMaster(testClusterNodes.nodes.values().iterator().next().clusterService.state()); - - final StepListener createSnapshotResponseStepListener = new StepListener<>(); - - continueOrDie(createRepoAndIndex(repoName, index, shards), - createIndexResponse -> client().admin().cluster().prepareCreateSnapshot(repoName, snapshotNamePrefix + "1") - .setWaitForCompletion(true).execute(createSnapshotResponseStepListener)); - - final StepListener createAnotherSnapshotResponseStepListener = new StepListener<>(); - - continueOrDie(createSnapshotResponseStepListener, acknowledgedResponse -> client().admin().cluster() - .prepareCreateSnapshot(repoName, snapshotNamePrefix + "2"). - setWaitForCompletion(true).execute(createAnotherSnapshotResponseStepListener)); - - final StepListener deleteStepListener = new StepListener<>(); - - continueOrDie(createAnotherSnapshotResponseStepListener, createSnapshotResponse -> { - assertEquals(createSnapshotResponse.getSnapshotInfo().state(), SnapshotState.SUCCESS); - client().admin().cluster().deleteSnapshots( - new DeleteSnapshotsRequest(repoName, new String[]{snapshotNamePrefix + "1", snapshotNamePrefix + "2"}), - ActionListener.wrap( - resp -> deleteStepListener.onResponse(true), - e -> { - final Throwable unwrapped = - ExceptionsHelper.unwrap(e, ConcurrentSnapshotExecutionException.class); - assertThat(unwrapped, instanceOf(ConcurrentSnapshotExecutionException.class)); - deleteStepListener.onResponse(false); - })); - - for (int i = 0; i < randomIntBetween(0, dataNodes); ++i) { - scheduleNow(this::disconnectOrRestartDataNode); - } - // Only disconnect master if we have more than a single master and can simulate a failover - final boolean disconnectedMaster = randomBoolean() && masterNodes > 1; - if (disconnectedMaster) { - scheduleNow(this::disconnectOrRestartMasterNode); - } - if (disconnectedMaster || randomBoolean()) { - scheduleSoon(() -> testClusterNodes.clearNetworkDisruptions()); - } else if (randomBoolean()) { - scheduleNow(() -> testClusterNodes.clearNetworkDisruptions()); - } - }); - - continueOrDie(deleteStepListener, r -> { - logger.info("done"); - }); - - runUntil(() -> testClusterNodes.randomMasterNode().map(master -> { - final ClusterState state = master.clusterService.state(); - final SnapshotsInProgress snapshotsInProgress = state.custom(SnapshotsInProgress.TYPE); - final SnapshotDeletionsInProgress snapshotDeletionsInProgress = state.custom(SnapshotDeletionsInProgress.TYPE); - return snapshotsInProgress != null && snapshotsInProgress.entries().isEmpty() && snapshotDeletionsInProgress != null - && snapshotDeletionsInProgress.getEntries().isEmpty(); - }).orElse(false), TimeUnit.MINUTES.toMillis(1L)); - - assertNotNull(createAnotherSnapshotResponseStepListener.result()); - SnapshotsInProgress finalSnapshotsInProgress = masterNode.clusterService.state().custom(SnapshotsInProgress.TYPE); - assertFalse(finalSnapshotsInProgress.entries().stream().anyMatch(entry -> entry.state().completed() == false)); - } - public void testConcurrentSnapshotCreateAndDelete() { setupTestCluster(randomFrom(1, 3, 5), randomIntBetween(2, 10)); From 0e074040fb9cbda6cb9b0fff0096f4f92d897d67 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 15:44:30 +0200 Subject: [PATCH 13/45] fixed --- .../org/elasticsearch/repositories/s3/S3Repository.java | 7 ++++--- .../repositories/s3/S3BlobStoreRepositoryTests.java | 6 +++--- .../upgrades/MultiVersionRepositoryAccessIT.java | 5 +++-- .../elasticsearch/repositories/RepositoriesService.java | 2 +- .../java/org/elasticsearch/snapshots/RestoreService.java | 4 ++-- .../org/elasticsearch/snapshots/SnapshotsService.java | 3 +-- .../cluster/serialization/ClusterSerializationTests.java | 6 +++--- .../snapshots/CorruptedBlobStoreRepositoryIT.java | 8 ++++---- .../elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java | 6 +++--- .../xpack/core/ilm/CleanupSnapshotStepTests.java | 8 ++++---- .../xpack/slm/SLMSnapshotBlockingIntegTests.java | 2 +- .../xpack/slm/SnapshotRetentionTaskTests.java | 7 ++++--- 12 files changed, 33 insertions(+), 31 deletions(-) diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java index 4069269d7d5e9..1ed588914b8bc 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java @@ -48,6 +48,7 @@ import org.elasticsearch.threadpool.Scheduler; import org.elasticsearch.threadpool.ThreadPool; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -248,12 +249,12 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera } @Override - public void deleteSnapshot(SnapshotId snapshotId, long repositoryStateId, Version repositoryMetaVersion, - ActionListener listener) { + public void deleteSnapshot(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, + ActionListener listener) { if (SnapshotsService.useShardGenerations(repositoryMetaVersion) == false) { listener = delayedListener(listener); } - super.deleteSnapshot(snapshotId, repositoryStateId, repositoryMetaVersion, listener); + super.deleteSnapshot(snapshotIds, repositoryStateId, repositoryMetaVersion, listener); } /** diff --git a/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java b/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java index e3fab59e7d47c..ebddf3fdfed0c 100644 --- a/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java +++ b/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java @@ -179,11 +179,11 @@ public void testEnforcedCooldownPeriod() throws IOException { assertThat(repository.threadPool().relativeTimeInNanos() - beforeThrottledSnapshot, greaterThan(TEST_COOLDOWN_PERIOD.getNanos())); final long beforeThrottledDelete = repository.threadPool().relativeTimeInNanos(); - client().admin().cluster().prepareDeleteSnapshot(repoName, newSnapshotName).get(); + client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{newSnapshotName}).get(); assertThat(repository.threadPool().relativeTimeInNanos() - beforeThrottledDelete, greaterThan(TEST_COOLDOWN_PERIOD.getNanos())); final long beforeFastDelete = repository.threadPool().relativeTimeInNanos(); - client().admin().cluster().prepareDeleteSnapshot(repoName, fakeOldSnapshot.getName()).get(); + client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{fakeOldSnapshot.getName()}).get(); assertThat(repository.threadPool().relativeTimeInNanos() - beforeFastDelete, lessThan(TEST_COOLDOWN_PERIOD.getNanos())); } @@ -215,7 +215,7 @@ public void testRequestStats() throws Exception { ensureGreen(index); assertHitCount(client().prepareSearch(index).setSize(0).setTrackTotalHits(true).get(), nbDocs); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repository, snapshot).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repository, new String[] {snapshot}).get()); final RepositoryStats repositoryStats = StreamSupport.stream( internalCluster().getInstances(RepositoriesService.class).spliterator(), false) diff --git a/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java b/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java index 15dcfea8cc5d9..66fdc7556e752 100644 --- a/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java +++ b/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java @@ -22,7 +22,7 @@ import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotStatus; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; @@ -252,7 +252,8 @@ private static void assertSnapshotStatusSuccessful(RestHighLevelClient client, S } private void deleteSnapshot(RestHighLevelClient client, String repoName, String name) throws IOException { - assertThat(client.snapshot().delete(new DeleteSnapshotRequest(repoName, name), RequestOptions.DEFAULT).isAcknowledged(), is(true)); + assertThat(client.snapshot().delete( + new DeleteSnapshotsRequest(repoName, name), RequestOptions.DEFAULT).isAcknowledged(), is(true)); } @SuppressWarnings("unchecked") diff --git a/server/src/main/java/org/elasticsearch/repositories/RepositoriesService.java b/server/src/main/java/org/elasticsearch/repositories/RepositoriesService.java index 4d56c6c17076a..119496bb41adc 100644 --- a/server/src/main/java/org/elasticsearch/repositories/RepositoriesService.java +++ b/server/src/main/java/org/elasticsearch/repositories/RepositoriesService.java @@ -487,7 +487,7 @@ private static boolean isRepositoryInUse(ClusterState clusterState, String repos SnapshotDeletionsInProgress deletionsInProgress = clusterState.custom(SnapshotDeletionsInProgress.TYPE); if (deletionsInProgress != null) { for (SnapshotDeletionsInProgress.Entry entry : deletionsInProgress.getEntries()) { - if (entry.getSnapshot().getRepository().equals(repository)) { + if (entry.repository().equals(repository)) { return true; } } diff --git a/server/src/main/java/org/elasticsearch/snapshots/RestoreService.java b/server/src/main/java/org/elasticsearch/snapshots/RestoreService.java index bea0769f59399..c567c4f110518 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/RestoreService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/RestoreService.java @@ -227,10 +227,10 @@ public ClusterState execute(ClusterState currentState) { // Check if the snapshot to restore is currently being deleted SnapshotDeletionsInProgress deletionsInProgress = currentState.custom(SnapshotDeletionsInProgress.TYPE); if (deletionsInProgress != null - && deletionsInProgress.getEntries().stream().anyMatch(entry -> entry.getSnapshot().equals(snapshot))) { + && deletionsInProgress.getEntries().stream().anyMatch(entry -> entry.getSnapshots().contains(snapshotId))) { throw new ConcurrentSnapshotExecutionException(snapshot, "cannot restore a snapshot while a snapshot deletion is in-progress [" + - deletionsInProgress.getEntries().get(0).getSnapshot() + "]"); + deletionsInProgress.getEntries().get(0) + "]"); } // Updating cluster state diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index cf483cecc8ad0..1cfa62e92c466 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -85,7 +85,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -1151,7 +1150,7 @@ private static SnapshotsInProgress.Entry findInProgressSnapshot(@Nullable Snapsh * Deletes a snapshot that is assumed to be in the repository and not tracked as in-progress in the cluster state. * * @param snapshotIds Snapshots to delete - * @param repoName + * @param repoName Repository name * @param repositoryStateId Repository generation to base the delete on * @param listener Listener to complete when done */ diff --git a/server/src/test/java/org/elasticsearch/cluster/serialization/ClusterSerializationTests.java b/server/src/test/java/org/elasticsearch/cluster/serialization/ClusterSerializationTests.java index 426f7a3cf9c85..e9c72590229e4 100644 --- a/server/src/test/java/org/elasticsearch/cluster/serialization/ClusterSerializationTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/serialization/ClusterSerializationTests.java @@ -118,9 +118,9 @@ public void testSnapshotDeletionsInProgressSerialization() throws Exception { ClusterState.Builder builder = ClusterState.builder(ClusterState.EMPTY_STATE) .putCustom(SnapshotDeletionsInProgress.TYPE, SnapshotDeletionsInProgress.newInstance( - new SnapshotDeletionsInProgress.Entry( - new Snapshot("repo1", new SnapshotId("snap1", UUIDs.randomBase64UUID())), - randomNonNegativeLong(), randomNonNegativeLong()) + new SnapshotDeletionsInProgress.Entry( + Collections.singletonList(new SnapshotId("snap1", UUIDs.randomBase64UUID())), "repo1", + randomNonNegativeLong(), randomNonNegativeLong()) )); if (includeRestore) { builder.putCustom(RestoreInProgress.TYPE, diff --git a/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java b/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java index e563524437e59..e7f5e0b29c4a3 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java @@ -111,7 +111,7 @@ public void testConcurrentlyChangeRepositoryContents() throws Exception { .put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES))); logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshot(repoName, snapshot).get(); + client.admin().cluster().prepareDeleteSnapshots(repoName, new String[] {snapshot}).get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareGetSnapshots(repoName) @@ -185,7 +185,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS assertThat(getRepositoryData(repositoryAfterRestart).getGenId(), is(beforeMoveGen + 1)); logger.info("--> delete snapshot"); - client().admin().cluster().prepareDeleteSnapshot(repoName, snapshot).get(); + client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshot}).get(); logger.info("--> verify index-N blob is found at the expected location"); assertThat(getRepositoryData(repositoryAfterRestart).getGenId(), is(beforeMoveGen + 2)); @@ -247,7 +247,7 @@ public void testHandlingMissingRootLevelSnapshotMetadata() throws Exception { is(SnapshotsService.OLD_SNAPSHOT_FORMAT)); logger.info("--> verify that snapshot with missing root level metadata can be deleted"); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotToCorrupt.getName()).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[] {snapshotToCorrupt.getName()}).get()); logger.info("--> verify that repository is assumed in new metadata format after removing corrupted snapshot"); assertThat(PlainActionFuture.get(f -> threadPool.generic().execute( @@ -305,7 +305,7 @@ public void testMountCorruptedRepositoryData() throws Exception { private void assertRepositoryBlocked(Client client, String repo, String existingSnapshot) { logger.info("--> try to delete snapshot"); final RepositoryException repositoryException3 = expectThrows(RepositoryException.class, - () -> client.admin().cluster().prepareDeleteSnapshot(repo, existingSnapshot).execute().actionGet()); + () -> client.admin().cluster().prepareDeleteSnapshots(repo, new String[]{existingSnapshot}).execute().actionGet()); assertThat(repositoryException3.getMessage(), containsString("Could not read repository data because the contents of the repository do not match its expected state.")); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java index 3392a5e5d78b7..d398dfdd16fb7 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java @@ -7,7 +7,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.ClusterState; @@ -49,8 +49,8 @@ void performDuringNoSnapshot(IndexMetadata indexMetadata, ClusterState currentCl listener.onResponse(true); return; } - DeleteSnapshotRequest deleteSnapshotRequest = new DeleteSnapshotRequest(repositoryName, snapshotName); - getClient().admin().cluster().deleteSnapshot(deleteSnapshotRequest, new ActionListener<>() { + DeleteSnapshotsRequest deleteSnapshotRequest = new DeleteSnapshotsRequest(repositoryName, snapshotName); + getClient().admin().cluster().deleteSnapshots(deleteSnapshotRequest, new ActionListener<>() { @Override public void onResponse(AcknowledgedResponse acknowledgedResponse) { diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStepTests.java index 3d925f012ba24..effa15f0f3bae 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStepTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotAction; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.Metadata; @@ -21,7 +21,7 @@ import java.util.Map; import static org.elasticsearch.xpack.core.ilm.AbstractStepMasterTimeoutTestCase.emptyClusterState; -import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.is; public class CleanupSnapshotStepTests extends AbstractStepTestCase { @@ -148,8 +148,8 @@ protected void Request request, ActionListener listener) { assertThat(action.name(), is(DeleteSnapshotAction.NAME)); - assertTrue(request instanceof DeleteSnapshotRequest); - assertThat(((DeleteSnapshotRequest) request).snapshot(), equalTo(expectedSnapshotName)); + assertTrue(request instanceof DeleteSnapshotsRequest); + assertThat(((DeleteSnapshotsRequest) request).snapshots(), arrayContaining(expectedSnapshotName)); } }; } diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java index 823f86627a9c7..ef97388a28594 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java @@ -439,7 +439,7 @@ public void testSLMRetentionAfterRestore() throws Exception { // Cancel/delete the snapshot try { - client().admin().cluster().prepareDeleteSnapshot(REPO, snapshotName).get(); + client().admin().cluster().prepareDeleteSnapshots(REPO, new String[]{snapshotName}).get(); } catch (SnapshotMissingException e) { // ignore } diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java index c181f9b8c075e..139d0cd493e2a 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; @@ -354,7 +354,8 @@ public void testOkToDeleteSnapshots() { assertThat(SnapshotRetentionTask.okayToDeleteSnapshots(state), equalTo(false)); SnapshotDeletionsInProgress delInProgress = new SnapshotDeletionsInProgress( - Collections.singletonList(new SnapshotDeletionsInProgress.Entry(snapshot, 0, 0))); + Collections.singletonList(new SnapshotDeletionsInProgress.Entry( + Collections.singletonList(snapshot.getSnapshotId()), snapshot.getRepository(), 0, 0))); state = ClusterState.builder(new ClusterName("cluster")) .putCustom(SnapshotDeletionsInProgress.TYPE, delInProgress) .build(); @@ -447,7 +448,7 @@ public void testErrStillRunsFailureHandlerWhenDeleting() throws Exception { @SuppressWarnings("unchecked") protected void doExecute(ActionType action, Request request, ActionListener listener) { - if (request instanceof DeleteSnapshotRequest) { + if (request instanceof DeleteSnapshotsRequest) { logger.info("--> called"); listener.onResponse((Response) new AcknowledgedResponse(true)); } else { From b4123baeabdb86934b2be2414b0e55963ea446ae Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 16:42:15 +0200 Subject: [PATCH 14/45] dead code --- .../repositories/blobstore/BlobStoreRepository.java | 9 --------- 1 file changed, 9 deletions(-) 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 e953078076768..ec61216f9a714 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -105,7 +105,6 @@ import org.elasticsearch.repositories.RepositoryStats; import org.elasticsearch.repositories.RepositoryVerificationException; import org.elasticsearch.repositories.ShardGenerations; -import org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException; import org.elasticsearch.snapshots.SnapshotException; import org.elasticsearch.snapshots.SnapshotId; import org.elasticsearch.snapshots.SnapshotInfo; @@ -495,14 +494,6 @@ public void deleteSnapshot(Collection snapshotIds, long repositorySt if (isReadOnly()) { listener.onFailure(new RepositoryException(metadata.name(), "cannot delete snapshot from a readonly repository")); } else { - final long latestKnownGen = latestKnownRepoGen.get(); - if (latestKnownGen > repositoryStateId) { - // TODO: Nicer exception - listener.onFailure(new ConcurrentSnapshotExecutionException( - metadata.name(), snapshotIds.toString(), "Another concurrent operation moved repo generation to [ " + latestKnownGen - + "] but this delete assumed generation [" + repositoryStateId + "]")); - return; - } try { final Map rootBlobs = blobContainer().listBlobs(); final RepositoryData repositoryData = safeRepositoryData(repositoryStateId, rootBlobs); From 75d2eef25efc8702fb45a43c5cfe18241469c686 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 17:22:57 +0200 Subject: [PATCH 15/45] mroe stuff --- .../repositories/s3/S3Repository.java | 4 +- .../repositories/FilterRepository.java | 6 +- .../repositories/Repository.java | 4 +- .../blobstore/BlobStoreRepository.java | 4 +- .../repositories/blobstore/package-info.java | 2 +- .../snapshots/SnapshotsService.java | 77 ++++++++++++------- .../elasticsearch/snapshots/package-info.java | 2 +- .../RepositoriesServiceTests.java | 4 +- .../index/shard/RestoreOnlyRepository.java | 4 +- .../xpack/ccr/repository/CcrRepository.java | 4 +- 10 files changed, 68 insertions(+), 43 deletions(-) diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java index 1ed588914b8bc..dec06be79be0d 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java @@ -249,12 +249,12 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera } @Override - public void deleteSnapshot(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, + public void deleteSnapshots(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, ActionListener listener) { if (SnapshotsService.useShardGenerations(repositoryMetaVersion) == false) { listener = delayedListener(listener); } - super.deleteSnapshot(snapshotIds, repositoryStateId, repositoryMetaVersion, listener); + super.deleteSnapshots(snapshotIds, repositoryStateId, repositoryMetaVersion, listener); } /** diff --git a/server/src/main/java/org/elasticsearch/repositories/FilterRepository.java b/server/src/main/java/org/elasticsearch/repositories/FilterRepository.java index 10b9f15fa49bf..fc57ddebdb08a 100644 --- a/server/src/main/java/org/elasticsearch/repositories/FilterRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/FilterRepository.java @@ -86,9 +86,9 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera } @Override - public void deleteSnapshot(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, - ActionListener listener) { - in.deleteSnapshot(snapshotIds, repositoryStateId, repositoryMetaVersion, listener); + public void deleteSnapshots(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, + ActionListener listener) { + in.deleteSnapshots(snapshotIds, repositoryStateId, repositoryMetaVersion, listener); } @Override diff --git a/server/src/main/java/org/elasticsearch/repositories/Repository.java b/server/src/main/java/org/elasticsearch/repositories/Repository.java index 5cd3d80cb8042..8d1f70714d14a 100644 --- a/server/src/main/java/org/elasticsearch/repositories/Repository.java +++ b/server/src/main/java/org/elasticsearch/repositories/Repository.java @@ -145,8 +145,8 @@ void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenerations, * @param repositoryMetaVersion version of the updated repository metadata to write * @param listener completion listener */ - void deleteSnapshot(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, - ActionListener listener); + void deleteSnapshots(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, + ActionListener listener); /** * Returns snapshot throttle time in nanoseconds */ 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 ec61216f9a714..a237f68918789 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -489,8 +489,8 @@ public RepositoryStats stats() { } @Override - public void deleteSnapshot(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, - ActionListener listener) { + public void deleteSnapshots(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, + ActionListener listener) { if (isReadOnly()) { listener.onFailure(new RepositoryException(metadata.name(), "cannot delete snapshot from a readonly repository")); } else { diff --git a/server/src/main/java/org/elasticsearch/repositories/blobstore/package-info.java b/server/src/main/java/org/elasticsearch/repositories/blobstore/package-info.java index 5adf213b62970..a72c86b4bdde4 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/package-info.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/package-info.java @@ -201,7 +201,7 @@ *

Deleting a Snapshot

* *

Deleting a snapshot is an operation that is exclusively executed on the master node that runs through the following sequence of - * action when {@link org.elasticsearch.repositories.blobstore.BlobStoreRepository#deleteSnapshot} is invoked:

+ * action when {@link org.elasticsearch.repositories.blobstore.BlobStoreRepository#deleteSnapshots} is invoked:

* *
    *
  1. Get the current {@code RepositoryData} from the latest {@code index-N} blob at the repository root.
  2. diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index 1cfa62e92c466..944762186ecc8 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -88,6 +88,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -607,7 +608,7 @@ private void finalizeSnapshotDeletionFromPreviousMaster(ClusterState state) { if (deletionsInProgress != null && deletionsInProgress.hasDeletionsInProgress()) { assert deletionsInProgress.getEntries().size() == 1 : "only one in-progress deletion allowed per cluster"; SnapshotDeletionsInProgress.Entry entry = deletionsInProgress.getEntries().get(0); - deleteSnapshotFromRepository(entry.repository(), entry.getSnapshots(), null, entry.repositoryStateId(), + deleteSnapshotsFromRepository(entry.repository(), entry.getSnapshots(), null, entry.repositoryStateId(), state.nodes().getMinNodeVersion()); } } @@ -991,7 +992,7 @@ private void failSnapshotCompletionListeners(Snapshot snapshot, Exception e) { * Deletes a snapshot from the repository or aborts a running snapshot. * First checks if the snapshot is still running and if so cancels the snapshot and then deletes it from the repository. * If the snapshot is not running, moves to trying to find a matching {@link Snapshot} for the given name in the repository and if - * one is found deletes it by invoking {@link #deleteCompletedSnapshot}. + * one is found deletes it by invoking {@link #deleteCompletedSnapshots}. * * @param repositoryName repositoryName * @param snapshotNames snapshotNames @@ -1078,20 +1079,9 @@ public void onFailure(String source, Exception e) { public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { if (runningSnapshot == null) { threadPool.generic().execute(ActionRunnable.wrap(listener, l -> - repositoriesService.repository(repositoryName).getRepositoryData( - ActionListener.wrap(repositoryData -> { - final String[] snapshotNamePatterns = snapshotNames.toArray(Strings.EMPTY_ARRAY); - List matchedEntry = repositoryData.getSnapshotIds() - .stream() - .filter(s -> Regex.simpleMatch(snapshotNamePatterns, s.getName())) - .collect(Collectors.toList()); - // If we can't find the snapshot by the given name in the repository at all or if the snapshot we find in - // the repository is not the one we expected to find when waiting for a finishing snapshot we fail. - if (matchedEntry.isEmpty() == false) { - deleteCompletedSnapshot(matchedEntry, repositoryName, repositoryData.getGenId(), Priority.NORMAL, l); - } else { - l.onFailure(new SnapshotMissingException(repositoryName, snapshotNames.toString())); - } + repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> { + final List foundSnapshots = matchingSnapshotIds(repositoryData, snapshotNames, repositoryName); + deleteCompletedSnapshots(foundSnapshots, repositoryName, repositoryData.getGenId(), Priority.NORMAL, l); }, l::onFailure)))); return; } @@ -1099,14 +1089,25 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS addListener(runningSnapshot, ActionListener.wrap( result -> { logger.debug("deleted snapshot completed - deleting files"); - // TODO: resolve other snapshots as well - deleteCompletedSnapshot(Collections.singletonList(result.v2().snapshotId()), repositoryName, - result.v1().getGenId(), Priority.IMMEDIATE, listener); + final List foundSnapshots = matchingSnapshotIds(result.v1(), snapshotNames, repositoryName); + assert foundSnapshots.contains(runningSnapshot.getSnapshotId()) : "Expected new RepositoryData to contain [" + + runningSnapshot + "] but it only contained snapshots " + result.v1().getSnapshotIds(); + deleteCompletedSnapshots(foundSnapshots, repositoryName, result.v1().getGenId(), Priority.IMMEDIATE, listener); }, e -> { if (abortedDuringInit) { logger.info("Successfully aborted snapshot [{}]", runningSnapshot); - listener.onResponse(null); + final Collection remainingPatterns = snapshotNames.stream() + .filter(name -> runningSnapshot.getSnapshotId().getName().equals(name)).collect(Collectors.toList()); + if (remainingPatterns.isEmpty()) { + listener.onResponse(null); + return; + } + threadPool.generic().execute(ActionRunnable.wrap(listener, l -> + repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> + deleteCompletedSnapshots( + matchingSnapshotIds(repositoryData, remainingPatterns, repositoryName), repositoryName, + repositoryData.getGenId(), Priority.NORMAL, l), l::onFailure)))); } else { if (ExceptionsHelper.unwrap(e, NotMasterException.class, FailedToCommitClusterStateException.class) != null) { @@ -1125,6 +1126,30 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS }); } + private static List matchingSnapshotIds(RepositoryData repositoryData, Collection snapshotsOrPatterns, + String repositoryName) { + final Map allSnapshotIds = repositoryData.getSnapshotIds().stream().collect( + Collectors.toMap(SnapshotId::getName, Function.identity())); + final List foundSnapshots = new ArrayList<>(); + for (String snapshotOrPattern : snapshotsOrPatterns) { + if (Regex.isSimpleMatchPattern(snapshotOrPattern) == false) { + final SnapshotId foundId = allSnapshotIds.get(snapshotOrPattern); + if (foundId == null) { + throw new SnapshotMissingException(repositoryName, snapshotOrPattern); + } else { + foundSnapshots.add(allSnapshotIds.get(snapshotOrPattern)); + } + } else { + for (Map.Entry entry : allSnapshotIds.entrySet()) { + if (Regex.simpleMatch(snapshotOrPattern, entry.getKey())) { + foundSnapshots.add(entry.getValue()); + } + } + } + } + return foundSnapshots; + } + // Return in-progress snapshot entry by name and repository in the given cluster state or null if none is found @Nullable private static SnapshotsInProgress.Entry findInProgressSnapshot(@Nullable SnapshotsInProgress snapshots, @@ -1154,8 +1179,8 @@ private static SnapshotsInProgress.Entry findInProgressSnapshot(@Nullable Snapsh * @param repositoryStateId Repository generation to base the delete on * @param listener Listener to complete when done */ - private void deleteCompletedSnapshot(List snapshotIds, String repoName, long repositoryStateId, Priority priority, - ActionListener listener) { + private void deleteCompletedSnapshots(List snapshotIds, String repoName, long repositoryStateId, Priority priority, + ActionListener listener) { logger.debug("deleting snapshots {} assuming repository generation [{}] and with priority [{}]", snapshotIds, repositoryStateId, priority); clusterService.submitStateUpdateTask("delete snapshot", new ClusterStateUpdateTask(priority) { @@ -1212,7 +1237,7 @@ public void onFailure(String source, Exception e) { @Override public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { - deleteSnapshotFromRepository(repoName, snapshotIds, listener, repositoryStateId, newState.nodes().getMinNodeVersion()); + deleteSnapshotsFromRepository(repoName, snapshotIds, listener, repositoryStateId, newState.nodes().getMinNodeVersion()); } }); } @@ -1280,11 +1305,11 @@ public static boolean useShardGenerations(Version repositoryMetaVersion) { * @param repositoryStateId the unique id representing the state of the repository at the time the deletion began * @param minNodeVersion minimum node version in the cluster */ - private void deleteSnapshotFromRepository(String repoName, Collection snapshotIds, @Nullable ActionListener listener, - long repositoryStateId, Version minNodeVersion) { + private void deleteSnapshotsFromRepository(String repoName, Collection snapshotIds, @Nullable ActionListener listener, + long repositoryStateId, Version minNodeVersion) { threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(ActionRunnable.wrap(listener, l -> { Repository repository = repositoriesService.repository(repoName); - repository.getRepositoryData(ActionListener.wrap(repositoryData -> repository.deleteSnapshot(snapshotIds, + repository.getRepositoryData(ActionListener.wrap(repositoryData -> repository.deleteSnapshots(snapshotIds, repositoryStateId, minCompatibleVersion(minNodeVersion, repoName, repositoryData, snapshotIds), ActionListener.wrap(v -> { diff --git a/server/src/main/java/org/elasticsearch/snapshots/package-info.java b/server/src/main/java/org/elasticsearch/snapshots/package-info.java index 010e63eae6b4f..d4a31ad41352c 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/package-info.java +++ b/server/src/main/java/org/elasticsearch/snapshots/package-info.java @@ -97,7 +97,7 @@ * {@link org.elasticsearch.cluster.SnapshotDeletionsInProgress}. * *
  3. Once the cluster state contains the deletion entry in {@code SnapshotDeletionsInProgress} the {@code SnapshotsService} will invoke - * {@link org.elasticsearch.repositories.Repository#deleteSnapshot} for the given snapshot, which will remove files associated with the + * {@link org.elasticsearch.repositories.Repository#deleteSnapshots} for the given snapshot, which will remove files associated with the * snapshot from the repository as well as update its meta-data to reflect the deletion of the snapshot.
  4. * *
  5. After the deletion of the snapshot's data from the repository finishes, the {@code SnapshotsService} will submit a cluster state diff --git a/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java b/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java index d3d32a68af7f1..a6de9a19c6119 100644 --- a/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java @@ -166,8 +166,8 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations indices, lo } @Override - public void deleteSnapshot(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, - ActionListener listener) { + public void deleteSnapshots(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, + ActionListener listener) { listener.onResponse(null); } diff --git a/test/framework/src/main/java/org/elasticsearch/index/shard/RestoreOnlyRepository.java b/test/framework/src/main/java/org/elasticsearch/index/shard/RestoreOnlyRepository.java index 56f5d286ba354..2679d785a4e38 100644 --- a/test/framework/src/main/java/org/elasticsearch/index/shard/RestoreOnlyRepository.java +++ b/test/framework/src/main/java/org/elasticsearch/index/shard/RestoreOnlyRepository.java @@ -104,8 +104,8 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera } @Override - public void deleteSnapshot(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, - ActionListener listener) { + public void deleteSnapshots(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, + ActionListener listener) { listener.onResponse(null); } diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java index ec282a8fba07e..2dbf0c907ebd9 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java @@ -260,8 +260,8 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera } @Override - public void deleteSnapshot(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, - ActionListener listener) { + public void deleteSnapshots(Collection snapshotIds, long repositoryStateId, Version repositoryMetaVersion, + ActionListener listener) { throw new UnsupportedOperationException("Unsupported for repository of type: " + TYPE); } From 4f5ff303c946d6e0e8a53bcc5d41f9da7ccf1695 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 17:46:50 +0200 Subject: [PATCH 16/45] fixes --- .../snapshots/SnapshotsService.java | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index 944762186ecc8..7cb92d8257f2a 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -1078,11 +1078,7 @@ public void onFailure(String source, Exception e) { @Override public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { if (runningSnapshot == null) { - threadPool.generic().execute(ActionRunnable.wrap(listener, l -> - repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> { - final List foundSnapshots = matchingSnapshotIds(repositoryData, snapshotNames, repositoryName); - deleteCompletedSnapshots(foundSnapshots, repositoryName, repositoryData.getGenId(), Priority.NORMAL, l); - }, l::onFailure)))); + resolveAndDeleteSnapshots(snapshotNames, listener, repositoryName); return; } logger.trace("adding snapshot completion listener to wait for deleted snapshot to finish"); @@ -1103,11 +1099,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS listener.onResponse(null); return; } - threadPool.generic().execute(ActionRunnable.wrap(listener, l -> - repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> - deleteCompletedSnapshots( - matchingSnapshotIds(repositoryData, remainingPatterns, repositoryName), repositoryName, - repositoryData.getGenId(), Priority.NORMAL, l), l::onFailure)))); + resolveAndDeleteSnapshots(remainingPatterns, listener, repositoryName); } else { if (ExceptionsHelper.unwrap(e, NotMasterException.class, FailedToCommitClusterStateException.class) != null) { @@ -1126,6 +1118,13 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS }); } + private void resolveAndDeleteSnapshots(Collection snapshotsOrPatterns, ActionListener listener, String repositoryName) { + threadPool.generic().execute(ActionRunnable.wrap(listener, l -> + repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> + deleteCompletedSnapshots(matchingSnapshotIds(repositoryData, snapshotsOrPatterns, repositoryName), repositoryName, + repositoryData.getGenId(), Priority.NORMAL, l), l::onFailure)))); + } + private static List matchingSnapshotIds(RepositoryData repositoryData, Collection snapshotsOrPatterns, String repositoryName) { final Map allSnapshotIds = repositoryData.getSnapshotIds().stream().collect( @@ -1157,14 +1156,11 @@ private static SnapshotsInProgress.Entry findInProgressSnapshot(@Nullable Snapsh if (snapshots == null) { return null; } - for (String snapshotName : snapshotNames) { - for (SnapshotsInProgress.Entry entry : snapshots.entries()) { - if (entry.repository().equals(repositoryName)) { - if (Regex.isSimpleMatchPattern(snapshotName) && entry.snapshot().getSnapshotId().getName().equals(snapshotName)) { - return entry; - } else if (Regex.simpleMatch(snapshotName, entry.snapshot().getSnapshotId().getName())) { - return entry; - } + final String[] snapshotsOrPatterns = snapshotNames.toArray(Strings.EMPTY_ARRAY); + for (SnapshotsInProgress.Entry entry : snapshots.entries()) { + if (entry.repository().equals(repositoryName)) { + if (Regex.simpleMatch(snapshotsOrPatterns, entry.snapshot().getSnapshotId().getName())) { + return entry; } } } @@ -1259,8 +1255,8 @@ public Version minCompatibleVersion(Version minNodeVersion, String repositoryNam Version minCompatVersion = minNodeVersion; final Collection snapshotIds = repositoryData.getSnapshotIds(); final Repository repository = repositoriesService.repository(repositoryName); - for (SnapshotId snapshotId : - snapshotIds.stream().filter(snapshotId -> excluded.contains(snapshotId) == false).collect(Collectors.toList())) { + for (SnapshotId snapshotId : snapshotIds.stream().filter(snapshotId -> excluded == null || excluded.contains(snapshotId) == false) + .collect(Collectors.toList())) { final Version known = repositoryData.getVersion(snapshotId); // If we don't have the version cached in the repository data yet we load it from the snapshot info blobs if (known == null) { From bf170bfb5836c4d33f68b1691c0eacd6f8385628 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 17:54:48 +0200 Subject: [PATCH 17/45] nicer --- .../snapshots/delete/TransportDeleteSnapshotAction.java | 2 +- .../java/org/elasticsearch/snapshots/SnapshotsService.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java index 709c5749dd8a3..1a9e5305893dc 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java @@ -72,7 +72,7 @@ protected ClusterBlockException checkBlock(DeleteSnapshotsRequest request, Clust @Override protected void masterOperation(Task task, final DeleteSnapshotsRequest request, ClusterState state, final ActionListener listener) { - snapshotsService.deleteSnapshot(request.repository(), Arrays.asList(request.snapshots()), + snapshotsService.deleteSnapshots(request.repository(), Arrays.asList(request.snapshots()), ActionListener.map(listener, v -> new AcknowledgedResponse(true))); } } diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index 7cb92d8257f2a..ccee829c88c24 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -998,7 +998,7 @@ private void failSnapshotCompletionListeners(Snapshot snapshot, Exception e) { * @param snapshotNames snapshotNames * @param listener listener */ - public void deleteSnapshot(final String repositoryName, final Collection snapshotNames, final ActionListener listener) { + public void deleteSnapshots(final String repositoryName, final Collection snapshotNames, final ActionListener listener) { logger.info("deleting snapshots {} from repository [{}]", snapshotNames, repositoryName); clusterService.submitStateUpdateTask("delete snapshot", new ClusterStateUpdateTask(Priority.NORMAL) { @@ -1168,7 +1168,7 @@ private static SnapshotsInProgress.Entry findInProgressSnapshot(@Nullable Snapsh } /** - * Deletes a snapshot that is assumed to be in the repository and not tracked as in-progress in the cluster state. + * Deletes snapshots that are assumed to be in the repository and not tracked as in-progress in the cluster state. * * @param snapshotIds Snapshots to delete * @param repoName Repository name @@ -1190,7 +1190,7 @@ public ClusterState execute(ClusterState currentState) { final RepositoryCleanupInProgress repositoryCleanupInProgress = currentState.custom(RepositoryCleanupInProgress.TYPE); if (repositoryCleanupInProgress != null && repositoryCleanupInProgress.hasCleanupInProgress()) { throw new ConcurrentSnapshotExecutionException(repoName, snapshotIds.toString(), - "cannot delete snapshot while a repository cleanup is in-progress in [" + repositoryCleanupInProgress + "]"); + "cannot delete snapshots while a repository cleanup is in-progress in [" + repositoryCleanupInProgress + "]"); } RestoreInProgress restoreInProgress = currentState.custom(RestoreInProgress.TYPE); if (restoreInProgress != null) { From 21bc7564d53c50ec8784a7ba342722380f7d460f Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 18:43:34 +0200 Subject: [PATCH 18/45] works better --- .../repositories/RepositoryData.java | 17 +++++++---------- .../blobstore/BlobStoreRepository.java | 8 ++++---- .../snapshots/SnapshotsService.java | 14 +++++++++----- .../repositories/RepositoryDataTests.java | 2 +- .../blobstore/BlobStoreRepositoryTests.java | 2 +- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java b/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java index c235c294d1270..dc0e88938dd84 100644 --- a/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java +++ b/server/src/main/java/org/elasticsearch/repositories/RepositoryData.java @@ -188,12 +188,8 @@ public List indicesToUpdateAfterRemovingSnapshot(Collection return indexSnapshots.entrySet().stream() .filter(entry -> { final Collection existingIds = entry.getValue(); - final boolean containsAll = existingIds.containsAll(snapshotIds); - if (containsAll && existingIds.size() > snapshotIds.size()) { - return true; - } if (snapshotIds.containsAll(existingIds)) { - return false; + return existingIds.size() > snapshotIds.size(); } for (SnapshotId snapshotId : snapshotIds) { if (entry.getValue().contains(snapshotId)) { @@ -201,8 +197,7 @@ public List indicesToUpdateAfterRemovingSnapshot(Collection } } return false; - }).map(Map.Entry::getKey) - .collect(Collectors.toList()); + }).map(Map.Entry::getKey).collect(Collectors.toList()); } /** @@ -260,14 +255,14 @@ public RepositoryData withGenId(long newGeneration) { } /** - * Remove a snapshot and remove any indices that no longer exist in the repository due to the deletion of the snapshot. + * Remove snapshots and remove any indices that no longer exist in the repository due to the deletion of the snapshots. * * @param snapshots Snapshot ids to remove * @param updatedShardGenerations Shard generations that changed as a result of removing the snapshot. * The {@code String[]} passed for each {@link IndexId} contains the new shard generation id for each * changed shard indexed by its shardId */ - public RepositoryData removeSnapshot(final Collection snapshots, final ShardGenerations updatedShardGenerations) { + public RepositoryData removeSnapshots(final Collection snapshots, final ShardGenerations updatedShardGenerations) { Map newSnapshotIds = snapshotIds.values().stream().filter(Predicate.not(snapshots::contains)) .collect(Collectors.toMap(SnapshotId::getUUID, Function.identity())); if (newSnapshotIds.size() != snapshotIds.size() - snapshots.size()) { @@ -291,7 +286,9 @@ public RepositoryData removeSnapshot(final Collection snapshots, fin } else { remaining = snapshotIds; } - indexSnapshots.put(indexId, remaining); + if (remaining.isEmpty() == false) { + indexSnapshots.put(indexId, remaining); + } } return new RepositoryData(genId, newSnapshotIds, newSnapshotStates, newSnapshotVersions, indexSnapshots, 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 a237f68918789..da4701ecb17b1 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -565,8 +565,8 @@ private void doDeleteShardSnapshots(Collection snapshotIds, long rep final StepListener> writeShardMetaDataAndComputeDeletesStep = new StepListener<>(); writeUpdatedShardMetaDataAndComputeDeletes(snapshotIds, repositoryData, true, writeShardMetaDataAndComputeDeletesStep); // Once we have put the new shard-level metadata into place, we can update the repository metadata as follows: - // 1. Remove the snapshot from the list of existing snapshots - // 2. Update the inShardSnapshotMetaDeleteResultdex shard generations of all updated shard folders + // 1. Remove the snapshots from the list of existing snapshots + // 2. Update the index shard generations of all updated shard folders // // Note: If we fail updating any of the individual shard paths, none of them are changed since the newly created // index-${gen_uuid} will not be referenced by the existing RepositoryData and new RepositoryData is only @@ -577,7 +577,7 @@ private void doDeleteShardSnapshots(Collection snapshotIds, long rep for (ShardSnapshotMetaDeleteResult newGen : deleteResults) { builder.put(newGen.indexId, newGen.shardId, newGen.newGeneration); } - final RepositoryData updatedRepoData = repositoryData.removeSnapshot(snapshotIds, builder.build()); + final RepositoryData updatedRepoData = repositoryData.removeSnapshots(snapshotIds, builder.build()); writeIndexGen(updatedRepoData, repositoryStateId, true, ActionListener.wrap(v -> writeUpdatedRepoDataStep.onResponse(updatedRepoData), listener::onFailure)); }, listener::onFailure); @@ -591,7 +591,7 @@ private void doDeleteShardSnapshots(Collection snapshotIds, long rep }, listener::onFailure); } else { // Write the new repository data first (with the removed snapshot), using no shard generations - final RepositoryData updatedRepoData = repositoryData.removeSnapshot(snapshotIds, ShardGenerations.EMPTY); + final RepositoryData updatedRepoData = repositoryData.removeSnapshots(snapshotIds, ShardGenerations.EMPTY); writeIndexGen(updatedRepoData, repositoryStateId, false, ActionListener.wrap(v -> { // Run unreferenced blobs cleanup in parallel to shard-level snapshot deletion final ActionListener afterCleanupsListener = diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index ccee829c88c24..e0af2f483c991 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -1093,8 +1093,8 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS e -> { if (abortedDuringInit) { logger.info("Successfully aborted snapshot [{}]", runningSnapshot); - final Collection remainingPatterns = snapshotNames.stream() - .filter(name -> runningSnapshot.getSnapshotId().getName().equals(name)).collect(Collectors.toList()); + final Collection remainingPatterns = new ArrayList<>(snapshotNames); + remainingPatterns.remove(runningSnapshot.getSnapshotId().getName()); if (remainingPatterns.isEmpty()) { listener.onResponse(null); return; @@ -1177,6 +1177,10 @@ private static SnapshotsInProgress.Entry findInProgressSnapshot(@Nullable Snapsh */ private void deleteCompletedSnapshots(List snapshotIds, String repoName, long repositoryStateId, Priority priority, ActionListener listener) { + if (snapshotIds.isEmpty()) { + listener.onResponse(null); + return; + } logger.debug("deleting snapshots {} assuming repository generation [{}] and with priority [{}]", snapshotIds, repositoryStateId, priority); clusterService.submitStateUpdateTask("delete snapshot", new ClusterStateUpdateTask(priority) { @@ -1184,12 +1188,12 @@ private void deleteCompletedSnapshots(List snapshotIds, String repoN public ClusterState execute(ClusterState currentState) { SnapshotDeletionsInProgress deletionsInProgress = currentState.custom(SnapshotDeletionsInProgress.TYPE); if (deletionsInProgress != null && deletionsInProgress.hasDeletionsInProgress()) { - throw new ConcurrentSnapshotExecutionException(repoName, snapshotIds.toString(), + throw new ConcurrentSnapshotExecutionException(new Snapshot(repoName, snapshotIds.get(0)), "cannot delete - another snapshot is currently being deleted in [" + deletionsInProgress + "]"); } final RepositoryCleanupInProgress repositoryCleanupInProgress = currentState.custom(RepositoryCleanupInProgress.TYPE); if (repositoryCleanupInProgress != null && repositoryCleanupInProgress.hasCleanupInProgress()) { - throw new ConcurrentSnapshotExecutionException(repoName, snapshotIds.toString(), + throw new ConcurrentSnapshotExecutionException(new Snapshot(repoName, snapshotIds.get(0)), "cannot delete snapshots while a repository cleanup is in-progress in [" + repositoryCleanupInProgress + "]"); } RestoreInProgress restoreInProgress = currentState.custom(RestoreInProgress.TYPE); @@ -1200,7 +1204,7 @@ public ClusterState execute(ClusterState currentState) { for (RestoreInProgress.Entry entry : restoreInProgress) { if (repoName.equals(entry.snapshot().getRepository()) && snapshotIds.contains(entry.snapshot().getSnapshotId())) { - throw new ConcurrentSnapshotExecutionException(repoName, snapshotIds.toString(), + throw new ConcurrentSnapshotExecutionException(new Snapshot(repoName, snapshotIds.get(0)), "cannot delete snapshot during a restore in progress in [" + restoreInProgress + "]"); } } diff --git a/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java b/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java index 1608eaad42537..ccdb2ffd0a07b 100644 --- a/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/RepositoryDataTests.java @@ -153,7 +153,7 @@ public void testRemoveSnapshot() { List snapshotIds = new ArrayList<>(repositoryData.getSnapshotIds()); assertThat(snapshotIds.size(), greaterThan(0)); SnapshotId removedSnapshotId = snapshotIds.remove(randomIntBetween(0, snapshotIds.size() - 1)); - RepositoryData newRepositoryData = repositoryData.removeSnapshot(Collections.singleton(removedSnapshotId), ShardGenerations.EMPTY); + RepositoryData newRepositoryData = repositoryData.removeSnapshots(Collections.singleton(removedSnapshotId), ShardGenerations.EMPTY); // make sure the repository data's indices no longer contain the removed snapshot for (final IndexId indexId : newRepositoryData.getIndices().values()) { assertFalse(newRepositoryData.getSnapshots(indexId).contains(removedSnapshotId)); diff --git a/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryTests.java b/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryTests.java index 619c3628ee2cf..13220410f21dc 100644 --- a/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryTests.java @@ -182,7 +182,7 @@ public void testIndexGenerationalFiles() throws Exception { assertThat(repository.readSnapshotIndexLatestBlob(), equalTo(expectedGeneration + 1L)); // removing a snapshot and writing to a new index generational file - repositoryData = ESBlobStoreRepositoryIntegTestCase.getRepositoryData(repository).removeSnapshot( + repositoryData = ESBlobStoreRepositoryIntegTestCase.getRepositoryData(repository).removeSnapshots( Collections.singleton(repositoryData.getSnapshotIds().iterator().next()), ShardGenerations.EMPTY); writeIndexGen(repository, repositoryData, repositoryData.getGenId()); assertEquals(ESBlobStoreRepositoryIntegTestCase.getRepositoryData(repository), repositoryData); From 841e0160e21aff90bdbdfb2156aaf514ac8135ee Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 18:46:48 +0200 Subject: [PATCH 19/45] simpler --- .../elasticsearch/client/SnapshotRequestConvertersTests.java | 2 +- .../admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java index 6bb5bfec903b5..c0c6e6e4a5990 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java @@ -269,7 +269,7 @@ public void testDeleteSnapshot() { DeleteSnapshotsRequest deleteSnapshotsRequest = new DeleteSnapshotsRequest(); deleteSnapshotsRequest.repository(repository); - deleteSnapshotsRequest.snapshots(new String[]{snapshot}); + deleteSnapshotsRequest.snapshots(snapshot); RequestConvertersTests.setRandomMasterTimeout(deleteSnapshotsRequest, expectedParams); Request request = SnapshotRequestConverters.deleteSnapshot(deleteSnapshotsRequest); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java index a4a24e486b873..024d72d4f5e15 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java @@ -144,7 +144,7 @@ public String[] snapshots() { * * @return this request */ - public DeleteSnapshotsRequest snapshots(String[] snapshots) { + public DeleteSnapshotsRequest snapshots(String... snapshots) { this.snapshots = snapshots; return this; } From 5cd97062e2e0493bec2a08b901ec1b5d07e54834 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 18:51:46 +0200 Subject: [PATCH 20/45] nicer --- .../src/main/java/org/elasticsearch/client/Requests.java | 8 ++++---- .../action/admin/cluster/RestDeleteSnapshotAction.java | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/client/Requests.java b/server/src/main/java/org/elasticsearch/client/Requests.java index 22c480339cf0e..817c5a64d12df 100644 --- a/server/src/main/java/org/elasticsearch/client/Requests.java +++ b/server/src/main/java/org/elasticsearch/client/Requests.java @@ -502,14 +502,14 @@ public static RestoreSnapshotRequest restoreSnapshotRequest(String repository, S } /** - * Deletes a snapshot + * Deletes snapshots * - * @param snapshot snapshot name + * @param snapshots snapshot names * @param repository repository name * @return delete snapshot request */ - public static DeleteSnapshotsRequest deleteSnapshotRequest(String repository, String snapshot) { - return new DeleteSnapshotsRequest(repository, new String[]{snapshot}); + public static DeleteSnapshotsRequest deleteSnapshotRequest(String repository, String[] snapshots) { + return new DeleteSnapshotsRequest(repository, snapshots); } /** diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java index 68c4ff052ed60..f0044a0f3ee2f 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java @@ -21,6 +21,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.common.Strings; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.action.RestToXContentListener; @@ -48,7 +49,8 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { - DeleteSnapshotsRequest deleteSnapshotsRequest = deleteSnapshotRequest(request.param("repository"), request.param("snapshot")); + DeleteSnapshotsRequest deleteSnapshotsRequest = deleteSnapshotRequest(request.param("repository"), + request.paramAsStringArray("snapshot", Strings.EMPTY_ARRAY)); deleteSnapshotsRequest.masterNodeTimeout(request.paramAsTime("master_timeout", deleteSnapshotsRequest.masterNodeTimeout())); return channel -> client.admin().cluster().deleteSnapshots(deleteSnapshotsRequest, new RestToXContentListener<>(channel)); } From 36dd5d51811a7eabfe015e1fba7742f72747a4d0 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 20:48:28 +0200 Subject: [PATCH 21/45] fixes --- .../blobstore/BlobStoreRepository.java | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) 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 da4701ecb17b1..abef4d6a63140 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -651,15 +651,33 @@ private void writeUpdatedShardMetaDataAndComputeDeletes(Collection s for (IndexId indexId : indices) { final Set survivingSnapshots = oldRepositoryData.getSnapshots(indexId).stream() .filter(id -> snapshotIds.contains(id) == false).collect(Collectors.toSet()); - executor.execute(ActionRunnable.wrap(deleteIndexMetadataListener, deleteIdxMetaListener -> { - final int shardCount = findMaxShardCount(snapshotIds, indexId); + final StepListener shardCountListener = new StepListener<>(); + final ActionListener shardCounts = new GroupedActionListener<>(ActionListener.wrap( + counts -> shardCountListener.onResponse(counts.stream().mapToInt(i -> i).max().orElse(0)), + shardCountListener::onFailure), snapshotIds.size()); + for (SnapshotId snapshotId : snapshotIds) { + executor.execute(ActionRunnable.supply(shardCounts, () -> { + try { + return getSnapshotIndexMetadata(snapshotId, indexId).getNumberOfShards(); + } catch (Exception ex) { + logger.warn(() -> new ParameterizedMessage( + "[{}] [{}] failed to read metadata for index", snapshotId, indexId.getName()), ex); + // Just invoke the listener without any shard generations to count it down, this index will be cleaned up + // by the stale data cleanup in the end. + // TODO: Getting here means repository corruption. We should find a way of dealing with this instead of just + // ignoring it and letting the cleanup deal with it. + return null; + } + })); + } + shardCountListener.whenComplete(shardCount -> { if (shardCount == 0) { - deleteIdxMetaListener.onResponse(null); + deleteIndexMetadataListener.onResponse(null); return; } // Listener for collecting the results of removing the snapshot from each shard's metadata in the current index final ActionListener allShardsListener = - new GroupedActionListener<>(deleteIdxMetaListener, shardCount); + new GroupedActionListener<>(deleteIndexMetadataListener, shardCount); for (int shardId = 0; shardId < shardCount; shardId++) { final int finalShardId = shardId; executor.execute(new AbstractRunnable() { @@ -672,44 +690,30 @@ protected void doRun() throws Exception { if (useUUIDs) { newGen = UUIDs.randomBase64UUID(); blobStoreIndexShardSnapshots = buildBlobStoreIndexShardSnapshots(blobs, shardContainer, - oldRepositoryData.shardGenerations().getShardGen(indexId, finalShardId)).v1(); + oldRepositoryData.shardGenerations().getShardGen(indexId, finalShardId)).v1(); } else { Tuple tuple = - buildBlobStoreIndexShardSnapshots(blobs, shardContainer); + buildBlobStoreIndexShardSnapshots(blobs, shardContainer); newGen = Long.toString(tuple.v2() + 1); blobStoreIndexShardSnapshots = tuple.v1(); } allShardsListener.onResponse(deleteFromShardSnapshotMeta(survivingSnapshots, indexId, finalShardId, - snapshotIds, shardContainer, blobs, blobStoreIndexShardSnapshots, newGen)); + snapshotIds, shardContainer, blobs, blobStoreIndexShardSnapshots, newGen)); } @Override public void onFailure(Exception ex) { logger.warn( - () -> new ParameterizedMessage("[{}] failed to delete shard data for shard [{}][{}]", - snapshotIds, indexId.getName(), finalShardId), ex); + () -> new ParameterizedMessage("[{}] failed to delete shard data for shard [{}][{}]", + snapshotIds, indexId.getName(), finalShardId), ex); // Just passing null here to count down the listener instead of failing it, the stale data left behind // here will be retried in the next delete or repository cleanup allShardsListener.onResponse(null); } }); } - })); - } - } - - private int findMaxShardCount(Collection snapshotIds, IndexId indexId) { - int maxShardCount = 0; - // TODO: parallelize this - for (SnapshotId snapshotId : snapshotIds) { - try { - maxShardCount = Math.max(maxShardCount, getSnapshotIndexMetadata(snapshotId, indexId).getNumberOfShards()); - } catch (Exception e) { - // TODO: Getting here means repository corruption. We should find a way of dealing with this instead of just ignoring - // it and letting the cleanup deal with it. - } + }, deleteIndexMetadataListener::onFailure); } - return maxShardCount; } private List resolveFilesToDelete(Collection snapshotIds, From 4b7f76b445519dbed96c10a53aeafd37a06c7dee Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 21:08:23 +0200 Subject: [PATCH 22/45] shorter diff --- .../elasticsearch/client/SnapshotClient.java | 14 +++++++------- .../client/SnapshotRequestConverters.java | 10 +++++----- .../org/elasticsearch/client/SnapshotIT.java | 6 +++--- .../client/SnapshotRequestConvertersTests.java | 12 ++++++------ .../SnapshotClientDocumentationIT.java | 6 +++--- .../MultiVersionRepositoryAccessIT.java | 4 ++-- ...Request.java => DeleteSnapshotRequest.java} | 18 +++++++++--------- .../delete/DeleteSnapshotRequestBuilder.java | 6 +++--- .../delete/TransportDeleteSnapshotAction.java | 8 ++++---- .../client/ClusterAdminClient.java | 6 +++--- .../org/elasticsearch/client/Requests.java | 6 +++--- .../client/support/AbstractClient.java | 6 +++--- .../cluster/RestDeleteSnapshotAction.java | 8 ++++---- .../snapshots/SnapshotResiliencyTests.java | 6 +++--- .../AbstractThirdPartyRepositoryTestCase.java | 4 ++-- .../xpack/core/ilm/CleanupSnapshotStep.java | 4 ++-- .../core/ilm/CleanupSnapshotStepTests.java | 6 +++--- .../xpack/slm/SnapshotRetentionTaskTests.java | 4 ++-- 18 files changed, 67 insertions(+), 67 deletions(-) rename server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/{DeleteSnapshotsRequest.java => DeleteSnapshotRequest.java} (86%) 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 e4221bb2737f2..134dc921c450d 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 @@ -30,7 +30,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.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; @@ -335,13 +335,13 @@ public Cancellable restoreAsync(RestoreSnapshotRequest restoreSnapshotRequest, R * See Snapshot and Restore * API on elastic.co * - * @param deleteSnapshotsRequest the request + * @param deleteSnapshotRequest the request * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized * @return the response * @throws IOException in case there is a problem sending the request or parsing back the response */ - public AcknowledgedResponse delete(DeleteSnapshotsRequest deleteSnapshotsRequest, RequestOptions options) throws IOException { - return restHighLevelClient.performRequestAndParseEntity(deleteSnapshotsRequest, + public AcknowledgedResponse delete(DeleteSnapshotRequest deleteSnapshotRequest, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(deleteSnapshotRequest, SnapshotRequestConverters::deleteSnapshot, options, AcknowledgedResponse::fromXContent, emptySet()); } @@ -351,14 +351,14 @@ public AcknowledgedResponse delete(DeleteSnapshotsRequest deleteSnapshotsRequest * See Snapshot and Restore * API on elastic.co * - * @param deleteSnapshotsRequest the request + * @param deleteSnapshotRequest the request * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized * @param listener the listener to be notified upon request completion * @return cancellable that may be used to cancel the request */ - public Cancellable deleteAsync(DeleteSnapshotsRequest deleteSnapshotsRequest, RequestOptions options, + public Cancellable deleteAsync(DeleteSnapshotRequest deleteSnapshotRequest, RequestOptions options, ActionListener listener) { - return restHighLevelClient.performRequestAsyncAndParseEntity(deleteSnapshotsRequest, + return restHighLevelClient.performRequestAsyncAndParseEntity(deleteSnapshotRequest, SnapshotRequestConverters::deleteSnapshot, options, AcknowledgedResponse::fromXContent, listener, emptySet()); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java index e5ffe037eba96..239fa06d14add 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java @@ -29,7 +29,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.snapshots.create.CreateSnapshotRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; @@ -173,15 +173,15 @@ static Request restoreSnapshot(RestoreSnapshotRequest restoreSnapshotRequest) th return request; } - static Request deleteSnapshot(DeleteSnapshotsRequest deleteSnapshotsRequest) { + static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) { String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_snapshot") - .addPathPart(deleteSnapshotsRequest.repository()) - .addCommaSeparatedPathParts(deleteSnapshotsRequest.snapshots()) + .addPathPart(deleteSnapshotRequest.repository()) + .addCommaSeparatedPathParts(deleteSnapshotRequest.snapshots()) .build(); Request request = new Request(HttpDelete.METHOD_NAME, endpoint); RequestConverters.Params parameters = new RequestConverters.Params(); - parameters.withMasterTimeout(deleteSnapshotsRequest.masterNodeTimeout()); + parameters.withMasterTimeout(deleteSnapshotRequest.masterNodeTimeout()); request.addParameters(parameters.asMap()); return request; } 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 4447ad55baebf..9415ef06bfafb 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,7 +30,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.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; @@ -165,7 +165,7 @@ public void testCreateSnapshot() throws Exception { if (waitForCompletion == false) { // If we don't wait for the snapshot to complete we have to cancel it to not leak the snapshot task AcknowledgedResponse deleteResponse = execute( - new DeleteSnapshotsRequest(repository, snapshot), + new DeleteSnapshotRequest(repository, snapshot), highLevelClient().snapshot()::delete, highLevelClient().snapshot()::deleteAsync ); assertTrue(deleteResponse.isAcknowledged()); @@ -301,7 +301,7 @@ public void testDeleteSnapshot() throws IOException { // check that the request went ok without parsing JSON here. When using the high level client, check acknowledgement instead. assertEquals(RestStatus.OK, createSnapshotResponse.status()); - DeleteSnapshotsRequest request = new DeleteSnapshotsRequest(repository, snapshot); + DeleteSnapshotRequest request = new DeleteSnapshotRequest(repository, snapshot); AcknowledgedResponse response = execute(request, highLevelClient().snapshot()::delete, highLevelClient().snapshot()::deleteAsync); assertTrue(response.isAcknowledged()); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java index c0c6e6e4a5990..e7ee97c4df247 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java @@ -28,7 +28,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.snapshots.create.CreateSnapshotRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; @@ -267,12 +267,12 @@ public void testDeleteSnapshot() { String endpoint = String.format(Locale.ROOT, "/_snapshot/%s/%s", repository, snapshot); - DeleteSnapshotsRequest deleteSnapshotsRequest = new DeleteSnapshotsRequest(); - deleteSnapshotsRequest.repository(repository); - deleteSnapshotsRequest.snapshots(snapshot); - RequestConvertersTests.setRandomMasterTimeout(deleteSnapshotsRequest, expectedParams); + DeleteSnapshotRequest deleteSnapshotRequest = new DeleteSnapshotRequest(); + deleteSnapshotRequest.repository(repository); + deleteSnapshotRequest.snapshots(snapshot); + RequestConvertersTests.setRandomMasterTimeout(deleteSnapshotRequest, expectedParams); - Request request = SnapshotRequestConverters.deleteSnapshot(deleteSnapshotsRequest); + Request request = SnapshotRequestConverters.deleteSnapshot(deleteSnapshotRequest); assertThat(request.getEndpoint(), equalTo(endpoint)); assertThat(request.getMethod(), equalTo(HttpDelete.METHOD_NAME)); assertThat(request.getParameters(), equalTo(expectedParams)); 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 ba29386a46b34..745e7365eca82 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,7 +29,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.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; @@ -752,7 +752,7 @@ public void testSnapshotDeleteSnapshot() throws IOException { createTestSnapshots(); // tag::delete-snapshot-request - DeleteSnapshotsRequest request = new DeleteSnapshotsRequest(repositoryName, snapshotName); + DeleteSnapshotRequest request = new DeleteSnapshotRequest(repositoryName, snapshotName); // end::delete-snapshot-request // tag::delete-snapshot-request-masterTimeout @@ -773,7 +773,7 @@ public void testSnapshotDeleteSnapshot() throws IOException { public void testSnapshotDeleteSnapshotAsync() throws InterruptedException { RestHighLevelClient client = highLevelClient(); { - DeleteSnapshotsRequest request = new DeleteSnapshotsRequest(); + DeleteSnapshotRequest request = new DeleteSnapshotRequest(); // tag::delete-snapshot-execute-listener ActionListener listener = diff --git a/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java b/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java index 66fdc7556e752..5523112d6bcf4 100644 --- a/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java +++ b/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java @@ -22,7 +22,7 @@ import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotStatus; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; @@ -253,7 +253,7 @@ private static void assertSnapshotStatusSuccessful(RestHighLevelClient client, S private void deleteSnapshot(RestHighLevelClient client, String repoName, String name) throws IOException { assertThat(client.snapshot().delete( - new DeleteSnapshotsRequest(repoName, name), RequestOptions.DEFAULT).isAcknowledged(), is(true)); + new DeleteSnapshotRequest(repoName, name), RequestOptions.DEFAULT).isAcknowledged(), is(true)); } @SuppressWarnings("unchecked") diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java similarity index 86% rename from server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java rename to server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java index 024d72d4f5e15..1239e1005381e 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotsRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java @@ -36,7 +36,7 @@ * files that are associated with this particular snapshot. All files that are shared with * at least one other existing snapshot are left intact. */ -public class DeleteSnapshotsRequest extends MasterNodeRequest { +public class DeleteSnapshotRequest extends MasterNodeRequest { private String repository; @@ -45,7 +45,7 @@ public class DeleteSnapshotsRequest extends MasterNodeRequest { /** * Constructs delete snapshot request builder */ public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAction action) { - super(client, action, new DeleteSnapshotsRequest()); + super(client, action, new DeleteSnapshotRequest()); } /** * Constructs delete snapshot request builder with specified repository and snapshot names */ public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAction action, String repository, String[] snapshots) { - super(client, action, new DeleteSnapshotsRequest(repository, snapshots)); + super(client, action, new DeleteSnapshotRequest(repository, snapshots)); } /** diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java index 1a9e5305893dc..0c855110d863d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/TransportDeleteSnapshotAction.java @@ -41,7 +41,7 @@ /** * Transport action for delete snapshot operation */ -public class TransportDeleteSnapshotAction extends TransportMasterNodeAction { +public class TransportDeleteSnapshotAction extends TransportMasterNodeAction { private final SnapshotsService snapshotsService; @Inject @@ -49,7 +49,7 @@ public TransportDeleteSnapshotAction(TransportService transportService, ClusterS ThreadPool threadPool, SnapshotsService snapshotsService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { super(DeleteSnapshotAction.NAME, transportService, clusterService, threadPool, actionFilters, - DeleteSnapshotsRequest::new,indexNameExpressionResolver); + DeleteSnapshotRequest::new,indexNameExpressionResolver); this.snapshotsService = snapshotsService; } @@ -64,13 +64,13 @@ protected AcknowledgedResponse read(StreamInput in) throws IOException { } @Override - protected ClusterBlockException checkBlock(DeleteSnapshotsRequest request, ClusterState state) { + protected ClusterBlockException checkBlock(DeleteSnapshotRequest request, ClusterState state) { // Cluster is not affected but we look up repositories in metadata return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ); } @Override - protected void masterOperation(Task task, final DeleteSnapshotsRequest request, ClusterState state, + protected void masterOperation(Task task, final DeleteSnapshotRequest request, ClusterState state, final ActionListener listener) { snapshotsService.deleteSnapshots(request.repository(), Arrays.asList(request.snapshots()), ActionListener.map(listener, v -> new AcknowledgedResponse(true))); diff --git a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index 16c66cfc829c4..08337a6e6f307 100644 --- a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -74,7 +74,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequestBuilder; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequestBuilder; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequestBuilder; @@ -519,12 +519,12 @@ public interface ClusterAdminClient extends ElasticsearchClient { /** * Delete snapshot. */ - ActionFuture deleteSnapshots(DeleteSnapshotsRequest request); + ActionFuture deleteSnapshots(DeleteSnapshotRequest request); /** * Delete snapshot. */ - void deleteSnapshots(DeleteSnapshotsRequest request, ActionListener listener); + void deleteSnapshots(DeleteSnapshotRequest request, ActionListener listener); /** * Delete snapshot. diff --git a/server/src/main/java/org/elasticsearch/client/Requests.java b/server/src/main/java/org/elasticsearch/client/Requests.java index 817c5a64d12df..f512ad8ea35d6 100644 --- a/server/src/main/java/org/elasticsearch/client/Requests.java +++ b/server/src/main/java/org/elasticsearch/client/Requests.java @@ -35,7 +35,7 @@ import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; import org.elasticsearch.action.admin.cluster.shards.ClusterSearchShardsRequest; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; @@ -508,8 +508,8 @@ public static RestoreSnapshotRequest restoreSnapshotRequest(String repository, S * @param repository repository name * @return delete snapshot request */ - public static DeleteSnapshotsRequest deleteSnapshotRequest(String repository, String[] snapshots) { - return new DeleteSnapshotsRequest(repository, snapshots); + public static DeleteSnapshotRequest deleteSnapshotRequest(String repository, String[] snapshots) { + return new DeleteSnapshotRequest(repository, snapshots); } /** diff --git a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java index 8cf5d08284ad6..2127151188617 100644 --- a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java +++ b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java @@ -102,7 +102,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequestBuilder; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotAction; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequestBuilder; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsAction; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; @@ -942,12 +942,12 @@ public GetSnapshotsRequestBuilder prepareGetSnapshots(String... repositories) { @Override - public ActionFuture deleteSnapshots(DeleteSnapshotsRequest request) { + public ActionFuture deleteSnapshots(DeleteSnapshotRequest request) { return execute(DeleteSnapshotAction.INSTANCE, request); } @Override - public void deleteSnapshots(DeleteSnapshotsRequest request, ActionListener listener) { + public void deleteSnapshots(DeleteSnapshotRequest request, ActionListener listener) { execute(DeleteSnapshotAction.INSTANCE, request, listener); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java index f0044a0f3ee2f..ee0b42fb2a1dd 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java @@ -19,7 +19,7 @@ package org.elasticsearch.rest.action.admin.cluster; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.Strings; import org.elasticsearch.rest.BaseRestHandler; @@ -49,9 +49,9 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { - DeleteSnapshotsRequest deleteSnapshotsRequest = deleteSnapshotRequest(request.param("repository"), + DeleteSnapshotRequest deleteSnapshotRequest = deleteSnapshotRequest(request.param("repository"), request.paramAsStringArray("snapshot", Strings.EMPTY_ARRAY)); - deleteSnapshotsRequest.masterNodeTimeout(request.paramAsTime("master_timeout", deleteSnapshotsRequest.masterNodeTimeout())); - return channel -> client.admin().cluster().deleteSnapshots(deleteSnapshotsRequest, new RestToXContentListener<>(channel)); + deleteSnapshotRequest.masterNodeTimeout(request.paramAsTime("master_timeout", deleteSnapshotRequest.masterNodeTimeout())); + return channel -> client.admin().cluster().deleteSnapshots(deleteSnapshotRequest, new RestToXContentListener<>(channel)); } } diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index 4ae8d34b00d4f..969aa548e7482 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -41,7 +41,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.create.TransportCreateSnapshotAction; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotAction; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.delete.TransportDeleteSnapshotAction; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotAction; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; @@ -535,7 +535,7 @@ public void testConcurrentSnapshotCreateAndDeleteOther() { continueOrDie(createOtherSnapshotResponseStepListener, createSnapshotResponse -> client().admin().cluster().deleteSnapshots( - new DeleteSnapshotsRequest(repoName, snapshotName), ActionListener.wrap( + new DeleteSnapshotRequest(repoName, snapshotName), ActionListener.wrap( resp -> deleteSnapshotStepListener.onResponse(true), e -> { final Throwable unwrapped = @@ -800,7 +800,7 @@ public void run() { continueOrDie(snapshotStartedListener, snapshotResponse -> { createdSnapshot.set(true); testClusterNodes.randomDataNodeSafe().client.admin().cluster().deleteSnapshots( - new DeleteSnapshotsRequest(repoName, snapshotName), noopListener()); + new DeleteSnapshotRequest(repoName, snapshotName), noopListener()); }); runUntil(() -> testClusterNodes.randomMasterNode().map(master -> { diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java index 2e06f764d6a59..e765f0bc1ad52 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java @@ -21,7 +21,7 @@ import org.elasticsearch.action.ActionRunnable; import org.elasticsearch.action.admin.cluster.repositories.cleanup.CleanupRepositoryResponse; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.common.Strings; import org.elasticsearch.common.blobstore.BlobMetadata; @@ -215,7 +215,7 @@ public void testCleanup() throws Exception { createDanglingIndex(repo, genericExec); logger.info("--> deleting a snapshot to trigger repository cleanup"); - client().admin().cluster().deleteSnapshots(new DeleteSnapshotsRequest("test-repo", snapshotName)).actionGet(); + client().admin().cluster().deleteSnapshots(new DeleteSnapshotRequest("test-repo", snapshotName)).actionGet(); assertConsistentRepository(repo, genericExec); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java index d398dfdd16fb7..b70d8cc45c807 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java @@ -7,7 +7,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.ClusterState; @@ -49,7 +49,7 @@ void performDuringNoSnapshot(IndexMetadata indexMetadata, ClusterState currentCl listener.onResponse(true); return; } - DeleteSnapshotsRequest deleteSnapshotRequest = new DeleteSnapshotsRequest(repositoryName, snapshotName); + DeleteSnapshotRequest deleteSnapshotRequest = new DeleteSnapshotRequest(repositoryName, snapshotName); getClient().admin().cluster().deleteSnapshots(deleteSnapshotRequest, new ActionListener<>() { @Override diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStepTests.java index effa15f0f3bae..d69acab6e02a1 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStepTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotAction; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.Metadata; @@ -148,8 +148,8 @@ protected void Request request, ActionListener listener) { assertThat(action.name(), is(DeleteSnapshotAction.NAME)); - assertTrue(request instanceof DeleteSnapshotsRequest); - assertThat(((DeleteSnapshotsRequest) request).snapshots(), arrayContaining(expectedSnapshotName)); + assertTrue(request instanceof DeleteSnapshotRequest); + assertThat(((DeleteSnapshotRequest) request).snapshots(), arrayContaining(expectedSnapshotName)); } }; } diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java index 139d0cd493e2a..795f5c86bb9cd 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; @@ -448,7 +448,7 @@ public void testErrStillRunsFailureHandlerWhenDeleting() throws Exception { @SuppressWarnings("unchecked") protected void doExecute(ActionType action, Request request, ActionListener listener) { - if (request instanceof DeleteSnapshotsRequest) { + if (request instanceof DeleteSnapshotRequest) { logger.info("--> called"); listener.onResponse((Response) new AcknowledgedResponse(true)); } else { From a85f127bf38f41ee465406d81d092d75d88aea01 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 21:13:17 +0200 Subject: [PATCH 23/45] revert naming stuff --- .../url/URLSnapshotRestoreTests.java | 2 +- .../s3/S3BlobStoreRepositoryTests.java | 6 ++-- .../client/ClusterAdminClient.java | 6 ++-- .../client/support/AbstractClient.java | 6 ++-- .../cluster/RestDeleteSnapshotAction.java | 2 +- .../cluster/snapshots/SnapshotBlocksIT.java | 2 +- .../CorruptedBlobStoreRepositoryIT.java | 8 +++--- .../DedicatedClusterSnapshotRestoreIT.java | 4 +-- ...etadataLoadingDuringSnapshotRestoreIT.java | 2 +- .../MinThreadsSnapshotRestoreIT.java | 8 +++--- .../SharedClusterSnapshotRestoreIT.java | 28 +++++++++---------- .../snapshots/SnapshotResiliencyTests.java | 10 +++---- .../AbstractThirdPartyRepositoryTestCase.java | 4 +-- .../ESBlobStoreRepositoryIntegTestCase.java | 10 +++---- ...ESMockAPIBasedRepositoryIntegTestCase.java | 2 +- .../xpack/core/ilm/CleanupSnapshotStep.java | 2 +- .../xpack/slm/SnapshotRetentionTask.java | 2 +- .../slm/SLMSnapshotBlockingIntegTests.java | 6 ++-- .../authz/SnapshotUserRoleIntegTests.java | 2 +- 19 files changed, 56 insertions(+), 56 deletions(-) diff --git a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java index 45f77b3ed3663..05ea4fa786aaf 100644 --- a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java +++ b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java @@ -120,7 +120,7 @@ public void testUrlRepository() throws Exception { assertThat(getSnapshotsResponse.getSnapshots("url-repo").size(), equalTo(1)); logger.info("--> delete snapshot"); - AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshots("test-repo", + AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap"}).get(); assertAcked(deleteSnapshotResponse); diff --git a/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java b/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java index ebddf3fdfed0c..70f31a9a10ea8 100644 --- a/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java +++ b/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java @@ -179,11 +179,11 @@ public void testEnforcedCooldownPeriod() throws IOException { assertThat(repository.threadPool().relativeTimeInNanos() - beforeThrottledSnapshot, greaterThan(TEST_COOLDOWN_PERIOD.getNanos())); final long beforeThrottledDelete = repository.threadPool().relativeTimeInNanos(); - client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{newSnapshotName}).get(); + client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{newSnapshotName}).get(); assertThat(repository.threadPool().relativeTimeInNanos() - beforeThrottledDelete, greaterThan(TEST_COOLDOWN_PERIOD.getNanos())); final long beforeFastDelete = repository.threadPool().relativeTimeInNanos(); - client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{fakeOldSnapshot.getName()}).get(); + client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{fakeOldSnapshot.getName()}).get(); assertThat(repository.threadPool().relativeTimeInNanos() - beforeFastDelete, lessThan(TEST_COOLDOWN_PERIOD.getNanos())); } @@ -215,7 +215,7 @@ public void testRequestStats() throws Exception { ensureGreen(index); assertHitCount(client().prepareSearch(index).setSize(0).setTrackTotalHits(true).get(), nbDocs); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repository, new String[] {snapshot}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repository, new String[] {snapshot}).get()); final RepositoryStats repositoryStats = StreamSupport.stream( internalCluster().getInstances(RepositoriesService.class).spliterator(), false) diff --git a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index 08337a6e6f307..d1c8ca99018f1 100644 --- a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -519,17 +519,17 @@ public interface ClusterAdminClient extends ElasticsearchClient { /** * Delete snapshot. */ - ActionFuture deleteSnapshots(DeleteSnapshotRequest request); + ActionFuture deleteSnapshot(DeleteSnapshotRequest request); /** * Delete snapshot. */ - void deleteSnapshots(DeleteSnapshotRequest request, ActionListener listener); + void deleteSnapshot(DeleteSnapshotRequest request, ActionListener listener); /** * Delete snapshot. */ - DeleteSnapshotRequestBuilder prepareDeleteSnapshots(String repository, String[] snapshot); + DeleteSnapshotRequestBuilder prepareDeleteSnapshot(String repository, String[] snapshot); /** * Restores a snapshot. diff --git a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java index 2127151188617..8032db05b38f9 100644 --- a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java +++ b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java @@ -942,17 +942,17 @@ public GetSnapshotsRequestBuilder prepareGetSnapshots(String... repositories) { @Override - public ActionFuture deleteSnapshots(DeleteSnapshotRequest request) { + public ActionFuture deleteSnapshot(DeleteSnapshotRequest request) { return execute(DeleteSnapshotAction.INSTANCE, request); } @Override - public void deleteSnapshots(DeleteSnapshotRequest request, ActionListener listener) { + public void deleteSnapshot(DeleteSnapshotRequest request, ActionListener listener) { execute(DeleteSnapshotAction.INSTANCE, request, listener); } @Override - public DeleteSnapshotRequestBuilder prepareDeleteSnapshots(String repository, String[] names) { + public DeleteSnapshotRequestBuilder prepareDeleteSnapshot(String repository, String[] names) { return new DeleteSnapshotRequestBuilder(this, DeleteSnapshotAction.INSTANCE, repository, names); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java index ee0b42fb2a1dd..561a995afabce 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java @@ -52,6 +52,6 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC DeleteSnapshotRequest deleteSnapshotRequest = deleteSnapshotRequest(request.param("repository"), request.paramAsStringArray("snapshot", Strings.EMPTY_ARRAY)); deleteSnapshotRequest.masterNodeTimeout(request.paramAsTime("master_timeout", deleteSnapshotRequest.masterNodeTimeout())); - return channel -> client.admin().cluster().deleteSnapshots(deleteSnapshotRequest, new RestToXContentListener<>(channel)); + return channel -> client.admin().cluster().deleteSnapshot(deleteSnapshotRequest, new RestToXContentListener<>(channel)); } } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java index 956d6b07f8be9..1a88f8c37f4a9 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java @@ -125,7 +125,7 @@ public void testDeleteSnapshotWithBlocks() { try { setClusterReadOnly(true); assertTrue( - client().admin().cluster().prepareDeleteSnapshots(REPOSITORY_NAME, new String[]{SNAPSHOT_NAME}).get().isAcknowledged()); + client().admin().cluster().prepareDeleteSnapshot(REPOSITORY_NAME, new String[]{SNAPSHOT_NAME}).get().isAcknowledged()); } finally { setClusterReadOnly(false); } diff --git a/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java b/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java index e7f5e0b29c4a3..9be5104665a2d 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java @@ -111,7 +111,7 @@ public void testConcurrentlyChangeRepositoryContents() throws Exception { .put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES))); logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshots(repoName, new String[] {snapshot}).get(); + client.admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshot}).get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareGetSnapshots(repoName) @@ -185,7 +185,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS assertThat(getRepositoryData(repositoryAfterRestart).getGenId(), is(beforeMoveGen + 1)); logger.info("--> delete snapshot"); - client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshot}).get(); + client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshot}).get(); logger.info("--> verify index-N blob is found at the expected location"); assertThat(getRepositoryData(repositoryAfterRestart).getGenId(), is(beforeMoveGen + 2)); @@ -247,7 +247,7 @@ public void testHandlingMissingRootLevelSnapshotMetadata() throws Exception { is(SnapshotsService.OLD_SNAPSHOT_FORMAT)); logger.info("--> verify that snapshot with missing root level metadata can be deleted"); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[] {snapshotToCorrupt.getName()}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshotToCorrupt.getName()}).get()); logger.info("--> verify that repository is assumed in new metadata format after removing corrupted snapshot"); assertThat(PlainActionFuture.get(f -> threadPool.generic().execute( @@ -305,7 +305,7 @@ public void testMountCorruptedRepositoryData() throws Exception { private void assertRepositoryBlocked(Client client, String repo, String existingSnapshot) { logger.info("--> try to delete snapshot"); final RepositoryException repositoryException3 = expectThrows(RepositoryException.class, - () -> client.admin().cluster().prepareDeleteSnapshots(repo, new String[]{existingSnapshot}).execute().actionGet()); + () -> client.admin().cluster().prepareDeleteSnapshot(repo, new String[]{existingSnapshot}).execute().actionGet()); assertThat(repositoryException3.getMessage(), containsString("Could not read repository data because the contents of the repository do not match its expected state.")); diff --git a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java index 8afc94d50787f..752327c83d07a 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java @@ -473,7 +473,7 @@ public void testSnapshotWithStuckNode() throws Exception { logger.info("--> execution was blocked on node [{}], aborting snapshot", blockedNode); ActionFuture deleteSnapshotResponseFuture = internalCluster().client(nodes.get(0)) - .admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap"}).execute(); + .admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap"}).execute(); // Make sure that abort makes some progress Thread.sleep(100); unblockNode("test-repo", blockedNode); @@ -1153,7 +1153,7 @@ public void testSnapshotTotalAndIncrementalSizes() throws IOException { // drop 1st one to avoid miscalculation as snapshot reuses some files of prev snapshot assertTrue(client.admin().cluster() - .prepareDeleteSnapshots(repositoryName, new String[]{snapshot0}) + .prepareDeleteSnapshot(repositoryName, new String[]{snapshot0}) .get().isAcknowledged()); response = client.admin().cluster().prepareSnapshotStatus(repositoryName) diff --git a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java index 473af1a9ee59c..2d62749c0f7ba 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java @@ -139,7 +139,7 @@ public void testWhenMetadataAreLoaded() throws Exception { assertIndexMetadataLoads("snap", "others", 3); // Deleting a snapshot does not load the global metadata state but loads each index metadata - assertAcked(client().admin().cluster().prepareDeleteSnapshots("repository", new String[]{"snap"}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot("repository", new String[]{"snap"}).get()); assertGlobalMetadataLoads("snap", 1); assertIndexMetadataLoads("snap", "docs", 4); assertIndexMetadataLoads("snap", "others", 3); diff --git a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java index 597296538588b..9d16f4086e5b1 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java @@ -84,13 +84,13 @@ public void testConcurrentSnapshotDeletionsNotAllowed() throws Exception { ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of first snapshot"); ActionFuture future = - client().admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot2}).execute(); + client().admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot2}).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); logger.info("--> try deleting the second snapshot, should fail because the first deletion is in progress"); try { - client().admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot1}).get(); + client().admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot1}).get(); fail("should not be able to delete snapshots concurrently"); } catch (ConcurrentSnapshotExecutionException e) { assertThat(e.getMessage(), containsString("cannot delete - another snapshot is currently being deleted")); @@ -103,7 +103,7 @@ public void testConcurrentSnapshotDeletionsNotAllowed() throws Exception { assertAcked(future.actionGet()); logger.info("--> delete second snapshot, which should now work"); - client().admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot1}).get(); + client().admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot1}).get(); assertTrue(client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots(repo).isEmpty()); } @@ -130,7 +130,7 @@ public void testSnapshottingWithInProgressDeletionNotAllowed() throws Exception ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of snapshot"); ActionFuture future = - client().admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot1}).execute(); + client().admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot1}).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 98cde3164e932..3488425bc6897 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -1303,10 +1303,10 @@ public void testDeleteSnapshot() throws Exception { if (randomBoolean()) { for (int i = 1; i < numberOfSnapshots - 1; i++) { - client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-" + i}).get(); + client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap-" + i}).get(); } } else { - client.admin().cluster().prepareDeleteSnapshots( + client.admin().cluster().prepareDeleteSnapshot( "test-repo", IntStream.range(1, numberOfSnapshots - 1).mapToObj(i -> "test-snap-" + i).toArray(String[]::new)).get(); } @@ -1326,7 +1326,7 @@ public void testDeleteSnapshot() throws Exception { assertThat(client.prepareSearch("test-idx").setSize(0).get().getHits().getTotalHits().value, equalTo(10L * numberOfSnapshots)); logger.info("--> delete the last snapshot"); - client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{lastSnapshot}).get(); + client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{lastSnapshot}).get(); logger.info("--> make sure that number of files is back to what it was when the first snapshot was made"); assertFileCount(repo, numberOfFiles[0]); } @@ -1471,7 +1471,7 @@ public void testDeleteSnapshotWithMissingIndexAndShardMetadata() throws Exceptio } logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-1"}).get(); + client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap-1"}).get(); logger.info("--> make sure snapshot doesn't exist"); @@ -1512,7 +1512,7 @@ public void testDeleteSnapshotWithMissingMetadata() throws Exception { Files.delete(metadata); logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-1"}).get(); + client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap-1"}).get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareGetSnapshots("test-repo") @@ -1549,7 +1549,7 @@ public void testDeleteSnapshotWithCorruptedSnapshotFile() throws Exception { outChan.truncate(randomInt(10)); } logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap-1"}).get(); + client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap-1"}).get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, @@ -1610,7 +1610,7 @@ public void testDeleteSnapshotWithCorruptedGlobalState() throws Exception { assertThat(snapshotStatusResponse.getSnapshots(), hasSize(1)); assertThat(snapshotStatusResponse.getSnapshots().get(0).getSnapshot().getSnapshotId().getName(), equalTo("test-snap")); - assertAcked(client().admin().cluster().prepareDeleteSnapshots("test-repo", new String[]{"test-snap"}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap"}).get()); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster() .prepareGetSnapshots("test-repo").addSnapshots("test-snap").get().getSnapshots("test-repo")); assertRequestBuilderThrows(client().admin().cluster().prepareSnapshotStatus("test-repo").addSnapshots("test-snap"), @@ -2024,7 +2024,7 @@ public void testReadonlyRepository() throws Exception { assertThat(getSnapshotsResponse.getSnapshots("readonly-repo").size(), equalTo(1)); logger.info("--> try deleting snapshot"); - assertRequestBuilderThrows(client.admin().cluster().prepareDeleteSnapshots("readonly-repo", new String[]{"test-snap"}), + assertRequestBuilderThrows(client.admin().cluster().prepareDeleteSnapshot("readonly-repo", new String[]{"test-snap"}), RepositoryException.class, "cannot delete snapshot from a readonly repository"); logger.info("--> try making another snapshot"); @@ -2715,7 +2715,7 @@ public void testDeleteSnapshotWhileRestoringFails() throws Exception { logger.info("--> try deleting the snapshot while the restore is in progress (should throw an error)"); ConcurrentSnapshotExecutionException e = expectThrows(ConcurrentSnapshotExecutionException.class, () -> - client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshotName}).get()); + client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshotName}).get()); assertEquals(repoName, e.getRepositoryName()); assertEquals(snapshotName, e.getSnapshotName()); assertThat(e.getMessage(), containsString("cannot delete snapshot during a restore")); @@ -2754,7 +2754,7 @@ public void testSnapshotName() throws Exception { () -> client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("_foo") .get().getSnapshots("test-repo")); expectThrows(SnapshotMissingException.class, - () -> client.admin().cluster().prepareDeleteSnapshots("test-repo", new String[] {"_foo"}).get()); + () -> client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[] {"_foo"}).get()); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareSnapshotStatus("test-repo").setSnapshots("_foo").get()); } @@ -2953,7 +2953,7 @@ public void testRestoreSnapshotWithCorruptedIndexMetadata() throws Exception { } } - assertAcked(client().admin().cluster().prepareDeleteSnapshots("test-repo", + assertAcked(client().admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{snapshotInfo.snapshotId().getName()}).get()); } @@ -3099,7 +3099,7 @@ public void testCannotCreateSnapshotsWithSameName() throws Exception { } logger.info("--> delete the first snapshot"); - client.admin().cluster().prepareDeleteSnapshots(repositoryName, new String[]{snapshotName}).get(); + client.admin().cluster().prepareDeleteSnapshot(repositoryName, new String[]{snapshotName}).get(); logger.info("--> try creating a snapshot with the same name, now it should work because the first one was deleted"); createSnapshotResponse = client.admin() @@ -3168,7 +3168,7 @@ public void testGetSnapshotsRequest() throws Exception { assertEquals("snap-on-empty-repo", getSnapshotsResponse.getSnapshots("test-repo").get(0).snapshotId().getName()); unblockNode(repositoryName, initialBlockedNode); // unblock node responseListener.actionGet(TimeValue.timeValueMillis(10000L)); // timeout after 10 seconds - client.admin().cluster().prepareDeleteSnapshots(repositoryName, new String[]{"snap-on-empty-repo"}).get(); + client.admin().cluster().prepareDeleteSnapshot(repositoryName, new String[]{"snap-on-empty-repo"}).get(); final int numSnapshots = randomIntBetween(1, 3) + 1; logger.info("--> take {} snapshot(s)", numSnapshots - 1); @@ -3835,7 +3835,7 @@ public void testSnapshotDifferentIndicesBySameName() { expectedCount = docCount; } logger.info("--> deleting snapshot [{}]", snapshotToDelete); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshotToDelete}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshotToDelete}).get()); logger.info("--> restoring snapshot [{}]", snapshotToRestore); client().admin().cluster().prepareRestoreSnapshot(repoName, snapshotToRestore).setIndices(indexName).setRenamePattern(indexName) .setRenameReplacement("restored-3").setWaitForCompletion(true).get(); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index 969aa548e7482..c7e6dec9104f4 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -429,7 +429,7 @@ public void testSnapshotDeleteWithMasterFailover() { continueOrDie(createSnapshotResponseStepListener, createSnapshotResponse -> { scheduleNow(this::disconnectOrRestartMasterNode); testClusterNodes.randomDataNodeSafe().client.admin().cluster() - .prepareDeleteSnapshots(repoName, new String[]{snapshotName}) + .prepareDeleteSnapshot(repoName, new String[]{snapshotName}) .execute(ActionListener.wrap(() -> snapshotDeleteResponded.set(true))); }); @@ -477,7 +477,7 @@ public void testConcurrentSnapshotCreateAndDelete() { public void clusterChanged(ClusterChangedEvent event) { final SnapshotsInProgress snapshotsInProgress = event.state().custom(SnapshotsInProgress.TYPE); if (snapshotsInProgress != null && snapshotsInProgress.entries().isEmpty() == false) { - client().admin().cluster().prepareDeleteSnapshots(repoName, new String[] {snapshotName}) + client().admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshotName}) .execute(deleteSnapshotStepListener); masterNode.clusterService.removeListener(this); } @@ -534,7 +534,7 @@ public void testConcurrentSnapshotCreateAndDeleteOther() { final StepListener deleteSnapshotStepListener = new StepListener<>(); continueOrDie(createOtherSnapshotResponseStepListener, - createSnapshotResponse -> client().admin().cluster().deleteSnapshots( + createSnapshotResponse -> client().admin().cluster().deleteSnapshot( new DeleteSnapshotRequest(repoName, snapshotName), ActionListener.wrap( resp -> deleteSnapshotStepListener.onResponse(true), e -> { @@ -610,7 +610,7 @@ public void testConcurrentSnapshotRestoreAndDeleteOther() { continueOrDie(createOtherSnapshotResponseStepListener, createSnapshotResponse -> { scheduleNow( - () -> client().admin().cluster().prepareDeleteSnapshots(repoName, new String[] {snapshotName}) + () -> client().admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshotName}) .execute(deleteSnapshotStepListener)); scheduleNow(() -> client().admin().cluster().restoreSnapshot( new RestoreSnapshotRequest(repoName, secondSnapshotName).waitForCompletion(true) @@ -799,7 +799,7 @@ public void run() { continueOrDie(snapshotStartedListener, snapshotResponse -> { createdSnapshot.set(true); - testClusterNodes.randomDataNodeSafe().client.admin().cluster().deleteSnapshots( + testClusterNodes.randomDataNodeSafe().client.admin().cluster().deleteSnapshot( new DeleteSnapshotRequest(repoName, snapshotName), noopListener()); }); diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java index e765f0bc1ad52..b5d67a189a110 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java @@ -132,7 +132,7 @@ public void testCreateSnapshot() { assertTrue(client().admin() .cluster() - .prepareDeleteSnapshots("test-repo", new String[]{snapshotName}) + .prepareDeleteSnapshot("test-repo", new String[]{snapshotName}) .get() .isAcknowledged()); } @@ -215,7 +215,7 @@ public void testCleanup() throws Exception { createDanglingIndex(repo, genericExec); logger.info("--> deleting a snapshot to trigger repository cleanup"); - client().admin().cluster().deleteSnapshots(new DeleteSnapshotRequest("test-repo", snapshotName)).actionGet(); + client().admin().cluster().deleteSnapshot(new DeleteSnapshotRequest("test-repo", snapshotName)).actionGet(); assertConsistentRepository(repo, genericExec); diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java index c485ed95d8ed3..d3c6a0656c1fe 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java @@ -328,13 +328,13 @@ public void testSnapshotAndRestore() throws Exception { } logger.info("--> delete snapshot {}:{}", repoName, snapshotName); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshotName}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshotName}).get()); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster().prepareGetSnapshots(repoName).setSnapshots(snapshotName).get().getSnapshots(repoName)); expectThrows(SnapshotMissingException.class, () -> - client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{snapshotName}).get()); + client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshotName}).get()); expectThrows(SnapshotRestoreException.class, () -> client().admin().cluster().prepareRestoreSnapshot(repoName, snapshotName).setWaitForCompletion(randomBoolean()).get()); @@ -391,7 +391,7 @@ public void testMultipleSnapshotAndRollback() throws Exception { for (int i = 0; i < iterationCount; i++) { logger.info("--> delete snapshot {}:{}", repoName, snapshotName + "-" + i); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[] {snapshotName + "-" + i}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshotName + "-" + i}).get()); } } @@ -429,7 +429,7 @@ public void testIndicesDeletedFromRepository() throws Exception { assertEquals(createSnapshotResponse.getSnapshotInfo().successfulShards(), createSnapshotResponse.getSnapshotInfo().totalShards()); logger.info("--> delete a snapshot"); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{"test-snap"}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{"test-snap"}).get()); logger.info("--> verify index folder deleted from blob container"); RepositoriesService repositoriesSvc = internalCluster().getInstance(RepositoriesService.class, internalCluster().getMasterName()); @@ -449,7 +449,7 @@ public void testIndicesDeletedFromRepository() throws Exception { } } - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repoName, new String[]{"test-snap2"}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{"test-snap2"}).get()); } protected void addRandomDocuments(String name, int numDocs) throws InterruptedException { diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java index 8dca4b8bd5b3d..5022c9ae6715c 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java @@ -156,7 +156,7 @@ public final void testSnapshotWithLargeSegmentFiles() throws Exception { ensureGreen(index); assertHitCount(client().prepareSearch(index).setSize(0).setTrackTotalHits(true).get(), nbDocs); - assertAcked(client().admin().cluster().prepareDeleteSnapshots(repository, new String[]{snapshot}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repository, new String[]{snapshot}).get()); } protected static String httpServerUrl() { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java index b70d8cc45c807..3392a5e5d78b7 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CleanupSnapshotStep.java @@ -50,7 +50,7 @@ void performDuringNoSnapshot(IndexMetadata indexMetadata, ClusterState currentCl return; } DeleteSnapshotRequest deleteSnapshotRequest = new DeleteSnapshotRequest(repositoryName, snapshotName); - getClient().admin().cluster().deleteSnapshots(deleteSnapshotRequest, new ActionListener<>() { + getClient().admin().cluster().deleteSnapshot(deleteSnapshotRequest, new ActionListener<>() { @Override public void onResponse(AcknowledgedResponse acknowledgedResponse) { diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java index 357b8bc4a764a..5e140e39aadf5 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java @@ -418,7 +418,7 @@ void deleteSnapshot(String slmPolicy, String repo, SnapshotId snapshot, Snapshot ActionListener listener) { logger.info("[{}] snapshot retention deleting snapshot [{}]", repo, snapshot); CountDownLatch latch = new CountDownLatch(1); - client.admin().cluster().prepareDeleteSnapshots(repo, new String[]{snapshot.getName()}) + client.admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot.getName()}) .execute(new LatchedActionListener<>(ActionListener.wrap(acknowledgedResponse -> { if (acknowledgedResponse.isAcknowledged()) { logger.debug("[{}] snapshot [{}] deleted successfully", repo, snapshot); diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java index ef97388a28594..fafaa73a7dc75 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java @@ -131,7 +131,7 @@ public void testSnapshotInProgress() throws Exception { // Cancel/delete the snapshot try { - client().admin().cluster().prepareDeleteSnapshots(REPO, new String[]{snapshotName}).get(); + client().admin().cluster().prepareDeleteSnapshot(REPO, new String[]{snapshotName}).get(); } catch (SnapshotMissingException e) { // ignore } @@ -235,7 +235,7 @@ public void testRetentionWhileSnapshotInProgress() throws Exception { assertBusy(() -> { try { logger.info("--> cancelling snapshot {}", secondSnapName); - client().admin().cluster().prepareDeleteSnapshots(REPO, new String[]{secondSnapName}).get(); + client().admin().cluster().prepareDeleteSnapshot(REPO, new String[]{secondSnapName}).get(); } catch (ConcurrentSnapshotExecutionException e) { logger.info("--> attempted to stop second snapshot", e); // just wait and retry @@ -439,7 +439,7 @@ public void testSLMRetentionAfterRestore() throws Exception { // Cancel/delete the snapshot try { - client().admin().cluster().prepareDeleteSnapshots(REPO, new String[]{snapshotName}).get(); + client().admin().cluster().prepareDeleteSnapshot(REPO, new String[]{snapshotName}).get(); } catch (SnapshotMissingException e) { // ignore } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java index 34a7350d029fe..610d192136394 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java @@ -126,7 +126,7 @@ public void testSnapshotUserRoleUnathorizedForDestructiveActions() { () -> client.admin().cluster().prepareRestoreSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(), "cluster:admin/snapshot/restore", "snapshot_user"); assertThrowsAuthorizationException( - () -> client.admin().cluster().prepareDeleteSnapshots("repo", + () -> client.admin().cluster().prepareDeleteSnapshot("repo", new String[]{randomAlphaOfLength(4).toLowerCase(Locale.ROOT)}).get(), "cluster:admin/snapshot/delete", "snapshot_user"); // try destructive/revealing actions on all indices From e0775d489fd5fbaffd209c4b4ba2cea4cd117c7a Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 21:16:59 +0200 Subject: [PATCH 24/45] assert --- .../main/java/org/elasticsearch/snapshots/SnapshotsService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index e0af2f483c991..a7bdd6acb4e2f 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -1119,6 +1119,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS } private void resolveAndDeleteSnapshots(Collection snapshotsOrPatterns, ActionListener listener, String repositoryName) { + assert snapshotsOrPatterns.isEmpty() == false; threadPool.generic().execute(ActionRunnable.wrap(listener, l -> repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> deleteCompletedSnapshots(matchingSnapshotIds(repositoryData, snapshotsOrPatterns, repositoryName), repositoryName, From b894d580e03f4bd64e08f4def68278212fa06e5e Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 21:51:35 +0200 Subject: [PATCH 25/45] shorter diff --- .../repositories/url/URLSnapshotRestoreTests.java | 3 +-- .../repositories/s3/S3BlobStoreRepositoryTests.java | 6 +++--- .../upgrades/MultiVersionRepositoryAccessIT.java | 3 +-- .../java/org/elasticsearch/client/ClusterAdminClient.java | 2 +- .../org/elasticsearch/client/support/AbstractClient.java | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java index 05ea4fa786aaf..2cc1d0992fafc 100644 --- a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java +++ b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java @@ -120,8 +120,7 @@ public void testUrlRepository() throws Exception { assertThat(getSnapshotsResponse.getSnapshots("url-repo").size(), equalTo(1)); logger.info("--> delete snapshot"); - AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshot("test-repo", - new String[]{"test-snap"}).get(); + AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").get(); assertAcked(deleteSnapshotResponse); logger.info("--> list available shapshot again, no snapshots should be returned"); diff --git a/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java b/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java index 70f31a9a10ea8..e3fab59e7d47c 100644 --- a/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java +++ b/plugins/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java @@ -179,11 +179,11 @@ public void testEnforcedCooldownPeriod() throws IOException { assertThat(repository.threadPool().relativeTimeInNanos() - beforeThrottledSnapshot, greaterThan(TEST_COOLDOWN_PERIOD.getNanos())); final long beforeThrottledDelete = repository.threadPool().relativeTimeInNanos(); - client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{newSnapshotName}).get(); + client().admin().cluster().prepareDeleteSnapshot(repoName, newSnapshotName).get(); assertThat(repository.threadPool().relativeTimeInNanos() - beforeThrottledDelete, greaterThan(TEST_COOLDOWN_PERIOD.getNanos())); final long beforeFastDelete = repository.threadPool().relativeTimeInNanos(); - client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{fakeOldSnapshot.getName()}).get(); + client().admin().cluster().prepareDeleteSnapshot(repoName, fakeOldSnapshot.getName()).get(); assertThat(repository.threadPool().relativeTimeInNanos() - beforeFastDelete, lessThan(TEST_COOLDOWN_PERIOD.getNanos())); } @@ -215,7 +215,7 @@ public void testRequestStats() throws Exception { ensureGreen(index); assertHitCount(client().prepareSearch(index).setSize(0).setTrackTotalHits(true).get(), nbDocs); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repository, new String[] {snapshot}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repository, snapshot).get()); final RepositoryStats repositoryStats = StreamSupport.stream( internalCluster().getInstances(RepositoriesService.class).spliterator(), false) diff --git a/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java b/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java index 5523112d6bcf4..15dcfea8cc5d9 100644 --- a/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java +++ b/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java @@ -252,8 +252,7 @@ private static void assertSnapshotStatusSuccessful(RestHighLevelClient client, S } private void deleteSnapshot(RestHighLevelClient client, String repoName, String name) throws IOException { - assertThat(client.snapshot().delete( - new DeleteSnapshotRequest(repoName, name), RequestOptions.DEFAULT).isAcknowledged(), is(true)); + assertThat(client.snapshot().delete(new DeleteSnapshotRequest(repoName, name), RequestOptions.DEFAULT).isAcknowledged(), is(true)); } @SuppressWarnings("unchecked") diff --git a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index d1c8ca99018f1..807c242fd9f46 100644 --- a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -529,7 +529,7 @@ public interface ClusterAdminClient extends ElasticsearchClient { /** * Delete snapshot. */ - DeleteSnapshotRequestBuilder prepareDeleteSnapshot(String repository, String[] snapshot); + DeleteSnapshotRequestBuilder prepareDeleteSnapshot(String repository, String... snapshot); /** * Restores a snapshot. diff --git a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java index 8032db05b38f9..fa288b268b79a 100644 --- a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java +++ b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java @@ -952,7 +952,7 @@ public void deleteSnapshot(DeleteSnapshotRequest request, ActionListener Date: Mon, 20 Apr 2020 21:59:57 +0200 Subject: [PATCH 26/45] shorter diff --- .../action/admin/cluster/RestDeleteSnapshotAction.java | 2 +- .../snapshots/ConcurrentSnapshotExecutionException.java | 5 ----- .../snapshots/CorruptedBlobStoreRepositoryIT.java | 8 ++++---- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java index 561a995afabce..f86739446c89b 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestDeleteSnapshotAction.java @@ -50,7 +50,7 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { DeleteSnapshotRequest deleteSnapshotRequest = deleteSnapshotRequest(request.param("repository"), - request.paramAsStringArray("snapshot", Strings.EMPTY_ARRAY)); + Strings.splitStringByCommaToArray(request.param("snapshot"))); deleteSnapshotRequest.masterNodeTimeout(request.paramAsTime("master_timeout", deleteSnapshotRequest.masterNodeTimeout())); return channel -> client.admin().cluster().deleteSnapshot(deleteSnapshotRequest, new RestToXContentListener<>(channel)); } diff --git a/server/src/main/java/org/elasticsearch/snapshots/ConcurrentSnapshotExecutionException.java b/server/src/main/java/org/elasticsearch/snapshots/ConcurrentSnapshotExecutionException.java index b90a0319646d1..91a40fea09ffb 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/ConcurrentSnapshotExecutionException.java +++ b/server/src/main/java/org/elasticsearch/snapshots/ConcurrentSnapshotExecutionException.java @@ -23,17 +23,12 @@ import org.elasticsearch.rest.RestStatus; import java.io.IOException; -import java.util.Collection; /** * Thrown when a user tries to multiple conflicting snapshot/restore operations at the same time. */ public class ConcurrentSnapshotExecutionException extends SnapshotException { - public ConcurrentSnapshotExecutionException(String repositoryName, Collection snapshots, String msg) { - super(repositoryName, snapshots.size() == 1 ? snapshots.iterator().next().getName() : snapshots.toString(), msg); - } - public ConcurrentSnapshotExecutionException(final String repositoryName, final String snapshotName, final String msg) { super(repositoryName, snapshotName, msg); } diff --git a/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java b/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java index 9be5104665a2d..e563524437e59 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java @@ -111,7 +111,7 @@ public void testConcurrentlyChangeRepositoryContents() throws Exception { .put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES))); logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshot}).get(); + client.admin().cluster().prepareDeleteSnapshot(repoName, snapshot).get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareGetSnapshots(repoName) @@ -185,7 +185,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS assertThat(getRepositoryData(repositoryAfterRestart).getGenId(), is(beforeMoveGen + 1)); logger.info("--> delete snapshot"); - client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshot}).get(); + client().admin().cluster().prepareDeleteSnapshot(repoName, snapshot).get(); logger.info("--> verify index-N blob is found at the expected location"); assertThat(getRepositoryData(repositoryAfterRestart).getGenId(), is(beforeMoveGen + 2)); @@ -247,7 +247,7 @@ public void testHandlingMissingRootLevelSnapshotMetadata() throws Exception { is(SnapshotsService.OLD_SNAPSHOT_FORMAT)); logger.info("--> verify that snapshot with missing root level metadata can be deleted"); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshotToCorrupt.getName()}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotToCorrupt.getName()).get()); logger.info("--> verify that repository is assumed in new metadata format after removing corrupted snapshot"); assertThat(PlainActionFuture.get(f -> threadPool.generic().execute( @@ -305,7 +305,7 @@ public void testMountCorruptedRepositoryData() throws Exception { private void assertRepositoryBlocked(Client client, String repo, String existingSnapshot) { logger.info("--> try to delete snapshot"); final RepositoryException repositoryException3 = expectThrows(RepositoryException.class, - () -> client.admin().cluster().prepareDeleteSnapshot(repo, new String[]{existingSnapshot}).execute().actionGet()); + () -> client.admin().cluster().prepareDeleteSnapshot(repo, existingSnapshot).execute().actionGet()); assertThat(repositoryException3.getMessage(), containsString("Could not read repository data because the contents of the repository do not match its expected state.")); From 44cf43286aa2467256e24dcbae357b03559ee74c Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 22:00:54 +0200 Subject: [PATCH 27/45] shorter diff --- .../xpack/slm/SLMSnapshotBlockingIntegTests.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java index fafaa73a7dc75..448fa2e821580 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java @@ -131,7 +131,7 @@ public void testSnapshotInProgress() throws Exception { // Cancel/delete the snapshot try { - client().admin().cluster().prepareDeleteSnapshot(REPO, new String[]{snapshotName}).get(); + client().admin().cluster().prepareDeleteSnapshot(REPO, snapshotName).get(); } catch (SnapshotMissingException e) { // ignore } @@ -235,7 +235,7 @@ public void testRetentionWhileSnapshotInProgress() throws Exception { assertBusy(() -> { try { logger.info("--> cancelling snapshot {}", secondSnapName); - client().admin().cluster().prepareDeleteSnapshot(REPO, new String[]{secondSnapName}).get(); + client().admin().cluster().prepareDeleteSnapshot(REPO, secondSnapName).get(); } catch (ConcurrentSnapshotExecutionException e) { logger.info("--> attempted to stop second snapshot", e); // just wait and retry @@ -439,7 +439,7 @@ public void testSLMRetentionAfterRestore() throws Exception { // Cancel/delete the snapshot try { - client().admin().cluster().prepareDeleteSnapshot(REPO, new String[]{snapshotName}).get(); + client().admin().cluster().prepareDeleteSnapshot(REPO, snapshotName).get(); } catch (SnapshotMissingException e) { // ignore } From 7002a15c089bd080d4242fdb6d6ba8b17a2a2eb6 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 22:02:12 +0200 Subject: [PATCH 28/45] shorter diff --- .../org/elasticsearch/xpack/slm/SnapshotRetentionTask.java | 3 ++- .../xpack/security/authz/SnapshotUserRoleIntegTests.java | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java index 5e140e39aadf5..b8b4c644922b6 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java @@ -362,6 +362,7 @@ void deleteSnapshots(Map> snapshotsToDelete, for (SnapshotInfo info : snapshots) { final String policyId = getPolicyId(info); final long deleteStartTime = nowNanoSupplier.getAsLong(); + // TODO: Use snapshot multi-delete instead of this loop deleteSnapshot(policyId, repo, info.snapshotId(), slmStats, ActionListener.wrap(acknowledgedResponse -> { deleted.incrementAndGet(); if (acknowledgedResponse.isAcknowledged()) { @@ -418,7 +419,7 @@ void deleteSnapshot(String slmPolicy, String repo, SnapshotId snapshot, Snapshot ActionListener listener) { logger.info("[{}] snapshot retention deleting snapshot [{}]", repo, snapshot); CountDownLatch latch = new CountDownLatch(1); - client.admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot.getName()}) + client.admin().cluster().prepareDeleteSnapshot(repo, snapshot.getName()) .execute(new LatchedActionListener<>(ActionListener.wrap(acknowledgedResponse -> { if (acknowledgedResponse.isAcknowledged()) { logger.debug("[{}] snapshot [{}] deleted successfully", repo, snapshot); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java index 610d192136394..520d495101fdc 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java @@ -126,8 +126,7 @@ public void testSnapshotUserRoleUnathorizedForDestructiveActions() { () -> client.admin().cluster().prepareRestoreSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(), "cluster:admin/snapshot/restore", "snapshot_user"); assertThrowsAuthorizationException( - () -> client.admin().cluster().prepareDeleteSnapshot("repo", - new String[]{randomAlphaOfLength(4).toLowerCase(Locale.ROOT)}).get(), + () -> client.admin().cluster().prepareDeleteSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(), "cluster:admin/snapshot/delete", "snapshot_user"); // try destructive/revealing actions on all indices for (final String indexToTest : Arrays.asList(INTERNAL_SECURITY_MAIN_INDEX_7, SECURITY_MAIN_ALIAS, ordinaryIndex)) { From bda3e6e3a3d3da5aafcd7ff96359595d2970b149 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 22:04:13 +0200 Subject: [PATCH 29/45] shorter diff --- .../blobstore/ESBlobStoreRepositoryIntegTestCase.java | 10 +++++----- .../ESMockAPIBasedRepositoryIntegTestCase.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java index d3c6a0656c1fe..dbf767dd8887e 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java @@ -328,13 +328,13 @@ public void testSnapshotAndRestore() throws Exception { } logger.info("--> delete snapshot {}:{}", repoName, snapshotName); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshotName}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster().prepareGetSnapshots(repoName).setSnapshots(snapshotName).get().getSnapshots(repoName)); expectThrows(SnapshotMissingException.class, () -> - client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshotName}).get()); + client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); expectThrows(SnapshotRestoreException.class, () -> client().admin().cluster().prepareRestoreSnapshot(repoName, snapshotName).setWaitForCompletion(randomBoolean()).get()); @@ -391,7 +391,7 @@ public void testMultipleSnapshotAndRollback() throws Exception { for (int i = 0; i < iterationCount; i++) { logger.info("--> delete snapshot {}:{}", repoName, snapshotName + "-" + i); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshotName + "-" + i}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName + "-" + i).get()); } } @@ -429,7 +429,7 @@ public void testIndicesDeletedFromRepository() throws Exception { assertEquals(createSnapshotResponse.getSnapshotInfo().successfulShards(), createSnapshotResponse.getSnapshotInfo().totalShards()); logger.info("--> delete a snapshot"); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{"test-snap"}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, "test-snap").get()); logger.info("--> verify index folder deleted from blob container"); RepositoriesService repositoriesSvc = internalCluster().getInstance(RepositoriesService.class, internalCluster().getMasterName()); @@ -449,7 +449,7 @@ public void testIndicesDeletedFromRepository() throws Exception { } } - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{"test-snap2"}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, "test-snap2").get()); } protected void addRandomDocuments(String name, int numDocs) throws InterruptedException { diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java index 5022c9ae6715c..045cb3f56993d 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESMockAPIBasedRepositoryIntegTestCase.java @@ -156,7 +156,7 @@ public final void testSnapshotWithLargeSegmentFiles() throws Exception { ensureGreen(index); assertHitCount(client().prepareSearch(index).setSize(0).setTrackTotalHits(true).get(), nbDocs); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repository, new String[]{snapshot}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repository, snapshot).get()); } protected static String httpServerUrl() { From b84152803fdec34a6c3f0f416beecee1a437d60e Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 22:06:07 +0200 Subject: [PATCH 30/45] shorter diff --- .../snapshots/DedicatedClusterSnapshotRestoreIT.java | 4 ++-- .../snapshots/MetadataLoadingDuringSnapshotRestoreIT.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java index 752327c83d07a..45ca1f0d545b5 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java @@ -473,7 +473,7 @@ public void testSnapshotWithStuckNode() throws Exception { logger.info("--> execution was blocked on node [{}], aborting snapshot", blockedNode); ActionFuture deleteSnapshotResponseFuture = internalCluster().client(nodes.get(0)) - .admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap"}).execute(); + .admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").execute(); // Make sure that abort makes some progress Thread.sleep(100); unblockNode("test-repo", blockedNode); @@ -1153,7 +1153,7 @@ public void testSnapshotTotalAndIncrementalSizes() throws IOException { // drop 1st one to avoid miscalculation as snapshot reuses some files of prev snapshot assertTrue(client.admin().cluster() - .prepareDeleteSnapshot(repositoryName, new String[]{snapshot0}) + .prepareDeleteSnapshot(repositoryName, snapshot0) .get().isAcknowledged()); response = client.admin().cluster().prepareSnapshotStatus(repositoryName) diff --git a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java index 2d62749c0f7ba..34761fc07ef9a 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java @@ -139,7 +139,7 @@ public void testWhenMetadataAreLoaded() throws Exception { assertIndexMetadataLoads("snap", "others", 3); // Deleting a snapshot does not load the global metadata state but loads each index metadata - assertAcked(client().admin().cluster().prepareDeleteSnapshot("repository", new String[]{"snap"}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot("repository", "snap").get()); assertGlobalMetadataLoads("snap", 1); assertIndexMetadataLoads("snap", "docs", 4); assertIndexMetadataLoads("snap", "others", 3); From e02710e0e873232e162bb63b1236940dfacda132 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 22:06:54 +0200 Subject: [PATCH 31/45] shorter diff --- .../snapshots/MinThreadsSnapshotRestoreIT.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java index 9d16f4086e5b1..738d97e3e2998 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java @@ -84,13 +84,13 @@ public void testConcurrentSnapshotDeletionsNotAllowed() throws Exception { ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of first snapshot"); ActionFuture future = - client().admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot2}).execute(); + client().admin().cluster().prepareDeleteSnapshot(repo, snapshot2).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); logger.info("--> try deleting the second snapshot, should fail because the first deletion is in progress"); try { - client().admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot1}).get(); + client().admin().cluster().prepareDeleteSnapshot(repo, snapshot1).get(); fail("should not be able to delete snapshots concurrently"); } catch (ConcurrentSnapshotExecutionException e) { assertThat(e.getMessage(), containsString("cannot delete - another snapshot is currently being deleted")); @@ -103,7 +103,7 @@ public void testConcurrentSnapshotDeletionsNotAllowed() throws Exception { assertAcked(future.actionGet()); logger.info("--> delete second snapshot, which should now work"); - client().admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot1}).get(); + client().admin().cluster().prepareDeleteSnapshot(repo, snapshot1).get(); assertTrue(client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots(repo).isEmpty()); } From 9d6bfb5f4cce77bc35e17573fbf6912843de5ab3 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 22:08:15 +0200 Subject: [PATCH 32/45] shorter diff --- .../elasticsearch/snapshots/SnapshotResiliencyTests.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java index c7e6dec9104f4..54e8f4eaac836 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java @@ -429,8 +429,7 @@ public void testSnapshotDeleteWithMasterFailover() { continueOrDie(createSnapshotResponseStepListener, createSnapshotResponse -> { scheduleNow(this::disconnectOrRestartMasterNode); testClusterNodes.randomDataNodeSafe().client.admin().cluster() - .prepareDeleteSnapshot(repoName, new String[]{snapshotName}) - .execute(ActionListener.wrap(() -> snapshotDeleteResponded.set(true))); + .prepareDeleteSnapshot(repoName, snapshotName).execute(ActionListener.wrap(() -> snapshotDeleteResponded.set(true))); }); runUntil(() -> testClusterNodes.randomMasterNode().map(master -> { @@ -477,8 +476,7 @@ public void testConcurrentSnapshotCreateAndDelete() { public void clusterChanged(ClusterChangedEvent event) { final SnapshotsInProgress snapshotsInProgress = event.state().custom(SnapshotsInProgress.TYPE); if (snapshotsInProgress != null && snapshotsInProgress.entries().isEmpty() == false) { - client().admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshotName}) - .execute(deleteSnapshotStepListener); + client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).execute(deleteSnapshotStepListener); masterNode.clusterService.removeListener(this); } } @@ -610,8 +608,7 @@ public void testConcurrentSnapshotRestoreAndDeleteOther() { continueOrDie(createOtherSnapshotResponseStepListener, createSnapshotResponse -> { scheduleNow( - () -> client().admin().cluster().prepareDeleteSnapshot(repoName, new String[] {snapshotName}) - .execute(deleteSnapshotStepListener)); + () -> client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).execute(deleteSnapshotStepListener)); scheduleNow(() -> client().admin().cluster().restoreSnapshot( new RestoreSnapshotRequest(repoName, secondSnapshotName).waitForCompletion(true) .renamePattern("(.+)").renameReplacement("restored_$1"), From 4cb1dd52eeb017e212b587c1c055132fe96a2179 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 22:11:23 +0200 Subject: [PATCH 33/45] shorter diff --- .../action/admin/cluster/snapshots/SnapshotBlocksIT.java | 3 +-- .../elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java index 1a88f8c37f4a9..90e544e9626e1 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java @@ -124,8 +124,7 @@ public void testDeleteSnapshotWithBlocks() { logger.info("--> deleting a snapshot is allowed when the cluster is read only"); try { setClusterReadOnly(true); - assertTrue( - client().admin().cluster().prepareDeleteSnapshot(REPOSITORY_NAME, new String[]{SNAPSHOT_NAME}).get().isAcknowledged()); + assertTrue(client().admin().cluster().prepareDeleteSnapshot(REPOSITORY_NAME, SNAPSHOT_NAME).get().isAcknowledged()); } finally { setClusterReadOnly(false); } diff --git a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java index 738d97e3e2998..9f437cdf70d35 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java @@ -129,8 +129,7 @@ public void testSnapshottingWithInProgressDeletionNotAllowed() throws Exception String blockedNode = internalCluster().getMasterName(); ((MockRepository)internalCluster().getInstance(RepositoriesService.class, blockedNode).repository(repo)).blockOnDataFiles(true); logger.info("--> start deletion of snapshot"); - ActionFuture future = - client().admin().cluster().prepareDeleteSnapshot(repo, new String[]{snapshot1}).execute(); + ActionFuture future = client().admin().cluster().prepareDeleteSnapshot(repo, snapshot1).execute(); logger.info("--> waiting for block to kick in on node [{}]", blockedNode); waitForBlock(blockedNode, repo, TimeValue.timeValueSeconds(10)); From b9171d599b46509c328961ea9cb169468e971631 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 20 Apr 2020 22:12:30 +0200 Subject: [PATCH 34/45] shorter diff --- .../repositories/AbstractThirdPartyRepositoryTestCase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java index b5d67a189a110..ceb2272e460da 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java @@ -132,7 +132,7 @@ public void testCreateSnapshot() { assertTrue(client().admin() .cluster() - .prepareDeleteSnapshot("test-repo", new String[]{snapshotName}) + .prepareDeleteSnapshot("test-repo", snapshotName) .get() .isAcknowledged()); } From bf48d12fd6b1e36037e1a98d61e18d1ada85092f Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 21 Apr 2020 08:31:02 +0200 Subject: [PATCH 35/45] shorter diff --- .../ClusterSerializationTests.java | 6 ++--- .../SharedClusterSnapshotRestoreIT.java | 27 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/cluster/serialization/ClusterSerializationTests.java b/server/src/test/java/org/elasticsearch/cluster/serialization/ClusterSerializationTests.java index e9c72590229e4..41d46e50aa66c 100644 --- a/server/src/test/java/org/elasticsearch/cluster/serialization/ClusterSerializationTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/serialization/ClusterSerializationTests.java @@ -118,9 +118,9 @@ public void testSnapshotDeletionsInProgressSerialization() throws Exception { ClusterState.Builder builder = ClusterState.builder(ClusterState.EMPTY_STATE) .putCustom(SnapshotDeletionsInProgress.TYPE, SnapshotDeletionsInProgress.newInstance( - new SnapshotDeletionsInProgress.Entry( - Collections.singletonList(new SnapshotId("snap1", UUIDs.randomBase64UUID())), "repo1", - randomNonNegativeLong(), randomNonNegativeLong()) + new SnapshotDeletionsInProgress.Entry( + Collections.singletonList(new SnapshotId("snap1", UUIDs.randomBase64UUID())), "repo1", + randomNonNegativeLong(), randomNonNegativeLong()) )); if (includeRestore) { builder.putCustom(RestoreInProgress.TYPE, diff --git a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 3488425bc6897..1b79b2c9f7402 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -1326,7 +1326,7 @@ public void testDeleteSnapshot() throws Exception { assertThat(client.prepareSearch("test-idx").setSize(0).get().getHits().getTotalHits().value, equalTo(10L * numberOfSnapshots)); logger.info("--> delete the last snapshot"); - client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{lastSnapshot}).get(); + client.admin().cluster().prepareDeleteSnapshot("test-repo", lastSnapshot).get(); logger.info("--> make sure that number of files is back to what it was when the first snapshot was made"); assertFileCount(repo, numberOfFiles[0]); } @@ -1471,7 +1471,7 @@ public void testDeleteSnapshotWithMissingIndexAndShardMetadata() throws Exceptio } logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap-1"}).get(); + client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-1").get(); logger.info("--> make sure snapshot doesn't exist"); @@ -1512,7 +1512,7 @@ public void testDeleteSnapshotWithMissingMetadata() throws Exception { Files.delete(metadata); logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap-1"}).get(); + client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-1").get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareGetSnapshots("test-repo") @@ -1549,7 +1549,7 @@ public void testDeleteSnapshotWithCorruptedSnapshotFile() throws Exception { outChan.truncate(randomInt(10)); } logger.info("--> delete snapshot"); - client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap-1"}).get(); + client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-1").get(); logger.info("--> make sure snapshot doesn't exist"); expectThrows(SnapshotMissingException.class, @@ -1610,7 +1610,7 @@ public void testDeleteSnapshotWithCorruptedGlobalState() throws Exception { assertThat(snapshotStatusResponse.getSnapshots(), hasSize(1)); assertThat(snapshotStatusResponse.getSnapshots().get(0).getSnapshot().getSnapshotId().getName(), equalTo("test-snap")); - assertAcked(client().admin().cluster().prepareDeleteSnapshot("test-repo", new String[]{"test-snap"}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").get()); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster() .prepareGetSnapshots("test-repo").addSnapshots("test-snap").get().getSnapshots("test-repo")); assertRequestBuilderThrows(client().admin().cluster().prepareSnapshotStatus("test-repo").addSnapshots("test-snap"), @@ -2024,8 +2024,8 @@ public void testReadonlyRepository() throws Exception { assertThat(getSnapshotsResponse.getSnapshots("readonly-repo").size(), equalTo(1)); logger.info("--> try deleting snapshot"); - assertRequestBuilderThrows(client.admin().cluster().prepareDeleteSnapshot("readonly-repo", new String[]{"test-snap"}), - RepositoryException.class, "cannot delete snapshot from a readonly repository"); + assertRequestBuilderThrows(client.admin().cluster().prepareDeleteSnapshot("readonly-repo", "test-snap"), RepositoryException.class, + "cannot delete snapshot from a readonly repository"); logger.info("--> try making another snapshot"); assertRequestBuilderThrows(client.admin().cluster().prepareCreateSnapshot("readonly-repo", "test-snap-2") @@ -2715,7 +2715,7 @@ public void testDeleteSnapshotWhileRestoringFails() throws Exception { logger.info("--> try deleting the snapshot while the restore is in progress (should throw an error)"); ConcurrentSnapshotExecutionException e = expectThrows(ConcurrentSnapshotExecutionException.class, () -> - client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshotName}).get()); + client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); assertEquals(repoName, e.getRepositoryName()); assertEquals(snapshotName, e.getSnapshotName()); assertThat(e.getMessage(), containsString("cannot delete snapshot during a restore")); @@ -2754,7 +2754,7 @@ public void testSnapshotName() throws Exception { () -> client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("_foo") .get().getSnapshots("test-repo")); expectThrows(SnapshotMissingException.class, - () -> client.admin().cluster().prepareDeleteSnapshot("test-repo", new String[] {"_foo"}).get()); + () -> client.admin().cluster().prepareDeleteSnapshot("test-repo", "_foo").get()); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareSnapshotStatus("test-repo").setSnapshots("_foo").get()); } @@ -2953,8 +2953,7 @@ public void testRestoreSnapshotWithCorruptedIndexMetadata() throws Exception { } } - assertAcked(client().admin().cluster().prepareDeleteSnapshot("test-repo", - new String[]{snapshotInfo.snapshotId().getName()}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot("test-repo", snapshotInfo.snapshotId().getName()).get()); } /** @@ -3099,7 +3098,7 @@ public void testCannotCreateSnapshotsWithSameName() throws Exception { } logger.info("--> delete the first snapshot"); - client.admin().cluster().prepareDeleteSnapshot(repositoryName, new String[]{snapshotName}).get(); + client.admin().cluster().prepareDeleteSnapshot(repositoryName, snapshotName).get(); logger.info("--> try creating a snapshot with the same name, now it should work because the first one was deleted"); createSnapshotResponse = client.admin() @@ -3168,7 +3167,7 @@ public void testGetSnapshotsRequest() throws Exception { assertEquals("snap-on-empty-repo", getSnapshotsResponse.getSnapshots("test-repo").get(0).snapshotId().getName()); unblockNode(repositoryName, initialBlockedNode); // unblock node responseListener.actionGet(TimeValue.timeValueMillis(10000L)); // timeout after 10 seconds - client.admin().cluster().prepareDeleteSnapshot(repositoryName, new String[]{"snap-on-empty-repo"}).get(); + client.admin().cluster().prepareDeleteSnapshot(repositoryName, "snap-on-empty-repo").get(); final int numSnapshots = randomIntBetween(1, 3) + 1; logger.info("--> take {} snapshot(s)", numSnapshots - 1); @@ -3835,7 +3834,7 @@ public void testSnapshotDifferentIndicesBySameName() { expectedCount = docCount; } logger.info("--> deleting snapshot [{}]", snapshotToDelete); - assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, new String[]{snapshotToDelete}).get()); + assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotToDelete).get()); logger.info("--> restoring snapshot [{}]", snapshotToRestore); client().admin().cluster().prepareRestoreSnapshot(repoName, snapshotToRestore).setIndices(indexName).setRenamePattern(indexName) .setRenameReplacement("restored-3").setWaitForCompletion(true).get(); From eada6f28400a1062af859789eae4050a85c760de Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 21 Apr 2020 08:32:24 +0200 Subject: [PATCH 36/45] shorter diff --- .../client/documentation/SnapshotClientDocumentationIT.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 745e7365eca82..3bc021b59a48f 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 @@ -752,7 +752,8 @@ public void testSnapshotDeleteSnapshot() throws IOException { createTestSnapshots(); // tag::delete-snapshot-request - DeleteSnapshotRequest request = new DeleteSnapshotRequest(repositoryName, snapshotName); + DeleteSnapshotRequest request = new DeleteSnapshotRequest(repositoryName); + request.snapshots(snapshotName); // end::delete-snapshot-request // tag::delete-snapshot-request-masterTimeout From 8440aef3c3c10e56a4290ed5abd1f30e5f10bd10 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 21 Apr 2020 08:34:11 +0200 Subject: [PATCH 37/45] fix docs --- .../snapshots/delete/DeleteSnapshotRequest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java index 1239e1005381e..504d2d94da8e9 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java @@ -32,9 +32,8 @@ /** * Delete snapshot request *

    - * Delete snapshot request removes the snapshot record from the repository and cleans up all - * files that are associated with this particular snapshot. All files that are shared with - * at least one other existing snapshot are left intact. + * Delete snapshot request removes snapshots from the repository and cleans up all files that are associated with the snapshots. + * All files that are shared with at least one other existing snapshot are left intact. */ public class DeleteSnapshotRequest extends MasterNodeRequest { @@ -131,16 +130,16 @@ public String repository() { } /** - * Returns repository name + * Returns snapshot names * - * @return repository name + * @return snapshot names */ public String[] snapshots() { return this.snapshots; } /** - * Sets snapshot name + * Sets snapshot names * * @return this request */ From 151ae507f758c434ad731158542413bef4436800 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 21 Apr 2020 08:40:52 +0200 Subject: [PATCH 38/45] docs --- docs/reference/snapshot-restore/take-snapshot.asciidoc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/reference/snapshot-restore/take-snapshot.asciidoc b/docs/reference/snapshot-restore/take-snapshot.asciidoc index 20c2b4837306b..aeeb18ecfc2d6 100644 --- a/docs/reference/snapshot-restore/take-snapshot.asciidoc +++ b/docs/reference/snapshot-restore/take-snapshot.asciidoc @@ -193,6 +193,15 @@ created the snapshotting process will be aborted and all files created as part o cleaned. Therefore, the delete snapshot operation can be used to cancel long running snapshot operations that were started by mistake. +It is also possible to delete multiple snapshots from a repository in one go, for example: + +[source,console] +----------------------------------- +DELETE /_snapshot/my_backup/my_backup,my_fs_backup +DELETE /_snapshot/my_backup/snap* +----------------------------------- +// TEST[skip:no my_fs_backup] + A repository can be unregistered using the following command: [source,console] From 8bfb7b2079dce60887cc75b8b455281aa5cdf52b Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 21 Apr 2020 08:56:01 +0200 Subject: [PATCH 39/45] rearrange stuff --- .../snapshots/SnapshotsService.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index a7bdd6acb4e2f..aef7f5439b6bf 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -1009,6 +1009,11 @@ public void deleteSnapshots(final String repositoryName, final Collection 1 && currentState.nodes().getMinNodeVersion().before(MULTI_DELETE_VERSION)) { + throw new IllegalArgumentException("Deleting multiple snapshots in a single request is only supported in version [ " + + MULTI_DELETE_VERSION + "] but cluster contained node of version [" + currentState.nodes().getMinNodeVersion() + + "]"); + } final SnapshotsInProgress snapshots = currentState.custom(SnapshotsInProgress.TYPE); final SnapshotsInProgress.Entry snapshotEntry = findInProgressSnapshot(snapshots, snapshotNames, repositoryName); if (snapshotEntry == null) { @@ -1085,10 +1090,11 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS addListener(runningSnapshot, ActionListener.wrap( result -> { logger.debug("deleted snapshot completed - deleting files"); - final List foundSnapshots = matchingSnapshotIds(result.v1(), snapshotNames, repositoryName); + final RepositoryData newRepoData = result.v1(); + final List foundSnapshots = matchingSnapshotIds(newRepoData, snapshotNames, repositoryName); assert foundSnapshots.contains(runningSnapshot.getSnapshotId()) : "Expected new RepositoryData to contain [" - + runningSnapshot + "] but it only contained snapshots " + result.v1().getSnapshotIds(); - deleteCompletedSnapshots(foundSnapshots, repositoryName, result.v1().getGenId(), Priority.IMMEDIATE, listener); + + runningSnapshot + "] but it only contained snapshots " + newRepoData.getSnapshotIds(); + deleteCompletedSnapshots(foundSnapshots, repositoryName, newRepoData.getGenId(), Priority.IMMEDIATE, listener); }, e -> { if (abortedDuringInit) { @@ -1115,15 +1121,17 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS } )); } - }); - } - private void resolveAndDeleteSnapshots(Collection snapshotsOrPatterns, ActionListener listener, String repositoryName) { - assert snapshotsOrPatterns.isEmpty() == false; - threadPool.generic().execute(ActionRunnable.wrap(listener, l -> - repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> - deleteCompletedSnapshots(matchingSnapshotIds(repositoryData, snapshotsOrPatterns, repositoryName), repositoryName, - repositoryData.getGenId(), Priority.NORMAL, l), l::onFailure)))); + // load latest repository data and run delete for all matching snapshots + private void resolveAndDeleteSnapshots(Collection snapshotsOrPatterns, ActionListener listener, + String repositoryName) { + assert snapshotsOrPatterns.isEmpty() == false; + threadPool.generic().execute(ActionRunnable.wrap(listener, l -> + repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> + deleteCompletedSnapshots(matchingSnapshotIds(repositoryData, snapshotsOrPatterns, repositoryName), + repositoryName, repositoryData.getGenId(), Priority.NORMAL, l), l::onFailure)))); + } + }); } private static List matchingSnapshotIds(RepositoryData repositoryData, Collection snapshotsOrPatterns, From a12e52070e5c69db09a386192fcf93e876190b60 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 21 Apr 2020 09:04:41 +0200 Subject: [PATCH 40/45] shorter --- .../java/org/elasticsearch/snapshots/SnapshotsService.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index aef7f5439b6bf..0845da081b9dd 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -1167,10 +1167,9 @@ private static SnapshotsInProgress.Entry findInProgressSnapshot(@Nullable Snapsh } final String[] snapshotsOrPatterns = snapshotNames.toArray(Strings.EMPTY_ARRAY); for (SnapshotsInProgress.Entry entry : snapshots.entries()) { - if (entry.repository().equals(repositoryName)) { - if (Regex.simpleMatch(snapshotsOrPatterns, entry.snapshot().getSnapshotId().getName())) { - return entry; - } + if (entry.repository().equals(repositoryName) + && Regex.simpleMatch(snapshotsOrPatterns, entry.snapshot().getSnapshotId().getName())) { + return entry; } } return null; From 2ebf708965e28045302904e1fd2f9a2880dce2f7 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 21 Apr 2020 09:24:49 +0200 Subject: [PATCH 41/45] some improvemnts --- .../blobstore/BlobStoreRepository.java | 37 +++++++------------ 1 file changed, 13 insertions(+), 24 deletions(-) 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 abef4d6a63140..7093523534537 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -651,12 +651,10 @@ private void writeUpdatedShardMetaDataAndComputeDeletes(Collection s for (IndexId indexId : indices) { final Set survivingSnapshots = oldRepositoryData.getSnapshots(indexId).stream() .filter(id -> snapshotIds.contains(id) == false).collect(Collectors.toSet()); - final StepListener shardCountListener = new StepListener<>(); - final ActionListener shardCounts = new GroupedActionListener<>(ActionListener.wrap( - counts -> shardCountListener.onResponse(counts.stream().mapToInt(i -> i).max().orElse(0)), - shardCountListener::onFailure), snapshotIds.size()); + final StepListener> shardCountListener = new StepListener<>(); + final ActionListener allShardCountsListener = new GroupedActionListener<>(shardCountListener, snapshotIds.size()); for (SnapshotId snapshotId : snapshotIds) { - executor.execute(ActionRunnable.supply(shardCounts, () -> { + executor.execute(ActionRunnable.supply(allShardCountsListener, () -> { try { return getSnapshotIndexMetadata(snapshotId, indexId).getNumberOfShards(); } catch (Exception ex) { @@ -670,7 +668,8 @@ private void writeUpdatedShardMetaDataAndComputeDeletes(Collection s } })); } - shardCountListener.whenComplete(shardCount -> { + shardCountListener.whenComplete(counts -> { + final int shardCount = counts.stream().mapToInt(i -> i).max().orElse(0); if (shardCount == 0) { deleteIndexMetadataListener.onResponse(null); return; @@ -684,7 +683,7 @@ private void writeUpdatedShardMetaDataAndComputeDeletes(Collection s @Override protected void doRun() throws Exception { final BlobContainer shardContainer = shardContainer(indexId, finalShardId); - final Set blobs = getShardBlobs(shardContainer); + final Set blobs = shardContainer.listBlobs().keySet(); final BlobStoreIndexShardSnapshots blobStoreIndexShardSnapshots; final String newGen; if (useUUIDs) { @@ -692,8 +691,7 @@ protected void doRun() throws Exception { blobStoreIndexShardSnapshots = buildBlobStoreIndexShardSnapshots(blobs, shardContainer, oldRepositoryData.shardGenerations().getShardGen(indexId, finalShardId)).v1(); } else { - Tuple tuple = - buildBlobStoreIndexShardSnapshots(blobs, shardContainer); + Tuple tuple = buildBlobStoreIndexShardSnapshots(blobs, shardContainer); newGen = Long.toString(tuple.v2() + 1); blobStoreIndexShardSnapshots = tuple.v1(); } @@ -704,8 +702,8 @@ protected void doRun() throws Exception { @Override public void onFailure(Exception ex) { logger.warn( - () -> new ParameterizedMessage("[{}] failed to delete shard data for shard [{}][{}]", - snapshotIds, indexId.getName(), finalShardId), ex); + () -> new ParameterizedMessage("{} failed to delete shard data for shard [{}][{}]", + snapshotIds, indexId.getName(), finalShardId), ex); // Just passing null here to count down the listener instead of failing it, the stale data left behind // here will be retried in the next delete or repository cleanup allShardsListener.onResponse(null); @@ -726,9 +724,10 @@ private List resolveFilesToDelete(Collection snapshotIds, shardContainer(shardResult.indexId, shardResult.shardId).path().buildAsString(); return shardResult.blobsToDelete.stream().map(blob -> shardPath + blob); }), - deleteResults.stream().map(shardResult -> shardResult.indexId).distinct().flatMap(indexId -> - snapshotIds.stream().map(snapshotId -> // TODO: Add filter via RepositoryData - indexContainer(indexId).path().buildAsString() + globalMetadataFormat.blobName(snapshotId.getUUID()))) + deleteResults.stream().map(shardResult -> shardResult.indexId).distinct().flatMap(indexId -> { + final String indexContainerPath = indexContainer(indexId).path().buildAsString(); + return snapshotIds.stream().map(snapshotId -> indexContainerPath + globalMetadataFormat.blobName(snapshotId.getUUID())); + }) ).map(absolutePath -> { assert absolutePath.startsWith(basePath); return absolutePath.substring(basePathLen); @@ -1953,16 +1952,6 @@ private void writeShardIndexBlob(BlobContainer shardContainer, String indexGener indexShardSnapshotsFormat.writeAtomic(updatedSnapshots, shardContainer, indexGeneration); } - private static Set getShardBlobs(BlobContainer shardContainer) throws IOException { - final Set blobs; - try { - blobs = shardContainer.listBlobs().keySet(); - } catch (IOException e) { - throw new IOException("Failed to list content of shard directory", e); - } - return blobs; - } - // Unused blobs are all previous index-, data- and meta-blobs and that are not referenced by the new index- as well as all // temporary blobs private static List unusedBlobs(Set blobs, Set survivingSnapshotUUIDs, From 0a392ec6366a25bb746820a87f0766b0d93a11da Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 21 Apr 2020 09:34:16 +0200 Subject: [PATCH 42/45] some improvemnts --- .../repositories/blobstore/BlobStoreRepository.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 7093523534537..34fc2b56e7730 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -1919,7 +1919,7 @@ private ShardSnapshotMetaDeleteResult deleteFromShardSnapshotMeta(Set snapshotIds, BlobContainer shardContainer, Set blobs, BlobStoreIndexShardSnapshots snapshots, - String indexGeneration) throws IOException { + String indexGeneration) { // Build a list of snapshots that should be preserved List newSnapshotsList = new ArrayList<>(); final Set survivingSnapshotNames = survivingSnapshots.stream().map(SnapshotId::getName).collect(Collectors.toSet()); @@ -1939,9 +1939,8 @@ private ShardSnapshotMetaDeleteResult deleteFromShardSnapshotMeta(Set Date: Tue, 21 Apr 2020 10:25:30 +0200 Subject: [PATCH 43/45] lets keep it simple --- .../snapshots/SnapshotsService.java | 58 +++++++++---------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index 0845da081b9dd..a42b167e6781b 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -89,6 +89,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -1015,7 +1016,17 @@ public ClusterState execute(ClusterState currentState) { + "]"); } final SnapshotsInProgress snapshots = currentState.custom(SnapshotsInProgress.TYPE); - final SnapshotsInProgress.Entry snapshotEntry = findInProgressSnapshot(snapshots, snapshotNames, repositoryName); + final SnapshotsInProgress.Entry snapshotEntry; + if (snapshotNames.size() == 1) { + final String snapshotName = snapshotNames.iterator().next(); + if (Regex.isSimpleMatchPattern(snapshotName)) { + snapshotEntry = null; + } else { + snapshotEntry = findInProgressSnapshot(snapshots, snapshotName, repositoryName); + } + } else { + snapshotEntry = null; + } if (snapshotEntry == null) { return currentState; } @@ -1083,29 +1094,23 @@ public void onFailure(String source, Exception e) { @Override public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { if (runningSnapshot == null) { - resolveAndDeleteSnapshots(snapshotNames, listener, repositoryName); + threadPool.generic().execute(ActionRunnable.wrap(listener, l -> + repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> + deleteCompletedSnapshots(matchingSnapshotIds(repositoryData, snapshotNames, repositoryName), + repositoryName, repositoryData.getGenId(), Priority.NORMAL, l), l::onFailure)))); return; } logger.trace("adding snapshot completion listener to wait for deleted snapshot to finish"); addListener(runningSnapshot, ActionListener.wrap( result -> { logger.debug("deleted snapshot completed - deleting files"); - final RepositoryData newRepoData = result.v1(); - final List foundSnapshots = matchingSnapshotIds(newRepoData, snapshotNames, repositoryName); - assert foundSnapshots.contains(runningSnapshot.getSnapshotId()) : "Expected new RepositoryData to contain [" - + runningSnapshot + "] but it only contained snapshots " + newRepoData.getSnapshotIds(); - deleteCompletedSnapshots(foundSnapshots, repositoryName, newRepoData.getGenId(), Priority.IMMEDIATE, listener); + deleteCompletedSnapshots(Collections.singletonList(result.v2().snapshotId()), repositoryName, + result.v1().getGenId(), Priority.IMMEDIATE, listener); }, e -> { if (abortedDuringInit) { logger.info("Successfully aborted snapshot [{}]", runningSnapshot); - final Collection remainingPatterns = new ArrayList<>(snapshotNames); - remainingPatterns.remove(runningSnapshot.getSnapshotId().getName()); - if (remainingPatterns.isEmpty()) { - listener.onResponse(null); - return; - } - resolveAndDeleteSnapshots(remainingPatterns, listener, repositoryName); + listener.onResponse(null); } else { if (ExceptionsHelper.unwrap(e, NotMasterException.class, FailedToCommitClusterStateException.class) != null) { @@ -1121,16 +1126,6 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS } )); } - - // load latest repository data and run delete for all matching snapshots - private void resolveAndDeleteSnapshots(Collection snapshotsOrPatterns, ActionListener listener, - String repositoryName) { - assert snapshotsOrPatterns.isEmpty() == false; - threadPool.generic().execute(ActionRunnable.wrap(listener, l -> - repositoriesService.repository(repositoryName).getRepositoryData(ActionListener.wrap(repositoryData -> - deleteCompletedSnapshots(matchingSnapshotIds(repositoryData, snapshotsOrPatterns, repositoryName), - repositoryName, repositoryData.getGenId(), Priority.NORMAL, l), l::onFailure)))); - } }); } @@ -1160,19 +1155,20 @@ private static List matchingSnapshotIds(RepositoryData repositoryDat // Return in-progress snapshot entry by name and repository in the given cluster state or null if none is found @Nullable - private static SnapshotsInProgress.Entry findInProgressSnapshot(@Nullable SnapshotsInProgress snapshots, - Collection snapshotNames, String repositoryName) { + private static SnapshotsInProgress.Entry findInProgressSnapshot(@Nullable SnapshotsInProgress snapshots, String snapshotName, + String repositoryName) { if (snapshots == null) { return null; } - final String[] snapshotsOrPatterns = snapshotNames.toArray(Strings.EMPTY_ARRAY); + SnapshotsInProgress.Entry snapshotEntry = null; for (SnapshotsInProgress.Entry entry : snapshots.entries()) { if (entry.repository().equals(repositoryName) - && Regex.simpleMatch(snapshotsOrPatterns, entry.snapshot().getSnapshotId().getName())) { - return entry; + && entry.snapshot().getSnapshotId().getName().equals(snapshotName)) { + snapshotEntry = entry; + break; } } - return null; + return snapshotEntry; } /** @@ -1267,7 +1263,7 @@ public Version minCompatibleVersion(Version minNodeVersion, String repositoryNam Version minCompatVersion = minNodeVersion; final Collection snapshotIds = repositoryData.getSnapshotIds(); final Repository repository = repositoriesService.repository(repositoryName); - for (SnapshotId snapshotId : snapshotIds.stream().filter(snapshotId -> excluded == null || excluded.contains(snapshotId) == false) + for (SnapshotId snapshotId : snapshotIds.stream().filter(excluded == null ? sn -> true : Predicate.not(excluded::contains)) .collect(Collectors.toList())) { final Version known = repositoryData.getVersion(snapshotId); // If we don't have the version cached in the repository data yet we load it from the snapshot info blobs From b41bab3838ecd231ca4a17d4466118210d88ded6 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Tue, 21 Apr 2020 12:48:23 +0200 Subject: [PATCH 44/45] update javadoc wording --- .../org/elasticsearch/snapshots/SnapshotsService.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index a42b167e6781b..c3f35eb7616f8 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -990,10 +990,11 @@ private void failSnapshotCompletionListeners(Snapshot snapshot, Exception e) { } /** - * Deletes a snapshot from the repository or aborts a running snapshot. - * First checks if the snapshot is still running and if so cancels the snapshot and then deletes it from the repository. - * If the snapshot is not running, moves to trying to find a matching {@link Snapshot} for the given name in the repository and if - * one is found deletes it by invoking {@link #deleteCompletedSnapshots}. + * Deletes snapshots from the repository or aborts a running snapshot. + * If deleting a single snapshot, first checks if a snapshot is still running and if so cancels the snapshot and then deletes it from + * the repository. + * If the snapshot is not running or multiple snapshot names are given, moves to trying to find a matching {@link Snapshot}s for the + * given names in the repository and deletes them by invoking {@link #deleteCompletedSnapshots}. * * @param repositoryName repositoryName * @param snapshotNames snapshotNames From 0efa76fadc5079cfa396290818b45f2d352ad9cb Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Wed, 22 Apr 2020 11:33:02 +0200 Subject: [PATCH 45/45] CR comments --- .../delete/DeleteSnapshotRequest.java | 16 ++------- .../delete/DeleteSnapshotRequestBuilder.java | 2 +- .../org/elasticsearch/client/Requests.java | 2 +- .../cluster/SnapshotDeletionsInProgress.java | 2 ++ .../snapshots/SnapshotsService.java | 4 +-- .../SharedClusterSnapshotRestoreIT.java | 35 +++++++++++++++++++ .../xpack/slm/SnapshotRetentionTask.java | 3 +- 7 files changed, 46 insertions(+), 18 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java index 504d2d94da8e9..6089e7ab15187 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequest.java @@ -48,22 +48,12 @@ public DeleteSnapshotRequest() { } /** - * Constructs a new delete snapshots request with repository and snapshot name + * Constructs a new delete snapshots request with repository and snapshot names * * @param repository repository name - * @param snapshot snapshot name + * @param snapshots snapshot names */ - public DeleteSnapshotRequest(String repository, String snapshot) { - this(repository, new String[]{snapshot}); - } - - /** - * Constructs a new delete snapshots request with repository and snapshot name - * - * @param repository repository name - * @param snapshots snapshot names - */ - public DeleteSnapshotRequest(String repository, String[] snapshots) { + public DeleteSnapshotRequest(String repository, String... snapshots) { this.repository = repository; this.snapshots = snapshots; } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java index 2e9556d2dfc1a..ac429d85269e4 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/delete/DeleteSnapshotRequestBuilder.java @@ -39,7 +39,7 @@ public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAc /** * Constructs delete snapshot request builder with specified repository and snapshot names */ - public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAction action, String repository, String[] snapshots) { + public DeleteSnapshotRequestBuilder(ElasticsearchClient client, DeleteSnapshotAction action, String repository, String... snapshots) { super(client, action, new DeleteSnapshotRequest(repository, snapshots)); } diff --git a/server/src/main/java/org/elasticsearch/client/Requests.java b/server/src/main/java/org/elasticsearch/client/Requests.java index f512ad8ea35d6..445c1935fad54 100644 --- a/server/src/main/java/org/elasticsearch/client/Requests.java +++ b/server/src/main/java/org/elasticsearch/client/Requests.java @@ -508,7 +508,7 @@ public static RestoreSnapshotRequest restoreSnapshotRequest(String repository, S * @param repository repository name * @return delete snapshot request */ - public static DeleteSnapshotRequest deleteSnapshotRequest(String repository, String[] snapshots) { + public static DeleteSnapshotRequest deleteSnapshotRequest(String repository, String... snapshots) { return new DeleteSnapshotRequest(repository, snapshots); } diff --git a/server/src/main/java/org/elasticsearch/cluster/SnapshotDeletionsInProgress.java b/server/src/main/java/org/elasticsearch/cluster/SnapshotDeletionsInProgress.java index 49cacaea019d0..bb08309896bdb 100644 --- a/server/src/main/java/org/elasticsearch/cluster/SnapshotDeletionsInProgress.java +++ b/server/src/main/java/org/elasticsearch/cluster/SnapshotDeletionsInProgress.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -180,6 +181,7 @@ public static final class Entry implements Writeable, RepositoryOperation { public Entry(List snapshots, String repoName, long startTime, long repositoryStateId) { this.snapshots = snapshots; + assert snapshots.size() == new HashSet<>(snapshots).size() : "Duplicate snapshot ids in " + snapshots; this.repoName = repoName; this.startTime = startTime; this.repositoryStateId = repositoryStateId; diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index 4fbf4f687787a..5e00ddbd545ce 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -1122,7 +1122,7 @@ private static List matchingSnapshotIds(RepositoryData repositoryDat String repositoryName) { final Map allSnapshotIds = repositoryData.getSnapshotIds().stream().collect( Collectors.toMap(SnapshotId::getName, Function.identity())); - final List foundSnapshots = new ArrayList<>(); + final Set foundSnapshots = new HashSet<>(); for (String snapshotOrPattern : snapshotsOrPatterns) { if (Regex.isSimpleMatchPattern(snapshotOrPattern) == false) { final SnapshotId foundId = allSnapshotIds.get(snapshotOrPattern); @@ -1139,7 +1139,7 @@ private static List matchingSnapshotIds(RepositoryData repositoryDat } } } - return foundSnapshots; + return List.copyOf(foundSnapshots); } // Return in-progress snapshot entry by name and repository in the given cluster state or null if none is found diff --git a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 1b79b2c9f7402..27d87e33514d5 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -129,6 +129,7 @@ import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasSize; @@ -3843,6 +3844,40 @@ public void testSnapshotDifferentIndicesBySameName() { assertHitCount(client().prepareSearch("restored-3").setSize(0).get(), expectedCount); } + public void testBulkDeleteWithOverlappingPatterns() { + final int numberOfSnapshots = between(5, 15); + Path repo = randomRepoPath(); + logger.info("--> creating repository at {}", repo.toAbsolutePath()); + assertAcked(client().admin().cluster().preparePutRepository("test-repo") + .setType("fs").setSettings(Settings.builder() + .put("location", repo) + .put("compress", false) + .put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES))); + + final String[] indices = {"test-idx-1", "test-idx-2", "test-idx-3"}; + createIndex(indices); + ensureGreen(); + + logger.info("--> creating {} snapshots ", numberOfSnapshots); + for (int i = 0; i < numberOfSnapshots; i++) { + for (int j = 0; j < 10; j++) { + indexDoc(randomFrom(indices), Integer.toString(i * 10 + j), "foo", "bar" + i * 10 + j); + } + refresh(); + logger.info("--> snapshot {}", i); + CreateSnapshotResponse createSnapshotResponse = client().admin().cluster().prepareCreateSnapshot("test-repo", "test-snap-" + i) + .setWaitForCompletion(true).get(); + assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), greaterThan(0)); + assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), + equalTo(createSnapshotResponse.getSnapshotInfo().totalShards())); + } + + logger.info("--> deleting all snapshots"); + client().admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-*", "*").get(); + final GetSnapshotsResponse getSnapshotsResponse = client().admin().cluster().prepareGetSnapshots("test-repo").get(); + assertThat(getSnapshotsResponse.getSnapshots("test-repo"), empty()); + } + private void verifySnapshotInfo(final String repo, final GetSnapshotsResponse response, final Map> indicesPerSnapshot) { for (SnapshotInfo snapshotInfo : response.getSnapshots("test-repo")) { diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java index b8b4c644922b6..0e1725ed22bbb 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java @@ -362,7 +362,8 @@ void deleteSnapshots(Map> snapshotsToDelete, for (SnapshotInfo info : snapshots) { final String policyId = getPolicyId(info); final long deleteStartTime = nowNanoSupplier.getAsLong(); - // TODO: Use snapshot multi-delete instead of this loop + // TODO: Use snapshot multi-delete instead of this loop if all nodes in the cluster support it + // i.e are newer or equal to SnapshotsService#MULTI_DELETE_VERSION deleteSnapshot(policyId, repo, info.snapshotId(), slmStats, ActionListener.wrap(acknowledgedResponse -> { deleted.incrementAndGet(); if (acknowledgedResponse.isAcknowledged()) {