mirror of https://github.com/apache/jclouds.git
Return lastModified and size when listing S3 parts
This commit is contained in:
parent
014f7a4fb9
commit
ec932321bd
|
@ -75,6 +75,7 @@ import org.jclouds.s3.domain.BucketMetadata;
|
||||||
import org.jclouds.s3.domain.CannedAccessPolicy;
|
import org.jclouds.s3.domain.CannedAccessPolicy;
|
||||||
import org.jclouds.s3.domain.DeleteResult;
|
import org.jclouds.s3.domain.DeleteResult;
|
||||||
import org.jclouds.s3.domain.ListBucketResponse;
|
import org.jclouds.s3.domain.ListBucketResponse;
|
||||||
|
import org.jclouds.s3.domain.ListMultipartUploadResponse;
|
||||||
import org.jclouds.s3.domain.ListMultipartUploadsResponse;
|
import org.jclouds.s3.domain.ListMultipartUploadsResponse;
|
||||||
import org.jclouds.s3.domain.ObjectMetadata;
|
import org.jclouds.s3.domain.ObjectMetadata;
|
||||||
import org.jclouds.s3.domain.Payer;
|
import org.jclouds.s3.domain.Payer;
|
||||||
|
@ -104,8 +105,10 @@ import org.jclouds.s3.xml.ListBucketHandler;
|
||||||
import org.jclouds.s3.xml.ListMultipartUploadsHandler;
|
import org.jclouds.s3.xml.ListMultipartUploadsHandler;
|
||||||
import org.jclouds.s3.xml.LocationConstraintHandler;
|
import org.jclouds.s3.xml.LocationConstraintHandler;
|
||||||
import org.jclouds.s3.xml.PartIdsFromHttpResponse;
|
import org.jclouds.s3.xml.PartIdsFromHttpResponse;
|
||||||
|
import org.jclouds.s3.xml.PartIdsFromHttpResponseFull;
|
||||||
import org.jclouds.s3.xml.PayerHandler;
|
import org.jclouds.s3.xml.PayerHandler;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -780,6 +783,8 @@ public interface S3Client extends Closeable {
|
||||||
@PathParam("key") String key, @QueryParam("uploadId") String uploadId,
|
@PathParam("key") String key, @QueryParam("uploadId") String uploadId,
|
||||||
@BinderParam(BindPartIdsAndETagsToRequest.class) Map<Integer, String> parts);
|
@BinderParam(BindPartIdsAndETagsToRequest.class) Map<Integer, String> parts);
|
||||||
|
|
||||||
|
/** @deprecated see #listMultipartPartsFull */
|
||||||
|
@Deprecated
|
||||||
@Named("ListMultipartParts")
|
@Named("ListMultipartParts")
|
||||||
@GET
|
@GET
|
||||||
@Path("/{key}")
|
@Path("/{key}")
|
||||||
|
@ -788,6 +793,15 @@ public interface S3Client extends Closeable {
|
||||||
@BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName,
|
@BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName,
|
||||||
@PathParam("key") String key, @QueryParam("uploadId") String uploadId);
|
@PathParam("key") String key, @QueryParam("uploadId") String uploadId);
|
||||||
|
|
||||||
|
@Beta
|
||||||
|
@Named("ListMultipartParts")
|
||||||
|
@GET
|
||||||
|
@Path("/{key}")
|
||||||
|
@XMLResponseParser(PartIdsFromHttpResponseFull.class)
|
||||||
|
Map<Integer, ListMultipartUploadResponse> listMultipartPartsFull(@Bucket @EndpointParam(parser = AssignCorrectHostnameForBucket.class)
|
||||||
|
@BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators(BucketNameValidator.class) String bucketName,
|
||||||
|
@PathParam("key") String key, @QueryParam("uploadId") String uploadId);
|
||||||
|
|
||||||
@Named("ListMultipartUploads")
|
@Named("ListMultipartUploads")
|
||||||
@GET
|
@GET
|
||||||
@Path("/")
|
@Path("/")
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.s3.domain;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.google.auto.value.AutoValue;
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
|
||||||
|
@AutoValue
|
||||||
|
@Beta
|
||||||
|
public abstract class ListMultipartUploadResponse {
|
||||||
|
public abstract int partNumber();
|
||||||
|
public abstract Date lastModified();
|
||||||
|
public abstract String eTag();
|
||||||
|
public abstract long size();
|
||||||
|
|
||||||
|
public static ListMultipartUploadResponse create(int partNumber, Date lastModified, String eTag, long size) {
|
||||||
|
checkArgument(partNumber > 0, "partNumber must be greater than zero, was: %s", partNumber);
|
||||||
|
checkNotNull(eTag, "eTag");
|
||||||
|
lastModified = (Date) checkNotNull(lastModified, "lastModified").clone();
|
||||||
|
checkArgument(size >= 0, "size must be positive, was: %s", size);
|
||||||
|
return new AutoValue_ListMultipartUploadResponse(partNumber, lastModified, eTag, size);
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,7 +33,10 @@ import com.google.common.collect.ImmutableMap;
|
||||||
* Parses the following XML document:
|
* Parses the following XML document:
|
||||||
* <p/>
|
* <p/>
|
||||||
* ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"
|
* ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"
|
||||||
|
*
|
||||||
|
* @deprecated see PartIdsFromHttpResponseFull
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class PartIdsFromHttpResponse extends ParseSax.HandlerWithResult<Map<Integer, String>> {
|
public class PartIdsFromHttpResponse extends ParseSax.HandlerWithResult<Map<Integer, String>> {
|
||||||
private final StringBuilder currentText = new StringBuilder();
|
private final StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.s3.xml;
|
||||||
|
|
||||||
|
import static org.jclouds.util.SaxUtils.currentOrNull;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.date.DateService;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.s3.domain.ListMultipartUploadResponse;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the following XML document:
|
||||||
|
* <p/>
|
||||||
|
* ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public final class PartIdsFromHttpResponseFull extends ParseSax.HandlerWithResult<Map<Integer, ListMultipartUploadResponse>> {
|
||||||
|
private final StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private final DateService dateParser;
|
||||||
|
|
||||||
|
private int partNumber;
|
||||||
|
private Date lastModfied;
|
||||||
|
private String eTag;
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
private final ImmutableMap.Builder<Integer, ListMultipartUploadResponse> parts = ImmutableMap.builder();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PartIdsFromHttpResponseFull(DateService dateParser) {
|
||||||
|
this.dateParser = dateParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, ListMultipartUploadResponse> getResult() {
|
||||||
|
return parts.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endElement(String uri, String name, String qName) {
|
||||||
|
if (qName.equals("PartNumber")) {
|
||||||
|
partNumber = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equals("LastModified")) {
|
||||||
|
lastModfied = dateParser.iso8601DateOrSecondsDateParse(currentOrNull(currentText));
|
||||||
|
} else if (qName.equals("ETag")) {
|
||||||
|
eTag = currentText.toString().trim();
|
||||||
|
} else if (qName.equals("Size")) {
|
||||||
|
size = Long.parseLong(currentText.toString().trim());
|
||||||
|
} else if (qName.equals("Part")) {
|
||||||
|
parts.put(partNumber, ListMultipartUploadResponse.create(partNumber, lastModfied, eTag, size));
|
||||||
|
}
|
||||||
|
currentText.setLength(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char[] ch, int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ import org.jclouds.s3.domain.AccessControlList.GroupGranteeURI;
|
||||||
import org.jclouds.s3.domain.AccessControlList.Permission;
|
import org.jclouds.s3.domain.AccessControlList.Permission;
|
||||||
import org.jclouds.s3.domain.CannedAccessPolicy;
|
import org.jclouds.s3.domain.CannedAccessPolicy;
|
||||||
import org.jclouds.s3.domain.DeleteResult;
|
import org.jclouds.s3.domain.DeleteResult;
|
||||||
|
import org.jclouds.s3.domain.ListMultipartUploadResponse;
|
||||||
import org.jclouds.s3.domain.ListMultipartUploadsResponse;
|
import org.jclouds.s3.domain.ListMultipartUploadsResponse;
|
||||||
import org.jclouds.s3.domain.ObjectMetadata;
|
import org.jclouds.s3.domain.ObjectMetadata;
|
||||||
import org.jclouds.s3.domain.ObjectMetadataBuilder;
|
import org.jclouds.s3.domain.ObjectMetadataBuilder;
|
||||||
|
@ -514,7 +515,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
String key = "constitution.txt";
|
String key = "constitution.txt";
|
||||||
String uploadId = getApi().initiateMultipartUpload(containerName,
|
String uploadId = getApi().initiateMultipartUpload(containerName,
|
||||||
ObjectMetadataBuilder.create().key(key).contentMD5(oneHundredOneConstitutionsMD5.asBytes()).build());
|
ObjectMetadataBuilder.create().key(key).contentMD5(oneHundredOneConstitutionsMD5.asBytes()).build());
|
||||||
assertThat(getApi().listMultipartParts(containerName, key, uploadId)).isEmpty();
|
assertThat(getApi().listMultipartPartsFull(containerName, key, uploadId)).isEmpty();
|
||||||
|
|
||||||
byte[] buffer = oneHundredOneConstitutions.read();
|
byte[] buffer = oneHundredOneConstitutions.read();
|
||||||
assertEquals(oneHundredOneConstitutions.size(), (long) buffer.length);
|
assertEquals(oneHundredOneConstitutions.size(), (long) buffer.length);
|
||||||
|
@ -534,7 +535,9 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
// available there.
|
// available there.
|
||||||
eTagOf1 = getApi().uploadPart(containerName, key, 1, uploadId, part1);
|
eTagOf1 = getApi().uploadPart(containerName, key, 1, uploadId, part1);
|
||||||
}
|
}
|
||||||
assertThat(getApi().listMultipartParts(containerName, key, uploadId)).containsOnlyKeys(1);
|
Map<Integer, ListMultipartUploadResponse> map = getApi().listMultipartPartsFull(containerName, key, uploadId);
|
||||||
|
assertThat(map).containsOnlyKeys(1);
|
||||||
|
assertThat(map.get(1).eTag()).isEqualTo(eTagOf1);
|
||||||
|
|
||||||
getApi().completeMultipartUpload(containerName, key, uploadId, ImmutableMap.of(1, eTagOf1));
|
getApi().completeMultipartUpload(containerName, key, uploadId, ImmutableMap.of(1, eTagOf1));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue