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
commit af6466db68e827dad016a1e34e1aaae937c6f6de Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Thu Sep 10 18:15:20 2020 +0200 Camel-AWS2-S3: Adding tests with localstack and test containers --- .../aws2/s3/localstack/Aws2S3BaseTest.java | 17 ++- .../S3CopyObjectCustomerKeyLocalstackTest.java | 167 +++++++++++++++++++++ .../S3DeleteBucketOperationLocalstackTest.java | 75 +++++++++ 3 files changed, 253 insertions(+), 6 deletions(-) diff --git a/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/Aws2S3BaseTest.java b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/Aws2S3BaseTest.java index 555f4f0..02ea4ff 100644 --- a/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/Aws2S3BaseTest.java +++ b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/Aws2S3BaseTest.java @@ -27,7 +27,8 @@ public class Aws2S3BaseTest extends ContainerAwareTestSupport { .withNetworkAliases(CONTAINER_NAME) .withEnv("SERVICES", "s3") .withExposedPorts(4572) - .waitingFor(Wait.forListeningPort()); + .waitingFor(Wait.forListeningPort()) + .waitingFor(Wait.forLogMessageContaining("Ready.", 1)); } public String getS3Url() { @@ -37,16 +38,20 @@ public class Aws2S3BaseTest extends ContainerAwareTestSupport { getContainerPort(CONTAINER_NAME, 4572)); } - @Override - protected CamelContext createCamelContext() throws Exception { - CamelContext context = super.createCamelContext(); - AWS2S3Component s3 = context.getComponent("aws2-s3", AWS2S3Component.class); + public S3Client getS3Client() { S3Client s3Client = S3Client .builder() .endpointOverride(URI.create("http://" + getS3Url())) .region(Region.EU_WEST_1) .build(); - s3.getConfiguration().setAmazonS3Client(s3Client); + return s3Client; + } + + @Override + protected CamelContext createCamelContext() throws Exception { + CamelContext context = super.createCamelContext(); + AWS2S3Component s3 = context.getComponent("aws2-s3", AWS2S3Component.class); + s3.getConfiguration().setAmazonS3Client(getS3Client()); return context; } } diff --git a/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/S3CopyObjectCustomerKeyLocalstackTest.java b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/S3CopyObjectCustomerKeyLocalstackTest.java new file mode 100644 index 0000000..18f8595 --- /dev/null +++ b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/S3CopyObjectCustomerKeyLocalstackTest.java @@ -0,0 +1,167 @@ +/* + * 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.aws2.s3.localstack; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.util.Base64; +import java.util.List; +import java.util.UUID; + +import javax.crypto.KeyGenerator; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.s3.AWS2S3Constants; +import org.apache.camel.component.aws2.s3.AWS2S3Operations; +import org.apache.camel.component.mock.MockEndpoint; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.core.ResponseInputStream; +import software.amazon.awssdk.services.s3.model.GetObjectRequest; +import software.amazon.awssdk.services.s3.model.GetObjectResponse; +import software.amazon.awssdk.utils.Md5Utils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static software.amazon.awssdk.services.s3.model.ServerSideEncryption.AES256; + +public class S3CopyObjectCustomerKeyLocalstackTest extends Aws2S3BaseTest { + + String key = UUID.randomUUID().toString(); + byte[] secretKey = generateSecretKey(); + String b64Key = Base64.getEncoder().encodeToString(secretKey); + String b64KeyMd5 = Md5Utils.md5AsBase64(secretKey); + + @EndpointInject + private ProducerTemplate template; + + @EndpointInject("mock:result") + private MockEndpoint result; + + @Test + public void sendIn() throws Exception { + result.expectedMessageCount(1); + + template.send("direct:putObject", new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(AWS2S3Constants.KEY, "test.txt"); + exchange.getIn().setBody("Test"); + } + }); + + template.send("direct:copyObject", new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(AWS2S3Constants.KEY, "test.txt"); + exchange.getIn().setHeader(AWS2S3Constants.DESTINATION_KEY, "test1.txt"); + exchange.getIn().setHeader(AWS2S3Constants.BUCKET_DESTINATION_NAME, "mycamel1"); + exchange.getIn().setHeader(AWS2S3Constants.S3_OPERATION, AWS2S3Operations.copyObject); + } + }); + + Exchange res = template.request("direct:getObject", new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + GetObjectRequest getObjectRequest = GetObjectRequest.builder() + .key("test1.txt") + .bucket("mycamel1") + .sseCustomerKey(b64Key) + .sseCustomerAlgorithm(AES256.name()) + .sseCustomerKeyMD5(b64KeyMd5) + .build(); + exchange.getIn().setHeader(AWS2S3Constants.S3_OPERATION, AWS2S3Operations.getObject); + exchange.getIn().setBody(getObjectRequest); + } + }); + + ResponseInputStream<GetObjectResponse> s3 = res.getIn().getBody(ResponseInputStream.class); + + assertEquals("Test", readInputStream(s3)); + + Exchange res1 = template.request("direct:listObject", new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(AWS2S3Constants.S3_OPERATION, AWS2S3Operations.listObjects); + } + }); + + List response = res1.getIn().getBody(List.class); + + assertEquals(1, response.size()); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + String awsEndpoint = "aws2-s3://mycamel?autoCreateBucket=true&useCustomerKey=true&customerKeyId=RAW(" + b64Key + + ")&customerKeyMD5=RAW(" + b64KeyMd5 + ")&customerAlgorithm=" + AES256.name(); + String awsEndpoint1 = "aws2-s3://mycamel1?autoCreateBucket=true&pojoRequest=true"; + String awsEndpoint2 = "aws2-s3://mycamel1?autoCreateBucket=true"; + from("direct:putObject").setHeader(AWS2S3Constants.KEY, constant("test.txt")).setBody(constant("Test")) + .to(awsEndpoint); + + from("direct:copyObject").to(awsEndpoint); + + from("direct:listObject").to(awsEndpoint2); + + from("direct:getObject").to(awsEndpoint1).to("mock:result"); + + } + }; + } + + protected static byte[] generateSecretKey() { + KeyGenerator generator; + try { + generator = KeyGenerator.getInstance("AES"); + generator.init(256, new SecureRandom()); + return generator.generateKey().getEncoded(); + } catch (Exception e) { + fail("Unable to generate symmetric key: " + e.getMessage()); + return null; + } + } + + private String readInputStream(ResponseInputStream<GetObjectResponse> s3Object) throws IOException { + StringBuilder textBuilder = new StringBuilder(); + try (Reader reader + = new BufferedReader(new InputStreamReader(s3Object, Charset.forName(StandardCharsets.UTF_8.name())))) { + int c = 0; + while ((c = reader.read()) != -1) { + textBuilder.append((char) c); + } + } + return textBuilder.toString(); + } +} diff --git a/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/S3DeleteBucketOperationLocalstackTest.java b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/S3DeleteBucketOperationLocalstackTest.java new file mode 100644 index 0000000..6b9aae7 --- /dev/null +++ b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/localstack/S3DeleteBucketOperationLocalstackTest.java @@ -0,0 +1,75 @@ +/* + * 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.aws2.s3.localstack; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.s3.AWS2S3Constants; +import org.apache.camel.component.aws2.s3.AWS2S3Operations; +import org.apache.camel.component.mock.MockEndpoint; +import org.junit.jupiter.api.Test; + +public class S3DeleteBucketOperationLocalstackTest extends Aws2S3BaseTest { + + @EndpointInject + private ProducerTemplate template; + + @EndpointInject("mock:result") + private MockEndpoint result; + + @Test + public void sendIn() throws Exception { + result.expectedMessageCount(1); + + template.send("direct:listBucket", new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(AWS2S3Constants.S3_OPERATION, AWS2S3Operations.listBuckets); + } + }); + + template.send("direct:deleteBucket", new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(AWS2S3Constants.BUCKET_NAME, "mycamel2"); + exchange.getIn().setHeader(AWS2S3Constants.S3_OPERATION, AWS2S3Operations.deleteBucket); + } + }); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + String awsEndpoint = "aws2-s3://mycamel2?autoCreateBucket=true"; + + from("direct:listBucket").to(awsEndpoint); + + from("direct:deleteBucket").to(awsEndpoint).to("mock:result"); + + } + }; + } +}