From c6013240abbef11085d901a95051d58da0ad91ab Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Wed, 10 Jul 2019 10:26:16 -0400 Subject: [PATCH] Start version 2.3 --- build.gradle | 4 +- gradle.properties | 2 +- .../aws/config/xml/AwsNamespaceHandler.java | 5 +- .../aws/config/xml/AwsParserUtils.java | 9 +- .../xml/S3OutboundChannelAdapterParser.java | 3 +- .../config/xml/S3OutboundGatewayParser.java | 30 +- ...3StreamingInboundChannelAdapterParser.java | 1 - .../xml/SnsInboundChannelAdapterParser.java | 7 +- .../xml/SnsOutboundChannelAdapterParser.java | 9 +- .../SqsMessageDrivenChannelAdapterParser.java | 3 +- .../inbound/S3InboundFileSynchronizer.java | 3 +- ...InboundFileSynchronizingMessageSource.java | 4 +- .../aws/inbound/S3StreamingMessageSource.java | 5 +- .../aws/inbound/SnsInboundChannelAdapter.java | 45 +- .../SqsMessageDrivenChannelAdapter.java | 22 +- .../aws/inbound/kinesis/CheckpointMode.java | 4 +- .../aws/inbound/kinesis/Checkpointer.java | 1 - .../KclMessageDrivenChannelAdapter.java | 90 ++-- .../KinesisMessageDrivenChannelAdapter.java | 430 ++++++++---------- ...esisMessageHeaderErrorMessageStrategy.java | 17 +- .../inbound/kinesis/KinesisShardOffset.java | 23 +- .../aws/inbound/kinesis/ListenerMode.java | 4 +- .../inbound/kinesis/ShardCheckpointer.java | 19 +- .../aws/lock/DynamoDbLockRegistry.java | 125 +++-- .../aws/metadata/DynamoDbMetadataStore.java | 137 +++--- .../outbound/AbstractAwsMessageHandler.java | 29 +- .../aws/outbound/KinesisMessageHandler.java | 70 ++- .../aws/outbound/KplMessageHandler.java | 71 ++- .../aws/outbound/S3MessageHandler.java | 179 ++++---- .../aws/outbound/SnsMessageHandler.java | 55 +-- .../aws/outbound/SqsMessageHandler.java | 30 +- ...AbstractMessageAttributesHeaderMapper.java | 44 +- .../integration/aws/support/AwsHeaders.java | 3 +- .../support/AwsRequestFailureException.java | 1 - .../integration/aws/support/S3FileInfo.java | 16 +- .../integration/aws/support/S3Session.java | 28 +- .../aws/support/S3SessionFactory.java | 6 +- .../aws/support/SnsBodyBuilder.java | 14 +- .../aws/support/SnsHeaderMapper.java | 12 +- .../aws/support/SqsHeaderMapper.java | 13 +- .../S3PersistentAcceptOnceFileListFilter.java | 5 +- .../integration/aws/DynamoDbLocalRunning.java | 11 +- .../integration/aws/KinesisLocalRunning.java | 11 +- .../S3InboundChannelAdapterParserTests.java | 9 +- .../xml/S3MessageHandlerParserTests.java | 29 +- ...amingInboundChannelAdapterParserTests.java | 6 +- .../SnsInboundChannelAdapterParserTests.java | 7 +- .../SnsOutboundChannelAdapterParserTests.java | 12 +- ...essageDrivenChannelAdapterParserTests.java | 15 +- .../xml/SqsMessageHandlerParserTests.java | 24 +- ...nesisMessageDrivenChannelAdapterTests.java | 158 +++---- .../inbound/S3InboundChannelAdapterTests.java | 8 +- .../S3StreamingChannelAdapterTests.java | 5 +- .../SnsInboundChannelAdapterTests.java | 21 +- .../SqsMessageDrivenChannelAdapterTests.java | 34 +- .../aws/kinesis/KinesisIntegrationTests.java | 30 +- ...amoDbLockRegistryLeaderInitiatorTests.java | 22 +- .../aws/lock/DynamoDbLockRegistryTests.java | 31 +- .../metadata/DynamoDbMetadataStoreTests.java | 17 +- .../outbound/KinesisMessageHandlerTests.java | 34 +- .../KinesisProducingMessageHandlerTests.java | 74 ++- .../aws/outbound/S3MessageHandlerTests.java | 49 +- .../aws/outbound/SnsMessageBuilderTests.java | 12 +- .../aws/outbound/SnsMessageHandlerTests.java | 14 +- .../aws/outbound/SqsMessageHandlerTests.java | 53 +-- 65 files changed, 937 insertions(+), 1327 deletions(-) diff --git a/build.gradle b/build.gradle index 752b851..a0ce9d2 100644 --- a/build.gradle +++ b/build.gradle @@ -37,8 +37,8 @@ ext { jacksonVersion = '2.9.9' servletApiVersion = '4.0.1' log4jVersion = '2.11.2' - springCloudAwsVersion = '2.1.1.RELEASE' - springIntegrationVersion = '5.1.6.RELEASE' + springCloudAwsVersion = '2.2.0.BUILD-SNAPSHOT' + springIntegrationVersion = '5.2.0.BUILD-SNAPSHOT' kinesisClientVersion = '1.10.0' kinesisProducerVersion = '0.12.11' diff --git a/gradle.properties b/gradle.properties index d5bd510..2368c30 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=2.2.1.BUILD-SNAPSHOT +version=2.3.0.BUILD-SNAPSHOT diff --git a/src/main/java/org/springframework/integration/aws/config/xml/AwsNamespaceHandler.java b/src/main/java/org/springframework/integration/aws/config/xml/AwsNamespaceHandler.java index 913c31f..f3a77a0 100644 --- a/src/main/java/org/springframework/integration/aws/config/xml/AwsNamespaceHandler.java +++ b/src/main/java/org/springframework/integration/aws/config/xml/AwsNamespaceHandler.java @@ -23,17 +23,16 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa * * @author Amol Nayak * @author Artem Bilan - * * @since 0.5 */ public class AwsNamespaceHandler extends AbstractIntegrationNamespaceHandler { - public void init() { registerBeanDefinitionParser("s3-outbound-channel-adapter", new S3OutboundChannelAdapterParser()); registerBeanDefinitionParser("s3-outbound-gateway", new S3OutboundGatewayParser()); registerBeanDefinitionParser("s3-inbound-channel-adapter", new S3InboundChannelAdapterParser()); - registerBeanDefinitionParser("s3-inbound-streaming-channel-adapter", new S3StreamingInboundChannelAdapterParser()); + registerBeanDefinitionParser("s3-inbound-streaming-channel-adapter", + new S3StreamingInboundChannelAdapterParser()); registerBeanDefinitionParser("sqs-outbound-channel-adapter", new SqsOutboundChannelAdapterParser()); registerBeanDefinitionParser("sqs-message-driven-channel-adapter", new SqsMessageDrivenChannelAdapterParser()); registerBeanDefinitionParser("sns-inbound-channel-adapter", new SnsInboundChannelAdapterParser()); diff --git a/src/main/java/org/springframework/integration/aws/config/xml/AwsParserUtils.java b/src/main/java/org/springframework/integration/aws/config/xml/AwsParserUtils.java index 282ce8d..92e33ee 100644 --- a/src/main/java/org/springframework/integration/aws/config/xml/AwsParserUtils.java +++ b/src/main/java/org/springframework/integration/aws/config/xml/AwsParserUtils.java @@ -58,12 +58,11 @@ public final class AwsParserUtils { super(); } - static void populateExpressionAttribute(String attributeName, BeanDefinitionBuilder builder, - Element element, ParserContext parserContext) { + static void populateExpressionAttribute(String attributeName, BeanDefinitionBuilder builder, Element element, + ParserContext parserContext) { - BeanDefinition beanDefinition = - IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression(attributeName, - attributeName + "-expression", parserContext, element, false); + BeanDefinition beanDefinition = IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression( + attributeName, attributeName + "-expression", parserContext, element, false); if (beanDefinition != null) { builder.addPropertyValue(Conventions.attributeNameToPropertyName(attributeName) + "Expression", beanDefinition); diff --git a/src/main/java/org/springframework/integration/aws/config/xml/S3OutboundChannelAdapterParser.java b/src/main/java/org/springframework/integration/aws/config/xml/S3OutboundChannelAdapterParser.java index 7af2d63..92e384c 100644 --- a/src/main/java/org/springframework/integration/aws/config/xml/S3OutboundChannelAdapterParser.java +++ b/src/main/java/org/springframework/integration/aws/config/xml/S3OutboundChannelAdapterParser.java @@ -31,8 +31,7 @@ public class S3OutboundChannelAdapterParser extends AbstractOutboundChannelAdapt @Override protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) { - AbstractBeanDefinition beanDefinition = new S3OutboundGatewayParser() - .parseHandler(element, parserContext) + AbstractBeanDefinition beanDefinition = new S3OutboundGatewayParser().parseHandler(element, parserContext) .getBeanDefinition(); beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(2, false); return beanDefinition; diff --git a/src/main/java/org/springframework/integration/aws/config/xml/S3OutboundGatewayParser.java b/src/main/java/org/springframework/integration/aws/config/xml/S3OutboundGatewayParser.java index cd334d7..be43716 100644 --- a/src/main/java/org/springframework/integration/aws/config/xml/S3OutboundGatewayParser.java +++ b/src/main/java/org/springframework/integration/aws/config/xml/S3OutboundGatewayParser.java @@ -50,18 +50,15 @@ public class S3OutboundGatewayParser extends AbstractConsumerEndpointParser { .error("One and only of 's3' and 'transfer-manager' attributes must be provided", element); } - BeanDefinition bucketExpression = - IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression("bucket", "bucket-expression", - parserContext, element, true); + BeanDefinition bucketExpression = IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression( + "bucket", "bucket-expression", parserContext, element, true); BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(S3MessageHandler.class) - .addConstructorArgReference(hasS3 ? s3 : transferManager) - .addConstructorArgValue(bucketExpression) + .addConstructorArgReference(hasS3 ? s3 : transferManager).addConstructorArgValue(bucketExpression) .addConstructorArgValue(true); - BeanDefinition commandExpression = - IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression("command", - "command-expression", parserContext, element, false); + BeanDefinition commandExpression = IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression( + "command", "command-expression", parserContext, element, false); if (commandExpression != null) { builder.addPropertyValue("commandExpression", commandExpression); @@ -70,27 +67,26 @@ public class S3OutboundGatewayParser extends AbstractConsumerEndpointParser { IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "progress-listener"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "upload-metadata-provider"); - BeanDefinition keyExpression = - IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined("key-expression", element); + BeanDefinition keyExpression = IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined("key-expression", + element); if (keyExpression != null) { builder.addPropertyValue("keyExpression", keyExpression); } - BeanDefinition objectAclExpression = - IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined("object-acl-expression", element); + BeanDefinition objectAclExpression = IntegrationNamespaceUtils + .createExpressionDefIfAttributeDefined("object-acl-expression", element); if (objectAclExpression != null) { builder.addPropertyValue("objectAclExpression", objectAclExpression); } - BeanDefinition destinationBucketExpression = - IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined("destination-bucket-expression", - element); + BeanDefinition destinationBucketExpression = IntegrationNamespaceUtils + .createExpressionDefIfAttributeDefined("destination-bucket-expression", element); if (destinationBucketExpression != null) { builder.addPropertyValue("destinationBucketExpression", destinationBucketExpression); } - BeanDefinition destinationKeyExpression = - IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined("destination-key-expression", element); + BeanDefinition destinationKeyExpression = IntegrationNamespaceUtils + .createExpressionDefIfAttributeDefined("destination-key-expression", element); if (destinationKeyExpression != null) { builder.addPropertyValue("destinationKeyExpression", destinationKeyExpression); } diff --git a/src/main/java/org/springframework/integration/aws/config/xml/S3StreamingInboundChannelAdapterParser.java b/src/main/java/org/springframework/integration/aws/config/xml/S3StreamingInboundChannelAdapterParser.java index a749d2c..27c761e 100644 --- a/src/main/java/org/springframework/integration/aws/config/xml/S3StreamingInboundChannelAdapterParser.java +++ b/src/main/java/org/springframework/integration/aws/config/xml/S3StreamingInboundChannelAdapterParser.java @@ -32,7 +32,6 @@ import org.springframework.integration.file.remote.RemoteFileOperations; * * @author Christian Tzolov * @author Artem Bilan - * * @since 1.1 */ public class S3StreamingInboundChannelAdapterParser extends AbstractRemoteFileStreamingInboundChannelAdapterParser { diff --git a/src/main/java/org/springframework/integration/aws/config/xml/SnsInboundChannelAdapterParser.java b/src/main/java/org/springframework/integration/aws/config/xml/SnsInboundChannelAdapterParser.java index 7316145..15a8533 100644 --- a/src/main/java/org/springframework/integration/aws/config/xml/SnsInboundChannelAdapterParser.java +++ b/src/main/java/org/springframework/integration/aws/config/xml/SnsInboundChannelAdapterParser.java @@ -47,7 +47,8 @@ public class SnsInboundChannelAdapterParser extends AbstractSingleBeanDefinition String id = super.resolveId(element, definition, parserContext); if (!element.hasAttribute("channel")) { - // the created channel will get the 'id', so the adapter's bean name includes a suffix + // the created channel will get the 'id', so the adapter's bean name includes + // a suffix id = id + ".adapter"; } if (!StringUtils.hasText(id)) { @@ -71,8 +72,8 @@ public class SnsInboundChannelAdapterParser extends AbstractSingleBeanDefinition IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "send-timeout", "requestTimeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.AUTO_STARTUP); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.PHASE); - BeanDefinition payloadExpressionDef = - IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined("payload-expression", element); + BeanDefinition payloadExpressionDef = IntegrationNamespaceUtils + .createExpressionDefIfAttributeDefined("payload-expression", element); if (payloadExpressionDef != null) { builder.addPropertyValue("payloadExpression", payloadExpressionDef); } diff --git a/src/main/java/org/springframework/integration/aws/config/xml/SnsOutboundChannelAdapterParser.java b/src/main/java/org/springframework/integration/aws/config/xml/SnsOutboundChannelAdapterParser.java index 04c50ff..0bf1576 100644 --- a/src/main/java/org/springframework/integration/aws/config/xml/SnsOutboundChannelAdapterParser.java +++ b/src/main/java/org/springframework/integration/aws/config/xml/SnsOutboundChannelAdapterParser.java @@ -37,15 +37,14 @@ public class SnsOutboundChannelAdapterParser extends AbstractOutboundChannelAdap protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) { String sns = element.getAttribute(AwsParserUtils.SNS_REF); - BeanDefinitionBuilder builder = - BeanDefinitionBuilder.genericBeanDefinition(SnsMessageHandler.class) - .addConstructorArgReference(sns); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SnsMessageHandler.class) + .addConstructorArgReference(sns); AwsParserUtils.populateExpressionAttribute("topic-arn", builder, element, parserContext); AwsParserUtils.populateExpressionAttribute("subject", builder, element, parserContext); - BeanDefinition message = - IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined("body-expression", element); + BeanDefinition message = IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined("body-expression", + element); if (message != null) { builder.addPropertyValue("bodyExpression", message); } diff --git a/src/main/java/org/springframework/integration/aws/config/xml/SqsMessageDrivenChannelAdapterParser.java b/src/main/java/org/springframework/integration/aws/config/xml/SqsMessageDrivenChannelAdapterParser.java index 28624a4..1e437fd 100644 --- a/src/main/java/org/springframework/integration/aws/config/xml/SqsMessageDrivenChannelAdapterParser.java +++ b/src/main/java/org/springframework/integration/aws/config/xml/SqsMessageDrivenChannelAdapterParser.java @@ -47,7 +47,8 @@ public class SqsMessageDrivenChannelAdapterParser extends AbstractSingleBeanDefi String id = super.resolveId(element, definition, parserContext); if (!element.hasAttribute("channel")) { - // the created channel will get the 'id', so the adapter's bean name includes a suffix + // the created channel will get the 'id', so the adapter's bean name includes + // a suffix id = id + ".adapter"; } if (!StringUtils.hasText(id)) { diff --git a/src/main/java/org/springframework/integration/aws/inbound/S3InboundFileSynchronizer.java b/src/main/java/org/springframework/integration/aws/inbound/S3InboundFileSynchronizer.java index 695128f..2391721 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/S3InboundFileSynchronizer.java +++ b/src/main/java/org/springframework/integration/aws/inbound/S3InboundFileSynchronizer.java @@ -47,7 +47,8 @@ public class S3InboundFileSynchronizer extends AbstractInboundFileSynchronizer sessionFactory) { diff --git a/src/main/java/org/springframework/integration/aws/inbound/S3InboundFileSynchronizingMessageSource.java b/src/main/java/org/springframework/integration/aws/inbound/S3InboundFileSynchronizingMessageSource.java index ed041cf..cc848ea 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/S3InboundFileSynchronizingMessageSource.java +++ b/src/main/java/org/springframework/integration/aws/inbound/S3InboundFileSynchronizingMessageSource.java @@ -25,7 +25,8 @@ import org.springframework.integration.file.remote.synchronizer.AbstractInboundF import com.amazonaws.services.s3.model.S3ObjectSummary; /** - * A {@link org.springframework.integration.core.MessageSource} implementation for the Amazon S3. + * A {@link org.springframework.integration.core.MessageSource} implementation for the + * Amazon S3. * * @author Artem Bilan */ @@ -41,7 +42,6 @@ public class S3InboundFileSynchronizingMessageSource super(synchronizer, comparator); } - public String getComponentType() { return "aws:s3-inbound-channel-adapter"; } diff --git a/src/main/java/org/springframework/integration/aws/inbound/S3StreamingMessageSource.java b/src/main/java/org/springframework/integration/aws/inbound/S3StreamingMessageSource.java index 81d6d2c..4a14bba 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/S3StreamingMessageSource.java +++ b/src/main/java/org/springframework/integration/aws/inbound/S3StreamingMessageSource.java @@ -36,7 +36,6 @@ import com.amazonaws.services.s3.model.S3ObjectSummary; * * @author Christian Tzolov * @author Artem Bilan - * * @since 1.1 */ public class S3StreamingMessageSource extends AbstractRemoteFileStreamingMessageSource { @@ -55,9 +54,7 @@ public class S3StreamingMessageSource extends AbstractRemoteFileStreamingMessage @Override protected List> asFileInfoList(Collection collection) { - return collection.stream() - .map(S3FileInfo::new) - .collect(Collectors.toList()); + return collection.stream().map(S3FileInfo::new).collect(Collectors.toList()); } @Override diff --git a/src/main/java/org/springframework/integration/aws/inbound/SnsInboundChannelAdapter.java b/src/main/java/org/springframework/integration/aws/inbound/SnsInboundChannelAdapter.java index b19dd2b..dad3024 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/SnsInboundChannelAdapter.java +++ b/src/main/java/org/springframework/integration/aws/inbound/SnsInboundChannelAdapter.java @@ -46,27 +46,29 @@ import com.amazonaws.services.sns.AmazonSNS; import com.fasterxml.jackson.databind.JsonNode; /** - * The {@link HttpRequestHandlingMessagingGateway} extension for the Amazon WS SNS HTTP(S) endpoints. - * Accepts all {@code x-amz-sns-message-type}s, converts the received Topic JSON message to the - * {@link Map} using {@link MappingJackson2HttpMessageConverter} and send it to the provided - * {@link #getRequestChannel()} as {@link Message} {@code payload}. + * The {@link HttpRequestHandlingMessagingGateway} extension for the Amazon WS SNS HTTP(S) + * endpoints. Accepts all {@code x-amz-sns-message-type}s, converts the received Topic + * JSON message to the {@link Map} using {@link MappingJackson2HttpMessageConverter} and + * send it to the provided {@link #getRequestChannel()} as {@link Message} + * {@code payload}. *

- * The mapped url must be configured inside the Amazon Web Service platform as a subscription. - * Before receiving any notification itself this HTTP endpoint must confirm the subscription. + * The mapped url must be configured inside the Amazon Web Service platform as a + * subscription. Before receiving any notification itself this HTTP endpoint must confirm + * the subscription. *

* The {@link #handleNotificationStatus} flag (defaults to {@code false}) indicates that * this endpoint should send the {@code SubscriptionConfirmation/UnsubscribeConfirmation} - * messages to the the provided {@link #getRequestChannel()}. - * If that, the {@link AwsHeaders#NOTIFICATION_STATUS} header is populated - * with the {@link NotificationStatus} value. In that case it is a responsibility of - * the application to {@link NotificationStatus#confirmSubscription()} or not. + * messages to the the provided {@link #getRequestChannel()}. If that, the + * {@link AwsHeaders#NOTIFICATION_STATUS} header is populated with the + * {@link NotificationStatus} value. In that case it is a responsibility of the + * application to {@link NotificationStatus#confirmSubscription()} or not. *

- * By default this endpoint just does {@link NotificationStatus#confirmSubscription()} - * for the {@code SubscriptionConfirmation} message type. - * And does nothing for the {@code UnsubscribeConfirmation}. + * By default this endpoint just does {@link NotificationStatus#confirmSubscription()} for + * the {@code SubscriptionConfirmation} message type. And does nothing for the + * {@code UnsubscribeConfirmation}. *

- * For the convenience on the underlying message flow routing a {@link AwsHeaders#SNS_MESSAGE_TYPE} - * header is present. + * For the convenience on the underlying message flow routing a + * {@link AwsHeaders#SNS_MESSAGE_TYPE} header is present. * * @author Artem Bilan * @author Kamil Przerwa @@ -75,8 +77,7 @@ public class SnsInboundChannelAdapter extends HttpRequestHandlingMessagingGatewa private final NotificationStatusResolver notificationStatusResolver; - private final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = - new MappingJackson2HttpMessageConverter(); + private final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); private volatile boolean handleNotificationStatus; @@ -94,8 +95,8 @@ public class SnsInboundChannelAdapter extends HttpRequestHandlingMessagingGatewa requestMapping.setMethods(HttpMethod.POST); requestMapping.setHeaders("x-amz-sns-message-type"); requestMapping.setPathPatterns(path); - this.jackson2HttpMessageConverter.setSupportedMediaTypes( - Arrays.asList(MediaType.APPLICATION_JSON_UTF8, MediaType.TEXT_PLAIN)); + this.jackson2HttpMessageConverter + .setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)); super.setRequestMapping(requestMapping); super.setStatusCodeExpression(new ValueExpression<>(HttpStatus.NO_CONTENT)); super.setMessageConverters(Collections.singletonList(this.jackson2HttpMessageConverter)); @@ -148,8 +149,9 @@ public class SnsInboundChannelAdapter extends HttpRequestHandlingMessagingGatewa return; } } - messageToSendBuilder.setHeader(AwsHeaders.SNS_MESSAGE_TYPE, type) - .setHeader(AwsHeaders.MESSAGE_ID, payload.get("MessageId")); + messageToSendBuilder.setHeader(AwsHeaders.SNS_MESSAGE_TYPE, type).setHeader(AwsHeaders.MESSAGE_ID, + payload.get("MessageId")); + super.send(messageToSendBuilder.build()); } @@ -203,7 +205,6 @@ public class SnsInboundChannelAdapter extends HttpRequestHandlingMessagingGatewa throw new UnsupportedOperationException(); } - private static class NotificationStatusResolver extends NotificationStatusHandlerMethodArgumentResolver { NotificationStatusResolver(AmazonSNS amazonSns) { diff --git a/src/main/java/org/springframework/integration/aws/inbound/SqsMessageDrivenChannelAdapter.java b/src/main/java/org/springframework/integration/aws/inbound/SqsMessageDrivenChannelAdapter.java index 0613dfa..5f9c121 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/SqsMessageDrivenChannelAdapter.java +++ b/src/main/java/org/springframework/integration/aws/inbound/SqsMessageDrivenChannelAdapter.java @@ -45,12 +45,12 @@ import org.springframework.util.Assert; import com.amazonaws.services.sqs.AmazonSQSAsync; /** - * The {@link MessageProducerSupport} implementation for the Amazon SQS {@code receiveMessage}. - * Works in 'listener' manner and delegates hard to the {@link SimpleMessageListenerContainer}. + * The {@link MessageProducerSupport} implementation for the Amazon SQS + * {@code receiveMessage}. Works in 'listener' manner and delegates hard to the + * {@link SimpleMessageListenerContainer}. * * @author Artem Bilan * @author Patrick Fitzsimons - * * @see SimpleMessageListenerContainerFactory * @see SimpleMessageListenerContainer * @see QueueMessageHandler @@ -59,8 +59,7 @@ import com.amazonaws.services.sqs.AmazonSQSAsync; @IntegrationManagedResource public class SqsMessageDrivenChannelAdapter extends MessageProducerSupport implements DisposableBean { - private final SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory = - new SimpleMessageListenerContainerFactory(); + private final SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory = new SimpleMessageListenerContainerFactory(); private final String[] queues; @@ -163,7 +162,7 @@ public class SqsMessageDrivenChannelAdapter extends MessageProducerSupport imple @ManagedAttribute public String[] getQueues() { - return Arrays.copyOf(this.queues, this.queues.length); + return Arrays.copyOf(this.queues, this.queues.length); } @Override @@ -185,17 +184,12 @@ public class SqsMessageDrivenChannelAdapter extends MessageProducerSupport imple protected void handleMessageInternal(Message message, String lookupDestination) { MessageHeaders headers = message.getHeaders(); - Message messageToSend = getMessageBuilderFactory() - .fromMessage(message) - .removeHeaders("LogicalResourceId", - "MessageId", - "ReceiptHandle", - "Acknowledgment") + Message messageToSend = getMessageBuilderFactory().fromMessage(message) + .removeHeaders("LogicalResourceId", "MessageId", "ReceiptHandle", "Acknowledgment") .setHeader(AwsHeaders.MESSAGE_ID, headers.get("MessageId")) .setHeader(AwsHeaders.RECEIPT_HANDLE, headers.get("ReceiptHandle")) .setHeader(AwsHeaders.RECEIVED_QUEUE, headers.get("LogicalResourceId")) - .setHeader(AwsHeaders.ACKNOWLEDGMENT, headers.get("Acknowledgment")) - .build(); + .setHeader(AwsHeaders.ACKNOWLEDGMENT, headers.get("Acknowledgment")).build(); sendMessage(messageToSend); } diff --git a/src/main/java/org/springframework/integration/aws/inbound/kinesis/CheckpointMode.java b/src/main/java/org/springframework/integration/aws/inbound/kinesis/CheckpointMode.java index 008c850..44bd023 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/kinesis/CheckpointMode.java +++ b/src/main/java/org/springframework/integration/aws/inbound/kinesis/CheckpointMode.java @@ -27,8 +27,8 @@ package org.springframework.integration.aws.inbound.kinesis; public enum CheckpointMode { /** - * Checkpoint after each processed record. - * Makes sense only if {@link ListenerMode#record} is used. + * Checkpoint after each processed record. Makes sense only if + * {@link ListenerMode#record} is used. */ record, diff --git a/src/main/java/org/springframework/integration/aws/inbound/kinesis/Checkpointer.java b/src/main/java/org/springframework/integration/aws/inbound/kinesis/Checkpointer.java index 5478488..9f86bbf 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/kinesis/Checkpointer.java +++ b/src/main/java/org/springframework/integration/aws/inbound/kinesis/Checkpointer.java @@ -20,7 +20,6 @@ package org.springframework.integration.aws.inbound.kinesis; * A callback for target record process to perform checkpoint on the related shard. * * @author Artem Bilan - * * @since 1.1 */ public interface Checkpointer { diff --git a/src/main/java/org/springframework/integration/aws/inbound/kinesis/KclMessageDrivenChannelAdapter.java b/src/main/java/org/springframework/integration/aws/inbound/kinesis/KclMessageDrivenChannelAdapter.java index c2fa167..a00b6b6 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/kinesis/KclMessageDrivenChannelAdapter.java +++ b/src/main/java/org/springframework/integration/aws/inbound/kinesis/KclMessageDrivenChannelAdapter.java @@ -110,9 +110,8 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { private boolean bindSourceRecord; public KclMessageDrivenChannelAdapter(String streams) { - this(streams, AmazonKinesisClientBuilder.defaultClient(), - AmazonCloudWatchClientBuilder.defaultClient(), AmazonDynamoDBClientBuilder.defaultClient(), - new DefaultAWSCredentialsProviderChain()); + this(streams, AmazonKinesisClientBuilder.defaultClient(), AmazonCloudWatchClientBuilder.defaultClient(), + AmazonDynamoDBClientBuilder.defaultClient(), new DefaultAWSCredentialsProviderChain()); } public KclMessageDrivenChannelAdapter(String streams, Regions region) { @@ -121,8 +120,7 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { AmazonDynamoDBClient.builder().withRegion(region).build(), new DefaultAWSCredentialsProviderChain()); } - public KclMessageDrivenChannelAdapter(String stream, - AmazonKinesis kinesisClient, AmazonCloudWatch cloudWatchClient, + public KclMessageDrivenChannelAdapter(String stream, AmazonKinesis kinesisClient, AmazonCloudWatch cloudWatchClient, AmazonDynamoDB dynamoDBClient, AWSCredentialsProvider kinesisProxyCredentialsProvider) { Assert.notNull(stream, "'stream' must not be null."); @@ -148,8 +146,8 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { } /** - * Specify an {@link InboundMessageMapper} to extract message headers embedded - * into the record data. + * Specify an {@link InboundMessageMapper} to extract message headers embedded into + * the record data. * @param embeddedHeadersMapper the {@link InboundMessageMapper} to use. */ public void setEmbeddedHeadersMapper(InboundMessageMapper embeddedHeadersMapper) { @@ -183,8 +181,8 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { } /** - * Sets the worker identifier used to distinguish different - * workers/processes of a Kinesis application. + * Sets the worker identifier used to distinguish different workers/processes of a + * Kinesis application. * @param workerId the worker identifier to use */ public void setWorkerId(String workerId) { @@ -194,8 +192,8 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { /** * Set to true to bind the source consumer record in the header named - * {@link IntegrationMessageHeaderAccessor#SOURCE_DATA}. - * Does not apply to batch listeners. + * {@link IntegrationMessageHeaderAccessor#SOURCE_DATA}. Does not apply to batch + * listeners. * @param bindSourceRecord true to bind. * @since 2.2 */ @@ -207,40 +205,22 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { protected void onInit() { super.onInit(); - KinesisClientLibConfiguration config = - new KinesisClientLibConfiguration( - this.consumerGroup, - this.stream, - null, - this.streamInitialSequence, - this.kinesisProxyCredentialsProvider, - null, null, - KinesisClientLibConfiguration.DEFAULT_FAILOVER_TIME_MILLIS, - this.workerId, - KinesisClientLibConfiguration.DEFAULT_MAX_RECORDS, - this.idleBetweenPolls, - false, - KinesisClientLibConfiguration.DEFAULT_PARENT_SHARD_POLL_INTERVAL_MILLIS, - KinesisClientLibConfiguration.DEFAULT_SHARD_SYNC_INTERVAL_MILLIS, - KinesisClientLibConfiguration.DEFAULT_CLEANUP_LEASES_UPON_SHARDS_COMPLETION, - new ClientConfiguration(), - new ClientConfiguration(), - new ClientConfiguration(), - this.consumerBackoff, - KinesisClientLibConfiguration.DEFAULT_METRICS_BUFFER_TIME_MILLIS, - KinesisClientLibConfiguration.DEFAULT_METRICS_MAX_QUEUE_SIZE, - KinesisClientLibConfiguration.DEFAULT_VALIDATE_SEQUENCE_NUMBER_BEFORE_CHECKPOINTING, - null, - KinesisClientLibConfiguration.DEFAULT_SHUTDOWN_GRACE_MILLIS); + KinesisClientLibConfiguration config = new KinesisClientLibConfiguration(this.consumerGroup, this.stream, null, + this.streamInitialSequence, this.kinesisProxyCredentialsProvider, null, null, + KinesisClientLibConfiguration.DEFAULT_FAILOVER_TIME_MILLIS, this.workerId, + KinesisClientLibConfiguration.DEFAULT_MAX_RECORDS, this.idleBetweenPolls, false, + KinesisClientLibConfiguration.DEFAULT_PARENT_SHARD_POLL_INTERVAL_MILLIS, + KinesisClientLibConfiguration.DEFAULT_SHARD_SYNC_INTERVAL_MILLIS, + KinesisClientLibConfiguration.DEFAULT_CLEANUP_LEASES_UPON_SHARDS_COMPLETION, new ClientConfiguration(), + new ClientConfiguration(), new ClientConfiguration(), this.consumerBackoff, + KinesisClientLibConfiguration.DEFAULT_METRICS_BUFFER_TIME_MILLIS, + KinesisClientLibConfiguration.DEFAULT_METRICS_MAX_QUEUE_SIZE, + KinesisClientLibConfiguration.DEFAULT_VALIDATE_SEQUENCE_NUMBER_BEFORE_CHECKPOINTING, null, + KinesisClientLibConfiguration.DEFAULT_SHUTDOWN_GRACE_MILLIS); - this.scheduler = new Worker.Builder() - .kinesisClient(this.kinesisClient) - .dynamoDBClient(this.dynamoDBClient) - .cloudWatchClient(this.cloudWatchClient) - .recordProcessorFactory(new RecordProcessorFactory()) - .execService(new ExecutorServiceAdapter(this.executor)) - .config(config) - .build(); + this.scheduler = new Worker.Builder().kinesisClient(this.kinesisClient).dynamoDBClient(this.dynamoDBClient) + .cloudWatchClient(this.cloudWatchClient).recordProcessorFactory(new RecordProcessorFactory()) + .execService(new ExecutorServiceAdapter(this.executor)).config(config).build(); } @Override @@ -273,8 +253,8 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { @Override public String toString() { - return "KclMessageDrivenChannelAdapter{consumerGroup='" + this.consumerGroup + '\'' + - ", stream='" + this.stream + "'}"; + return "KclMessageDrivenChannelAdapter{consumerGroup='" + this.consumerGroup + '\'' + ", stream='" + this.stream + + "'}"; } private class RecordProcessorFactory implements IRecordProcessorFactory { @@ -354,11 +334,11 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { if (KclMessageDrivenChannelAdapter.this.embeddedHeadersMapper != null) { try { - messageToUse = - KclMessageDrivenChannelAdapter.this.embeddedHeadersMapper.toMessage((byte[]) payload); + messageToUse = KclMessageDrivenChannelAdapter.this.embeddedHeadersMapper + .toMessage((byte[]) payload); if (messageToUse == null) { - throw new IllegalStateException("The 'embeddedHeadersMapper' returned null for payload: " + - Arrays.toString((byte[]) payload)); + throw new IllegalStateException("The 'embeddedHeadersMapper' returned null for payload: " + + Arrays.toString((byte[]) payload)); } payload = messageToUse.getPayload(); } @@ -401,8 +381,8 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { } /** - * If there's an error channel, we create a new attributes holder here. - * Then set the attributes for use by the {@link ErrorMessageStrategy}. + * If there's an error channel, we create a new attributes holder here. Then set + * the attributes for use by the {@link ErrorMessageStrategy}. * @param record the Kinesis record to use. * @param message the Spring Messaging message to use. */ @@ -426,7 +406,8 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { checkpointer.checkpoint(); } catch (ShutdownException se) { - // Ignore checkpoint if the processor instance has been shutdown (fail over). + // Ignore checkpoint if the processor instance has been shutdown (fail + // over). logger.info("Caught shutdown exception, skipping checkpoint.", se); } catch (ThrottlingException e) { @@ -435,7 +416,8 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport { } } catch (InvalidStateException e) { - // This indicates an issue with the DynamoDB table (check for table, provisioned + // This indicates an issue with the DynamoDB table (check for table, + // provisioned // IOPS). logger.error("Cannot save checkpoint to the DynamoDB table used by the Amazon Kinesis Client Library.", e); diff --git a/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisMessageDrivenChannelAdapter.java b/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisMessageDrivenChannelAdapter.java index 56eeb81..7a5c0ce 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisMessageDrivenChannelAdapter.java +++ b/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisMessageDrivenChannelAdapter.java @@ -80,12 +80,12 @@ import com.amazonaws.services.kinesis.model.ShardIteratorType; import com.amazonaws.services.kinesis.model.StreamStatus; /** - * The {@link MessageProducerSupport} implementation for receiving data from Amazon Kinesis stream(s). + * The {@link MessageProducerSupport} implementation for receiving data from Amazon + * Kinesis stream(s). * * @author Artem Bilan * @author Krzysztof Witkowski * @author Hervé Fortin - * * @since 1.1 */ @ManagedResource @@ -108,13 +108,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i private final ShardConsumerManager shardConsumerManager = new ShardConsumerManager(); - private final ExecutorService shardLocksExecutor = - Executors.newSingleThreadExecutor( - new CustomizableThreadFactory( - (getComponentName() == null - ? "" - : getComponentName()) - + "-kinesis-shard-locks-")); + private final ExecutorService shardLocksExecutor = Executors.newSingleThreadExecutor(new CustomizableThreadFactory( + (getComponentName() == null ? "" : getComponentName()) + "-kinesis-shard-locks-")); private String consumerGroup = "SpringIntegration"; @@ -175,8 +170,7 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i this.streams = Arrays.copyOf(streams, streams.length); } - public KinesisMessageDrivenChannelAdapter(AmazonKinesis amazonKinesis, - KinesisShardOffset... shardOffsets) { + public KinesisMessageDrivenChannelAdapter(AmazonKinesis amazonKinesis, KinesisShardOffset... shardOffsets) { Assert.notNull(amazonKinesis, "'amazonKinesis' must not be null."); Assert.notEmpty(shardOffsets, "'shardOffsets' must not be null."); @@ -245,8 +239,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } /** - * The maximum record to poll per on get-records request. - * Not greater then {@code 10000}. + * The maximum record to poll per on get-records request. Not greater then + * {@code 10000}. * @param recordsLimit the number of records to for per on get-records request. * @see GetRecordsRequest#setLimit */ @@ -274,12 +268,11 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } /** - * The maximum number of concurrent {@link ConsumerInvoker}s running. - * The {@link ShardConsumer}s are evenly distributed between {@link ConsumerInvoker}s. - * Messages from within the same shard will be processed sequentially. - * In other words each shard is tied with the particular thread. - * By default the concurrency is unlimited and shard - * is processed in the {@link #consumerExecutor} directly. + * The maximum number of concurrent {@link ConsumerInvoker}s running. The + * {@link ShardConsumer}s are evenly distributed between {@link ConsumerInvoker}s. + * Messages from within the same shard will be processed sequentially. In other words + * each shard is tied with the particular thread. By default the concurrency is + * unlimited and shard is processed in the {@link #consumerExecutor} directly. * @param concurrency the concurrency maximum number */ public void setConcurrency(int concurrency) { @@ -287,8 +280,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } /** - * The sleep interval in milliseconds used in the main loop between shards polling cycles. - * Defaults to {@code 1000}l minimum {@code 250}. + * The sleep interval in milliseconds used in the main loop between shards polling + * cycles. Defaults to {@code 1000}l minimum {@code 250}. * @param idleBetweenPolls the interval to sleep between shards polling cycles. */ public void setIdleBetweenPolls(int idleBetweenPolls) { @@ -296,7 +289,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } /** - * Specify an {@link InboundMessageMapper} to extract message headers embedded into the record data. + * Specify an {@link InboundMessageMapper} to extract message headers embedded into + * the record data. * @param embeddedHeadersMapper the {@link InboundMessageMapper} to use. * @since 2.0 */ @@ -305,8 +299,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } /** - * Specify a {@link LockRegistry} for an exclusive access to provided streams. - * This is not used when shards-based configuration is provided. + * Specify a {@link LockRegistry} for an exclusive access to provided streams. This is + * not used when shards-based configuration is provided. * @param lockRegistry the {@link LockRegistry} to use. * @since 2.0 */ @@ -316,8 +310,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i /** * Set to true to bind the source consumer record in the header named - * {@link IntegrationMessageHeaderAccessor#SOURCE_DATA}. - * Does not apply to batch listeners. + * {@link IntegrationMessageHeaderAccessor#SOURCE_DATA}. Does not apply to batch + * listeners. * @param bindSourceRecord true to bind. * @since 2.2 */ @@ -330,19 +324,12 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i super.onInit(); if (this.consumerExecutor == null) { - this.consumerExecutor = Executors.newCachedThreadPool( - new CustomizableThreadFactory((getComponentName() == null - ? "" - : getComponentName()) - + "-kinesis-consumer-")); + this.consumerExecutor = Executors.newCachedThreadPool(new CustomizableThreadFactory( + (getComponentName() == null ? "" : getComponentName()) + "-kinesis-consumer-")); } if (this.dispatcherExecutor == null) { - this.dispatcherExecutor = - Executors.newCachedThreadPool( - new CustomizableThreadFactory((getComponentName() == null - ? "" - : getComponentName()) - + "-kinesis-dispatcher-")); + this.dispatcherExecutor = Executors.newCachedThreadPool(new CustomizableThreadFactory( + (getComponentName() == null ? "" : getComponentName()) + "-kinesis-dispatcher-")); } if (this.streams == null) { @@ -371,8 +358,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } else { if (this.logger.isDebugEnabled()) { - this.logger.debug("There is no ShardConsumer for shard [" + shard + "] in stream [" + shard - + "] to stop."); + this.logger.debug( + "There is no ShardConsumer for shard [" + shard + "] in stream [" + shard + "] to stop."); } } } @@ -420,9 +407,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i private void restartShardConsumerForOffset(KinesisShardOffset shardOffset) { Assert.isTrue(this.shardOffsets.contains(shardOffset), - "The [" + KinesisMessageDrivenChannelAdapter.this + - "] doesn't operate shard [" + shardOffset.getShard() + - "] for stream [" + shardOffset.getStream() + "]"); + "The [" + KinesisMessageDrivenChannelAdapter.this + "] doesn't operate shard [" + shardOffset.getShard() + + "] for stream [" + shardOffset.getStream() + "]"); if (logger.isDebugEnabled()) { logger.debug("Resetting consumer for [" + shardOffset + "]..."); @@ -456,8 +442,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i super.doStart(); if (ListenerMode.batch.equals(this.listenerMode) && CheckpointMode.record.equals(this.checkpointMode)) { this.checkpointMode = CheckpointMode.batch; - logger.warn("The 'checkpointMode' is overridden from [CheckpointMode.record] to [CheckpointMode.batch] " + - "because it does not make sense in case of [ListenerMode.batch]."); + logger.warn("The 'checkpointMode' is overridden from [CheckpointMode.record] to [CheckpointMode.batch] " + + "because it does not make sense in case of [ListenerMode.batch]."); } if (this.streams != null) { @@ -507,14 +493,13 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } try { if (!shardsGatherLatch.await(this.startTimeout, TimeUnit.MILLISECONDS)) { - throw new IllegalStateException("The [ " - + KinesisMessageDrivenChannelAdapter.this + - "] could not start during timeout: " + this.startTimeout); + throw new IllegalStateException("The [ " + KinesisMessageDrivenChannelAdapter.this + + "] could not start during timeout: " + this.startTimeout); } } catch (InterruptedException e) { - throw new IllegalStateException("The [ " + KinesisMessageDrivenChannelAdapter.this + - "] has been interrupted from start."); + throw new IllegalStateException( + "The [ " + KinesisMessageDrivenChannelAdapter.this + "] has been interrupted from start."); } } @@ -526,28 +511,26 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i String exclusiveStartShardId = null; while (true) { - DescribeStreamRequest describeStreamRequest = new DescribeStreamRequest() - .withStreamName(stream) + DescribeStreamRequest describeStreamRequest = new DescribeStreamRequest().withStreamName(stream) .withExclusiveStartShardId(exclusiveStartShardId); DescribeStreamResult describeStreamResult = null; - // Call DescribeStream, with backoff and retries (if we get LimitExceededException). + // Call DescribeStream, with backoff and retries (if we get + // LimitExceededException). try { describeStreamResult = this.amazonKinesis.describeStream(describeStreamRequest); } catch (Exception e) { - logger.info("Got an exception when describing stream [" + stream + "]. " + - "Backing off for [" + this.describeStreamBackoff + "] millis.", e); + logger.info("Got an exception when describing stream [" + stream + "]. " + "Backing off for [" + + this.describeStreamBackoff + "] millis.", e); } - if (describeStreamResult == null || - !StreamStatus.ACTIVE.toString().equals( - describeStreamResult.getStreamDescription().getStreamStatus())) { + if (describeStreamResult == null || !StreamStatus.ACTIVE.toString() + .equals(describeStreamResult.getStreamDescription().getStreamStatus())) { if (describeStreamRetries++ > this.describeStreamRetries) { - ResourceNotFoundException resourceNotFoundException = - new ResourceNotFoundException("The stream [" + stream + - "] isn't ACTIVE or doesn't exist."); + ResourceNotFoundException resourceNotFoundException = new ResourceNotFoundException( + "The stream [" + stream + "] isn't ACTIVE or doesn't exist."); resourceNotFoundException.setServiceName("Kinesis"); throw resourceNotFoundException; } @@ -557,8 +540,9 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new IllegalStateException("The [describeStream] thread for the stream [" - + stream + "] has been interrupted.", e); + throw new IllegalStateException( + "The [describeStream] thread for the stream [" + stream + "] has been interrupted.", + e); } } @@ -571,19 +555,19 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i if (endingSequenceNumber != null) { String checkpoint = this.checkpointStore.get(key); - boolean skipClosedShard = checkpoint != null && - new BigInteger(endingSequenceNumber) - .compareTo(new BigInteger(checkpoint)) <= 0; + boolean skipClosedShard = checkpoint != null && new BigInteger(endingSequenceNumber) + .compareTo(new BigInteger(checkpoint)) <= 0; if (logger.isTraceEnabled()) { - logger.trace("The shard [" + shard + "] in stream [" + stream + - "] is closed CLOSED with endingSequenceNumber [" + endingSequenceNumber + - "].\nThe last processed checkpoint is [" + checkpoint + "]." + - (skipClosedShard ? "\nThe shard will be skipped." : "")); + logger.trace("The shard [" + shard + "] in stream [" + stream + + "] is closed CLOSED with endingSequenceNumber [" + endingSequenceNumber + + "].\nThe last processed checkpoint is [" + checkpoint + "]." + + (skipClosedShard ? "\nThe shard will be skipped." : "")); } if (skipClosedShard) { - // Skip CLOSED shard which has been read before according a checkpoint + // Skip CLOSED shard which has been read before + // according a checkpoint continue; } } @@ -592,8 +576,9 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } } catch (Exception e) { - logger.info("Got an exception when processing shards in stream [" + stream + "].\n" + - "Retrying...", e); + logger.info( + "Got an exception when processing shards in stream [" + stream + "].\n" + "Retrying...", + e); continue; } @@ -693,8 +678,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } /** - * If there's an error channel, we create a new attributes holder here. - * Then set the attributes for use by the {@link ErrorMessageStrategy}. + * If there's an error channel, we create a new attributes holder here. Then set the + * attributes for use by the {@link ErrorMessageStrategy}. * @param record the Kinesis record to use. * @param message the Spring Messaging message to use. */ @@ -719,10 +704,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i @Override public String toString() { - return "KinesisMessageDrivenChannelAdapter{" + - "shardOffsets=" + this.shardOffsets + - ", consumerGroup='" + this.consumerGroup + '\'' + - '}'; + return "KinesisMessageDrivenChannelAdapter{" + "shardOffsets=" + this.shardOffsets + ", consumerGroup='" + + this.consumerGroup + '\'' + '}'; } private final class ConsumerDispatcher implements SchedulingAwareRunnable { @@ -744,8 +727,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } } - Iterator iterator = - KinesisMessageDrivenChannelAdapter.this.shardConsumers.values().iterator(); + Iterator iterator = KinesisMessageDrivenChannelAdapter.this.shardConsumers.values() + .iterator(); while (iterator.hasNext()) { ShardConsumer shardConsumer = iterator.next(); shardConsumer.execute(); @@ -836,65 +819,62 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i if (this.task == null) { switch (this.state) { - case NEW: - case EXPIRED: - this.task = () -> { - try { - if (this.shardOffset.isReset()) { - this.checkpointer.remove(); - } - else { - String checkpoint = this.checkpointer.getCheckpoint(); - if (checkpoint != null) { - this.shardOffset.setSequenceNumber(checkpoint); - this.shardOffset.setIteratorType(ShardIteratorType.AFTER_SEQUENCE_NUMBER); - } - } - if (logger.isInfoEnabled() && this.state == ConsumerState.NEW) { - logger.info("The [" + this + "] has been started."); - } - GetShardIteratorRequest shardIteratorRequest = - this.shardOffset.toShardIteratorRequest(); - this.shardIterator = - KinesisMessageDrivenChannelAdapter.this.amazonKinesis - .getShardIterator(shardIteratorRequest) - .getShardIterator(); - if (ConsumerState.STOP != this.state) { - this.state = ConsumerState.CONSUME; + case NEW: + case EXPIRED: + this.task = () -> { + try { + if (this.shardOffset.isReset()) { + this.checkpointer.remove(); + } + else { + String checkpoint = this.checkpointer.getCheckpoint(); + if (checkpoint != null) { + this.shardOffset.setSequenceNumber(checkpoint); + this.shardOffset.setIteratorType(ShardIteratorType.AFTER_SEQUENCE_NUMBER); } } - finally { - this.task = null; + if (logger.isInfoEnabled() && this.state == ConsumerState.NEW) { + logger.info("The [" + this + "] has been started."); } - }; - break; - - case CONSUME: - this.task = this.processTask; - break; - - case SLEEP: - if (System.currentTimeMillis() >= this.sleepUntil) { - this.state = ConsumerState.CONSUME; - } - this.task = null; - break; - - case STOP: - if (this.shardIterator == null) { - if (logger.isInfoEnabled()) { - logger.info("Stopping the [" + this + - "] on the checkpoint [" + this.checkpointer.getCheckpoint() + - "] because the shard has been CLOSED and exhausted."); + GetShardIteratorRequest shardIteratorRequest = this.shardOffset.toShardIteratorRequest(); + this.shardIterator = KinesisMessageDrivenChannelAdapter.this.amazonKinesis + .getShardIterator(shardIteratorRequest).getShardIterator(); + if (ConsumerState.STOP != this.state) { + this.state = ConsumerState.CONSUME; } } - else { - if (logger.isInfoEnabled()) { - logger.info("Stopping the [" + this + "]."); - } + finally { + this.task = null; } - this.task = null; - break; + }; + break; + + case CONSUME: + this.task = this.processTask; + break; + + case SLEEP: + if (System.currentTimeMillis() >= this.sleepUntil) { + this.state = ConsumerState.CONSUME; + } + this.task = null; + break; + + case STOP: + if (this.shardIterator == null) { + if (logger.isInfoEnabled()) { + logger.info("Stopping the [" + this + "] on the checkpoint [" + + this.checkpointer.getCheckpoint() + + "] because the shard has been CLOSED and exhausted."); + } + } + else { + if (logger.isInfoEnabled()) { + logger.info("Stopping the [" + this + "]."); + } + } + this.task = null; + break; } if (this.task != null) { @@ -939,11 +919,9 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i if (ConsumerState.STOP != this.state && result.getRecords().isEmpty()) { if (logger.isDebugEnabled()) { - logger.debug("No records for [" + this + - "] on sequenceNumber [" + - this.checkpointer.getLastCheckpointValue() + - "]. Suspend consuming for [" + - KinesisMessageDrivenChannelAdapter.this.consumerBackoff + "] milliseconds."); + logger.debug("No records for [" + this + "] on sequenceNumber [" + + this.checkpointer.getLastCheckpointValue() + "]. Suspend consuming for [" + + KinesisMessageDrivenChannelAdapter.this.consumerBackoff + "] milliseconds."); } prepareSleepState(); } @@ -959,18 +937,20 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i return KinesisMessageDrivenChannelAdapter.this.amazonKinesis.getRecords(getRecordsRequest); } catch (ExpiredIteratorException e) { - // Iterator expired, but this does not mean that shard no longer contains records. - // Lets acquire iterator again (using checkpointer for iterator start sequence number). + // Iterator expired, but this does not mean that shard no longer contains + // records. + // Lets acquire iterator again (using checkpointer for iterator start + // sequence number). if (logger.isInfoEnabled()) { - logger.info("Shard iterator for [" + ShardConsumer.this + "] expired.\n" + - "A new one will be started from the check pointed sequence number."); + logger.info("Shard iterator for [" + ShardConsumer.this + "] expired.\n" + + "A new one will be started from the check pointed sequence number."); } this.state = ConsumerState.EXPIRED; } catch (ProvisionedThroughputExceededException e) { if (logger.isWarnEnabled()) { - logger.warn("GetRecords request throttled for [" + ShardConsumer.this + - "] with the reason: " + e.getErrorMessage()); + logger.warn("GetRecords request throttled for [" + ShardConsumer.this + "] with the reason: " + + e.getErrorMessage()); } // We are throttled, so let's sleep prepareSleepState(); @@ -980,8 +960,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } private void prepareSleepState() { - ShardConsumer.this.sleepUntil = System.currentTimeMillis() + - KinesisMessageDrivenChannelAdapter.this.consumerBackoff; + ShardConsumer.this.sleepUntil = System.currentTimeMillis() + + KinesisMessageDrivenChannelAdapter.this.consumerBackoff; ShardConsumer.this.state = ConsumerState.SLEEP; } @@ -993,63 +973,56 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i this.checkpointer.setHighestSequence(records.get(records.size() - 1).getSequenceNumber()); switch (KinesisMessageDrivenChannelAdapter.this.listenerMode) { - case record: - for (Record record : records) { - performSend(prepareMessageForRecord(record), record); + case record: + for (Record record : records) { + performSend(prepareMessageForRecord(record), record); - if (CheckpointMode.record.equals(KinesisMessageDrivenChannelAdapter.this.checkpointMode)) { - this.checkpointer.checkpoint(record.getSequenceNumber()); - } + if (CheckpointMode.record.equals(KinesisMessageDrivenChannelAdapter.this.checkpointMode)) { + this.checkpointer.checkpoint(record.getSequenceNumber()); } + } - break; + break; - case batch: - Object payload = records; + case batch: + Object payload = records; - if (KinesisMessageDrivenChannelAdapter.this.embeddedHeadersMapper != null) { - payload = records.stream() - .map(this::prepareMessageForRecord) - .collect(Collectors.toList()); - } + if (KinesisMessageDrivenChannelAdapter.this.embeddedHeadersMapper != null) { + payload = records.stream().map(this::prepareMessageForRecord).collect(Collectors.toList()); + } - final List partitionKeys; - final List sequenceNumbers; - if (KinesisMessageDrivenChannelAdapter.this.converter != null) { - partitionKeys = new ArrayList<>(); - sequenceNumbers = new ArrayList<>(); + final List partitionKeys; + final List sequenceNumbers; + if (KinesisMessageDrivenChannelAdapter.this.converter != null) { + partitionKeys = new ArrayList<>(); + sequenceNumbers = new ArrayList<>(); - payload = records.stream() - .map(r -> { - partitionKeys.add(r.getPartitionKey()); - sequenceNumbers.add(r.getSequenceNumber()); + payload = records.stream().map(r -> { + partitionKeys.add(r.getPartitionKey()); + sequenceNumbers.add(r.getSequenceNumber()); - return KinesisMessageDrivenChannelAdapter.this.converter - .convert(r.getData().array()); - }) - .collect(Collectors.toList()); - } - else { - partitionKeys = null; - sequenceNumbers = null; - } + return KinesisMessageDrivenChannelAdapter.this.converter.convert(r.getData().array()); + }).collect(Collectors.toList()); + } + else { + partitionKeys = null; + sequenceNumbers = null; + } - AbstractIntegrationMessageBuilder messageBuilder = - getMessageBuilderFactory() - .withPayload(payload) - .setHeader(AwsHeaders.RECEIVED_PARTITION_KEY, partitionKeys) - .setHeader(AwsHeaders.RECEIVED_SEQUENCE_NUMBER, sequenceNumbers); + AbstractIntegrationMessageBuilder messageBuilder = getMessageBuilderFactory().withPayload(payload) + .setHeader(AwsHeaders.RECEIVED_PARTITION_KEY, partitionKeys) + .setHeader(AwsHeaders.RECEIVED_SEQUENCE_NUMBER, sequenceNumbers); - performSend(messageBuilder, records); + performSend(messageBuilder, records); - break; + break; } if (CheckpointMode.batch.equals(KinesisMessageDrivenChannelAdapter.this.checkpointMode)) { this.checkpointer.checkpoint(); } - else if (CheckpointMode.periodic.equals(KinesisMessageDrivenChannelAdapter.this.checkpointMode) && - System.currentTimeMillis() > nextCheckpointTimeInMillis) { + else if (CheckpointMode.periodic.equals(KinesisMessageDrivenChannelAdapter.this.checkpointMode) + && System.currentTimeMillis() > nextCheckpointTimeInMillis) { this.checkpointer.checkpoint(); this.nextCheckpointTimeInMillis = System.currentTimeMillis() + checkpointsInterval; } @@ -1061,9 +1034,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i if (KinesisMessageDrivenChannelAdapter.this.embeddedHeadersMapper != null) { try { - messageToUse = - KinesisMessageDrivenChannelAdapter.this.embeddedHeadersMapper - .toMessage((byte[]) payload); + messageToUse = KinesisMessageDrivenChannelAdapter.this.embeddedHeadersMapper + .toMessage((byte[]) payload); payload = messageToUse.getPayload(); } @@ -1072,17 +1044,14 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } } - if (payload instanceof byte[] && - KinesisMessageDrivenChannelAdapter.this.converter != null) { + if (payload instanceof byte[] && KinesisMessageDrivenChannelAdapter.this.converter != null) { payload = KinesisMessageDrivenChannelAdapter.this.converter.convert((byte[]) payload); } - AbstractIntegrationMessageBuilder messageBuilder = - getMessageBuilderFactory() - .withPayload(payload) - .setHeader(AwsHeaders.RECEIVED_PARTITION_KEY, record.getPartitionKey()) - .setHeader(AwsHeaders.RECEIVED_SEQUENCE_NUMBER, record.getSequenceNumber()); + AbstractIntegrationMessageBuilder messageBuilder = getMessageBuilderFactory().withPayload(payload) + .setHeader(AwsHeaders.RECEIVED_PARTITION_KEY, record.getPartitionKey()) + .setHeader(AwsHeaders.RECEIVED_SEQUENCE_NUMBER, record.getSequenceNumber()); if (KinesisMessageDrivenChannelAdapter.this.bindSourceRecord) { messageBuilder.setHeader(IntegrationMessageHeaderAccessor.SOURCE_DATA, record); @@ -1109,18 +1078,14 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i sendMessage(messageToSend); } catch (Exception e) { - logger.info("Got an exception during sending a '" + messageToSend + "'" + - "\nfor the '" + rawRecord + "'.\n" + - "Consider to use 'errorChannel' flow for the compensation logic.", e); + logger.info("Got an exception during sending a '" + messageToSend + "'" + "\nfor the '" + rawRecord + + "'.\n" + "Consider to use 'errorChannel' flow for the compensation logic.", e); } } @Override public String toString() { - return "ShardConsumer{" + - "shardOffset=" + this.shardOffset + - ", state=" + this.state + - '}'; + return "ShardConsumer{" + "shardOffset=" + this.shardOffset + ", state=" + this.state + '}'; } } @@ -1166,7 +1131,7 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i throw new IllegalStateException("ConsumerInvoker thread [" + this + "] has been interrupted", e); } - for (Iterator iterator = this.consumers.iterator(); iterator.hasNext(); ) { + for (Iterator iterator = this.consumers.iterator(); iterator.hasNext();) { ShardConsumer shardConsumer = iterator.next(); if (ConsumerState.STOP == shardConsumer.state) { iterator.remove(); @@ -1184,7 +1149,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } } synchronized (KinesisMessageDrivenChannelAdapter.this.consumerInvokers) { - // The attempt to survive if ShardConsumer has been added during synchronization + // The attempt to survive if ShardConsumer has been added during + // synchronization if (this.consumers.isEmpty()) { KinesisMessageDrivenChannelAdapter.this.consumerInvokers.remove(this); break; @@ -1225,33 +1191,31 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i try { while (!Thread.currentThread().isInterrupted()) { - this.shardOffsetsToConsumer.entrySet() - .removeIf(entry -> { - boolean remove = true; - if (KinesisMessageDrivenChannelAdapter.this.lockRegistry != null) { - String key = entry.getKey(); - Lock lock = - KinesisMessageDrivenChannelAdapter.this.lockRegistry.obtain(key); - try { - if (lock.tryLock()) { - this.locks.put(key, lock); - } - else { - remove = false; - } - - } - catch (Exception e) { - logger.error("Error during locking: " + lock, e); - } + this.shardOffsetsToConsumer.entrySet().removeIf(entry -> { + boolean remove = true; + if (KinesisMessageDrivenChannelAdapter.this.lockRegistry != null) { + String key = entry.getKey(); + Lock lock = KinesisMessageDrivenChannelAdapter.this.lockRegistry.obtain(key); + try { + if (lock.tryLock()) { + this.locks.put(key, lock); + } + else { + remove = false; } - if (remove) { - populateConsumer(entry.getValue()); - } + } + catch (Exception e) { + logger.error("Error during locking: " + lock, e); + } + } - return remove; - }); + if (remove) { + populateConsumer(entry.getValue()); + } + + return remove; + }); while (KinesisMessageDrivenChannelAdapter.this.lockRegistry != null) { String lockKey = this.forUnlocking.poll(); @@ -1276,13 +1240,13 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new IllegalStateException("ShardConsumerManager Thread [" + - this + "] has been interrupted", e); + throw new IllegalStateException( + "ShardConsumerManager Thread [" + this + "] has been interrupted", e); } } } finally { - for (Iterator iterator = this.locks.values().iterator(); iterator.hasNext(); ) { + for (Iterator iterator = this.locks.values().iterator(); iterator.hasNext();) { Lock lock = iterator.next(); try { lock.unlock(); diff --git a/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisMessageHeaderErrorMessageStrategy.java b/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisMessageHeaderErrorMessageStrategy.java index e3bd87f..42a18d8 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisMessageHeaderErrorMessageStrategy.java +++ b/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisMessageHeaderErrorMessageStrategy.java @@ -28,25 +28,22 @@ import org.springframework.messaging.Message; import org.springframework.messaging.support.ErrorMessage; /** - * The {@link ErrorMessageStrategy} implementation to build an {@link ErrorMessage} - * with the {@link AwsHeaders#RAW_RECORD} header by the value from - * the the provided {@link AttributeAccessor}. + * The {@link ErrorMessageStrategy} implementation to build an {@link ErrorMessage} with + * the {@link AwsHeaders#RAW_RECORD} header by the value from the the provided + * {@link AttributeAccessor}. * * @author Artem Bilan - * * @since 2.0 */ public class KinesisMessageHeaderErrorMessageStrategy implements ErrorMessageStrategy { @Override public ErrorMessage buildErrorMessage(Throwable throwable, AttributeAccessor context) { - Object inputMessage = - context == null ? null : context.getAttribute(ErrorMessageUtils.INPUT_MESSAGE_CONTEXT_KEY); + Object inputMessage = context == null ? null + : context.getAttribute(ErrorMessageUtils.INPUT_MESSAGE_CONTEXT_KEY); - Map headers = - context == null - ? new HashMap<>() - : Collections.singletonMap(AwsHeaders.RAW_RECORD, context.getAttribute(AwsHeaders.RAW_RECORD)); + Map headers = context == null ? new HashMap<>() + : Collections.singletonMap(AwsHeaders.RAW_RECORD, context.getAttribute(AwsHeaders.RAW_RECORD)); return new ErrorMessage(throwable, headers, inputMessage instanceof Message ? (Message) inputMessage : null); } diff --git a/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisShardOffset.java b/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisShardOffset.java index 5ddc555..3b7b229 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisShardOffset.java +++ b/src/main/java/org/springframework/integration/aws/inbound/kinesis/KinesisShardOffset.java @@ -114,11 +114,8 @@ public class KinesisShardOffset { public GetShardIteratorRequest toShardIteratorRequest() { Assert.state(this.stream != null && this.shard != null, "'stream' and 'shard' must not be null for conversion to the GetShardIteratorRequest."); - return new GetShardIteratorRequest() - .withStreamName(this.stream) - .withShardId(this.shard) - .withShardIteratorType(this.iteratorType) - .withStartingSequenceNumber(this.sequenceNumber) + return new GetShardIteratorRequest().withStreamName(this.stream).withShardId(this.shard) + .withShardIteratorType(this.iteratorType).withStartingSequenceNumber(this.sequenceNumber) .withTimestamp(this.timestamp); } @@ -131,8 +128,7 @@ public class KinesisShardOffset { return false; } KinesisShardOffset that = (KinesisShardOffset) o; - return Objects.equals(this.stream, that.stream) && - Objects.equals(this.shard, that.shard); + return Objects.equals(this.stream, that.stream) && Objects.equals(this.shard, that.shard); } @Override @@ -140,17 +136,11 @@ public class KinesisShardOffset { return Objects.hash(this.stream, this.shard); } - @Override public String toString() { - return "KinesisShardOffset{" + - "iteratorType=" + this.iteratorType + - ", sequenceNumber='" + this.sequenceNumber + '\'' + - ", timestamp=" + this.timestamp + - ", stream='" + this.stream + '\'' + - ", shard='" + this.shard + '\'' + - ", reset=" + this.reset + - '}'; + return "KinesisShardOffset{" + "iteratorType=" + this.iteratorType + ", sequenceNumber='" + this.sequenceNumber + + '\'' + ", timestamp=" + this.timestamp + ", stream='" + this.stream + '\'' + ", shard='" + this.shard + + '\'' + ", reset=" + this.reset + '}'; } public static KinesisShardOffset latest() { @@ -211,5 +201,4 @@ public class KinesisShardOffset { return kinesisShardOffset; } - } diff --git a/src/main/java/org/springframework/integration/aws/inbound/kinesis/ListenerMode.java b/src/main/java/org/springframework/integration/aws/inbound/kinesis/ListenerMode.java index 5ea896a..5453a05 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/kinesis/ListenerMode.java +++ b/src/main/java/org/springframework/integration/aws/inbound/kinesis/ListenerMode.java @@ -33,8 +33,8 @@ public enum ListenerMode { record, /** - * Each {@link Message} will contain {@code List} ( if not empty) - * of converted or raw {@code Record}s. + * Each {@link Message} will contain {@code List} ( if not empty) of converted or raw + * {@code Record}s. */ batch diff --git a/src/main/java/org/springframework/integration/aws/inbound/kinesis/ShardCheckpointer.java b/src/main/java/org/springframework/integration/aws/inbound/kinesis/ShardCheckpointer.java index d657f58..9b6c90e 100644 --- a/src/main/java/org/springframework/integration/aws/inbound/kinesis/ShardCheckpointer.java +++ b/src/main/java/org/springframework/integration/aws/inbound/kinesis/ShardCheckpointer.java @@ -25,14 +25,13 @@ import org.springframework.integration.metadata.ConcurrentMetadataStore; import org.springframework.integration.metadata.MetadataStore; /** - * An internal {@link Checkpointer} implementation based on - * provided {@link MetadataStore} and {@code key} for shard. + * An internal {@link Checkpointer} implementation based on provided {@link MetadataStore} + * and {@code key} for shard. *

- * The instances of this class is created by the {@link KinesisMessageDrivenChannelAdapter} - * for each {@code ShardConsumer}. + * The instances of this class is created by the + * {@link KinesisMessageDrivenChannelAdapter} for each {@code ShardConsumer}. * * @author Artem Bilan - * * @since 1.1 */ class ShardCheckpointer implements Checkpointer { @@ -61,8 +60,8 @@ class ShardCheckpointer implements Checkpointer { public boolean checkpoint(String sequenceNumber) { if (this.active) { String existingSequence = getCheckpoint(); - if (existingSequence == null || - new BigInteger(existingSequence).compareTo(new BigInteger(sequenceNumber)) < 0) { + if (existingSequence == null + || new BigInteger(existingSequence).compareTo(new BigInteger(sequenceNumber)) < 0) { if (existingSequence != null) { return this.checkpointStore.replace(this.key, existingSequence, sequenceNumber); } @@ -102,10 +101,8 @@ class ShardCheckpointer implements Checkpointer { @Override public String toString() { - return "ShardCheckpointer{" + - "key='" + this.key + '\'' + - ", lastCheckpointValue='" + this.lastCheckpointValue + '\'' + - '}'; + return "ShardCheckpointer{" + "key='" + this.key + '\'' + ", lastCheckpointValue='" + this.lastCheckpointValue + + '\'' + '}'; } } diff --git a/src/main/java/org/springframework/integration/aws/lock/DynamoDbLockRegistry.java b/src/main/java/org/springframework/integration/aws/lock/DynamoDbLockRegistry.java index 84e80af..703313a 100644 --- a/src/main/java/org/springframework/integration/aws/lock/DynamoDbLockRegistry.java +++ b/src/main/java/org/springframework/integration/aws/lock/DynamoDbLockRegistry.java @@ -54,14 +54,14 @@ import com.amazonaws.services.dynamodbv2.model.LockTableDoesNotExistException; import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; /** - * An {@link ExpirableLockRegistry} implementation for the AWS DynamoDB. - * The algorithm is based on the {@link AmazonDynamoDBLockClient}. + * An {@link ExpirableLockRegistry} implementation for the AWS DynamoDB. The algorithm is + * based on the {@link AmazonDynamoDBLockClient}. *

- * Can create table in DynamoDB if an external {@link AmazonDynamoDBLockClient} is not provided. + * Can create table in DynamoDB if an external {@link AmazonDynamoDBLockClient} is not + * provided. * * @author Artem Bilan * @author Karl Lessard - * * @since 2.0 */ public class DynamoDbLockRegistry implements ExpirableLockRegistry, InitializingBean, DisposableBean { @@ -72,7 +72,8 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing public static final String DEFAULT_TABLE_NAME = "SpringIntegrationLockRegistry"; /** - * The {@value DEFAULT_PARTITION_KEY_NAME} default name for the partition key in the table. + * The {@value DEFAULT_PARTITION_KEY_NAME} default name for the partition key in the + * table. */ public static final String DEFAULT_PARTITION_KEY_NAME = "lockKey"; @@ -87,7 +88,8 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing public static final String DEFAULT_SORT_KEY = "SpringIntegrationLocks"; /** - * The {@value DEFAULT_REFRESH_PERIOD_MS} default period in milliseconds between DB polling requests. + * The {@value DEFAULT_REFRESH_PERIOD_MS} default period in milliseconds between DB + * polling requests. */ public static final long DEFAULT_REFRESH_PERIOD_MS = 1000L; @@ -124,11 +126,11 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing private long heartbeatPeriod = 5L; /** - * An {@link ExecutorService} to call {@link AmazonDynamoDBLockClient#releaseLock(LockItem)} - * in the separate thread when the current one is interrupted. + * An {@link ExecutorService} to call + * {@link AmazonDynamoDBLockClient#releaseLock(LockItem)} in the separate thread when + * the current one is interrupted. */ - private Executor executor = - Executors.newCachedThreadPool(new CustomizableThreadFactory("dynamodb-lock-registry-")); + private Executor executor = Executors.newCachedThreadPool(new CustomizableThreadFactory("dynamodb-lock-registry-")); /** * Flag to denote whether the {@link ExecutorService} was provided via the setter and @@ -138,7 +140,6 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing private volatile boolean initialized; - public DynamoDbLockRegistry(AmazonDynamoDB dynamoDB) { this(dynamoDB, DEFAULT_TABLE_NAME); } @@ -202,8 +203,8 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing } /** - * Set the {@link Executor}, where is not provided then a default of - * cached thread pool Executor will be used. + * Set the {@link Executor}, where is not provided then a default of cached thread + * pool Executor will be used. * @param executor the executor service */ public void setExecutor(Executor executor) { @@ -214,22 +215,16 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing @Override public void afterPropertiesSet() { if (!this.dynamoDBLockClientExplicitlySet) { - AmazonDynamoDBLockClientOptions dynamoDBLockClientOptions = - AmazonDynamoDBLockClientOptions - .builder(this.dynamoDB, this.tableName) - .withPartitionKeyName(this.partitionKey) - .withSortKeyName(this.sortKeyName) - .withHeartbeatPeriod(this.heartbeatPeriod) - .withLeaseDuration(this.leaseDuration) - .build(); + AmazonDynamoDBLockClientOptions dynamoDBLockClientOptions = AmazonDynamoDBLockClientOptions + .builder(this.dynamoDB, this.tableName).withPartitionKeyName(this.partitionKey) + .withSortKeyName(this.sortKeyName).withHeartbeatPeriod(this.heartbeatPeriod) + .withLeaseDuration(this.leaseDuration).build(); this.dynamoDBLockClient = new AmazonDynamoDBLockClient(dynamoDBLockClientOptions); } - this.leaseDuration = - (long) new DirectFieldAccessor(this.dynamoDBLockClient) - .getPropertyValue("leaseDurationInMilliseconds"); - + this.leaseDuration = (long) new DirectFieldAccessor(this.dynamoDBLockClient) + .getPropertyValue("leaseDurationInMilliseconds"); this.executor.execute(() -> { try { @@ -244,14 +239,10 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing } } - CreateDynamoDBTableOptions createDynamoDBTableOptions = - CreateDynamoDBTableOptions - .builder(this.dynamoDB, - new ProvisionedThroughput(this.readCapacity, this.writeCapacity), - this.tableName) - .withPartitionKeyName(this.partitionKey) - .withSortKeyName(this.sortKeyName) - .build(); + CreateDynamoDBTableOptions createDynamoDBTableOptions = CreateDynamoDBTableOptions + .builder(this.dynamoDB, new ProvisionedThroughput(this.readCapacity, this.writeCapacity), + this.tableName) + .withPartitionKeyName(this.partitionKey).withSortKeyName(this.sortKeyName).build(); AmazonDynamoDBLockClient.createLockTableInDynamoDB(createDynamoDBTableOptions); } @@ -278,7 +269,8 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing finally { // Release create table barrier either way. // If there is an error during creation/description, - // we deffer the actual ResourceNotFoundException to the end-user active calls. + // we deffer the actual ResourceNotFoundException to the end-user active + // calls. this.createTableLatch.countDown(); } }); @@ -287,12 +279,11 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing } private void awaitForActive() { - Assert.state(this.initialized, () -> "The component has not been initialized: " + this + - ".\n Is it declared as a bean?"); + Assert.state(this.initialized, + () -> "The component has not been initialized: " + this + ".\n Is it declared as a bean?"); - IllegalStateException illegalStateException = - new IllegalStateException( - "The DynamoDb table " + this.tableName + " has not been created during " + 60 + " seconds"); + IllegalStateException illegalStateException = new IllegalStateException( + "The DynamoDb table " + this.tableName + " has not been created during " + 60 + " seconds"); try { if (!this.createTableLatch.await(60, TimeUnit.SECONDS)) { throw illegalStateException; @@ -336,16 +327,11 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing @Override public String toString() { - return "DynamoDbLockRegistry{" + "tableName='" + this.tableName + '\'' + - ", readCapacity=" + this.readCapacity + - ", writeCapacity=" + this.writeCapacity + - ", partitionKey='" + this.partitionKey + '\'' + - ", sortKeyName='" + this.sortKeyName + '\'' + - ", sortKey='" + this.sortKey + '\'' + - ", refreshPeriod=" + this.refreshPeriod + - ", leaseDuration=" + this.leaseDuration + - ", heartbeatPeriod=" + this.heartbeatPeriod + - '}'; + return "DynamoDbLockRegistry{" + "tableName='" + this.tableName + '\'' + ", readCapacity=" + this.readCapacity + + ", writeCapacity=" + this.writeCapacity + ", partitionKey='" + this.partitionKey + '\'' + + ", sortKeyName='" + this.sortKeyName + '\'' + ", sortKey='" + this.sortKey + '\'' + ", refreshPeriod=" + + this.refreshPeriod + ", leaseDuration=" + this.leaseDuration + ", heartbeatPeriod=" + + this.heartbeatPeriod + '}'; } private final class DynamoDbLock implements Lock { @@ -354,7 +340,8 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing private final String key; - // It is safe to use a shared instance - access is guaranteed by the delegate lock. + // It is safe to use a shared instance - access is guaranteed by the delegate + // lock. private final AcquireLockOptions.AcquireLockOptionsBuilder acquireLockOptionsBuilder; private LockItem lockItem; @@ -363,11 +350,8 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing private DynamoDbLock(String key) { this.key = key; - this.acquireLockOptionsBuilder = - AcquireLockOptions.builder(this.key) - .withReplaceData(false) - .withSortKey(DynamoDbLockRegistry.this.sortKey) - .withTimeUnit(TimeUnit.MILLISECONDS); + this.acquireLockOptionsBuilder = AcquireLockOptions.builder(this.key).withReplaceData(false) + .withSortKey(DynamoDbLockRegistry.this.sortKey).withTimeUnit(TimeUnit.MILLISECONDS); } private void rethrowAsLockException(Exception e) { @@ -388,15 +372,15 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing while (true) { try { while (!doLock()) { - Thread.sleep(100); //NOSONAR + Thread.sleep(100); // NOSONAR } break; } catch (InterruptedException e) { /* * This method must be uninterruptible so catch and ignore - * interrupts and only break out of the while loop when - * we get the lock. + * interrupts and only break out of the while loop when we get the + * lock. */ wasInterruptedWhileUninterruptible = true; } @@ -430,7 +414,7 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing try { while (!doLock()) { - Thread.sleep(100); //NOSONAR + Thread.sleep(100); // NOSONAR if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } @@ -468,10 +452,10 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing return false; } - long additionalTimeToWait = Math.max(TimeUnit.MILLISECONDS.convert(time, unit) - System.currentTimeMillis() + start, 0L); + long additionalTimeToWait = Math + .max(TimeUnit.MILLISECONDS.convert(time, unit) - System.currentTimeMillis() + start, 0L); - this.acquireLockOptionsBuilder - .withAdditionalTimeToWaitForLock(additionalTimeToWait) + this.acquireLockOptionsBuilder.withAdditionalTimeToWaitForLock(additionalTimeToWait) .withRefreshPeriod(DynamoDbLockRegistry.this.refreshPeriod); boolean acquired = false; @@ -500,10 +484,8 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing acquired = true; } else { - this.lockItem = - DynamoDbLockRegistry.this.dynamoDBLockClient - .tryAcquireLock(this.acquireLockOptionsBuilder.build()) - .orElse(null); + this.lockItem = DynamoDbLockRegistry.this.dynamoDBLockClient + .tryAcquireLock(this.acquireLockOptionsBuilder.build()).orElse(null); acquired = this.lockItem != null; } @@ -527,9 +509,8 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing try { if (Thread.currentThread().isInterrupted()) { LockItem lockItemToRelease = this.lockItem; - DynamoDbLockRegistry.this.executor.execute(() -> - DynamoDbLockRegistry.this.dynamoDBLockClient.releaseLock(lockItemToRelease) - ); + DynamoDbLockRegistry.this.executor + .execute(() -> DynamoDbLockRegistry.this.dynamoDBLockClient.releaseLock(lockItemToRelease)); } else { DynamoDbLockRegistry.this.dynamoDBLockClient.releaseLock(this.lockItem); @@ -552,10 +533,8 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing @Override public String toString() { SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd@HH:mm:ss.SSS"); - return "DynamoDbLock [lockKey=" + this.key - + ",lockedAt=" + dateFormat.format(new Date(this.lastUsed)) - + ", lockItem=" + this.lockItem - + "]"; + return "DynamoDbLock [lockKey=" + this.key + ",lockedAt=" + dateFormat.format(new Date(this.lastUsed)) + + ", lockItem=" + this.lockItem + "]"; } } diff --git a/src/main/java/org/springframework/integration/aws/metadata/DynamoDbMetadataStore.java b/src/main/java/org/springframework/integration/aws/metadata/DynamoDbMetadataStore.java index e574c08..2b7e0db 100644 --- a/src/main/java/org/springframework/integration/aws/metadata/DynamoDbMetadataStore.java +++ b/src/main/java/org/springframework/integration/aws/metadata/DynamoDbMetadataStore.java @@ -61,13 +61,13 @@ import com.amazonaws.waiters.WaiterParameters; * The {@link ConcurrentMetadataStore} for the {@link AmazonDynamoDB}. * * @author Artem Bilan - * * @since 1.1 */ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, InitializingBean { /** - * The {@value DEFAULT_TABLE_NAME} default name for the metadata table in the DynamoDB. + * The {@value DEFAULT_TABLE_NAME} default name for the metadata table in the + * DynamoDB. */ public static final String DEFAULT_TABLE_NAME = "SpringIntegrationMetadataStore"; @@ -105,9 +105,7 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ Assert.notNull(dynamoDB, "'dynamoDB' must not be null."); Assert.hasText(tableName, "'tableName' must not be empty."); this.dynamoDB = dynamoDB; - this.table = - new DynamoDB(this.dynamoDB) - .getTable(tableName); + this.table = new DynamoDB(this.dynamoDB).getTable(tableName); } @@ -128,11 +126,13 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ } /** - * Configure a period in seconds for items expiration. - * If it is configured to non-positive value ({@code <= 0}), the TTL is disabled on the table. + * Configure a period in seconds for items expiration. If it is configured to + * non-positive value ({@code <= 0}), the TTL is disabled on the table. * @param timeToLive period in seconds for items expiration. * @since 2.0 - * @see DynamoDB TTL + * @see DynamoDB + * TTL */ public void setTimeToLive(int timeToLive) { this.timeToLive = timeToLive; @@ -153,37 +153,34 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ } } - CreateTableRequest createTableRequest = - new CreateTableRequest() - .withTableName(this.table.getTableName()) - .withKeySchema(new KeySchemaElement(KEY, KeyType.HASH)) - .withAttributeDefinitions(new AttributeDefinition(KEY, ScalarAttributeType.S)) - .withProvisionedThroughput(new ProvisionedThroughput(this.readCapacity, this.writeCapacity)); - + CreateTableRequest createTableRequest = new CreateTableRequest().withTableName(this.table.getTableName()) + .withKeySchema(new KeySchemaElement(KEY, KeyType.HASH)) + .withAttributeDefinitions(new AttributeDefinition(KEY, ScalarAttributeType.S)) + .withProvisionedThroughput(new ProvisionedThroughput(this.readCapacity, this.writeCapacity)); this.dynamoDB.createTableAsync(createTableRequest, new AsyncHandler() { @Override public void onError(Exception e) { - logger.error("Cannot create DynamoDb table: " + - DynamoDbMetadataStore.this.table.getTableName(), e); + logger.error( + "Cannot create DynamoDb table: " + DynamoDbMetadataStore.this.table.getTableName(), + e); DynamoDbMetadataStore.this.createTableLatch.countDown(); } @Override public void onSuccess(CreateTableRequest request, CreateTableResult createTableResult) { - Waiter waiter = - DynamoDbMetadataStore.this.dynamoDB.waiters() - .tableExists(); + Waiter waiter = DynamoDbMetadataStore.this.dynamoDB.waiters() + .tableExists(); - WaiterParameters waiterParameters = - new WaiterParameters<>( - new DescribeTableRequest(DynamoDbMetadataStore.this.table.getTableName())) - .withPollingStrategy( - new PollingStrategy( - new MaxAttemptsRetryStrategy(DynamoDbMetadataStore.this.createTableRetries), - new FixedDelayStrategy(DynamoDbMetadataStore.this.createTableDelay))); + WaiterParameters waiterParameters = new WaiterParameters<>( + new DescribeTableRequest(DynamoDbMetadataStore.this.table.getTableName())) + .withPollingStrategy(new PollingStrategy( + new MaxAttemptsRetryStrategy( + DynamoDbMetadataStore.this.createTableRetries), + new FixedDelayStrategy( + DynamoDbMetadataStore.this.createTableDelay))); waiter.runAsync(waiterParameters, new WaiterHandler() { @@ -196,8 +193,8 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ @Override public void onWaitFailure(Exception e) { - logger.error("Cannot describe DynamoDb table: " + - DynamoDbMetadataStore.this.table.getTableName(), e); + logger.error("Cannot describe DynamoDb table: " + + DynamoDbMetadataStore.this.table.getTableName(), e); DynamoDbMetadataStore.this.createTableLatch.countDown(); } @@ -213,13 +210,9 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ private void updateTimeToLiveIfAny() { if (this.timeToLive != null) { - UpdateTimeToLiveRequest updateTimeToLiveRequest = - new UpdateTimeToLiveRequest() - .withTableName(this.table.getTableName()) - .withTimeToLiveSpecification( - new TimeToLiveSpecification() - .withAttributeName(TTL) - .withEnabled(this.timeToLive > 0)); + UpdateTimeToLiveRequest updateTimeToLiveRequest = new UpdateTimeToLiveRequest() + .withTableName(this.table.getTableName()).withTimeToLiveSpecification( + new TimeToLiveSpecification().withAttributeName(TTL).withEnabled(this.timeToLive > 0)); try { this.dynamoDB.updateTimeToLive(updateTimeToLiveRequest); @@ -233,15 +226,15 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ } private void awaitForActive() { - Assert.state(this.initialized, () -> "The component has not been initialized: " + this + - ".\n Is it declared as a bean?"); + Assert.state(this.initialized, + () -> "The component has not been initialized: " + this + ".\n Is it declared as a bean?"); try { this.createTableLatch.await(this.createTableRetries * this.createTableDelay, TimeUnit.SECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new IllegalStateException("The DynamoDb table " + this.table.getTableName() + - " has not been created during " + this.createTableRetries * this.createTableDelay + " seconds"); + throw new IllegalStateException("The DynamoDb table " + this.table.getTableName() + + " has not been created during " + this.createTableRetries * this.createTableDelay + " seconds"); } } @@ -252,10 +245,7 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ awaitForActive(); - Item item = - new Item() - .withPrimaryKey(KEY, key) - .withString(VALUE, value); + Item item = new Item().withPrimaryKey(KEY, key).withString(VALUE, value); if (this.timeToLive != null && this.timeToLive > 0) { item = item.withLong(TTL, (System.currentTimeMillis() + this.timeToLive) / 1000); @@ -282,21 +272,12 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ awaitForActive(); - UpdateItemSpec updateItemSpec = - new UpdateItemSpec() - .withPrimaryKey(KEY, key) - .withAttributeUpdate( - new AttributeUpdate(VALUE) - .put(value)) - .withExpected( - new Expected(KEY) - .notExist()); + UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey(KEY, key) + .withAttributeUpdate(new AttributeUpdate(VALUE).put(value)).withExpected(new Expected(KEY).notExist()); if (this.timeToLive != null && this.timeToLive > 0) { - updateItemSpec = - updateItemSpec.addAttributeUpdate( - new AttributeUpdate(TTL) - .put((System.currentTimeMillis() + this.timeToLive) / 1000)); + updateItemSpec = updateItemSpec.addAttributeUpdate( + new AttributeUpdate(TTL).put((System.currentTimeMillis() + this.timeToLive) / 1000)); } try { @@ -316,27 +297,17 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ awaitForActive(); - UpdateItemSpec updateItemSpec = - new UpdateItemSpec() - .withPrimaryKey(KEY, key) - .withAttributeUpdate( - new AttributeUpdate(VALUE) - .put(newValue)) - .withExpected( - new Expected(VALUE) - .eq(oldValue)) - .withReturnValues(ReturnValue.UPDATED_NEW); + UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey(KEY, key) + .withAttributeUpdate(new AttributeUpdate(VALUE).put(newValue)) + .withExpected(new Expected(VALUE).eq(oldValue)).withReturnValues(ReturnValue.UPDATED_NEW); if (this.timeToLive != null && this.timeToLive > 0) { - updateItemSpec = - updateItemSpec.addAttributeUpdate( - new AttributeUpdate(TTL) - .put((System.currentTimeMillis() + this.timeToLive) / 1000)); + updateItemSpec = updateItemSpec.addAttributeUpdate( + new AttributeUpdate(TTL).put((System.currentTimeMillis() + this.timeToLive) / 1000)); } try { - return this.table.updateItem(updateItemSpec) - .getItem() != null; + return this.table.updateItem(updateItemSpec).getItem() != null; } catch (ConditionalCheckFailedException e) { return false; @@ -349,12 +320,9 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ awaitForActive(); - Item item = - this.table.deleteItem( - new DeleteItemSpec() - .withPrimaryKey(KEY, key) - .withReturnValues(ReturnValue.ALL_OLD)) - .getItem(); + Item item = this.table + .deleteItem(new DeleteItemSpec().withPrimaryKey(KEY, key).withReturnValues(ReturnValue.ALL_OLD)) + .getItem(); return getValueIfAny(item); } @@ -370,12 +338,9 @@ public class DynamoDbMetadataStore implements ConcurrentMetadataStore, Initializ @Override public String toString() { - return "DynamoDbMetadataStore{" + "table=" + this.table + - ", createTableRetries=" + this.createTableRetries + - ", createTableDelay=" + this.createTableDelay + - ", readCapacity=" + this.readCapacity + - ", writeCapacity=" + this.writeCapacity + - ", timeToLive=" + this.timeToLive + - '}'; + return "DynamoDbMetadataStore{" + "table=" + this.table + ", createTableRetries=" + this.createTableRetries + + ", createTableDelay=" + this.createTableDelay + ", readCapacity=" + this.readCapacity + + ", writeCapacity=" + this.writeCapacity + ", timeToLive=" + this.timeToLive + '}'; } + } diff --git a/src/main/java/org/springframework/integration/aws/outbound/AbstractAwsMessageHandler.java b/src/main/java/org/springframework/integration/aws/outbound/AbstractAwsMessageHandler.java index 0f329cb..b01d23d 100644 --- a/src/main/java/org/springframework/integration/aws/outbound/AbstractAwsMessageHandler.java +++ b/src/main/java/org/springframework/integration/aws/outbound/AbstractAwsMessageHandler.java @@ -42,14 +42,12 @@ import com.amazonaws.AmazonWebServiceRequest; import com.amazonaws.handlers.AsyncHandler; /** - * The base {@link AbstractMessageProducingHandler} for AWS services. - * Utilizes common logic ({@link AsyncHandler}, {@link ErrorMessageStrategy}, - * {@code failureChannel} etc.) and message pre- and post-processing, + * The base {@link AbstractMessageProducingHandler} for AWS services. Utilizes common + * logic ({@link AsyncHandler}, {@link ErrorMessageStrategy}, {@code failureChannel} etc.) + * and message pre- and post-processing, * * @param the headers container type. - * * @author Artem Bilan - * * @since 2.0 */ public abstract class AbstractAwsMessageHandler extends AbstractMessageProducingHandler { @@ -106,9 +104,9 @@ public abstract class AbstractAwsMessageHandler extends AbstractMessageProduc } /** - * Set the failure channel. After a failure on put, an {@link ErrorMessage} will be sent - * to this channel with a payload of a {@link AwsRequestFailureException} with the - * failed message and cause. + * Set the failure channel. After a failure on put, an {@link ErrorMessage} will be + * sent to this channel with a payload of a {@link AwsRequestFailureException} with + * the failed message and cause. * @param failureChannel the failure channel. */ public void setFailureChannel(MessageChannel failureChannel) { @@ -116,8 +114,8 @@ public abstract class AbstractAwsMessageHandler extends AbstractMessageProduc } /** - * Set the failure channel name. After a failure on put, an {@link ErrorMessage} will be - * sent to this channel name with a payload of a {@link AwsRequestFailureException} + * Set the failure channel name. After a failure on put, an {@link ErrorMessage} will + * be sent to this channel name with a payload of a {@link AwsRequestFailureException} * with the failed message and cause. * @param failureChannelName the failure channel name. */ @@ -213,9 +211,8 @@ public abstract class AbstractAwsMessageHandler extends AbstractMessageProduc } if (getFailureChannel() != null) { - AbstractAwsMessageHandler.this.messagingTemplate.send(getFailureChannel(), - getErrorMessageStrategy() - .buildErrorMessage(new AwsRequestFailureException(message, request, ex), null)); + AbstractAwsMessageHandler.this.messagingTemplate.send(getFailureChannel(), getErrorMessageStrategy() + .buildErrorMessage(new AwsRequestFailureException(message, request, ex), null)); } } @@ -227,15 +224,13 @@ public abstract class AbstractAwsMessageHandler extends AbstractMessageProduc } if (getOutputChannel() != null) { - AbstractIntegrationMessageBuilder messageBuilder = - getMessageBuilderFactory() - .fromMessage(message); + AbstractIntegrationMessageBuilder messageBuilder = getMessageBuilderFactory() + .fromMessage(message); additionalOnSuccessHeaders(messageBuilder, request, result); messageBuilder.setHeaderIfAbsent(AwsHeaders.SERVICE_RESULT, result); - AbstractAwsMessageHandler.this.messagingTemplate.send(getOutputChannel(), messageBuilder.build()); } } diff --git a/src/main/java/org/springframework/integration/aws/outbound/KinesisMessageHandler.java b/src/main/java/org/springframework/integration/aws/outbound/KinesisMessageHandler.java index 7790f2e..778a8de 100644 --- a/src/main/java/org/springframework/integration/aws/outbound/KinesisMessageHandler.java +++ b/src/main/java/org/springframework/integration/aws/outbound/KinesisMessageHandler.java @@ -44,13 +44,12 @@ import com.amazonaws.services.kinesis.model.PutRecordsRequest; import com.amazonaws.services.kinesis.model.PutRecordsResult; /** - * The {@link AbstractMessageHandler} implementation for the Amazon Kinesis {@code putRecord(s)}. + * The {@link AbstractMessageHandler} implementation for the Amazon Kinesis + * {@code putRecord(s)}. * * @author Artem Bilan * @author Jacob Severson - * * @since 1.1 - * * @see AmazonKinesisAsync#putRecord(PutRecordRequest) * @see AmazonKinesisAsync#putRecords(PutRecordsRequest) * @see com.amazonaws.handlers.AsyncHandler @@ -77,8 +76,8 @@ public class KinesisMessageHandler extends AbstractAwsMessageHandler { } /** - * Specify a {@link Converter} to serialize {@code payload} to the {@code byte[]} - * if that isn't {@code byte[]} already. + * Specify a {@link Converter} to serialize {@code payload} to the {@code byte[]} if + * that isn't {@code byte[]} already. * @param converter the {@link Converter} to use; cannot be null. */ public void setConverter(Converter converter) { @@ -131,9 +130,10 @@ public class KinesisMessageHandler extends AbstractAwsMessageHandler { } /** - * Specify a {@link OutboundMessageMapper} for embedding message headers into the record data - * together with payload. - * @param embeddedHeadersMapper the {@link OutboundMessageMapper} to embed headers into the record data. + * Specify a {@link OutboundMessageMapper} for embedding message headers into the + * record data together with payload. + * @param embeddedHeadersMapper the {@link OutboundMessageMapper} to embed headers + * into the record data. * @since 2.0 * @see org.springframework.integration.support.json.EmbeddedJsonHeadersMessageMapper */ @@ -148,26 +148,24 @@ public class KinesisMessageHandler extends AbstractAwsMessageHandler { */ @Override public void setHeaderMapper(HeaderMapper headerMapper) { - throw new UnsupportedOperationException("Kinesis doesn't support headers.\n" + - "Consider to use 'OutboundMessageMapper' for embedding headers into the record data."); + throw new UnsupportedOperationException("Kinesis doesn't support headers.\n" + + "Consider to use 'OutboundMessageMapper' for embedding headers into the record data."); } @Override protected Future handleMessageToAws(Message message) { if (message.getPayload() instanceof PutRecordsRequest) { - AsyncHandler asyncHandler = - obtainAsyncHandler(message, (PutRecordsRequest) message.getPayload()); + AsyncHandler asyncHandler = obtainAsyncHandler(message, + (PutRecordsRequest) message.getPayload()); return this.amazonKinesis.putRecordsAsync((PutRecordsRequest) message.getPayload(), asyncHandler); } else { - final PutRecordRequest putRecordRequest = - (message.getPayload() instanceof PutRecordRequest) - ? (PutRecordRequest) message.getPayload() - : buildPutRecordRequest(message); + final PutRecordRequest putRecordRequest = (message.getPayload() instanceof PutRecordRequest) + ? (PutRecordRequest) message.getPayload() : buildPutRecordRequest(message); - AsyncHandler asyncHandler = - obtainAsyncHandler(message, putRecordRequest); + AsyncHandler asyncHandler = obtainAsyncHandler(message, + putRecordRequest); return this.amazonKinesis.putRecordAsync(putRecordRequest, asyncHandler); } @@ -179,22 +177,21 @@ public class KinesisMessageHandler extends AbstractAwsMessageHandler { if (!StringUtils.hasText(stream) && this.streamExpression != null) { stream = this.streamExpression.getValue(getEvaluationContext(), message, String.class); } - Assert.state(stream != null, "'stream' must not be null for sending a Kinesis record. " + - "Consider configuring this handler with a 'stream'( or 'streamExpression') or supply an " + - "'aws_stream' message header."); + Assert.state(stream != null, + "'stream' must not be null for sending a Kinesis record. " + + "Consider configuring this handler with a 'stream'( or 'streamExpression') or supply an " + + "'aws_stream' message header."); String partitionKey = messageHeaders.get(AwsHeaders.PARTITION_KEY, String.class); if (!StringUtils.hasText(partitionKey) && this.partitionKeyExpression != null) { partitionKey = this.partitionKeyExpression.getValue(getEvaluationContext(), message, String.class); } - Assert.state(partitionKey != null, "'partitionKey' must not be null for sending a Kinesis record. " + - "Consider configuring this handler with a 'partitionKey'( or 'partitionKeyExpression') or supply an " + - "'aws_partitionKey' message header."); + Assert.state(partitionKey != null, "'partitionKey' must not be null for sending a Kinesis record. " + + "Consider configuring this handler with a 'partitionKey'( or 'partitionKeyExpression') or supply an " + + "'aws_partitionKey' message header."); - String explicitHashKey = - (this.explicitHashKeyExpression != null - ? this.explicitHashKeyExpression.getValue(getEvaluationContext(), message, String.class) - : null); + String explicitHashKey = (this.explicitHashKeyExpression != null + ? this.explicitHashKeyExpression.getValue(getEvaluationContext(), message, String.class) : null); String sequenceNumber = messageHeaders.get(AwsHeaders.SEQUENCE_NUMBER, String.class); if (!StringUtils.hasText(sequenceNumber) && this.sequenceNumberExpression != null) { @@ -214,10 +211,7 @@ public class KinesisMessageHandler extends AbstractAwsMessageHandler { } } else { - byte[] bytes = - payload instanceof byte[] - ? (byte[]) payload - : this.converter.convert(payload); + byte[] bytes = payload instanceof byte[] ? (byte[]) payload : this.converter.convert(payload); Assert.notNull(bytes, "payload cannot be null"); if (this.embeddedHeadersMapper != null) { messageToEmbed = new MutableMessage<>(bytes, messageHeaders); @@ -238,12 +232,8 @@ public class KinesisMessageHandler extends AbstractAwsMessageHandler { } } - return new PutRecordRequest() - .withStreamName(stream) - .withPartitionKey(partitionKey) - .withExplicitHashKey(explicitHashKey) - .withSequenceNumberForOrdering(sequenceNumber) - .withData(data); + return new PutRecordRequest().withStreamName(stream).withPartitionKey(partitionKey) + .withExplicitHashKey(explicitHashKey).withSequenceNumberForOrdering(sequenceNumber).withData(data); } @Override @@ -251,11 +241,9 @@ public class KinesisMessageHandler extends AbstractAwsMessageHandler { AmazonWebServiceRequest request, Object result) { if (result instanceof PutRecordResult) { - messageBuilder - .setHeader(AwsHeaders.SHARD, ((PutRecordResult) result).getShardId()) + messageBuilder.setHeader(AwsHeaders.SHARD, ((PutRecordResult) result).getShardId()) .setHeader(AwsHeaders.SEQUENCE_NUMBER, ((PutRecordResult) result).getSequenceNumber()); } } } - diff --git a/src/main/java/org/springframework/integration/aws/outbound/KplMessageHandler.java b/src/main/java/org/springframework/integration/aws/outbound/KplMessageHandler.java index 1a4c39b..f2863cb 100644 --- a/src/main/java/org/springframework/integration/aws/outbound/KplMessageHandler.java +++ b/src/main/java/org/springframework/integration/aws/outbound/KplMessageHandler.java @@ -51,13 +51,12 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; /** - * The {@link AbstractMessageHandler} implementation for the Amazon Kinesis Producer Library {@code putRecord(s)}. + * The {@link AbstractMessageHandler} implementation for the Amazon Kinesis Producer + * Library {@code putRecord(s)}. * * @author Arnaud Lecollaire * @author Artem Bilan - * * @since 2.2.0 - * * @see AmazonKinesisAsync#putRecord(PutRecordRequest) * @see AmazonKinesisAsync#putRecords(PutRecordsRequest) * @see com.amazonaws.handlers.AsyncHandler @@ -84,8 +83,8 @@ public class KplMessageHandler extends AbstractAwsMessageHandler { } /** - * Specify a {@link Converter} to serialize {@code payload} to the {@code byte[]} - * if that isn't {@code byte[]} already. + * Specify a {@link Converter} to serialize {@code payload} to the {@code byte[]} if + * that isn't {@code byte[]} already. * @param converter the {@link Converter} to use; cannot be null. */ public void setConverter(Converter converter) { @@ -138,9 +137,10 @@ public class KplMessageHandler extends AbstractAwsMessageHandler { } /** - * Specify a {@link OutboundMessageMapper} for embedding message headers into the record data - * together with payload. - * @param embeddedHeadersMapper the {@link OutboundMessageMapper} to embed headers into the record data. + * Specify a {@link OutboundMessageMapper} for embedding message headers into the + * record data together with payload. + * @param embeddedHeadersMapper the {@link OutboundMessageMapper} to embed headers + * into the record data. * @since 2.0 * @see org.springframework.integration.support.json.EmbeddedJsonHeadersMessageMapper */ @@ -155,8 +155,8 @@ public class KplMessageHandler extends AbstractAwsMessageHandler { */ @Override public void setHeaderMapper(HeaderMapper headerMapper) { - throw new UnsupportedOperationException("Kinesis doesn't support headers.\n" + - "Consider to use 'OutboundMessageMapper' for embedding headers into the record data."); + throw new UnsupportedOperationException("Kinesis doesn't support headers.\n" + + "Consider to use 'OutboundMessageMapper' for embedding headers into the record data."); } @Override @@ -168,10 +168,8 @@ public class KplMessageHandler extends AbstractAwsMessageHandler { return handleUserRecord(message, buildPutRecordRequest(message), (UserRecord) message.getPayload()); } else { - final PutRecordRequest putRecordRequest = - (message.getPayload() instanceof PutRecordRequest) - ? (PutRecordRequest) message.getPayload() - : buildPutRecordRequest(message); + final PutRecordRequest putRecordRequest = (message.getPayload() instanceof PutRecordRequest) + ? (PutRecordRequest) message.getPayload() : buildPutRecordRequest(message); // convert the PutRecordRequest to a UserRecord UserRecord userRecord = new UserRecord(); @@ -187,16 +185,14 @@ public class KplMessageHandler extends AbstractAwsMessageHandler { UserRecord userRecord) { ListenableFuture recordResult = this.kinesisProducer.addUserRecord(userRecord); - final AsyncHandler asyncHandler = - obtainAsyncHandler(message, putRecordRequest); + final AsyncHandler asyncHandler = obtainAsyncHandler(message, + putRecordRequest); final FutureCallback callback = new FutureCallback() { @Override public void onFailure(Throwable ex) { - asyncHandler - .onError(ex instanceof Exception ? - (Exception) ex : - new AwsRequestFailureException(message, putRecordRequest, ex)); + asyncHandler.onError(ex instanceof Exception ? (Exception) ex + : new AwsRequestFailureException(message, putRecordRequest, ex)); } @Override @@ -215,22 +211,21 @@ public class KplMessageHandler extends AbstractAwsMessageHandler { if (!StringUtils.hasText(stream) && this.streamExpression != null) { stream = this.streamExpression.getValue(getEvaluationContext(), message, String.class); } - Assert.state(stream != null, "'stream' must not be null for sending a Kinesis record. " + - "Consider configuring this handler with a 'stream'( or 'streamExpression') or supply an " + - "'aws_stream' message header."); + Assert.state(stream != null, + "'stream' must not be null for sending a Kinesis record. " + + "Consider configuring this handler with a 'stream'( or 'streamExpression') or supply an " + + "'aws_stream' message header."); String partitionKey = messageHeaders.get(AwsHeaders.PARTITION_KEY, String.class); if (!StringUtils.hasText(partitionKey) && this.partitionKeyExpression != null) { partitionKey = this.partitionKeyExpression.getValue(getEvaluationContext(), message, String.class); } - Assert.state(partitionKey != null, "'partitionKey' must not be null for sending a Kinesis record. " + - "Consider configuring this handler with a 'partitionKey'( or 'partitionKeyExpression') or supply an " + - "'aws_partitionKey' message header."); + Assert.state(partitionKey != null, "'partitionKey' must not be null for sending a Kinesis record. " + + "Consider configuring this handler with a 'partitionKey'( or 'partitionKeyExpression') or supply an " + + "'aws_partitionKey' message header."); - String explicitHashKey = - (this.explicitHashKeyExpression != null - ? this.explicitHashKeyExpression.getValue(getEvaluationContext(), message, String.class) - : null); + String explicitHashKey = (this.explicitHashKeyExpression != null + ? this.explicitHashKeyExpression.getValue(getEvaluationContext(), message, String.class) : null); String sequenceNumber = messageHeaders.get(AwsHeaders.SEQUENCE_NUMBER, String.class); if (!StringUtils.hasText(sequenceNumber) && this.sequenceNumberExpression != null) { @@ -250,10 +245,7 @@ public class KplMessageHandler extends AbstractAwsMessageHandler { } } else { - byte[] bytes = - payload instanceof byte[] - ? (byte[]) payload - : this.converter.convert(payload); + byte[] bytes = payload instanceof byte[] ? (byte[]) payload : this.converter.convert(payload); Assert.notNull(bytes, "payload cannot be null"); if (this.embeddedHeadersMapper != null) { messageToEmbed = new MutableMessage<>(bytes, messageHeaders); @@ -274,12 +266,8 @@ public class KplMessageHandler extends AbstractAwsMessageHandler { } } - return new PutRecordRequest() - .withStreamName(stream) - .withPartitionKey(partitionKey) - .withExplicitHashKey(explicitHashKey) - .withSequenceNumberForOrdering(sequenceNumber) - .withData(data); + return new PutRecordRequest().withStreamName(stream).withPartitionKey(partitionKey) + .withExplicitHashKey(explicitHashKey).withSequenceNumberForOrdering(sequenceNumber).withData(data); } @Override @@ -287,8 +275,7 @@ public class KplMessageHandler extends AbstractAwsMessageHandler { AmazonWebServiceRequest request, Object result) { if (result instanceof PutRecordResult) { - messageBuilder - .setHeader(AwsHeaders.SHARD, ((PutRecordResult) result).getShardId()) + messageBuilder.setHeader(AwsHeaders.SHARD, ((PutRecordResult) result).getShardId()) .setHeader(AwsHeaders.SEQUENCE_NUMBER, ((PutRecordResult) result).getSequenceNumber()); } } diff --git a/src/main/java/org/springframework/integration/aws/outbound/S3MessageHandler.java b/src/main/java/org/springframework/integration/aws/outbound/S3MessageHandler.java index 0261ceb..1993672 100644 --- a/src/main/java/org/springframework/integration/aws/outbound/S3MessageHandler.java +++ b/src/main/java/org/springframework/integration/aws/outbound/S3MessageHandler.java @@ -56,46 +56,53 @@ import com.amazonaws.services.s3.transfer.internal.S3ProgressListenerChain; import com.amazonaws.util.Md5Utils; /** - * The {@link AbstractReplyProducingMessageHandler} implementation for the Amazon S3 services. + * The {@link AbstractReplyProducingMessageHandler} implementation for the Amazon S3 + * services. *

- * The implementation is fully based on the {@link TransferManager} and support its {@code upload}, - * {@code download} and {@code copy} operations which can be determined by the provided - * or evaluated via SpEL expression at runtime {@link S3MessageHandler.Command}. + * The implementation is fully based on the {@link TransferManager} and support its + * {@code upload}, {@code download} and {@code copy} operations which can be determined by + * the provided or evaluated via SpEL expression at runtime + * {@link S3MessageHandler.Command}. *

- * This {@link AbstractReplyProducingMessageHandler} can behave as a "one-way" (by default) or - * "request-reply" component according to the {@link #produceReply} constructor argument. + * This {@link AbstractReplyProducingMessageHandler} can behave as a "one-way" (by + * default) or "request-reply" component according to the {@link #produceReply} + * constructor argument. *

- * The "one-way" behavior is also blocking, which is achieved with the {@link Transfer#waitForException()} - * invocation. Consider to use an async upstream hand off if this blocking behavior isn't appropriate. + * The "one-way" behavior is also blocking, which is achieved with the + * {@link Transfer#waitForException()} invocation. Consider to use an async upstream hand + * off if this blocking behavior isn't appropriate. *

- * The "request-reply" behavior is async and the {@link Transfer} result from the {@link TransferManager} - * operation is sent to the {@link #getOutputChannel()}, assuming the transfer progress observation in the - * downstream flow. + * The "request-reply" behavior is async and the {@link Transfer} result from the + * {@link TransferManager} operation is sent to the {@link #getOutputChannel()}, assuming + * the transfer progress observation in the downstream flow. *

- * The {@link S3ProgressListener} can be supplied to track the transfer progress. - * Also the listener can be populated into the returned {@link Transfer} afterwards in the downstream flow. - * If the context of the {@code requestMessage} is important in the {@code progressChanged} event, it is - * recommended to use a {@link MessageS3ProgressListener} implementation instead. - * *

- * For the upload operation the {@link UploadMetadataProvider} callback can be supplied to populate required - * {@link ObjectMetadata} options, as for a single entry, as well as for each file in directory to upload. + * The {@link S3ProgressListener} can be supplied to track the transfer progress. Also the + * listener can be populated into the returned {@link Transfer} afterwards in the + * downstream flow. If the context of the {@code requestMessage} is important in the + * {@code progressChanged} event, it is recommended to use a + * {@link MessageS3ProgressListener} implementation instead. * *

- * For the upload operation the {@link #objectAclExpression} can be provided to {@link AmazonS3#setObjectAcl} - * after the successful transfer. - * The supported SpEL result types are: {@link AccessControlList} or {@link CannedAccessControlList}. + * For the upload operation the {@link UploadMetadataProvider} callback can be supplied to + * populate required {@link ObjectMetadata} options, as for a single entry, as well as for + * each file in directory to upload. *

- * For download operation the {@code payload} must be a {@link File} instance, representing a single file - * for downloaded content or directory to download all files from the S3 virtual directory. + * For the upload operation the {@link #objectAclExpression} can be provided to + * {@link AmazonS3#setObjectAcl} after the successful transfer. The supported SpEL result + * types are: {@link AccessControlList} or {@link CannedAccessControlList}. + *

+ * For download operation the {@code payload} must be a {@link File} instance, + * representing a single file for downloaded content or directory to download all files + * from the S3 virtual directory. *

* An S3 Object {@code key} for upload and download can be determined by the provided - * {@link #keyExpression} or the {@link File#getName()} is used directly. The former has precedence. + * {@link #keyExpression} or the {@link File#getName()} is used directly. The former has + * precedence. *

* For copy operation all {@link #keyExpression}, {@link #destinationBucketExpression} and * {@link #destinationKeyExpression} are required and must not evaluate to {@code null}. * * @author Artem Bilan * @author John Logan - * * @see TransferManager */ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { @@ -138,11 +145,7 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } public S3MessageHandler(AmazonS3 amazonS3, Expression bucketExpression, boolean produceReply) { - this(TransferManagerBuilder.standard() - .withS3Client(amazonS3) - .build(), - bucketExpression, - produceReply); + this(TransferManagerBuilder.standard().withS3Client(amazonS3).build(), bucketExpression, produceReply); Assert.notNull(amazonS3, "'amazonS3' must not be null"); } @@ -168,7 +171,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } /** - * The SpEL expression to evaluate S3 object key at runtime against {@code requestMessage}. + * The SpEL expression to evaluate S3 object key at runtime against + * {@code requestMessage}. * @param keyExpression the SpEL expression for S3 key. */ public void setKeyExpression(Expression keyExpression) { @@ -176,8 +180,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } /** - * The SpEL expression to evaluate S3 object ACL at runtime against {@code requestMessage} - * for the {@code upload} operation. + * The SpEL expression to evaluate S3 object ACL at runtime against + * {@code requestMessage} for the {@code upload} operation. * @param objectAclExpression the SpEL expression for S3 object ACL. */ public void setObjectAclExpression(Expression objectAclExpression) { @@ -185,7 +189,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } /** - * Specify a {@link S3MessageHandler.Command} to perform against {@link TransferManager}. + * Specify a {@link S3MessageHandler.Command} to perform against + * {@link TransferManager}. * @param command The {@link S3MessageHandler.Command} to use. * @see S3MessageHandler.Command */ @@ -195,9 +200,10 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } /** - * The SpEL expression to evaluate the command to perform on {@link TransferManager}: {@code upload}, - * {@code download} or {@code copy}. - * @param commandExpression the SpEL expression to evaluate the {@link TransferManager} operation. + * The SpEL expression to evaluate the command to perform on {@link TransferManager}: + * {@code upload}, {@code download} or {@code copy}. + * @param commandExpression the SpEL expression to evaluate the + * {@link TransferManager} operation. * @see Command */ public void setCommandExpression(Expression commandExpression) { @@ -233,8 +239,9 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } /** - * Specify an {@link ObjectMetadata} callback to populate the metadata for upload operation, - * e.g. {@code Content-MD5}, {@code Content-Type} or any other required options. + * Specify an {@link ObjectMetadata} callback to populate the metadata for upload + * operation, e.g. {@code Content-MD5}, {@code Content-Type} or any other required + * options. * @param uploadMetadataProvider the {@link UploadMetadataProvider} to use for upload. */ public void setUploadMetadataProvider(UploadMetadataProvider uploadMetadataProvider) { @@ -242,7 +249,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } /** - * Specify a {@link ResourceIdResolver} to resolve logical bucket names to physical resource ids. + * Specify a {@link ResourceIdResolver} to resolve logical bucket names to physical + * resource ids. * @param resourceIdResolver the {@link ResourceIdResolver} to use. */ public void setResourceIdResolver(ResourceIdResolver resourceIdResolver) { @@ -259,23 +267,23 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { @Override protected Object handleRequestMessage(Message requestMessage) { Command command = this.commandExpression.getValue(this.evaluationContext, requestMessage, Command.class); - Assert.state(command != null, () -> - "'commandExpression' [" + this.commandExpression.getExpressionString() + "] cannot evaluate to null."); + Assert.state(command != null, () -> "'commandExpression' [" + this.commandExpression.getExpressionString() + + "] cannot evaluate to null."); Transfer transfer = null; switch (command) { - case UPLOAD: - transfer = upload(requestMessage); - break; + case UPLOAD: + transfer = upload(requestMessage); + break; - case DOWNLOAD: - transfer = download(requestMessage); - break; + case DOWNLOAD: + transfer = download(requestMessage); + break; - case COPY: - transfer = copy(requestMessage); - break; + case COPY: + transfer = copy(requestMessage); + break; } if (this.produceReply) { @@ -325,8 +333,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { InputStream inputStream = (InputStream) payload; if (metadata.getContentMD5() == null) { Assert.state(inputStream.markSupported(), - "For an upload InputStream with no MD5 digest metadata, " + - "the markSupported() method must evaluate to true."); + "For an upload InputStream with no MD5 digest metadata, " + + "the markSupported() method must evaluate to true."); String contentMd5 = Md5Utils.md5AsBase64(inputStream); metadata.setContentMD5(contentMd5); inputStream.reset(); @@ -348,9 +356,7 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { if (metadata.getContentType() == null) { metadata.setContentType(Mimetypes.getInstance().getMimetype(fileToUpload)); } - putObjectRequest = - new PutObjectRequest(bucketName, key, fileToUpload) - .withMetadata(metadata); + putObjectRequest = new PutObjectRequest(bucketName, key, fileToUpload).withMetadata(metadata); } else if (payload instanceof byte[]) { byte[] payloadBytes = (byte[]) payload; @@ -366,10 +372,9 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, metadata); } else { - throw new IllegalArgumentException("Unsupported payload type: [" - + payload.getClass() - + "]. The only supported payloads for the upload request are " + - "java.io.File, java.io.InputStream, byte[] and PutObjectRequest."); + throw new IllegalArgumentException("Unsupported payload type: [" + payload.getClass() + + "]. The only supported payloads for the upload request are " + + "java.io.File, java.io.InputStream, byte[] and PutObjectRequest."); } } catch (IOException e) { @@ -378,8 +383,7 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { if (key == null) { if (this.keyExpression != null) { - throw new IllegalStateException("The 'keyExpression' [" - + this.keyExpression.getExpressionString() + throw new IllegalStateException("The 'keyExpression' [" + this.keyExpression.getExpressionString() + "] must not evaluate to null. Root object is: " + requestMessage); } else { @@ -410,11 +414,10 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { if (this.objectAclExpression != null) { Object acl = this.objectAclExpression.getValue(this.evaluationContext, requestMessage); Assert.state(acl == null || acl instanceof AccessControlList || acl instanceof CannedAccessControlList, - () -> "The 'objectAclExpression' [" - + this.objectAclExpression.getExpressionString() - + "] must evaluate to com.amazonaws.services.s3.model.AccessControlList " + - "or must evaluate to com.amazonaws.services.s3.model.CannedAccessControlList. " + - "Gotten: [" + acl + "]"); + () -> "The 'objectAclExpression' [" + this.objectAclExpression.getExpressionString() + + "] must evaluate to com.amazonaws.services.s3.model.AccessControlList " + + "or must evaluate to com.amazonaws.services.s3.model.CannedAccessControlList. " + + "Gotten: [" + acl + "]"); SetObjectAclRequest aclRequest; @@ -459,9 +462,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { private Transfer download(Message requestMessage) { Object payload = requestMessage.getPayload(); - Assert.state(payload instanceof File, - () -> "For the 'DOWNLOAD' operation the 'payload' must be of " + - "'java.io.File' type, but gotten: [" + payload.getClass() + ']'); + Assert.state(payload instanceof File, () -> "For the 'DOWNLOAD' operation the 'payload' must be of " + + "'java.io.File' type, but gotten: [" + payload.getClass() + ']'); File targetFile = (File) payload; @@ -476,8 +478,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } Assert.state(key != null, - () -> "The 'keyExpression' must not be null for non-File payloads and can't evaluate to null. " + - "Root object is: " + requestMessage); + () -> "The 'keyExpression' must not be null for non-File payloads and can't evaluate to null. " + + "Root object is: " + requestMessage); if (targetFile.isDirectory()) { return this.transferManager.downloadDirectory(bucket, key, targetFile); @@ -501,10 +503,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { sourceKey = this.keyExpression.getValue(this.evaluationContext, requestMessage, String.class); } - Assert.state(sourceKey != null, - () -> "The 'keyExpression' must not be null for 'copy' operation " + - "and 'keyExpression' can't evaluate to null. " + - "Root object is: " + requestMessage); + Assert.state(sourceKey != null, () -> "The 'keyExpression' must not be null for 'copy' operation " + + "and 'keyExpression' can't evaluate to null. " + "Root object is: " + requestMessage); String destinationBucketName = null; if (this.destinationBucketExpression != null) { @@ -517,8 +517,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } Assert.state(destinationBucketName != null, - () -> "The 'destinationBucketExpression' must not be null for 'copy' operation " + - "and can't evaluate to null. Root object is: " + requestMessage); + () -> "The 'destinationBucketExpression' must not be null for 'copy' operation " + + "and can't evaluate to null. Root object is: " + requestMessage); String destinationKey = null; if (this.destinationKeyExpression != null) { @@ -527,12 +527,11 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } Assert.state(destinationKey != null, - () -> "The 'destinationKeyExpression' must not be null for 'copy' operation " + - "and can't evaluate to null. Root object is: " + requestMessage); + () -> "The 'destinationKeyExpression' must not be null for 'copy' operation " + + "and can't evaluate to null. Root object is: " + requestMessage); - - CopyObjectRequest copyObjectRequest = - new CopyObjectRequest(sourceBucketName, sourceKey, destinationBucketName, destinationKey); + CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceKey, destinationBucketName, + destinationKey); return this.transferManager.copy(copyObjectRequest); } @@ -544,10 +543,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { else { bucketName = this.bucketExpression.getValue(this.evaluationContext, requestMessage, String.class); } - Assert.state(bucketName != null, - () -> "The 'bucketExpression' [" - + this.bucketExpression.getExpressionString() - + "] must not evaluate to null. Root object is: " + requestMessage); + Assert.state(bucketName != null, () -> "The 'bucketExpression' [" + this.bucketExpression.getExpressionString() + + "] must not evaluate to null. Root object is: " + requestMessage); if (this.resourceIdResolver != null) { bucketName = this.resourceIdResolver.resolveToPhysicalResourceId(bucketName); @@ -581,8 +578,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } /** - * An {@link S3ProgressListener} extension to provide a {@code requestMessage} - * context for the {@code progressChanged} event. + * An {@link S3ProgressListener} extension to provide a {@code requestMessage} context + * for the {@code progressChanged} event. * * @since 2.1 */ @@ -598,8 +595,8 @@ public class S3MessageHandler extends AbstractReplyProducingMessageHandler { } /** - * The callback to populate an {@link ObjectMetadata} for upload operation. - * The message can be used as a metadata source. + * The callback to populate an {@link ObjectMetadata} for upload operation. The + * message can be used as a metadata source. */ public interface UploadMetadataProvider { diff --git a/src/main/java/org/springframework/integration/aws/outbound/SnsMessageHandler.java b/src/main/java/org/springframework/integration/aws/outbound/SnsMessageHandler.java index 1929cbd..7ec00ba 100644 --- a/src/main/java/org/springframework/integration/aws/outbound/SnsMessageHandler.java +++ b/src/main/java/org/springframework/integration/aws/outbound/SnsMessageHandler.java @@ -49,36 +49,28 @@ import com.amazonaws.services.sns.model.PublishResult; *

* The algorithm to populate SNS Message body is like: *

    - *
  • - * If the {@code payload instanceof PublishRequest} it is used as is for publishing. + *
  • If the {@code payload instanceof PublishRequest} it is used as is for publishing. *
  • - *
  • - * If the {@link #bodyExpression} is specified, it is used to be evaluated - * against {@code requestMessage}. - *
  • - *
  • - * If the evaluation result (or {@code payload}) is instance of {@link SnsBodyBuilder}, - * the SNS Message is built from there and the {@code messageStructure} - * of the {@link PublishRequest} is set to {@code json}. - * For the convenience the package {@code org.springframework.integration.aws.support} is imported - * to the {@link #getEvaluationContext()} to allow bypass it for the {@link SnsBodyBuilder} - * from the {@link #bodyExpression} definition. For example: + *
  • If the {@link #bodyExpression} is specified, it is used to be evaluated against + * {@code requestMessage}.
  • + *
  • If the evaluation result (or {@code payload}) is instance of + * {@link SnsBodyBuilder}, the SNS Message is built from there and the + * {@code messageStructure} of the {@link PublishRequest} is set to {@code json}. For the + * convenience the package {@code org.springframework.integration.aws.support} is imported + * to the {@link #getEvaluationContext()} to allow bypass it for the + * {@link SnsBodyBuilder} from the {@link #bodyExpression} definition. For example: *
      * {@code
      * String bodyExpression =
      * "SnsBodyBuilder.withDefault(payload).forProtocols(payload.substring(0, 140), 'sms')";
      * snsMessageHandler.setBodyExpression(spelExpressionParser.parseExpression(bodyExpression));
      * }
    - * 
    - *
  • - *
  • - * Otherwise the {@code payload} (or the {@link #bodyExpression} evaluation result) is converted - * to the {@link String} using {@link #getConversionService()}. - *
  • + * + *
  • Otherwise the {@code payload} (or the {@link #bodyExpression} evaluation result) is + * converted to the {@link String} using {@link #getConversionService()}.
  • *
* * @author Artem Bilan - * * @see AmazonSNSAsync * @see PublishRequest * @see SnsBodyBuilder @@ -122,12 +114,13 @@ public class SnsMessageHandler extends AbstractAwsMessageHandler> { @@ -74,7 +74,6 @@ public class SqsMessageHandler extends AbstractAwsMessageHandler handleMessageToAws(Message message) { Object payload = message.getPayload(); if (payload instanceof SendMessageBatchRequest) { - AsyncHandler asyncHandler = - obtainAsyncHandler(message, (SendMessageBatchRequest) payload); + AsyncHandler asyncHandler = obtainAsyncHandler(message, + (SendMessageBatchRequest) payload); return this.amazonSqs.sendMessageBatchAsync((SendMessageBatchRequest) payload, asyncHandler); } @@ -177,9 +176,10 @@ public class SqsMessageHandler extends AbstractAwsMessageHandler asyncHandler = - obtainAsyncHandler(message, sendMessageRequest); + AsyncHandler asyncHandler = obtainAsyncHandler(message, + sendMessageRequest); return this.amazonSqs.sendMessageAsync(sendMessageRequest, asyncHandler); } diff --git a/src/main/java/org/springframework/integration/aws/support/AbstractMessageAttributesHeaderMapper.java b/src/main/java/org/springframework/integration/aws/support/AbstractMessageAttributesHeaderMapper.java index 19a53b0..4694b38 100644 --- a/src/main/java/org/springframework/integration/aws/support/AbstractMessageAttributesHeaderMapper.java +++ b/src/main/java/org/springframework/integration/aws/support/AbstractMessageAttributesHeaderMapper.java @@ -33,38 +33,31 @@ import org.springframework.util.MimeType; import org.springframework.util.NumberUtils; /** - * Base {@link HeaderMapper} implementation for common logic in SQS and SNS - * around message attributes mapping. + * Base {@link HeaderMapper} implementation for common logic in SQS and SNS around message + * attributes mapping. * * The {@link #toHeaders(Map)} is not supported. * * @param the target message attribute type. - * * @author Artem Bilan - * * @since 2.0 */ public abstract class AbstractMessageAttributesHeaderMapper implements HeaderMapper> { private static final Log logger = LogFactory.getLog(SqsHeaderMapper.class); - private volatile String[] outboundHeaderNames = { - "!" + MessageHeaders.ID, - "!" + MessageHeaders.TIMESTAMP, - "!" + AwsHeaders.MESSAGE_ID, - "!" + AwsHeaders.QUEUE, - "!" + AwsHeaders.TOPIC, - "*" }; + private volatile String[] outboundHeaderNames = { "!" + MessageHeaders.ID, "!" + MessageHeaders.TIMESTAMP, + "!" + AwsHeaders.MESSAGE_ID, "!" + AwsHeaders.QUEUE, "!" + AwsHeaders.TOPIC, "*" }; /** * Provide the header names that should be mapped to a AWS request object attributes - * (for outbound adapters) from a Spring Integration Message's headers. - * The values can also contain simple wildcard patterns (e.g. "foo*" or "*foo") to be matched. - * Also supports negated ('!') patterns. First match wins (positive or negative). - * To match the names starting with {@code !} symbol, - * you have to escape it prepending with the {@code \} symbol in the pattern definition. - * Defaults to map all ({@code *}) if the type is supported by SQS. - * The {@link MessageHeaders#ID}, {@link MessageHeaders#TIMESTAMP}, {@link AwsHeaders#MESSAGE_ID}, + * (for outbound adapters) from a Spring Integration Message's headers. The values can + * also contain simple wildcard patterns (e.g. "foo*" or "*foo") to be matched. Also + * supports negated ('!') patterns. First match wins (positive or negative). To match + * the names starting with {@code !} symbol, you have to escape it prepending with the + * {@code \} symbol in the pattern definition. Defaults to map all ({@code *}) if the + * type is supported by SQS. The {@link MessageHeaders#ID}, + * {@link MessageHeaders#TIMESTAMP}, {@link AwsHeaders#MESSAGE_ID}, * {@link AwsHeaders#QUEUE} and {@link AwsHeaders#TOPIC} are ignored by default. * @param outboundHeaderNames The inbound header names. */ @@ -83,10 +76,8 @@ public abstract class AbstractMessageAttributesHeaderMapper implements Header if (Boolean.TRUE.equals(PatternMatchUtils.smartMatch(messageHeaderName, this.outboundHeaderNames))) { - if (messageHeaderValue instanceof UUID - || messageHeaderValue instanceof MimeType - || messageHeaderValue instanceof Boolean - || messageHeaderValue instanceof String) { + if (messageHeaderValue instanceof UUID || messageHeaderValue instanceof MimeType + || messageHeaderValue instanceof Boolean || messageHeaderValue instanceof String) { target.put(messageHeaderName, getStringMessageAttribute(messageHeaderValue.toString())); } @@ -102,11 +93,10 @@ public abstract class AbstractMessageAttributesHeaderMapper implements Header } else { if (logger.isWarnEnabled()) { - logger.warn( - String.format("Message header with name '%s' and type '%s' cannot be sent as" + - " message attribute because it is not supported by SQS.", - messageHeaderName, - messageHeaderValue.getClass().getName())); + logger.warn(String.format( + "Message header with name '%s' and type '%s' cannot be sent as" + + " message attribute because it is not supported by SQS.", + messageHeaderName, messageHeaderValue.getClass().getName())); } } diff --git a/src/main/java/org/springframework/integration/aws/support/AwsHeaders.java b/src/main/java/org/springframework/integration/aws/support/AwsHeaders.java index 59013f6..8182f7a 100644 --- a/src/main/java/org/springframework/integration/aws/support/AwsHeaders.java +++ b/src/main/java/org/springframework/integration/aws/support/AwsHeaders.java @@ -106,7 +106,8 @@ public abstract class AwsHeaders { public static final String CHECKPOINTER = PREFIX + "checkpointer"; /** - * The {@value SERVICE_RESULT} header represents a {@link com.amazonaws.AmazonWebServiceResult}. + * The {@value SERVICE_RESULT} header represents a + * {@link com.amazonaws.AmazonWebServiceResult}. */ public static final String SERVICE_RESULT = PREFIX + "serviceResult"; diff --git a/src/main/java/org/springframework/integration/aws/support/AwsRequestFailureException.java b/src/main/java/org/springframework/integration/aws/support/AwsRequestFailureException.java index c959cef..7f594f9 100644 --- a/src/main/java/org/springframework/integration/aws/support/AwsRequestFailureException.java +++ b/src/main/java/org/springframework/integration/aws/support/AwsRequestFailureException.java @@ -25,7 +25,6 @@ import com.amazonaws.AmazonWebServiceRequest; * An exception that is the payload of an {@code ErrorMessage} when a send fails. * * @author Jacob Severson - * * @since 1.1 */ public class AwsRequestFailureException extends MessagingException { diff --git a/src/main/java/org/springframework/integration/aws/support/S3FileInfo.java b/src/main/java/org/springframework/integration/aws/support/S3FileInfo.java index 28ff64b..6dd64a0 100644 --- a/src/main/java/org/springframework/integration/aws/support/S3FileInfo.java +++ b/src/main/java/org/springframework/integration/aws/support/S3FileInfo.java @@ -24,10 +24,10 @@ import org.springframework.util.Assert; import com.amazonaws.services.s3.model.S3ObjectSummary; /** - * An Amazon S3 {@link org.springframework.integration.file.remote.FileInfo} implementation. + * An Amazon S3 {@link org.springframework.integration.file.remote.FileInfo} + * implementation. * * @author Christian Tzolov - * * @since 1.1 */ public class S3FileInfo extends AbstractFileInfo { @@ -65,9 +65,8 @@ public class S3FileInfo extends AbstractFileInfo { } /** - * A permissions representation string. - * Throws {@link UnsupportedOperationException} to avoid extra - * {@link com.amazonaws.services.s3.AmazonS3#getObjectAcl} REST call. + * A permissions representation string. Throws {@link UnsupportedOperationException} + * to avoid extra {@link com.amazonaws.services.s3.AmazonS3#getObjectAcl} REST call. * The target application amy choose to do that by its logic. * @return the permissions representation string. */ @@ -83,10 +82,9 @@ public class S3FileInfo extends AbstractFileInfo { @Override public String toString() { - return "FileInfo [isDirectory=" + isDirectory() + ", isLink=" + isLink() - + ", Size=" + getSize() + ", ModifiedTime=" - + new Date(getModified()) + ", Filename=" + getFilename() - + ", RemoteDirectory=" + getRemoteDirectory() + "]"; + return "FileInfo [isDirectory=" + isDirectory() + ", isLink=" + isLink() + ", Size=" + getSize() + + ", ModifiedTime=" + new Date(getModified()) + ", Filename=" + getFilename() + ", RemoteDirectory=" + + getRemoteDirectory() + "]"; } } diff --git a/src/main/java/org/springframework/integration/aws/support/S3Session.java b/src/main/java/org/springframework/integration/aws/support/S3Session.java index 97309e0..ee949b5 100644 --- a/src/main/java/org/springframework/integration/aws/support/S3Session.java +++ b/src/main/java/org/springframework/integration/aws/support/S3Session.java @@ -67,17 +67,16 @@ public class S3Session implements Session { public S3ObjectSummary[] list(String path) throws IOException { String[] bucketPrefix = splitPathToBucketAndKey(path, false); - ListObjectsRequest listObjectsRequest = new ListObjectsRequest() - .withBucketName(bucketPrefix[0]); + ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucketPrefix[0]); if (bucketPrefix.length > 1) { listObjectsRequest.setPrefix(bucketPrefix[1]); } /* - For listing objects, Amazon S3 returns up to 1,000 keys in the response. - If you have more than 1,000 keys in your bucket, the response will be truncated. - You should always check for if the response is truncated. - */ + * For listing objects, Amazon S3 returns up to 1,000 keys in the response. If you + * have more than 1,000 keys in your bucket, the response will be truncated. You + * should always check for if the response is truncated. + */ ObjectListing objectListing; List objectSummaries = new ArrayList<>(); do { @@ -103,17 +102,16 @@ public class S3Session implements Session { public String[] listNames(String path) throws IOException { String[] bucketPrefix = splitPathToBucketAndKey(path, false); - ListObjectsRequest listObjectsRequest = new ListObjectsRequest() - .withBucketName(bucketPrefix[0]); + ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucketPrefix[0]); if (bucketPrefix.length > 1) { listObjectsRequest.setPrefix(bucketPrefix[1]); } /* - For listing objects, Amazon S3 returns up to 1,000 keys in the response. - If you have more than 1,000 keys in your bucket, the response will be truncated. - You should always check for if the response is truncated. - */ + * For listing objects, Amazon S3 returns up to 1,000 keys in the response. If you + * have more than 1,000 keys in your bucket, the response will be truncated. You + * should always check for if the response is truncated. + */ ObjectListing objectListing; List names = new ArrayList<>(); do { @@ -139,11 +137,11 @@ public class S3Session implements Session { public void rename(String pathFrom, String pathTo) throws IOException { String[] bucketKeyFrom = splitPathToBucketAndKey(pathFrom, true); String[] bucketKeyTo = splitPathToBucketAndKey(pathTo, true); - CopyObjectRequest copyRequest = new CopyObjectRequest(bucketKeyFrom[0], bucketKeyFrom[1], - bucketKeyTo[0], bucketKeyTo[1]); + CopyObjectRequest copyRequest = new CopyObjectRequest(bucketKeyFrom[0], bucketKeyFrom[1], bucketKeyTo[0], + bucketKeyTo[1]); this.amazonS3.copyObject(copyRequest); - //Delete the source + // Delete the source this.amazonS3.deleteObject(bucketKeyFrom[0], bucketKeyFrom[1]); } diff --git a/src/main/java/org/springframework/integration/aws/support/S3SessionFactory.java b/src/main/java/org/springframework/integration/aws/support/S3SessionFactory.java index 50fe7c4..508babb 100644 --- a/src/main/java/org/springframework/integration/aws/support/S3SessionFactory.java +++ b/src/main/java/org/springframework/integration/aws/support/S3SessionFactory.java @@ -26,9 +26,9 @@ import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.S3ObjectSummary; /** - * An Amazon S3 specific {@link SessionFactory} implementation. - * Also this class implements {@link SharedSessionCapable} around the single instance, - * since the {@link S3Session} is simple thread-safe wrapper for the {@link AmazonS3}. + * An Amazon S3 specific {@link SessionFactory} implementation. Also this class implements + * {@link SharedSessionCapable} around the single instance, since the {@link S3Session} is + * simple thread-safe wrapper for the {@link AmazonS3}. * * @author Artem Bilan */ diff --git a/src/main/java/org/springframework/integration/aws/support/SnsBodyBuilder.java b/src/main/java/org/springframework/integration/aws/support/SnsBodyBuilder.java index c8df4c4..636d2ff 100644 --- a/src/main/java/org/springframework/integration/aws/support/SnsBodyBuilder.java +++ b/src/main/java/org/springframework/integration/aws/support/SnsBodyBuilder.java @@ -22,10 +22,9 @@ import java.util.Map; import org.springframework.util.Assert; /** - * An utility class to simplify an SNS Message body building. - * Can be used from the {@code SnsMessageHandler#bodyExpression} definition or - * directly in case of manual {@link com.amazonaws.services.sns.model.PublishRequest} - * building. + * An utility class to simplify an SNS Message body building. Can be used from the + * {@code SnsMessageHandler#bodyExpression} definition or directly in case of manual + * {@link com.amazonaws.services.sns.model.PublishRequest} building. * * @author Artem Bilan */ @@ -51,11 +50,8 @@ public final class SnsBodyBuilder { public String build() { StringBuilder stringBuilder = new StringBuilder("{"); for (Map.Entry entry : this.snsMessage.entrySet()) { - stringBuilder.append("\"") - .append(entry.getKey()) - .append("\":\"") - .append(entry.getValue().replaceAll("\"", "\\\\\"")) - .append("\","); + stringBuilder.append("\"").append(entry.getKey()).append("\":\"") + .append(entry.getValue().replaceAll("\"", "\\\\\"")).append("\","); } return stringBuilder.substring(0, stringBuilder.length() - 1) + "}"; } diff --git a/src/main/java/org/springframework/integration/aws/support/SnsHeaderMapper.java b/src/main/java/org/springframework/integration/aws/support/SnsHeaderMapper.java index ec38f4b..dc3ddbf 100644 --- a/src/main/java/org/springframework/integration/aws/support/SnsHeaderMapper.java +++ b/src/main/java/org/springframework/integration/aws/support/SnsHeaderMapper.java @@ -21,22 +21,20 @@ import java.nio.ByteBuffer; import com.amazonaws.services.sns.model.MessageAttributeValue; /** - * The {@link AbstractMessageAttributesHeaderMapper} implementation for the mapping - * from headers to SNS message attributes. + * The {@link AbstractMessageAttributesHeaderMapper} implementation for the mapping from + * headers to SNS message attributes. *

- * On the Inbound side, the SNS message is fully mapped from the JSON to the message payload. - * Only important HTTP headers are mapped to the message headers. + * On the Inbound side, the SNS message is fully mapped from the JSON to the message + * payload. Only important HTTP headers are mapped to the message headers. * * @author Artem Bilan - * * @since 2.0 */ public class SnsHeaderMapper extends AbstractMessageAttributesHeaderMapper { @Override protected MessageAttributeValue buildMessageAttribute(String dataType, Object value) { - MessageAttributeValue messageAttributeValue = new MessageAttributeValue() - .withDataType(dataType); + MessageAttributeValue messageAttributeValue = new MessageAttributeValue().withDataType(dataType); if (value instanceof ByteBuffer) { return messageAttributeValue.withBinaryValue((ByteBuffer) value); } diff --git a/src/main/java/org/springframework/integration/aws/support/SqsHeaderMapper.java b/src/main/java/org/springframework/integration/aws/support/SqsHeaderMapper.java index 8ea4b13..d81f555 100644 --- a/src/main/java/org/springframework/integration/aws/support/SqsHeaderMapper.java +++ b/src/main/java/org/springframework/integration/aws/support/SqsHeaderMapper.java @@ -23,22 +23,21 @@ import org.springframework.messaging.MessageHeaders; import com.amazonaws.services.sqs.model.MessageAttributeValue; /** - * The {@link AbstractMessageAttributesHeaderMapper} implementation for the mapping - * from headers to SQS message attributes. + * The {@link AbstractMessageAttributesHeaderMapper} implementation for the mapping from + * headers to SQS message attributes. *

- * The {@link org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer} maps - * all the SQS message attributes to the {@link MessageHeaders}. + * The + * {@link org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer} + * maps all the SQS message attributes to the {@link MessageHeaders}. * * @author Artem Bilan - * * @since 2.0 */ public class SqsHeaderMapper extends AbstractMessageAttributesHeaderMapper { @Override protected MessageAttributeValue buildMessageAttribute(String dataType, Object value) { - MessageAttributeValue messageAttributeValue = new MessageAttributeValue() - .withDataType(dataType); + MessageAttributeValue messageAttributeValue = new MessageAttributeValue().withDataType(dataType); if (value instanceof ByteBuffer) { return messageAttributeValue.withBinaryValue((ByteBuffer) value); } diff --git a/src/main/java/org/springframework/integration/aws/support/filters/S3PersistentAcceptOnceFileListFilter.java b/src/main/java/org/springframework/integration/aws/support/filters/S3PersistentAcceptOnceFileListFilter.java index 3ba4876..7aedb02 100644 --- a/src/main/java/org/springframework/integration/aws/support/filters/S3PersistentAcceptOnceFileListFilter.java +++ b/src/main/java/org/springframework/integration/aws/support/filters/S3PersistentAcceptOnceFileListFilter.java @@ -16,15 +16,14 @@ package org.springframework.integration.aws.support.filters; - import org.springframework.integration.file.filters.AbstractPersistentAcceptOnceFileListFilter; import org.springframework.integration.metadata.ConcurrentMetadataStore; import com.amazonaws.services.s3.model.S3ObjectSummary; /** - * Persistent file list filter using the server's file timestamp to detect if we've already - * 'seen' this file. + * Persistent file list filter using the server's file timestamp to detect if we've + * already 'seen' this file. * * @author Artem Bilan */ diff --git a/src/test/java/org/springframework/integration/aws/DynamoDbLocalRunning.java b/src/test/java/org/springframework/integration/aws/DynamoDbLocalRunning.java index 531687d..b6616be 100644 --- a/src/test/java/org/springframework/integration/aws/DynamoDbLocalRunning.java +++ b/src/test/java/org/springframework/integration/aws/DynamoDbLocalRunning.java @@ -38,11 +38,10 @@ import com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsync; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsyncClientBuilder; /** - * The {@link TestWatcher} implementation for local Amazon DynamoDB service. - * See https://github.com/mhart/dynalite. + * The {@link TestWatcher} implementation for local Amazon DynamoDB service. See + * https://github.com/mhart/dynalite. * * @author Artem Bilan - * * @since 1.1 */ public final class DynamoDbLocalRunning extends TestWatcher { @@ -75,10 +74,7 @@ public final class DynamoDbLocalRunning extends TestWatcher { this.amazonDynamoDB = AmazonDynamoDBAsyncClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("", ""))) - .withClientConfiguration( - new ClientConfiguration() - .withMaxErrorRetry(0) - .withConnectionTimeout(1000)) + .withClientConfiguration(new ClientConfiguration().withMaxErrorRetry(0).withConnectionTimeout(1000)) .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration(url, Regions.DEFAULT_REGION.getName())) .build(); @@ -93,7 +89,6 @@ public final class DynamoDbLocalRunning extends TestWatcher { return super.apply(base, description); } - public static DynamoDbLocalRunning isRunning() { return isRunning(DEFAULT_PORT); } diff --git a/src/test/java/org/springframework/integration/aws/KinesisLocalRunning.java b/src/test/java/org/springframework/integration/aws/KinesisLocalRunning.java index 8f61bfd..a31e0b0 100644 --- a/src/test/java/org/springframework/integration/aws/KinesisLocalRunning.java +++ b/src/test/java/org/springframework/integration/aws/KinesisLocalRunning.java @@ -39,11 +39,10 @@ import com.amazonaws.services.kinesis.AmazonKinesisAsync; import com.amazonaws.services.kinesis.AmazonKinesisAsyncClientBuilder; /** - * The {@link TestWatcher} implementation for local Amazon Kinesis service. - * See https://github.com/mhart/kinesalite. + * The {@link TestWatcher} implementation for local Amazon Kinesis service. See + * https://github.com/mhart/kinesalite. * * @author Artem Bilan - * * @since 1.1 */ public final class KinesisLocalRunning extends TestWatcher { @@ -79,10 +78,7 @@ public final class KinesisLocalRunning extends TestWatcher { this.amazonKinesis = AmazonKinesisAsyncClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("", ""))) - .withClientConfiguration( - new ClientConfiguration() - .withMaxErrorRetry(0) - .withConnectionTimeout(1000)) + .withClientConfiguration(new ClientConfiguration().withMaxErrorRetry(0).withConnectionTimeout(1000)) .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration(url, Regions.DEFAULT_REGION.getName())) .build(); @@ -95,7 +91,6 @@ public final class KinesisLocalRunning extends TestWatcher { assumeNoException(e); } - return new Statement() { @Override diff --git a/src/test/java/org/springframework/integration/aws/config/xml/S3InboundChannelAdapterParserTests.java b/src/test/java/org/springframework/integration/aws/config/xml/S3InboundChannelAdapterParserTests.java index 23daa63..e598838 100644 --- a/src/test/java/org/springframework/integration/aws/config/xml/S3InboundChannelAdapterParserTests.java +++ b/src/test/java/org/springframework/integration/aws/config/xml/S3InboundChannelAdapterParserTests.java @@ -89,9 +89,9 @@ public class S3InboundChannelAdapterParserTests { S3InboundFileSynchronizer fisync = TestUtils.getPropertyValue(inbound, "synchronizer", S3InboundFileSynchronizer.class); - assertThat(TestUtils.getPropertyValue(fisync, "remoteDirectoryExpression", Expression.class) - .getExpressionString()) - .isEqualTo("'foo/bar'"); + assertThat( + TestUtils.getPropertyValue(fisync, "remoteDirectoryExpression", Expression.class).getExpressionString()) + .isEqualTo("'foo/bar'"); assertThat(TestUtils.getPropertyValue(fisync, "localFilenameGeneratorExpression")).isNotNull(); assertThat(TestUtils.getPropertyValue(fisync, "preserveTimestamp", Boolean.class)).isTrue(); assertThat(TestUtils.getPropertyValue(fisync, "temporaryFileSuffix", String.class)).isEqualTo(".foo"); @@ -111,8 +111,7 @@ public class S3InboundChannelAdapterParserTests { assertThat(TestUtils.getPropertyValue(fisync, "remoteFileTemplate.sessionFactory")) .isSameAs(this.s3SessionFactory); assertThat(TestUtils.getPropertyValue(inbound, "fileSource.scanner.filter.fileFilters", Collection.class) - .contains(this.acceptAllFilter)) - .isTrue(); + .contains(this.acceptAllFilter)).isTrue(); final AtomicReference genMethod = new AtomicReference(); ReflectionUtils.doWithMethods(AbstractInboundFileSynchronizer.class, new ReflectionUtils.MethodCallback() { diff --git a/src/test/java/org/springframework/integration/aws/config/xml/S3MessageHandlerParserTests.java b/src/test/java/org/springframework/integration/aws/config/xml/S3MessageHandlerParserTests.java index 148a21c..64629a4 100644 --- a/src/test/java/org/springframework/integration/aws/config/xml/S3MessageHandlerParserTests.java +++ b/src/test/java/org/springframework/integration/aws/config/xml/S3MessageHandlerParserTests.java @@ -91,20 +91,16 @@ public class S3MessageHandlerParserTests { public void testS3OutboundChannelAdapterParser() { assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, "transferManager.s3")) .isSameAs(this.amazonS3); - assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, - "bucketExpression.literalValue")) + assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, "bucketExpression.literalValue")) .isEqualTo("foo"); assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, - "destinationBucketExpression.expression")) - .isEqualTo("'bar'"); - assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, - "destinationKeyExpression.expression")) - .isEqualTo("'baz'"); - assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, - "keyExpression.expression")) + "destinationBucketExpression.expression")).isEqualTo("'bar'"); + assertThat( + TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, "destinationKeyExpression.expression")) + .isEqualTo("'baz'"); + assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, "keyExpression.expression")) .isEqualTo("payload.name"); - assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, - "objectAclExpression.expression")) + assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, "objectAclExpression.expression")) .isEqualTo("'qux'"); assertThat(TestUtils.getPropertyValue(this.s3OutboundChannelAdapterHandler, "commandExpression.literalValue")) .isEqualTo(S3MessageHandler.Command.COPY.name()); @@ -132,17 +128,16 @@ public class S3MessageHandlerParserTests { public void testS3OutboundGatewayParser() { assertThat(TestUtils.getPropertyValue(this.s3OutboundGatewayHandler, "transferManager")) .isSameAs(this.transferManager); - assertThat(TestUtils.getPropertyValue(this.s3OutboundGatewayHandler, - "bucketExpression.expression")) + assertThat(TestUtils.getPropertyValue(this.s3OutboundGatewayHandler, "bucketExpression.expression")) .isEqualTo("'FOO'"); - Expression commandExpression = - TestUtils.getPropertyValue(this.s3OutboundGatewayHandler, "commandExpression", Expression.class); + Expression commandExpression = TestUtils.getPropertyValue(this.s3OutboundGatewayHandler, "commandExpression", + Expression.class); assertThat(TestUtils.getPropertyValue(commandExpression, "expression")) .isEqualTo("'" + S3MessageHandler.Command.DOWNLOAD.name() + "'"); StandardEvaluationContext evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.beanFactory); - S3MessageHandler.Command command = - commandExpression.getValue(evaluationContext, S3MessageHandler.Command.class); + S3MessageHandler.Command command = commandExpression.getValue(evaluationContext, + S3MessageHandler.Command.class); assertThat(command).isEqualTo(S3MessageHandler.Command.DOWNLOAD); diff --git a/src/test/java/org/springframework/integration/aws/config/xml/S3StreamingInboundChannelAdapterParserTests.java b/src/test/java/org/springframework/integration/aws/config/xml/S3StreamingInboundChannelAdapterParserTests.java index 02f0ae2..4c94a51 100644 --- a/src/test/java/org/springframework/integration/aws/config/xml/S3StreamingInboundChannelAdapterParserTests.java +++ b/src/test/java/org/springframework/integration/aws/config/xml/S3StreamingInboundChannelAdapterParserTests.java @@ -73,9 +73,9 @@ public class S3StreamingInboundChannelAdapterParserTests { S3StreamingMessageSource source = TestUtils.getPropertyValue(this.s3Inbound, "source", S3StreamingMessageSource.class); - assertThat(TestUtils.getPropertyValue(source, "remoteDirectoryExpression", Expression.class) - .getExpressionString()) - .isEqualTo("foo/bar"); + assertThat( + TestUtils.getPropertyValue(source, "remoteDirectoryExpression", Expression.class).getExpressionString()) + .isEqualTo("foo/bar"); assertThat(TestUtils.getPropertyValue(source, "comparator")).isSameAs(this.comparator); String remoteFileSeparator = (String) TestUtils.getPropertyValue(source, "remoteFileSeparator"); diff --git a/src/test/java/org/springframework/integration/aws/config/xml/SnsInboundChannelAdapterParserTests.java b/src/test/java/org/springframework/integration/aws/config/xml/SnsInboundChannelAdapterParserTests.java index 0e3d0e9..307185d 100644 --- a/src/test/java/org/springframework/integration/aws/config/xml/SnsInboundChannelAdapterParserTests.java +++ b/src/test/java/org/springframework/integration/aws/config/xml/SnsInboundChannelAdapterParserTests.java @@ -54,17 +54,14 @@ public class SnsInboundChannelAdapterParserTests { @Qualifier("snsInboundChannelAdapter") private SnsInboundChannelAdapter snsInboundChannelAdapter; - @Test public void testSnsInboundChannelAdapterParser() { assertThat(TestUtils.getPropertyValue(this.snsInboundChannelAdapter, "notificationStatusResolver.amazonSns")) .isSameAs(this.amazonSns); - assertThat(TestUtils.getPropertyValue(this.snsInboundChannelAdapter, "handleNotificationStatus", - Boolean.class)) + assertThat(TestUtils.getPropertyValue(this.snsInboundChannelAdapter, "handleNotificationStatus", Boolean.class)) .isTrue(); assertThat(TestUtils.getPropertyValue(this.snsInboundChannelAdapter, "requestMapping.pathPatterns", - String[].class)) - .isEqualTo(new String[] { "/foo" }); + String[].class)).isEqualTo(new String[] { "/foo" }); assertThat(TestUtils.getPropertyValue(this.snsInboundChannelAdapter, "payloadExpression.expression")) .isEqualTo("payload.Message"); assertThat(this.snsInboundChannelAdapter.isRunning()).isFalse(); diff --git a/src/test/java/org/springframework/integration/aws/config/xml/SnsOutboundChannelAdapterParserTests.java b/src/test/java/org/springframework/integration/aws/config/xml/SnsOutboundChannelAdapterParserTests.java index 6e792a6..e8d8cd4 100644 --- a/src/test/java/org/springframework/integration/aws/config/xml/SnsOutboundChannelAdapterParserTests.java +++ b/src/test/java/org/springframework/integration/aws/config/xml/SnsOutboundChannelAdapterParserTests.java @@ -79,8 +79,7 @@ public class SnsOutboundChannelAdapterParserTests { public void testSnsOutboundChannelAdapterDefaultParser() { Object handler = TestUtils.getPropertyValue(this.defaultAdapter, "handler"); - assertThat(TestUtils.getPropertyValue(this.defaultAdapter, "inputChannel")) - .isSameAs(this.notificationChannel); + assertThat(TestUtils.getPropertyValue(this.defaultAdapter, "inputChannel")).isSameAs(this.notificationChannel); assertThat(TestUtils.getPropertyValue(this.defaultAdapterHandler, "amazonSns")).isSameAs(this.amazonSns); assertThat(TestUtils.getPropertyValue(this.defaultAdapterHandler, "evaluationContext")).isNotNull(); @@ -101,14 +100,11 @@ public class SnsOutboundChannelAdapterParserTests { assertThat(TestUtils.getPropertyValue(this.defaultAdapterHandler, "errorMessageStrategy")) .isSameAs(this.errorMessageStrategy); - assertThat(TestUtils.getPropertyValue(this.defaultAdapterHandler, "asyncHandler")) - .isSameAs(this.asyncHandler); + assertThat(TestUtils.getPropertyValue(this.defaultAdapterHandler, "asyncHandler")).isSameAs(this.asyncHandler); - assertThat(TestUtils.getPropertyValue(this.defaultAdapterHandler, "sync", Boolean.class)) - .isFalse(); + assertThat(TestUtils.getPropertyValue(this.defaultAdapterHandler, "sync", Boolean.class)).isFalse(); - assertThat(TestUtils.getPropertyValue(this.defaultAdapterHandler, - "sendTimeoutExpression.literalValue")) + assertThat(TestUtils.getPropertyValue(this.defaultAdapterHandler, "sendTimeoutExpression.literalValue")) .isEqualTo("202"); } diff --git a/src/test/java/org/springframework/integration/aws/config/xml/SqsMessageDrivenChannelAdapterParserTests.java b/src/test/java/org/springframework/integration/aws/config/xml/SqsMessageDrivenChannelAdapterParserTests.java index 8c3457b..1f3784e 100644 --- a/src/test/java/org/springframework/integration/aws/config/xml/SqsMessageDrivenChannelAdapterParserTests.java +++ b/src/test/java/org/springframework/integration/aws/config/xml/SqsMessageDrivenChannelAdapterParserTests.java @@ -75,17 +75,14 @@ public class SqsMessageDrivenChannelAdapterParserTests { @Bean public DestinationResolver destinationResolver() { DestinationResolver destinationResolver = Mockito.mock(DestinationResolver.class); - willThrow(DestinationResolutionException.class) - .given(destinationResolver) - .resolveDestination(anyString()); + willThrow(DestinationResolutionException.class).given(destinationResolver).resolveDestination(anyString()); return destinationResolver; } @Test public void testSqsMessageDrivenChannelAdapterParser() { - SimpleMessageListenerContainer listenerContainer = - TestUtils.getPropertyValue(this.sqsMessageDrivenChannelAdapter, "listenerContainer", - SimpleMessageListenerContainer.class); + SimpleMessageListenerContainer listenerContainer = TestUtils.getPropertyValue( + this.sqsMessageDrivenChannelAdapter, "listenerContainer", SimpleMessageListenerContainer.class); assertThat(TestUtils.getPropertyValue(listenerContainer, "amazonSqs")).isSameAs(this.amazonSqs); assertThat(TestUtils.getPropertyValue(listenerContainer, "resourceIdResolver")) .isSameAs(this.resourceIdResolver); @@ -106,12 +103,10 @@ public class SqsMessageDrivenChannelAdapterParserTests { .isSameAs(this.errorChannel); assertThat(TestUtils.getPropertyValue(this.sqsMessageDrivenChannelAdapter, "errorChannel")) .isSameAs(this.nullChannel); - assertThat(TestUtils.getPropertyValue(this.sqsMessageDrivenChannelAdapter, - "messagingTemplate.sendTimeout")) + assertThat(TestUtils.getPropertyValue(this.sqsMessageDrivenChannelAdapter, "messagingTemplate.sendTimeout")) .isEqualTo(2000L); assertThat(TestUtils.getPropertyValue(this.sqsMessageDrivenChannelAdapter, "messageDeletionPolicy", - SqsMessageDeletionPolicy.class)) - .isEqualTo(SqsMessageDeletionPolicy.NEVER); + SqsMessageDeletionPolicy.class)).isEqualTo(SqsMessageDeletionPolicy.NEVER); } } diff --git a/src/test/java/org/springframework/integration/aws/config/xml/SqsMessageHandlerParserTests.java b/src/test/java/org/springframework/integration/aws/config/xml/SqsMessageHandlerParserTests.java index 05db682..44be060 100644 --- a/src/test/java/org/springframework/integration/aws/config/xml/SqsMessageHandlerParserTests.java +++ b/src/test/java/org/springframework/integration/aws/config/xml/SqsMessageHandlerParserTests.java @@ -81,10 +81,8 @@ public class SqsMessageHandlerParserTests { assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, "amazonSqs")) .isSameAs(this.amazonSqs); assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, - "destinationResolver.resourceIdResolver")) - .isSameAs(this.resourceIdResolver); - assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, - "queueExpression.literalValue")) + "destinationResolver.resourceIdResolver")).isSameAs(this.resourceIdResolver); + assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, "queueExpression.literalValue")) .isEqualTo("foo"); assertThat(this.sqsOutboundChannelAdapter.getPhase()).isEqualTo(100); assertThat(this.sqsOutboundChannelAdapter.isAutoStartup()).isFalse(); @@ -94,17 +92,14 @@ public class SqsMessageHandlerParserTests { assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapter, "handler")) .isSameAs(this.sqsOutboundChannelAdapterHandler); - assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, - "delayExpression.expression")) + assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, "delayExpression.expression")) .isEqualTo("'200'"); assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, - "messageDeduplicationIdExpression.literalValue")) - .isEqualTo("foo"); + "messageDeduplicationIdExpression.literalValue")).isEqualTo("foo"); assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, - "messageGroupIdExpression.expression")) - .isEqualTo("'bar'"); + "messageGroupIdExpression.expression")).isEqualTo("'bar'"); assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, "failureChannel")) .isSameAs(this.failureChannel); @@ -121,12 +116,11 @@ public class SqsMessageHandlerParserTests { assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, "asyncHandler")) .isSameAs(this.asyncHandler); - assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, "sync", Boolean.class)) - .isFalse(); + assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, "sync", Boolean.class)).isFalse(); - assertThat(TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, - "sendTimeoutExpression.literalValue")) - .isEqualTo("202"); + assertThat( + TestUtils.getPropertyValue(this.sqsOutboundChannelAdapterHandler, "sendTimeoutExpression.literalValue")) + .isEqualTo("202"); } } diff --git a/src/test/java/org/springframework/integration/aws/inbound/KinesisMessageDrivenChannelAdapterTests.java b/src/test/java/org/springframework/integration/aws/inbound/KinesisMessageDrivenChannelAdapterTests.java index 2126b7b..b2d405b 100644 --- a/src/test/java/org/springframework/integration/aws/inbound/KinesisMessageDrivenChannelAdapterTests.java +++ b/src/test/java/org/springframework/integration/aws/inbound/KinesisMessageDrivenChannelAdapterTests.java @@ -73,7 +73,6 @@ import com.amazonaws.services.kinesis.model.StreamStatus; /** * @author Artem Bilan - * * @since 1.1 */ @RunWith(SpringRunner.class) @@ -108,9 +107,8 @@ public class KinesisMessageDrivenChannelAdapterTests { @SuppressWarnings({ "unchecked", "rawtypes" }) public void testKinesisMessageDrivenChannelAdapter() { this.kinesisMessageDrivenChannelAdapter.start(); - final Set shardOffsets = - TestUtils.getPropertyValue(this.kinesisMessageDrivenChannelAdapter, "shardOffsets", Set.class); - + final Set shardOffsets = TestUtils.getPropertyValue(this.kinesisMessageDrivenChannelAdapter, + "shardOffsets", Set.class); KinesisShardOffset testOffset1 = KinesisShardOffset.latest(STREAM1, "1"); KinesisShardOffset testOffset2 = KinesisShardOffset.latest(STREAM1, "2"); @@ -119,8 +117,8 @@ public class KinesisMessageDrivenChannelAdapterTests { assertThat(shardOffsets).doesNotContain(KinesisShardOffset.latest(STREAM1, "3")); } - Map shardConsumers = - TestUtils.getPropertyValue(this.kinesisMessageDrivenChannelAdapter, "shardConsumers", Map.class); + Map shardConsumers = TestUtils.getPropertyValue(this.kinesisMessageDrivenChannelAdapter, + "shardConsumers", Map.class); await().untilAsserted(() -> assertThat(shardConsumers.keySet()).contains(testOffset1, testOffset2)); @@ -154,14 +152,13 @@ public class KinesisMessageDrivenChannelAdapterTests { this.kinesisMessageDrivenChannelAdapter.stop(); - Map forLocking = - TestUtils.getPropertyValue(this.kinesisMessageDrivenChannelAdapter, - "shardConsumerManager.locks", Map.class); + Map forLocking = TestUtils.getPropertyValue(this.kinesisMessageDrivenChannelAdapter, + "shardConsumerManager.locks", Map.class); await().untilAsserted(() -> assertThat(forLocking).hasSize(0)); - final List consumerInvokers = - TestUtils.getPropertyValue(this.kinesisMessageDrivenChannelAdapter, "consumerInvokers", List.class); + final List consumerInvokers = TestUtils.getPropertyValue(this.kinesisMessageDrivenChannelAdapter, + "consumerInvokers", List.class); await().untilAsserted(() -> assertThat(consumerInvokers).hasSize(0)); this.kinesisMessageDrivenChannelAdapter.setListenerMode(ListenerMode.batch); @@ -186,8 +183,9 @@ public class KinesisMessageDrivenChannelAdapterTests { assertThat(sequenceNumberHeader).isInstanceOf(List.class); assertThat((List) sequenceNumberHeader).contains("2"); - await().untilAsserted(() -> - assertThat(this.checkpointStore.get("SpringIntegration" + ":" + STREAM1 + ":" + "1")).isEqualTo("2")); + await().untilAsserted( + () -> assertThat(this.checkpointStore.get("SpringIntegration" + ":" + STREAM1 + ":" + "1")) + .isEqualTo("2")); assertThat(TestUtils.getPropertyValue(this.kinesisMessageDrivenChannelAdapter, "consumerInvokers", List.class)) .hasSize(2); @@ -195,7 +193,6 @@ public class KinesisMessageDrivenChannelAdapterTests { this.kinesisMessageDrivenChannelAdapter.stop(); } - @Test @SuppressWarnings("rawtypes") public void testReshadring() throws InterruptedException { @@ -225,44 +222,29 @@ public class KinesisMessageDrivenChannelAdapterTests { public AmazonKinesis amazonKinesis() { AmazonKinesis amazonKinesis = mock(AmazonKinesis.class); - given(amazonKinesis.describeStream(new DescribeStreamRequest().withStreamName(STREAM1))) - .willReturn(new DescribeStreamResult() - .withStreamDescription(new StreamDescription() - .withStreamName(STREAM1) - .withStreamStatus(StreamStatus.UPDATING)), - new DescribeStreamResult() - .withStreamDescription(new StreamDescription() - .withStreamName(STREAM1) - .withStreamStatus(StreamStatus.ACTIVE) - .withHasMoreShards(false) - .withShards(new Shard() - .withShardId("1") - .withSequenceNumberRange(new SequenceNumberRange()), - new Shard() - .withShardId("2") - .withSequenceNumberRange(new SequenceNumberRange()), - new Shard() - .withShardId("3") - .withSequenceNumberRange(new SequenceNumberRange() - .withEndingSequenceNumber("1"))))); + given(amazonKinesis.describeStream(new DescribeStreamRequest().withStreamName(STREAM1))).willReturn( + new DescribeStreamResult().withStreamDescription( + new StreamDescription().withStreamName(STREAM1).withStreamStatus(StreamStatus.UPDATING)), + new DescribeStreamResult().withStreamDescription(new StreamDescription().withStreamName(STREAM1) + .withStreamStatus(StreamStatus.ACTIVE).withHasMoreShards(false) + .withShards(new Shard().withShardId("1").withSequenceNumberRange(new SequenceNumberRange()), + new Shard().withShardId("2").withSequenceNumberRange(new SequenceNumberRange()), + new Shard().withShardId("3").withSequenceNumberRange( + new SequenceNumberRange().withEndingSequenceNumber("1"))))); String shard1Iterator1 = "shard1Iterator1"; String shard1Iterator2 = "shard1Iterator2"; given(amazonKinesis.getShardIterator(KinesisShardOffset.latest(STREAM1, "1").toShardIteratorRequest())) - .willReturn( - new GetShardIteratorResult().withShardIterator(shard1Iterator1), + .willReturn(new GetShardIteratorResult().withShardIterator(shard1Iterator1), new GetShardIteratorResult().withShardIterator(shard1Iterator2)); String shard2Iterator1 = "shard2Iterator1"; given(amazonKinesis.getShardIterator(KinesisShardOffset.latest(STREAM1, "2").toShardIteratorRequest())) - .willReturn(new GetShardIteratorResult() - .withShardIterator(shard2Iterator1)); + .willReturn(new GetShardIteratorResult().withShardIterator(shard2Iterator1)); - given(amazonKinesis.getRecords(new GetRecordsRequest() - .withShardIterator(shard1Iterator1) - .withLimit(25))) + given(amazonKinesis.getRecords(new GetRecordsRequest().withShardIterator(shard1Iterator1).withLimit(25))) .willThrow(new ProvisionedThroughputExceededException("Iterator throttled")) .willThrow(new ExpiredIteratorException("Iterator expired")); @@ -270,47 +252,28 @@ public class KinesisMessageDrivenChannelAdapterTests { String shard1Iterator3 = "shard1Iterator3"; - given(amazonKinesis.getRecords(new GetRecordsRequest() - .withShardIterator(shard1Iterator2) - .withLimit(25))) - .willReturn(new GetRecordsResult() - .withNextShardIterator(shard1Iterator3) - .withRecords(new Record() - .withPartitionKey("partition1") - .withSequenceNumber("1") - .withData(ByteBuffer.wrap(serializingConverter.convert("foo"))), - new Record() - .withPartitionKey("partition1") - .withSequenceNumber("2") - .withData(ByteBuffer.wrap(serializingConverter.convert("bar"))))); + given(amazonKinesis.getRecords(new GetRecordsRequest().withShardIterator(shard1Iterator2).withLimit(25))) + .willReturn(new GetRecordsResult().withNextShardIterator(shard1Iterator3).withRecords( + new Record().withPartitionKey("partition1").withSequenceNumber("1") + .withData(ByteBuffer.wrap(serializingConverter.convert("foo"))), + new Record().withPartitionKey("partition1").withSequenceNumber("2") + .withData(ByteBuffer.wrap(serializingConverter.convert("bar"))))); - given(amazonKinesis.getRecords(new GetRecordsRequest() - .withShardIterator(shard2Iterator1) - .withLimit(25))) - .willReturn(new GetRecordsResult() - .withNextShardIterator(shard2Iterator1)); + given(amazonKinesis.getRecords(new GetRecordsRequest().withShardIterator(shard2Iterator1).withLimit(25))) + .willReturn(new GetRecordsResult().withNextShardIterator(shard2Iterator1)); - given(amazonKinesis.getRecords(new GetRecordsRequest() - .withShardIterator(shard1Iterator3) - .withLimit(25))) - .willReturn(new GetRecordsResult() - .withNextShardIterator(shard1Iterator3)); + given(amazonKinesis.getRecords(new GetRecordsRequest().withShardIterator(shard1Iterator3).withLimit(25))) + .willReturn(new GetRecordsResult().withNextShardIterator(shard1Iterator3)); String shard1Iterator4 = "shard1Iterator4"; - given(amazonKinesis.getShardIterator(KinesisShardOffset.afterSequenceNumber(STREAM1, "1", "1") - .toShardIteratorRequest())) - .willReturn(new GetShardIteratorResult() - .withShardIterator(shard1Iterator4)); + given(amazonKinesis.getShardIterator( + KinesisShardOffset.afterSequenceNumber(STREAM1, "1", "1").toShardIteratorRequest())) + .willReturn(new GetShardIteratorResult().withShardIterator(shard1Iterator4)); - given(amazonKinesis.getRecords(new GetRecordsRequest() - .withShardIterator(shard1Iterator4) - .withLimit(25))) - .willReturn(new GetRecordsResult() - .withNextShardIterator(shard1Iterator3) - .withRecords(new Record() - .withPartitionKey("partition1") - .withSequenceNumber("2") + given(amazonKinesis.getRecords(new GetRecordsRequest().withShardIterator(shard1Iterator4).withLimit(25))) + .willReturn(new GetRecordsResult().withNextShardIterator(shard1Iterator3) + .withRecords(new Record().withPartitionKey("partition1").withSequenceNumber("2") .withData(ByteBuffer.wrap(serializingConverter.convert("bar"))))); return amazonKinesis; @@ -326,8 +289,8 @@ public class KinesisMessageDrivenChannelAdapterTests { @Bean public KinesisMessageDrivenChannelAdapter kinesisMessageDrivenChannelAdapter() { - KinesisMessageDrivenChannelAdapter adapter = - new KinesisMessageDrivenChannelAdapter(amazonKinesis(), STREAM1); + KinesisMessageDrivenChannelAdapter adapter = new KinesisMessageDrivenChannelAdapter(amazonKinesis(), + STREAM1); adapter.setAutoStartup(false); adapter.setOutputChannel(kinesisChannel()); adapter.setCheckpointStore(checkpointStore()); @@ -356,34 +319,21 @@ public class KinesisMessageDrivenChannelAdapterTests { AmazonKinesis amazonKinesis = mock(AmazonKinesis.class); given(amazonKinesis.describeStream(new DescribeStreamRequest().withStreamName(STREAM_FOR_RESHARDING))) - .willReturn( - new DescribeStreamResult() - .withStreamDescription(new StreamDescription() - .withStreamName(STREAM_FOR_RESHARDING) - .withStreamStatus(StreamStatus.ACTIVE) - .withHasMoreShards(false) - .withShards(new Shard() - .withShardId("closedShard") - .withSequenceNumberRange(new SequenceNumberRange() - .withEndingSequenceNumber("1"))))); + .willReturn(new DescribeStreamResult() + .withStreamDescription(new StreamDescription().withStreamName(STREAM_FOR_RESHARDING) + .withStreamStatus(StreamStatus.ACTIVE).withHasMoreShards(false) + .withShards(new Shard().withShardId("closedShard").withSequenceNumberRange( + new SequenceNumberRange().withEndingSequenceNumber("1"))))); String shard1Iterator1 = "shard1Iterator1"; - given(amazonKinesis.getShardIterator(KinesisShardOffset.latest(STREAM_FOR_RESHARDING, "closedShard") - .toShardIteratorRequest())) - .willReturn( - new GetShardIteratorResult() - .withShardIterator(shard1Iterator1)); + given(amazonKinesis.getShardIterator( + KinesisShardOffset.latest(STREAM_FOR_RESHARDING, "closedShard").toShardIteratorRequest())) + .willReturn(new GetShardIteratorResult().withShardIterator(shard1Iterator1)); - - given(amazonKinesis.getRecords(new GetRecordsRequest() - .withShardIterator(shard1Iterator1) - .withLimit(25))) - .willReturn(new GetRecordsResult() - .withNextShardIterator(null) - .withRecords(new Record() - .withPartitionKey("partition1") - .withSequenceNumber("1") + given(amazonKinesis.getRecords(new GetRecordsRequest().withShardIterator(shard1Iterator1).withLimit(25))) + .willReturn(new GetRecordsResult().withNextShardIterator(null) + .withRecords(new Record().withPartitionKey("partition1").withSequenceNumber("1") .withData(ByteBuffer.wrap("foo".getBytes())))); return amazonKinesis; @@ -391,8 +341,8 @@ public class KinesisMessageDrivenChannelAdapterTests { @Bean public KinesisMessageDrivenChannelAdapter reshardingChannelAdapter() { - KinesisMessageDrivenChannelAdapter adapter = - new KinesisMessageDrivenChannelAdapter(amazonKinesisForResharding(), STREAM_FOR_RESHARDING); + KinesisMessageDrivenChannelAdapter adapter = new KinesisMessageDrivenChannelAdapter( + amazonKinesisForResharding(), STREAM_FOR_RESHARDING); adapter.setAutoStartup(false); adapter.setOutputChannel(kinesisChannel()); adapter.setStartTimeout(10000); diff --git a/src/test/java/org/springframework/integration/aws/inbound/S3InboundChannelAdapterTests.java b/src/test/java/org/springframework/integration/aws/inbound/S3InboundChannelAdapterTests.java index db2bf47..2409de9 100644 --- a/src/test/java/org/springframework/integration/aws/inbound/S3InboundChannelAdapterTests.java +++ b/src/test/java/org/springframework/integration/aws/inbound/S3InboundChannelAdapterTests.java @@ -178,8 +178,8 @@ public class S3InboundChannelAdapterTests { synchronizer.setPreserveTimestamp(true); synchronizer.setRemoteDirectory(S3_BUCKET); synchronizer.setFilter(new S3RegexPatternFileListFilter(".*\\.test$")); - Expression expression = - PARSER.parseExpression("(#this.contains('/') ? #this.substring(#this.lastIndexOf('/') + 1) : #this).toUpperCase() + '.a'"); + Expression expression = PARSER.parseExpression( + "(#this.contains('/') ? #this.substring(#this.lastIndexOf('/') + 1) : #this).toUpperCase() + '.a'"); synchronizer.setLocalFilenameGeneratorExpression(expression); return synchronizer; } @@ -187,8 +187,8 @@ public class S3InboundChannelAdapterTests { @Bean @InboundChannelAdapter(value = "s3FilesChannel", poller = @Poller(fixedDelay = "100")) public S3InboundFileSynchronizingMessageSource s3InboundFileSynchronizingMessageSource() { - S3InboundFileSynchronizingMessageSource messageSource = - new S3InboundFileSynchronizingMessageSource(s3InboundFileSynchronizer()); + S3InboundFileSynchronizingMessageSource messageSource = new S3InboundFileSynchronizingMessageSource( + s3InboundFileSynchronizer()); messageSource.setAutoCreateLocalDirectory(true); messageSource.setLocalDirectory(LOCAL_FOLDER); messageSource.setLocalFilter(new AcceptOnceFileListFilter()); diff --git a/src/test/java/org/springframework/integration/aws/inbound/S3StreamingChannelAdapterTests.java b/src/test/java/org/springframework/integration/aws/inbound/S3StreamingChannelAdapterTests.java index 2c775c7..5a575fc 100644 --- a/src/test/java/org/springframework/integration/aws/inbound/S3StreamingChannelAdapterTests.java +++ b/src/test/java/org/springframework/integration/aws/inbound/S3StreamingChannelAdapterTests.java @@ -66,7 +66,6 @@ import com.amazonaws.services.s3.model.S3ObjectSummary; /** * @author Christian Tzolov * @author Artem Bilan - * * @since 1.1 */ @RunWith(SpringJUnit4ClassRunner.class) @@ -154,7 +153,6 @@ public class S3StreamingChannelAdapterTests { return amazonS3; } - @Bean @InboundChannelAdapter(value = "s3FilesChannel", poller = @Poller(fixedDelay = "100")) public S3StreamingMessageSource s3InboundStreamingMessageSource(AmazonS3 amazonS3) { @@ -163,8 +161,7 @@ public class S3StreamingChannelAdapterTests { S3StreamingMessageSource s3MessageSource = new S3StreamingMessageSource(s3FileTemplate, Comparator.comparing(S3ObjectSummary::getKey)); s3MessageSource.setRemoteDirectory("/" + S3_BUCKET + "/subdir"); - s3MessageSource.setFilter(new S3PersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "streaming" - )); + s3MessageSource.setFilter(new S3PersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "streaming")); return s3MessageSource; } diff --git a/src/test/java/org/springframework/integration/aws/inbound/SnsInboundChannelAdapterTests.java b/src/test/java/org/springframework/integration/aws/inbound/SnsInboundChannelAdapterTests.java index dd5abd2..69e112b 100644 --- a/src/test/java/org/springframework/integration/aws/inbound/SnsInboundChannelAdapterTests.java +++ b/src/test/java/org/springframework/integration/aws/inbound/SnsInboundChannelAdapterTests.java @@ -89,9 +89,8 @@ public class SnsInboundChannelAdapterTests { @Test public void testSubscriptionConfirmation() throws Exception { - this.mockMvc.perform( - post("/mySampleTopic") - .header("x-amz-sns-message-type", "SubscriptionConfirmation") + this.mockMvc + .perform(post("/mySampleTopic").header("x-amz-sns-message-type", "SubscriptionConfirmation") .contentType(MediaType.APPLICATION_JSON) .content(StreamUtils.copyToByteArray(this.subscriptionConfirmation.getInputStream()))) .andExpect(status().isNoContent()); @@ -107,16 +106,14 @@ public class SnsInboundChannelAdapterTests { notificationStatus.confirmSubscription(); - verify(this.amazonSns) - .confirmSubscription("arn:aws:sns:eu-west-1:111111111111:mySampleTopic", "111"); + verify(this.amazonSns).confirmSubscription("arn:aws:sns:eu-west-1:111111111111:mySampleTopic", "111"); } @Test @SuppressWarnings("unchecked") public void testNotification() throws Exception { - this.mockMvc.perform( - post("/mySampleTopic") - .header("x-amz-sns-message-type", "Notification") + this.mockMvc + .perform(post("/mySampleTopic").header("x-amz-sns-message-type", "Notification") .contentType(MediaType.TEXT_PLAIN) .content(StreamUtils.copyToByteArray(this.notificationMessage.getInputStream()))) .andExpect(status().isNoContent()); @@ -131,9 +128,8 @@ public class SnsInboundChannelAdapterTests { @Test public void testUnsubscribe() throws Exception { - this.mockMvc.perform( - post("/mySampleTopic") - .header("x-amz-sns-message-type", "UnsubscribeConfirmation") + this.mockMvc + .perform(post("/mySampleTopic").header("x-amz-sns-message-type", "UnsubscribeConfirmation") .contentType(MediaType.TEXT_PLAIN) .content(StreamUtils.copyToByteArray(this.unsubscribeConfirmation.getInputStream()))) .andExpect(status().isNoContent()); @@ -149,8 +145,7 @@ public class SnsInboundChannelAdapterTests { notificationStatus.confirmSubscription(); - verify(this.amazonSns) - .confirmSubscription("arn:aws:sns:eu-west-1:111111111111:mySampleTopic", "233"); + verify(this.amazonSns).confirmSubscription("arn:aws:sns:eu-west-1:111111111111:mySampleTopic", "233"); } @Configuration diff --git a/src/test/java/org/springframework/integration/aws/inbound/SqsMessageDrivenChannelAdapterTests.java b/src/test/java/org/springframework/integration/aws/inbound/SqsMessageDrivenChannelAdapterTests.java index 580fecf..296c692 100644 --- a/src/test/java/org/springframework/integration/aws/inbound/SqsMessageDrivenChannelAdapterTests.java +++ b/src/test/java/org/springframework/integration/aws/inbound/SqsMessageDrivenChannelAdapterTests.java @@ -73,9 +73,9 @@ public class SqsMessageDrivenChannelAdapterTests { @Test public void testSqsMessageDrivenChannelAdapter() { - assertThat(TestUtils.getPropertyValue(this.sqsMessageDrivenChannelAdapter, - "listenerContainer.queueStopTimeout")) - .isEqualTo(10000L); + assertThat( + TestUtils.getPropertyValue(this.sqsMessageDrivenChannelAdapter, "listenerContainer.queueStopTimeout")) + .isEqualTo(10000L); org.springframework.messaging.Message receive = this.inputChannel.receive(1000); assertThat(receive).isNotNull(); assertThat((String) receive.getPayload()).isIn("messageContent", "messageContent2"); @@ -89,7 +89,8 @@ public class SqsMessageDrivenChannelAdapterTests { this.controlBusInput.send(new GenericMessage<>("@sqsMessageDrivenChannelAdapter.stop('testQueue')")); } catch (Exception e) { - // May fail with NPE. See https://github.com/spring-cloud/spring-cloud-aws/issues/232 + // May fail with NPE. See + // https://github.com/spring-cloud/spring-cloud-aws/issues/232 } this.controlBusInput.send(new GenericMessage<>("@sqsMessageDrivenChannelAdapter.isRunning('testQueue')")); @@ -104,10 +105,10 @@ public class SqsMessageDrivenChannelAdapterTests { assertThat(receive).isNotNull(); assertThat((Boolean) receive.getPayload()).isTrue(); - assertThatThrownBy(() -> - this.controlBusInput.send(new GenericMessage<>("@sqsMessageDrivenChannelAdapter.start('foo')"))) - .hasCauseExactlyInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("Queue with name 'foo' does not exist"); + assertThatThrownBy( + () -> this.controlBusInput.send(new GenericMessage<>("@sqsMessageDrivenChannelAdapter.start('foo')"))) + .hasCauseExactlyInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Queue with name 'foo' does not exist"); assertThat(this.sqsMessageDrivenChannelAdapter.getQueues()).isEqualTo(new String[] { "testQueue" }); } @@ -122,16 +123,13 @@ public class SqsMessageDrivenChannelAdapterTests { given(sqs.getQueueUrl(new GetQueueUrlRequest("testQueue"))) .willReturn(new GetQueueUrlResult().withQueueUrl("http://testQueue.amazonaws.com")); - - given(sqs.receiveMessage(new ReceiveMessageRequest("http://testQueue.amazonaws.com") - .withAttributeNames("All") - .withMessageAttributeNames("All") - .withMaxNumberOfMessages(10) - .withWaitTimeSeconds(20))) - .willReturn(new ReceiveMessageResult() - .withMessages(new Message().withBody("messageContent"), - new Message().withBody("messageContent2"))) - .willReturn(new ReceiveMessageResult()); + given(sqs.receiveMessage( + new ReceiveMessageRequest("http://testQueue.amazonaws.com").withAttributeNames("All") + .withMessageAttributeNames("All").withMaxNumberOfMessages(10).withWaitTimeSeconds(20))) + .willReturn(new ReceiveMessageResult().withMessages( + new Message().withBody("messageContent"), + new Message().withBody("messageContent2"))) + .willReturn(new ReceiveMessageResult()); given(sqs.getQueueAttributes(any(GetQueueAttributesRequest.class))) .willReturn(new GetQueueAttributesResult()); diff --git a/src/test/java/org/springframework/integration/aws/kinesis/KinesisIntegrationTests.java b/src/test/java/org/springframework/integration/aws/kinesis/KinesisIntegrationTests.java index 7a6d51c..647bbe5 100644 --- a/src/test/java/org/springframework/integration/aws/kinesis/KinesisIntegrationTests.java +++ b/src/test/java/org/springframework/integration/aws/kinesis/KinesisIntegrationTests.java @@ -59,7 +59,6 @@ import org.springframework.test.context.junit4.SpringRunner; /** * @author Artem Bilan - * * @since 1.1 */ @RunWith(SpringRunner.class) @@ -92,17 +91,12 @@ public class KinesisIntegrationTests { @Test public void testKinesisInboundOutbound() { - this.kinesisSendChannel.send( - MessageBuilder.withPayload("foo") - .setHeader(AwsHeaders.STREAM, TEST_STREAM) - .build()); + this.kinesisSendChannel + .send(MessageBuilder.withPayload("foo").setHeader(AwsHeaders.STREAM, TEST_STREAM).build()); Date now = new Date(); - this.kinesisSendChannel.send( - MessageBuilder.withPayload(now) - .setHeader(AwsHeaders.STREAM, TEST_STREAM) - .setHeader("foo", "BAR") - .build()); + this.kinesisSendChannel.send(MessageBuilder.withPayload(now).setHeader(AwsHeaders.STREAM, TEST_STREAM) + .setHeader("foo", "BAR").build()); Message receive = this.kinesisReceiveChannel.receive(10_000); assertThat(receive).isNotNull(); @@ -114,20 +108,16 @@ public class KinesisIntegrationTests { assertThat(errorMessage).isNotNull(); assertThat(errorMessage.getHeaders().get(AwsHeaders.RAW_RECORD)).isNotNull(); assertThat(((Exception) errorMessage.getPayload()).getMessage()) - .contains("Channel 'kinesisReceiveChannel' expected one of the following data types " + - "[class java.util.Date], but received [class java.lang.String]"); - + .contains("Channel 'kinesisReceiveChannel' expected one of the following data types " + + "[class java.util.Date], but received [class java.lang.String]"); for (int i = 0; i < 1000; i++) { - this.kinesisSendChannel.send( - MessageBuilder.withPayload(new Date()) - .setHeader(AwsHeaders.STREAM, TEST_STREAM) - .build()); + this.kinesisSendChannel + .send(MessageBuilder.withPayload(new Date()).setHeader(AwsHeaders.STREAM, TEST_STREAM).build()); } Set receivedSequences = new HashSet<>(); - for (int i = 0; i < 1000; i++) { receive = this.kinesisReceiveChannel.receive(10_000); assertThat(receive).isNotNull(); @@ -165,8 +155,8 @@ public class KinesisIntegrationTests { } private KinesisMessageDrivenChannelAdapter kinesisMessageDrivenChannelAdapter() { - KinesisMessageDrivenChannelAdapter adapter = - new KinesisMessageDrivenChannelAdapter(KINESIS_LOCAL_RUNNING.getKinesis(), TEST_STREAM); + KinesisMessageDrivenChannelAdapter adapter = new KinesisMessageDrivenChannelAdapter( + KINESIS_LOCAL_RUNNING.getKinesis(), TEST_STREAM); adapter.setOutputChannel(kinesisReceiveChannel()); adapter.setErrorChannel(errorChannel()); adapter.setErrorMessageStrategy(new KinesisMessageHeaderErrorMessageStrategy()); diff --git a/src/test/java/org/springframework/integration/aws/leader/DynamoDbLockRegistryLeaderInitiatorTests.java b/src/test/java/org/springframework/integration/aws/leader/DynamoDbLockRegistryLeaderInitiatorTests.java index 20d94c8..f4d5647 100644 --- a/src/test/java/org/springframework/integration/aws/leader/DynamoDbLockRegistryLeaderInitiatorTests.java +++ b/src/test/java/org/springframework/integration/aws/leader/DynamoDbLockRegistryLeaderInitiatorTests.java @@ -47,7 +47,6 @@ import com.amazonaws.waiters.WaiterParameters; /** * @author Artem Bilan - * * @since 2.0 */ public class DynamoDbLockRegistryLeaderInitiatorTests { @@ -64,13 +63,11 @@ public class DynamoDbLockRegistryLeaderInitiatorTests { try { dynamoDB.deleteTableAsync(DynamoDbLockRegistry.DEFAULT_TABLE_NAME); - Waiter waiter = - dynamoDB.waiters() - .tableNotExists(); + Waiter waiter = dynamoDB.waiters().tableNotExists(); waiter.run(new WaiterParameters<>(new DescribeTableRequest(DynamoDbLockRegistry.DEFAULT_TABLE_NAME)) - .withPollingStrategy(new PollingStrategy(new MaxAttemptsRetryStrategy(25), - new FixedDelayStrategy(1)))); + .withPollingStrategy( + new PollingStrategy(new MaxAttemptsRetryStrategy(25), new FixedDelayStrategy(1)))); } catch (Exception e) { @@ -93,10 +90,8 @@ public class DynamoDbLockRegistryLeaderInitiatorTests { lockRepository.afterPropertiesSet(); registries.add(lockRepository); - LockRegistryLeaderInitiator initiator = - new LockRegistryLeaderInitiator( - lockRepository, - new DefaultCandidate("foo#" + i, "bar")); + LockRegistryLeaderInitiator initiator = new LockRegistryLeaderInitiator(lockRepository, + new DefaultCandidate("foo#" + i, "bar")); initiator.setExecutorService( Executors.newSingleThreadExecutor(new CustomizableThreadFactory("lock-leadership-" + i + "-"))); initiator.setLeaderEventPublisher(countingPublisher); @@ -136,7 +131,8 @@ public class DynamoDbLockRegistryLeaderInitiatorTests { initiator2.setLeaderEventPublisher(new CountingPublisher(granted2, revoked2, acquireLockFailed2)); - // It's hard to see round-robin election, so let's make the yielding initiator to sleep long before restarting + // It's hard to see round-robin election, so let's make the yielding initiator to + // sleep long before restarting initiator1.setBusyWaitMillis(1000); initiator1.getContext().yield(); @@ -161,8 +157,8 @@ public class DynamoDbLockRegistryLeaderInitiatorTests { initiator2.stop(); CountDownLatch revoked11 = new CountDownLatch(1); - initiator1.setLeaderEventPublisher(new CountingPublisher(new CountDownLatch(1), revoked11, - new CountDownLatch(1))); + initiator1.setLeaderEventPublisher( + new CountingPublisher(new CountDownLatch(1), revoked11, new CountDownLatch(1))); initiator1.getContext().yield(); diff --git a/src/test/java/org/springframework/integration/aws/lock/DynamoDbLockRegistryTests.java b/src/test/java/org/springframework/integration/aws/lock/DynamoDbLockRegistryTests.java index 49501a9..42014cd 100644 --- a/src/test/java/org/springframework/integration/aws/lock/DynamoDbLockRegistryTests.java +++ b/src/test/java/org/springframework/integration/aws/lock/DynamoDbLockRegistryTests.java @@ -51,7 +51,6 @@ import com.amazonaws.waiters.WaiterParameters; /** * @author Artem Bilan - * * @since 2.0 */ @RunWith(SpringRunner.class) @@ -73,13 +72,11 @@ public class DynamoDbLockRegistryTests { try { dynamoDB.deleteTableAsync(DynamoDbLockRegistry.DEFAULT_TABLE_NAME); - Waiter waiter = - dynamoDB.waiters() - .tableNotExists(); + Waiter waiter = dynamoDB.waiters().tableNotExists(); waiter.run(new WaiterParameters<>(new DescribeTableRequest(DynamoDbLockRegistry.DEFAULT_TABLE_NAME)) - .withPollingStrategy(new PollingStrategy(new MaxAttemptsRetryStrategy(25), - new FixedDelayStrategy(1)))); + .withPollingStrategy( + new PollingStrategy(new MaxAttemptsRetryStrategy(25), new FixedDelayStrategy(1)))); } catch (Exception e) { @@ -303,17 +300,16 @@ public class DynamoDbLockRegistryTests { lock.lockInterruptibly(); final AtomicBoolean locked = new AtomicBoolean(); final CountDownLatch latch = new CountDownLatch(1); - Future result = - this.taskExecutor.submit(() -> { - try { - lock.unlock(); - } - catch (Exception e) { - latch.countDown(); - return e; - } - return null; - }); + Future result = this.taskExecutor.submit(() -> { + try { + lock.unlock(); + } + catch (Exception e) { + latch.countDown(); + return e; + } + return null; + }); assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue(); assertThat(locked.get()).isFalse(); @@ -324,7 +320,6 @@ public class DynamoDbLockRegistryTests { assertThat(((Exception) imse).getMessage()).contains("You do not own"); } - @Configuration public static class ContextConfiguration { diff --git a/src/test/java/org/springframework/integration/aws/metadata/DynamoDbMetadataStoreTests.java b/src/test/java/org/springframework/integration/aws/metadata/DynamoDbMetadataStoreTests.java index 83fd20f..890d2c5 100644 --- a/src/test/java/org/springframework/integration/aws/metadata/DynamoDbMetadataStoreTests.java +++ b/src/test/java/org/springframework/integration/aws/metadata/DynamoDbMetadataStoreTests.java @@ -40,7 +40,6 @@ import com.amazonaws.waiters.WaiterParameters; /** * @author Artem Bilan - * * @since 1.1 * */ @@ -64,13 +63,10 @@ public class DynamoDbMetadataStoreTests { try { dynamoDB.deleteTableAsync(TEST_TABLE); - Waiter waiter = - dynamoDB.waiters() - .tableNotExists(); + Waiter waiter = dynamoDB.waiters().tableNotExists(); - waiter.run(new WaiterParameters<>(new DescribeTableRequest(TEST_TABLE)) - .withPollingStrategy(new PollingStrategy(new MaxAttemptsRetryStrategy(25), - new FixedDelayStrategy(1)))); + waiter.run(new WaiterParameters<>(new DescribeTableRequest(TEST_TABLE)).withPollingStrategy( + new PollingStrategy(new MaxAttemptsRetryStrategy(25), new FixedDelayStrategy(1)))); } catch (Exception e) { @@ -87,11 +83,8 @@ public class DynamoDbMetadataStoreTests { createTableLatch.await(); - DYNAMO_DB_RUNNING.getDynamoDB() - .deleteItem(TEST_TABLE, - Collections.singletonMap("KEY", - new AttributeValue() - .withS(this.file1))); + DYNAMO_DB_RUNNING.getDynamoDB().deleteItem(TEST_TABLE, + Collections.singletonMap("KEY", new AttributeValue().withS(this.file1))); } @Test diff --git a/src/test/java/org/springframework/integration/aws/outbound/KinesisMessageHandlerTests.java b/src/test/java/org/springframework/integration/aws/outbound/KinesisMessageHandlerTests.java index 1189d8d..cbbcad3 100644 --- a/src/test/java/org/springframework/integration/aws/outbound/KinesisMessageHandlerTests.java +++ b/src/test/java/org/springframework/integration/aws/outbound/KinesisMessageHandlerTests.java @@ -58,7 +58,6 @@ import com.amazonaws.services.kinesis.model.PutRecordsRequestEntry; /** * @author Artem Bilan - * * @since 1.1 */ @RunWith(SpringRunner.class) @@ -100,18 +99,15 @@ public class KinesisMessageHandlerTests { assertThat(e.getMessage()).contains("'partitionKey' must not be null for sending a Kinesis record"); } - message = MessageBuilder.fromMessage(message) - .setHeader(AwsHeaders.PARTITION_KEY, "fooKey") - .setHeader(AwsHeaders.SEQUENCE_NUMBER, "10") - .setHeader("foo", "bar") - .build(); + message = MessageBuilder.fromMessage(message).setHeader(AwsHeaders.PARTITION_KEY, "fooKey") + .setHeader(AwsHeaders.SEQUENCE_NUMBER, "10").setHeader("foo", "bar").build(); this.kinesisSendChannel.send(message); - ArgumentCaptor putRecordRequestArgumentCaptor = - ArgumentCaptor.forClass(PutRecordRequest.class); - ArgumentCaptor> asyncHandlerArgumentCaptor = - ArgumentCaptor.forClass((Class>) (Class) AsyncHandler.class); + ArgumentCaptor putRecordRequestArgumentCaptor = ArgumentCaptor + .forClass(PutRecordRequest.class); + ArgumentCaptor> asyncHandlerArgumentCaptor = ArgumentCaptor + .forClass((Class>) (Class) AsyncHandler.class); verify(this.amazonKinesis).putRecordAsync(putRecordRequestArgumentCaptor.capture(), asyncHandlerArgumentCaptor.capture()); @@ -136,28 +132,22 @@ public class KinesisMessageHandlerTests { verify(this.asyncHandler).onError(eq(testingException)); - message = new GenericMessage<>(new PutRecordsRequest() - .withStreamName("myStream") - .withRecords(new PutRecordsRequestEntry() - .withData(ByteBuffer.wrap("test".getBytes())) - .withPartitionKey("testKey"))); + message = new GenericMessage<>(new PutRecordsRequest().withStreamName("myStream").withRecords( + new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey"))); this.kinesisSendChannel.send(message); - ArgumentCaptor putRecordsRequestArgumentCaptor = - ArgumentCaptor.forClass(PutRecordsRequest.class); + ArgumentCaptor putRecordsRequestArgumentCaptor = ArgumentCaptor + .forClass(PutRecordsRequest.class); verify(this.amazonKinesis).putRecordsAsync(putRecordsRequestArgumentCaptor.capture(), any(AsyncHandler.class)); PutRecordsRequest putRecordsRequest = putRecordsRequestArgumentCaptor.getValue(); assertThat(putRecordsRequest.getStreamName()).isEqualTo("myStream"); - assertThat(putRecordsRequest.getRecords()) - .containsExactlyInAnyOrder(new PutRecordsRequestEntry() - .withData(ByteBuffer.wrap("test".getBytes())) - .withPartitionKey("testKey")); + assertThat(putRecordsRequest.getRecords()).containsExactlyInAnyOrder( + new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey")); } - @Configuration @EnableIntegration public static class ContextConfiguration { diff --git a/src/test/java/org/springframework/integration/aws/outbound/KinesisProducingMessageHandlerTests.java b/src/test/java/org/springframework/integration/aws/outbound/KinesisProducingMessageHandlerTests.java index 19c7c85..228098f 100644 --- a/src/test/java/org/springframework/integration/aws/outbound/KinesisProducingMessageHandlerTests.java +++ b/src/test/java/org/springframework/integration/aws/outbound/KinesisProducingMessageHandlerTests.java @@ -57,7 +57,6 @@ import com.amazonaws.services.kinesis.model.PutRecordsResult; /** * @author Jacob Severson - * * @since 1.1 */ @RunWith(SpringRunner.class) @@ -99,10 +98,8 @@ public class KinesisProducingMessageHandlerTests { assertThat(e.getMessage()).contains("'partitionKey' must not be null for sending a Kinesis record"); } - message = MessageBuilder.fromMessage(message) - .setHeader(AwsHeaders.PARTITION_KEY, "fooKey") - .setHeader(AwsHeaders.SEQUENCE_NUMBER, "10") - .build(); + message = MessageBuilder.fromMessage(message).setHeader(AwsHeaders.PARTITION_KEY, "fooKey") + .setHeader(AwsHeaders.SEQUENCE_NUMBER, "10").build(); this.kinesisSendChannel.send(message); @@ -111,10 +108,8 @@ public class KinesisProducingMessageHandlerTests { assertThat(success.getHeaders().get(AwsHeaders.SEQUENCE_NUMBER)).isEqualTo("10"); assertThat(success.getPayload()).isEqualTo("message"); - message = MessageBuilder.fromMessage(message) - .setHeader(AwsHeaders.PARTITION_KEY, "fooKey") - .setHeader(AwsHeaders.SEQUENCE_NUMBER, "10") - .build(); + message = MessageBuilder.fromMessage(message).setHeader(AwsHeaders.PARTITION_KEY, "fooKey") + .setHeader(AwsHeaders.SEQUENCE_NUMBER, "10").build(); this.kinesisSendChannel.send(message); @@ -125,28 +120,20 @@ public class KinesisProducingMessageHandlerTests { assertThat(((PutRecordRequest) putRecordFailure.getRequest()).getPartitionKey()).isEqualTo("fooKey"); assertThat(((PutRecordRequest) putRecordFailure.getRequest()).getSequenceNumberForOrdering()).isEqualTo("10"); assertThat(((PutRecordRequest) putRecordFailure.getRequest()).getExplicitHashKey()).isNull(); - assertThat(((PutRecordRequest) putRecordFailure.getRequest()) - .getData()).isEqualTo(ByteBuffer.wrap("message".getBytes())); + assertThat(((PutRecordRequest) putRecordFailure.getRequest()).getData()) + .isEqualTo(ByteBuffer.wrap("message".getBytes())); - message = new GenericMessage<>(new PutRecordsRequest() - .withStreamName("myStream") - .withRecords(new PutRecordsRequestEntry() - .withData(ByteBuffer.wrap("test".getBytes())) - .withPartitionKey("testKey"))); + message = new GenericMessage<>(new PutRecordsRequest().withStreamName("myStream").withRecords( + new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey"))); this.kinesisSendChannel.send(message); success = this.successChannel.receive(10000); - assertThat(((PutRecordsRequest) success.getPayload()).getRecords()) - .containsExactlyInAnyOrder(new PutRecordsRequestEntry() - .withData(ByteBuffer.wrap("test".getBytes())) - .withPartitionKey("testKey")); + assertThat(((PutRecordsRequest) success.getPayload()).getRecords()).containsExactlyInAnyOrder( + new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey")); - message = new GenericMessage<>(new PutRecordsRequest() - .withStreamName("myStream") - .withRecords(new PutRecordsRequestEntry() - .withData(ByteBuffer.wrap("test".getBytes())) - .withPartitionKey("testKey"))); + message = new GenericMessage<>(new PutRecordsRequest().withStreamName("myStream").withRecords( + new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey"))); this.kinesisSendChannel.send(message); @@ -154,10 +141,8 @@ public class KinesisProducingMessageHandlerTests { AwsRequestFailureException putRecordsFailure = (AwsRequestFailureException) failed.getPayload(); assertThat(putRecordsFailure.getCause().getMessage()).isEqualTo("putRecordsRequestEx"); assertThat(((PutRecordsRequest) putRecordsFailure.getRequest()).getStreamName()).isEqualTo("myStream"); - assertThat(((PutRecordsRequest) putRecordsFailure.getRequest()).getRecords()) - .containsExactlyInAnyOrder(new PutRecordsRequestEntry() - .withData(ByteBuffer.wrap("test".getBytes())) - .withPartitionKey("testKey")); + assertThat(((PutRecordsRequest) putRecordsFailure.getRequest()).getRecords()).containsExactlyInAnyOrder( + new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey")); } @Configuration @@ -169,30 +154,25 @@ public class KinesisProducingMessageHandlerTests { public AmazonKinesisAsync amazonKinesis() { AmazonKinesisAsync mock = mock(AmazonKinesisAsync.class); - given(mock.putRecordAsync(any(PutRecordRequest.class), any(AsyncHandler.class))) - .willAnswer(invocation -> { - PutRecordRequest request = invocation.getArgument(0); - AsyncHandler handler = invocation.getArgument(1); - PutRecordResult result = new PutRecordResult() - .withSequenceNumber(request.getSequenceNumberForOrdering()) - .withShardId("shardId-1"); - handler.onSuccess(new PutRecordRequest(), result); - return mock(Future.class); - }) - .willAnswer(invocation -> { - AsyncHandler handler = invocation.getArgument(1); - handler.onError(new RuntimeException("putRecordRequestEx")); - return mock(Future.class); - }); - + given(mock.putRecordAsync(any(PutRecordRequest.class), any(AsyncHandler.class))).willAnswer(invocation -> { + PutRecordRequest request = invocation.getArgument(0); + AsyncHandler handler = invocation.getArgument(1); + PutRecordResult result = new PutRecordResult() + .withSequenceNumber(request.getSequenceNumberForOrdering()).withShardId("shardId-1"); + handler.onSuccess(new PutRecordRequest(), result); + return mock(Future.class); + }).willAnswer(invocation -> { + AsyncHandler handler = invocation.getArgument(1); + handler.onError(new RuntimeException("putRecordRequestEx")); + return mock(Future.class); + }); given(mock.putRecordsAsync(any(PutRecordsRequest.class), any(AsyncHandler.class))) .willAnswer(invocation -> { AsyncHandler handler = invocation.getArgument(1); handler.onSuccess(new PutRecordsRequest(), new PutRecordsResult()); return mock(Future.class); - }) - .willAnswer(invocation -> { + }).willAnswer(invocation -> { AsyncHandler handler = invocation.getArgument(1); handler.onError(new RuntimeException("putRecordsRequestEx")); return mock(Future.class); diff --git a/src/test/java/org/springframework/integration/aws/outbound/S3MessageHandlerTests.java b/src/test/java/org/springframework/integration/aws/outbound/S3MessageHandlerTests.java index 3fa6a6f..96cc94f 100644 --- a/src/test/java/org/springframework/integration/aws/outbound/S3MessageHandlerTests.java +++ b/src/test/java/org/springframework/integration/aws/outbound/S3MessageHandlerTests.java @@ -147,19 +147,16 @@ public class S3MessageHandlerTests { @Qualifier("s3MessageHandler") private S3MessageHandler s3MessageHandler; - - @Test public void testUploadFile() throws IOException, InterruptedException { File file = this.temporaryFolder.newFile("foo.mp3"); Message message = MessageBuilder.withPayload(file) - .setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name()) - .build(); + .setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name()).build(); this.s3SendChannel.send(message); - ArgumentCaptor putObjectRequestArgumentCaptor = - ArgumentCaptor.forClass(PutObjectRequest.class); + ArgumentCaptor putObjectRequestArgumentCaptor = ArgumentCaptor + .forClass(PutObjectRequest.class); verify(this.amazonS3, atLeastOnce()).putObject(putObjectRequestArgumentCaptor.capture()); PutObjectRequest putObjectRequest = putObjectRequestArgumentCaptor.getValue(); @@ -179,8 +176,8 @@ public class S3MessageHandlerTests { assertThat(this.transferCompletedLatch.await(10, TimeUnit.SECONDS)).isTrue(); assertThat(this.aclLatch.await(10, TimeUnit.SECONDS)).isTrue(); - ArgumentCaptor setObjectAclRequestArgumentCaptor = - ArgumentCaptor.forClass(SetObjectAclRequest.class); + ArgumentCaptor setObjectAclRequestArgumentCaptor = ArgumentCaptor + .forClass(SetObjectAclRequest.class); verify(this.amazonS3).setObjectAcl(setObjectAclRequestArgumentCaptor.capture()); SetObjectAclRequest setObjectAclRequest = setObjectAclRequestArgumentCaptor.getValue(); @@ -200,9 +197,7 @@ public class S3MessageHandlerTests { InputStream payload = new StringInputStream("a"); Message message = MessageBuilder.withPayload(payload) - .setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name()) - .setHeader("key", "myStream") - .build(); + .setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name()).setHeader("key", "myStream").build(); assertThatThrownBy(() -> this.s3SendChannel.send(message)) .hasCauseExactlyInstanceOf(IllegalStateException.class) @@ -212,8 +207,8 @@ public class S3MessageHandlerTests { this.s3SendChannel.send(message); - ArgumentCaptor putObjectRequestArgumentCaptor = - ArgumentCaptor.forClass(PutObjectRequest.class); + ArgumentCaptor putObjectRequestArgumentCaptor = ArgumentCaptor + .forClass(PutObjectRequest.class); verify(this.amazonS3, atLeastOnce()).putObject(putObjectRequestArgumentCaptor.capture()); PutObjectRequest putObjectRequest = putObjectRequestArgumentCaptor.getValue(); @@ -234,9 +229,7 @@ public class S3MessageHandlerTests { File file = this.temporaryFolder.newFile("foo.mp3"); FileInputStream fileInputStream = new FileInputStream(file); Message message = MessageBuilder.withPayload(fileInputStream) - .setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name()) - .setHeader("key", "myStream") - .build(); + .setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name()).setHeader("key", "myStream").build(); try { this.s3SendChannel.send(message); @@ -252,14 +245,12 @@ public class S3MessageHandlerTests { public void testUploadByteArray() throws IOException { byte[] payload = "b".getBytes("UTF-8"); Message message = MessageBuilder.withPayload(payload) - .setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name()) - .setHeader("key", "myStream") - .build(); + .setHeader("s3Command", S3MessageHandler.Command.UPLOAD.name()).setHeader("key", "myStream").build(); this.s3SendChannel.send(message); - ArgumentCaptor putObjectRequestArgumentCaptor = - ArgumentCaptor.forClass(PutObjectRequest.class); + ArgumentCaptor putObjectRequestArgumentCaptor = ArgumentCaptor + .forClass(PutObjectRequest.class); verify(this.amazonS3, atLeastOnce()).putObject(putObjectRequestArgumentCaptor.capture()); PutObjectRequest putObjectRequest = putObjectRequestArgumentCaptor.getValue(); @@ -279,8 +270,7 @@ public class S3MessageHandlerTests { public void testDownloadDirectory() throws IOException { File directoryForDownload = this.temporaryFolder.newFolder("myFolder"); Message message = MessageBuilder.withPayload(directoryForDownload) - .setHeader("s3Command", S3MessageHandler.Command.DOWNLOAD) - .build(); + .setHeader("s3Command", S3MessageHandler.Command.DOWNLOAD).build(); this.s3SendChannel.send(message); @@ -404,21 +394,16 @@ public class S3MessageHandlerTests { else { return invocation.callRealMethod(); } - }) - .given(amazonS3) - .getObject(any(GetObjectRequest.class)); + }).given(amazonS3).getObject(any(GetObjectRequest.class)); willAnswer(invocation -> { aclLatch().countDown(); return null; - }) - .given(amazonS3) - .setObjectAcl(any(SetObjectAclRequest.class)); + }).given(amazonS3).setObjectAcl(any(SetObjectAclRequest.class)); return amazonS3; } - @Bean public CountDownLatch aclLatch() { return new CountDownLatch(1); @@ -453,8 +438,8 @@ public class S3MessageHandlerTests { public MessageHandler s3MessageHandler() { S3MessageHandler s3MessageHandler = new S3MessageHandler(amazonS3(), S3_BUCKET_NAME); s3MessageHandler.setCommandExpression(PARSER.parseExpression("headers.s3Command")); - Expression keyExpression = - PARSER.parseExpression("payload instanceof T(java.io.File) ? payload.name : headers.key"); + Expression keyExpression = PARSER + .parseExpression("payload instanceof T(java.io.File) ? payload.name : headers.key"); s3MessageHandler.setKeyExpression(keyExpression); s3MessageHandler.setObjectAclExpression(new ValueExpression<>(CannedAccessControlList.PublicReadWrite)); s3MessageHandler.setUploadMetadataProvider((metadata, message) -> { diff --git a/src/test/java/org/springframework/integration/aws/outbound/SnsMessageBuilderTests.java b/src/test/java/org/springframework/integration/aws/outbound/SnsMessageBuilderTests.java index f174f2e..53ed4f8 100644 --- a/src/test/java/org/springframework/integration/aws/outbound/SnsMessageBuilderTests.java +++ b/src/test/java/org/springframework/integration/aws/outbound/SnsMessageBuilderTests.java @@ -43,9 +43,7 @@ public class SnsMessageBuilderTests { assertThat(message).isEqualTo("{\"default\":\"foo\"}"); try { - SnsBodyBuilder.withDefault("foo") - .forProtocols("{\"foo\" : \"bar\"}") - .build(); + SnsBodyBuilder.withDefault("foo").forProtocols("{\"foo\" : \"bar\"}").build(); fail("IllegalArgumentException expected"); } catch (Exception e) { @@ -53,9 +51,7 @@ public class SnsMessageBuilderTests { assertThat(e.getMessage()).contains("protocols must not be empty."); } try { - SnsBodyBuilder.withDefault("foo") - .forProtocols("{\"foo\" : \"bar\"}", "") - .build(); + SnsBodyBuilder.withDefault("foo").forProtocols("{\"foo\" : \"bar\"}", "").build(); fail("IllegalArgumentException expected"); } catch (Exception e) { @@ -63,9 +59,7 @@ public class SnsMessageBuilderTests { assertThat(e.getMessage()).contains("protocols must not contain empty elements."); } - message = SnsBodyBuilder.withDefault("foo") - .forProtocols("{\"foo\" : \"bar\"}", "sms") - .build(); + message = SnsBodyBuilder.withDefault("foo").forProtocols("{\"foo\" : \"bar\"}", "sms").build(); assertThat(message).isEqualTo("{\"default\":\"foo\",\"sms\":\"{\\\"foo\\\" : \\\"bar\\\"}\"}"); } diff --git a/src/test/java/org/springframework/integration/aws/outbound/SnsMessageHandlerTests.java b/src/test/java/org/springframework/integration/aws/outbound/SnsMessageHandlerTests.java index 887577a..800e5ec 100644 --- a/src/test/java/org/springframework/integration/aws/outbound/SnsMessageHandlerTests.java +++ b/src/test/java/org/springframework/integration/aws/outbound/SnsMessageHandlerTests.java @@ -77,14 +77,10 @@ public class SnsMessageHandlerTests { @Test @SuppressWarnings("unchecked") public void testSnsMessageHandler() { - SnsBodyBuilder payload = SnsBodyBuilder.withDefault("foo") - .forProtocols("{\"foo\" : \"bar\"}", "sms"); + SnsBodyBuilder payload = SnsBodyBuilder.withDefault("foo").forProtocols("{\"foo\" : \"bar\"}", "sms"); - Message message = MessageBuilder.withPayload(payload) - .setHeader("topic", "topic") - .setHeader("subject", "subject") - .setHeader("foo", "bar") - .build(); + Message message = MessageBuilder.withPayload(payload).setHeader("topic", "topic") + .setHeader("subject", "subject").setHeader("foo", "bar").build(); this.sendToSnsChannel.send(message); @@ -128,9 +124,7 @@ public class SnsMessageHandlerTests { AsyncHandler asyncHandler = invocation.getArgument(1); asyncHandler.onSuccess(invocation.getArgument(0), publishResult); return new AsyncResult<>(publishResult); - }) - .given(mock) - .publishAsync(any(PublishRequest.class), any(AsyncHandler.class)); + }).given(mock).publishAsync(any(PublishRequest.class), any(AsyncHandler.class)); return mock; } diff --git a/src/test/java/org/springframework/integration/aws/outbound/SqsMessageHandlerTests.java b/src/test/java/org/springframework/integration/aws/outbound/SqsMessageHandlerTests.java index e05fe8b..18e0876 100644 --- a/src/test/java/org/springframework/integration/aws/outbound/SqsMessageHandlerTests.java +++ b/src/test/java/org/springframework/integration/aws/outbound/SqsMessageHandlerTests.java @@ -98,35 +98,31 @@ public class SqsMessageHandlerTests { this.sqsMessageHandler.setQueue("foo"); this.sqsSendChannel.send(message); - ArgumentCaptor sendMessageRequestArgumentCaptor = - ArgumentCaptor.forClass(SendMessageRequest.class); - verify(this.amazonSqs) - .sendMessageAsync(sendMessageRequestArgumentCaptor.capture(), any(AsyncHandler.class)); - assertThat(sendMessageRequestArgumentCaptor.getValue().getQueueUrl()) - .isEqualTo("https://queue-url.com/foo"); + ArgumentCaptor sendMessageRequestArgumentCaptor = ArgumentCaptor + .forClass(SendMessageRequest.class); + verify(this.amazonSqs).sendMessageAsync(sendMessageRequestArgumentCaptor.capture(), any(AsyncHandler.class)); + assertThat(sendMessageRequestArgumentCaptor.getValue().getQueueUrl()).isEqualTo("https://queue-url.com/foo"); message = MessageBuilder.withPayload("message").setHeader(AwsHeaders.QUEUE, "bar").build(); this.sqsSendChannel.send(message); - verify(this.amazonSqs, times(2)) - .sendMessageAsync(sendMessageRequestArgumentCaptor.capture(), any(AsyncHandler.class)); + verify(this.amazonSqs, times(2)).sendMessageAsync(sendMessageRequestArgumentCaptor.capture(), + any(AsyncHandler.class)); - assertThat(sendMessageRequestArgumentCaptor.getValue().getQueueUrl()) - .isEqualTo("https://queue-url.com/bar"); + assertThat(sendMessageRequestArgumentCaptor.getValue().getQueueUrl()).isEqualTo("https://queue-url.com/bar"); SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); Expression expression = spelExpressionParser.parseExpression("headers.foo"); this.sqsMessageHandler.setQueueExpression(expression); message = MessageBuilder.withPayload("message").setHeader("foo", "baz").build(); this.sqsSendChannel.send(message); - verify(this.amazonSqs, times(3)) - .sendMessageAsync(sendMessageRequestArgumentCaptor.capture(), any(AsyncHandler.class)); + verify(this.amazonSqs, times(3)).sendMessageAsync(sendMessageRequestArgumentCaptor.capture(), + any(AsyncHandler.class)); SendMessageRequest sendMessageRequestArgumentCaptorValue = sendMessageRequestArgumentCaptor.getValue(); - assertThat(sendMessageRequestArgumentCaptorValue.getQueueUrl()) - .isEqualTo("https://queue-url.com/baz"); + assertThat(sendMessageRequestArgumentCaptorValue.getQueueUrl()).isEqualTo("https://queue-url.com/baz"); - Map messageAttributes = - sendMessageRequestArgumentCaptorValue.getMessageAttributes(); + Map messageAttributes = sendMessageRequestArgumentCaptorValue + .getMessageAttributes(); assertThat(messageAttributes).doesNotContainKey(MessageHeaders.ID); assertThat(messageAttributes).doesNotContainKey(MessageHeaders.TIMESTAMP); @@ -142,17 +138,15 @@ public class SqsMessageHandlerTests { this.sqsMessageHandlerWithAutoQueueCreate.setQueue("foo"); this.sqsSendChannelWithAutoCreate.send(message); - ArgumentCaptor createQueueRequestArgumentCaptor = - ArgumentCaptor.forClass(CreateQueueRequest.class); + ArgumentCaptor createQueueRequestArgumentCaptor = ArgumentCaptor + .forClass(CreateQueueRequest.class); verify(this.amazonSqs).createQueue(createQueueRequestArgumentCaptor.capture()); assertThat(createQueueRequestArgumentCaptor.getValue().getQueueName()).isEqualTo("foo"); - ArgumentCaptor sendMessageRequestArgumentCaptor = - ArgumentCaptor.forClass(SendMessageRequest.class); - verify(this.amazonSqs) - .sendMessageAsync(sendMessageRequestArgumentCaptor.capture(), any(AsyncHandler.class)); - assertThat(sendMessageRequestArgumentCaptor.getValue().getQueueUrl()) - .isEqualTo("https://queue-url.com/foo"); + ArgumentCaptor sendMessageRequestArgumentCaptor = ArgumentCaptor + .forClass(SendMessageRequest.class); + verify(this.amazonSqs).sendMessageAsync(sendMessageRequestArgumentCaptor.capture(), any(AsyncHandler.class)); + assertThat(sendMessageRequestArgumentCaptor.getValue().getQueueUrl()).isEqualTo("https://queue-url.com/foo"); } @Configuration @@ -168,18 +162,14 @@ public class SqsMessageHandlerTests { GetQueueUrlResult queueUrl = new GetQueueUrlResult(); queueUrl.setQueueUrl("https://queue-url.com/" + getQueueUrlRequest.getQueueName()); return queueUrl; - }) - .given(amazonSqs) - .getQueueUrl(any(GetQueueUrlRequest.class)); + }).given(amazonSqs).getQueueUrl(any(GetQueueUrlRequest.class)); willAnswer(invocation -> { CreateQueueRequest createQueueRequest = (CreateQueueRequest) invocation.getArguments()[0]; CreateQueueResult queueUrl = new CreateQueueResult(); queueUrl.setQueueUrl("https://queue-url.com/" + createQueueRequest.getQueueName()); return queueUrl; - }) - .given(amazonSqs) - .createQueue(any(CreateQueueRequest.class)); + }).given(amazonSqs).createQueue(any(CreateQueueRequest.class)); return amazonSqs; } @@ -193,7 +183,8 @@ public class SqsMessageHandlerTests { @Bean @ServiceActivator(inputChannel = "sqsSendChannelWithAutoCreate") public MessageHandler sqsMessageHandlerWithAutoQueueCreate() { - DynamicQueueUrlDestinationResolver destinationResolver = new DynamicQueueUrlDestinationResolver(amazonSqs(), null); + DynamicQueueUrlDestinationResolver destinationResolver = new DynamicQueueUrlDestinationResolver(amazonSqs(), + null); destinationResolver.setAutoCreate(true); return new SqsMessageHandler(amazonSqs(), destinationResolver); }