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 2018/01/12 09:39:29 UTC

[camel] branch master updated: CAMEL-12135 - Camel-AWS S3: Add the ability to specify credentials and region at component level

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 8757e5a  CAMEL-12135 - Camel-AWS S3: Add the ability to specify credentials and region at component level
8757e5a is described below

commit 8757e5aac64107732f43a58e4ea23940b1c11429
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Fri Jan 12 09:13:01 2018 +0100

    CAMEL-12135 - Camel-AWS S3: Add the ability to specify credentials and region at component level
---
 .../camel-aws/src/main/docs/aws-s3-component.adoc  |  14 +-
 .../apache/camel/component/aws/s3/S3Component.java |  68 +++-
 .../camel/component/aws/s3/S3Configuration.java    |  13 +
 .../aws/s3/S3ComponentConfigurationTest.java       |  28 ++
 .../s3/springboot/S3ComponentConfiguration.java    | 366 +++++++++++++++++++++
 5 files changed, 487 insertions(+), 2 deletions(-)

diff --git a/components/camel-aws/src/main/docs/aws-s3-component.adoc b/components/camel-aws/src/main/docs/aws-s3-component.adoc
index 8d3b027..b6a5c39 100644
--- a/components/camel-aws/src/main/docs/aws-s3-component.adoc
+++ b/components/camel-aws/src/main/docs/aws-s3-component.adoc
@@ -35,7 +35,19 @@ from("aws-s3:helloBucket?accessKey=yourAccessKey&secretKey=yourSecretKey&prefix=
 
 
 // component options: START
-The AWS S3 Storage Service component has no options.
+The AWS S3 Storage Service component supports 5 options which are listed below.
+
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *configuration* (advanced) | The AWS S3 default configuration |  | S3Configuration
+| *accessKey* (common) | Amazon AWS Access Key |  | String
+| *secretKey* (common) | Amazon AWS Secret Key |  | String
+| *region* (common) | The region where the bucket is located. This option is used in the com.amazonaws.services.s3.model.CreateBucketRequest. |  | String
+| *resolveProperty Placeholders* (advanced) | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | boolean
+|===
 // component options: END
 
 
diff --git a/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Component.java b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Component.java
index 0e56f44..f17dc31 100644
--- a/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Component.java
+++ b/components/camel-aws/src/main/java/org/apache/camel/component/aws/s3/S3Component.java
@@ -21,9 +21,20 @@ import java.util.Map;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.impl.DefaultComponent;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.util.ObjectHelper;
 
 public class S3Component extends DefaultComponent {
     
+    @Metadata
+    private String accessKey;
+    @Metadata
+    private String secretKey;
+    @Metadata
+    private String region;
+    @Metadata(label = "advanced")    
+    private S3Configuration configuration;
+    
     public S3Component() {
         this(null);
     }
@@ -31,11 +42,12 @@ public class S3Component extends DefaultComponent {
     public S3Component(CamelContext context) {
         super(context);
         
+        this.configuration = new S3Configuration();
         registerExtension(new S3ComponentVerifierExtension());
     }
 
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
-        S3Configuration configuration = new S3Configuration();
+        final S3Configuration configuration = this.configuration.copy();
         setProperties(configuration, parameters);
 
         if (remaining == null || remaining.trim().length() == 0) {
@@ -46,6 +58,15 @@ public class S3Component extends DefaultComponent {
         }
         configuration.setBucketName(remaining);
 
+        if (ObjectHelper.isEmpty(configuration.getAccessKey())) {
+            setAccessKey(accessKey);
+        }
+        if (ObjectHelper.isEmpty(configuration.getSecretKey())) {
+            setSecretKey(secretKey);
+        }
+        if (ObjectHelper.isEmpty(configuration.getRegion())) {
+            setRegion(region);
+        }
         if (configuration.getAmazonS3Client() == null && (configuration.getAccessKey() == null || configuration.getSecretKey() == null)) {
             throw new IllegalArgumentException("AmazonS3Client or accessKey and secretKey must be specified");
         }
@@ -54,4 +75,49 @@ public class S3Component extends DefaultComponent {
         setProperties(endpoint, parameters);
         return endpoint;
     }
+    
+    public S3Configuration getConfiguration() {
+        return configuration;
+    }
+
+    /**
+     * The AWS S3 default configuration
+     */
+    public void setConfiguration(S3Configuration configuration) {
+        this.configuration = configuration;
+    }
+    
+    public String getAccessKey() {
+        return configuration.getAccessKey();
+    }
+
+    /**
+     * Amazon AWS Access Key
+     */
+    public void setAccessKey(String accessKey) {
+        configuration.setAccessKey(accessKey);
+    }
+
+    public String getSecretKey() {
+        return configuration.getSecretKey();
+    }
+
+    /**
+     * Amazon AWS Secret Key
+     */
+    public void setSecretKey(String secretKey) {
+        configuration.setSecretKey(secretKey);
+    }
+    
+    public String getRegion() {
+        return configuration.getRegion();
+    }
+
+    /**
+     * The region where the bucket is located. This option is used in the
+     * `com.amazonaws.services.s3.model.CreateBucketRequest`.
+     */
+    public void setRegion(String region) {
+        configuration.setRegion(region);
+    }
 }
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 fcca089..2e0ba6a 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
@@ -19,6 +19,7 @@ package org.apache.camel.component.aws.s3;
 import com.amazonaws.services.s3.AmazonS3;
 import com.amazonaws.services.s3.model.EncryptionMaterials;
 
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriParams;
 import org.apache.camel.util.ObjectHelper;
@@ -358,4 +359,16 @@ public class S3Configuration implements Cloneable {
     boolean hasProxyConfiguration() {
         return ObjectHelper.isNotEmpty(getProxyHost()) && ObjectHelper.isNotEmpty(getProxyPort());
     }
+    
+    // *************************************************
+    //
+    // *************************************************
+
+    public S3Configuration copy() {
+        try {
+            return (S3Configuration)super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeCamelException(e);
+        }
+    }
 }
diff --git a/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentConfigurationTest.java b/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentConfigurationTest.java
index 39ec751..1437cd3 100644
--- a/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentConfigurationTest.java
+++ b/components/camel-aws/src/test/java/org/apache/camel/component/aws/s3/S3ComponentConfigurationTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.aws.s3;
 
+import com.amazonaws.regions.Regions;
+
 import org.apache.camel.impl.JndiRegistry;
 import org.apache.camel.impl.PropertyPlaceholderDelegateRegistry;
 import org.apache.camel.test.junit4.CamelTestSupport;
@@ -144,6 +146,32 @@ public class S3ComponentConfigurationTest extends CamelTestSupport {
     }
     
     @Test
+    public void createEndpointWithComponentElements() throws Exception {
+        S3Component component = new S3Component(context);
+        component.setAccessKey("XXX");
+        component.setSecretKey("YYY");
+        S3Endpoint endpoint = (S3Endpoint)component.createEndpoint("aws-s3://MyBucket");
+        
+        assertEquals("MyBucket", endpoint.getConfiguration().getBucketName());
+        assertEquals("XXX", endpoint.getConfiguration().getAccessKey());
+        assertEquals("YYY", endpoint.getConfiguration().getSecretKey());
+    }
+    
+    @Test
+    public void createEndpointWithComponentAndEndpointElements() throws Exception {
+        S3Component component = new S3Component(context);
+        component.setAccessKey("XXX");
+        component.setSecretKey("YYY");
+        component.setRegion(Regions.US_WEST_1.toString());
+        S3Endpoint endpoint = (S3Endpoint)component.createEndpoint("aws-s3://MyBucket?accessKey=xxxxxx&secretKey=yyyyy&region=US_EAST_1");
+        
+        assertEquals("MyBucket", endpoint.getConfiguration().getBucketName());
+        assertEquals("xxxxxx", endpoint.getConfiguration().getAccessKey());
+        assertEquals("yyyyy", endpoint.getConfiguration().getSecretKey());
+        assertEquals("US_EAST_1", endpoint.getConfiguration().getRegion());
+    }
+    
+    @Test
     public void createEndpointWithoutSecretKeyAndAccessKeyConfiguration() throws Exception {
         AmazonS3ClientMock mock = new AmazonS3ClientMock();
         
diff --git a/platforms/spring-boot/components-starter/camel-aws-starter/src/main/java/org/apache/camel/component/aws/s3/springboot/S3ComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-aws-starter/src/main/java/org/apache/camel/component/aws/s3/springboot/S3ComponentConfiguration.java
index 9696eea..9ca5603 100644
--- a/platforms/spring-boot/components-starter/camel-aws-starter/src/main/java/org/apache/camel/component/aws/s3/springboot/S3ComponentConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-aws-starter/src/main/java/org/apache/camel/component/aws/s3/springboot/S3ComponentConfiguration.java
@@ -17,8 +17,12 @@
 package org.apache.camel.component.aws.s3.springboot;
 
 import javax.annotation.Generated;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.model.EncryptionMaterials;
+import org.apache.camel.component.aws.s3.S3Operations;
 import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon;
 import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
 
 /**
  * The aws-s3 component is used for storing and retrieving objecct from Amazon
@@ -33,12 +37,62 @@ public class S3ComponentConfiguration
             ComponentConfigurationPropertiesCommon {
 
     /**
+     * The AWS S3 default configuration
+     */
+    private S3ConfigurationNestedConfiguration configuration;
+    /**
+     * Amazon AWS Access Key
+     */
+    private String accessKey;
+    /**
+     * Amazon AWS Secret Key
+     */
+    private String secretKey;
+    /**
+     * The region where the bucket is located. This option is used in the
+     * com.amazonaws.services.s3.model.CreateBucketRequest.
+     */
+    private String region;
+    /**
      * Whether the component should resolve property placeholders on itself when
      * starting. Only properties which are of String type can use property
      * placeholders.
      */
     private Boolean resolvePropertyPlaceholders = true;
 
+    public S3ConfigurationNestedConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(
+            S3ConfigurationNestedConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public void setSecretKey(String secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    public String getRegion() {
+        return region;
+    }
+
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
     public Boolean getResolvePropertyPlaceholders() {
         return resolvePropertyPlaceholders;
     }
@@ -47,4 +101,316 @@ public class S3ComponentConfiguration
             Boolean resolvePropertyPlaceholders) {
         this.resolvePropertyPlaceholders = resolvePropertyPlaceholders;
     }
+
+    public static class S3ConfigurationNestedConfiguration {
+        public static final Class CAMEL_NESTED_CLASS = org.apache.camel.component.aws.s3.S3Configuration.class;
+        /**
+         * Setup the partSize which is used in multi part upload, the default
+         * size is 25M.
+         */
+        private Long partSize = 26214400L;
+        /**
+         * If it is true, camel will upload the file with multi part format, the
+         * part size is decided by the option of `partSize`
+         */
+        private Boolean multiPartUpload = false;
+        /**
+         * The region with which the AWS-S3 client wants to work with.
+         */
+        private String amazonS3Endpoint;
+        /**
+         * Amazon AWS Access Key
+         */
+        private String accessKey;
+        /**
+         * Amazon AWS Secret Key
+         */
+        private String secretKey;
+        /**
+         * Reference to a `com.amazonaws.services.sqs.AmazonS3` in the
+         * link:registry.html[Registry].
+         */
+        private AmazonS3 amazonS3Client;
+        /**
+         * The prefix which is used in the
+         * com.amazonaws.services.s3.model.ListObjectsRequest to only consume
+         * objects we are interested in.
+         */
+        private String prefix;
+        /**
+         * Name of the bucket. The bucket will be created if it doesn't already
+         * exists.
+         */
+        private String bucketName;
+        /**
+         * To get the object from the bucket with the given file name
+         */
+        private String fileName;
+        /**
+         * The region where the bucket is located. This option is used in the
+         * `com.amazonaws.services.s3.model.CreateBucketRequest`.
+         */
+        private String region;
+        /**
+         * If it is true, the exchange body will be set to a stream to the
+         * contents of the file. If false, the headers will be set with the S3
+         * object metadata, but the body will be null. This option is strongly
+         * related to autocloseBody option. In case of setting includeBody to
+         * true and autocloseBody to false, it will be up to the caller to close
+         * the S3Object stream. Setting autocloseBody to true, will close the
+         * S3Object stream automatically.
+         */
+        private Boolean includeBody = true;
+        /**
+         * Delete objects from S3 after they have been retrieved. The delete is
+         * only performed if the Exchange is committed. If a rollback occurs,
+         * the object is not deleted.
+         * <p/>
+         * If this option is false, then the same objects will be retrieve over
+         * and over again on the polls. Therefore you need to use the Idempotent
+         * Consumer EIP in the route to filter out duplicates. You can filter
+         * using the {@link S3Constants#BUCKET_NAME} and {@link S3Constants#KEY}
+         * headers, or only the {@link S3Constants#KEY} header.
+         */
+        private Boolean deleteAfterRead = true;
+        /**
+         * Delete file object after the S3 file has been uploaded
+         */
+        private Boolean deleteAfterWrite = false;
+        /**
+         * The policy for this queue to set in the
+         * `com.amazonaws.services.s3.AmazonS3#setBucketPolicy()` method.
+         */
+        private String policy;
+        /**
+         * The storage class to set in the
+         * `com.amazonaws.services.s3.model.PutObjectRequest` request.
+         */
+        private String storageClass;
+        /**
+         * Sets the server-side encryption algorithm when encrypting the object
+         * using AWS-managed keys. For example use <tt>AES256</tt>.
+         */
+        private String serverSideEncryption;
+        /**
+         * To define a proxy host when instantiating the SQS client
+         */
+        private String proxyHost;
+        /**
+         * Specify a proxy port to be used inside the client definition.
+         */
+        private Integer proxyPort;
+        /**
+         * Whether or not the S3 client should use path style access
+         */
+        private Boolean pathStyleAccess = false;
+        /**
+         * The operation to do in case the user don't want to do only an upload
+         */
+        private S3Operations operation;
+        /**
+         * If this option is true and includeBody is true, then the
+         * S3Object.close() method will be called on exchange completion. This
+         * option is strongly related to includeBody option. In case of setting
+         * includeBody to true and autocloseBody to false, it will be up to the
+         * caller to close the S3Object stream. Setting autocloseBody to true,
+         * will close the S3Object stream automatically.
+         */
+        private Boolean autocloseBody = true;
+        /**
+         * The encryption materials to use in case of Symmetric/Asymmetric
+         * client usage
+         */
+        @NestedConfigurationProperty
+        private EncryptionMaterials encryptionMaterials;
+        /**
+         * Define if encryption must be used or not
+         */
+        private Boolean useEncryption = false;
+
+        public Long getPartSize() {
+            return partSize;
+        }
+
+        public void setPartSize(Long partSize) {
+            this.partSize = partSize;
+        }
+
+        public Boolean getMultiPartUpload() {
+            return multiPartUpload;
+        }
+
+        public void setMultiPartUpload(Boolean multiPartUpload) {
+            this.multiPartUpload = multiPartUpload;
+        }
+
+        public String getAmazonS3Endpoint() {
+            return amazonS3Endpoint;
+        }
+
+        public void setAmazonS3Endpoint(String amazonS3Endpoint) {
+            this.amazonS3Endpoint = amazonS3Endpoint;
+        }
+
+        public String getAccessKey() {
+            return accessKey;
+        }
+
+        public void setAccessKey(String accessKey) {
+            this.accessKey = accessKey;
+        }
+
+        public String getSecretKey() {
+            return secretKey;
+        }
+
+        public void setSecretKey(String secretKey) {
+            this.secretKey = secretKey;
+        }
+
+        public AmazonS3 getAmazonS3Client() {
+            return amazonS3Client;
+        }
+
+        public void setAmazonS3Client(AmazonS3 amazonS3Client) {
+            this.amazonS3Client = amazonS3Client;
+        }
+
+        public String getPrefix() {
+            return prefix;
+        }
+
+        public void setPrefix(String prefix) {
+            this.prefix = prefix;
+        }
+
+        public String getBucketName() {
+            return bucketName;
+        }
+
+        public void setBucketName(String bucketName) {
+            this.bucketName = bucketName;
+        }
+
+        public String getFileName() {
+            return fileName;
+        }
+
+        public void setFileName(String fileName) {
+            this.fileName = fileName;
+        }
+
+        public String getRegion() {
+            return region;
+        }
+
+        public void setRegion(String region) {
+            this.region = region;
+        }
+
+        public Boolean getIncludeBody() {
+            return includeBody;
+        }
+
+        public void setIncludeBody(Boolean includeBody) {
+            this.includeBody = includeBody;
+        }
+
+        public Boolean getDeleteAfterRead() {
+            return deleteAfterRead;
+        }
+
+        public void setDeleteAfterRead(Boolean deleteAfterRead) {
+            this.deleteAfterRead = deleteAfterRead;
+        }
+
+        public Boolean getDeleteAfterWrite() {
+            return deleteAfterWrite;
+        }
+
+        public void setDeleteAfterWrite(Boolean deleteAfterWrite) {
+            this.deleteAfterWrite = deleteAfterWrite;
+        }
+
+        public String getPolicy() {
+            return policy;
+        }
+
+        public void setPolicy(String policy) {
+            this.policy = policy;
+        }
+
+        public String getStorageClass() {
+            return storageClass;
+        }
+
+        public void setStorageClass(String storageClass) {
+            this.storageClass = storageClass;
+        }
+
+        public String getServerSideEncryption() {
+            return serverSideEncryption;
+        }
+
+        public void setServerSideEncryption(String serverSideEncryption) {
+            this.serverSideEncryption = serverSideEncryption;
+        }
+
+        public String getProxyHost() {
+            return proxyHost;
+        }
+
+        public void setProxyHost(String proxyHost) {
+            this.proxyHost = proxyHost;
+        }
+
+        public Integer getProxyPort() {
+            return proxyPort;
+        }
+
+        public void setProxyPort(Integer proxyPort) {
+            this.proxyPort = proxyPort;
+        }
+
+        public Boolean getPathStyleAccess() {
+            return pathStyleAccess;
+        }
+
+        public void setPathStyleAccess(Boolean pathStyleAccess) {
+            this.pathStyleAccess = pathStyleAccess;
+        }
+
+        public S3Operations getOperation() {
+            return operation;
+        }
+
+        public void setOperation(S3Operations operation) {
+            this.operation = operation;
+        }
+
+        public Boolean getAutocloseBody() {
+            return autocloseBody;
+        }
+
+        public void setAutocloseBody(Boolean autocloseBody) {
+            this.autocloseBody = autocloseBody;
+        }
+
+        public EncryptionMaterials getEncryptionMaterials() {
+            return encryptionMaterials;
+        }
+
+        public void setEncryptionMaterials(
+                EncryptionMaterials encryptionMaterials) {
+            this.encryptionMaterials = encryptionMaterials;
+        }
+
+        public Boolean getUseEncryption() {
+            return useEncryption;
+        }
+
+        public void setUseEncryption(Boolean useEncryption) {
+            this.useEncryption = useEncryption;
+        }
+    }
 }
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
['"commits@camel.apache.org" <co...@camel.apache.org>'].