diff --git a/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java b/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java index 55ed180169a..efc67afc523 100644 --- a/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -99,7 +99,7 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent snapshotIds = snapshots(); + if (snapshotIds.contains(snapshotId)) { + ImmutableList.Builder builder = ImmutableList.builder(); + for (SnapshotId id : snapshotIds) { + if (!snapshotId.equals(id)) { + builder.add(id); + } + } + snapshotIds = builder.build(); + } + writeSnapshotList(snapshotIds); // Now delete all indices for (String index : snapshot.indices()) { BlobPath indexPath = basePath().add("indices").add(index); @@ -268,7 +280,7 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent shardFailures) { - BlobStoreSnapshot snapshot = (BlobStoreSnapshot)readSnapshot(snapshotId); + BlobStoreSnapshot snapshot = (BlobStoreSnapshot) readSnapshot(snapshotId); if (snapshot == null) { throw new SnapshotMissingException(snapshotId); } diff --git a/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java b/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java index b14acc9bdda..825e674c6d5 100644 --- a/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java +++ b/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java @@ -19,6 +19,8 @@ package org.elasticsearch.repositories.uri; +import com.google.common.collect.ImmutableList; +import org.elasticsearch.cluster.metadata.SnapshotId; import org.elasticsearch.common.blobstore.BlobPath; import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.blobstore.url.URLBlobStore; @@ -52,6 +54,8 @@ public class URLRepository extends BlobStoreRepository { private final BlobPath basePath; + private boolean listDirectories; + /** * Constructs new read-only URL-based repository * @@ -72,6 +76,7 @@ public class URLRepository extends BlobStoreRepository { } int concurrentStreams = repositorySettings.settings().getAsInt("concurrent_streams", componentSettings.getAsInt("concurrent_streams", 5)); ExecutorService concurrentStreamPool = EsExecutors.newScaling(1, concurrentStreams, 60, TimeUnit.SECONDS, EsExecutors.daemonThreadFactory(settings, "[fs_stream]")); + listDirectories = repositorySettings.settings().getAsBoolean("list_directories", componentSettings.getAsBoolean("list_directories", true)); blobStore = new URLBlobStore(componentSettings, concurrentStreamPool, url); basePath = BlobPath.cleanPath(); } @@ -88,4 +93,17 @@ public class URLRepository extends BlobStoreRepository { protected BlobPath basePath() { return basePath; } + + @Override + public ImmutableList snapshots() { + if (listDirectories) { + return super.snapshots(); + } else { + try { + return readSnapshotList(); + } catch (IOException ex) { + throw new RepositoryException(repositoryName, "failed to get snapshot list in repository", ex); + } + } + } } diff --git a/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreTests.java b/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreTests.java index b1cf306e3c3..50740528b41 100644 --- a/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreTests.java +++ b/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ListenableActionFuture; import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; @@ -784,7 +785,7 @@ public class SharedClusterSnapshotRestoreTests extends AbstractSnapshotTests { logger.info("--> trying to create a repository with different name"); putRepositoryResponse = client.admin().cluster().preparePutRepository("test-repo-2") .setType("fs").setSettings(ImmutableSettings.settingsBuilder().put("location", new File(repositoryLocation, "test")) - ).get(); + ).get(); assertThat(putRepositoryResponse.isAcknowledged(), equalTo(true)); logger.info("--> unblocking blocked node"); @@ -851,13 +852,11 @@ public class SharedClusterSnapshotRestoreTests extends AbstractSnapshotTests { logger.info("--> delete index"); wipeIndices("test-idx"); - logger.info("--> delete file system repository"); - wipeRepositories("test-repo"); - logger.info("--> create read-only URL repository"); putRepositoryResponse = client.admin().cluster().preparePutRepository("url-repo") .setType("url").setSettings(ImmutableSettings.settingsBuilder() .put("url", repositoryLocation.toURI().toURL()) + .put("list_directories", randomBoolean()) ).get(); assertThat(putRepositoryResponse.isAcknowledged(), equalTo(true)); logger.info("--> restore index after deletion"); @@ -870,6 +869,15 @@ public class SharedClusterSnapshotRestoreTests extends AbstractSnapshotTests { GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("url-repo").get(); assertThat(getSnapshotsResponse.getSnapshots(), notNullValue()); assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(1)); + + logger.info("--> delete snapshot"); + DeleteSnapshotResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").get(); + assertAcked(deleteSnapshotResponse); + + logger.info("--> list available shapshot again, no snapshots should be returned"); + getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("url-repo").get(); + assertThat(getSnapshotsResponse.getSnapshots(), notNullValue()); + assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(0)); } private boolean waitForIndex(String index, TimeValue timeout) throws InterruptedException {