From d07c4a215e452c99f5ddae7fe006d801339d96e7 Mon Sep 17 00:00:00 2001 From: Timur Alperovich Date: Thu, 29 Jun 2017 00:17:27 -0700 Subject: [PATCH] Handle empty delimiter/prefix in FS store. When delimiter/prefix is an empty string, jclouds filesystem blobstore should treat them as not being set. --- .../blobstore/config/LocalBlobStore.java | 6 ++++- .../BaseContainerIntegrationTest.java | 26 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java index f45e27aca5..6d9533d114 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java @@ -90,6 +90,7 @@ import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.base.Strings; import com.google.common.base.Supplier; import com.google.common.base.Throwables; import com.google.common.collect.FluentIterable; @@ -266,7 +267,7 @@ public final class LocalBlobStore implements BlobStore { if (options != null) { if (options.getDir() != null && !options.getDir().isEmpty()) { contents = filterDirectory(contents, options); - } else if (options.getPrefix() != null) { + } else if (!Strings.isNullOrEmpty(options.getPrefix())) { contents = filterPrefix(contents, options); } else if (!options.isRecursive() || (options.getDelimiter() != null)) { String delimiter = options.getDelimiter() == null ? storageStrategy.getSeparator() : options.getDelimiter(); @@ -349,6 +350,9 @@ public final class LocalBlobStore implements BlobStore { private SortedSet extractCommonPrefixes(SortedSet contents, String delimiter, String prefix) { + if (Strings.isNullOrEmpty(delimiter)) { + return contents; + } SortedSet commonPrefixes = newTreeSet( transform(contents, new CommonPrefixes(prefix, delimiter))); commonPrefixes.remove(CommonPrefixes.NO_PREFIX); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java index e2cc6329f0..e6cb0ae158 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java @@ -53,6 +53,7 @@ import org.jclouds.http.HttpResponse; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.io.ByteSource; @@ -595,6 +596,31 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { } } + /** Test that listing with an empty string for prefix and delimiter returns all of the keys. */ + @Test(groups = {"integration", "live"}) + public void testListEmptyPrefixDelimiter() throws Exception { + final String container = getContainerName(); + BlobStore blobStore = view.getBlobStore(); + blobStore.createContainerInLocation(null, container); + + try { + ImmutableList blobs = ImmutableList.of("a", "b", "c"); + for (String blob : blobs) { + blobStore.putBlob(container, blobStore.blobBuilder(blob).payload("").build()); + } + ListContainerOptions options = ListContainerOptions.Builder.delimiter("") + .prefix("").afterMarker(""); + PageSet rs = blobStore.list(container, options); + ImmutableList.Builder builder = ImmutableList.builder(); + for (StorageMetadata sm : rs) { + builder.add(sm.getName()); + } + assertThat(builder.build()).containsExactlyElementsOf(blobs); + } finally { + returnContainer(container); + } + } + @DataProvider public Object[][] getBlobsToEscape() { ImmutableSet testNames = ImmutableSet.of("%20", "%20 ", " %20", " ", "%", "%%");