You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2016/07/05 11:22:29 UTC

[4/4] camel git commit: CAMEL-10100: Add support for copyObject in camel aws-s3

CAMEL-10100: Add support for copyObject in camel aws-s3


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/02d395d4
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/02d395d4
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/02d395d4

Branch: refs/heads/master
Commit: 02d395d47f5dee17a0dd218d4e17fa950de606a4
Parents: 3ed19b7
Author: Andrea Cosentino <an...@gmail.com>
Authored: Tue Jul 5 12:26:10 2016 +0200
Committer: Andrea Cosentino <an...@gmail.com>
Committed: Tue Jul 5 12:46:50 2016 +0200

----------------------------------------------------------------------
 components/camel-aws/src/main/docs/aws-s3.adoc  |  5 +-
 .../camel/component/aws/s3/S3Configuration.java | 16 +++-
 .../camel/component/aws/s3/S3Constants.java     | 37 ++++----
 .../camel/component/aws/s3/S3Operations.java    | 22 +++++
 .../camel/component/aws/s3/S3Producer.java      | 77 +++++++++++++++-
 .../component/aws/s3/AmazonS3ClientMock.java    |  5 +-
 .../aws/s3/S3ComponentCopyObjectSpringTest.java | 84 +++++++++++++++++
 .../aws/s3/S3ComponentCopyObjectTest.java       | 96 ++++++++++++++++++++
 .../aws/s3/S3ComponentSpringTest-context.xml    |  6 +-
 9 files changed, 322 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/02d395d4/components/camel-aws/src/main/docs/aws-s3.adoc
----------------------------------------------------------------------
diff --git a/components/camel-aws/src/main/docs/aws-s3.adoc b/components/camel-aws/src/main/docs/aws-s3.adoc
index 04597b7..0b3ba5b 100644
--- a/components/camel-aws/src/main/docs/aws-s3.adoc
+++ b/components/camel-aws/src/main/docs/aws-s3.adoc
@@ -43,8 +43,9 @@ The AWS S3 Storage Service component has no options.
 
 
 
+
 // endpoint options: START
-The AWS S3 Storage Service component supports 39 endpoint options which are listed below:
+The AWS S3 Storage Service component supports 40 endpoint options which are listed below:
 
 {% raw %}
 [width="100%",cols="2s,1,1m,1m,5",options="header"]
@@ -54,6 +55,7 @@ The AWS S3 Storage Service component supports 39 endpoint options which are list
 | accessKey | common |  | String | Amazon AWS Access Key
 | amazonS3Client | common |  | AmazonS3 | Reference to a com.amazonaws.services.sqs.AmazonS3 in the link:registry.htmlRegistry.
 | amazonS3Endpoint | common |  | String | The region with which the AWS-S3 client wants to work with.
+| operation | common |  | S3Operations | Camel 2.18: The operation to do in case the user don't want to do only an upload
 | pathStyleAccess | common | false | boolean | Whether or not the S3 client should use path style access
 | policy | common |  | String | Camel 2.8.4: The policy for this queue to set in the com.amazonaws.services.s3.AmazonS3setBucketPolicy() method.
 | proxyHost | common |  | String | Camel 2.16: To define a proxy host when instantiating the SQS client
@@ -99,6 +101,7 @@ The AWS S3 Storage Service component supports 39 endpoint options which are list
 
 
 
+
 Required S3 component options
 
 You have to provide the amazonS3Client in the

http://git-wip-us.apache.org/repos/asf/camel/blob/02d395d4/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Configuration.java
----------------------------------------------------------------------
diff --git a/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Configuration.java b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Configuration.java
index abaad4d..9e36157 100644
--- a/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Configuration.java
+++ b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Configuration.java
@@ -17,6 +17,7 @@
 package org.apache.camel.component.aws.s3;
 
 import com.amazonaws.services.s3.AmazonS3;
+
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriParams;
 import org.apache.camel.util.ObjectHelper;
