Logo Search packages:      
Sourcecode: jets3t version File versions  Download package

SoapS3Service.java

/*
 * 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.VersionOrDeleteMarkersChunk;
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.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.BaseVersionOrDeleteMarker;
import org.jets3t.service.model.S3Bucket;
import org.jets3t.service.model.S3BucketLoggingStatus;
import org.jets3t.service.model.S3BucketVersioningStatus;
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
 * <a href="http://ws.apache.org/axis/">Apache Axis 1.4</a> library.
 * <p>
 * <b>Note</b>: This SOAP implementation does <b>not</b> 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.
 * </p>
 * <p>
 * <b>Note 2</b>: The SOAP implementation does not perform retries when communication with s3 fails.
 * </p>
 * <p>
 * The preferred S3Service implementation in JetS3t is
 * {@link org.jets3t.service.impl.rest.httpclient.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. <b>We do not
 * recommend that this service be used to perform any real work.</b>
 * </p>
 *
 * @author James Murty
 */
00107 public class SoapS3Service extends S3Service {
    private static final long serialVersionUID = -7952919998435920809L;

    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: <code>Cockpit/0.7.3</code> or <code>My App Name/1.0</code>
     * @param jets3tProperties
     * JetS3t properties that will be applied within this service.
     *
     * @throws S3ServiceException
     */
00127     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: <code>Cockpit/0.7.3</code> or <code>My App Name/1.0</code>
     * @throws S3ServiceException
     */
00160     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
     */
00174     public SoapS3Service(AWSCredentials awsCredentials) throws S3ServiceException {
        this(awsCredentials, null);
    }

    protected void shutdownImpl() throws S3ServiceException {
        locator = 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
     */
00236     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];
            GrantAndPermission jets3tGrantAndPermission = convertGrant(grant);
            acl.grantPermission(jets3tGrantAndPermission.getGrantee(),
                  jets3tGrantAndPermission.getPermission());
        }
        return acl;
    }

    private GrantAndPermission convertGrant(Grant grant) throws S3ServiceException {
        org.jets3t.service.acl.Permission permission =
            org.jets3t.service.acl.Permission.parsePermission(grant.getPermission().toString());
        org.jets3t.service.acl.GranteeInterface jets3tGrantee = null;

        Grantee grantee = grant.getGrantee();
        if (grantee instanceof Group) {
            jets3tGrantee = new GroupGrantee();
            jets3tGrantee.setIdentifier(((Group)grantee).getURI());
        } else if (grantee instanceof CanonicalUser) {
            CanonicalUser canonicalUser = (CanonicalUser) grantee;
            jets3tGrantee = new CanonicalGrantee();
            jets3tGrantee.setIdentifier(canonicalUser.getID());
            ((CanonicalGrantee)jets3tGrantee).setDisplayName(canonicalUser.getDisplayName());
        } else if (grantee instanceof AmazonCustomerByEmail) {
            AmazonCustomerByEmail customerByEmail = (AmazonCustomerByEmail) grantee;
            jets3tGrantee = new EmailAddressGrantee();
            jets3tGrantee.setIdentifier(customerByEmail.getEmailAddress());
        } else {
            throw new S3ServiceException("Unrecognised grantee type: " + grantee.getClass());
        }
        return new GrantAndPermission(jets3tGrantee, permission);
    }

    /**
     * Converts a jets3t AccessControlList object to an array of SOAP Grant objects.
     *
     * @param acl
     * @return
     * @throws S3ServiceException
     */
00283     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();
            Grant grant = convertGrantAndPermissionToGrant(jets3tGaP);
            grants[index++] = grant;
        }
        return grants;
    }

    private Grant convertGrantAndPermissionToGrant(GrantAndPermission jets3tGaP)
            throws S3ServiceException
    {
        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);
        return grant;
    }

    /**
     * Converts metadata information from a standard map to SOAP objects.
     *
     * @param metadataMap
     * @return
     */
00340     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
    ////////////////////////////////////////////////////////////////

00363     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;
    }

00395     protected S3Owner getAccountOwnerImpl() throws S3ServiceException {
        if (log.isDebugEnabled()) {
            log.debug("Looking up owner of S3 account via the ListAllBuckets response: "
                + getAWSCredentials().getAccessKey());
        }

        S3Owner owner = 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);

            owner = new S3Owner(
                result.getOwner().getID(),
                result.getOwner().getDisplayName());
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new S3ServiceException("Unable to List Buckets", e);
        }
        return owner;
    }

00421     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;
        }
    }

