You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by or...@apache.org on 2020/10/09 11:20:09 UTC

[camel] branch master updated: Migrated the AWS Test infra from Camel Kafka Connector (#4405)

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

orpiske 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 c633944  Migrated the AWS Test infra from Camel Kafka Connector (#4405)
c633944 is described below

commit c633944c972338b6f2e51f2b4e7d03361a3461f3
Author: Otavio Rodolfo Piske <or...@users.noreply.github.com>
AuthorDate: Fri Oct 9 13:19:52 2020 +0200

    Migrated the AWS Test infra from Camel Kafka Connector (#4405)
    
    This simplifies using localstack containers as well as the actual AWS
    service as part of the tests
---
 parent/pom.xml                                     |   5 +
 .../{ => camel-test-infra-aws-common}/pom.xml      |  25 ++--
 .../src/main/resources/META-INF/MANIFEST.MF        |   0
 .../camel/test/infra/aws/common/AWSCommon.java     |  44 ++++++
 .../camel/test/infra/aws/common/AWSConfigs.java    |  28 ++++
 .../test/infra/aws/common/services/AWSService.java |  51 +++++++
 test-infra/camel-test-infra-aws-v1/pom.xml         | 100 +++++++++++++
 .../src/main/resources/META-INF/MANIFEST.MF        |   0
 .../test/infra/aws/clients/AWSClientUtils.java     | 165 +++++++++++++++++++++
 .../aws/common/TestAWSCredentialsProvider.java     |  66 +++++++++
 .../services/AWSKinesisLocalContainerService.java  |  56 +++++++
 .../aws/services/AWSLocalContainerService.java     | 101 +++++++++++++
 .../test/infra/aws/services/AWSRemoteService.java  |  69 +++++++++
 .../aws/services/AWSS3LocalContainerService.java   |  56 +++++++
 .../aws/services/AWSSNSLocalContainerService.java  |  52 +++++++
 .../aws/services/AWSSQSLocalContainerService.java  |  51 +++++++
 .../test/infra/aws/services/AWSServiceFactory.java | 106 +++++++++++++
 test-infra/pom.xml                                 |   2 +
 18 files changed, 965 insertions(+), 12 deletions(-)

diff --git a/parent/pom.xml b/parent/pom.xml
index a77d8b3..82671f3 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -3466,6 +3466,11 @@
                 <version>${testcontainers-version}</version>
             </dependency>
             <dependency>
+                <groupId>org.testcontainers</groupId>
+                <artifactId>localstack</artifactId>
+                <version>${testcontainers-version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.assertj</groupId>
                 <artifactId>assertj-core</artifactId>
                 <version>${assertj-version}</version>
diff --git a/test-infra/pom.xml b/test-infra/camel-test-infra-aws-common/pom.xml
similarity index 72%
copy from test-infra/pom.xml
copy to test-infra/camel-test-infra-aws-common/pom.xml
index d5f2079..84668f9 100644
--- a/test-infra/pom.xml
+++ b/test-infra/camel-test-infra-aws-common/pom.xml
@@ -20,22 +20,23 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <artifactId>camel-parent</artifactId>
+        <artifactId>camel-test-infra-parent</artifactId>
         <groupId>org.apache.camel</groupId>
+        <relativePath>../camel-test-infra-parent/pom.xml</relativePath>
         <version>3.6.0-SNAPSHOT</version>
-        <relativePath>../parent</relativePath>
     </parent>
-
     <modelVersion>4.0.0</modelVersion>
-    <artifactId>test-infra</artifactId>
 
-    <packaging>pom</packaging>
-    <name>Camel :: Test Infra</name>
-    <description>Test infrastructure for Camel</description>
+    <name>Camel :: Test Infra :: AWS Common</name>
+    <artifactId>camel-test-infra-aws-common</artifactId>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
 
-    <modules>
-        <module>camel-test-infra-common</module>
-        <module>camel-test-infra-kafka</module>
-        <module>camel-test-infra-parent</module>
-    </modules>
 </project>
\ No newline at end of file
diff --git a/test-infra/camel-test-infra-aws-common/src/main/resources/META-INF/MANIFEST.MF b/test-infra/camel-test-infra-aws-common/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e69de29
diff --git a/test-infra/camel-test-infra-aws-common/src/test/java/org/apache/camel/test/infra/aws/common/AWSCommon.java b/test-infra/camel-test-infra-aws-common/src/test/java/org/apache/camel/test/infra/aws/common/AWSCommon.java
new file mode 100644
index 0000000..aac67fc
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-common/src/test/java/org/apache/camel/test/infra/aws/common/AWSCommon.java
@@ -0,0 +1,44 @@
+/*
+ * 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.test.infra.aws.common;
+
+public final class AWSCommon {
+    /**
+     * The default SQS queue name used during the tests
+     */
+    public static final String BASE_SQS_QUEUE_NAME = "ckc";
+
+    /**
+     * The default SQS queue name used during the tests
+     */
+    public static final String DEFAULT_SQS_QUEUE_FOR_SNS = "ckcsns";
+
+    /**
+     * The default S3 bucket name used during the tests
+     */
+    public static final String DEFAULT_S3_BUCKET = "ckc-s3";
+
+    /**
+     * Base name for the Kinesis stream
+     */
+    public static final String KINESIS_STREAM_BASE_NAME = "ckc-kin-stream";
+
+    private AWSCommon() {
+    }
+
+}
diff --git a/test-infra/camel-test-infra-aws-common/src/test/java/org/apache/camel/test/infra/aws/common/AWSConfigs.java b/test-infra/camel-test-infra-aws-common/src/test/java/org/apache/camel/test/infra/aws/common/AWSConfigs.java
new file mode 100644
index 0000000..c9503ea
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-common/src/test/java/org/apache/camel/test/infra/aws/common/AWSConfigs.java
@@ -0,0 +1,28 @@
+/*
+ * 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.test.infra.aws.common;
+
+public final class AWSConfigs {
+    public static final String ACCESS_KEY = "access.key";
+    public static final String SECRET_KEY = "secret.key";
+    public static final String REGION = "aws.region";
+    public static final String AMAZON_AWS_HOST = "aws.host";
+    public static final String PROTOCOL = "aws.protocol";
+
+    private AWSConfigs() {
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-common/src/test/java/org/apache/camel/test/infra/aws/common/services/AWSService.java b/test-infra/camel-test-infra-aws-common/src/test/java/org/apache/camel/test/infra/aws/common/services/AWSService.java
new file mode 100644
index 0000000..b588963
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-common/src/test/java/org/apache/camel/test/infra/aws/common/services/AWSService.java
@@ -0,0 +1,51 @@
+/*
+ * 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.test.infra.aws.common.services;
+
+import java.util.Properties;
+
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+public interface AWSService<T> extends BeforeAllCallback, AfterAllCallback {
+
+    T getClient();
+
+    Properties getConnectionProperties();
+
+    /**
+     * Perform any initialization necessary
+     */
+    void initialize();
+
+    /**
+     * Shuts down the service after the test has completed
+     */
+    void shutdown();
+
+    @Override
+    default void beforeAll(ExtensionContext extensionContext) throws Exception {
+        initialize();
+    }
+
+    @Override
+    default void afterAll(ExtensionContext extensionContext) throws Exception {
+        shutdown();
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-v1/pom.xml b/test-infra/camel-test-infra-aws-v1/pom.xml
new file mode 100644
index 0000000..140ed69
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/pom.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>camel-test-infra-parent</artifactId>
+        <groupId>org.apache.camel</groupId>
+        <relativePath>../camel-test-infra-parent/pom.xml</relativePath>
+        <version>3.6.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <name>Camel :: Test Infra :: AWS SDK v1</name>
+    <artifactId>camel-test-infra-aws-v1</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-aws-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>localstack</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.amazonaws</groupId>
+            <artifactId>aws-java-sdk-core</artifactId>
+            <version>${aws-java-sdk-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.amazonaws</groupId>
+            <artifactId>aws-java-sdk-sqs</artifactId>
+            <version>${aws-java-sdk-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.amazonaws</groupId>
+            <artifactId>aws-java-sdk-kinesis</artifactId>
+            <version>${aws-java-sdk-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.amazonaws</groupId>
+            <artifactId>aws-java-sdk-s3</artifactId>
+            <version>${aws-java-sdk-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.amazonaws</groupId>
+            <artifactId>aws-java-sdk-sns</artifactId>
+            <version>${aws-java-sdk-version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/test-infra/camel-test-infra-aws-v1/src/main/resources/META-INF/MANIFEST.MF b/test-infra/camel-test-infra-aws-v1/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e69de29
diff --git a/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/clients/AWSClientUtils.java b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/clients/AWSClientUtils.java
new file mode 100644
index 0000000..8b0094e
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/clients/AWSClientUtils.java
@@ -0,0 +1,165 @@
+/*
+ * 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.test.infra.aws.clients;
+
+import com.amazonaws.ClientConfiguration;
+import com.amazonaws.Protocol;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.regions.Regions;
+import com.amazonaws.services.kinesis.AmazonKinesis;
+import com.amazonaws.services.kinesis.AmazonKinesisClientBuilder;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3ClientBuilder;
+import com.amazonaws.services.sns.AmazonSNS;
+import com.amazonaws.services.sns.AmazonSNSClientBuilder;
+import com.amazonaws.services.sqs.AmazonSQS;
+import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
+import org.apache.camel.test.infra.aws.common.AWSConfigs;
+import org.apache.camel.test.infra.aws.common.TestAWSCredentialsProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class AWSClientUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(AWSClientUtils.class);
+
+    private AWSClientUtils() {
+    }
+
+    private static String getRegion() {
+        String regionStr = System.getProperty(AWSConfigs.REGION);
+        String region;
+
+        if (regionStr != null && !regionStr.isEmpty()) {
+            region = Regions.valueOf(regionStr).getName();
+        } else {
+            region = Regions.US_EAST_1.getName();
+        }
+
+        return region;
+    }
+
+    public static AmazonSNS newSNSClient() {
+        LOG.debug("Creating a custom SNS client for running a AWS SNS test");
+        AmazonSNSClientBuilder clientBuilder = AmazonSNSClientBuilder
+                .standard();
+
+        String awsInstanceType = System.getProperty("aws-service.instance.type");
+        String region = getRegion();
+
+        if (awsInstanceType == null || awsInstanceType.equals("local-aws-container")) {
+            String amazonHost = System.getProperty(AWSConfigs.AMAZON_AWS_HOST);
+
+            ClientConfiguration clientConfiguration = new ClientConfiguration();
+            clientConfiguration.setProtocol(Protocol.HTTP);
+
+            clientBuilder
+                    .withClientConfiguration(clientConfiguration)
+                    .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(amazonHost, region))
+                    .withCredentials(new TestAWSCredentialsProvider("accesskey", "secretkey"));
+        } else {
+            clientBuilder
+                    .withRegion(region)
+                    .withCredentials(new TestAWSCredentialsProvider());
+        }
+
+        return clientBuilder.build();
+    }
+
+    public static AmazonSQS newSQSClient() {
+        LOG.debug("Creating a custom SQS client");
+        AmazonSQSClientBuilder clientBuilder = AmazonSQSClientBuilder
+                .standard();
+
+        String awsInstanceType = System.getProperty("aws-service.instance.type");
+        String region = getRegion();
+
+        if (awsInstanceType == null || awsInstanceType.equals("local-aws-container")) {
+            String amazonHost = System.getProperty(AWSConfigs.AMAZON_AWS_HOST);
+
+            ClientConfiguration clientConfiguration = new ClientConfiguration();
+            clientConfiguration.setProtocol(Protocol.HTTP);
+
+            clientBuilder
+                    .withClientConfiguration(clientConfiguration)
+                    .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(amazonHost, region))
+                    .withCredentials(new TestAWSCredentialsProvider("accesskey", "secretkey"));
+        } else {
+            clientBuilder
+                    .withRegion(region)
+                    .withCredentials(new TestAWSCredentialsProvider());
+        }
+
+        return clientBuilder.build();
+    }
+
+    public static AmazonS3 newS3Client() {
+        LOG.debug("Creating a new S3 client");
+        AmazonS3ClientBuilder clientBuilder = AmazonS3ClientBuilder.standard();
+
+        String awsInstanceType = System.getProperty("aws-service.instance.type");
+        String region = getRegion();
+
+        if (awsInstanceType == null || awsInstanceType.equals("local-aws-container")) {
+            String amazonHost = System.getProperty(AWSConfigs.AMAZON_AWS_HOST);
+            ClientConfiguration clientConfiguration = new ClientConfiguration();
+            clientConfiguration.setProtocol(Protocol.HTTP);
+
+            clientBuilder
+                    .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(amazonHost, region))
+                    .withClientConfiguration(clientConfiguration)
+                    .withCredentials(new TestAWSCredentialsProvider("accesskey", "secretkey"));
+        } else {
+            clientBuilder
+                    .withRegion(region)
+                    .withCredentials(new TestAWSCredentialsProvider());
+        }
+
+        clientBuilder
+                .withPathStyleAccessEnabled(true);
+
+        return clientBuilder.build();
+    }
+
+    public static AmazonKinesis newKinesisClient() {
+        LOG.debug("Creating a new AWS Kinesis client");
+        AmazonKinesisClientBuilder clientBuilder = AmazonKinesisClientBuilder.standard();
+
+        String awsInstanceType = System.getProperty("aws-service.kinesis.instance.type");
+        String region = getRegion();
+
+        if (awsInstanceType == null || awsInstanceType.equals("local-aws-container")) {
+            String amazonHost = System.getProperty(AWSConfigs.AMAZON_AWS_HOST);
+
+            LOG.debug("Creating a new AWS Kinesis client to access {}", amazonHost);
+
+            ClientConfiguration clientConfiguration = new ClientConfiguration();
+            clientConfiguration.setProtocol(Protocol.HTTP);
+
+            clientBuilder
+                    .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(amazonHost, region))
+                    .withClientConfiguration(clientConfiguration)
+                    .withCredentials(new TestAWSCredentialsProvider("accesskey", "secretkey"));
+        } else {
+            clientBuilder
+                    .withRegion(region)
+                    .withCredentials(new TestAWSCredentialsProvider());
+        }
+
+        return clientBuilder.build();
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/common/TestAWSCredentialsProvider.java b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/common/TestAWSCredentialsProvider.java
new file mode 100644
index 0000000..dcfba3d
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/common/TestAWSCredentialsProvider.java
@@ -0,0 +1,66 @@
+/*
+ * 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.test.infra.aws.common;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+
+public class TestAWSCredentialsProvider implements AWSCredentialsProvider {
+    private static class TestAWSCredentials implements AWSCredentials {
+        private final String accessKey;
+        private final String secretKey;
+
+        public TestAWSCredentials() {
+            this(System.getProperty(AWSConfigs.ACCESS_KEY), System.getProperty(AWSConfigs.SECRET_KEY));
+        }
+
+        public TestAWSCredentials(String accessKey, String secretKey) {
+            this.accessKey = accessKey;
+            this.secretKey = secretKey;
+        }
+
+        @Override
+        public String getAWSAccessKeyId() {
+            return accessKey;
+        }
+
+        @Override
+        public String getAWSSecretKey() {
+            return secretKey;
+        }
+    };
+
+    private AWSCredentials credentials;
+
+    public TestAWSCredentialsProvider() {
+        credentials = new TestAWSCredentials();
+    }
+
+    public TestAWSCredentialsProvider(String accessKey, String secretKey) {
+        credentials = new TestAWSCredentials(accessKey, secretKey);
+    }
+
+    @Override
+    public AWSCredentials getCredentials() {
+        return credentials;
+    }
+
+    @Override
+    public void refresh() {
+
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSKinesisLocalContainerService.java b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSKinesisLocalContainerService.java
new file mode 100644
index 0000000..ee55c47
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSKinesisLocalContainerService.java
@@ -0,0 +1,56 @@
+/*
+ * 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.test.infra.aws.services;
+
+import com.amazonaws.ClientConfiguration;
+import com.amazonaws.Protocol;
+import com.amazonaws.services.kinesis.AmazonKinesis;
+import com.amazonaws.services.kinesis.AmazonKinesisClientBuilder;
+import org.testcontainers.containers.localstack.LocalStackContainer;
+
+public class AWSKinesisLocalContainerService extends AWSLocalContainerService<AmazonKinesis> {
+
+    public AWSKinesisLocalContainerService() {
+        super(LocalStackContainer.Service.KINESIS);
+    }
+
+    @Override
+    public String getServiceEndpoint() {
+        return super.getServiceEndpoint(LocalStackContainer.Service.KINESIS);
+    }
+
+    @Override
+    public String getAmazonHost() {
+        final int kinesisPort = 4568;
+
+        return getContainer().getContainerIpAddress() + ":" + getContainer().getMappedPort(kinesisPort);
+    }
+
+    @Override
+    public AmazonKinesis getClient() {
+        ClientConfiguration clientConfiguration = new ClientConfiguration();
+        clientConfiguration.setProtocol(Protocol.HTTP);
+
+        return AmazonKinesisClientBuilder
+                .standard()
+                .withEndpointConfiguration(getContainer().getEndpointConfiguration(LocalStackContainer.Service.KINESIS))
+                .withCredentials(getContainer().getDefaultCredentialsProvider())
+                .withClientConfiguration(clientConfiguration)
+                .build();
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSLocalContainerService.java b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSLocalContainerService.java
new file mode 100644
index 0000000..16a08fe
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSLocalContainerService.java
@@ -0,0 +1,101 @@
+/*
+ * 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.test.infra.aws.services;
+
+import java.util.Properties;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.regions.Regions;
+import org.apache.camel.test.infra.aws.common.AWSConfigs;
+import org.apache.camel.test.infra.aws.common.services.AWSService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.localstack.LocalStackContainer;
+
+abstract class AWSLocalContainerService<T> implements AWSService<T> {
+    private static final Logger LOG = LoggerFactory.getLogger(AWSLocalContainerService.class);
+    private final LocalStackContainer container;
+
+    public AWSLocalContainerService(LocalStackContainer.Service... services) {
+        this.container = new LocalStackContainer().withServices(services);
+
+        container.start();
+    }
+
+    protected abstract String getAmazonHost();
+
+    protected abstract String getServiceEndpoint();
+
+    @Override
+    public void initialize() {
+        LOG.info("AWS service running at address {}", getServiceEndpoint());
+    }
+
+    @Override
+    public void shutdown() {
+        LOG.info("Stopping local AWS service");
+        container.stop();
+    }
+
+    private AWSCredentials getCredentials() {
+        return container.getDefaultCredentialsProvider().getCredentials();
+    }
+
+    @Override
+    public Properties getConnectionProperties() {
+        Properties properties = new Properties();
+
+        AWSCredentials credentials = getCredentials();
+
+        properties.put(AWSConfigs.ACCESS_KEY, credentials.getAWSAccessKeyId());
+
+        properties.put(AWSConfigs.SECRET_KEY, credentials.getAWSSecretKey());
+
+        properties.put(AWSConfigs.REGION, Regions.US_EAST_1.name());
+
+        properties.put(AWSConfigs.AMAZON_AWS_HOST, getAmazonHost());
+
+        /**
+         * We need to set this one. For some sets, when they instantiate the clients within Camel, they need to know
+         * what is the Amazon host being used (ie.: when creating them using the withEndpointConfiguration()). Because
+         * this happens within Camel, there's no way to pass that information easily. Therefore, the host is set as a
+         * property and read by whatever class/method creates the clients to pass to Camel.
+         *
+         * Do not unset.
+         */
+        System.setProperty(AWSConfigs.AMAZON_AWS_HOST, getAmazonHost());
+
+        properties.put(AWSConfigs.PROTOCOL, "http");
+
+        return properties;
+    }
+
+    protected LocalStackContainer getContainer() {
+        return container;
+    }
+
+    protected String getAmazonHost(int port) {
+        return container.getContainerIpAddress() + ":" + container.getMappedPort(port);
+    }
+
+    protected String getServiceEndpoint(LocalStackContainer.Service service) {
+        return container
+                .getEndpointConfiguration(service)
+                .getServiceEndpoint();
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSRemoteService.java b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSRemoteService.java
new file mode 100644
index 0000000..db499ec
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSRemoteService.java
@@ -0,0 +1,69 @@
+/*
+ * 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.test.infra.aws.services;
+
+import java.util.Properties;
+import java.util.function.Supplier;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.regions.Regions;
+import org.apache.camel.test.infra.aws.common.AWSConfigs;
+import org.apache.camel.test.infra.aws.common.TestAWSCredentialsProvider;
+import org.apache.camel.test.infra.aws.common.services.AWSService;
+
+public class AWSRemoteService<T> implements AWSService<T> {
+    private static final AWSCredentialsProvider CREDENTIALS_PROVIDER = new TestAWSCredentialsProvider();
+    private Supplier<T> remoteClientSupplier;
+
+    public AWSRemoteService(Supplier<T> remoteClientSupplier) {
+        this.remoteClientSupplier = remoteClientSupplier;
+    }
+
+    @Override
+    public T getClient() {
+        return remoteClientSupplier.get();
+    }
+
+    private AWSCredentials getCredentials() {
+        return CREDENTIALS_PROVIDER.getCredentials();
+    }
+
+    @Override
+    public Properties getConnectionProperties() {
+        Properties properties = new Properties();
+
+        AWSCredentials credentials = getCredentials();
+
+        properties.put(AWSConfigs.ACCESS_KEY, credentials.getAWSAccessKeyId());
+        properties.put(AWSConfigs.SECRET_KEY, credentials.getAWSSecretKey());
+        properties.put(AWSConfigs.REGION, Regions.US_EAST_1.name());
+
+        return properties;
+    }
+
+    @Override
+    public void initialize() {
+
+    }
+
+    @Override
+    public void shutdown() {
+
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSS3LocalContainerService.java b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSS3LocalContainerService.java
new file mode 100644
index 0000000..f58def9
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSS3LocalContainerService.java
@@ -0,0 +1,56 @@
+/*
+ * 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.test.infra.aws.services;
+
+import com.amazonaws.ClientConfiguration;
+import com.amazonaws.Protocol;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3ClientBuilder;
+import org.testcontainers.containers.localstack.LocalStackContainer;
+
+public class AWSS3LocalContainerService extends AWSLocalContainerService<AmazonS3> {
+
+    public AWSS3LocalContainerService() {
+        super(LocalStackContainer.Service.S3);
+    }
+
+    @Override
+    public String getServiceEndpoint() {
+        return super.getServiceEndpoint(LocalStackContainer.Service.S3);
+    }
+
+    @Override
+    public String getAmazonHost() {
+        final int s3Port = 4572;
+
+        return getContainer().getContainerIpAddress() + ":" + getContainer().getMappedPort(s3Port);
+    }
+
+    @Override
+    public AmazonS3 getClient() {
+        ClientConfiguration clientConfiguration = new ClientConfiguration();
+        clientConfiguration.setProtocol(Protocol.HTTP);
+
+        return AmazonS3ClientBuilder
+                .standard()
+                .withEndpointConfiguration(getContainer().getEndpointConfiguration(LocalStackContainer.Service.S3))
+                .withCredentials(getContainer().getDefaultCredentialsProvider())
+                .withClientConfiguration(clientConfiguration)
+                .build();
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSSNSLocalContainerService.java b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSSNSLocalContainerService.java
new file mode 100644
index 0000000..d0764dd
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSSNSLocalContainerService.java
@@ -0,0 +1,52 @@
+/*
+ * 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.test.infra.aws.services;
+
+import com.amazonaws.services.sqs.AmazonSQS;
+import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
+import org.testcontainers.containers.localstack.LocalStackContainer;
+
+public class AWSSNSLocalContainerService extends AWSLocalContainerService<AmazonSQS> {
+
+    public AWSSNSLocalContainerService() {
+        super(LocalStackContainer.Service.SQS,
+              LocalStackContainer.Service.SNS);
+    }
+
+    @Override
+    public String getServiceEndpoint() {
+        return super.getServiceEndpoint(LocalStackContainer.Service.SNS);
+    }
+
+    @Override
+    public String getAmazonHost() {
+        final int snsPort = 4575;
+
+        return super.getAmazonHost(snsPort);
+    }
+
+    @Override
+    public AmazonSQS getClient() {
+        return AmazonSQSClientBuilder
+                .standard()
+                .withEndpointConfiguration(getContainer()
+                        .getEndpointConfiguration(LocalStackContainer.Service.SQS))
+                .withCredentials(getContainer().getDefaultCredentialsProvider())
+                .build();
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSSQSLocalContainerService.java b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSSQSLocalContainerService.java
new file mode 100644
index 0000000..b506d09
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSSQSLocalContainerService.java
@@ -0,0 +1,51 @@
+/*
+ * 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.test.infra.aws.services;
+
+import com.amazonaws.services.sqs.AmazonSQS;
+import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
+import org.testcontainers.containers.localstack.LocalStackContainer;
+
+public class AWSSQSLocalContainerService extends AWSLocalContainerService<AmazonSQS> {
+
+    public AWSSQSLocalContainerService() {
+        super(LocalStackContainer.Service.SQS);
+    }
+
+    @Override
+    public String getServiceEndpoint() {
+        return super.getServiceEndpoint(LocalStackContainer.Service.SQS);
+    }
+
+    @Override
+    public String getAmazonHost() {
+        final int sqsPort = 4576;
+
+        return super.getAmazonHost(sqsPort);
+    }
+
+    @Override
+    public AmazonSQS getClient() {
+        return AmazonSQSClientBuilder
+                .standard()
+                .withEndpointConfiguration(getContainer()
+                        .getEndpointConfiguration(LocalStackContainer.Service.SQS))
+                .withCredentials(getContainer().getDefaultCredentialsProvider())
+                .build();
+    }
+}
diff --git a/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSServiceFactory.java b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSServiceFactory.java
new file mode 100644
index 0000000..050a658
--- /dev/null
+++ b/test-infra/camel-test-infra-aws-v1/src/test/java/org/apache/camel/test/infra/aws/services/AWSServiceFactory.java
@@ -0,0 +1,106 @@
+/*
+ * 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.test.infra.aws.services;
+
+import com.amazonaws.services.kinesis.AmazonKinesis;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.sqs.AmazonSQS;
+import org.apache.camel.test.infra.aws.clients.AWSClientUtils;
+import org.apache.camel.test.infra.aws.common.services.AWSService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class AWSServiceFactory {
+    private static final Logger LOG = LoggerFactory.getLogger(AWSServiceFactory.class);
+
+    private AWSServiceFactory() {
+    }
+
+    private static String getInstanceTypeName(String awsInstanceType) {
+        return awsInstanceType == null ? "default" : awsInstanceType;
+    }
+
+    public static AWSService<AmazonSQS> createSQSService() {
+        String awsInstanceType = System.getProperty("aws-service.instance.type");
+        LOG.info("Creating a {} AWS SQS instance", getInstanceTypeName(awsInstanceType));
+
+        if (awsInstanceType == null || awsInstanceType.equals("local-aws-container")) {
+            return new AWSSQSLocalContainerService();
+        }
+
+        if (awsInstanceType.equals("remote")) {
+            return new AWSRemoteService<>(AWSClientUtils::newSQSClient);
+        }
+
+        LOG.error("Invalid AWS instance type: {}. Must be either 'remote' or 'local-aws-container'",
+                getInstanceTypeName(awsInstanceType));
+        throw new UnsupportedOperationException("Invalid AWS instance type");
+    }
+
+    public static AWSService<AmazonSQS> createSNSService() {
+        String awsInstanceType = System.getProperty("aws-service.instance.type");
+        LOG.info("Creating a {} AWS SNS instance", getInstanceTypeName(awsInstanceType));
+
+        if (awsInstanceType == null || awsInstanceType.equals("local-aws-container")) {
+            return new AWSSNSLocalContainerService();
+        }
+
+        if (awsInstanceType.equals("remote")) {
+            return new AWSRemoteService<>(AWSClientUtils::newSQSClient);
+        }
+
+        LOG.error("Invalid AWS instance type: {}. Must be either 'remote' or 'local-aws-container'",
+                awsInstanceType);
+        throw new UnsupportedOperationException("Invalid AWS instance type");
+
+    }
+
+    public static AWSService<AmazonKinesis> createKinesisService() {
+        String awsInstanceType = System.getProperty("aws-service.kinesis.instance.type");
+        LOG.info("Creating a {} AWS kinesis instance", getInstanceTypeName(awsInstanceType));
+
+        if (awsInstanceType == null || awsInstanceType.equals("local-aws-container")) {
+            return new AWSKinesisLocalContainerService();
+        }
+
+        if (awsInstanceType.equals("remote")) {
+            return new AWSRemoteService<>(AWSClientUtils::newKinesisClient);
+        }
+
+        LOG.error("Invalid AWS instance type: {}. Must be either 'remote' or 'local-aws-container'",
+                awsInstanceType);
+        throw new UnsupportedOperationException("Invalid AWS instance type");
+    }
+
+    public static AWSService<AmazonS3> createS3Service() {
+        String awsInstanceType = System.getProperty("aws-service.instance.type");
+        LOG.info("Creating a {} AWS S3 instance", awsInstanceType);
+
+        if (awsInstanceType == null || awsInstanceType.equals("local-aws-container")) {
+            return new AWSS3LocalContainerService();
+        }
+
+        if (awsInstanceType.equals("remote")) {
+            return new AWSRemoteService<>(AWSClientUtils::newS3Client);
+        }
+
+        LOG.error("Invalid AWS instance type: {}. Must be either 'remote' or 'local-aws-container'",
+                awsInstanceType);
+        throw new UnsupportedOperationException("Invalid AWS instance type");
+    }
+}
diff --git a/test-infra/pom.xml b/test-infra/pom.xml
index d5f2079..f4c8034 100644
--- a/test-infra/pom.xml
+++ b/test-infra/pom.xml
@@ -37,5 +37,7 @@
         <module>camel-test-infra-common</module>
         <module>camel-test-infra-kafka</module>
         <module>camel-test-infra-parent</module>
+        <module>camel-test-infra-aws-v1</module>
+        <module>camel-test-infra-aws-common</module>
     </modules>
 </project>
\ No newline at end of file