JCLOUDS-945: fix local blobstore marker handling

Previously using prefix markers would not correctly find the next key.
Add test for this behavior.
This commit is contained in:
Andrew Gaul 2016-10-04 20:45:41 -07:00
parent 26c060a0e8
commit 50e6d44433
4 changed files with 33 additions and 15 deletions

View File

@ -46,6 +46,11 @@ public class AtmosContainerIntegrationLiveTest extends BaseContainerIntegrationT
throw new SkipException("cannot specify arbitrary markers");
}
@Override
public void testListMarkerPrefix() throws Exception {
throw new SkipException("cannot specify arbitrary markers");
}
@Override
public void testListContainerWithZeroMaxResults() throws Exception {
throw new SkipException("Atmos requires a positive integer for max results");

View File

@ -276,21 +276,11 @@ public final class LocalBlobStore implements BlobStore {
if (options.getMarker() != null) {
final String finalMarker = options.getMarker();
String delimiter = storageStrategy.getSeparator();
Optional<StorageMetadata> lastMarkerMetadata;
if (finalMarker.endsWith(delimiter)) {
lastMarkerMetadata = tryFind(contents, new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata metadata) {
int length = finalMarker.length() - 1;
return metadata.getName().substring(0, length).compareTo(finalMarker.substring(0, length)) > 0;
}
});
} else {
lastMarkerMetadata = tryFind(contents, new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata metadata) {
return metadata.getName().compareTo(finalMarker) > 0;
}
});
}
Optional<StorageMetadata> lastMarkerMetadata = tryFind(contents, new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata metadata) {
return metadata.getName().compareTo(finalMarker) > 0;
}
});
if (lastMarkerMetadata.isPresent()) {
contents = contents.tailSet(lastMarkerMetadata.get());
} else {

View File

@ -577,6 +577,24 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
}
}
/** Test that listing with a marker prefix matches the first key with that prefix. */
@Test
public void testListMarkerPrefix() throws Exception {
BlobStore blobStore = view.getBlobStore();
final String container = getContainerName();
try {
blobStore.createContainerInLocation(null, container);
blobStore.putBlob(container, blobStore.blobBuilder("a/a").payload("").build());
blobStore.putBlob(container, blobStore.blobBuilder("b/b").payload("").build());
ListContainerOptions options = new ListContainerOptions().afterMarker("b/").recursive();
PageSet<? extends StorageMetadata> res = blobStore.list(container, options);
assertThat(res).hasSize(1);
assertThat(res.iterator().next().getName()).isEqualTo("b/b");
} finally {
returnContainer(container);
}
}
@DataProvider
public Object[][] getBlobsToEscape() {
ImmutableSet<String> testNames = ImmutableSet.of("%20", "%20 ", " %20", " ");

View File

@ -35,4 +35,9 @@ public class AzureBlobContainerIntegrationLiveTest extends BaseContainerIntegrat
public void testListContainerWithZeroMaxResults() throws Exception {
throw new SkipException("Azure requires a positive integer for max results");
}
@Override
public void testListMarkerPrefix() throws Exception {
throw new SkipException("cannot specify arbitrary markers");
}
}