![JAR search and dependency download from the Maven repository](/logo.png)
src.org.jets3t.service.impl.soap.axis.SoapS3Service Maven / Gradle / Ivy
/*
* jets3t : Java Extra-Tasty S3 Toolkit (for Amazon S3 online storage service)
* This is a java.net project, see https://jets3t.dev.java.net/
*
* Copyright 2006 James Murty
*
* Licensed 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.jets3t.service.impl.soap.axis;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.activation.DataHandler;
import javax.xml.rpc.ServiceException;
import javax.xml.transform.stream.StreamSource;
import org.apache.axis.attachments.AttachmentPart;
import org.apache.axis.attachments.SourceDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jets3t.service.Constants;
import org.jets3t.service.Jets3tProperties;
import org.jets3t.service.S3ObjectsChunk;
import org.jets3t.service.S3Service;
import org.jets3t.service.S3ServiceException;
import org.jets3t.service.acl.AccessControlList;
import org.jets3t.service.acl.CanonicalGrantee;
import org.jets3t.service.acl.EmailAddressGrantee;
import org.jets3t.service.acl.GrantAndPermission;
import org.jets3t.service.acl.GranteeInterface;
import org.jets3t.service.acl.GroupGrantee;
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
import org.jets3t.service.impl.soap.axis._2006_03_01.AccessControlPolicy;
import org.jets3t.service.impl.soap.axis._2006_03_01.AmazonCustomerByEmail;
import org.jets3t.service.impl.soap.axis._2006_03_01.AmazonS3SoapBindingStub;
import org.jets3t.service.impl.soap.axis._2006_03_01.AmazonS3_ServiceLocator;
import org.jets3t.service.impl.soap.axis._2006_03_01.BucketLoggingStatus;
import org.jets3t.service.impl.soap.axis._2006_03_01.CanonicalUser;
import org.jets3t.service.impl.soap.axis._2006_03_01.CopyObjectResult;
import org.jets3t.service.impl.soap.axis._2006_03_01.GetObjectResult;
import org.jets3t.service.impl.soap.axis._2006_03_01.Grant;
import org.jets3t.service.impl.soap.axis._2006_03_01.Grantee;
import org.jets3t.service.impl.soap.axis._2006_03_01.Group;
import org.jets3t.service.impl.soap.axis._2006_03_01.ListAllMyBucketsEntry;
import org.jets3t.service.impl.soap.axis._2006_03_01.ListAllMyBucketsResult;
import org.jets3t.service.impl.soap.axis._2006_03_01.ListBucketResult;
import org.jets3t.service.impl.soap.axis._2006_03_01.ListEntry;
import org.jets3t.service.impl.soap.axis._2006_03_01.LoggingSettings;
import org.jets3t.service.impl.soap.axis._2006_03_01.MetadataDirective;
import org.jets3t.service.impl.soap.axis._2006_03_01.MetadataEntry;
import org.jets3t.service.impl.soap.axis._2006_03_01.Permission;
import org.jets3t.service.impl.soap.axis._2006_03_01.PrefixEntry;
import org.jets3t.service.impl.soap.axis._2006_03_01.PutObjectResult;
import org.jets3t.service.model.S3Bucket;
import org.jets3t.service.model.S3BucketLoggingStatus;
import org.jets3t.service.model.S3Object;
import org.jets3t.service.model.S3Owner;
import org.jets3t.service.security.AWSCredentials;
import org.jets3t.service.utils.Mimetypes;
import org.jets3t.service.utils.ServiceUtils;
/**
* SOAP implementation of an S3Service based on the
* Apache Axis 1.4 library.
*
* Note: This SOAP implementation does not support IO streaming uploads to S3. Any
* documents uploaded by this implementation must fit inside memory allocated to the Java program
* running this class if OutOfMemory errors are to be avoided.
*
*
* Note 2: The SOAP implementation does not perform retries when communication with s3 fails.
*
*
* The preferred S3Service implementation in JetS3t is {@link RestS3Service}. This SOAP
* implementation class is provided with JetS3t as a proof-of-concept, showing that alternative
* service implementations are possible and what a SOAP service might look like. We do not
* recommend that this service be used to perform any real work.
*
*
* @author James Murty
*/
public class SoapS3Service extends S3Service {
private static final long serialVersionUID = 6421138869712673819L;
private static final Log log = LogFactory.getLog(SoapS3Service.class);
private AmazonS3_ServiceLocator locator = null;
/**
* Constructs the SOAP service implementation and, based on the value of {@link S3Service#isHttpsOnly}
* sets the SOAP endpoint to use HTTP or HTTPS protocols.
*
* @param awsCredentials
* @param invokingApplicationDescription
* a short description of the application using the service, suitable for inclusion in a
* user agent string for REST/HTTP requests. Ideally this would include the application's
* version number, for example: Cockpit/0.6.1
or My App Name/1.0
* @param jets3tProperties
* JetS3t properties that will be applied within this service.
*
* @throws S3ServiceException
*/
public SoapS3Service(AWSCredentials awsCredentials, String invokingApplicationDescription,
Jets3tProperties jets3tProperties) throws S3ServiceException
{
super(awsCredentials, invokingApplicationDescription, jets3tProperties);
locator = new AmazonS3_ServiceLocator();
if (super.isHttpsOnly()) {
// Use an SSL connection, to further secure the signature.
if (log.isDebugEnabled()) {
log.debug("SOAP service will use HTTPS for all communication");
}
locator.setAmazonS3EndpointAddress("https://" + Constants.S3_HOSTNAME + "/soap");
} else {
if (log.isDebugEnabled()) {
log.debug("SOAP service will use HTTP for all communication");
}
locator.setAmazonS3EndpointAddress("http://" + Constants.S3_HOSTNAME + "/soap");
}
// Ensure we can get the stub.
getSoapBinding();
}
/**
* Constructs the SOAP service implementation and, based on the value of {@link S3Service#isHttpsOnly}
* sets the SOAP endpoint to use HTTP or HTTPS protocols.
*
* @param awsCredentials
* @param invokingApplicationDescription
* a short description of the application using the service, suitable for inclusion in a
* user agent string for REST/HTTP requests. Ideally this would include the application's
* version number, for example: Cockpit/0.6.1
or My App Name/1.0
* @throws S3ServiceException
*/
public SoapS3Service(AWSCredentials awsCredentials, String invokingApplicationDescription)
throws S3ServiceException
{
this(awsCredentials, invokingApplicationDescription,
Jets3tProperties.getInstance(Constants.JETS3T_PROPERTIES_FILENAME));
}
/**
* Constructs the SOAP service implementation and, based on the value of {@link S3Service#isHttpsOnly}
* sets the SOAP endpoint to use HTTP or HTTPS protocols.
*
* @param awsCredentials
* @throws S3ServiceException
*/
public SoapS3Service(AWSCredentials awsCredentials) throws S3ServiceException {
this(awsCredentials, null);
}
private AmazonS3SoapBindingStub getSoapBinding() throws S3ServiceException {
try {
return (AmazonS3SoapBindingStub) locator.getAmazonS3();
} catch (ServiceException e) {
throw new S3ServiceException("Unable to initialise SOAP binding", e);
}
}
private String getAWSAccessKey() {
if (getAWSCredentials() == null) {
return null;
} else {
return getAWSCredentials().getAccessKey();
}
}
private String getAWSSecretKey() {
if (getAWSCredentials() == null) {
return null;
} else {
return getAWSCredentials().getSecretKey();
}
}
private Calendar getTimeStamp( long timestamp ) throws ParseException {
if (getAWSCredentials() == null) {
return null;
}
Calendar ts = new GregorianCalendar();
Date date = ServiceUtils.parseIso8601Date(convertDateToString(ts));
ts.setTime(date);
return ts;
}
private String convertDateToString(Calendar cal) {
if (cal != null) {
return ServiceUtils.formatIso8601Date(cal.getTime());
} else {
return "";
}
}
private S3Owner convertOwner(CanonicalUser user) {
S3Owner owner = new S3Owner(user.getID(), user.getDisplayName());
return owner;
}
/**
* Converts a SOAP object AccessControlPolicy to a jets3t AccessControlList.
*
* @param policy
* @return
* @throws S3ServiceException
*/
private AccessControlList convertAccessControlTypes(AccessControlPolicy policy)
throws S3ServiceException
{
AccessControlList acl = new AccessControlList();
acl.setOwner(convertOwner(policy.getOwner()));
Grant[] grants = policy.getAccessControlList();
for (int i = 0; i < grants.length; i++) {
Grant grant = (Grant) grants[i];
org.jets3t.service.acl.Permission permission =
org.jets3t.service.acl.Permission.parsePermission(grant.getPermission().toString());
Grantee grantee = grant.getGrantee();
if (grantee instanceof Group) {
GroupGrantee jets3tGrantee = new GroupGrantee();
jets3tGrantee.setIdentifier(((Group)grantee).getURI());
acl.grantPermission(jets3tGrantee, permission);
} else if (grantee instanceof CanonicalUser) {
CanonicalUser canonicalUser = (CanonicalUser) grantee;
CanonicalGrantee jets3tGrantee = new CanonicalGrantee();
jets3tGrantee.setIdentifier(canonicalUser.getID());
jets3tGrantee.setDisplayName(canonicalUser.getDisplayName());
acl.grantPermission(jets3tGrantee, permission);
} else if (grantee instanceof AmazonCustomerByEmail) {
AmazonCustomerByEmail customerByEmail = (AmazonCustomerByEmail) grantee;
EmailAddressGrantee jets3tGrantee = new EmailAddressGrantee();
jets3tGrantee.setIdentifier(customerByEmail.getEmailAddress());
acl.grantPermission(jets3tGrantee, permission);
} else {
throw new S3ServiceException("Unrecognised grantee type: " + grantee.getClass());
}
}
return acl;
}
/**
* Converts a jets3t AccessControlList object to an array of SOAP Grant objects.
*
* @param acl
* @return
* @throws S3ServiceException
*/
private Grant[] convertACLtoGrants(AccessControlList acl) throws S3ServiceException {
if (acl == null) {
return null;
}
if (acl.isCannedRestACL()) {
throw new S3ServiceException("Cannot use canned REST ACLs with SOAP service");
}
Grant[] grants = new Grant[acl.getGrants().size()];
Iterator grantIter = acl.getGrants().iterator();
int index = 0;
while (grantIter.hasNext()) {
GrantAndPermission jets3tGaP = (GrantAndPermission) grantIter.next();
GranteeInterface jets3tGrantee = jets3tGaP.getGrantee();
Grant grant = new Grant();
if (jets3tGrantee instanceof GroupGrantee) {
GroupGrantee groupGrantee = (GroupGrantee) jets3tGrantee;
Group group = new Group();
group.setURI(groupGrantee.getIdentifier());
grant.setGrantee(group);
} else if (jets3tGrantee instanceof CanonicalGrantee) {
CanonicalGrantee canonicalGrantee = (CanonicalGrantee) jets3tGrantee;
CanonicalUser canonicalUser = new CanonicalUser();
canonicalUser.setID(canonicalGrantee.getIdentifier());
canonicalUser.setDisplayName(canonicalGrantee.getDisplayName());
grant.setGrantee(canonicalUser);
} else if (jets3tGrantee instanceof EmailAddressGrantee) {
EmailAddressGrantee emailGrantee = (EmailAddressGrantee) jets3tGrantee;
AmazonCustomerByEmail customerByEmail = new AmazonCustomerByEmail();
customerByEmail.setEmailAddress(emailGrantee.getIdentifier());
grant.setGrantee(customerByEmail);
} else {
throw new S3ServiceException("Unrecognised jets3t grantee type: "
+ jets3tGrantee.getClass());
}
Permission permission = Permission.fromString(jets3tGaP.getPermission().toString());
grant.setPermission(permission);
grants[index++] = grant;
}
return grants;
}
/**
* Converts metadata information from a standard map to SOAP objects.
*
* @param metadataMap
* @return
*/
private MetadataEntry[] convertMetadata(Map metadataMap) {
MetadataEntry[] metadata = new MetadataEntry[metadataMap.size()];
Iterator metadataIter = metadataMap.entrySet().iterator();
int index = 0;
while (metadataIter.hasNext()) {
Map.Entry entry = (Map.Entry) metadataIter.next();
Object metadataName = entry.getKey();
Object metadataValue = entry.getValue();
if (log.isDebugEnabled()) {
log.debug("Setting metadata: " + metadataName + "=" + metadataValue);
}
MetadataEntry mdEntry = new MetadataEntry();
mdEntry.setName(metadataName.toString());
mdEntry.setValue(metadataValue.toString());
metadata[index++] = mdEntry;
}
return metadata;
}
////////////////////////////////////////////////////////////////
// Methods below this point implement S3Service abstract methods
////////////////////////////////////////////////////////////////
protected S3Bucket[] listAllBucketsImpl() throws S3ServiceException {
if (log.isDebugEnabled()) {
log.debug("Listing all buckets for AWS user: " + getAWSCredentials().getAccessKey());
}
S3Bucket[] buckets = null;
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "ListAllMyBuckets" + convertDateToString(timestamp));
ListAllMyBucketsResult result = s3SoapBinding.listAllMyBuckets(
getAWSAccessKey(), timestamp, signature);
ListAllMyBucketsEntry[] entries = result.getBuckets();
buckets = new S3Bucket[entries.length];
int index = 0;
for (int i = 0; i < entries.length; i++) {
ListAllMyBucketsEntry entry = (ListAllMyBucketsEntry) entries[i];
S3Bucket bucket = new S3Bucket();
bucket.setName(entry.getName());
bucket.setCreationDate(entry.getCreationDate().getTime());
buckets[index++] = bucket;
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to List Buckets", e);
}
return buckets;
}
public boolean isBucketAccessible(String bucketName) throws S3ServiceException {
if (log.isDebugEnabled()) {
log.debug("Checking existence of bucket: " + bucketName);
}
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "ListBucket" + convertDateToString(timestamp));
s3SoapBinding.listBucket(
bucketName, null, null, new Integer(0),
null, getAWSAccessKey(), timestamp, signature, null);
// If we get this far, the bucket exists.
return true;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
return false;
}
}
public int checkBucketStatus(String bucketName) throws S3ServiceException {
throw new S3ServiceException("The method checkBucketStatus(String bucketName) "
+ "is not implemented in " + this.getClass().getName());
}
protected S3Object[] listObjectsImpl(String bucketName, String prefix, String delimiter, long maxListingLength)
throws S3ServiceException
{
return listObjectsInternalImpl(bucketName, prefix, delimiter, maxListingLength, true, null)
.getObjects();
}
protected S3ObjectsChunk listObjectsChunkedImpl(String bucketName, String prefix, String delimiter,
long maxListingLength, String priorLastKey, boolean completeListing) throws S3ServiceException {
return listObjectsInternalImpl(bucketName, prefix, delimiter, maxListingLength, completeListing, priorLastKey);
}
protected S3ObjectsChunk listObjectsInternalImpl(String bucketName, String prefix,
String delimiter, long maxListingLength, boolean automaticallyMergeChunks, String priorLastKey)
throws S3ServiceException
{
ArrayList objects = new ArrayList();
ArrayList commonPrefixes = new ArrayList();
boolean incompleteListing = true;
try {
while (incompleteListing) {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "ListBucket" + convertDateToString(timestamp));
ListBucketResult result = s3SoapBinding.listBucket(
bucketName, prefix, priorLastKey, new Integer((int)maxListingLength),
delimiter, getAWSAccessKey(), timestamp, signature, null);
ListEntry[] entries = result.getContents();
S3Object[] partialObjects = new S3Object[
(entries == null? 0 : entries.length)];
if (log.isDebugEnabled()) {
log.debug("Found " + partialObjects.length + " objects in one batch");
}
for (int i = 0; entries != null && i < entries.length; i++) {
ListEntry entry = entries[i];
S3Object object = new S3Object(entry.getKey());
object.setLastModifiedDate(entry.getLastModified().getTime());
object.setETag(entry.getETag());
object.setContentLength(entry.getSize());
object.setStorageClass(entry.getStorageClass().toString());
object.setOwner(convertOwner(entry.getOwner()));
partialObjects[i] = object;
// This shouldn't be necessary, but result.getNextMarker() doesn't work as expected.
priorLastKey = object.getKey();
}
objects.addAll(Arrays.asList(partialObjects));
PrefixEntry[] prefixEntries = result.getCommonPrefixes();
if (prefixEntries != null) {
if (log.isDebugEnabled()) {
log.debug("Found " + prefixEntries.length + " common prefixes in one batch");
}
}
for (int i = 0; prefixEntries != null && i < prefixEntries.length; i++ ) {
PrefixEntry entry = prefixEntries[i];
commonPrefixes.add(entry.getPrefix());
}
incompleteListing = result.isIsTruncated();
if (incompleteListing) {
if (result.getNextMarker() != null) {
// Use NextMarker as the marker for where subsequent listing should start
priorLastKey = result.getNextMarker();
} else {
// Use the prior last key instead of NextMarker if it isn't available.
}
if (log.isDebugEnabled()) {
log.debug("Yet to receive complete listing of bucket contents, "
+ "last key for prior chunk: " + priorLastKey);
}
} else {
priorLastKey = null;
}
if (!automaticallyMergeChunks)
break;
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to List Objects in bucket: " + bucketName, e);
}
if (automaticallyMergeChunks) {
if (log.isDebugEnabled()) {
log.debug("Found " + objects.size() + " objects in total");
}
return new S3ObjectsChunk(
prefix, delimiter,
(S3Object[]) objects.toArray(new S3Object[objects.size()]),
(String[]) commonPrefixes.toArray(new String[commonPrefixes.size()]),
null);
} else {
return new S3ObjectsChunk(
prefix, delimiter,
(S3Object[]) objects.toArray(new S3Object[objects.size()]),
(String[]) commonPrefixes.toArray(new String[commonPrefixes.size()]),
priorLastKey);
}
}
protected S3Bucket createBucketImpl(String bucketName, String location,
AccessControlList acl) throws S3ServiceException
{
if (location != S3Bucket.LOCATION_US) {
throw new S3ServiceException("The SOAP API interface for S3 does " +
"not allow you to create buckets located anywhere other than " +
"the US");
}
Grant[] grants = null;
if (acl != null) {
grants = convertACLtoGrants(acl);
}
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "CreateBucket" + convertDateToString(timestamp));
s3SoapBinding.createBucket(
bucketName, grants, getAWSAccessKey(), timestamp, signature);
S3Bucket bucket = new S3Bucket(bucketName);
bucket.setAcl(acl);
return bucket;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Create Bucket: " + bucketName, e);
}
}
protected String getBucketLocationImpl(String bucketName)
throws S3ServiceException
{
throw new S3ServiceException("The SOAP API interface for S3 does " +
"not allow you to retrieve location information for a bucket");
}
protected void deleteBucketImpl(String bucketName) throws S3ServiceException {
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "DeleteBucket" + convertDateToString(timestamp));
s3SoapBinding.deleteBucket(
bucketName, getAWSAccessKey(), timestamp, signature, null);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Delete Bucket: " + bucketName, e);
}
}
protected S3Object putObjectImpl(String bucketName, S3Object object) throws S3ServiceException {
if (log.isDebugEnabled()) {
log.debug("Creating Object with key " + object.getKey() + " in bucket " + bucketName);
}
Grant[] grants = null;
if (object.getAcl() != null) {
grants = convertACLtoGrants(object.getAcl());
}
MetadataEntry[] metadata = convertMetadata(object.getMetadataMap());
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
long contentLength = object.getContentLength();
String contentType = object.getContentType();
if (contentType == null) {
// Set default content type.
contentType = Mimetypes.MIMETYPE_OCTET_STREAM;
}
if (object.getDataInputStream() != null) {
if (log.isDebugEnabled()) {
log.debug("Uploading data input stream for S3Object: " + object.getKey());
}
if (contentLength == 0 && object.getDataInputStream().available() > 0) {
if (log.isWarnEnabled()) {
log.warn("S3Object " + object.getKey()
+ " - Content-Length was set to 0 despite having a non-empty data"
+ " input stream. The Content-length will be determined in memory.");
}
// Read all data into memory to determine it's length.
BufferedInputStream bis = new BufferedInputStream(object.getDataInputStream());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(baos);
try {
byte[] buffer = new byte[8192];
int read = -1;
while ((read = bis.read(buffer)) != -1) {
bos.write(buffer, 0, read);
}
} finally {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
}
contentLength = baos.size();
object.setDataInputStream(new ByteArrayInputStream(baos.toByteArray()));
if (log.isDebugEnabled()) {
log.debug("Content-Length value has been reset to " + contentLength);
}
}
DataHandler dataHandler = new DataHandler(
new SourceDataSource(
null, contentType, new StreamSource(object.getDataInputStream())));
s3SoapBinding.addAttachment(dataHandler);
} else {
DataHandler dataHandler = new DataHandler(
new SourceDataSource(
null, contentType, new StreamSource()));
s3SoapBinding.addAttachment(dataHandler);
}
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "PutObject" + convertDateToString(timestamp));
PutObjectResult result =
s3SoapBinding.putObject(bucketName, object.getKey(), metadata,
contentLength, grants, null, getAWSAccessKey(),
timestamp, signature, null);
// Ensure no data was corrupted, if we have the MD5 hash available to check.
String eTag = result.getETag().substring(1, result.getETag().length() - 1);
String eTagAsBase64 = ServiceUtils.toBase64(
ServiceUtils.fromHex(eTag));
String md5HashAsBase64 = object.getMd5HashAsBase64();
if (md5HashAsBase64 != null && !eTagAsBase64.equals(md5HashAsBase64)) {
throw new S3ServiceException(
"Object created but ETag returned by S3 does not match MD5 hash value of object");
}
object.setETag(result.getETag());
object.setContentLength(contentLength);
object.setContentType(contentType);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Create Object: " + object.getKey(), e);
}
return object;
}
protected void deleteObjectImpl(String bucketName, String objectKey) throws S3ServiceException {
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "DeleteObject" + convertDateToString(timestamp));
s3SoapBinding.deleteObject(bucketName, objectKey,
getAWSAccessKey(), timestamp, signature, null);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Delete Object: " + objectKey, e);
}
}
protected Map copyObjectImpl(String sourceBucketName, String sourceObjectKey,
String destinationBucketName, String destinationObjectKey,
AccessControlList acl, Map destinationMetadata, Calendar ifModifiedSince,
Calendar ifUnmodifiedSince, String[] ifMatchTags, String[] ifNoneMatchTags)
throws S3ServiceException
{
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "CopyObject" + convertDateToString(timestamp));
MetadataDirective metadataDirective = null;
MetadataEntry[] metadata = null;
if (destinationMetadata != null) {
metadataDirective = MetadataDirective.REPLACE;
metadata = convertMetadata(destinationMetadata);
} else {
metadataDirective = MetadataDirective.COPY;
}
Grant[] grants = null;
if (acl != null) {
grants = convertACLtoGrants(acl);
}
CopyObjectResult result = s3SoapBinding.copyObject(
sourceBucketName, sourceObjectKey, destinationBucketName,
destinationObjectKey, metadataDirective, metadata, grants,
ifModifiedSince, ifUnmodifiedSince, ifMatchTags, ifNoneMatchTags,
null, getAWSAccessKey(), timestamp, signature, null);
Map resultMap = new HashMap();
resultMap.put("ETag", result.getETag());
resultMap.put("Last-Modified", result.getLastModified().getTime());
return resultMap;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Copy Object from '" +
sourceBucketName + ":" + sourceObjectKey + "' to '" +
destinationBucketName + ":" + destinationObjectKey + "'", e);
}
}
protected S3Object getObjectDetailsImpl(String bucketName, String objectKey, Calendar ifModifiedSince,
Calendar ifUnmodifiedSince, String[] ifMatchTags, String[] ifNoneMatchTags)
throws S3ServiceException
{
return getObjectImpl(false, bucketName, objectKey, ifModifiedSince, ifUnmodifiedSince,
ifMatchTags, ifNoneMatchTags, null, null);
}
protected S3Object getObjectImpl(String bucketName, String objectKey, Calendar ifModifiedSince,
Calendar ifUnmodifiedSince, String[] ifMatchTags, String[] ifNoneMatchTags,
Long byteRangeStart, Long byteRangeEnd)
throws S3ServiceException
{
return getObjectImpl(true, bucketName, objectKey, ifModifiedSince, ifUnmodifiedSince,
ifMatchTags, ifNoneMatchTags, byteRangeStart, byteRangeEnd);
}
private S3Object getObjectImpl(boolean withData, String bucketName, String objectKey,
Calendar ifModifiedSince, Calendar ifUnmodifiedSince, String[] ifMatchTags,
String[] ifNoneMatchTags, Long byteRangeStart, Long byteRangeEnd)
throws S3ServiceException
{
boolean useExtendedGet =
ifModifiedSince != null || ifUnmodifiedSince != null
|| ifMatchTags != null || ifNoneMatchTags != null
|| byteRangeStart != null || byteRangeEnd != null;
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
GetObjectResult result = null;
if (useExtendedGet) {
if (log.isDebugEnabled()) {
log.debug("Using Extended GET to apply constraints: "
+ "ifModifiedSince=" + (ifModifiedSince != null? ifModifiedSince.getTime().toString() : "null")
+ ", ifUnmodifiedSince=" + (ifUnmodifiedSince != null? ifUnmodifiedSince.getTime().toString() : "null")
+ ", ifMatchTags=" + (ifMatchTags != null? Arrays.asList(ifMatchTags).toString() : "null")
+ ", ifNoneMatchTags=" + (ifNoneMatchTags != null? Arrays.asList(ifNoneMatchTags).toString() : "null")
+ ", byteRangeStart=" + byteRangeStart + ", byteRangeEnd=" + byteRangeEnd);
}
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "GetObjectExtended" + convertDateToString(timestamp));
result = s3SoapBinding.getObjectExtended(
bucketName, objectKey, true, withData, false, byteRangeStart, byteRangeEnd,
ifModifiedSince, ifUnmodifiedSince, ifMatchTags, ifNoneMatchTags,
Boolean.FALSE, getAWSAccessKey(), timestamp, signature, null);
// Throw an exception if the preconditions failed.
int expectedStatusCode = 200;
if (byteRangeStart != null || byteRangeEnd != null) {
// Partial data responses have a status code of 206.
expectedStatusCode = 206;
}
if (result.getStatus().getCode() != expectedStatusCode) {
throw new S3ServiceException("Precondition failed when getting object "
+ objectKey + ": " + result.getStatus().getDescription());
}
} else {
if (log.isDebugEnabled()) {
log.debug("Using standard GET (no constraints to apply)");
}
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "GetObject" + convertDateToString(timestamp));
result = s3SoapBinding.getObject(
bucketName, objectKey, true, withData, false,
getAWSAccessKey(), timestamp, signature, null);
}
S3Object object = new S3Object(objectKey);
object.setETag(result.getETag());
object.setLastModifiedDate(result.getLastModified().getTime());
object.setBucketName(bucketName);
// Get data details from the SOAP attachment.
if (withData) {
Object[] attachments = s3SoapBinding.getAttachments();
if (log.isDebugEnabled()) {
log.debug("SOAP attachment count for " + object.getKey() + ": " + attachments.length);
}
for (int i = 0; i < attachments.length; i++) {
if (i > 0) {
throw new S3ServiceException(
"Received multiple SOAP attachment parts, this shouldn't happen");
}
AttachmentPart part = (AttachmentPart) attachments[i];
object.setContentType(part.getContentType());
object.setContentLength(part.getSize());
object.setDataInputStream(part.getDataHandler().getInputStream());
}
}
// Populate object's metadata details.
MetadataEntry[] metadata = result.getMetadata();
for (int i = 0; i < metadata.length; i++) {
MetadataEntry entry = metadata[i];
object.addMetadata(entry.getName(), entry.getValue());
}
object.setMetadataComplete(true);
return object;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Get Object: " + objectKey, e);
}
}
protected void putObjectAclImpl(String bucketName, String objectKey, AccessControlList acl)
throws S3ServiceException
{
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
Grant[] grants = convertACLtoGrants(acl);
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "SetObjectAccessControlPolicy" + convertDateToString(timestamp));
s3SoapBinding.setObjectAccessControlPolicy(bucketName, objectKey, grants,
getAWSAccessKey(), timestamp, signature, null);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Put Object ACL", e);
}
}
protected void putBucketAclImpl(String bucketName, AccessControlList acl)
throws S3ServiceException
{
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
Grant[] grants = convertACLtoGrants(acl);
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "SetBucketAccessControlPolicy" + convertDateToString(timestamp));
s3SoapBinding.setBucketAccessControlPolicy(bucketName, grants,
getAWSAccessKey(), timestamp, signature, null);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Put Bucket ACL", e);
}
}
protected AccessControlList getObjectAclImpl(String bucketName, String objectKey) throws S3ServiceException {
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "GetObjectAccessControlPolicy" + convertDateToString(timestamp));
AccessControlPolicy result = s3SoapBinding.getObjectAccessControlPolicy(
bucketName, objectKey, getAWSAccessKey(),
timestamp, signature, null);
return convertAccessControlTypes(result);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Get ACL", e);
}
}
protected AccessControlList getBucketAclImpl(String bucketName) throws S3ServiceException {
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "GetBucketAccessControlPolicy" + convertDateToString(timestamp));
AccessControlPolicy result = s3SoapBinding.getBucketAccessControlPolicy(bucketName,
getAWSAccessKey(), timestamp, signature, null);
return convertAccessControlTypes(result);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Get ACL", e);
}
}
protected S3BucketLoggingStatus getBucketLoggingStatusImpl(String bucketName) throws S3ServiceException {
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "GetBucketLoggingStatus" + convertDateToString(timestamp));
BucketLoggingStatus loggingStatus = s3SoapBinding.getBucketLoggingStatus(
bucketName, getAWSAccessKey(), timestamp, signature, null);
LoggingSettings loggingSettings = loggingStatus.getLoggingEnabled();
if (loggingSettings != null) {
return new S3BucketLoggingStatus(loggingSettings.getTargetBucket(), loggingSettings.getTargetPrefix());
} else {
return new S3BucketLoggingStatus();
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Get Bucket logging status for " + bucketName, e);
}
}
protected void setBucketLoggingStatusImpl(String bucketName, S3BucketLoggingStatus status) throws S3ServiceException {
try {
AmazonS3SoapBindingStub s3SoapBinding = getSoapBinding();
Calendar timestamp = getTimeStamp( System.currentTimeMillis() );
String signature = ServiceUtils.signWithHmacSha1(getAWSSecretKey(),
Constants.SOAP_SERVICE_NAME + "SetBucketLoggingStatus" + convertDateToString(timestamp));
LoggingSettings loggingSettings = null;
if (status.isLoggingEnabled()) {
loggingSettings = new LoggingSettings(
status.getTargetBucketName(), status.getLogfilePrefix(), new Grant[] {});
}
s3SoapBinding.setBucketLoggingStatus(
bucketName, getAWSAccessKey(), timestamp, signature, null,
new BucketLoggingStatus(loggingSettings));
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new S3ServiceException("Unable to Set Bucket logging status for " + bucketName
+ ": " + status, e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy