mirror of https://github.com/apache/jclouds.git
JCLOUDS-930: Handle subdir entries correctly.
When listing blobs, Swift returns an array of "subdir" entries for every common prefix. The openstack-swift provider needs to process such entries and add them to the result set. The subdir array is an array of strings, so additional metadata needs to be added to the objects (bogus ETag, bogus LastModifiedDate, and so on). When directory marker blobs are used, this means that potential _two_ entries are generated for every directory if: 1. the delimiter is set and matches the directory blob (e.g. dir/ and delimiter /) 2. there are objects under the directory name (e.g. dir/blob), which will result in results that include common prefixes (subdir) In the above example, we should expect two results: "dir" and "dir/" representing the directory marker blob and the common prefix, respectively. This is caught in the testDirectory integration test. The patch changes the behavior of the Swift provider to correctly handle the results in the subdir stanza and changes the test to expect the directory marker to be returned in the list.
This commit is contained in:
parent
1c1cfffd5d
commit
6d27fbb18a
|
@ -46,6 +46,7 @@ public class ParseObjectListFromResponse implements Function<HttpResponse, Objec
|
|||
private static final class InternalObject {
|
||||
String name;
|
||||
String hash;
|
||||
String subdir;
|
||||
long bytes;
|
||||
String content_type;
|
||||
Date last_modified;
|
||||
|
@ -66,11 +67,14 @@ public class ParseObjectListFromResponse implements Function<HttpResponse, Objec
|
|||
@Override
|
||||
public ObjectList apply(HttpResponse from) {
|
||||
List<SwiftObject> objects = Lists.transform(json.apply(from), toSwiftObject);
|
||||
|
||||
Container container = parseContainer.apply(from);
|
||||
return ObjectList.create(objects, container);
|
||||
}
|
||||
|
||||
static class ToSwiftObject implements Function<InternalObject, SwiftObject> {
|
||||
private static final String SUBDIR_ETAG = "deadbeef";
|
||||
|
||||
private final String containerUri;
|
||||
|
||||
ToSwiftObject(String containerUri) {
|
||||
|
@ -79,6 +83,14 @@ public class ParseObjectListFromResponse implements Function<HttpResponse, Objec
|
|||
|
||||
@Override
|
||||
public SwiftObject apply(InternalObject input) {
|
||||
if (input.subdir != null) {
|
||||
return SwiftObject.builder()
|
||||
.uri(uriBuilder(containerUri).clearQuery().appendPath(input.subdir).build())
|
||||
.name(input.subdir)
|
||||
.etag(SUBDIR_ETAG)
|
||||
.payload(payload(input.bytes, input.hash, "application/directory", input.expires))
|
||||
.lastModified(new Date(0)).build();
|
||||
}
|
||||
return SwiftObject.builder()
|
||||
.uri(uriBuilder(containerUri).clearQuery().appendPath(input.name).build())
|
||||
.name(input.name)
|
||||
|
|
|
@ -234,9 +234,9 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
awaitConsistency();
|
||||
|
||||
container = view.getBlobStore().list(containerName);
|
||||
// we should still have only the directory under root
|
||||
// we should get back the subdir entry and the directory marker
|
||||
assert container.getNextMarker() == null;
|
||||
assert container.size() == 1 : container;
|
||||
assertThat(container).hasSize(2);
|
||||
|
||||
container = view.getBlobStore().list(containerName, inDirectory(directory));
|
||||
// we should have only the 10 items under the directory
|
||||
|
|
Loading…
Reference in New Issue