00443     public int checkBucketStatus(String bucketName) throws S3ServiceException {
        throw new S3ServiceException("The method checkBucketStatus(String bucketName) "
            + "is not implemented in " + this.getClass().getName());
    }

00448     protected S3Object[] listObjectsImpl(String bucketName, String prefix, String delimiter, long maxListingLength)
        throws S3ServiceException
    {
        return listObjectsInternalImpl(bucketName, prefix, delimiter, maxListingLength, true, null)
            .getObjects();
    }

00455     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);
        }
    }

00554     protected S3Bucket createBucketImpl(String bucketName, String location,
        AccessControlList acl) throws S3ServiceException
    {
        if (location != null && !"US".equalsIgnoreCase(location)) {
            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,
      String versionId, String multiFactorSerialNumber, String multiFactorAuthCode)
        throws S3ServiceException
    {
        if (versionId != null || multiFactorSerialNumber != null || multiFactorAuthCode != null)
        {
            throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
        }
        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);
        }
    }

00730     protected Map copyObjectImpl(String sourceBucketName, String sourceObjectKey,
        String destinationBucketName, String destinationObjectKey,
        AccessControlList acl, Map destinationMetadata, Calendar ifModifiedSince,
        Calendar ifUnmodifiedSince, String[] ifMatchTags, String[] ifNoneMatchTags,
        String versionId) throws S3ServiceException
    {
        if (versionId != null) {
            throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
        }
        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, String versionId)
        throws S3ServiceException
    {
        if (versionId != null) {
            throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
        }
        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, String versionId)
        throws S3ServiceException
    {
        if (versionId != null) {
            throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
        }
        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,
      String versionId) throws S3ServiceException
    {
        if (versionId != null) {
            throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
        }
        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,
      String versionId) throws S3ServiceException
    {
        if (versionId != null) {
            throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
        }
        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();
            S3BucketLoggingStatus s3BucketLoggingStatus = null;
            if (loggingSettings != null) {
                s3BucketLoggingStatus = new S3BucketLoggingStatus(
                        loggingSettings.getTargetBucket(), loggingSettings.getTargetPrefix());
                Grant[] grants = loggingSettings.getTargetGrants();
                if (grants != null) {
                    for (int i = 0; i < grants.length; i++) {
                        Grant grant = grants[i];
                        s3BucketLoggingStatus.addTargetGrant(convertGrant(grant));
                    }
                }
            } else {
                s3BucketLoggingStatus = new S3BucketLoggingStatus();
            }
            return 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[] {});
                if (status.getTargetGrants() != null) {
                    ArrayList grantsList = new ArrayList();
                    for (int i = 0; i < status.getTargetGrants().length; i++) {
                        GrantAndPermission grantAndPermission = status.getTargetGrants()[i];
                        grantsList.add(convertGrantAndPermissionToGrant(grantAndPermission));
                    }
                    loggingSettings.setTargetGrants(
                        (Grant[]) grantsList.toArray(new Grant[grantsList.size()]));
                }
            }
            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);
        }
    }

    protected boolean isRequesterPaysBucketImpl(String bucketName) throws S3ServiceException {
        throw new S3ServiceException("The SOAP API interface for S3 does not allow " +
            "you to retrieve request payment configuration settings for a bucket, " +
            "please use the REST API client class RestS3Service instead");
    }

    protected void setRequesterPaysBucketImpl(String bucketName, boolean requesterPays) throws S3ServiceException {
        throw new S3ServiceException("The SOAP API interface for S3 does not allow " +
            "you to set a bucket's request payment configuration settings, " +
            "please use the REST API client class RestS3Service instead");
    }

    protected S3BucketVersioningStatus getBucketVersioningStatusImpl(String bucketName)
            throws S3ServiceException
    {
        throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
    }

01056     protected VersionOrDeleteMarkersChunk listVersionedObjectsChunkedImpl(
            String bucketName, String prefix, String delimiter,
            long maxListingLength, String priorLastKey,
            String priorLastVersion, boolean completeListing)
            throws S3ServiceException
    {
        throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
    }

    protected BaseVersionOrDeleteMarker[] listVersionedObjectsImpl(
            String bucketName, String prefix, String delimiter,
            String keyMarker, String versionMarker, long maxListingLength)
            throws S3ServiceException
    {
        throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
    }

    protected void updateBucketVersioningStatusImpl(String bucketName,
            boolean enabled, boolean multiFactorAuthDeleteEnabled,
            String multiFactorSerialNumber, String multiFactorAuthCode)
            throws S3ServiceException
    {
        throw new S3ServiceException("The SOAP API interface for S3 does not support versioning");
    }

}

Generated by  Doxygen 1.6.0   Back to index