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 f83ceecb716f2d1cb29a877c5cdaad7ebbefa775 Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Tue Nov 19 12:55:38 2019 +0100 CAMEL-14106 - Camel-AWS: S3 Range Get --- .../apache/camel/component/aws/s3/S3Constants.java | 2 + .../camel/component/aws/s3/S3Operations.java | 3 +- .../apache/camel/component/aws/s3/S3Producer.java | 20 ++++ .../aws/s3/S3ComponentGetObjectRangeTest.java | 71 ++++++++++++++ .../S3ObjectRangeOperationIntegrationTest.java | 106 +++++++++++++++++++++ .../endpoint/dsl/S3EndpointBuilderFactory.java | 3 +- 6 files changed, 203 insertions(+), 2 deletions(-) diff --git a/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Constants.java b/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Constants.java index 84b6169..88215b6 100644 --- a/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Constants.java +++ b/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Constants.java @@ -45,4 +45,6 @@ public interface S3Constants { String SERVER_SIDE_ENCRYPTION = "CamelAwsS3ServerSideEncryption"; String EXPIRATION_TIME = "CamelAwsS3ExpirationTime"; String REPLICATION_STATUS = "CamelAwsS3ReplicationStatus"; + String RANGE_START = "CamelAwsS3RangeStart"; + String RANGE_END = "CamelAwsS3RangeEnd"; } \ No newline at end of file diff --git a/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Operations.java b/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Operations.java index 90fb17c..2bf5c96 100644 --- a/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Operations.java +++ b/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Operations.java @@ -24,5 +24,6 @@ public enum S3Operations { deleteBucket, listBuckets, downloadLink, - getObject + getObject, + getObjectRange } diff --git a/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Producer.java b/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Producer.java index e5fc068..edd9089 100644 --- a/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Producer.java +++ b/components/camel-aws-s3/src/main/java/org/apache/camel/component/aws/s3/S3Producer.java @@ -112,6 +112,9 @@ public class S3Producer extends DefaultProducer { case getObject: getObject(getEndpoint().getS3Client(), exchange); break; + case getObjectRange: + getObjectRange(getEndpoint().getS3Client(), exchange); + break; default: throw new IllegalArgumentException("Unsupported operation"); } @@ -369,6 +372,23 @@ public class S3Producer extends DefaultProducer { Message message = getMessageForResponse(exchange); message.setBody(res); } + + private void getObjectRange(AmazonS3 s3Client, Exchange exchange) { + final String bucketName = determineBucketName(exchange); + final String sourceKey = determineKey(exchange); + final String rangeStart = exchange.getIn().getHeader(S3Constants.RANGE_START, String.class); + final String rangeEnd = exchange.getIn().getHeader(S3Constants.RANGE_END, String.class); + + if (ObjectHelper.isEmpty(rangeStart) || ObjectHelper.isEmpty(rangeEnd)) { + throw new IllegalArgumentException("A Range start and range end header must be configured to perform a range get operation."); + } + + GetObjectRequest req = new GetObjectRequest(bucketName, sourceKey).withRange(Long.parseLong(rangeStart), Long.parseLong(rangeEnd)); + S3Object res = s3Client.getObject(req); + + Message message = getMessageForResponse(exchange); + message.setBody(res); + } private void listObjects(AmazonS3 s3Client, Exchange exchange) { final String bucketName = determineBucketName(exchange); diff --git a/components/camel-aws-s3/src/test/java/org/apache/camel/component/aws/s3/S3ComponentGetObjectRangeTest.java b/components/camel-aws-s3/src/test/java/org/apache/camel/component/aws/s3/S3ComponentGetObjectRangeTest.java new file mode 100644 index 0000000..8f59852 --- /dev/null +++ b/components/camel-aws-s3/src/test/java/org/apache/camel/component/aws/s3/S3ComponentGetObjectRangeTest.java @@ -0,0 +1,71 @@ +/* + * 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.BindToRegistry; +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.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +import com.amazonaws.services.s3.AmazonS3; + +public class S3ComponentGetObjectRangeTest extends CamelTestSupport { + + @BindToRegistry("amazonS3Client") + AmazonS3 clientMock = new AmazonS3ClientMock(); + + @EndpointInject + private ProducerTemplate template; + + @EndpointInject("mock:result") + private MockEndpoint result; + + @Test + public void sendIn() throws Exception { + result.expectedMessageCount(1); + + template.send("direct:getObjectRange", new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(S3Constants.KEY, "pippo.txt"); + exchange.getIn().setHeader(S3Constants.RANGE_START, 0); + exchange.getIn().setHeader(S3Constants.RANGE_END, 9); + } + }); + assertMockEndpointsSatisfied(); + + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + String awsEndpoint = "aws-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectRange"; + + from("direct:getObjectRange").to(awsEndpoint).to("mock:result"); + + } + }; + } +} diff --git a/components/camel-aws-s3/src/test/java/org/apache/camel/component/aws/s3/integration/S3ObjectRangeOperationIntegrationTest.java b/components/camel-aws-s3/src/test/java/org/apache/camel/component/aws/s3/integration/S3ObjectRangeOperationIntegrationTest.java new file mode 100644 index 0000000..8a0e1c8 --- /dev/null +++ b/components/camel-aws-s3/src/test/java/org/apache/camel/component/aws/s3/integration/S3ObjectRangeOperationIntegrationTest.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.component.aws.s3.integration; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.apache.camel.BindToRegistry; +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.aws.s3.S3Constants; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.s3.model.S3Object; + +@Ignore("Must be manually tested. Provide your own accessKey and secretKey!") +public class S3ObjectRangeOperationIntegrationTest extends CamelTestSupport { + + @BindToRegistry("amazonS3Client") + AmazonS3 client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("xxx", "yyy"))).withRegion(Regions.US_WEST_1).build(); + + @EndpointInject + private ProducerTemplate template; + + @EndpointInject("mock:result") + private MockEndpoint result; + + private static final Logger LOG = LoggerFactory.getLogger(S3ObjectRangeOperationIntegrationTest.class); + + + @Test + public void sendIn() throws Exception { + result.expectedMessageCount(1); + + template.send("direct:getObjectRange", new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(S3Constants.KEY, "pippo.txt"); + exchange.getIn().setHeader(S3Constants.RANGE_START, 0); + exchange.getIn().setHeader(S3Constants.RANGE_END, 9); + } + }); + assertMockEndpointsSatisfied(); + + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + String awsEndpoint = "aws-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectRange"; + + from("direct:getObjectRange").to(awsEndpoint).process(new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + S3Object s3 = exchange.getIn().getBody(S3Object.class); + displayTextInputStream(s3.getObjectContent()); + + } + }).to("mock:result"); + + } + }; + } + + private static void displayTextInputStream(InputStream input) throws IOException { + // Read the text input stream one line at a time and display each line. + BufferedReader reader = new BufferedReader(new InputStreamReader(input)); + String line = null; + while ((line = reader.readLine()) != null) { + LOG.info(line); + } + } +} diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/S3EndpointBuilderFactory.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/S3EndpointBuilderFactory.java index c3f46d2..a706e4f 100644 --- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/S3EndpointBuilderFactory.java +++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/S3EndpointBuilderFactory.java @@ -2302,7 +2302,8 @@ public interface S3EndpointBuilderFactory { deleteBucket, listBuckets, downloadLink, - getObject; + getObject, + getObjectRange; } /** * AWS S3 Storage Service (camel-aws-s3)