@@ -61,6 +62,8 @@ public class S3Configuration implements Cloneable {
     private boolean includeBody = true;
     @UriParam
     private boolean pathStyleAccess;
+    @UriParam
+    private S3Operations operation;
 
     public long getPartSize() {
         return partSize;
@@ -280,7 +283,18 @@ public class S3Configuration implements Cloneable {
         return pathStyleAccess;
     }
 
-    boolean hasProxyConfiguration() {
+    public S3Operations getOperation() {
+		return operation;
+	}
+
+    /**
+     * *Camel 2.18*: The operation to do in case the user don't want to do only an upload
+     */
+	public void setOperation(S3Operations operation) {
+		this.operation = operation;
+	}
+
+	boolean hasProxyConfiguration() {
         return ObjectHelper.isNotEmpty(getProxyHost()) && ObjectHelper.isNotEmpty(getProxyPort());
 
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/02d395d4/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Constants.java
----------------------------------------------------------------------
diff --git a/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Constants.java b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Constants.java
index 8bd783f..c337f19 100644
--- a/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Constants.java
+++ b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Constants.java
@@ -22,21 +22,24 @@ package org.apache.camel.component.aws.s3;
  */
 public interface S3Constants {
 
-    String BUCKET_NAME         = "CamelAwsS3BucketName";
-    String CACHE_CONTROL       = "CamelAwsS3ContentControl";
-    String CONTENT_DISPOSITION = "CamelAwsS3ContentDisposition";
-    String CONTENT_ENCODING    = "CamelAwsS3ContentEncoding";
-    String CONTENT_LENGTH      = "CamelAwsS3ContentLength";
-    String CONTENT_MD5         = "CamelAwsS3ContentMD5";
-    String CONTENT_TYPE        = "CamelAwsS3ContentType";
-    String E_TAG               = "CamelAwsS3ETag";
-    String KEY                 = "CamelAwsS3Key";
-    String LAST_MODIFIED       = "CamelAwsS3LastModified";
-    String STORAGE_CLASS       = "CamelAwsS3StorageClass";
-    String VERSION_ID          = "CamelAwsS3VersionId";
-    String CANNED_ACL          = "CamelAwsS3CannedAcl";
-    String ACL                 = "CamelAwsS3Acl";
-    String USER_METADATA       = "CamelAwsS3UserMetadata";
-    String S3_HEADERS          = "CamelAwsS3Headers";
-    String SERVER_SIDE_ENCRYPTION = "CamelAwsS3ServerSideEncryption";
+    String BUCKET_NAME                     = "CamelAwsS3BucketName";
+    String BUCKET_DESTINATION_NAME         = "CamelAwsS3BucketDestinationName";
+    String CACHE_CONTROL                   = "CamelAwsS3ContentControl";
+    String CONTENT_DISPOSITION             = "CamelAwsS3ContentDisposition";
+    String CONTENT_ENCODING                = "CamelAwsS3ContentEncoding";
+    String CONTENT_LENGTH                  = "CamelAwsS3ContentLength";
+    String CONTENT_MD5                     = "CamelAwsS3ContentMD5";
+    String CONTENT_TYPE                    = "CamelAwsS3ContentType";
+    String E_TAG                           = "CamelAwsS3ETag";
+    String KEY                             = "CamelAwsS3Key";
+    String DESTINATION_KEY                 = "CamelAwsS3DestinationKey";
+    String LAST_MODIFIED                   = "CamelAwsS3LastModified";
+    String STORAGE_CLASS                   = "CamelAwsS3StorageClass";
+    String VERSION_ID                      = "CamelAwsS3VersionId";
+    String CANNED_ACL                      = "CamelAwsS3CannedAcl";
+    String ACL                             = "CamelAwsS3Acl";
+    String USER_METADATA                   = "CamelAwsS3UserMetadata";
+    String S3_HEADERS                      = "CamelAwsS3Headers";
+    String S3_OPERATION                    = "CamelAwsS3Operation";
+    String SERVER_SIDE_ENCRYPTION          = "CamelAwsS3ServerSideEncryption";
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/02d395d4/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Operations.java
----------------------------------------------------------------------
diff --git a/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Operations.java b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Operations.java
new file mode 100644
index 0000000..33be0a2
--- /dev/null
+++ b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Operations.java
@@ -0,0 +1,22 @@
+/**
+ * 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.apache.camel.component.aws.s3;
+
+public enum S3Operations {
+
+    copyObject
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/02d395d4/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Producer.java
----------------------------------------------------------------------
diff --git a/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Producer.java b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Producer.java
index 0b97f99..538d413 100644
--- a/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Producer.java
+++ b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Producer.java
@@ -25,11 +25,14 @@ import java.util.List;
 import java.util.Map;
 
 import com.amazonaws.services.cloudfront.model.InvalidArgumentException;
+import com.amazonaws.services.s3.AmazonS3;
 import com.amazonaws.services.s3.model.AbortMultipartUploadRequest;
 import com.amazonaws.services.s3.model.AccessControlList;
 import com.amazonaws.services.s3.model.CannedAccessControlList;
 import com.amazonaws.services.s3.model.CompleteMultipartUploadRequest;
 import com.amazonaws.services.s3.model.CompleteMultipartUploadResult;
+import com.amazonaws.services.s3.model.CopyObjectRequest;
+import com.amazonaws.services.s3.model.CopyObjectResult;
 import com.amazonaws.services.s3.model.InitiateMultipartUploadRequest;
 import com.amazonaws.services.s3.model.InitiateMultipartUploadResult;
 import com.amazonaws.services.s3.model.ObjectMetadata;
@@ -42,10 +45,12 @@ import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.WrappedFile;
+import org.apache.camel.component.aws.ec2.EC2Constants;
 import org.apache.camel.impl.DefaultProducer;
 import org.apache.camel.util.CastUtils;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.URISupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -69,11 +74,22 @@ public class S3Producer extends DefaultProducer {
 
     @Override
     public void process(final Exchange exchange) throws Exception {
-        if (getConfiguration().isMultiPartUpload()) {
-            processMultiPart(exchange);
-        } else {
-            processSingleOp(exchange);
-        }
+    	S3Operations operation = determineOperation(exchange);
+    	if (ObjectHelper.isEmpty(operation)) {
+            if (getConfiguration().isMultiPartUpload()) {
+                processMultiPart(exchange);
+            } else {
+                processSingleOp(exchange);
+            }
+    	} else {
+            switch (operation) {
+            case copyObject:
+                copyObject(getEndpoint().getS3Client(), exchange);
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported operation");
+            }
+    	}
     }
 
     public void processMultiPart(final Exchange exchange) throws Exception {
@@ -225,6 +241,57 @@ public class S3Producer extends DefaultProducer {
             FileUtil.deleteFile(filePayload);
         }
     }
+    
+    private void copyObject(AmazonS3 s3Client, Exchange exchange) {
+        String bucketNameDestination;
+        String destinationKey;
+        String sourceKey;
+        String bucketName;
+        String versionId;
+        
+        bucketName = exchange.getIn().getHeader(S3Constants.BUCKET_NAME, String.class);
+        if (ObjectHelper.isEmpty(bucketName)) {
+        	bucketName = getConfiguration().getBucketName();
+        }
+        sourceKey = exchange.getIn().getHeader(S3Constants.KEY, String.class);
+        destinationKey = exchange.getIn().getHeader(S3Constants.DESTINATION_KEY, String.class);
+        bucketNameDestination = exchange.getIn().getHeader(S3Constants.BUCKET_DESTINATION_NAME, String.class);
+        versionId = exchange.getIn().getHeader(S3Constants.VERSION_ID, String.class);
+        
+        if (ObjectHelper.isEmpty(bucketName)) {
+        	throw new IllegalArgumentException("Bucket Name must be specified for copyObject Operation");
+        }
+        if (ObjectHelper.isEmpty(bucketNameDestination)) {
+        	throw new IllegalArgumentException("Bucket Name Destination must be specified for copyObject Operation");
+        }
+        if (ObjectHelper.isEmpty(sourceKey)) {
+        	throw new IllegalArgumentException("Source Key must be specified for copyObject Operation");
+        }
+        if (ObjectHelper.isEmpty(destinationKey)) {
+        	throw new IllegalArgumentException("Destination Key must be specified for copyObject Operation");
+        }
+        CopyObjectRequest copyObjectRequest;
+        if (ObjectHelper.isEmpty(versionId)) {
+            copyObjectRequest = new CopyObjectRequest(bucketName, sourceKey, bucketNameDestination, destinationKey);
+        } else {
+        	copyObjectRequest = new CopyObjectRequest(bucketName, sourceKey, versionId, bucketNameDestination, destinationKey);
+        }
+        CopyObjectResult copyObjectResult = s3Client.copyObject(copyObjectRequest);
+        
+        Message message = getMessageForResponse(exchange);
+        message.setHeader(S3Constants.E_TAG, copyObjectResult.getETag());
+        if (copyObjectResult.getVersionId() != null) {
+            message.setHeader(S3Constants.VERSION_ID, copyObjectResult.getVersionId());
+        }
+    }
+    
+    private S3Operations determineOperation(Exchange exchange) {
+        S3Operations operation = exchange.getIn().getHeader(EC2Constants.OPERATION, S3Operations.class);
+        if (operation == null) {
+            operation = getConfiguration().getOperation();
+        }
+        return operation;
+    }
 
     private ObjectMetadata determineMetadata(final Exchange exchange) {
         ObjectMetadata objectMetadata = new ObjectMetadata();

http://git-wip-us.apache.org/repos/asf/camel/blob/02d395d4/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/AmazonS3ClientMock.java
----------------------------------------------------------------------
diff --git a/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/AmazonS3ClientMock.java b/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/AmazonS3ClientMock.java
index 60ad8e0..dfbb6a2 100644
--- a/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/AmazonS3ClientMock.java
+++ b/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/AmazonS3ClientMock.java
@@ -340,7 +340,10 @@ public class AmazonS3ClientMock extends AmazonS3Client {
 
     @Override
     public CopyObjectResult copyObject(CopyObjectRequest copyObjectRequest) throws AmazonClientException, AmazonServiceException {
-        throw new UnsupportedOperationException();
+        CopyObjectResult copyObjectResult = new CopyObjectResult();
+        copyObjectResult.setETag("3a5c8b1ad448bca04584ecb55b836264");
+        copyObjectResult.setVersionId("11192828ahsh2723");
+        return copyObjectResult;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/02d395d4/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentCopyObjectSpringTest.java
----------------------------------------------------------------------
diff --git a/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentCopyObjectSpringTest.java b/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentCopyObjectSpringTest.java
new file mode 100644
index 0000000..5053932
--- /dev/null
+++ b/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentCopyObjectSpringTest.java
@@ -0,0 +1,84 @@
+/**
+ * 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.apache.camel.component.aws.s3;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Processor;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.spring.CamelSpringTestSupport;
+import org.junit.Test;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class S3ComponentCopyObjectSpringTest extends CamelSpringTestSupport {
+    
+    @EndpointInject(uri = "direct:start")
+    private ProducerTemplate template;
+    
+    @EndpointInject(uri = "mock:result")
+    private MockEndpoint result;
+    
+    private AmazonS3ClientMock client;
+    
+    @Test
+    public void sendIn() throws Exception {
+        result.expectedMessageCount(1);
+        
+        template.send("direct:copyObject", ExchangePattern.InOnly, new Processor() {
+            public void process(Exchange exchange) throws Exception {
+				exchange.getIn().setHeader(S3Constants.BUCKET_DESTINATION_NAME, "camelDestinationBucket");
+				exchange.getIn().setHeader(S3Constants.KEY, "camelKey");
+				exchange.getIn().setHeader(S3Constants.DESTINATION_KEY, "camelDestinationKey");
+            }
+        });
+        
+        assertMockEndpointsSatisfied();
+        
+        assertResultExchange(result.getExchanges().get(0));
+        
+    }
+    
+    private void assertResultExchange(Exchange resultExchange) {
+        assertEquals(resultExchange.getIn().getHeader(S3Constants.VERSION_ID), "11192828ahsh2723");
+        assertNull(resultExchange.getIn().getHeader(S3Constants.LAST_MODIFIED));
+        assertEquals(resultExchange.getIn().getHeader(S3Constants.E_TAG), "3a5c8b1ad448bca04584ecb55b836264");
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CONTENT_TYPE));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CONTENT_ENCODING));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CONTENT_DISPOSITION));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CONTENT_MD5));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CACHE_CONTROL));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.USER_METADATA));
+    }
+    
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+        
+        client = new AmazonS3ClientMock();
+        registry.bind("amazonS3Client", client);
+        
+        return registry;
+    }
+    
+    @Override
+    protected ClassPathXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("org/apache/camel/component/aws/s3/S3ComponentSpringTest-context.xml");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/02d395d4/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentCopyObjectTest.java
----------------------------------------------------------------------
diff --git a/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentCopyObjectTest.java b/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentCopyObjectTest.java
new file mode 100644
index 0000000..77cacd3
--- /dev/null
+++ b/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentCopyObjectTest.java
@@ -0,0 +1,96 @@
+/**
+ * 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.apache.camel.component.aws.s3;
+
+import java.util.Map;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Processor;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class S3ComponentCopyObjectTest extends CamelTestSupport {
+    
+    @EndpointInject(uri = "direct:start")
+    private ProducerTemplate template;
+    
+    @EndpointInject(uri = "mock:result")
+    private MockEndpoint result;
+    
+    private AmazonS3ClientMock client;
+    
+    @Test
+    public void sendIn() throws Exception {
+        result.expectedMessageCount(1);
+        
+        template.send("direct:start", ExchangePattern.InOnly, new Processor() {
+            public void process(Exchange exchange) throws Exception {
+				exchange.getIn().setHeader(S3Constants.BUCKET_DESTINATION_NAME, "camelDestinationBucket");
+				exchange.getIn().setHeader(S3Constants.KEY, "camelKey");
+				exchange.getIn().setHeader(S3Constants.DESTINATION_KEY, "camelDestinationKey");
+            }
+        });
+        
+        assertMockEndpointsSatisfied();
+        
+        assertResultExchange(result.getExchanges().get(0));
+        
+    }
+    
+    private void assertResultExchange(Exchange resultExchange) {
+        assertEquals(resultExchange.getIn().getHeader(S3Constants.VERSION_ID), "11192828ahsh2723");
+        assertNull(resultExchange.getIn().getHeader(S3Constants.LAST_MODIFIED));
+        assertEquals(resultExchange.getIn().getHeader(S3Constants.E_TAG), "3a5c8b1ad448bca04584ecb55b836264");
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CONTENT_TYPE));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CONTENT_ENCODING));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CONTENT_DISPOSITION));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CONTENT_MD5));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.CACHE_CONTROL));
+        assertNull(resultExchange.getIn().getHeader(S3Constants.USER_METADATA));
+    }
+    
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+        
+        client = new AmazonS3ClientMock();
+        registry.bind("amazonS3Client", client);
+        
+        return registry;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                String awsEndpoint = "aws-s3://mycamelbucket?amazonS3Client=#amazonS3Client&region=us-west-1&operation=copyObject";
+                
+                from("direct:start")
+                    .to(awsEndpoint)
+                    .to("mock:result");
+                
+            }
+        };
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/02d395d4/components/camel-aws/src/test/resources/org/apache/camel/component/aws/s3/S3ComponentSpringTest-context.xml
----------------------------------------------------------------------
diff --git a/components/camel-aws/src/test/resources/org/apache/camel/component/aws/s3/S3ComponentSpringTest-context.xml b/components/camel-aws/src/test/resources/org/apache/camel/component/aws/s3/S3ComponentSpringTest-context.xml
index df5ef66..bf6212c 100644
--- a/components/camel-aws/src/test/resources/org/apache/camel/component/aws/s3/S3ComponentSpringTest-context.xml
+++ b/components/camel-aws/src/test/resources/org/apache/camel/component/aws/s3/S3ComponentSpringTest-context.xml
@@ -25,7 +25,11 @@
             <from uri="direct:start"/>
             <to uri="aws-s3://mycamelbucket?amazonS3Client=#amazonS3Client"/>
         </route>
-        
+        <route>
+            <from uri="direct:copyObject"/>
+            <to uri="aws-s3://mycamelbucket?amazonS3Client=#amazonS3Client&amp;operation=copyObject"/>
+            <to uri="mock:result"/>
+        </route>       
         <route>
             <from uri="aws-s3://mycamelbucket?amazonS3Client=#amazonS3Client&amp;maxMessagesPerPoll=5"/>
             <to uri="mock:result"/>