From c9be3aab186df75712f5fd125ef688228e01ac16 Mon Sep 17 00:00:00 2001 From: armogur Date: Tue, 24 Jan 2023 08:09:49 +0100 Subject: [PATCH 1/4] Update JDK to 17. Switch from javax.jms.* to jakarta.jms.* namespace. Update testing libraries and maven plugins. --- pom.xml | 414 +++--- .../AmazonSQSMessagingClientWrapper.java | 306 ++-- .../sqs/javamessaging/PrefetchManager.java | 6 +- .../sqs/javamessaging/SQSConnection.java | 89 +- .../javamessaging/SQSConnectionFactory.java | 82 +- .../javamessaging/SQSConnectionMetaData.java | 43 +- .../sqs/javamessaging/SQSMessageConsumer.java | 24 +- .../SQSMessageConsumerPrefetch.java | 70 +- .../sqs/javamessaging/SQSMessageProducer.java | 346 ++--- .../SQSMessagingClientConstants.java | 4 +- .../javamessaging/SQSQueueDestination.java | 71 +- .../amazon/sqs/javamessaging/SQSSession.java | 437 +++--- .../SQSSessionCallbackScheduler.java | 48 +- .../acknowledge/AcknowledgeMode.java | 33 +- .../acknowledge/Acknowledger.java | 10 +- .../acknowledge/AutoAcknowledger.java | 13 +- .../acknowledge/BulkSQSOperation.java | 10 +- .../acknowledge/NegativeAcknowledger.java | 10 +- .../acknowledge/RangedAcknowledger.java | 14 +- .../acknowledge/SQSMessageIdentifier.java | 101 +- .../acknowledge/UnorderedAcknowledger.java | 6 +- .../message/SQSBytesMessage.java | 23 +- .../sqs/javamessaging/message/SQSMessage.java | 781 ++++------- .../message/SQSObjectMessage.java | 10 +- .../javamessaging/message/SQSTextMessage.java | 6 +- .../util/ExponentialBackoffStrategy.java | 6 +- .../util/SQSMessagingClientUtil.java | 2 +- .../sqs/javamessaging/AcknowledgerCommon.java | 10 +- .../AmazonSQSMessagingClientWrapperTest.java | 277 ++-- .../javamessaging/AutoAcknowledgerTest.java | 43 +- .../javamessaging/BulkSQSOperationTest.java | 80 +- .../ExponentialBackoffStrategyTest.java | 26 +- ...essageListenerConcurrentOperationTest.java | 108 +- .../NegativeAcknowledgerTest.java | 60 +- .../javamessaging/RangedAcknowledgerTest.java | 63 +- .../SQSConnectionFactoryTest.java | 14 +- .../sqs/javamessaging/SQSConnectionTest.java | 437 +++--- .../SQSMessageConsumerPrefetchFifoTest.java | 426 +++--- .../SQSMessageConsumerPrefetchTest.java | 1231 ++++++++--------- .../javamessaging/SQSMessageConsumerTest.java | 171 +-- .../SQSMessageProducerFifoTest.java | 218 ++- .../javamessaging/SQSMessageProducerTest.java | 406 ++---- .../SQSMessagingClientUtilTest.java | 4 +- .../SQSQueueDestinationTest.java | 8 +- .../SQSSessionCallbackSchedulerTest.java | 283 ++-- .../sqs/javamessaging/SQSSessionTest.java | 774 ++++------- .../UnorderedAcknowledgerTest.java | 27 +- .../message/SQSBytesMessageTest.java | 366 ++--- .../javamessaging/message/SQSMessageTest.java | 428 +++--- .../message/SQSObjectMessageTest.java | 55 +- .../message/SQSTextMessageTest.java | 8 +- 51 files changed, 3474 insertions(+), 5014 deletions(-) diff --git a/pom.xml b/pom.xml index 55468df..e8ec8ba 100644 --- a/pom.xml +++ b/pom.xml @@ -1,207 +1,223 @@ - - 4.0.0 - com.amazonaws - amazon-sqs-java-messaging-lib - 2.0.3 - Amazon SQS Java Messaging Library - The Amazon SQS Java Messaging Library holds the Java Message Service compatible classes, that are used - for communicating with Amazon Simple Queue Service. - - https://github.com/awslabs/amazon-sqs-java-messaging-lib - - https://github.com/awslabs/amazon-sqs-java-messaging-lib.git - - - - Apache License, Version 2.0 - https://aws.amazon.com/apache2.0 - repo - - - - - amazonwebservices - Amazon Web Services - https://aws.amazon.com - - developer - - - - - 2.18.1 - UTF-8 - + + 4.0.0 + com.amazonaws + amazon-sqs-java-messaging-lib + 2.1 + Amazon SQS Java Messaging Library + The Amazon SQS Java Messaging Library holds the Java Message Service compatible classes, that are used + for communicating with Amazon Simple Queue Service. + + https://github.com/awslabs/amazon-sqs-java-messaging-lib + + https://github.com/awslabs/amazon-sqs-java-messaging-lib.git + + + + Apache License, Version 2.0 + https://aws.amazon.com/apache2.0 + repo + + + + + amazonwebservices + Amazon Web Services + https://aws.amazon.com + + developer + + + + + 2.19.13 + UTF-8 + - - - software.amazon.awssdk - sqs - ${aws-java-sdk.version} - - - software.amazon.awssdk - auth - ${aws-java-sdk.version} - - - software.amazon.awssdk - utils - ${aws-java-sdk.version} - - - - org.slf4j - slf4j-api - 2.0.3 - + + + org.projectlombok + lombok + 1.18.24 + + + software.amazon.awssdk + sqs + ${aws-java-sdk.version} + + + software.amazon.awssdk + auth + ${aws-java-sdk.version} + + + software.amazon.awssdk + utils + ${aws-java-sdk.version} + - - joda-time - joda-time - 2.12.2 - + + org.slf4j + slf4j-api + 2.0.5 + + + jakarta.jms + jakarta.jms-api + 3.1.0 + + + org.junit.jupiter + junit-jupiter + 5.9.2 + test + + + org.assertj + assertj-core + 3.24.1 + test + + + org.hamcrest + hamcrest + 2.2 + test + + + org.mockito + mockito-core + 4.11.0 + test + + + org.mockito + mockito-junit-jupiter + 4.11.0 + test + + - - org.apache.geronimo.specs - geronimo-jms_1.1_spec - 1.1.1 - - - org.junit.jupiter - junit-jupiter-engine - 5.9.1 - test - - - junit - junit - 4.13.2 - test - - - org.mockito - mockito-core - 1.10.8 - test - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 1.8 - 1.8 - UTF-8 - - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.0.0-M7 - - - - integration-test - verify - - - - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.2.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - attach-javadocs - - jar - - - - -Xdoclint:none - - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.13 - true - - ossrh - https://aws.oss.sonatype.org - true - - - - - - - - publishing - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 17 + 17 + UTF-8 + + + org.projectlombok + lombok + 1.18.24 + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.0.0-M7 + + + + integration-test + verify + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M7 + + + - - org.apache.maven.plugins - maven-gpg-plugin - 3.0.1 - - - sign-artifacts - verify - - sign - + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.4.1 + + + attach-javadocs + + jar + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true - - --pinentry-mode - loopback - + ossrh + https://aws.oss.sonatype.org + true - - - + - - - + + + + + publishing + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.0.1 + + + sign-artifacts + verify + + sign + + + + --pinentry-mode + loopback + + + + + + + + + diff --git a/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java b/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java index 40ea58d..8f09507 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java +++ b/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java @@ -14,38 +14,20 @@ */ package com.amazon.sqs.javamessaging; -import java.util.HashSet; -import java.util.Set; - -import javax.jms.InvalidDestinationException; -import javax.jms.JMSException; -import javax.jms.JMSSecurityException; - +import jakarta.jms.InvalidDestinationException; +import jakarta.jms.JMSException; +import jakarta.jms.JMSSecurityException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.awscore.AwsRequest; import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.exception.SdkException; import software.amazon.awssdk.services.sqs.SqsClient; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchResponse; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityRequest; -import software.amazon.awssdk.services.sqs.model.CreateQueueRequest; -import software.amazon.awssdk.services.sqs.model.CreateQueueResponse; -import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest; -import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchResponse; -import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; -import software.amazon.awssdk.services.sqs.model.GetQueueUrlRequest; -import software.amazon.awssdk.services.sqs.model.GetQueueUrlResponse; -import software.amazon.awssdk.services.sqs.model.QueueDoesNotExistException; -import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; -import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; -import software.amazon.awssdk.services.sqs.model.SendMessageRequest; -import software.amazon.awssdk.services.sqs.model.SendMessageResponse; +import software.amazon.awssdk.services.sqs.model.*; +import java.util.Set; /** @@ -55,39 +37,30 @@ */ public class AmazonSQSMessagingClientWrapper { private static final Logger LOG = LoggerFactory.getLogger(AmazonSQSMessagingClientWrapper.class); - - private static final Set SECURITY_EXCEPTION_ERROR_CODES; - static { - /** - * List of exceptions that can classified as security. These exceptions - * are not thrown during connection-set-up rather after the service - * calls of the SqsClient. - */ - SECURITY_EXCEPTION_ERROR_CODES = new HashSet(); - SECURITY_EXCEPTION_ERROR_CODES.add("MissingClientTokenId"); - SECURITY_EXCEPTION_ERROR_CODES.add("InvalidClientTokenId"); - SECURITY_EXCEPTION_ERROR_CODES.add("MissingAuthenticationToken"); - SECURITY_EXCEPTION_ERROR_CODES.add("AccessDenied"); - } + + /** + * List of exceptions that can classified as security. These exceptions + * are not thrown during connection-set-up rather after the service + * calls of the SqsClient. + */ + private static final Set SECURITY_EXCEPTION_ERROR_CODES = Set.of("MissingClientTokenId", + "InvalidClientTokenId", "MissingAuthenticationToken", "AccessDenied"); + ; private final SqsClient amazonSQSClient; private final AwsCredentialsProvider credentialsProvider; - + /** - * @param amazonSQSClient - * The AWS SDK Client for SQS. - * @throws JMSException - * if the client is null + * @param amazonSQSClient The AWS SDK Client for SQS. + * @throws JMSException if the client is null */ public AmazonSQSMessagingClientWrapper(SqsClient amazonSQSClient) throws JMSException { this(amazonSQSClient, null); } - + /** - * @param amazonSQSClient - * The AWS SDK Client for SQS. - * @throws JMSException - * if the client is null + * @param amazonSQSClient The AWS SDK Client for SQS. + * @throws JMSException if the client is null */ public AmazonSQSMessagingClientWrapper(SqsClient amazonSQSClient, AwsCredentialsProvider credentialsProvider) throws JMSException { if (amazonSQSClient == null) { @@ -96,122 +69,112 @@ public AmazonSQSMessagingClientWrapper(SqsClient amazonSQSClient, AwsCredentials this.amazonSQSClient = amazonSQSClient; this.credentialsProvider = credentialsProvider; } - + /** * If one uses any other AWS SDK operations other than explicitly listed * here, the exceptions thrown by those operations will not be wrapped as * JMSException. + * * @return amazonSQSClient */ public SqsClient getAmazonSQSClient() { return amazonSQSClient; } - + /** * Calls deleteMessage and wraps SdkException. This is used to * acknowledge single messages, so that they can be deleted from SQS queue. - * - * @param deleteMessageRequest - * Container for the necessary parameters to execute the - * deleteMessage service method on SqsClient. + * + * @param deleteMessageRequest Container for the necessary parameters to execute the + * deleteMessage service method on SqsClient. * @throws JMSException */ public void deleteMessage(DeleteMessageRequest deleteMessageRequest) throws JMSException { try { - prepareRequest(deleteMessageRequest); - amazonSQSClient.deleteMessage(deleteMessageRequest); + amazonSQSClient.deleteMessage(prepareRequest(deleteMessageRequest)); } catch (SdkException e) { throw handleException(e, "deleteMessage"); } } - + /** * Calls deleteMessageBatch and wraps * SdkException. This is used to acknowledge multiple * messages on client_acknowledge mode, so that they can be deleted from SQS * queue. - * - * @param deleteMessageBatchRequest - * Container for the necessary parameters to execute the - * deleteMessageBatch service method on SqsClient. This is the - * batch version of deleteMessage. Max batch size is 10. + * + * @param deleteMessageBatchRequest Container for the necessary parameters to execute the + * deleteMessageBatch service method on SqsClient. This is the + * batch version of deleteMessage. Max batch size is 10. * @return The response from the deleteMessageBatch service method, as - * returned by SqsClient + * returned by SqsClient * @throws JMSException */ public DeleteMessageBatchResponse deleteMessageBatch(DeleteMessageBatchRequest deleteMessageBatchRequest) throws JMSException { try { - prepareRequest(deleteMessageBatchRequest); - return amazonSQSClient.deleteMessageBatch(deleteMessageBatchRequest); + return amazonSQSClient.deleteMessageBatch(prepareRequest(deleteMessageBatchRequest)); } catch (SdkException e) { throw handleException(e, "deleteMessageBatch"); - } + } } - + /** * Calls sendMessage and wraps * AmazonClientException. - * - * @param sendMessageRequest - * Container for the necessary parameters to execute the - * sendMessage service method on SqsClient. + * + * @param sendMessageRequest Container for the necessary parameters to execute the + * sendMessage service method on SqsClient. * @return The response from the sendMessage service method, as returned by - * SqsClient + * SqsClient * @throws JMSException */ public SendMessageResponse sendMessage(SendMessageRequest sendMessageRequest) throws JMSException { try { - prepareRequest(sendMessageRequest); - return amazonSQSClient.sendMessage(sendMessageRequest); + return amazonSQSClient.sendMessage(prepareRequest(sendMessageRequest)); } catch (SdkException e) { throw handleException(e, "sendMessage"); - } + } } - + /** * Check if the requested queue exists. This function calls * GetQueueUrl for the given queue name, returning true on * success, false if it gets QueueDoesNotExistException. - * - * @param queueName - * the queue to check + * + * @param queueName the queue to check * @return true if the queue exists, false if it doesn't. * @throws JMSException */ public boolean queueExists(String queueName) throws JMSException { try { - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(queueName).build(); - prepareRequest(getQueueUrlRequest); - amazonSQSClient.getQueueUrl(getQueueUrlRequest); + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(queueName).build(); + amazonSQSClient.getQueueUrl(prepareRequest(getQueueUrlRequest)); return true; } catch (QueueDoesNotExistException e) { return false; } catch (SdkException e) { - throw handleException(e, "getQueueUrl"); - } + throw handleException(e, "getQueueUrl"); + } } - + /** * Check if the requested queue exists. This function calls * GetQueueUrl for the given queue name with the given owner * accountId, returning true on success, false if it gets * QueueDoesNotExistException. - * - * @param queueName - * the queue to check - * @param queueOwnerAccountId - * The AWS accountId of the account that created the queue + * + * @param queueName the queue to check + * @param queueOwnerAccountId The AWS accountId of the account that created the queue * @return true if the queue exists, false if it doesn't. * @throws JMSException */ public boolean queueExists(String queueName, String queueOwnerAccountId) throws JMSException { try { GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder() - .queueName(queueName) - .queueOwnerAWSAccountId(queueOwnerAccountId) - .build(); - prepareRequest(getQueueUrlRequest); - amazonSQSClient.getQueueUrl(getQueueUrlRequest); + .queueName(queueName) + .queueOwnerAWSAccountId(queueOwnerAccountId) + .build(); + amazonSQSClient.getQueueUrl(prepareRequest(getQueueUrlRequest)); return true; } catch (QueueDoesNotExistException e) { return false; @@ -219,150 +182,140 @@ public boolean queueExists(String queueName, String queueOwnerAccountId) throws throw handleException(e, "getQueueUrl"); } } - + /** * Gets the queueUrl of a queue given a queue name. - * + * * @param queueName * @return The response from the GetQueueUrl service method, as returned by - * SqsClient, which will include queue`s URL + * SqsClient, which will include queue`s URL * @throws JMSException */ public GetQueueUrlResponse getQueueUrl(String queueName) throws JMSException { - GetQueueUrlRequest request = GetQueueUrlRequest.builder() - .queueName(queueName) - .build(); + GetQueueUrlRequest request = GetQueueUrlRequest.builder() + .queueName(queueName) + .build(); return getQueueUrl(request); } - + /** * Gets the queueUrl of a queue given a queue name owned by the provided accountId. - * + * * @param queueName * @param queueOwnerAccountId The AWS accountId of the account that created the queue * @return The response from the GetQueueUrl service method, as returned by - * SqsClient, which will include queue`s URL + * SqsClient, which will include queue`s URL * @throws JMSException */ public GetQueueUrlResponse getQueueUrl(String queueName, String queueOwnerAccountId) throws JMSException { - GetQueueUrlRequest request = GetQueueUrlRequest.builder() - .queueName(queueName) - .queueOwnerAWSAccountId(queueOwnerAccountId) - .build(); + GetQueueUrlRequest request = GetQueueUrlRequest.builder() + .queueName(queueName) + .queueOwnerAWSAccountId(queueOwnerAccountId) + .build(); return getQueueUrl(request); } - + /** * Calls getQueueUrl and wraps SdkException - * - * @param getQueueUrlRequest - * Container for the necessary parameters to execute the - * getQueueUrl service method on SqsClient. + * + * @param getQueueUrlRequest Container for the necessary parameters to execute the + * getQueueUrl service method on SqsClient. * @return The response from the GetQueueUrl service method, as returned by - * SqsClient, which will include queue`s URL + * SqsClient, which will include queue`s URL * @throws JMSException */ public GetQueueUrlResponse getQueueUrl(GetQueueUrlRequest getQueueUrlRequest) throws JMSException { try { - prepareRequest(getQueueUrlRequest); - return amazonSQSClient.getQueueUrl(getQueueUrlRequest); + return amazonSQSClient.getQueueUrl(prepareRequest(getQueueUrlRequest)); } catch (SdkException e) { - throw handleException(e, "getQueueUrl"); - } + throw handleException(e, "getQueueUrl"); + } } - + /** * Calls createQueue to create the queue with the default queue attributes, * and wraps SdkException - * + * * @param queueName * @return The response from the createQueue service method, as returned by - * SqsClient. This call creates a new queue, or returns the URL of - * an existing one. + * SqsClient. This call creates a new queue, or returns the URL of + * an existing one. * @throws JMSException */ public CreateQueueResponse createQueue(String queueName) throws JMSException { return createQueue(CreateQueueRequest.builder().queueName(queueName).build()); } - + /** * Calls createQueue to create the queue with the provided queue attributes * if any, and wraps SdkException - * - * @param createQueueRequest - * Container for the necessary parameters to execute the - * createQueue service method on SqsClient. + * + * @param createQueueRequest Container for the necessary parameters to execute the + * createQueue service method on SqsClient. * @return The response from the createQueue service method, as returned by - * SqsClient. This call creates a new queue, or returns the URL of - * an existing one. + * SqsClient. This call creates a new queue, or returns the URL of + * an existing one. * @throws JMSException */ public CreateQueueResponse createQueue(CreateQueueRequest createQueueRequest) throws JMSException { try { - prepareRequest(createQueueRequest); - return amazonSQSClient.createQueue(createQueueRequest); + return amazonSQSClient.createQueue(prepareRequest(createQueueRequest)); } catch (SdkException e) { - throw handleException(e, "createQueue"); - } + throw handleException(e, "createQueue"); + } } - + /** * Calls receiveMessage and wraps SdkException. Used by * {@link SQSMessageConsumerPrefetch} to receive up to minimum of * (numberOfMessagesToPrefetch,10) messages from SQS queue into consumer * prefetch buffers. - * - * @param receiveMessageRequest - * Container for the necessary parameters to execute the - * receiveMessage service method on SqsClient. + * + * @param receiveMessageRequest Container for the necessary parameters to execute the + * receiveMessage service method on SqsClient. * @return The response from the ReceiveMessage service method, as returned - * by SqsClient. + * by SqsClient. * @throws JMSException - */ + */ public ReceiveMessageResponse receiveMessage(ReceiveMessageRequest receiveMessageRequest) throws JMSException { try { - prepareRequest(receiveMessageRequest); - return amazonSQSClient.receiveMessage(receiveMessageRequest); + return amazonSQSClient.receiveMessage(prepareRequest(receiveMessageRequest)); } catch (SdkException e) { throw handleException(e, "receiveMessage"); } } - + /** * Calls changeMessageVisibility and wraps SdkException. This is * used to for negative acknowledge of a single message, so that messages can be received again without any delay. - * - * @param changeMessageVisibilityRequest - * Container for the necessary parameters to execute the - * changeMessageVisibility service method on SqsClient. + * + * @param changeMessageVisibilityRequest Container for the necessary parameters to execute the + * changeMessageVisibility service method on SqsClient. * @throws JMSException */ public void changeMessageVisibility(ChangeMessageVisibilityRequest changeMessageVisibilityRequest) throws JMSException { try { - prepareRequest(changeMessageVisibilityRequest); - amazonSQSClient.changeMessageVisibility(changeMessageVisibilityRequest); + amazonSQSClient.changeMessageVisibility(prepareRequest(changeMessageVisibilityRequest)); } catch (SdkException e) { throw handleException(e, "changeMessageVisibility"); - } + } } - + /** * Calls changeMessageVisibilityBatch and wraps SdkException. This is * used to for negative acknowledge of messages in batch, so that messages * can be received again without any delay. - * - * @param changeMessageVisibilityBatchRequest - * Container for the necessary parameters to execute the - * changeMessageVisibilityBatch service method on SqsClient. + * + * @param changeMessageVisibilityBatchRequest Container for the necessary parameters to execute the + * changeMessageVisibilityBatch service method on SqsClient. * @return The response from the changeMessageVisibilityBatch service - * method, as returned by SqsClient. + * method, as returned by SqsClient. * @throws JMSException */ - public ChangeMessageVisibilityBatchResponse changeMessageVisibilityBatch(ChangeMessageVisibilityBatchRequest changeMessageVisibilityBatchRequest) - throws JMSException { + public ChangeMessageVisibilityBatchResponse changeMessageVisibilityBatch( + ChangeMessageVisibilityBatchRequest changeMessageVisibilityBatchRequest) throws JMSException { try { - prepareRequest(changeMessageVisibilityBatchRequest); - return amazonSQSClient.changeMessageVisibilityBatch(changeMessageVisibilityBatchRequest); + return amazonSQSClient.changeMessageVisibilityBatch(prepareRequest(changeMessageVisibilityBatchRequest)); } catch (SdkException e) { throw handleException(e, "changeMessageVisibilityBatch"); } @@ -374,7 +327,7 @@ public ChangeMessageVisibilityBatchResponse changeMessageVisibilityBatch(ChangeM */ private String logAndGetAmazonServiceException(AwsServiceException ase, String action) { String errorMessage = "AmazonServiceException: " + action + ". RequestId: " + ase.requestId() + - "\nHTTPStatusCode: " + ase.statusCode() + " AmazonErrorCode: " + errorCode(ase); + "\nHTTPStatusCode: " + ase.statusCode() + " AmazonErrorCode: " + errorCode(ase); LOG.error(errorMessage, ase); return errorMessage; } @@ -388,12 +341,10 @@ private String logAndGetAmazonClientException(SdkException ace, String action) { LOG.error(errorMessage, ace); return errorMessage; } - - private JMSException handleException(SdkException e, String operationName) throws JMSException { + + private JMSException handleException(SdkException e, String operationName) { JMSException jmsException; - if (e instanceof AwsServiceException) { - AwsServiceException se = ( AwsServiceException ) e; - + if (e instanceof AwsServiceException se) { if (e instanceof QueueDoesNotExistException) { jmsException = new InvalidDestinationException( logAndGetAmazonServiceException(se, operationName), errorCode(se)); @@ -411,23 +362,20 @@ private JMSException handleException(SdkException e, String operationName) throw jmsException.initCause(e); return jmsException; } - + private static String errorCode(AwsServiceException e) { - return e.awsErrorDetails() != null ? e.awsErrorDetails().errorCode() : ""; + return e.awsErrorDetails() != null ? e.awsErrorDetails().errorCode() : ""; } - - + + private static boolean isJMSSecurityException(AwsServiceException e) { - return SECURITY_EXCEPTION_ERROR_CODES.contains(errorCode(e)) ; + return SECURITY_EXCEPTION_ERROR_CODES.contains(errorCode(e)); } - - private void prepareRequest(AwsRequest request) { - if(credentialsProvider != null) { - request = request.toBuilder().overrideConfiguration(AwsRequestOverrideConfiguration - .builder() - .credentialsProvider(credentialsProvider) - .build()).build(); - } + + private T prepareRequest(T request) { + return credentialsProvider == null ? request : (T) request.toBuilder().overrideConfiguration( + AwsRequestOverrideConfiguration.builder().credentialsProvider(credentialsProvider).build()) + .build(); } - + } diff --git a/src/main/java/com/amazon/sqs/javamessaging/PrefetchManager.java b/src/main/java/com/amazon/sqs/javamessaging/PrefetchManager.java index b0a203a..2251f7d 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/PrefetchManager.java +++ b/src/main/java/com/amazon/sqs/javamessaging/PrefetchManager.java @@ -25,13 +25,13 @@ public interface PrefetchManager { * messageQueue when user calls for receive or message listener onMessage is * called. */ - public void messageDispatched(); + void messageDispatched(); /** * Notify the prefetchThread that the message listener has finished with any * previous message and is ready to accept another. */ - public void messageListenerReady(); + void messageListenerReady(); /** * This is used to determine the state of the consumer, when the message @@ -39,5 +39,5 @@ public interface PrefetchManager { * * @return The message consumer, which owns the prefetchThread */ - public SQSMessageConsumer getMessageConsumer(); + SQSMessageConsumer getMessageConsumer(); } diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSConnection.java b/src/main/java/com/amazon/sqs/javamessaging/SQSConnection.java index e6da0c4..2bd94cf 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSConnection.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSConnection.java @@ -18,20 +18,20 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import javax.jms.IllegalStateException; -import javax.jms.Connection; -import javax.jms.ConnectionConsumer; -import javax.jms.ConnectionMetaData; -import javax.jms.Destination; -import javax.jms.ExceptionListener; -import javax.jms.InvalidClientIDException; -import javax.jms.JMSException; -import javax.jms.Queue; -import javax.jms.QueueConnection; -import javax.jms.QueueSession; -import javax.jms.ServerSessionPool; -import javax.jms.Session; -import javax.jms.Topic; +import jakarta.jms.IllegalStateException; +import jakarta.jms.Connection; +import jakarta.jms.ConnectionConsumer; +import jakarta.jms.ConnectionMetaData; +import jakarta.jms.Destination; +import jakarta.jms.ExceptionListener; +import jakarta.jms.InvalidClientIDException; +import jakarta.jms.JMSException; +import jakarta.jms.Queue; +import jakarta.jms.QueueConnection; +import jakarta.jms.QueueSession; +import jakarta.jms.ServerSessionPool; +import jakarta.jms.Session; +import jakarta.jms.Topic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -107,7 +107,7 @@ public class SQSConnection implements Connection, QueueConnection { */ private volatile boolean actionOnConnectionTaken = false; - private final Set sessions = Collections.newSetFromMap(new ConcurrentHashMap()); + private final Set sessions = Collections.newSetFromMap(new ConcurrentHashMap<>()); SQSConnection(AmazonSQSMessagingClientWrapper amazonSQSClientJMSWrapper, int numberOfMessagesToPrefetch) { amazonSQSClient = amazonSQSClientJMSWrapper; @@ -167,7 +167,7 @@ public QueueSession createQueueSession(boolean transacted, int acknowledgeMode) * * @param transacted * Only false is supported. - * @param acknowledgeMode + * @param sessionMode * Legal values are Session.AUTO_ACKNOWLEDGE, * Session.CLIENT_ACKNOWLEDGE, * Session.DUPS_OK_ACKNOWLEDGE, and @@ -179,26 +179,26 @@ public QueueSession createQueueSession(boolean transacted, int acknowledgeMode) * transaction and acknowledge mode. */ @Override - public Session createSession(boolean transacted, int acknowledgeMode) throws JMSException { + public Session createSession(boolean transacted, int sessionMode) throws JMSException { checkClosed(); actionOnConnectionTaken = true; - if (transacted || acknowledgeMode == Session.SESSION_TRANSACTED) + if (transacted || sessionMode == Session.SESSION_TRANSACTED) throw new JMSException("SQSSession does not support transacted"); SQSSession sqsSession; - if (acknowledgeMode == Session.AUTO_ACKNOWLEDGE) { - sqsSession = new SQSSession(this, AcknowledgeMode.ACK_AUTO.withOriginalAcknowledgeMode(acknowledgeMode)); - } else if (acknowledgeMode == Session.CLIENT_ACKNOWLEDGE || acknowledgeMode == Session.DUPS_OK_ACKNOWLEDGE) { - sqsSession = new SQSSession(this, AcknowledgeMode.ACK_RANGE.withOriginalAcknowledgeMode(acknowledgeMode)); - } else if (acknowledgeMode == SQSSession.UNORDERED_ACKNOWLEDGE) { - sqsSession = new SQSSession(this, AcknowledgeMode.ACK_UNORDERED.withOriginalAcknowledgeMode(acknowledgeMode)); + if (sessionMode == Session.AUTO_ACKNOWLEDGE) { + sqsSession = new SQSSession(this, AcknowledgeMode.ACK_AUTO.withOriginalAcknowledgeMode(sessionMode)); + } else if (sessionMode == Session.CLIENT_ACKNOWLEDGE || sessionMode == Session.DUPS_OK_ACKNOWLEDGE) { + sqsSession = new SQSSession(this, AcknowledgeMode.ACK_RANGE.withOriginalAcknowledgeMode(sessionMode)); + } else if (sessionMode == SQSSession.UNORDERED_ACKNOWLEDGE) { + sqsSession = new SQSSession(this, AcknowledgeMode.ACK_UNORDERED.withOriginalAcknowledgeMode(sessionMode)); } else { LOG.error("Unrecognized acknowledgeMode. Cannot create Session."); throw new JMSException("Unrecognized acknowledgeMode. Cannot create Session."); } synchronized (stateLock) { if (closing) { - /** + /* * SQSSession's constructor has already started a SQSSessionCallbackScheduler which should be closed * before leaving sqsSession object. */ @@ -207,7 +207,7 @@ public Session createSession(boolean transacted, int acknowledgeMode) throws JMS } sessions.add(sqsSession); - /** + /* * Any new sessions created on a started connection should be * started on creation */ @@ -215,10 +215,19 @@ public Session createSession(boolean transacted, int acknowledgeMode) throws JMS sqsSession.start(); } } - return sqsSession; } + @Override + public Session createSession(int sessionMode) throws JMSException { + return createSession(false, sessionMode); + } + + @Override + public Session createSession() throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + @Override public ExceptionListener getExceptionListener() throws JMSException { checkClosing(); @@ -303,7 +312,7 @@ public void start() throws JMSException { * This means that a client can rely on the fact that none of its message * listeners will be called and that all threads of control waiting for * receive calls to return will not return with a message until the - * connection is restarted. The receive timers for a stopped connection + * connection is restarted. The received timers for a stopped connection * continue to advance, so receives may time out while the connection is * stopped. *

@@ -336,7 +345,7 @@ public void stop() throws JMSException { try { for (Session session : sessions) { SQSSession sqsSession = (SQSSession) session; - /** + /* * Session stop call blocks until receives and/or * message listeners in progress have completed. */ @@ -375,12 +384,11 @@ public void stop() throws JMSException { */ @Override public void close() throws JMSException { - if (closed) { return; } - /** + /* * A message listener must not attempt to close its own connection as * this would lead to deadlock. */ @@ -411,7 +419,7 @@ public void close() throws JMSException { } } - }/** Blocks until closing of the connection completes */ + }/* Blocks until closing of the connection completes */ else { synchronized (stateLock) { while (!closed) { @@ -432,7 +440,7 @@ public void close() throws JMSException { * from list of Sessions. */ void removeSession(Session session) throws JMSException { - /** + /* * No need to synchronize on stateLock assuming this can be only called * by session.close(), on which point connection will not be worried * about missing closing this session. @@ -505,9 +513,22 @@ public ConnectionConsumer createConnectionConsumer(Destination destination, Stri throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } + @Override + public ConnectionConsumer createSharedConnectionConsumer(Topic topic, String subscriptionName, String messageSelector, ServerSessionPool sessionPool, int maxMessages) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + /** This method is not supported. */ @Override - public ConnectionConsumer createDurableConnectionConsumer(Topic topic, String subscriptionName, String messageSelector, + public ConnectionConsumer createDurableConnectionConsumer( + Topic topic, String subscriptionName, String messageSelector, + ServerSessionPool sessionPool, int maxMessages) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public ConnectionConsumer createSharedDurableConnectionConsumer( + Topic topic, String subscriptionName, String messageSelector, ServerSessionPool sessionPool, int maxMessages) throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionFactory.java b/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionFactory.java index 57d1e5e..ebdc3d3 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionFactory.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionFactory.java @@ -14,13 +14,7 @@ */ package com.amazon.sqs.javamessaging; -import java.util.function.Supplier; - -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; - +import jakarta.jms.*; import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; @@ -28,20 +22,22 @@ import software.amazon.awssdk.services.sqs.SqsClient; import software.amazon.awssdk.services.sqs.SqsClientBuilder; +import java.util.function.Supplier; + /** * A ConnectionFactory object encapsulates a set of connection configuration * parameters for SqsClient as well as setting * numberOfMessagesToPrefetch. - *

+ *

* The numberOfMessagesToPrefetch parameter is used to size of the * prefetched messages, which can be tuned based on the application workload. It * helps in returning messages from internal buffers(if there is any) instead of * waiting for the SQS receiveMessage call to return. - *

+ *

* If more physical connections than the default maximum value (that is 50 as of * today) are needed on the connection pool, * {@link software.amazon.awssdk.core.client.config.ClientOverrideConfiguration} needs to be configured. - *

+ *

* None of the createConnection methods set-up the physical * connection to SQS, so validity of credentials are not checked with those * methods. @@ -50,18 +46,16 @@ public class SQSConnectionFactory implements ConnectionFactory, QueueConnectionFactory { private final ProviderConfiguration providerConfiguration; private final Supplier amazonSQSClientSupplier; - - /* - /* + /** * Creates a SQSConnectionFactory that uses SqsClientBuilder.standard() for creating SqsClient connections. * Every SQSConnection will have its own copy of SqsClient. */ public SQSConnectionFactory(ProviderConfiguration providerConfiguration) { this(providerConfiguration, SqsClient.create()); } - - /* + + /** * Creates a SQSConnectionFactory that uses the provided SqsClient connection. * Every SQSConnection will use the same provided SqsClient. */ @@ -73,15 +67,10 @@ public SQSConnectionFactory(ProviderConfiguration providerConfiguration, final S throw new IllegalArgumentException("AmazonSQS client cannot be null"); } this.providerConfiguration = providerConfiguration; - this.amazonSQSClientSupplier = new Supplier() { - @Override - public SqsClient get() { - return client; - } - }; + this.amazonSQSClientSupplier = () -> client; } - - /* + + /** * Creates a SQSConnectionFactory that uses the provided SqsClientBuilder for creating AmazonSQS client connections. * Every SQSConnection will have its own copy of AmazonSQS client created through the provided builder. */ @@ -93,19 +82,14 @@ public SQSConnectionFactory(ProviderConfiguration providerConfiguration, final S throw new IllegalArgumentException("AmazonSQS client builder cannot be null"); } this.providerConfiguration = providerConfiguration; - this.amazonSQSClientSupplier = new Supplier() { - @Override - public SqsClient get() { - return clientBuilder.build(); - } - }; + this.amazonSQSClientSupplier = clientBuilder::build; } - + @Override public SQSConnection createConnection() throws JMSException { try { - SqsClient amazonSQS = amazonSQSClientSupplier.get(); + SqsClient amazonSQS = amazonSQSClientSupplier.get(); return createConnection(amazonSQS, null); } catch (RuntimeException e) { throw (JMSException) new JMSException("Error creating SQS client: " + e.getMessage()).initCause(e); @@ -118,36 +102,52 @@ public SQSConnection createConnection(String awsAccessKeyId, String awsSecretKey return createConnection(basicAWSCredentials); } + @Override + public JMSContext createContext() { + throw new JMSRuntimeException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public JMSContext createContext(String userName, String password) { + throw new JMSRuntimeException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public JMSContext createContext(String userName, String password, int sessionMode) { + throw new JMSRuntimeException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public JMSContext createContext(int sessionMode) { + throw new JMSRuntimeException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + public SQSConnection createConnection(AwsCredentials awsCredentials) throws JMSException { AwsCredentialsProvider awsCredentialsProvider = StaticCredentialsProvider.create(awsCredentials); return createConnection(awsCredentialsProvider); } - + public SQSConnection createConnection(AwsCredentialsProvider awsCredentialsProvider) throws JMSException { try { SqsClient amazonSQS = amazonSQSClientSupplier.get(); return createConnection(amazonSQS, awsCredentialsProvider); - } catch(Exception e) { + } catch (Exception e) { throw (JMSException) new JMSException("Error creating SQS client: " + e.getMessage()).initCause(e); } } - + private SQSConnection createConnection(SqsClient amazonSQS, AwsCredentialsProvider awsCredentialsProvider) throws JMSException { AmazonSQSMessagingClientWrapper amazonSQSClientJMSWrapper = new AmazonSQSMessagingClientWrapper(amazonSQS, awsCredentialsProvider); return new SQSConnection(amazonSQSClientJMSWrapper, providerConfiguration.getNumberOfMessagesToPrefetch()); } - + @Override public QueueConnection createQueueConnection() throws JMSException { - return (QueueConnection) createConnection(); + return createConnection(); } @Override public QueueConnection createQueueConnection(String userName, String password) throws JMSException { - return (QueueConnection) createConnection(userName, password); + return createConnection(userName, password); } - - - - } diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionMetaData.java b/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionMetaData.java index 40eee1e..32b5543 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionMetaData.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionMetaData.java @@ -14,42 +14,39 @@ */ package com.amazon.sqs.javamessaging; -import java.util.ArrayList; +import jakarta.jms.ConnectionMetaData; +import jakarta.jms.JMSException; + import java.util.Collections; import java.util.Enumeration; import java.util.List; -import javax.jms.ConnectionMetaData; -import javax.jms.JMSException; - public class SQSConnectionMetaData implements ConnectionMetaData { - - private String jmsVersion; - private int jmsMajorVersion; - private int jmsMinorVersion; - - private String jmsProviderName; - private String providerVersion; - private int providerMajorVersion; - private int providerMinorVersion; - - private List jmsxProperty; - + + private final String jmsVersion; + private final int jmsMajorVersion; + private final int jmsMinorVersion; + + private final String jmsProviderName; + private final String providerVersion; + private final int providerMajorVersion; + private final int providerMinorVersion; + + private final List jmsxProperty; + SQSConnectionMetaData() { this.jmsVersion = "1.1"; this.jmsMajorVersion = 1; this.jmsMinorVersion = 1; - + this.jmsProviderName = "Amazon"; this.providerVersion = "1.0"; this.providerMajorVersion = 1; this.providerMinorVersion = 0; - - this.jmsxProperty = new ArrayList(); - jmsxProperty.add(SQSMessagingClientConstants.JMSX_DELIVERY_COUNT); - jmsxProperty.add(SQSMessagingClientConstants.JMSX_GROUP_ID); - jmsxProperty.add(SQSMessagingClientConstants.JMSX_GROUP_SEC); + + this.jmsxProperty = List.of(SQSMessagingClientConstants.JMSX_DELIVERY_COUNT, + SQSMessagingClientConstants.JMSX_GROUP_ID, SQSMessagingClientConstants.JMSX_GROUP_SEC); } @Override @@ -90,5 +87,5 @@ public int getProviderMinorVersion() throws JMSException { @Override public Enumeration getJMSXPropertyNames() throws JMSException { return Collections.enumeration(jmsxProperty); - } + } } diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumer.java b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumer.java index 29e3dfa..2be04b8 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumer.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumer.java @@ -21,13 +21,13 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; -import javax.jms.IllegalStateException; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.Queue; -import javax.jms.QueueReceiver; +import jakarta.jms.IllegalStateException; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageListener; +import jakarta.jms.Queue; +import jakarta.jms.QueueReceiver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,7 +67,7 @@ public class SQSMessageConsumer implements MessageConsumer, QueueReceiver { private final ExecutorService prefetchExecutor; /** - * Prefetch Runnable. This include keeping internal message buffer filled and call MessageListener if set. + * Prefetch Runnable. This includes keeping internal message buffer filled and call MessageListener if set. */ private final SQSMessageConsumerPrefetch sqsMessageConsumerPrefetch; @@ -107,7 +107,7 @@ public class SQSMessageConsumer implements MessageConsumer, QueueReceiver { */ @Override public Queue getQueue() throws JMSException { - return (Queue) sqsDestination; + return sqsDestination; } /** @@ -226,8 +226,8 @@ void doClose() { try { if (!prefetchExecutor.isShutdown()) { - LOG.info("Shutting down " + SQSSession.CONSUMER_PREFETCH_EXECUTER_NAME + " executor"); - /** Shut down executor. */ + LOG.info("Shutting down " + SQSSession.CONSUMER_PREFETCH_EXECUTOR_NAME + " executor"); + // Shut down executor. prefetchExecutor.shutdown(); } @@ -235,7 +235,7 @@ void doClose() { if (!prefetchExecutor.awaitTermination(PREFETCH_EXECUTOR_GRACEFUL_SHUTDOWN_TIME, TimeUnit.SECONDS)) { - LOG.warn("Can't terminate executor service " + SQSSession.CONSUMER_PREFETCH_EXECUTER_NAME + + LOG.warn("Can't terminate executor service " + SQSSession.CONSUMER_PREFETCH_EXECUTOR_NAME + " after " + PREFETCH_EXECUTOR_GRACEFUL_SHUTDOWN_TIME + " seconds, some running threads will be shutdown immediately"); prefetchExecutor.shutdownNow(); diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetch.java b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetch.java index 456329a..aa96434 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetch.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetch.java @@ -23,9 +23,9 @@ import java.util.Set; import java.util.UUID; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.MessageListener; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.MessageListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -136,7 +136,7 @@ public class SQSMessageConsumerPrefetch implements Runnable, PrefetchManager { queueUrl = sqsDestination.getQueueUrl(); this.sqsDestination = sqsDestination; this.sqsSessionRunnable = sqsSessionRunnable; - messageQueue = new ArrayDeque(numberOfMessagesToPrefetch); + messageQueue = new ArrayDeque<>(numberOfMessagesToPrefetch); } MessageListener getMessageListener() { @@ -172,7 +172,7 @@ protected void setMessageListener(MessageListener messageListener) { return; } - List allPrefetchedMessages = new ArrayList(messageQueue); + List allPrefetchedMessages = new ArrayList<>(messageQueue); sqsSessionRunnable.scheduleCallBacks(messageListener, allPrefetchedMessages); messageQueue.clear(); @@ -272,11 +272,11 @@ protected List getMessages(int batchSize, int waitTimeSeconds) throws J * converted to JMS message will be immediately negative acknowledged. */ protected void processReceivedMessages(List messages) { - List nackMessages = new ArrayList(); - List messageManagers = new ArrayList(); + List nackMessages = new ArrayList<>(); + List messageManagers = new ArrayList<>(); for (Message message : messages) { try { - javax.jms.Message jmsMessage = convertToJMSMessage(message); + jakarta.jms.Message jmsMessage = convertToJMSMessage(message); messageManagers.add(new MessageManager(this, jmsMessage)); } catch (JMSException e) { LOG.warn("Caught exception while converting received messages", e); @@ -327,7 +327,7 @@ protected void waitForPrefetch() throws InterruptedException { stateLock.wait(); } catch (InterruptedException e) { LOG.warn("Interrupted while waiting on prefetch", e); - /** For interruption, we do not nack the messages */ + // For interruption, we do not nack the messages throw e; } } @@ -340,10 +340,10 @@ protected void waitForPrefetch() throws InterruptedException { * @return Converted JMS message * @throws JMSException */ - protected javax.jms.Message convertToJMSMessage(Message message) throws JMSException { + protected jakarta.jms.Message convertToJMSMessage(Message message) throws JMSException { MessageAttributeValue messageTypeAttribute = message.messageAttributes().get( SQSMessage.JMS_SQS_MESSAGE_TYPE); - javax.jms.Message jmsMessage = null; + jakarta.jms.Message jmsMessage; if (messageTypeAttribute == null) { jmsMessage = new SQSTextMessage(acknowledger, queueUrl, message); } else { @@ -461,31 +461,15 @@ private void unrequestMessage() { } } - public static class MessageManager { + public record MessageManager(PrefetchManager prefetchManager, jakarta.jms.Message message) { - private final PrefetchManager prefetchManager; - - private final javax.jms.Message message; - - public MessageManager(PrefetchManager prefetchManager, javax.jms.Message message) { - this.prefetchManager = prefetchManager; - this.message = message; - } - - public PrefetchManager getPrefetchManager() { - return prefetchManager; - } - - public javax.jms.Message getMessage() { - return message; - } } - javax.jms.Message receive() throws JMSException { + jakarta.jms.Message receive() throws JMSException { return receive(0); } - javax.jms.Message receive(long timeout) throws JMSException { + jakarta.jms.Message receive(long timeout) throws JMSException { if (cannotDeliver()) { return null; } @@ -499,10 +483,8 @@ javax.jms.Message receive(long timeout) throws JMSException { requestMessage(); try { // If message exists in queue poll. - if (!messageQueue.isEmpty()) { - messageManager = messageQueue.pollFirst(); - } else { - long startTime = System.currentTimeMillis(); + if (messageQueue.isEmpty()) { + long startTime = System.currentTimeMillis(); long waitTime = 0; while (messageQueue.isEmpty() && !isClosed() && @@ -517,9 +499,9 @@ javax.jms.Message receive(long timeout) throws JMSException { if (messageQueue.isEmpty() || isClosed()) { return null; } - messageManager = messageQueue.pollFirst(); } - } finally { + messageManager = messageQueue.pollFirst(); + } finally { if (messageManager == null) { unrequestMessage(); } @@ -538,7 +520,7 @@ protected void notifyStateChange() { } } - javax.jms.Message receiveNoWait() throws JMSException { + jakarta.jms.Message receiveNoWait() throws JMSException { if (cannotDeliver()) { return null; } @@ -593,11 +575,11 @@ void close() { /** * Helper that notifies PrefetchThread that message is dispatched and AutoAcknowledge */ - private javax.jms.Message messageHandler(MessageManager messageManager) throws JMSException { + private jakarta.jms.Message messageHandler(MessageManager messageManager) throws JMSException { if (messageManager == null) { return null; } - javax.jms.Message message = messageManager.getMessage(); + jakarta.jms.Message message = messageManager.message(); // Notify PrefetchThread that message is dispatched this.messageDispatched(); @@ -624,11 +606,7 @@ private boolean cannotDeliver() throws JMSException { * Sleeps for the configured time. */ protected void sleep(long sleepTimeMillis) throws InterruptedException { - try { - Thread.sleep(sleepTimeMillis); - } catch (InterruptedException e) { - throw e; - } + Thread.sleep(sleepTimeMillis); } protected boolean isClosed() { @@ -636,13 +614,13 @@ protected boolean isClosed() { } List purgePrefetchedMessagesWithGroups(Set affectedGroups) throws JMSException { - List purgedMessages = new ArrayList(); + List purgedMessages = new ArrayList<>(); synchronized (stateLock) { //let's walk over the prefetched messages Iterator managerIterator = messageQueue.iterator(); while (managerIterator.hasNext()) { MessageManager messageManager = managerIterator.next(); - SQSMessage prefetchedMessage = (SQSMessage)messageManager.getMessage(); + SQSMessage prefetchedMessage = (SQSMessage)messageManager.message(); SQSMessageIdentifier messageIdentifier = SQSMessageIdentifier.fromSQSMessage(prefetchedMessage); //is the prefetch entry for one of the affected group ids? diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageProducer.java b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageProducer.java index 9ea6fc3..2175819 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageProducer.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageProducer.java @@ -14,63 +14,62 @@ */ package com.amazon.sqs.javamessaging; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.jms.Destination; -import javax.jms.IllegalStateException; -import javax.jms.InvalidDestinationException; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageFormatException; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.QueueSender; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.amazon.sqs.javamessaging.message.SQSBytesMessage; import com.amazon.sqs.javamessaging.message.SQSMessage; import com.amazon.sqs.javamessaging.message.SQSMessage.JMSMessagePropertyValue; import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; - +import jakarta.jms.IllegalStateException; +import jakarta.jms.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; import software.amazon.awssdk.services.sqs.model.SendMessageRequest; import software.amazon.awssdk.services.sqs.model.SendMessageRequest.Builder; import software.amazon.awssdk.services.sqs.model.SendMessageResponse; import software.amazon.awssdk.utils.BinaryUtils; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + /** * A client uses a MessageProducer object to send messages to a queue * destination. A MessageProducer object is created by passing a Destination * object to a message-producer creation method supplied by a session. - *

+ *

* A client also has the option of creating a message producer without supplying * a queue destination. In this case, a destination must be provided with every send * operation. - *

*/ public class SQSMessageProducer implements MessageProducer, QueueSender { private static final Logger LOG = LoggerFactory.getLogger(SQSMessageProducer.class); - private long MAXIMUM_DELIVERY_DELAY_MILLISECONDS = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES); - + private final long MAXIMUM_DELIVERY_DELAY_MILLISECONDS = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES); + private int deliveryDelaySeconds = 0; - /** This field is not actually used. */ + /** + * This field is not actually used. + */ private long timeToLive; - /** This field is not actually used. */ + /** + * This field is not actually used. + */ private int defaultPriority; - /** This field is not actually used. */ + /** + * This field is not actually used. + */ private int deliveryMode; - /** This field is not actually used. */ + /** + * This field is not actually used. + */ private boolean disableMessageTimestamp; - /** This field is not actually used. */ + /** + * This field is not actually used. + */ private boolean disableMessageID; /** @@ -92,32 +91,31 @@ public class SQSMessageProducer implements MessageProducer, QueueSender { void sendInternal(SQSQueueDestination queue, Message rawMessage) throws JMSException { checkClosed(); - String sqsMessageBody = null; - String messageType = null; - if (!(rawMessage instanceof SQSMessage)) { + if (!(rawMessage instanceof SQSMessage message)) { throw new MessageFormatException( - "Unrecognized message type. Messages have to be one of: SQSBytesMessage, SQSObjectMessage, or SQSTextMessage"); + "Unrecognized message type. Messages have to be one of: SQSBytesMessage, SQSObjectMessage, or SQSTextMessage"); } - - SQSMessage message = (SQSMessage)rawMessage; + + String sqsMessageBody = null; + String messageType = null; message.setJMSDestination(queue); - if (message instanceof SQSBytesMessage) { - sqsMessageBody = BinaryUtils.toBase64(((SQSBytesMessage) message).getBodyAsBytes()); + if (message instanceof SQSBytesMessage sqsBytesMessage) { + sqsMessageBody = BinaryUtils.toBase64(sqsBytesMessage.getBodyAsBytes()); messageType = SQSMessage.BYTE_MESSAGE_TYPE; - } else if (message instanceof SQSObjectMessage) { - sqsMessageBody = ((SQSObjectMessage) message).getMessageBody(); + } else if (message instanceof SQSObjectMessage sqsObjectMessage) { + sqsMessageBody = sqsObjectMessage.getMessageBody(); messageType = SQSMessage.OBJECT_MESSAGE_TYPE; - } else if (message instanceof SQSTextMessage) { - sqsMessageBody = ((SQSTextMessage) message).getText(); + } else if (message instanceof SQSTextMessage sqsTextMessage) { + sqsMessageBody = sqsTextMessage.getText(); messageType = SQSMessage.TEXT_MESSAGE_TYPE; } - + if (sqsMessageBody == null || sqsMessageBody.isEmpty()) { throw new JMSException("Message body cannot be null or empty"); } - Map messageAttributes = propertyToMessageAttribute((SQSMessage) message); + Map messageAttributes = propertyToMessageAttribute(message); - /** + /* * These will override existing attributes if they exist. Everything that * has prefix JMS_ is reserved for JMS Provider, but if the user sets that * attribute, it will be overwritten. @@ -127,9 +125,9 @@ void sendInternal(SQSQueueDestination queue, Message rawMessage) throws JMSExcep addCorrelationIDToQueueReservedAttributes(messageAttributes, message); Builder sendMessageRequest = SendMessageRequest.builder() - .queueUrl(queue.getQueueUrl()) - .messageBody(sqsMessageBody) - .messageAttributes(messageAttributes); + .queueUrl(queue.getQueueUrl()) + .messageBody(sqsMessageBody) + .messageAttributes(messageAttributes); if (deliveryDelaySeconds != 0) { sendMessageRequest.delaySeconds(deliveryDelaySeconds); @@ -147,7 +145,7 @@ void sendInternal(SQSQueueDestination queue, Message rawMessage) throws JMSExcep SendMessageResponse sendMessageResult = amazonSQSClient.sendMessage(sendMessageRequest.build()); String messageId = sendMessageResult.messageId(); LOG.info("Message sent to SQS with SQS-assigned messageId: " + messageId); - /** TODO: Do not support disableMessageID for now. */ + // TODO: Do not support disableMessageID for now. message.setSQSMessageId(messageId); // if the message was sent to FIFO queue, the sequence number will be @@ -162,24 +160,18 @@ void sendInternal(SQSQueueDestination queue, Message rawMessage) throws JMSExcep public Queue getQueue() throws JMSException { return sqsDestination; } - + /** * Sends a message to a queue. - * - * @param queue - * the queue destination to send this message to - * @param message - * the message to send - * @throws InvalidDestinationException - * If a client uses this method with a destination other than - * SQS queue destination. - * @throws MessageFormatException - * If an invalid message is specified. - * @throws UnsupportedOperationException - * If a client uses this method with a MessageProducer that - * specified a destination at creation time. - * @throws JMSException - * If session is closed or internal error. + * + * @param queue the queue destination to send this message to + * @param message the message to send + * @throws InvalidDestinationException If a client uses this method with a destination other than + * SQS queue destination. + * @throws MessageFormatException If an invalid message is specified. + * @throws UnsupportedOperationException If a client uses this method with a MessageProducer that + * specified a destination at creation time. + * @throws JMSException If session is closed or internal error. */ @Override public void send(Queue queue, Message message) throws JMSException { @@ -188,7 +180,7 @@ public void send(Queue queue, Message message) throws JMSException { "Incompatible implementation of Queue. Please use SQSQueueDestination implementation."); } checkIfDestinationAlreadySet(); - sendInternal((SQSQueueDestination)queue, message); + sendInternal((SQSQueueDestination) queue, message); } /** @@ -200,7 +192,7 @@ public void send(Queue queue, Message message) throws JMSException { */ Map propertyToMessageAttribute(SQSMessage message) throws JMSException { - Map messageAttributes = new HashMap(); + Map messageAttributes = new HashMap<>(); Enumeration propertyNames = message.getPropertyNames(); while (propertyNames.hasMoreElements()) { @@ -224,9 +216,9 @@ Map propertyToMessageAttribute(SQSMessage message JMSMessagePropertyValue propertyObject = message.getJMSMessagePropertyValue(propertyName); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .dataType(propertyObject.getType()) - .stringValue(propertyObject.getStringMessageAttributeValue()) - .build(); + .dataType(propertyObject.getType()) + .stringValue(propertyObject.getStringMessageAttributeValue()) + .build(); messageAttributes.put(propertyName, messageAttributeValue); } @@ -241,10 +233,8 @@ private void addReplyToQueueReservedAttributes(Map messageAttributes, - SQSMessage message) throws JMSException { + SQSMessage message) throws JMSException { String correlationID = message.getJMSCorrelationID(); if (correlationID != null) { @@ -273,76 +263,65 @@ private void addCorrelationIDToQueueReservedAttributes(Map messageAttributes, String key, String value) { MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.STRING) - .stringValue(value) - .build(); + .dataType(SQSMessagingClientConstants.STRING) + .stringValue(value) + .build(); messageAttributes.put(key, messageAttributeValue); } - + /** * Sends a message to a queue. - *

+ *

* Send does not support deliveryMode, priority, and timeToLive. It will * ignore anything in deliveryMode, priority, and timeToLive. - * - * @param queue - * the queue destination to send this message to - * @param message - * the message to send + * + * @param queue the queue destination to send this message to + * @param message the message to send * @param deliveryMode * @param priority - * @param timeToLive - * @throws InvalidDestinationException - * If a client uses this method with a destination other than - * SQS queue destination. - * @throws MessageFormatException - * If an invalid message is specified. - * @throws UnsupportedOperationException - * If a client uses this method with a MessageProducer that - * specified a destination at creation time. - * @throws JMSException - * If session is closed or internal error. + * @param timeToLive + * @throws InvalidDestinationException If a client uses this method with a destination other than + * SQS queue destination. + * @throws MessageFormatException If an invalid message is specified. + * @throws UnsupportedOperationException If a client uses this method with a MessageProducer that + * specified a destination at creation time. + * @throws JMSException If session is closed or internal error. */ @Override public void send(Queue queue, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException { send(queue, message); } - + /** * Gets the destination associated with this MessageProducer. - * + * * @return this producer's queue destination */ @Override public Destination getDestination() throws JMSException { return sqsDestination; } - + /** * Closes the message producer. */ @Override public void close() throws JMSException { - if (closed.compareAndSet(false, true)) { parentSQSSession.removeProducer(this); } } - + /** * Sends a message to a destination created during the creation time of this * message producer. - * - * @param message - * the message to send - * @throws MessageFormatException - * If an invalid message is specified. - * @throws UnsupportedOperationException - * If a client uses this method with a MessageProducer that did - * not specify a destination at creation time. - * @throws JMSException - * If session is closed or internal error. + * + * @param message the message to send + * @throws MessageFormatException If an invalid message is specified. + * @throws UnsupportedOperationException If a client uses this method with a MessageProducer that did + * not specify a destination at creation time. + * @throws JMSException If session is closed or internal error. */ @Override public void send(Message message) throws JMSException { @@ -352,49 +331,39 @@ public void send(Message message) throws JMSException { } sendInternal(sqsDestination, message); } - + /** * Sends a message to a destination created during the creation time of this * message producer. - *

+ *

* Send does not support deliveryMode, priority, and timeToLive. It will * ignore anything in deliveryMode, priority, and timeToLive. - * - * @param message - * the message to send + * + * @param message the message to send * @param deliveryMode * @param priority - * @param timeToLive - * @throws MessageFormatException - * If an invalid message is specified. - * @throws UnsupportedOperationException - * If a client uses this method with a MessageProducer that did - * not specify a destination at creation time. - * @throws JMSException - * If session is closed or internal error. + * @param timeToLive + * @throws MessageFormatException If an invalid message is specified. + * @throws UnsupportedOperationException If a client uses this method with a MessageProducer that did + * not specify a destination at creation time. + * @throws JMSException If session is closed or internal error. */ @Override public void send(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException { send(message); } - + /** * Sends a message to a queue destination. - * - * @param destination - * the queue destination to send this message to - * @param message - * the message to send - * @throws InvalidDestinationException - * If a client uses this method with a destination other than - * valid SQS queue destination. - * @throws MessageFormatException - * If an invalid message is specified. - * @throws UnsupportedOperationException - * If a client uses this method with a MessageProducer that - * specified a destination at creation time. - * @throws JMSException - * If session is closed or internal error. + * + * @param destination the queue destination to send this message to + * @param message the message to send + * @throws InvalidDestinationException If a client uses this method with a destination other than + * valid SQS queue destination. + * @throws MessageFormatException If an invalid message is specified. + * @throws UnsupportedOperationException If a client uses this method with a MessageProducer that + * specified a destination at creation time. + * @throws JMSException If session is closed or internal error. */ @Override public void send(Destination destination, Message message) throws JMSException { @@ -410,95 +379,130 @@ public void send(Destination destination, Message message) throws JMSException { /** * Sends a message to a queue destination. - *

+ *

* Send does not support deliveryMode, priority, and timeToLive. It will * ignore anything in deliveryMode, priority, and timeToLive. - * - * @param destination - * the queue destination to send this message to - * @param message - * the message to send + * + * @param destination the queue destination to send this message to + * @param message the message to send * @param deliveryMode * @param priority * @param timeToLive - * @throws InvalidDestinationException - * If a client uses this method with a destination other than - * valid SQS queue destination. - * @throws MessageFormatException - * If an invalid message is specified. - * @throws UnsupportedOperationException - * If a client uses this method with a MessageProducer that - * specified a destination at creation time. - * @throws JMSException - * If session is closed or internal error. + * @throws InvalidDestinationException If a client uses this method with a destination other than + * valid SQS queue destination. + * @throws MessageFormatException If an invalid message is specified. + * @throws UnsupportedOperationException If a client uses this method with a MessageProducer that + * specified a destination at creation time. + * @throws JMSException If session is closed or internal error. */ @Override public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException { send(destination, message); } - /** This method is not supported. */ + @Override + public void send(Message message, CompletionListener completionListener) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public void send(Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public void send(Destination destination, Message message, CompletionListener completionListener) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive, + CompletionListener completionListener) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + /** + * This method is not supported. + */ @Override public void setDisableMessageID(boolean value) throws JMSException { this.disableMessageID = value; } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public boolean getDisableMessageID() throws JMSException { return disableMessageID; } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public void setDisableMessageTimestamp(boolean value) throws JMSException { this.disableMessageTimestamp = value; } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public boolean getDisableMessageTimestamp() throws JMSException { return disableMessageTimestamp; } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public void setDeliveryMode(int deliveryMode) throws JMSException { this.deliveryMode = deliveryMode; } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public int getDeliveryMode() throws JMSException { return deliveryMode; } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public void setPriority(int defaultPriority) throws JMSException { this.defaultPriority = defaultPriority; } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public int getPriority() throws JMSException { return defaultPriority; } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public void setTimeToLive(long timeToLive) throws JMSException { this.timeToLive = timeToLive; } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public long getTimeToLive() throws JMSException { return timeToLive; } - + /** - * Sets the minimum length of time in milliseconds that must elapse after a + * Sets the minimum length of time in milliseconds that must elapse after a * message is sent before the JMS provider may deliver the message to a consumer. *

* This must be a multiple of 1000, since SQS only supports delivery delays @@ -511,17 +515,17 @@ public void setDeliveryDelay(long deliveryDelay) { if (deliveryDelay % 1000 != 0) { throw new IllegalArgumentException("Delivery delay must be a multiple of 1000: " + deliveryDelay); } - this.deliveryDelaySeconds = (int)(deliveryDelay / 1000); + this.deliveryDelaySeconds = (int) (deliveryDelay / 1000); } /** - * Gets the minimum length of time in milliseconds that must elapse after a + * Gets the minimum length of time in milliseconds that must elapse after a * message is sent before the JMS provider may deliver the message to a consumer. */ public long getDeliveryDelay() { - return deliveryDelaySeconds * 1000; + return deliveryDelaySeconds * 1000L; } - + void checkClosed() throws IllegalStateException { if (closed.get()) { throw new IllegalStateException("The producer is closed."); diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSMessagingClientConstants.java b/src/main/java/com/amazon/sqs/javamessaging/SQSMessagingClientConstants.java index 099c8b4..65c1a17 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSMessagingClientConstants.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSMessagingClientConstants.java @@ -14,8 +14,8 @@ */ package com.amazon.sqs.javamessaging; -import javax.jms.ConnectionMetaData; -import javax.jms.JMSException; +import jakarta.jms.ConnectionMetaData; +import jakarta.jms.JMSException; public class SQSMessagingClientConstants { diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSQueueDestination.java b/src/main/java/com/amazon/sqs/javamessaging/SQSQueueDestination.java index 4a42eb1..4b8c00a 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSQueueDestination.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSQueueDestination.java @@ -14,16 +14,20 @@ */ package com.amazon.sqs.javamessaging; -import javax.jms.Destination; -import javax.jms.JMSException; - -import javax.jms.Queue; +import jakarta.jms.Destination; +import jakarta.jms.Queue; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; /** * A SQSQueueDestination object encapsulates a queue name and SQS specific queue * URL. This is the way a client specifies the identity of a queue to JMS API * methods. */ +@Getter +@ToString(exclude = {"isFifo"}) +@EqualsAndHashCode public class SQSQueueDestination implements Destination, Queue { private final String queueName; @@ -37,63 +41,4 @@ public class SQSQueueDestination implements Destination, Queue { this.queueUrl = queueUrl; this.isFifo = this.queueName.endsWith(".fifo"); } - - /** - * Returns the name of this queue. - * - * @return queueName - */ - @Override - public String getQueueName() throws JMSException { - return this.queueName; - } - - /** - * Returns the queueUrl of this queue. - * - * @return queueUrl - */ - public String getQueueUrl() { - return queueUrl; - } - - public boolean isFifo() { - return isFifo; - } - - @Override - public String toString() { - return "SQSDestination [queueName=" + queueName + ", queueUrl=" + queueUrl + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((queueName == null) ? 0 : queueName.hashCode()); - result = prime * result + ((queueUrl == null) ? 0 : queueUrl.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SQSQueueDestination other = (SQSQueueDestination) obj; - if (queueName == null) { - if (other.queueName != null) - return false; - } else if (!queueName.equals(other.queueName)) - return false; - if (queueUrl == null) { - if (other.queueUrl != null) - return false; - } else if (!queueUrl.equals(other.queueUrl)) - return false; - return true; - } } diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSSession.java b/src/main/java/com/amazon/sqs/javamessaging/SQSSession.java index e26a085..03fcfb6 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSSession.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSSession.java @@ -14,45 +14,6 @@ */ package com.amazon.sqs.javamessaging; -import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import javax.jms.BytesMessage; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.MapMessage; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.ObjectMessage; -import javax.jms.Queue; -import javax.jms.QueueBrowser; -import javax.jms.QueueReceiver; -import javax.jms.QueueSender; -import javax.jms.QueueSession; -import javax.jms.Session; -import javax.jms.StreamMessage; -import javax.jms.TemporaryQueue; -import javax.jms.TemporaryTopic; -import javax.jms.TextMessage; -import javax.jms.Topic; -import javax.jms.TopicSubscriber; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.IllegalStateException; - import com.amazon.sqs.javamessaging.SQSMessageConsumerPrefetch.MessageManager; import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; @@ -62,6 +23,18 @@ import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; import com.amazon.sqs.javamessaging.util.SQSMessagingClientThreadFactory; +import jakarta.jms.IllegalStateException; +import jakarta.jms.Queue; +import jakarta.jms.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; /** * A session serves several purposes: @@ -73,9 +46,9 @@ *

  • It serializes execution of message listeners registered with its message * consumers.
  • * - *

    + *

    * Not safe for concurrent use. - *

    + *

    * This session object does not support: *

      *
    • (Temporary)Topic
    • @@ -89,20 +62,24 @@ */ public class SQSSession implements Session, QueueSession { private static final Logger LOG = LoggerFactory.getLogger(SQSSession.class); - + private static final int SESSION_EXECUTOR_GRACEFUL_SHUTDOWN_TIME = 10; - + static final String SESSION_EXECUTOR_NAME = "SessionCallBackScheduler"; - /** Used to create session callback scheduler threads */ + /** + * Used to create session callback scheduler threads + */ static final SQSMessagingClientThreadFactory SESSION_THREAD_FACTORY = new SQSMessagingClientThreadFactory( SESSION_EXECUTOR_NAME, false, true); - static final String CONSUMER_PREFETCH_EXECUTER_NAME = "ConsumerPrefetch"; + static final String CONSUMER_PREFETCH_EXECUTOR_NAME = "ConsumerPrefetch"; - /** Used to create consumer prefetcher threads */ + /** + * Used to create consumer prefetcher threads + */ static final SQSMessagingClientThreadFactory CONSUMER_PREFETCH_THREAD_FACTORY = new SQSMessagingClientThreadFactory( - CONSUMER_PREFETCH_EXECUTER_NAME, true); + CONSUMER_PREFETCH_EXECUTOR_NAME, true); /** * Non standard acknowledge mode. This is a variation of CLIENT_ACKNOWLEDGE @@ -121,7 +98,7 @@ public class SQSSession implements Session, QueueSession { * False if Session is stopped. */ volatile boolean running = false; - + /** * True if Session is closed or close is in-progress. */ @@ -139,7 +116,7 @@ public class SQSSession implements Session, QueueSession { * Acknowledger of this Session. */ private final Acknowledger acknowledger; - + /** * Negative acknowledger of this Session */ @@ -154,7 +131,7 @@ public class SQSSession implements Session, QueueSession { * Set of MessageConsumer under this Session */ private final Set messageConsumers; - + /** * Thread that is responsible to guarantee serial execution of message * delivery on message listeners @@ -167,7 +144,7 @@ public class SQSSession implements Session, QueueSession { private final ExecutorService executor; private final Object stateLock = new Object(); - + /** * Used to determine if the caller thread is the session callback thread. * Guarded by stateLock @@ -180,15 +157,15 @@ public class SQSSession implements Session, QueueSession { */ private SQSMessageConsumer activeConsumerInCallback = null; - SQSSession(SQSConnection parentSQSConnection, AcknowledgeMode acknowledgeMode) throws JMSException{ + SQSSession(SQSConnection parentSQSConnection, AcknowledgeMode acknowledgeMode) throws JMSException { this(parentSQSConnection, acknowledgeMode, - Collections.newSetFromMap(new ConcurrentHashMap()), - Collections.newSetFromMap(new ConcurrentHashMap())); + Collections.newSetFromMap(new ConcurrentHashMap<>()), + Collections.newSetFromMap(new ConcurrentHashMap<>())); } SQSSession(SQSConnection parentSQSConnection, AcknowledgeMode acknowledgeMode, Set messageConsumers, - Set messageProducers) throws JMSException{ + Set messageProducers) throws JMSException { this.parentSQSConnection = parentSQSConnection; this.amazonSQSClient = parentSQSConnection.getWrappedAmazonSQSClient(); this.acknowledgeMode = acknowledgeMode; @@ -201,11 +178,11 @@ public class SQSSession implements Session, QueueSession { executor.execute(sqsSessionRunnable); } - + SQSConnection getParentConnection() { return parentSQSConnection; } - + /** * @return True if the current thread is the callback thread */ @@ -214,14 +191,13 @@ boolean isActiveCallbackSessionThread() { return activeCallbackSessionThread == Thread.currentThread(); } } - + /** * Creates a QueueReceiver for the specified queue. - * @param queue - * a queue receiver + * + * @param queue a queue receiver * @return new message consumer - * @throws JMSException - * If session is closed + * @throws JMSException If session is closed */ @Override public QueueReceiver createReceiver(Queue queue) throws JMSException { @@ -231,46 +207,41 @@ public QueueReceiver createReceiver(Queue queue) throws JMSException { /** * Creates a QueueReceiver for the specified queue. Does not * support messageSelector. It will drop anything in messageSelector. - * - * @param queue - * a queue destination - * @param messageSelector + * + * @param queue a queue destination + * @param messageSelector * @return new message receiver - * @throws JMSException - * If session is closed + * @throws JMSException If session is closed */ @Override public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException { return createReceiver(queue); } - + /** * Creates a QueueSender for the specified queue. - * - * @param queue - * a queue destination + * + * @param queue a queue destination * @return new message sender - * @throws JMSException - * If session is closed + * @throws JMSException If session is closed */ @Override public QueueSender createSender(Queue queue) throws JMSException { return (QueueSender) createProducer(queue); } - + /** * Creates a BytesMessage. - * + * * @return new BytesMessage - * @throws JMSException - * If session is closed or internal error + * @throws JMSException If session is closed or internal error */ @Override public BytesMessage createBytesMessage() throws JMSException { checkClosed(); return new SQSBytesMessage(); } - + /** * According to JMS specification, a message can be sent with only headers * without any payload, SQS does not support messages with empty payload. so @@ -280,56 +251,50 @@ public BytesMessage createBytesMessage() throws JMSException { public Message createMessage() throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - + /** * Creates a ObjectMessage. - * + * * @return new ObjectMessage - * @throws JMSException - * If session is closed or internal error + * @throws JMSException If session is closed or internal error */ @Override public ObjectMessage createObjectMessage() throws JMSException { checkClosed(); return new SQSObjectMessage(); } - + /** * Creates an initialized ObjectMessage. - * - * @param object - * The initialized ObjectMessage + * + * @param object The initialized ObjectMessage * @return new ObjectMessage - * @throws JMSException - * If session is closed or internal error + * @throws JMSException If session is closed or internal error */ @Override public ObjectMessage createObjectMessage(Serializable object) throws JMSException { checkClosed(); return new SQSObjectMessage(object); } - + /** * Creates a TextMessage. - * + * * @return new TextMessage - * @throws JMSException - * If session is closed or internal error + * @throws JMSException If session is closed or internal error */ @Override public TextMessage createTextMessage() throws JMSException { checkClosed(); return new SQSTextMessage(); } - + /** * Creates an initialized TextMessage. - * - * @param text - * The initialized TextMessage + * + * @param text The initialized TextMessage * @return new TextMessage - * @throws JMSException - * If session is closed or internal error + * @throws JMSException If session is closed or internal error */ @Override public TextMessage createTextMessage(String text) throws JMSException { @@ -340,48 +305,45 @@ public TextMessage createTextMessage(String text) throws JMSException { /** * Returns the acknowledge mode of the session. The acknowledge mode is set * at the time that the session is created. - * + * * @return acknowledge mode */ @Override public int getAcknowledgeMode() throws JMSException { return acknowledgeMode.getOriginalAcknowledgeMode(); } - + /** * Closes the session. - *

      + *

      * This will not return until all the message consumers and producers close * internally, which blocks until receives and/or message listeners in * progress have completed. A blocked message consumer receive call returns * null when this session is closed. - *

      + *

      * Since consumer prefetch threads use SQS long-poll feature with 20 seconds * timeout, closing each consumer prefetch thread can take up to 20 seconds, * which in-turn will impact the time on session close. - *

      + *

      * This method is safe for concurrent use. - *

      + *

      * A message listener must not attempt to close its own session; otherwise * throws a IllegalStateException. - *

      + *

      * Invoking any other session method on a closed session must throw a * IllegalStateException. - * - * @throws IllegalStateException - * If called by a message listener on its own - * Session. - * @throws JMSException - * On internal error. + * + * @throws IllegalStateException If called by a message listener on its own + * Session. + * @throws JMSException On internal error. */ @Override public void close() throws JMSException { - if (closed) { return; } - - /** + + /* * A MessageListener must not attempt to close its own Session as * this would lead to deadlock */ @@ -389,7 +351,7 @@ public void close() throws JMSException { throw new IllegalStateException( "MessageListener must not attempt to close its own Session to prevent potential deadlock issues"); } - + doClose(); } @@ -402,7 +364,7 @@ void doClose() throws JMSException { } stateLock.notifyAll(); } - + if (closed) { return; } @@ -414,20 +376,19 @@ void doClose() throws JMSException { for (SQSMessageConsumer messageConsumer : messageConsumers) { messageConsumer.close(); } - + recover(); - + try { if (executor != null) { LOG.info("Shutting down " + SESSION_EXECUTOR_NAME + " executor"); - /** Shut down executor. */ executor.shutdown(); - + waitForCallbackComplete(); - + sqsSessionRunnable.close(); - + for (MessageProducer messageProducer : messageProducers) { messageProducer.close(); } @@ -435,15 +396,15 @@ void doClose() throws JMSException { if (!executor.awaitTermination(10, TimeUnit.SECONDS)) { LOG.warn("Can't terminate executor service " + SESSION_EXECUTOR_NAME + " after " + - SESSION_EXECUTOR_GRACEFUL_SHUTDOWN_TIME + - " seconds, some running threads will be shutdown immediately"); + SESSION_EXECUTOR_GRACEFUL_SHUTDOWN_TIME + + " seconds, some running threads will be shutdown immediately"); executor.shutdownNow(); } } } catch (InterruptedException e) { LOG.error("Interrupted while closing the session.", e); } - + } finally { synchronized (stateLock) { closed = true; @@ -451,8 +412,7 @@ void doClose() throws JMSException { stateLock.notifyAll(); } } - }/** Blocks until closing of the session completes */ - else { + }/* Blocks until closing of the session completes */ else { synchronized (stateLock) { while (!closed) { try { @@ -469,48 +429,45 @@ void doClose() throws JMSException { /** * Negative acknowledges all the messages on the session that is delivered * but not acknowledged. - * - * @throws JMSException - * If session is closed or on internal error. + * + * @throws JMSException If session is closed or on internal error. */ @Override public void recover() throws JMSException { checkClosed(); - + //let's get all unacknowledged message identifiers List unAckedMessages = acknowledger.getUnAckMessages(); acknowledger.forgetUnAckMessages(); - + //let's summarize which queues and which message groups we're nacked //we have to purge all prefetched messages and queued up callback entries for affected queues and groups //if not, we would end up consuming messages out of order Map> queueToGroupsMapping = getAffectedGroupsPerQueueUrl(unAckedMessages); for (SQSMessageConsumer consumer : this.messageConsumers) { - SQSQueueDestination sqsQueue = (SQSQueueDestination)consumer.getQueue(); + SQSQueueDestination sqsQueue = (SQSQueueDestination) consumer.getQueue(); Set affectedGroups = queueToGroupsMapping.get(sqsQueue.getQueueUrl()); if (affectedGroups != null) { unAckedMessages.addAll(consumer.purgePrefetchedMessagesWithGroups(affectedGroups)); } } - + unAckedMessages.addAll(sqsSessionRunnable.purgeScheduledCallbacksForQueuesAndGroups(queueToGroupsMapping)); - + if (!unAckedMessages.isEmpty()) { negativeAcknowledger.bulkAction(unAckedMessages, unAckedMessages.size()); } } private Map> getAffectedGroupsPerQueueUrl(List messages) { - Map> queueToGroupsMapping = new HashMap>(); + Map> queueToGroupsMapping = new HashMap<>(); for (SQSMessageIdentifier message : messages) { String groupId = message.getGroupId(); if (groupId != null) { String queueUrl = message.getQueueUrl(); - if (!queueToGroupsMapping.containsKey(queueUrl)) { - queueToGroupsMapping.put(queueUrl, new HashSet()); - } - queueToGroupsMapping.get(queueUrl).add(groupId); + Set groups = queueToGroupsMapping.computeIfAbsent(queueUrl, k -> new HashSet<>()); + groups.add(groupId); } } return queueToGroupsMapping; @@ -519,16 +476,14 @@ private Map> getAffectedGroupsPerQueueUrl(ListMessageProducer for the specified destination. * Only queue destinations are supported at this time. - * - * @param destination - * a queue destination + * + * @param destination a queue destination * @return new message producer - * @throws JMSException - * If session is closed or queue destination is not used + * @throws JMSException If session is closed or queue destination is not used */ @Override public MessageProducer createProducer(Destination destination) throws JMSException { @@ -544,29 +499,27 @@ public MessageProducer createProducer(Destination destination) throws JMSExcepti } return messageProducer; } - + /** * Creates a MessageConsumer for the specified destination. * Only queue destinations are supported at this time. - * - * @param destination - * a queue destination + * + * @param destination a queue destination * @return new message consumer - * @throws JMSException - * If session is closed or queue destination is not used + * @throws JMSException If session is closed or queue destination is not used */ @Override public MessageConsumer createConsumer(Destination destination) throws JMSException { checkClosed(); - if (!(destination instanceof SQSQueueDestination)) { + if (!(destination instanceof SQSQueueDestination sqsQueueDestination)) { throw new JMSException("Actual type of Destination/Queue has to be SQSQueueDestination"); } SQSMessageConsumer messageConsumer; synchronized (stateLock) { checkClosing(); - messageConsumer = createSQSMessageConsumer((SQSQueueDestination) destination); + messageConsumer = createSQSMessageConsumer(sqsQueueDestination); messageConsumers.add(messageConsumer); - if( running ) { + if (running) { messageConsumer.startPrefetch(); } } @@ -575,23 +528,20 @@ public MessageConsumer createConsumer(Destination destination) throws JMSExcepti SQSMessageConsumer createSQSMessageConsumer(SQSQueueDestination destination) { return new SQSMessageConsumer( - parentSQSConnection, this, sqsSessionRunnable, (SQSQueueDestination) destination, - acknowledger, negativeAcknowledger, + parentSQSConnection, this, sqsSessionRunnable, destination, + acknowledger, negativeAcknowledger, CONSUMER_PREFETCH_THREAD_FACTORY); } /** - * * Creates a MessageConsumer for the specified destination. * Only queue destinations are supported at this time. * It will ignore any argument in messageSelector. - * - * @param destination - * a queue destination - * @param messageSelector + * + * @param destination a queue destination + * @param messageSelector * @return new message consumer - * @throws JMSException - * If session is closed or queue destination is not used + * @throws JMSException If session is closed or queue destination is not used */ @Override @@ -601,19 +551,17 @@ public MessageConsumer createConsumer(Destination destination, String messageSel } return createConsumer(destination); } - + /** * Creates a MessageConsumer for the specified destination. * Only queue destinations are supported at this time. It will ignore any * argument in messageSelector and NoLocal. - * - * @param destination - * a queue destination + * + * @param destination a queue destination * @param messageSelector * @param NoLocal * @return new message consumer - * @throws JMSException - * If session is closed or queue destination is not used + * @throws JMSException If session is closed or queue destination is not used */ @Override public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean NoLocal) throws JMSException { @@ -623,31 +571,39 @@ public MessageConsumer createConsumer(Destination destination, String messageSel return createConsumer(destination); } + @Override + public MessageConsumer createSharedConsumer(Topic topic, String sharedSubscriptionName) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public MessageConsumer createSharedConsumer(Topic topic, String sharedSubscriptionName, String messageSelector) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + /** * This does not create SQS Queue. This method is only to create JMS Queue Object. * Make sure the queue exists corresponding to the queueName. + * * @param queueName * @return a queue destination - * @throws JMSException - * If session is closed or invalid queue is provided + * @throws JMSException If session is closed or invalid queue is provided */ @Override public Queue createQueue(String queueName) throws JMSException { checkClosed(); return new SQSQueueDestination(queueName, amazonSQSClient.getQueueUrl(queueName).queueUrl()); } - + /** * This does not create SQS Queue. This method is only to create JMS Queue * Object. Make sure the queue exists corresponding to the queueName and * ownerAccountId. - * + * * @param queueName - * @param ownerAccountId - * the account id, which originally created the queue on SQS + * @param ownerAccountId the account id, which originally created the queue on SQS * @return a queue destination - * @throws JMSException - * If session is closed or invalid queue is provided + * @throws JMSException If session is closed or invalid queue is provided */ public Queue createQueue(String queueName, String ownerAccountId) throws JMSException { checkClosed(); @@ -668,9 +624,9 @@ void removeConsumer(SQSMessageConsumer consumer) { * it will remove itself from list of producers. */ void removeProducer(SQSMessageProducer producer) { - messageProducers.remove(producer); + messageProducers.remove(producer); } - + void startingCallback(SQSMessageConsumer consumer) throws InterruptedException, JMSException { if (closed) { return; @@ -693,7 +649,7 @@ void startingCallback(SQSMessageConsumer consumer) throws InterruptedException, activeCallbackSessionThread = Thread.currentThread(); } } - + void finishedCallback() throws JMSException { synchronized (stateLock) { if (activeConsumerInCallback == null) { @@ -704,7 +660,7 @@ void finishedCallback() throws JMSException { stateLock.notifyAll(); } } - + void waitForConsumerCallbackToComplete(SQSMessageConsumer consumer) throws InterruptedException { synchronized (stateLock) { while (activeConsumerInCallback == consumer) { @@ -718,7 +674,7 @@ void waitForConsumerCallbackToComplete(SQSMessageConsumer consumer) throws Inter } } } - + void waitForCallbackComplete() { synchronized (stateLock) { while (activeConsumerInCallback != null) { @@ -731,114 +687,149 @@ void waitForCallbackComplete() { } } - /** SQS does not support transacted. Transacted will always be false. */ + /** + * SQS does not support transacted. Transacted will always be false. + */ @Override public boolean getTransacted() throws JMSException { return false; } - /** This method is not supported. This method is related to transaction which SQS doesn't support */ + /** + * This method is not supported. This method is related to transaction which SQS doesn't support + */ @Override public void commit() throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. This method is related to transaction which SQS doesn't support */ + /** + * This method is not supported. This method is related to transaction which SQS doesn't support + */ @Override public void rollback() throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. This method is related to Topic which SQS doesn't support */ + /** + * This method is not supported. This method is related to Topic which SQS doesn't support + */ @Override public void unsubscribe(String name) throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public Topic createTopic(String topicName) throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal) throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + @Override + public MessageConsumer createDurableConsumer(Topic topic, String name) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public MessageConsumer createDurableConsumer(Topic topic, String name, String messageSelector, boolean noLocal) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public MessageConsumer createSharedDurableConsumer(Topic topic, String name) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + @Override + public MessageConsumer createSharedDurableConsumer(Topic topic, String name, String messageSelector) throws JMSException { + throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); + } + + /** + * This method is not supported. + */ @Override public QueueBrowser createBrowser(Queue queue) throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public QueueBrowser createBrowser(Queue queue, String messageSelector) throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public TemporaryQueue createTemporaryQueue() throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public TemporaryTopic createTemporaryTopic() throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public MessageListener getMessageListener() throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public void setMessageListener(MessageListener listener) throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public StreamMessage createStreamMessage() throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - /** This method is not supported. */ + /** + * This method is not supported. + */ @Override public MapMessage createMapMessage() throws JMSException { throw new JMSException(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } - static class CallbackEntry { - private final MessageListener messageListener; - private final MessageManager messageManager; - - CallbackEntry(MessageListener messageListener, MessageManager messageManager) { - this.messageListener = messageListener; - this.messageManager = messageManager; - } - - public MessageListener getMessageListener() { - return messageListener; - } - - public MessageManager getMessageManager() { - return messageManager; - } + record CallbackEntry(MessageListener messageListener, MessageManager messageManager) { } - + /** * Check if session is closed. */ @@ -847,7 +838,7 @@ public void checkClosed() throws IllegalStateException { throw new IllegalStateException("Session is closed"); } } - + /** * Check if session is closed or closing. */ @@ -856,19 +847,19 @@ public void checkClosing() throws IllegalStateException { throw new IllegalStateException("Session is closed or closing"); } } - + void start() throws IllegalStateException { checkClosed(); synchronized (stateLock) { checkClosing(); - running = true; + running = true; for (SQSMessageConsumer messageConsumer : messageConsumers) { messageConsumer.startPrefetch(); } stateLock.notifyAll(); } } - + void stop() throws IllegalStateException { checkClosed(); synchronized (stateLock) { @@ -890,11 +881,11 @@ void stop() throws IllegalStateException { boolean isCallbackActive() { return activeConsumerInCallback != null; } - + void setActiveConsumerInCallback(SQSMessageConsumer consumer) { activeConsumerInCallback = consumer; } - + Object getStateLock() { return stateLock; } @@ -902,7 +893,7 @@ Object getStateLock() { boolean isClosed() { return closed; } - + boolean isClosing() { return closing; } diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSSessionCallbackScheduler.java b/src/main/java/com/amazon/sqs/javamessaging/SQSSessionCallbackScheduler.java index 58499ab..ddb4688 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSSessionCallbackScheduler.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSSessionCallbackScheduler.java @@ -22,9 +22,9 @@ import java.util.Map; import java.util.Set; -import javax.jms.JMSException; -import javax.jms.MessageListener; -import javax.jms.Session; +import jakarta.jms.JMSException; +import jakarta.jms.MessageListener; +import jakarta.jms.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,11 +46,11 @@ public class SQSSessionCallbackScheduler implements Runnable { protected ArrayDeque callbackQueue; - private AcknowledgeMode acknowledgeMode; + private final AcknowledgeMode acknowledgeMode; - private SQSSession session; + private final SQSSession session; - private NegativeAcknowledger negativeAcknowledger; + private final NegativeAcknowledger negativeAcknowledger; private final Acknowledger acknowledger; @@ -71,7 +71,7 @@ public class SQSSessionCallbackScheduler implements Runnable { this.acknowledgeMode = acknowledgeMode; this.acknowledger = acknowledger; this.negativeAcknowledger = negativeAcknowledger; - callbackQueue = new ArrayDeque(); + callbackQueue = new ArrayDeque<>(); } /** @@ -80,7 +80,7 @@ public class SQSSessionCallbackScheduler implements Runnable { */ void close() { closed = true; - /** Wake-up the thread in case it was blocked on empty queue */ + /* Wake-up the thread in case it was blocked on empty queue */ synchronized (callbackQueue) { callbackQueue.notify(); } @@ -101,7 +101,7 @@ public void run() { try { callbackQueue.wait(); } catch (InterruptedException e) { - /** + /* * Will be retried on the next loop, and * break if the callback scheduler is closed. */ @@ -113,10 +113,10 @@ public void run() { } } - MessageListener messageListener = callbackEntry.getMessageListener(); - MessageManager messageManager = callbackEntry.getMessageManager(); - SQSMessage message = (SQSMessage) messageManager.getMessage(); - SQSMessageConsumer messageConsumer = messageManager.getPrefetchManager().getMessageConsumer(); + MessageListener messageListener = callbackEntry.messageListener(); + MessageManager messageManager = callbackEntry.messageManager(); + SQSMessage message = (SQSMessage) messageManager.message(); + SQSMessageConsumer messageConsumer = messageManager.prefetchManager().getMessageConsumer(); if (messageConsumer.isClosed()) { nackReceivedMessage(message); continue; @@ -133,11 +133,11 @@ public void run() { } try { - /** + /* * Notifying consumer prefetch thread so that it can * continue to prefetch */ - messageManager.getPrefetchManager().messageDispatched(); + messageManager.prefetchManager().messageDispatched(); int ackMode = acknowledgeMode.getOriginalAcknowledgeMode(); boolean tryNack = true; try { @@ -171,7 +171,7 @@ public void run() { } } - /** + /* * The consumer close is delegated to the session thread * if consumer close is called by its message listener's * onMessage method on its own consumer. @@ -185,7 +185,7 @@ public void run() { // Let the prefetch manager know we're available to // process another message (if there is a still a listener attached). - messageManager.getPrefetchManager().messageListenerReady(); + messageManager.prefetchManager().messageListenerReady(); } } catch (Throwable ex) { LOG.error("Unexpected exception thrown during the run of the scheduled callback", ex); @@ -193,7 +193,7 @@ public void run() { } } finally { if (callbackEntry != null) { - nackReceivedMessage((SQSMessage) callbackEntry.getMessageManager().getMessage()); + nackReceivedMessage((SQSMessage) callbackEntry.messageManager().message()); } nackQueuedMessages(); } @@ -219,9 +219,9 @@ void scheduleCallBacks(MessageListener messageListener, List mes void nackQueuedMessages() { synchronized (callbackQueue) { try { - List nackMessageIdentifiers = new ArrayList(); + List nackMessageIdentifiers = new ArrayList<>(); while (!callbackQueue.isEmpty()) { - SQSMessage nackMessage = (SQSMessage) callbackQueue.pollFirst().getMessageManager().getMessage(); + SQSMessage nackMessage = (SQSMessage) callbackQueue.pollFirst().messageManager().message(); nackMessageIdentifiers.add(SQSMessageIdentifier.fromSQSMessage(nackMessage)); } @@ -237,7 +237,7 @@ void nackQueuedMessages() { private void nackReceivedMessage(SQSMessage message) { try { SQSMessageIdentifier messageIdentifier = SQSMessageIdentifier.fromSQSMessage(message); - List nackMessageIdentifiers = new ArrayList(); + List nackMessageIdentifiers = new ArrayList<>(); nackMessageIdentifiers.add(messageIdentifier); //failing to process a message with a specific group id means we have to nack all the pending messages with the same group id @@ -255,13 +255,13 @@ private void nackReceivedMessage(SQSMessage message) { } List purgeScheduledCallbacksForQueuesAndGroups(Map> queueToGroupsMapping) throws JMSException { - List purgedCallbacks = new ArrayList(); + List purgedCallbacks = new ArrayList<>(); synchronized (callbackQueue) { //let's walk over the callback queue Iterator callbackIterator = callbackQueue.iterator(); while (callbackIterator.hasNext()) { CallbackEntry callbackEntry = callbackIterator.next(); - SQSMessageIdentifier pendingCallbackIdentifier = SQSMessageIdentifier.fromSQSMessage((SQSMessage) callbackEntry.getMessageManager().getMessage()); + SQSMessageIdentifier pendingCallbackIdentifier = SQSMessageIdentifier.fromSQSMessage((SQSMessage) callbackEntry.messageManager().message()); //is the callback entry for one of the affected queues? Set affectedGroupsInQueue = queueToGroupsMapping.get(pendingCallbackIdentifier.getQueueUrl()); @@ -274,7 +274,7 @@ List purgeScheduledCallbacksForQueuesAndGroups(Map + *

      * Specifies the different possible modes of acknowledgment: *

        *
      • In ACK_AUTO mode, every time the user receives a message, it is @@ -37,22 +35,22 @@ public enum AcknowledgeMode { ACK_AUTO, ACK_UNORDERED, ACK_RANGE; private int originalAcknowledgeMode; - + /** - * Sets the acknowledge mode. + * Sets the acknowledgment mode. */ public AcknowledgeMode withOriginalAcknowledgeMode(int originalAcknowledgeMode) { this.originalAcknowledgeMode = originalAcknowledgeMode; return this; } - + /** - * Returns the acknowledge mode. + * Returns the acknowledgment mode. */ public int getOriginalAcknowledgeMode() { return originalAcknowledgeMode; } - + /** * Creates the acknowledger associated with the session, which will be used * to acknowledge the delivered messages on consumers of the session. @@ -61,19 +59,12 @@ public int getOriginalAcknowledgeMode() { * the SQS client to delete messages * @param parentSQSSession * the associated session for the acknowledger - * @throws JMSException - * If invalid acknowledge mode is used. */ - public Acknowledger createAcknowledger(AmazonSQSMessagingClientWrapper amazonSQSClient, SQSSession parentSQSSession) throws JMSException { - switch (this) { - case ACK_AUTO: - return new AutoAcknowledger(amazonSQSClient, parentSQSSession); - case ACK_RANGE: - return new RangedAcknowledger(amazonSQSClient, parentSQSSession); - case ACK_UNORDERED: - return new UnorderedAcknowledger(amazonSQSClient, parentSQSSession); - default: - throw new JMSException(this + " - AcknowledgeMode does not exist"); - } + public Acknowledger createAcknowledger(AmazonSQSMessagingClientWrapper amazonSQSClient, SQSSession parentSQSSession) { + return switch (this) { + case ACK_AUTO -> new AutoAcknowledger(amazonSQSClient, parentSQSSession); + case ACK_RANGE -> new RangedAcknowledger(amazonSQSClient, parentSQSSession); + case ACK_UNORDERED -> new UnorderedAcknowledger(amazonSQSClient, parentSQSSession); + }; } } diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/Acknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/Acknowledger.java index 290d902..a453707 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/Acknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/Acknowledger.java @@ -16,7 +16,7 @@ import java.util.List; -import javax.jms.JMSException; +import jakarta.jms.JMSException; import com.amazon.sqs.javamessaging.message.SQSMessage; @@ -29,7 +29,7 @@ public interface Acknowledger { * message to acknowledge. * @throws JMSException */ - public void acknowledge(SQSMessage message) throws JMSException; + void acknowledge(SQSMessage message) throws JMSException; /** * Used when receiving messages. Depending on acknowledge mode this will @@ -39,17 +39,17 @@ public interface Acknowledger { * notify acknowledger message is received * @throws JMSException */ - public void notifyMessageReceived(SQSMessage message) throws JMSException; + void notifyMessageReceived(SQSMessage message) throws JMSException; /** * Used in negative acknowledge. Gets all delivered but not acknowledged * messages. */ - public List getUnAckMessages(); + List getUnAckMessages(); /** * Deletes all not acknowledged delivered messages. */ - public void forgetUnAckMessages(); + void forgetUnAckMessages(); } diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/AutoAcknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/AutoAcknowledger.java index 9be8f93..df5c3bf 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/AutoAcknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/AutoAcknowledger.java @@ -14,17 +14,16 @@ */ package com.amazon.sqs.javamessaging.acknowledge; -import java.util.Collections; -import java.util.List; - -import javax.jms.JMSException; - import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; import com.amazon.sqs.javamessaging.SQSSession; import com.amazon.sqs.javamessaging.message.SQSMessage; - +import jakarta.jms.JMSException; import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * Used by session to automatically acknowledge a client's receipt of a message * either when the session has successfully returned from a call to receive or @@ -65,7 +64,7 @@ public void notifyMessageReceived(SQSMessage message) throws JMSException { */ @Override public List getUnAckMessages() { - return Collections.emptyList(); + return new ArrayList<>(); } /** AutoAcknowledge doesn't need to do anything in this method. */ diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/BulkSQSOperation.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/BulkSQSOperation.java index 6eb0243..fb338a0 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/BulkSQSOperation.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/BulkSQSOperation.java @@ -20,7 +20,7 @@ import java.util.Map; import java.util.Map.Entry; -import javax.jms.JMSException; +import jakarta.jms.JMSException; import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; @@ -46,7 +46,7 @@ public void bulkAction(List messageIdentifierList, int ind assert indexOfMessage > 0; assert indexOfMessage <= messageIdentifierList.size(); - Map> receiptHandleWithSameQueueUrl = new HashMap>(); + Map> receiptHandleWithSameQueueUrl = new HashMap<>(); // Add all messages up to and including requested message into Map. // Map contains key as queueUrl and value as list receiptHandles from @@ -55,12 +55,8 @@ public void bulkAction(List messageIdentifierList, int ind for (int i = 0; i < indexOfMessage; i++) { SQSMessageIdentifier messageIdentifier = messageIdentifierList.get(i); String queueUrl = messageIdentifier.getQueueUrl(); - List receiptHandles = receiptHandleWithSameQueueUrl.get(queueUrl); + List receiptHandles = receiptHandleWithSameQueueUrl.computeIfAbsent(queueUrl, k -> new ArrayList<>()); // if value of queueUrl is null create new list. - if (receiptHandles == null) { - receiptHandles = new ArrayList(); - receiptHandleWithSameQueueUrl.put(queueUrl, receiptHandles); - } // add receiptHandle to the list. receiptHandles.add(messageIdentifier.getReceiptHandle()); // Once there are 10 messages in messageBatch, apply the batch action diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/NegativeAcknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/NegativeAcknowledger.java index 2c77187..9dfbf40 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/NegativeAcknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/NegativeAcknowledger.java @@ -18,7 +18,7 @@ import java.util.ArrayList; import java.util.List; -import javax.jms.JMSException; +import jakarta.jms.JMSException; import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; @@ -59,9 +59,9 @@ public NegativeAcknowledger(AmazonSQSMessagingClientWrapper amazonSQSClient) { * If action throws. */ public void bulkAction(ArrayDeque messageQueue, String queueUrl) throws JMSException { - List receiptHandles = new ArrayList(); + List receiptHandles = new ArrayList<>(); while (!messageQueue.isEmpty()) { - receiptHandles.add(((SQSMessage) (messageQueue.pollFirst().getMessage())).getReceiptHandle()); + receiptHandles.add(((SQSMessage) (messageQueue.pollFirst().message())).getReceiptHandle()); // If there is more than 10 stop can call action if (receiptHandles.size() == SQSMessagingClientConstants.MAX_BATCH) { @@ -88,13 +88,11 @@ public void bulkAction(ArrayDeque messageQueue, String queueUrl) */ @Override public void action(String queueUrl, List receiptHandles) throws JMSException { - if (receiptHandles == null || receiptHandles.isEmpty()) { return; } - List nackEntries = new ArrayList( - receiptHandles.size()); + List nackEntries = new ArrayList<>(receiptHandles.size()); int batchId = 0; for (String messageReceiptHandle : receiptHandles) { ChangeMessageVisibilityBatchRequestEntry changeMessageVisibilityBatchRequestEntry = ChangeMessageVisibilityBatchRequestEntry.builder() diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/RangedAcknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/RangedAcknowledger.java index 17885a8..a0e2bea 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/RangedAcknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/RangedAcknowledger.java @@ -19,7 +19,7 @@ import java.util.List; import java.util.Queue; -import javax.jms.JMSException; +import jakarta.jms.JMSException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,7 +53,7 @@ public class RangedAcknowledger extends BulkSQSOperation implements Acknowledger public RangedAcknowledger(AmazonSQSMessagingClientWrapper amazonSQSClient, SQSSession session) { this.amazonSQSClient = amazonSQSClient; this.session = session; - this.unAckMessages = new LinkedList(); + this.unAckMessages = new LinkedList<>(); } /** @@ -69,9 +69,9 @@ public void acknowledge(SQSMessage message) throws JMSException { int indexOfMessage = indexOf(ackMessage); - /** + /* * In case the message has already been deleted, warn user about it and - * return. If not then then it should continue with acknowledging all + * return. If not then it should continue with acknowledging all * the messages received before that */ if (indexOfMessage == -1) { @@ -114,7 +114,7 @@ public void notifyMessageReceived(SQSMessage message) throws JMSException { */ @Override public List getUnAckMessages() { - return new ArrayList(unAckMessages); + return new ArrayList<>(unAckMessages); } /** @@ -135,7 +135,7 @@ public void action(String queueUrl, List receiptHandles) throws JMSExcep return; } - List deleteMessageBatchRequestEntries = new ArrayList(); + List deleteMessageBatchRequestEntries = new ArrayList<>(); int batchId = 0; for (String receiptHandle : receiptHandles) { // Remove the message from queue of unAckMessages @@ -154,7 +154,7 @@ public void action(String queueUrl, List receiptHandles) throws JMSExcep .queueUrl(queueUrl) .entries(deleteMessageBatchRequestEntries) .build(); - /** + /* * TODO: If one of the batch calls fail, then the remaining messages on * the batch will not be deleted, and will be visible and delivered as * duplicate after visibility timeout expires. diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/SQSMessageIdentifier.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/SQSMessageIdentifier.java index 443b578..1b9e522 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/SQSMessageIdentifier.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/SQSMessageIdentifier.java @@ -14,23 +14,34 @@ */ package com.amazon.sqs.javamessaging.acknowledge; -import javax.jms.JMSException; - import com.amazon.sqs.javamessaging.message.SQSMessage; +import jakarta.jms.JMSException; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; /** * Identifies an SQS message, when (negative)acknowledging the message */ +@ToString(onlyExplicitlyIncluded = true) +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@Getter public class SQSMessageIdentifier { // The queueUrl where the message was sent or received from - private String queueUrl; + @ToString.Include + @EqualsAndHashCode.Include + private final String queueUrl; // The receipt handle returned after the delivery of the message from SQS - private String receiptHandle; + @ToString.Include + @EqualsAndHashCode.Include + private final String receiptHandle; // The SQS message id assigned on send. - private String sqsMessageId; + @ToString.Include + @EqualsAndHashCode.Include + private final String sqsMessageId; // The group id to which the message belongs private String groupId; @@ -52,84 +63,4 @@ public SQSMessageIdentifier(String queueUrl, String receiptHandle, String sqsMes public static SQSMessageIdentifier fromSQSMessage(SQSMessage sqsMessage) throws JMSException { return new SQSMessageIdentifier(sqsMessage.getQueueUrl(), sqsMessage.getReceiptHandle(), sqsMessage.getSQSMessageId(), sqsMessage.getSQSMessageGroupId()); } - - /** - * Returns the queueUrl where the message was sent or received from. - * - * @return queueUrl - */ - public String getQueueUrl() { - return this.queueUrl; - } - - /** - * Returns the receipt handle returned after the delivery of the message - * from SQS. - * - * @return receiptHandle - */ - public String getReceiptHandle() { - return this.receiptHandle; - } - - /** - * Returns the SQS message id assigned on send. - * - * @return sqsMessageId - */ - public String getSQSMessageID() { - return this.sqsMessageId; - } - - /** - * Returns the group id to which the message belongs. Non-null only for messages received from FIFO queues. - * - * @return groupId - */ - public String getGroupId() { - return this.groupId; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((queueUrl == null) ? 0 : queueUrl.hashCode()); - result = prime * result + ((receiptHandle == null) ? 0 : receiptHandle.hashCode()); - result = prime * result + ((sqsMessageId == null) ? 0 : sqsMessageId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SQSMessageIdentifier other = (SQSMessageIdentifier) obj; - if (queueUrl == null) { - if (other.queueUrl != null) - return false; - } else if (!queueUrl.equals(other.queueUrl)) - return false; - if (receiptHandle == null) { - if (other.receiptHandle != null) - return false; - } else if (!receiptHandle.equals(other.receiptHandle)) - return false; - if (sqsMessageId == null) { - if (other.sqsMessageId != null) - return false; - } else if (!sqsMessageId.equals(other.sqsMessageId)) - return false; - return true; - } - - @Override - public String toString() { - return "SQSMessageIdentifier [queueUrl=" + queueUrl + ", receiptHandle=" + receiptHandle + - ", sqsMessageId=" + sqsMessageId + "]"; - } } diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/UnorderedAcknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/UnorderedAcknowledger.java index fd5e060..499896d 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/UnorderedAcknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/UnorderedAcknowledger.java @@ -19,7 +19,7 @@ import java.util.List; import java.util.Map; -import javax.jms.JMSException; +import jakarta.jms.JMSException; import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; import com.amazon.sqs.javamessaging.SQSSession; @@ -45,7 +45,7 @@ public class UnorderedAcknowledger implements Acknowledger { public UnorderedAcknowledger (AmazonSQSMessagingClientWrapper amazonSQSClient, SQSSession session) { this.amazonSQSClient = amazonSQSClient; this.session = session; - this.unAckMessages = new HashMap(); + this.unAckMessages = new HashMap<>(); } /** @@ -76,7 +76,7 @@ public void notifyMessageReceived(SQSMessage message) throws JMSException { */ @Override public List getUnAckMessages() { - return new ArrayList(unAckMessages.values()); + return new ArrayList<>(unAckMessages.values()); } /** diff --git a/src/main/java/com/amazon/sqs/javamessaging/message/SQSBytesMessage.java b/src/main/java/com/amazon/sqs/javamessaging/message/SQSBytesMessage.java index e8c759b..4f720ba 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/message/SQSBytesMessage.java +++ b/src/main/java/com/amazon/sqs/javamessaging/message/SQSBytesMessage.java @@ -22,12 +22,12 @@ import java.io.IOException; import java.util.Arrays; -import javax.jms.BytesMessage; -import javax.jms.JMSException; -import javax.jms.MessageEOFException; -import javax.jms.MessageFormatException; -import javax.jms.MessageNotReadableException; -import javax.jms.MessageNotWriteableException; +import jakarta.jms.BytesMessage; +import jakarta.jms.JMSException; +import jakarta.jms.MessageEOFException; +import jakarta.jms.MessageFormatException; +import jakarta.jms.MessageNotReadableException; +import jakarta.jms.MessageNotWriteableException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,8 +42,6 @@ * licensed under Apache2.0. Its methods are based largely on those found in * java.io.DataInputStream and * java.io.DataOutputStream. - * - * @see org.apache.activemq.command.ActiveMQStreamMessage */ public class SQSBytesMessage extends SQSMessage implements BytesMessage { private static final Logger LOG = LoggerFactory.getLogger(SQSBytesMessage.class); @@ -62,9 +60,9 @@ public class SQSBytesMessage extends SQSMessage implements BytesMessage { public SQSBytesMessage(Acknowledger acknowledger, String queueUrl, Message sqsMessage) throws JMSException { super(acknowledger, queueUrl, sqsMessage); try { - /** Bytes is set by the reset() */ + /* Bytes are set by the reset() */ dataOut.write(BinaryUtils.fromBase64(sqsMessage.body())); - /** Makes it read-only */ + /* Makes it read-only */ reset(); } catch (IOException e) { LOG.error("IOException: Message cannot be written", e); @@ -433,7 +431,7 @@ public int readBytes(byte[] value, int length) throws JMSException { } checkCanRead(); try { - /** + /* * Almost copy of readFully implementation except that EOFException * is not thrown if the stream is at the end of file and no byte is * available @@ -446,7 +444,7 @@ public int readBytes(byte[] value, int length) throws JMSException { } n += count; } - /** + /* * JMS specification mentions that the next read of the stream * returns -1 if the previous read consumed the byte stream and * there are no more bytes left to be read from the stream @@ -751,7 +749,6 @@ public void writeObject(Object value) throws JMSException { */ @Override public void reset() throws JMSException { - if (dataOut != null) { bytes = bytesOut.toByteArray(); dataOut = null; diff --git a/src/main/java/com/amazon/sqs/javamessaging/message/SQSMessage.java b/src/main/java/com/amazon/sqs/javamessaging/message/SQSMessage.java index caa03d6..a121267 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/message/SQSMessage.java +++ b/src/main/java/com/amazon/sqs/javamessaging/message/SQSMessage.java @@ -14,35 +14,26 @@ */ package com.amazon.sqs.javamessaging.message; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageFormatException; -import javax.jms.MessageNotWriteableException; - import com.amazon.sqs.javamessaging.SQSMessageConsumerPrefetch; import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; import com.amazon.sqs.javamessaging.SQSQueueDestination; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; - +import jakarta.jms.*; import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; +import java.lang.IllegalStateException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.Map.Entry; + import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.*; /** * The SQSMessage is the root class of all SQS JMS messages and implements JMS * Message interface. - *

        + *

        * Not all message headers are supported at this time: *

          *
        • JMSMessageID is always assigned as SQS provided message id.
        • @@ -52,18 +43,17 @@ * prefetching used in {@link SQSMessageConsumerPrefetch}, this can be set to * true although user never received the message. This is set based on SQS * ApproximateReceiveCount attribute - *
        • JMSDestination
        • is the destination object which message - * is sent to and received from. + *
        • JMSDestination is the destination object which message + * is sent to and received from.
        • *
        - *

        - *

        + *

        * JMSXDeliveryCount reserved property is supported and set based on the - * approximate receive count observed on the SQS side. + * approximate reception count observed on the SQS side. */ public class SQSMessage implements Message { - - private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); - + + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + // Define constant message types. public static final String BYTE_MESSAGE_TYPE = "byte"; public static final String OBJECT_MESSAGE_TYPE = "object"; @@ -72,7 +62,7 @@ public class SQSMessage implements Message { public static final String JMS_SQS_REPLY_TO_QUEUE_NAME = "JMS_SQSReplyToQueueName"; public static final String JMS_SQS_REPLY_TO_QUEUE_URL = "JMS_SQSReplyToQueueURL"; public static final String JMS_SQS_CORRELATION_ID = "JMS_SQSCorrelationID"; - + // Default JMS Message properties private int deliveryMode = Message.DEFAULT_DELIVERY_MODE; private int priority = Message.DEFAULT_PRIORITY; @@ -85,16 +75,16 @@ public class SQSMessage implements Message { private SQSQueueDestination replyTo; private Destination destination; - private final Map properties = new HashMap(); + private final Map properties = new HashMap<>(); private boolean writePermissionsForProperties; private boolean writePermissionsForBody; /** - * Function for acknowledging message. + * Function for acknowledging message. */ private Acknowledger acknowledger; - + /** * Original SQS Message ID. */ @@ -113,20 +103,16 @@ public class SQSMessage implements Message { * This is called at the receiver side to create a * JMS message from the SQS message received. */ - SQSMessage(Acknowledger acknowledger, String queueUrl, software.amazon.awssdk.services.sqs.model.Message sqsMessage) throws JMSException{ + SQSMessage(Acknowledger acknowledger, String queueUrl, software.amazon.awssdk.services.sqs.model.Message sqsMessage) throws JMSException { this.acknowledger = acknowledger; this.queueUrl = queueUrl; receiptHandle = sqsMessage.receiptHandle(); this.setSQSMessageId(sqsMessage.messageId()); - Map systemAttributes = sqsMessage.attributes(); + Map systemAttributes = sqsMessage.attributes(); int receiveCount = Integer.parseInt(systemAttributes.get(MessageSystemAttributeName.fromValue(APPROXIMATE_RECEIVE_COUNT))); - - /** - * JMSXDeliveryCount is set based on SQS ApproximateReceiveCount - * attribute. - */ - properties.put(JMSX_DELIVERY_COUNT, new JMSMessagePropertyValue( - receiveCount, INT)); + + // JMSXDeliveryCount is set based on SQS ApproximateReceiveCount attribute. + properties.put(JMSX_DELIVERY_COUNT, new JMSMessagePropertyValue(receiveCount, INT)); if (receiveCount > 1) { setJMSRedelivered(true); } @@ -142,8 +128,10 @@ public class SQSMessage implements Message { writePermissionsForBody = false; writePermissionsForProperties = false; } - - private void mapSystemAttributeToJmsMessageProperty(Map systemAttributes, String systemAttributeName, String jmsMessagePropertyName) throws JMSException { + + private void mapSystemAttributeToJmsMessageProperty(Map systemAttributes, + String systemAttributeName, String jmsMessagePropertyName) + throws JMSException { String systemAttributeValue = systemAttributes.get(MessageSystemAttributeName.fromValue(systemAttributeName)); if (systemAttributeValue != null) { properties.put(jmsMessagePropertyName, new JMSMessagePropertyValue(systemAttributeValue, STRING)); @@ -172,76 +160,78 @@ protected void checkPropertyWritePermissions() throws JMSException { throw new MessageNotWriteableException("Message properties are not writable"); } } - + protected void checkBodyWritePermissions() throws JMSException { if (!writePermissionsForBody) { throw new MessageNotWriteableException("Message body is not writable"); } } - + protected static JMSException convertExceptionToJMSException(Exception e) { JMSException ex = new JMSException(e.getMessage()); ex.initCause(e); return ex; } - + protected static MessageFormatException convertExceptionToMessageFormatException(Exception e) { MessageFormatException ex = new MessageFormatException(e.getMessage()); ex.initCause(e); return ex; } - + protected void setBodyWritePermissions(boolean enable) { writePermissionsForBody = enable; } - + /** * Get SQS Message Group Id (applicable for FIFO queues, available also as JMS property 'JMSXGroupId') - * @throws JMSException + * + * @throws JMSException */ public String getSQSMessageGroupId() throws JMSException { return getStringProperty(SQSMessagingClientConstants.JMSX_GROUP_ID); } - + /** * Get SQS Message Deduplication Id (applicable for FIFO queues, available also as JMS property 'JMS_SQS_DeduplicationId') - * @throws JMSException + * + * @throws JMSException */ public String getSQSMessageDeduplicationId() throws JMSException { return getStringProperty(SQSMessagingClientConstants.JMS_SQS_DEDUPLICATION_ID); } - + /** * Get SQS Message Sequence Number (applicable for FIFO queues, available also as JMS property 'JMS_SQS_SequenceNumber') - * @throws JMSException + * + * @throws JMSException */ public String getSQSMessageSequenceNumber() throws JMSException { return getStringProperty(SQSMessagingClientConstants.JMS_SQS_SEQUENCE_NUMBER); } - + /** * Get SQS Message Id. - * + * * @return SQS Message Id. */ public String getSQSMessageId() { return sqsMessageID; } - + /** * Set SQS Message Id, used on send. - * - * @param sqsMessageID - * messageId assigned by SQS during send. + * + * @param sqsMessageID messageId assigned by SQS during send. */ public void setSQSMessageId(String sqsMessageID) throws JMSException { this.sqsMessageID = sqsMessageID; this.setJMSMessageID(String.format(SQSMessagingClientConstants.MESSAGE_ID_FORMAT, sqsMessageID)); } - + /** * Get SQS Message receiptHandle. - * + * * @return SQS Message receiptHandle. */ public String getReceiptHandle() { @@ -250,35 +240,34 @@ public String getReceiptHandle() { /** * Get queueUrl the message came from. - * + * * @return queueUrl. */ public String getQueueUrl() { return queueUrl; } - + /** * Gets the message ID. - *

        + *

        * The JMSMessageID header field contains a value that uniquely identifies * each message sent by a provider. It is set to SQS messageId with the * prefix 'ID:'. - * + * * @return the ID of the message. */ @Override public String getJMSMessageID() throws JMSException { return messageID; } - + /** * Sets the message ID. It should have prefix 'ID:'. - *

        + *

        * Set when a message is sent. This method can be used to change the value * for a message that has been received. - * - * @param id - * The ID of the message. + * + * @param id The ID of the message. */ @Override public void setJMSMessageID(String id) throws JMSException { @@ -302,11 +291,7 @@ public byte[] getJMSCorrelationIDAsBytes() throws JMSException { @Override public void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException { - try { - this.correlationID = correlationID != null ? new String(correlationID, "UTF-8") : null; - } catch (UnsupportedEncodingException e) { - throw new JMSException(e.getMessage()); - } + this.correlationID = correlationID != null ? new String(correlationID, StandardCharsets.UTF_8) : null; } @Override @@ -329,37 +314,36 @@ public void setJMSReplyTo(Destination replyTo) throws JMSException { if (replyTo != null && !(replyTo instanceof SQSQueueDestination)) { throw new IllegalArgumentException("The replyTo Destination must be a SQSQueueDestination"); } - this.replyTo = (SQSQueueDestination)replyTo; + this.replyTo = (SQSQueueDestination) replyTo; } - + /** * Gets the Destination object for this message. - *

        + *

        * The JMSDestination header field contains the destination to which the * message is being sent. - *

        + *

        * When a message is sent, this field is ignored. After completion of the * send or publish method, the field holds the destination specified by the * method. - *

        + *

        * When a message is received, its JMSDestination value must be equivalent * to the value assigned when it was sent. - * + * * @return The destination of this message. */ @Override public Destination getJMSDestination() throws JMSException { return destination; } - + /** * Sets the Destination object for this message. - *

        + *

        * Set when a message is sent. This method can be used to change the value * for a message that has been received. - * - * @param destination - * The destination for this message. + * + * @param destination The destination for this message. */ @Override public void setJMSDestination(Destination destination) throws JMSException { @@ -406,6 +390,17 @@ public void setJMSExpiration(long expiration) throws JMSException { this.expiration = expiration; } + @Override + public long getJMSDeliveryTime() throws JMSException { + // FIXME + return 0; + } + + @Override + public void setJMSDeliveryTime(long deliveryTime) throws JMSException { + // FIXME + } + @Override public int getJMSPriority() throws JMSException { return priority; @@ -415,7 +410,7 @@ public int getJMSPriority() throws JMSException { public void setJMSPriority(int priority) throws JMSException { this.priority = priority; } - + /** * Clears a message's properties and set the write permissions for * properties. The message's header fields and body are not cleared. @@ -425,12 +420,11 @@ public void clearProperties() throws JMSException { properties.clear(); writePermissionsForProperties = true; } - + /** * Indicates whether a property value exists for the given property name. - * - * @param name - * The name of the property. + * + * @param name The name of the property. * @return true if the property exists. */ @Override @@ -441,20 +435,15 @@ public boolean propertyExists(String name) throws JMSException { /** * Get the value for a property that represents a java primitive(e.g. int or * long). - * - * @param property - * The name of the property to get. - * @param type - * The type of the property. + * + * @param property The name of the property to get. + * @param type The type of the property. * @return the converted value for the property. - * @throws JMSException - * On internal error. - * @throws MessageFormatException - * If the property cannot be converted to the specified type. - * @throws NullPointerException - * and NumberFormatException when property name or value is - * null. Method throws same exception as primitives - * corresponding valueOf(String) method. + * @throws JMSException On internal error. + * @throws MessageFormatException If the property cannot be converted to the specified type. + * @throws NullPointerException and NumberFormatException when property name or value is + * null. Method throws same exception as primitives + * corresponding valueOf(String) method. */ T getPrimitiveProperty(String property, Class type) throws JMSException { if (property == null) { @@ -467,7 +456,7 @@ T getPrimitiveProperty(String property, Class type) throws JMSException { T convertedValue = TypeConversionSupport.convert(value, type); if (convertedValue == null) { throw new MessageFormatException("Property " + property + " was " + value.getClass().getName() + - " and cannot be read as " + type.getName()); + " and cannot be read as " + type.getName()); } return convertedValue; } @@ -484,183 +473,145 @@ private T handleNullPropertyValue(String name, Class clazz) { throw new NumberFormatException("Value of property with name " + name + " is null."); } } - + /** * Returns the value of the boolean property with the specified * name. - * - * @param name - * The name of the property to get. + * + * @param name The name of the property to get. * @return the boolean property value for the specified name. - * @throws JMSException - * On internal error. - * @throws MessageFormatException - * If the property cannot be converted to the specified type. - * @throws NullPointerException - * When property name is null. + * @throws JMSException On internal error. + * @throws MessageFormatException If the property cannot be converted to the specified type. + * @throws NullPointerException When property name is null. */ @Override public boolean getBooleanProperty(String name) throws JMSException { return getPrimitiveProperty(name, Boolean.class); } - + /** * Returns the value of the byte property with the specified * name. - * - * @param name - * The name of the property to get. + * + * @param name The name of the property to get. * @return the byte property value for the specified name. - * @throws JMSException - * On internal error. - * @throws MessageFormatException - * If the property cannot be converted to the specified type. - * @throws NullPointerException - * When property name is null. - * @throws NumberFormatException - * When property value is null. + * @throws JMSException On internal error. + * @throws MessageFormatException If the property cannot be converted to the specified type. + * @throws NullPointerException When property name is null. + * @throws NumberFormatException When property value is null. */ @Override public byte getByteProperty(String name) throws JMSException { return getPrimitiveProperty(name, Byte.class); } - + /** * Returns the value of the short property with the specified * name. - * - * @param name - * The name of the property to get. + * + * @param name The name of the property to get. * @return the short property value for the specified name. - * @throws JMSException - * On internal error. - * @throws MessageFormatException - * If the property cannot be converted to the specified type. - * @throws NullPointerException - * When property name is null. - * @throws NumberFormatException - * When property value is null. + * @throws JMSException On internal error. + * @throws MessageFormatException If the property cannot be converted to the specified type. + * @throws NullPointerException When property name is null. + * @throws NumberFormatException When property value is null. */ @Override public short getShortProperty(String name) throws JMSException { return getPrimitiveProperty(name, Short.class); } - + /** * Returns the value of the int property with the specified * name. - * - * @param name - * The name of the property to get. + * + * @param name The name of the property to get. * @return the int property value for the specified name. - * @throws JMSException - * On internal error. - * @throws MessageFormatException - * If the property cannot be converted to the specified type. - * @throws NullPointerException - * When property name is null. - * @throws NumberFormatException - * When property value is null. + * @throws JMSException On internal error. + * @throws MessageFormatException If the property cannot be converted to the specified type. + * @throws NullPointerException When property name is null. + * @throws NumberFormatException When property value is null. */ @Override public int getIntProperty(String name) throws JMSException { return getPrimitiveProperty(name, Integer.class); } - + /** * Returns the value of the long property with the specified * name. - * - * @param name - * The name of the property to get. + * + * @param name The name of the property to get. * @return the long property value for the specified name. - * @throws JMSException - * On internal error. - * @throws MessageFormatException - * If the property cannot be converted to the specified type. - * @throws NullPointerException - * When property name is null. - * @throws NumberFormatException - * When property value is null. + * @throws JMSException On internal error. + * @throws MessageFormatException If the property cannot be converted to the specified type. + * @throws NullPointerException When property name is null. + * @throws NumberFormatException When property value is null. */ @Override public long getLongProperty(String name) throws JMSException { return getPrimitiveProperty(name, Long.class); } - + /** * Returns the value of the float property with the specified * name. - * - * @param name - * The name of the property to get. + * + * @param name The name of the property to get. * @return the float property value for the specified name. - * @throws JMSException - * Wn internal error. - * @throws MessageFormatException - * If the property cannot be converted to the specified type. - * @throws NullPointerException - * When property name or value is null. + * @throws JMSException Wn internal error. + * @throws MessageFormatException If the property cannot be converted to the specified type. + * @throws NullPointerException When property name or value is null. */ @Override public float getFloatProperty(String name) throws JMSException { return getPrimitiveProperty(name, Float.class); } - + /** * Returns the value of the double property with the specified * name. - * - * @param name - * The name of the property to get. + * + * @param name The name of the property to get. * @return the double property value for the specified name. - * @throws JMSException - * On internal error. - * @throws MessageFormatException - * If the property cannot be converted to the specified type. - * @throws NullPointerException - * When property name or value is null. + * @throws JMSException On internal error. + * @throws MessageFormatException If the property cannot be converted to the specified type. + * @throws NullPointerException When property name or value is null. */ @Override public double getDoubleProperty(String name) throws JMSException { return getPrimitiveProperty(name, Double.class); } - + /** * Returns the value of the String property with the specified * name. - * - * @param name - * The name of the property to get. + * + * @param name The name of the property to get. * @return the String property value for the specified name. - * @throws JMSException - * On internal error. - * @throws MessageFormatException - * If the property cannot be converted to the specified type. - * @throws NullPointerException - * When property name is null. + * @throws JMSException On internal error. + * @throws MessageFormatException If the property cannot be converted to the specified type. + * @throws NullPointerException When property name is null. */ @Override public String getStringProperty(String name) throws JMSException { return getPrimitiveProperty(name, String.class); } - + /** * Returns the value of the Java object property with the specified name. - *

        + *

        * This method can be used to return, in boxed format, an object that has * been stored as a property in the message with the equivalent * setObjectProperty method call, or its equivalent primitive * setter method. - * - * @param name - * The name of the property to get. + * + * @param name The name of the property to get. * @return the Java object property value with the specified name, in boxed - * format (for example, if the property was set as an - * int, an Integer is returned); if there - * is no property by this name, a null value is returned. - * @throws JMSException - * On internal error. + * format (for example, if the property was set as an + * int, an Integer is returned); if there + * is no property by this name, a null value is returned. + * @throws JMSException On internal error. */ @Override public Object getObjectProperty(String name) throws JMSException { @@ -670,30 +621,23 @@ public Object getObjectProperty(String name) throws JMSException { } return null; } - + /** * Returns the property value with message attribute to object property * conversions took place. - *

        - * - * @param name - * The name of the property to get. + *

        + * + * @param name The name of the property to get. * @return JMSMessagePropertyValue with object value and - * corresponding SQS message attribute type and message attribute - * string value. - * @throws JMSException - * On internal error. + * corresponding SQS message attribute type and message attribute + * string value. + * @throws JMSException On internal error. */ public JMSMessagePropertyValue getJMSMessagePropertyValue(String name) throws JMSException { return properties.get(name); } - private static class PropertyEnum implements Enumeration { - private final Iterator propertyItr; - - public PropertyEnum(Iterator propertyItr) { - this.propertyItr = propertyItr; - } + private record PropertyEnum(Iterator propertyItr) implements Enumeration { @Override public boolean hasMoreElements() { @@ -705,201 +649,154 @@ public String nextElement() { return propertyItr.next(); } } - + /** * Returns an Enumeration of all the property names. - *

        + *

        * Note that JMS standard header fields are not considered properties and * are not returned in this enumeration. - * + * * @return an enumeration of all the names of property values. - * @throws JMSException - * On internal error. + * @throws JMSException On internal error. */ @Override public Enumeration getPropertyNames() throws JMSException { return new PropertyEnum(properties.keySet().iterator()); } - + /** * Sets a boolean property value with the specified name into * the message. - * - * @param name - * The name of the property to set. - * @param value - * The boolean value of the property to set. - * @throws JMSException - * On internal error. - * @throws IllegalArgumentException - * If the name or value is null or empty string. - * @throws MessageNotWriteableException - * If properties are read-only. + * + * @param name The name of the property to set. + * @param value The boolean value of the property to set. + * @throws JMSException On internal error. + * @throws IllegalArgumentException If the name or value is null or empty string. + * @throws MessageNotWriteableException If properties are read-only. */ @Override public void setBooleanProperty(String name, boolean value) throws JMSException { setObjectProperty(name, value); } - + /** * Sets a byte property value with the specified name into * the message. - * - * @param name - * The name of the property to set. - * @param value - * The byte value of the property to set. - * @throws JMSException - * On internal error. - * @throws IllegalArgumentException - * If the name or value is null or empty string. - * @throws MessageNotWriteableException - * If properties are read-only. + * + * @param name The name of the property to set. + * @param value The byte value of the property to set. + * @throws JMSException On internal error. + * @throws IllegalArgumentException If the name or value is null or empty string. + * @throws MessageNotWriteableException If properties are read-only. */ @Override public void setByteProperty(String name, byte value) throws JMSException { setObjectProperty(name, value); } - + /** * Sets a short property value with the specified name into * the message. - * - * @param name - * The name of the property to set. - * @param value - * The short value of the property to set. - * @throws JMSException - * On internal error. - * @throws IllegalArgumentException - * If the name or value is null or empty string. - * @throws MessageNotWriteableException - * If properties are read-only. + * + * @param name The name of the property to set. + * @param value The short value of the property to set. + * @throws JMSException On internal error. + * @throws IllegalArgumentException If the name or value is null or empty string. + * @throws MessageNotWriteableException If properties are read-only. */ @Override public void setShortProperty(String name, short value) throws JMSException { setObjectProperty(name, value); } - + /** * Sets a int property value with the specified name into * the message. - * - * @param name - * The name of the property to set. - * @param value - * The int value of the property to set. - * @throws JMSException - * On internal error. - * @throws IllegalArgumentException - * If the name or value is null or empty string. - * @throws MessageNotWriteableException - * If properties are read-only. + * + * @param name The name of the property to set. + * @param value The int value of the property to set. + * @throws JMSException On internal error. + * @throws IllegalArgumentException If the name or value is null or empty string. + * @throws MessageNotWriteableException If properties are read-only. */ @Override public void setIntProperty(String name, int value) throws JMSException { setObjectProperty(name, value); } - + /** * Sets a long property value with the specified name into * the message. - * - * @param name - * The name of the property to set. - * @param value - * The long value of the property to set. - * @throws JMSException - * On internal error. - * @throws IllegalArgumentException - * If the name or value is null or empty string. - * @throws MessageNotWriteableException - * If properties are read-only. + * + * @param name The name of the property to set. + * @param value The long value of the property to set. + * @throws JMSException On internal error. + * @throws IllegalArgumentException If the name or value is null or empty string. + * @throws MessageNotWriteableException If properties are read-only. */ @Override public void setLongProperty(String name, long value) throws JMSException { setObjectProperty(name, value); } - + /** * Sets a float property value with the specified name into * the message. - * - * @param name - * The name of the property to set. - * @param value - * The float value of the property to set. - * @throws JMSException - * On internal error. - * @throws IllegalArgumentException - * If the name or value is null or empty string. - * @throws MessageNotWriteableException - * If properties are read-only. + * + * @param name The name of the property to set. + * @param value The float value of the property to set. + * @throws JMSException On internal error. + * @throws IllegalArgumentException If the name or value is null or empty string. + * @throws MessageNotWriteableException If properties are read-only. */ @Override public void setFloatProperty(String name, float value) throws JMSException { setObjectProperty(name, value); } - + /** * Sets a double property value with the specified name into * the message. - * - * @param name - * The name of the property to set. - * @param value - * The double value of the property to set. - * @throws JMSException - * On internal error. - * @throws IllegalArgumentException - * If the name or value is null or empty string. - * @throws MessageNotWriteableException - * If properties are read-only. + * + * @param name The name of the property to set. + * @param value The double value of the property to set. + * @throws JMSException On internal error. + * @throws IllegalArgumentException If the name or value is null or empty string. + * @throws MessageNotWriteableException If properties are read-only. */ @Override public void setDoubleProperty(String name, double value) throws JMSException { setObjectProperty(name, value); } - + /** * Sets a String property value with the specified name into * the message. - * - * @param name - * The name of the property to set. - * @param value - * The String value of the property to set. - * @throws JMSException - * On internal error. - * @throws IllegalArgumentException - * If the name or value is null or empty string. - * @throws MessageNotWriteableException - * If properties are read-only. + * + * @param name The name of the property to set. + * @param value The String value of the property to set. + * @throws JMSException On internal error. + * @throws IllegalArgumentException If the name or value is null or empty string. + * @throws MessageNotWriteableException If properties are read-only. */ @Override public void setStringProperty(String name, String value) throws JMSException { setObjectProperty(name, value); } - + /** * Sets a Java object property value with the specified name into the * message. - *

        + *

        * Note that this method works only for the boxed primitive object types * (Integer, Double, Long ...) and String objects. - * - * @param name - * The name of the property to set. - * @param value - * The object value of the property to set. - * @throws JMSException - * On internal error. - * @throws IllegalArgumentException - * If the name or value is null or empty string. - * @throws MessageFormatException - * If the object is invalid type. - * @throws MessageNotWriteableException - * If properties are read-only. + * + * @param name The name of the property to set. + * @param value The object value of the property to set. + * @throws JMSException On internal error. + * @throws IllegalArgumentException If the name or value is null or empty string. + * @throws MessageFormatException If the object is invalid type. + * @throws MessageNotWriteableException If properties are read-only. */ @Override public void setObjectProperty(String name, Object value) throws JMSException { @@ -909,33 +806,31 @@ public void setObjectProperty(String name, Object value) throws JMSException { if (value == null || "".equals(value)) { throw new IllegalArgumentException("Property value can not be null or empty."); } - if(!isValidPropertyValueType(value)) { + if (!isValidPropertyValueType(value)) { throw new MessageFormatException("Value of property with name " + name + " has incorrect type " + value.getClass().getName() + "."); } checkPropertyWritePermissions(); properties.put(name, new JMSMessagePropertyValue(value)); } - + /** - *

        + *

        * Acknowledges message(s). - *

        + *

        * A client may individually acknowledge each message as it is consumed, or * it may choose to acknowledge multiple messages based on acknowledge mode, * which in turn might might acknowledge all messages consumed by the * session. - *

        + *

        * Messages that have been received but not acknowledged may be redelivered. - *

        + *

        * If the session is closed, messages cannot be acknowledged. - *

        + *

        * If only the consumer is closed, messages can still be acknowledged. - * + * + * @throws JMSException On Internal error + * @throws IllegalStateException If this method is called on a closed session. * @see com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode - * @throws JMSException - * On Internal error - * @throws IllegalStateException - * If this method is called on a closed session. */ @Override public void acknowledge() throws JMSException { @@ -943,27 +838,36 @@ public void acknowledge() throws JMSException { acknowledger.acknowledge(this); } } - + /** - *

        + *

        * Clears out the message body. Clearing a message's body does not clear its * header values or property entries. - *

        + *

        * This method cannot be called directly instead the implementation on the * subclasses should be used. - * - * @throws JMSException - * If directly called + * + * @throws JMSException If directly called */ @Override public void clearBody() throws JMSException { throw new JMSException("SQSMessage does not have any body"); } + @Override + public T getBody(Class c) throws JMSException { + throw new JMSException("SQSMessage does not have any body"); + } + + @Override + public boolean isBodyAssignableTo(Class c) throws JMSException { + throw new JMSException("SQSMessage does not have any body"); + } + private boolean isValidPropertyValueType(Object value) { return value instanceof Boolean || value instanceof Byte || value instanceof Short || - value instanceof Integer || value instanceof Long || value instanceof Float || - value instanceof Double || value instanceof String; + value instanceof Integer || value instanceof Long || value instanceof Float || + value instanceof Double || value instanceof String; } /** @@ -973,181 +877,92 @@ private boolean isValidPropertyValueType(Object value) { */ public static class TypeConversionSupport { - static class ConversionKey { - final Class from; - - final Class to; - - public ConversionKey(Class from, Class to) { - this.from = from; - this.to = to; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((from == null) ? 0 : from.hashCode()); - result = prime * result + ((to == null) ? 0 : to.hashCode()); - return result; - } + record ConversionKey(Class from, Class to) { - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ConversionKey other = (ConversionKey) obj; - if (from == null) { - if (other.from != null) - return false; - } else if (!from.equals(other.from)) - return false; - if (to == null) { - if (other.to != null) - return false; - } else if (!to.equals(other.to)) - return false; - return true; - } } interface Converter { Object convert(Object value); } - static final private Map CONVERSION_MAP = new HashMap(); + static final private Map CONVERSION_MAP = new HashMap<>(); + static { - Converter toStringConverter = new Converter() { - public Object convert(Object value) { - return value.toString(); - } - }; - CONVERSION_MAP.put(new ConversionKey(Boolean.class, String.class), toStringConverter); - CONVERSION_MAP.put(new ConversionKey(Byte.class, String.class), toStringConverter); - CONVERSION_MAP.put(new ConversionKey(Short.class, String.class), toStringConverter); - CONVERSION_MAP.put(new ConversionKey(Integer.class, String.class), toStringConverter); - CONVERSION_MAP.put(new ConversionKey(Long.class, String.class), toStringConverter); - CONVERSION_MAP.put(new ConversionKey(Float.class, String.class), toStringConverter); - CONVERSION_MAP.put(new ConversionKey(Double.class, String.class), toStringConverter); - - CONVERSION_MAP.put(new ConversionKey(String.class, Boolean.class), new Converter() { - public Object convert(Object value) { - String stringValue = (String) value; - if (Boolean.valueOf(stringValue) || INT_TRUE.equals((String) value)) { - return Boolean.TRUE; - } - return Boolean.FALSE; - } - }); - CONVERSION_MAP.put(new ConversionKey(String.class, Byte.class), new Converter() { - public Object convert(Object value) { - return Byte.valueOf((String) value); - } - }); - CONVERSION_MAP.put(new ConversionKey(String.class, Short.class), new Converter() { - public Object convert(Object value) { - return Short.valueOf((String) value); - } - }); - CONVERSION_MAP.put(new ConversionKey(String.class, Integer.class), new Converter() { - public Object convert(Object value) { - return Integer.valueOf((String) value); - } - }); - CONVERSION_MAP.put(new ConversionKey(String.class, Long.class), new Converter() { - public Object convert(Object value) { - return Long.valueOf((String) value); - } - }); - CONVERSION_MAP.put(new ConversionKey(String.class, Float.class), new Converter() { - public Object convert(Object value) { - return Float.valueOf((String) value); - } - }); - CONVERSION_MAP.put(new ConversionKey(String.class, Double.class), new Converter() { - public Object convert(Object value) { - return Double.valueOf((String) value); + CONVERSION_MAP.put(new ConversionKey(Boolean.class, String.class), Object::toString); + CONVERSION_MAP.put(new ConversionKey(Byte.class, String.class), Object::toString); + CONVERSION_MAP.put(new ConversionKey(Short.class, String.class), Object::toString); + CONVERSION_MAP.put(new ConversionKey(Integer.class, String.class), Object::toString); + CONVERSION_MAP.put(new ConversionKey(Long.class, String.class), Object::toString); + CONVERSION_MAP.put(new ConversionKey(Float.class, String.class), Object::toString); + CONVERSION_MAP.put(new ConversionKey(Double.class, String.class), Object::toString); + + CONVERSION_MAP.put(new ConversionKey(String.class, Boolean.class), value -> { + String stringValue = (String) value; + if (Boolean.parseBoolean(stringValue) || INT_TRUE.equals(stringValue)) { + return Boolean.TRUE; } + return Boolean.FALSE; }); - - Converter longConverter = new Converter() { - public Object convert(Object value) { - return Long.valueOf(((Number) value).longValue()); - } - }; + CONVERSION_MAP.put(new ConversionKey(String.class, Byte.class), value -> Byte.valueOf((String) value)); + CONVERSION_MAP.put(new ConversionKey(String.class, Short.class), value -> Short.valueOf((String) value)); + CONVERSION_MAP.put(new ConversionKey(String.class, Integer.class), value -> Integer.valueOf((String) value)); + CONVERSION_MAP.put(new ConversionKey(String.class, Long.class), value -> Long.valueOf((String) value)); + CONVERSION_MAP.put(new ConversionKey(String.class, Float.class), value -> Float.valueOf((String) value)); + CONVERSION_MAP.put(new ConversionKey(String.class, Double.class), value -> Double.valueOf((String) value)); + + Converter longConverter = value -> ((Number) value).longValue(); CONVERSION_MAP.put(new ConversionKey(Byte.class, Long.class), longConverter); CONVERSION_MAP.put(new ConversionKey(Short.class, Long.class), longConverter); CONVERSION_MAP.put(new ConversionKey(Integer.class, Long.class), longConverter); - CONVERSION_MAP.put(new ConversionKey(Date.class, Long.class), new Converter() { - public Object convert(Object value) { - return Long.valueOf(((Date) value).getTime()); - } - }); + CONVERSION_MAP.put(new ConversionKey(Date.class, Long.class), value -> ((Date) value).getTime()); - Converter intConverter = new Converter() { - public Object convert(Object value) { - return Integer.valueOf(((Number) value).intValue()); - } - }; + Converter intConverter = value -> ((Number) value).intValue(); CONVERSION_MAP.put(new ConversionKey(Byte.class, Integer.class), intConverter); CONVERSION_MAP.put(new ConversionKey(Short.class, Integer.class), intConverter); - CONVERSION_MAP.put(new ConversionKey(Byte.class, Short.class), new Converter() { - public Object convert(Object value) { - return Short.valueOf(((Number) value).shortValue()); - } - }); + CONVERSION_MAP.put(new ConversionKey(Byte.class, Short.class), value -> ((Number) value).shortValue()); - CONVERSION_MAP.put(new ConversionKey(Float.class, Double.class), new Converter() { - public Object convert(Object value) { - return Double.valueOf(((Number) value).doubleValue()); - } - }); + CONVERSION_MAP.put(new ConversionKey(Float.class, Double.class), value -> ((Number) value).doubleValue()); } @SuppressWarnings("unchecked") static public T convert(Object value, Class clazz) { - assert value != null && clazz != null; if (value.getClass() == clazz) return (T) value; - Converter c = (Converter) CONVERSION_MAP.get(new ConversionKey(value.getClass(), clazz)); + Converter c = CONVERSION_MAP.get(new ConversionKey(value.getClass(), clazz)); if (c == null) return null; return (T) c.convert(value); } } - + /** * This class is used fulfill object value, corresponding SQS message * attribute type and message attribute string value. */ public static class JMSMessagePropertyValue { - + private final Object value; private final String type; - + private final String stringMessageAttributeValue; - - public JMSMessagePropertyValue(String stringValue, String type) throws JMSException{ + + public JMSMessagePropertyValue(String stringValue, String type) throws JMSException { this.type = type; this.value = getObjectValue(stringValue, type); this.stringMessageAttributeValue = stringValue; } - + public JMSMessagePropertyValue(Object value) throws JMSException { this.type = getType(value); this.value = value; if (BOOLEAN.equals(type)) { - if((Boolean) value) { + if ((Boolean) value) { stringMessageAttributeValue = INT_TRUE; } else { stringMessageAttributeValue = INT_FALSE; @@ -1156,12 +971,12 @@ public JMSMessagePropertyValue(Object value) throws JMSException { stringMessageAttributeValue = value.toString(); } } - + public JMSMessagePropertyValue(Object value, String type) throws JMSException { this.value = value; this.type = type; if (BOOLEAN.equals(type)) { - if((Boolean) value) { + if ((Boolean) value) { stringMessageAttributeValue = INT_TRUE; } else { stringMessageAttributeValue = INT_FALSE; @@ -1170,7 +985,7 @@ public JMSMessagePropertyValue(Object value, String type) throws JMSException { stringMessageAttributeValue = value.toString(); } } - + private static String getType(Object value) throws JMSException { if (value instanceof String) { return STRING; @@ -1216,7 +1031,7 @@ private static Object getObjectValue(String value, String type) throws JMSExcept } else { throw new JMSException(type + " is not a supported JMS property type"); } - } + } public String getType() { return type; @@ -1225,7 +1040,7 @@ public String getType() { public Object getValue() { return value; } - + public String getStringMessageAttributeValue() { return stringMessageAttributeValue; } @@ -1234,9 +1049,9 @@ public String getStringMessageAttributeValue() { /** * This method sets the JMS_SQS_SEQUENCE_NUMBER property on the message. It is exposed explicitly here, so that - * it can be invoked even on read-only message object obtained through receing a message. + * it can be invoked even on read-only message object obtained through receiving a message. * This support the use case of send a received message by using the same JMSMessage object. - * + * * @param sequenceNumber Sequence number to set. If null or empty, the stored sequence number will be removed. * @throws JMSException */ diff --git a/src/main/java/com/amazon/sqs/javamessaging/message/SQSObjectMessage.java b/src/main/java/com/amazon/sqs/javamessaging/message/SQSObjectMessage.java index 69cac77..b9a8f87 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/message/SQSObjectMessage.java +++ b/src/main/java/com/amazon/sqs/javamessaging/message/SQSObjectMessage.java @@ -21,8 +21,8 @@ import java.io.ObjectOutputStream; import java.io.Serializable; -import javax.jms.JMSException; -import javax.jms.ObjectMessage; +import jakarta.jms.JMSException; +import jakarta.jms.ObjectMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -80,9 +80,9 @@ public SQSObjectMessage(Serializable payload) throws JMSException { * * @param payload * The Serializable containing the message's body - * @throws MessageNotWriteableException + * @throws jakarta.jms.MessageNotWriteableException * If the message is in read-only mode. - * @throws MessageFormatException + * @throws jakarta.jms.MessageFormatException * If object serialization fails. */ @Override @@ -94,7 +94,7 @@ public void setObject(Serializable payload) throws JMSException { /** * Gets the Serializable containing this message's body * - * @throws MessageFormatException + * @throws jakarta.jms.MessageFormatException * If object deserialization fails. */ @Override diff --git a/src/main/java/com/amazon/sqs/javamessaging/message/SQSTextMessage.java b/src/main/java/com/amazon/sqs/javamessaging/message/SQSTextMessage.java index 82f733a..7bdad8a 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/message/SQSTextMessage.java +++ b/src/main/java/com/amazon/sqs/javamessaging/message/SQSTextMessage.java @@ -14,8 +14,8 @@ */ package com.amazon.sqs.javamessaging.message; -import javax.jms.JMSException; -import javax.jms.TextMessage; +import jakarta.jms.JMSException; +import jakarta.jms.TextMessage; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; @@ -66,7 +66,7 @@ public SQSTextMessage(String payload) throws JMSException { * * @param string * The String containing the message's body - * @throws MessageNotWriteableException + * @throws jakarta.jms.MessageNotWriteableException * If the message is in read-only mode. */ @Override diff --git a/src/main/java/com/amazon/sqs/javamessaging/util/ExponentialBackoffStrategy.java b/src/main/java/com/amazon/sqs/javamessaging/util/ExponentialBackoffStrategy.java index 04cfe29..35d3b1d 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/util/ExponentialBackoffStrategy.java +++ b/src/main/java/com/amazon/sqs/javamessaging/util/ExponentialBackoffStrategy.java @@ -20,9 +20,9 @@ */ public class ExponentialBackoffStrategy { - private long delayInterval; - private long initialDelay; - private long maxDelay; + private final long delayInterval; + private final long initialDelay; + private final long maxDelay; public ExponentialBackoffStrategy(long delayInterval, long initialDelay, long maxDelay) { this.delayInterval = delayInterval; diff --git a/src/main/java/com/amazon/sqs/javamessaging/util/SQSMessagingClientUtil.java b/src/main/java/com/amazon/sqs/javamessaging/util/SQSMessagingClientUtil.java index cb79d49..d262c9f 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/util/SQSMessagingClientUtil.java +++ b/src/main/java/com/amazon/sqs/javamessaging/util/SQSMessagingClientUtil.java @@ -51,7 +51,7 @@ public static String serializePropertyName(String name) { if (Character.isLetterOrDigit(ch) || HYPHEN == ch || DOT == ch) { stringBuilder.append(ch); } else { - stringBuilder.append(UNDERSCORE + Integer.toString((int) ch) + UNDERSCORE); + stringBuilder.append(UNDERSCORE).append(Integer.toString(ch)).append(UNDERSCORE); } } return stringBuilder.toString(); diff --git a/src/test/java/com/amazon/sqs/javamessaging/AcknowledgerCommon.java b/src/test/java/com/amazon/sqs/javamessaging/AcknowledgerCommon.java index 54907b2..8764ba3 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/AcknowledgerCommon.java +++ b/src/test/java/com/amazon/sqs/javamessaging/AcknowledgerCommon.java @@ -14,14 +14,12 @@ */ package com.amazon.sqs.javamessaging; -import static org.junit.Assert.assertEquals; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.jms.JMSException; +import jakarta.jms.JMSException; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import com.amazon.sqs.javamessaging.message.SQSMessage; @@ -30,6 +28,8 @@ import software.amazon.awssdk.services.sqs.model.Message; import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * Parent class for the Acknowledger tests */ @@ -38,7 +38,7 @@ public class AcknowledgerCommon { protected String baseQueueUrl = "queueUrl"; protected Acknowledger acknowledger; protected AmazonSQSMessagingClientWrapper amazonSQSClient; - protected List populatedMessages = new ArrayList(); + protected List populatedMessages = new ArrayList<>(); /* * Generate and populate the list with sqs message from different queues @@ -66,7 +66,7 @@ public void populateMessage(int populateMessageSize) throws JMSException { .attributes(mockAttributes) .build(); - SQSMessage message = (SQSMessage) new SQSTextMessage(acknowledger, queueUrl, sqsMessage); + SQSMessage message = new SQSTextMessage(acknowledger, queueUrl, sqsMessage); populatedMessages.add(message); acknowledger.notifyMessageReceived(message); diff --git a/src/test/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapperTest.java b/src/test/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapperTest.java index 008d125..863b3d6 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapperTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapperTest.java @@ -14,32 +14,19 @@ */ package com.amazon.sqs.javamessaging; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import javax.jms.InvalidDestinationException; -import javax.jms.JMSException; - -import org.junit.Before; -import org.junit.Test; - +import jakarta.jms.InvalidDestinationException; +import jakarta.jms.JMSException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import software.amazon.awssdk.core.exception.SdkException; import software.amazon.awssdk.core.exception.SdkServiceException; import software.amazon.awssdk.services.sqs.SqsClient; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityRequest; -import software.amazon.awssdk.services.sqs.model.CreateQueueRequest; -import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest; -import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; -import software.amazon.awssdk.services.sqs.model.GetQueueUrlRequest; -import software.amazon.awssdk.services.sqs.model.QueueDoesNotExistException; -import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; -import software.amazon.awssdk.services.sqs.model.SendMessageRequest; +import software.amazon.awssdk.services.sqs.model.*; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; /** * Test the AmazonSQSMessagingClientWrapper class @@ -52,7 +39,7 @@ public class AmazonSQSMessagingClientWrapperTest { private SqsClient amazonSQSClient; private AmazonSQSMessagingClientWrapper wrapper; - @Before + @BeforeEach public void setup() throws JMSException { amazonSQSClient = mock(SqsClient.class); wrapper = new AmazonSQSMessagingClientWrapper(amazonSQSClient); @@ -61,87 +48,88 @@ public void setup() throws JMSException { /* * Test constructing client with null amazon sqs client */ - @Test(expected = JMSException.class) - public void testNullSQSClient() throws JMSException { - new AmazonSQSMessagingClientWrapper(null); + @Test + public void testNullSQSClient() { + assertThatThrownBy(() -> new AmazonSQSMessagingClientWrapper(null)) + .isInstanceOf(JMSException.class); } /* * Test delete message wrap amazon sqs client amazon client exception */ - @Test(expected = JMSException.class) - public void testDeleteMessageThrowAmazonClientException() throws JMSException { - + @Test + public void testDeleteMessageThrowAmazonClientException() { DeleteMessageRequest deleteMessageRequest = DeleteMessageRequest.builder().build(); doThrow(SdkServiceException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).deleteMessage(eq(deleteMessageRequest)); - wrapper.deleteMessage(deleteMessageRequest); + assertThatThrownBy(() -> wrapper.deleteMessage(deleteMessageRequest)) + .isInstanceOf(JMSException.class); } /* * Test delete message wrap amazon sqs client amazon service exception */ - @Test(expected = JMSException.class) - public void testDeleteMessageThrowAmazonServiceException() throws JMSException { - + @Test + public void testDeleteMessageThrowAmazonServiceException() { DeleteMessageRequest deleteMessageRequest = DeleteMessageRequest.builder().build(); doThrow(SdkServiceException.create("ase", new Throwable("broken"))) .when(amazonSQSClient).deleteMessage(eq(deleteMessageRequest)); - wrapper.deleteMessage(deleteMessageRequest); + assertThatThrownBy(() -> wrapper.deleteMessage(deleteMessageRequest)) + .isInstanceOf(JMSException.class); } /* * Test delete message batch wrap amazon sqs client amazon client exception */ - @Test(expected = JMSException.class) - public void testDeleteMessageBatchThrowAmazonClientException() throws JMSException { - + @Test + public void testDeleteMessageBatchThrowAmazonClientException() { DeleteMessageBatchRequest deleteMessageBatchRequest = DeleteMessageBatchRequest.builder().build(); doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).deleteMessageBatch(eq(deleteMessageBatchRequest)); - wrapper.deleteMessageBatch(deleteMessageBatchRequest); + assertThatThrownBy(() -> wrapper.deleteMessageBatch(deleteMessageBatchRequest)) + .isInstanceOf(JMSException.class); } /* * Test delete message batch wrap amazon sqs client amazon service exception */ - @Test(expected = JMSException.class) - public void testDeleteMessageBatchThrowAmazonServiceException() throws JMSException { - + @Test + public void testDeleteMessageBatchThrowAmazonServiceException() { DeleteMessageBatchRequest deleteMessageBatchRequest = DeleteMessageBatchRequest.builder().build(); doThrow(SdkServiceException.create("ase", new Throwable("broken"))) .when(amazonSQSClient).deleteMessageBatch(eq(deleteMessageBatchRequest)); - wrapper.deleteMessageBatch(deleteMessageBatchRequest); + assertThatThrownBy(() -> wrapper.deleteMessageBatch(deleteMessageBatchRequest)) + .isInstanceOf(JMSException.class); } /* * Test send message batch wrap amazon sqs client amazon client exception */ - @Test(expected = JMSException.class) - public void testSendMessageThrowAmazonClientException() throws JMSException { - + @Test + public void testSendMessageThrowAmazonClientException() { SendMessageRequest sendMessageRequest = SendMessageRequest.builder().build(); doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).sendMessage(eq(sendMessageRequest)); - wrapper.sendMessage(sendMessageRequest); + assertThatThrownBy(() -> wrapper.sendMessage(sendMessageRequest)) + .isInstanceOf(JMSException.class); } /* * Test send message batch wrap amazon sqs client amazon service exception */ - @Test(expected = JMSException.class) - public void testSendMessageThrowAmazonServiceException() throws JMSException { - + @Test + public void testSendMessageThrowAmazonServiceException() { SendMessageRequest sendMessageRequest = SendMessageRequest.builder().build(); doThrow(SdkServiceException.create("ase", new Throwable("broken"))) .when(amazonSQSClient).sendMessage(eq(sendMessageRequest)); - wrapper.sendMessage(sendMessageRequest); + assertThatThrownBy(() -> wrapper.sendMessage(sendMessageRequest)) + .isInstanceOf(JMSException.class); } /* @@ -150,72 +138,74 @@ public void testSendMessageThrowAmazonServiceException() throws JMSException { @Test public void testGetQueueUrlQueueName() throws JMSException { GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); - + wrapper.getQueueUrl(QUEUE_NAME); verify(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); } - + /* * Test getQueueUrl with queue name and owner account id input */ @Test public void testGetQueueUrlQueueNameWithAccountId() throws JMSException { - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).queueOwnerAWSAccountId(OWNER_ACCOUNT_ID).build(); - - wrapper.getQueueUrl(QUEUE_NAME, OWNER_ACCOUNT_ID); + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME) + .queueOwnerAWSAccountId(OWNER_ACCOUNT_ID).build(); + + wrapper.getQueueUrl(QUEUE_NAME, OWNER_ACCOUNT_ID); verify(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); } /* * Test getQueueUrl with queue name input wrap amazon sqs client amazon client exception */ - @Test(expected = JMSException.class) - public void testGetQueueUrlQueueNameThrowAmazonClientException() throws JMSException { - - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); + @Test + public void testGetQueueUrlQueueNameThrowAmazonClientException() { + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); - wrapper.getQueueUrl(QUEUE_NAME); + assertThatThrownBy(() -> wrapper.getQueueUrl(QUEUE_NAME)) + .isInstanceOf(JMSException.class); } /* * Test getQueueUrl with queue name input wrap amazon sqs client amazon service exception */ - @Test(expected = JMSException.class) - public void testGetQueueUrlQueueNameThrowAmazonServiceException() throws JMSException { - - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); + @Test + public void testGetQueueUrlQueueNameThrowAmazonServiceException() { + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); doThrow(SdkServiceException.create("ase", new Throwable("BROKEN"))) .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); - wrapper.getQueueUrl(QUEUE_NAME); + assertThatThrownBy(() -> wrapper.getQueueUrl(QUEUE_NAME)) + .isInstanceOf(JMSException.class); } /* * Test getQueueUrl with queue name input wrap amazon sqs queue does not exist exception */ - @Test(expected = InvalidDestinationException.class) - public void testGetQueueUrlQueueNameThrowQueueDoesNotExistException() throws JMSException { - - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); + @Test + public void testGetQueueUrlQueueNameThrowQueueDoesNotExistException() { + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); doThrow(QueueDoesNotExistException.builder().message("qdnee").build()) .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); - wrapper.getQueueUrl(QUEUE_NAME); + assertThatThrownBy(() -> wrapper.getQueueUrl(QUEUE_NAME)) + .isInstanceOf(InvalidDestinationException.class); } - + /* * Test getQueueUrl with queue name input wrap amazon sqs queue does not exist exception */ - @Test(expected = InvalidDestinationException.class) - public void testGetQueueUrlQueueNameWithAccountIdThrowQueueDoesNotExistException() throws JMSException { - - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueOwnerAWSAccountId(OWNER_ACCOUNT_ID).queueName(QUEUE_NAME).build(); + @Test + public void testGetQueueUrlQueueNameWithAccountIdThrowQueueDoesNotExistException() { + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueOwnerAWSAccountId(OWNER_ACCOUNT_ID) + .queueName(QUEUE_NAME).build(); doThrow(QueueDoesNotExistException.builder().message("qdnee").build()) - .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); + .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); - wrapper.getQueueUrl(QUEUE_NAME,OWNER_ACCOUNT_ID); + assertThatThrownBy(() -> wrapper.getQueueUrl(QUEUE_NAME, OWNER_ACCOUNT_ID)) + .isInstanceOf(InvalidDestinationException.class); } /* @@ -223,8 +213,9 @@ public void testGetQueueUrlQueueNameWithAccountIdThrowQueueDoesNotExistException */ @Test public void testGetQueueUrl() throws JMSException { + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); + wrapper = new AmazonSQSMessagingClientWrapper(amazonSQSClient); wrapper.getQueueUrl(getQueueUrlRequest); verify(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); @@ -233,27 +224,27 @@ public void testGetQueueUrl() throws JMSException { /* * Test getQueueUrl wrap amazon sqs amazon client exception */ - @Test(expected = JMSException.class) - public void testGetQueueUrlThrowAmazonClientException() throws JMSException { - - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); + @Test + public void testGetQueueUrlThrowAmazonClientException() { + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); - wrapper.getQueueUrl(getQueueUrlRequest); + assertThatThrownBy(() -> wrapper.getQueueUrl(getQueueUrlRequest)) + .isInstanceOf(JMSException.class); } /* * Test getQueueUrl wrap amazon sqs amazon service exception */ - @Test(expected = JMSException.class) - public void testGetQueueUrlThrowAmazonServiceException() throws JMSException { - - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); + @Test + public void testGetQueueUrlThrowAmazonServiceException() { + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); doThrow(SdkServiceException.create("ase", new Throwable("BROKEN"))) .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); - wrapper.getQueueUrl(QUEUE_NAME); + assertThatThrownBy(() -> wrapper.getQueueUrl(QUEUE_NAME)) + .isInstanceOf(JMSException.class); } /* @@ -261,9 +252,8 @@ public void testGetQueueUrlThrowAmazonServiceException() throws JMSException { */ @Test public void testQueueExistsWhenQueueIsPresent() throws JMSException { - assertTrue(wrapper.queueExists(QUEUE_NAME)); - + verify(amazonSQSClient).getQueueUrl(eq(GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build())); } @@ -272,7 +262,6 @@ public void testQueueExistsWhenQueueIsPresent() throws JMSException { */ @Test public void testQueueExistsThrowQueueDoesNotExistException() throws JMSException { - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); doThrow(QueueDoesNotExistException.builder().message("qdnee").build()) .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); @@ -283,27 +272,27 @@ public void testQueueExistsThrowQueueDoesNotExistException() throws JMSException /* * Test queue exist when amazon sqs client throws AmazonClientException */ - @Test(expected = JMSException.class) - public void testQueueExistsThrowAmazonClientException() throws JMSException { - + @Test + public void testQueueExistsThrowAmazonClientException() { GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); - wrapper.queueExists(QUEUE_NAME); + assertThatThrownBy(() -> wrapper.queueExists(QUEUE_NAME)) + .isInstanceOf(JMSException.class); } /* * Test queue exist when amazon sqs client throws AmazonServiceException */ - @Test(expected = JMSException.class) - public void testQueueExistsThrowAmazonServiceException() throws JMSException { - - GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); + @Test + public void testQueueExistsThrowAmazonServiceException() { + GetQueueUrlRequest getQueueUrlRequest = GetQueueUrlRequest.builder().queueName(QUEUE_NAME).build(); doThrow(SdkServiceException.create("ase", new Throwable("BROKEN"))) .when(amazonSQSClient).getQueueUrl(eq(getQueueUrlRequest)); - wrapper.queueExists(QUEUE_NAME); + assertThatThrownBy(() -> wrapper.queueExists(QUEUE_NAME)) + .isInstanceOf(JMSException.class); } /* @@ -311,7 +300,6 @@ public void testQueueExistsThrowAmazonServiceException() throws JMSException { */ @Test public void testCreateQueueWithName() throws JMSException { - wrapper.createQueue(QUEUE_NAME); verify(amazonSQSClient).createQueue(CreateQueueRequest.builder().queueName(QUEUE_NAME).build()); } @@ -319,25 +307,25 @@ public void testCreateQueueWithName() throws JMSException { /* * Test create queue when amazon sqs client throws AmazonClientException */ - @Test(expected = JMSException.class) - public void testCreateQueueWithNameThrowAmazonClientException() throws JMSException { - + @Test + public void testCreateQueueWithNameThrowAmazonClientException() { doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).createQueue(eq(CreateQueueRequest.builder().queueName(QUEUE_NAME).build())); - wrapper.createQueue(QUEUE_NAME); + assertThatThrownBy(() -> wrapper.createQueue(QUEUE_NAME)) + .isInstanceOf(JMSException.class); } /* * Test create queue when amazon sqs client throws AmazonServiceException */ - @Test(expected = JMSException.class) - public void testCreateQueueWithNameThrowAmazonServiceException() throws JMSException { - + @Test + public void testCreateQueueWithNameThrowAmazonServiceException() { doThrow(SdkServiceException.create("ase", new Throwable("BROKEN"))) .when(amazonSQSClient).createQueue(eq(CreateQueueRequest.builder().queueName(QUEUE_NAME).build())); - wrapper.createQueue(QUEUE_NAME); + assertThatThrownBy(() -> wrapper.createQueue(QUEUE_NAME)) + .isInstanceOf(JMSException.class); } /* @@ -345,7 +333,6 @@ public void testCreateQueueWithNameThrowAmazonServiceException() throws JMSExcep */ @Test public void testCreateQueue() throws JMSException { - CreateQueueRequest createQueueRequest = CreateQueueRequest.builder().queueName(QUEUE_NAME).build(); wrapper.createQueue(createQueueRequest); @@ -355,28 +342,27 @@ public void testCreateQueue() throws JMSException { /* * Test create queue when amazon sqs client throws AmazonClientException */ - @Test(expected = JMSException.class) - public void testCreateQueueThrowAmazonClientException() throws JMSException { - + @Test + public void testCreateQueueThrowAmazonClientException() { CreateQueueRequest createQueueRequest = CreateQueueRequest.builder().queueName(QUEUE_NAME).build(); doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).createQueue(eq(createQueueRequest)); - wrapper.createQueue(createQueueRequest); + assertThatThrownBy(() -> wrapper.createQueue(createQueueRequest)) + .isInstanceOf(JMSException.class); } /* * Test create queue when amazon sqs client throws AmazonServiceException */ - @Test(expected = JMSException.class) - public void testCreateQueueThrowAmazonServiceException() throws JMSException { - - + @Test + public void testCreateQueueThrowAmazonServiceException() { CreateQueueRequest createQueueRequest = CreateQueueRequest.builder().queueName(QUEUE_NAME).build(); doThrow(SdkServiceException.create("ase", new Throwable("BROKEN"))) .when(amazonSQSClient).createQueue(eq(createQueueRequest)); - wrapper.createQueue(createQueueRequest); + assertThatThrownBy(() -> wrapper.createQueue(createQueueRequest)) + .isInstanceOf(JMSException.class); } /* @@ -384,7 +370,6 @@ public void testCreateQueueThrowAmazonServiceException() throws JMSException { */ @Test public void testReceiveMessage() throws JMSException { - ReceiveMessageRequest getQueueUrlRequest = ReceiveMessageRequest.builder().build(); wrapper.receiveMessage(getQueueUrlRequest); verify(amazonSQSClient).receiveMessage(getQueueUrlRequest); @@ -393,27 +378,27 @@ public void testReceiveMessage() throws JMSException { /* * Test receive message when amazon sqs client throws AmazonClientException */ - @Test(expected = JMSException.class) - public void testReceiveMessageThrowAmazonClientException() throws JMSException { - + @Test + public void testReceiveMessageThrowAmazonClientException() { ReceiveMessageRequest getQueueUrlRequest = ReceiveMessageRequest.builder().build(); doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).receiveMessage(eq(getQueueUrlRequest)); - wrapper.receiveMessage(getQueueUrlRequest); + assertThatThrownBy(() -> wrapper.receiveMessage(getQueueUrlRequest)) + .isInstanceOf(JMSException.class); } /* * Test receive message when amazon sqs client throws AmazonServiceException */ - @Test(expected = JMSException.class) - public void testReceiveMessageThrowAmazonServiceException() throws JMSException { - + @Test + public void testReceiveMessageThrowAmazonServiceException() { ReceiveMessageRequest getQueueUrlRequest = ReceiveMessageRequest.builder().build(); doThrow(SdkServiceException.create("ase", new Throwable("BROKEN"))) .when(amazonSQSClient).receiveMessage(eq(getQueueUrlRequest)); - wrapper.receiveMessage(getQueueUrlRequest); + assertThatThrownBy(() -> wrapper.receiveMessage(getQueueUrlRequest)) + .isInstanceOf(JMSException.class); } /* @@ -421,7 +406,6 @@ public void testReceiveMessageThrowAmazonServiceException() throws JMSException */ @Test public void testChangeMessageVisibility() throws JMSException { - ChangeMessageVisibilityRequest changeMessageVisibilityRequest = ChangeMessageVisibilityRequest.builder().build(); wrapper.changeMessageVisibility(changeMessageVisibilityRequest); verify(amazonSQSClient).changeMessageVisibility(changeMessageVisibilityRequest); @@ -430,27 +414,27 @@ public void testChangeMessageVisibility() throws JMSException { /* * Test change message visibility when amazon sqs client throws AmazonClientException */ - @Test(expected = JMSException.class) - public void testChangeMessageVisibilityThrowAmazonClientException() throws JMSException { - + @Test + public void testChangeMessageVisibilityThrowAmazonClientException() { ChangeMessageVisibilityRequest changeMessageVisibilityRequest = ChangeMessageVisibilityRequest.builder().build(); doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).changeMessageVisibility(eq(changeMessageVisibilityRequest)); - wrapper.changeMessageVisibility(changeMessageVisibilityRequest); + assertThatThrownBy(() -> wrapper.changeMessageVisibility(changeMessageVisibilityRequest)) + .isInstanceOf(JMSException.class); } /* * Test change message visibility when amazon sqs client throws AmazonServiceException */ - @Test(expected = JMSException.class) - public void testChangeMessageVisibilityThrowAmazonServiceException() throws JMSException { - + @Test + public void testChangeMessageVisibilityThrowAmazonServiceException() { ChangeMessageVisibilityRequest changeMessageVisibilityRequest = ChangeMessageVisibilityRequest.builder().build(); doThrow(SdkServiceException.create("ase", new Throwable("BROKEN"))) .when(amazonSQSClient).changeMessageVisibility(eq(changeMessageVisibilityRequest)); - wrapper.changeMessageVisibility(changeMessageVisibilityRequest); + assertThatThrownBy(() -> wrapper.changeMessageVisibility(changeMessageVisibilityRequest)) + .isInstanceOf(JMSException.class); } /* @@ -458,7 +442,6 @@ public void testChangeMessageVisibilityThrowAmazonServiceException() throws JMSE */ @Test public void testChangeMessageVisibilityBatch() throws JMSException { - ChangeMessageVisibilityBatchRequest changeMessageVisibilityBatchRequest = ChangeMessageVisibilityBatchRequest.builder().build(); wrapper.changeMessageVisibilityBatch(changeMessageVisibilityBatchRequest); verify(amazonSQSClient).changeMessageVisibilityBatch(changeMessageVisibilityBatchRequest); @@ -467,27 +450,27 @@ public void testChangeMessageVisibilityBatch() throws JMSException { /* * Test change message visibility batch when amazon sqs client throws AmazonClientException */ - @Test(expected = JMSException.class) - public void testChangeMessageVisibilityBatchThrowAmazonClientException() throws JMSException { - + @Test + public void testChangeMessageVisibilityBatchThrowAmazonClientException() { ChangeMessageVisibilityBatchRequest changeMessageVisibilityBatchRequest = ChangeMessageVisibilityBatchRequest.builder().build(); doThrow(SdkException.create("ace", new Throwable("BROKEN"))) .when(amazonSQSClient).changeMessageVisibilityBatch(eq(changeMessageVisibilityBatchRequest)); - wrapper.changeMessageVisibilityBatch(changeMessageVisibilityBatchRequest); + assertThatThrownBy(() -> wrapper.changeMessageVisibilityBatch(changeMessageVisibilityBatchRequest)) + .isInstanceOf(JMSException.class); } /* * Test change message visibility batch when amazon sqs client throws AmazonServiceException */ - @Test(expected = JMSException.class) - public void testChangeMessageVisibilityBatchThrowAmazonServiceException() throws JMSException { - + @Test + public void testChangeMessageVisibilityBatchThrowAmazonServiceException() { ChangeMessageVisibilityBatchRequest changeMessageVisibilityBatchRequest = ChangeMessageVisibilityBatchRequest.builder().build(); doThrow(SdkServiceException.create("ase", new Throwable("BROKEN"))) .when(amazonSQSClient).changeMessageVisibilityBatch(eq(changeMessageVisibilityBatchRequest)); - wrapper.changeMessageVisibilityBatch(changeMessageVisibilityBatchRequest); + assertThatThrownBy(() -> wrapper.changeMessageVisibilityBatch(changeMessageVisibilityBatchRequest)) + .isInstanceOf(JMSException.class); } /* diff --git a/src/test/java/com/amazon/sqs/javamessaging/AutoAcknowledgerTest.java b/src/test/java/com/amazon/sqs/javamessaging/AutoAcknowledgerTest.java index 32f2198..559f125 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/AutoAcknowledgerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/AutoAcknowledgerTest.java @@ -14,28 +14,19 @@ */ package com.amazon.sqs.javamessaging; -import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; -import com.amazon.sqs.javamessaging.SQSSession; import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; import com.amazon.sqs.javamessaging.acknowledge.AutoAcknowledger; -import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; import com.amazon.sqs.javamessaging.message.SQSMessage; - -import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; - -import javax.jms.IllegalStateException; -import java.util.Collections; -import org.junit.Test; -import org.junit.Before; +import jakarta.jms.IllegalStateException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; /** * Test the AutoAcknowledger class @@ -49,7 +40,7 @@ public class AutoAcknowledgerTest { private AmazonSQSMessagingClientWrapper amazonSQSClient; private SQSSession session; - @Before + @BeforeEach public void before() throws Exception { amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); session = mock(SQSSession.class); @@ -61,7 +52,6 @@ public void before() throws Exception { */ @Test public void testAcknowledge() throws Exception { - /* * Set up message mock */ @@ -93,7 +83,6 @@ public void testAcknowledge() throws Exception { */ @Test public void testAcknowledgeWhenSessionClosed() throws Exception { - /* * Set up mocks */ @@ -109,12 +98,8 @@ public void testAcknowledgeWhenSessionClosed() throws Exception { /* * Use the acknowledger to ack the message */ - try { - acknowledger.acknowledge(message); - fail(); - } catch (IllegalStateException ise) { - // Expected exception - } + assertThatThrownBy(() -> acknowledger.acknowledge(message)) + .isInstanceOf(IllegalStateException.class); } /** @@ -122,7 +107,6 @@ public void testAcknowledgeWhenSessionClosed() throws Exception { */ @Test public void testNotifyMessageReceived() throws Exception { - SQSMessage message = mock(SQSMessage.class); acknowledger.notifyMessageReceived(message); verify(acknowledger).acknowledge(message); @@ -132,8 +116,7 @@ public void testNotifyMessageReceived() throws Exception { * Test get UnAckMessages */ @Test - public void testGetUnAckMessages() throws Exception { - - assertEquals(Collections.emptyList(), acknowledger.getUnAckMessages()); + public void testGetUnAckMessages() { + assertThat(acknowledger.getUnAckMessages()).isEmpty(); } } diff --git a/src/test/java/com/amazon/sqs/javamessaging/BulkSQSOperationTest.java b/src/test/java/com/amazon/sqs/javamessaging/BulkSQSOperationTest.java index cf816f0..b093bef 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/BulkSQSOperationTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/BulkSQSOperationTest.java @@ -16,15 +16,14 @@ import com.amazon.sqs.javamessaging.acknowledge.BulkSQSOperation; import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -import javax.jms.JMSException; import java.util.ArrayList; import java.util.List; -import org.junit.Test; -import org.junit.Before; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -39,13 +38,11 @@ public class BulkSQSOperationTest { private BulkSQSOperation bulkAction; - @Before - public void before() throws Exception { - + @BeforeEach + public void before() { bulkAction = spy(new BulkSQSOperation() { @Override - public void action(String queueUrl, List receiptHandles) throws JMSException { - return; + public void action(String queueUrl, List receiptHandles) { } }); } @@ -54,34 +51,21 @@ public void action(String queueUrl, List receiptHandles) throws JMSExcep * Test illegal index value cases */ @Test - public void testBulkActionIllegalIndexValue() throws Exception { - - List messageIdentifierList = new ArrayList(); - messageIdentifierList.add(new SQSMessageIdentifier(QUEUE_URL, "receiptHandle1", "sqsMessageId1")); - messageIdentifierList.add(new SQSMessageIdentifier(QUEUE_URL, "receiptHandle2", "sqsMessageId2")); - messageIdentifierList.add(new SQSMessageIdentifier(QUEUE_URL, "receiptHandle3", "sqsMessageId3")); + public void testBulkActionIllegalIndexValue() { + List messageIdentifierList = List.of( + new SQSMessageIdentifier(QUEUE_URL, "receiptHandle1", "sqsMessageId1"), + new SQSMessageIdentifier(QUEUE_URL, "receiptHandle2", "sqsMessageId2"), + new SQSMessageIdentifier(QUEUE_URL, "receiptHandle3", "sqsMessageId3")); int negativeSize = -10; - try { - bulkAction.bulkAction(messageIdentifierList, negativeSize); - fail(); - } catch(AssertionError ae) { - // expected exception - } + assertThatThrownBy(() -> bulkAction.bulkAction(messageIdentifierList, negativeSize)) + .isInstanceOf(AssertionError.class); - try { - bulkAction.bulkAction(messageIdentifierList, 0); - fail(); - } catch(AssertionError ae) { - // expected exception - } + assertThatThrownBy(() -> bulkAction.bulkAction(messageIdentifierList, 0)) + .isInstanceOf(AssertionError.class); - try { - bulkAction.bulkAction(messageIdentifierList, 3); - fail(); - } catch(AssertionError ae) { - // expected exception - } + assertThatThrownBy(() -> bulkAction.bulkAction(messageIdentifierList, messageIdentifierList.size() + 1)) + .isInstanceOf(AssertionError.class); } /** @@ -89,22 +73,21 @@ public void testBulkActionIllegalIndexValue() throws Exception { */ @Test public void testBulkActionBelowBatchSize() throws Exception { - - List messageIdentifierList = new ArrayList(); + List messageIdentifierList = new ArrayList<>(); int numMessagesFromQueue = (SQSMessagingClientConstants.MAX_BATCH - 2) / 2; // Create message from the first queue int i = 0; - List receiptHandles1 = new ArrayList(); + List receiptHandles1 = new ArrayList<>(); for (; i < numMessagesFromQueue; ++i) { messageIdentifierList.add(new SQSMessageIdentifier(QUEUE_URL + 1, - RECEIPT_HANDLE_PREFIX + i, MESSAGE_ID_PREFIX + i)); + RECEIPT_HANDLE_PREFIX + i, MESSAGE_ID_PREFIX + i)); receiptHandles1.add(RECEIPT_HANDLE_PREFIX + i); } // Create message from the second queue - List receiptHandles2 = new ArrayList(); + List receiptHandles2 = new ArrayList<>(); for (; i < numMessagesFromQueue * 2; ++i) { messageIdentifierList.add(new SQSMessageIdentifier(QUEUE_URL + 2, RECEIPT_HANDLE_PREFIX + i, MESSAGE_ID_PREFIX + i)); @@ -123,14 +106,13 @@ public void testBulkActionBelowBatchSize() throws Exception { */ @Test public void testBulkActionAboveBatchSize() throws Exception { - - List messageIdentifierList = new ArrayList(); + List messageIdentifierList = new ArrayList<>(); int numMessagesFromQueue = SQSMessagingClientConstants.MAX_BATCH * 2 + 3; // Create messages from the first batch int i = 0; - List firstBatchReceiptHandles = new ArrayList(); + List firstBatchReceiptHandles = new ArrayList<>(); for (; i < SQSMessagingClientConstants.MAX_BATCH; ++i) { messageIdentifierList.add(new SQSMessageIdentifier(QUEUE_URL + 1, RECEIPT_HANDLE_PREFIX + i, MESSAGE_ID_PREFIX + i)); @@ -138,7 +120,7 @@ public void testBulkActionAboveBatchSize() throws Exception { } // Create messages from the second batch - List secondBatchReceiptHandles = new ArrayList(); + List secondBatchReceiptHandles = new ArrayList<>(); for (; i < SQSMessagingClientConstants.MAX_BATCH * 2; ++i) { messageIdentifierList.add(new SQSMessageIdentifier(QUEUE_URL + 1, RECEIPT_HANDLE_PREFIX + i, MESSAGE_ID_PREFIX + i)); @@ -146,7 +128,7 @@ public void testBulkActionAboveBatchSize() throws Exception { } // Create messages from the third batch - List thirdBatchReceiptHandles = new ArrayList(); + List thirdBatchReceiptHandles = new ArrayList<>(); for (; i < numMessagesFromQueue; ++i) { messageIdentifierList.add(new SQSMessageIdentifier(QUEUE_URL + 1, RECEIPT_HANDLE_PREFIX + i, MESSAGE_ID_PREFIX + i)); @@ -154,19 +136,19 @@ public void testBulkActionAboveBatchSize() throws Exception { } // Create messages from a different queue - List receiptHandles2 = new ArrayList(); + List receiptHandles2 = new ArrayList<>(); for (i = 0; i < SQSMessagingClientConstants.MAX_BATCH / 2; ++i) { messageIdentifierList.add(new SQSMessageIdentifier(QUEUE_URL + 2, RECEIPT_HANDLE_PREFIX + i, MESSAGE_ID_PREFIX + i)); receiptHandles2.add(RECEIPT_HANDLE_PREFIX + i); } - final List> receiptHandlesList = new ArrayList>(); - final List queueUrlList = new ArrayList(); + final List> receiptHandlesList = new ArrayList<>(); + final List queueUrlList = new ArrayList<>(); bulkAction = new BulkSQSOperation() { @Override - public void action(String queueUrl, List receiptHandles) throws JMSException { - receiptHandlesList.add(new ArrayList(receiptHandles)); + public void action(String queueUrl, List receiptHandles) { + receiptHandlesList.add(new ArrayList<>(receiptHandles)); queueUrlList.add(queueUrl); } }; diff --git a/src/test/java/com/amazon/sqs/javamessaging/ExponentialBackoffStrategyTest.java b/src/test/java/com/amazon/sqs/javamessaging/ExponentialBackoffStrategyTest.java index 36af469..56e008e 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/ExponentialBackoffStrategyTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/ExponentialBackoffStrategyTest.java @@ -14,11 +14,10 @@ */ package com.amazon.sqs.javamessaging; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - import com.amazon.sqs.javamessaging.util.ExponentialBackoffStrategy; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; /** * Test the ExponentialBackoffStrategy class @@ -26,27 +25,26 @@ public class ExponentialBackoffStrategyTest { private static final int DELAY_INTERVAL = 10; - private static final int INITAL_DELAY = 20; + private static final int INITIAL_DELAY = 20; private static final int MAX_DELAY = 300; /** * test delay with illegal value of retry attempts */ @Test - public void testDelayBeforeNextRetryNonPositiveRetryAttempt() throws Exception { - - ExponentialBackoffStrategy backoff = new ExponentialBackoffStrategy(DELAY_INTERVAL, INITAL_DELAY, MAX_DELAY); + public void testDelayBeforeNextRetryNonPositiveRetryAttempt() { + ExponentialBackoffStrategy backoff = new ExponentialBackoffStrategy(DELAY_INTERVAL, INITIAL_DELAY, MAX_DELAY); - assertEquals(INITAL_DELAY, backoff.delayBeforeNextRetry(0)); - assertEquals(INITAL_DELAY, backoff.delayBeforeNextRetry(-10)); + assertEquals(INITIAL_DELAY, backoff.delayBeforeNextRetry(0)); + assertEquals(INITIAL_DELAY, backoff.delayBeforeNextRetry(-10)); } /** * test first delay result in delay initial value */ @Test - public void testDelayBeforeNextRetryFirstAttempt() throws Exception { - ExponentialBackoffStrategy backoff = new ExponentialBackoffStrategy(DELAY_INTERVAL, INITAL_DELAY, MAX_DELAY); + public void testDelayBeforeNextRetryFirstAttempt() { + ExponentialBackoffStrategy backoff = new ExponentialBackoffStrategy(DELAY_INTERVAL, INITIAL_DELAY, MAX_DELAY); assertEquals(DELAY_INTERVAL, backoff.delayBeforeNextRetry(1)); } @@ -55,8 +53,8 @@ public void testDelayBeforeNextRetryFirstAttempt() throws Exception { * test delay from 2 to 1000 */ @Test - public void testDelayBeforeNextRetry() throws Exception { - ExponentialBackoffStrategy backoff = new ExponentialBackoffStrategy(DELAY_INTERVAL, INITAL_DELAY, MAX_DELAY); + public void testDelayBeforeNextRetry() { + ExponentialBackoffStrategy backoff = new ExponentialBackoffStrategy(DELAY_INTERVAL, INITIAL_DELAY, MAX_DELAY); assertEquals(20, backoff.delayBeforeNextRetry(2)); assertEquals(40, backoff.delayBeforeNextRetry(3)); diff --git a/src/test/java/com/amazon/sqs/javamessaging/MessageListenerConcurrentOperationTest.java b/src/test/java/com/amazon/sqs/javamessaging/MessageListenerConcurrentOperationTest.java index 6a1b061..9a22ff0 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/MessageListenerConcurrentOperationTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/MessageListenerConcurrentOperationTest.java @@ -14,29 +14,24 @@ */ package com.amazon.sqs.javamessaging; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; +import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; +import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; +import com.amazon.sqs.javamessaging.message.SQSMessage; +import jakarta.jms.IllegalStateException; +import jakarta.jms.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.util.Collections; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; -import javax.jms.IllegalStateException; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.Session; - -import org.junit.Before; -import org.junit.Test; - -import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; -import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; -import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; -import com.amazon.sqs.javamessaging.message.SQSMessage; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Test concurrent operation of message listener on session and connections @@ -55,7 +50,7 @@ public class MessageListenerConcurrentOperationTest { /** * Message listener that creates a producer on the session */ - private MessageListener msgListenerCreatesProducer = new MessageListener() { + private final MessageListener msgListenerCreatesProducer = new MessageListener() { @Override public void onMessage(Message message) { try { @@ -69,7 +64,7 @@ public void onMessage(Message message) { /** * Message listener that creates a consumer on the session */ - private MessageListener msgListenerCreatesConsumer = new MessageListener() { + private final MessageListener msgListenerCreatesConsumer = new MessageListener() { @Override public void onMessage(Message message) { try { @@ -80,9 +75,8 @@ public void onMessage(Message message) { } }; - @Before + @BeforeEach public void Setup() throws JMSException { - Acknowledger acknowledger = mock(Acknowledger.class); NegativeAcknowledger negativeAcknowledger = mock(NegativeAcknowledger.class); SQSQueueDestination sqsDestination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL); @@ -90,19 +84,16 @@ public void Setup() throws JMSException { connection = new SQSConnection(amazonSQSClient, NUMBER_OF_MESSAGES_TO_PREFETCH); session = new SQSSession(connection, AcknowledgeMode.ACK_AUTO); - SQSSessionCallbackScheduler sqsSessionRunnable = new SQSSessionCallbackScheduler(session, AcknowledgeMode.ACK_AUTO, acknowledger, negativeAcknowledger); + SQSSessionCallbackScheduler sqsSessionRunnable = new SQSSessionCallbackScheduler(session, + AcknowledgeMode.ACK_AUTO, acknowledger, negativeAcknowledger); SQSMessageConsumer consumer = mock(SQSMessageConsumer.class); - SQSMessageConsumerPrefetch preftecher = new SQSMessageConsumerPrefetch(sqsSessionRunnable, acknowledger, negativeAcknowledger, sqsDestination, - amazonSQSClient, NUMBER_OF_MESSAGES_TO_PREFETCH); - preftecher.setMessageConsumer(consumer); + SQSMessageConsumerPrefetch preFetcher = new SQSMessageConsumerPrefetch(sqsSessionRunnable, acknowledger, + negativeAcknowledger, sqsDestination, amazonSQSClient, NUMBER_OF_MESSAGES_TO_PREFETCH); + preFetcher.setMessageConsumer(consumer); - msgManager = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager.getMessage()) - .thenReturn(mock(SQSMessage.class)); - when(msgManager.getPrefetchManager()) - .thenReturn(preftecher); + msgManager = new SQSMessageConsumerPrefetch.MessageManager(preFetcher, mock(SQSMessage.class)); } /** @@ -132,7 +123,6 @@ public void verify() { // Test session close operation with create producer operation for (int i = 0; i < 10; ++i) { - connection = new SQSConnection(amazonSQSClient, NUMBER_OF_MESSAGES_TO_PREFETCH); session = (SQSSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); @@ -142,7 +132,6 @@ public void verify() { // Test session close operation with create consumer operation for (int i = 0; i < 10; ++i) { - connection = new SQSConnection(amazonSQSClient, NUMBER_OF_MESSAGES_TO_PREFETCH); session = (SQSSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); @@ -178,7 +167,6 @@ public void verify() { // Test connection start operation with create producer operation for (int i = 0; i < 10; ++i) { - connection = new SQSConnection(amazonSQSClient, NUMBER_OF_MESSAGES_TO_PREFETCH); session = (SQSSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); @@ -188,7 +176,6 @@ public void verify() { // Test connection start operation with create consumer operation for (int i = 0; i < 10; ++i) { - connection = new SQSConnection(amazonSQSClient, NUMBER_OF_MESSAGES_TO_PREFETCH); session = (SQSSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); @@ -203,7 +190,6 @@ public void verify() { */ @Test public void testConcurrentConnectionCloseOperation() throws JMSException, InterruptedException { - ConcurrentOperation closeConnectionOperation = new ConcurrentOperation() { @Override public void setup() throws JMSException { @@ -244,7 +230,6 @@ public void verify() { */ @Test public void testConcurrentConnectionStopOperation() throws JMSException, InterruptedException { - ConcurrentOperation stopConnectionOperation = new ConcurrentOperation() { @Override public void setup() throws JMSException { @@ -267,7 +252,6 @@ public void verify() { // Test connection stop operation with create producer operation for (int i = 0; i < 10; ++i) { - connection = new SQSConnection(amazonSQSClient, NUMBER_OF_MESSAGES_TO_PREFETCH); session = (SQSSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); @@ -277,7 +261,6 @@ public void verify() { // Test connection stop operation with create consumer operation for (int i = 0; i < 10; ++i) { - connection = new SQSConnection(amazonSQSClient, NUMBER_OF_MESSAGES_TO_PREFETCH); session = (SQSSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); @@ -286,45 +269,32 @@ public void verify() { } } - public void testConcurrentExecution(final MessageListener msgListener, final ConcurrentOperation operation) throws JMSException, InterruptedException { - + public void testConcurrentExecution(final MessageListener msgListener, final ConcurrentOperation operation) + throws JMSException, InterruptedException { // Start the session operation.setup(); final CyclicBarrier startBarrier = new CyclicBarrier(2); final CountDownLatch finishLatch = new CountDownLatch(1); - Thread t1 = new Thread(new Runnable() { - @Override - public void run() { - try { - startBarrier.await(); - operation.applyOperation(); - } catch (JMSException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (BrokenBarrierException e) { - e.printStackTrace(); - } - finishLatch.countDown(); + Thread t1 = new Thread(() -> { + try { + startBarrier.await(); + operation.applyOperation(); + } catch (JMSException | InterruptedException | BrokenBarrierException e) { + e.printStackTrace(); } + finishLatch.countDown(); }); // Start the callback scheduler - Thread t2 = new Thread(new Runnable() { - @Override - public void run() { - - try { - startBarrier.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (BrokenBarrierException e) { - e.printStackTrace(); - } - session.getSqsSessionRunnable().scheduleCallBacks(msgListener, Collections.singletonList(msgManager)); + Thread t2 = new Thread(() -> { + try { + startBarrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + e.printStackTrace(); } + session.getSqsSessionRunnable().scheduleCallBacks(msgListener, Collections.singletonList(msgManager)); }); t1.start(); @@ -340,11 +310,11 @@ public void run() { */ private interface ConcurrentOperation { - public abstract void setup() throws JMSException; + void setup() throws JMSException; - public abstract void applyOperation() throws JMSException; + void applyOperation() throws JMSException; - public abstract void verify(); + void verify(); } } diff --git a/src/test/java/com/amazon/sqs/javamessaging/NegativeAcknowledgerTest.java b/src/test/java/com/amazon/sqs/javamessaging/NegativeAcknowledgerTest.java index e3bf4de..013e518 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/NegativeAcknowledgerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/NegativeAcknowledgerTest.java @@ -14,33 +14,22 @@ */ package com.amazon.sqs.javamessaging; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyList; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; +import com.amazon.sqs.javamessaging.message.SQSMessage; +import jakarta.jms.JMSException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; +import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequestEntry; import java.util.ArrayDeque; -import java.util.ArrayList; import java.util.Collections; import java.util.List; -import javax.jms.JMSException; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; -import com.amazon.sqs.javamessaging.message.SQSMessage; - -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequestEntry; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.*; /** * Test the NegativeAcknowledger class @@ -51,8 +40,8 @@ public class NegativeAcknowledgerTest extends AcknowledgerCommon { private NegativeAcknowledger negativeAcknowledger; - @Before - public void setupRanded() throws JMSException { + @BeforeEach + public void setupRanded() { amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); negativeAcknowledger = spy(new NegativeAcknowledger(amazonSQSClient)); } @@ -62,14 +51,10 @@ public void setupRanded() throws JMSException { */ @Test public void testNackBulkAction() throws JMSException { - /* * Set up the message queue */ - List receiptHandles = new ArrayList(); - receiptHandles.add("r0"); - receiptHandles.add("r1"); - receiptHandles.add("r2"); + List receiptHandles = List.of("r0", "r1", "r2"); ArrayDeque messageQueue = addSQSMessageToQueue(3); @@ -89,7 +74,6 @@ public void testNackBulkAction() throws JMSException { */ @Test public void testNackBulkActionLargeBatch() throws JMSException { - /* * Set up the message queue */ @@ -111,12 +95,7 @@ public void testNackBulkActionLargeBatch() throws JMSException { */ @Test public void testAction() throws JMSException { - - - List receiptHandles = new ArrayList(); - receiptHandles.add("r0"); - receiptHandles.add("r1"); - receiptHandles.add("r2"); + List receiptHandles = List.of("r0", "r1", "r2"); negativeAcknowledger.action(QUEUE_URL, receiptHandles); @@ -127,11 +106,11 @@ public void testAction() throws JMSException { assertEquals(1, argumentCaptor.getAllValues().size()); assertEquals(QUEUE_URL, argumentCaptor.getAllValues().get(0).queueUrl()); - List captureList = argumentCaptor.getAllValues().get(0).entries(); + List captureList = argumentCaptor.getAllValues().get(0).entries(); assertEquals(receiptHandles.size(), captureList.size()); for (ChangeMessageVisibilityBatchRequestEntry item : captureList) { - receiptHandles.contains(item.receiptHandle()); + assertTrue(receiptHandles.contains(item.receiptHandle())); } } @@ -140,7 +119,6 @@ public void testAction() throws JMSException { */ @Test public void testActionEmptyReceiptHandles() throws JMSException { - negativeAcknowledger.action(QUEUE_URL, null); negativeAcknowledger.action(QUEUE_URL, Collections.emptyList()); @@ -152,9 +130,7 @@ public void testActionEmptyReceiptHandles() throws JMSException { * Utility function */ private ArrayDeque addSQSMessageToQueue(int count) { - - ArrayDeque messageQueue = - new ArrayDeque(); + ArrayDeque messageQueue = new ArrayDeque<>(); PrefetchManager prefetchManager = mock(PrefetchManager.class); for (int i = 0; i < count; ++i) { diff --git a/src/test/java/com/amazon/sqs/javamessaging/RangedAcknowledgerTest.java b/src/test/java/com/amazon/sqs/javamessaging/RangedAcknowledgerTest.java index 41f7f5e..7d3039b 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/RangedAcknowledgerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/RangedAcknowledgerTest.java @@ -14,32 +14,22 @@ */ package com.amazon.sqs.javamessaging; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; +import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; +import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; +import com.amazon.sqs.javamessaging.message.SQSMessage; +import jakarta.jms.JMSException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.jms.JMSException; - -import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; -import com.amazon.sqs.javamessaging.SQSSession; -import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; -import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; -import com.amazon.sqs.javamessaging.message.SQSMessage; - -import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; /** @@ -47,7 +37,7 @@ */ public class RangedAcknowledgerTest extends AcknowledgerCommon { - @Before + @BeforeEach public void setupRanded() throws JMSException { amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); acknowledger = AcknowledgeMode.ACK_RANGE.createAcknowledger(amazonSQSClient, mock(SQSSession.class)); @@ -62,7 +52,7 @@ public void testForget() throws JMSException { populateMessage(populateMessageSize); acknowledger.forgetUnAckMessages(); - Assert.assertEquals(0, acknowledger.getUnAckMessages().size()); + assertEquals(0, acknowledger.getUnAckMessages().size()); } /** @@ -73,10 +63,10 @@ public void testFullAck() throws JMSException { int populateMessageSize = 34; populateMessage(populateMessageSize); int ackMessage = 33; - + testAcknowledge(populateMessageSize, ackMessage); - - Assert.assertEquals(0, acknowledger.getUnAckMessages().size()); + + assertEquals(0, acknowledger.getUnAckMessages().size()); } /** @@ -92,22 +82,22 @@ public void testOneAck() throws JMSException { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(DeleteMessageBatchRequest.class); verify(amazonSQSClient, times(5)).deleteMessageBatch(argumentCaptor.capture()); - + //key is the queue url //value is the sequence of sizes of expected batches - Map> expectedCalls = new HashMap>(); - List queue0Calls = new ArrayList(); + Map> expectedCalls = new HashMap<>(); + List queue0Calls = new ArrayList<>(); queue0Calls.add(10); queue0Calls.add(1); expectedCalls.put(baseQueueUrl + 0, queue0Calls); - List queue1Calls = new ArrayList(); + List queue1Calls = new ArrayList<>(); queue1Calls.add(10); queue1Calls.add(1); expectedCalls.put(baseQueueUrl + 1, queue1Calls); - List queue2Calls = new ArrayList(); + List queue2Calls = new ArrayList<>(); queue2Calls.add(4); expectedCalls.put(baseQueueUrl + 2, queue2Calls); - + for (DeleteMessageBatchRequest request : argumentCaptor.getAllValues()) { String queueUrl = request.queueUrl(); List expectedSequence = expectedCalls.get(queueUrl); @@ -119,7 +109,7 @@ public void testOneAck() throws JMSException { expectedCalls.remove(queueUrl); } } - + assertTrue(expectedCalls.isEmpty()); } @@ -140,6 +130,7 @@ public void testTwoAck() throws JMSException { /** * Utility function to acknowledge the first indexOfMessageToAck un-acknowledge messages + * * @param populateMessageSize current un-acknowledge messages size * @param indexOfMessageToAck index of message to acknowledge */ @@ -149,11 +140,11 @@ public void testAcknowledge(int populateMessageSize, int indexOfMessageToAck) th for (int i = 0; i < indexOfMessageToAck; i++) { SQSMessage message = populatedMessages.get(i); - SQSMessageIdentifier sqsMessageIdentifier = new SQSMessageIdentifier(message.getQueueUrl(), message.getReceiptHandle(), - message.getSQSMessageId()); - Assert.assertFalse(acknowledger.getUnAckMessages().contains(sqsMessageIdentifier)); + SQSMessageIdentifier sqsMessageIdentifier = new SQSMessageIdentifier( + message.getQueueUrl(), message.getReceiptHandle(), message.getSQSMessageId()); + assertFalse(acknowledger.getUnAckMessages().contains(sqsMessageIdentifier)); } - Assert.assertEquals((populateMessageSize - indexOfMessageToAck - 1), acknowledger.getUnAckMessages().size()); + assertEquals((populateMessageSize - indexOfMessageToAck - 1), acknowledger.getUnAckMessages().size()); } } diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionFactoryTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionFactoryTest.java index 123e28f..879d0be 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionFactoryTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionFactoryTest.java @@ -14,22 +14,22 @@ */ package com.amazon.sqs.javamessaging; -import javax.jms.JMSException; - -import org.junit.Test; - +import jakarta.jms.JMSException; +import org.junit.jupiter.api.Test; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.sqs.SqsClient; import software.amazon.awssdk.services.sqs.SqsClientBuilder; -import static org.mockito.Mockito.*; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.Mockito.mock; public class SQSConnectionFactoryTest { @Test - public void canCreateFactoryWithDefaultProviderSettings() throws JMSException { + public void canCreateFactoryWithDefaultProviderSettings() { + System.setProperty("aws.region", "eu-central-1"); new SQSConnectionFactory(new ProviderConfiguration()); //cannot actually attempt to create a connection because the default client builder depends on environment settings or instance configuration to be present //which we cannot guarantee on the builder fleet diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionTest.java index bec4e41..678f9e9 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionTest.java @@ -14,16 +14,10 @@ */ package com.amazon.sqs.javamessaging; -import javax.jms.*; -import javax.jms.IllegalStateException; - -import org.junit.Before; -import org.junit.Test; - -import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; -import com.amazon.sqs.javamessaging.SQSConnection; -import com.amazon.sqs.javamessaging.SQSQueueDestination; -import com.amazon.sqs.javamessaging.SQSSession; +import jakarta.jms.IllegalStateException; +import jakarta.jms.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; @@ -31,7 +25,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import static org.junit.Assert.*; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; /** @@ -42,20 +37,18 @@ public class SQSConnectionTest { public static final String QUEUE_URL = "QueueUrl"; public static final String QUEUE_NAME = "QueueName"; - private AmazonSQSMessagingClientWrapper amazonSQSClientJMSWrapper; private SQSConnection sqsConnection; private SQSQueueDestination destination; - private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); + private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); private SQSSession session1; private SQSSession session2; - @Before + @BeforeEach public void setup() throws JMSException { - destination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL); int numberOfMessagesToPrefetch = 10; - amazonSQSClientJMSWrapper = mock(AmazonSQSMessagingClientWrapper.class); + AmazonSQSMessagingClientWrapper amazonSQSClientJMSWrapper = mock(AmazonSQSMessagingClientWrapper.class); sqsConnection = spy(new SQSConnection(amazonSQSClientJMSWrapper, numberOfMessagesToPrefetch)); session1 = mock(SQSSession.class); @@ -69,81 +62,53 @@ public void setup() throws JMSException { */ @Test public void testUnsupportedFeatures() { + assertThatThrownBy(() -> sqsConnection.createConnectionConsumer(destination, "messageSelector", null, 10)) + .isInstanceOf(JMSException.class); - try { - sqsConnection.createConnectionConsumer(destination, "messageSelector", null, 10); - fail(); - } catch (JMSException jmse) { - // expected - } + Topic topic = mock(Topic.class); + assertThatThrownBy(() -> sqsConnection.createDurableConnectionConsumer(topic, "subscriptionName", "messageSelector", null, 10)) + .isInstanceOf(JMSException.class); - try { - Topic topic = mock(Topic.class); - sqsConnection.createDurableConnectionConsumer(topic, "subscriptionName", "messageSelector", null, 10); - fail(); - } catch (JMSException jmse) { - // expected - } - - try { - Queue queue = mock(Queue.class); - sqsConnection.createConnectionConsumer(queue, "messageSelector", null, 10); - fail(); - } catch (JMSException jmse) { - // expected - } + Queue queue = mock(Queue.class); + assertThatThrownBy(() -> sqsConnection.createConnectionConsumer(queue, "messageSelector", null, 10)) + .isInstanceOf(JMSException.class); } /** * Test set client id when connection is closing */ @Test - public void testSetClientIdWhenClosing() throws JMSException { - + public void testSetClientIdWhenClosing() { sqsConnection.setClosing(true); - try { - sqsConnection.setClientID("clientId"); - fail(); - } catch (IllegalStateException ise) { - assertEquals("Connection is closed or closing", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.setClientID("clientId")) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Connection is closed or closing"); } /** * Test set client id on an invalid client id */ @Test - public void testSetClientIdInvalidClientId() throws JMSException { - - try { - sqsConnection.setClientID(null); - fail(); - } catch (InvalidClientIDException ice) { - assertEquals("ClientID is empty", ice.getMessage()); - } - - try { - sqsConnection.setClientID(""); - fail(); - } catch (InvalidClientIDException ice) { - assertEquals("ClientID is empty", ice.getMessage()); - } + public void testSetClientIdInvalidClientId() { + assertThatThrownBy(() -> sqsConnection.setClientID(null)) + .isInstanceOf(InvalidClientIDException.class) + .hasMessage("ClientID is empty"); + + assertThatThrownBy(() -> sqsConnection.setClientID("")) + .isInstanceOf(InvalidClientIDException.class) + .hasMessage("ClientID is empty"); } /** * Test set client id when action on connection is already made */ @Test - public void testSetClientIdActionTaken() throws JMSException { - + public void testSetClientIdActionTaken() { sqsConnection.setActionOnConnectionTaken(true); - try { - sqsConnection.setClientID("id"); - fail(); - } catch (IllegalStateException ise) { - assertEquals("Client ID cannot be set after any action on the connection is taken", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.setClientID("id")) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Client ID cannot be set after any action on the connection is taken"); } /** @@ -151,14 +116,10 @@ public void testSetClientIdActionTaken() throws JMSException { */ @Test public void testSetClientId() throws JMSException { - sqsConnection.setClientID("id"); - try { - sqsConnection.setClientID("id2"); - fail(); - } catch (IllegalStateException ise) { - assertEquals("ClientID is already set", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.setClientID("id2")) + .isInstanceOf(IllegalStateException.class) + .hasMessage("ClientID is already set"); assertEquals("id", sqsConnection.getClientID()); } @@ -168,16 +129,11 @@ public void testSetClientId() throws JMSException { */ @Test public void testClosing() throws JMSException { - sqsConnection.checkClosing(); - sqsConnection.setClosing(true); - try { - sqsConnection.checkClosing(); - fail(); - } catch (IllegalStateException ise) { - assertEquals("Connection is closed or closing", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.checkClosing()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Connection is closed or closing"); } /** @@ -185,16 +141,11 @@ public void testClosing() throws JMSException { */ @Test public void testCheckClosed() throws JMSException { - sqsConnection.checkClosed(); - sqsConnection.setClosed(true); - try { - sqsConnection.checkClosed(); - fail(); - } catch (IllegalStateException ise) { - assertEquals("Connection is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.checkClosed()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Connection is closed"); } /** @@ -202,7 +153,6 @@ public void testCheckClosed() throws JMSException { */ @Test public void testExceptionListener() throws JMSException { - ExceptionListener listener = mock(ExceptionListener.class); sqsConnection.setExceptionListener(listener); @@ -216,7 +166,6 @@ public void testExceptionListener() throws JMSException { */ @Test public void testCloseWhenAlreadyClosed() throws JMSException { - /* * Set up connection */ @@ -239,39 +188,35 @@ public void testCloseWhenAlreadyClosed() throws JMSException { */ @Test public void testCloseWhenClosing() throws JMSException, InterruptedException { - /* * Set up connection and mocks */ sqsConnection.setClosing(true); - final CountDownLatch beforeCloseCall= new CountDownLatch(1); + final CountDownLatch beforeCloseCall = new CountDownLatch(1); final CountDownLatch passedCloseCall = new CountDownLatch(1); /* * call close in different thread */ - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeCloseCall.countDown(); - sqsConnection.close(); - passedCloseCall.countDown(); - } catch (JMSException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeCloseCall.countDown(); + sqsConnection.close(); + passedCloseCall.countDown(); + } catch (JMSException e) { + e.printStackTrace(); } }); // Yield execution to allow the connection to wait - assertEquals(true, beforeCloseCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeCloseCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Release the lock and ensure that we are still waiting since the did not run synchronized (sqsConnection.getStateLock()) { sqsConnection.getStateLock().notifyAll(); } - assertEquals(false, passedCloseCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedCloseCall.await(2, TimeUnit.SECONDS)); // Simulate connection closed sqsConnection.setClosed(true); @@ -289,8 +234,7 @@ public void run() { * Test close */ @Test - public void testClose() throws JMSException, InterruptedException { - + public void testClose() throws JMSException { /* * Close */ @@ -309,23 +253,19 @@ public void testClose() throws JMSException, InterruptedException { * Test close from the callback thread */ @Test - public void testCloseThreadGroup() throws JMSException, InterruptedException { - + public void testCloseThreadGroup() throws InterruptedException { final AtomicBoolean flag = new AtomicBoolean(false); final CountDownLatch passedCloseCall = new CountDownLatch(1); - Thread t = SQSSession.SESSION_THREAD_FACTORY.newThread(new Runnable() { - @Override - public void run() { - try { - sqsConnection.close(); - } catch (IllegalStateException e) { - flag.set(true); - } catch (JMSException e) { - e.printStackTrace(); - } - passedCloseCall.countDown(); + Thread t = SQSSession.SESSION_THREAD_FACTORY.newThread(() -> { + try { + sqsConnection.close(); + } catch (IllegalStateException e) { + flag.set(true); + } catch (JMSException e) { + e.printStackTrace(); } + passedCloseCall.countDown(); }); t.start(); @@ -342,7 +282,6 @@ public void run() { */ @Test public void testStopNoOpIfAlreadyClosed() throws JMSException { - /* * Set up connection */ @@ -351,12 +290,9 @@ public void testStopNoOpIfAlreadyClosed() throws JMSException { /* * stop consumer */ - try { - sqsConnection.stop(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Connection is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.stop()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Connection is closed"); /* * Verify results @@ -370,7 +306,6 @@ public void testStopNoOpIfAlreadyClosed() throws JMSException { */ @Test public void testStopNoOpIfNotRunning() throws JMSException { - /* * Set up connection */ @@ -393,7 +328,6 @@ public void testStopNoOpIfNotRunning() throws JMSException { */ @Test public void testStopThreadGroup() throws JMSException, InterruptedException { - /* * Set up connection */ @@ -401,19 +335,15 @@ public void testStopThreadGroup() throws JMSException, InterruptedException { final CountDownLatch passedStopCall = new CountDownLatch(1); sqsConnection.setRunning(true); - Thread t = SQSSession.SESSION_THREAD_FACTORY.newThread(new Runnable() { - @Override - public void run() { - - try { - sqsConnection.close(); - } catch (IllegalStateException e) { - flag.set(true); - } catch (JMSException e) { - e.printStackTrace(); - } - passedStopCall.countDown(); + Thread t = SQSSession.SESSION_THREAD_FACTORY.newThread(() -> { + try { + sqsConnection.close(); + } catch (IllegalStateException e) { + flag.set(true); + } catch (JMSException e) { + e.printStackTrace(); } + passedStopCall.countDown(); }); t.start(); @@ -431,20 +361,15 @@ public void run() { * Test stop when connection is closing */ @Test - public void testStopWhenClosing() throws JMSException, InterruptedException { - + public void testStopWhenClosing() throws JMSException { /* * Set up connection */ sqsConnection.setClosing(true); sqsConnection.setRunning(true); - try { - sqsConnection.stop(); - fail(); - } catch (IllegalStateException e) { - //expected - } + assertThatThrownBy(() -> sqsConnection.stop()) + .isInstanceOf(IllegalStateException.class); /* * Verify results @@ -458,7 +383,6 @@ public void testStopWhenClosing() throws JMSException, InterruptedException { */ @Test public void testStopBlocksOnStateLock() throws InterruptedException, IllegalStateException { - /* * Set up the latches and mocks */ @@ -469,17 +393,14 @@ public void testStopBlocksOnStateLock() throws InterruptedException, IllegalStat sqsConnection.setRunning(true); // Run a thread to hold the stateLock - executorService.execute(new Runnable() { - @Override - public void run() { - try { - synchronized (sqsConnection.getStateLock()) { - holdStateLock.countDown(); - mainRelease.await(); - } - } catch (InterruptedException e) { - e.printStackTrace(); + executorService.execute(() -> { + try { + synchronized (sqsConnection.getStateLock()) { + holdStateLock.countDown(); + mainRelease.await(); } + } catch (InterruptedException e) { + e.printStackTrace(); } }); @@ -487,16 +408,13 @@ public void run() { holdStateLock.await(); // Run another thread that tries to start the connection while state lock is been held - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeConnectionStopCall.countDown(); - sqsConnection.stop(); - passedConnectionStopCall.countDown(); - } catch (JMSException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeConnectionStopCall.countDown(); + sqsConnection.stop(); + passedConnectionStopCall.countDown(); + } catch (JMSException e) { + e.printStackTrace(); } }); @@ -504,7 +422,7 @@ public void run() { Thread.sleep(10); // Ensure that we wait on state lock - assertEquals(false, passedConnectionStopCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedConnectionStopCall.await(2, TimeUnit.SECONDS)); // Release the thread holding the state lock mainRelease.countDown(); @@ -522,21 +440,17 @@ public void run() { */ @Test public void testStartNoOpIfAlreadyClosed() throws JMSException { - /* - * Set up conenction + * Set up connection */ sqsConnection.close(); /* * Start connection */ - try { - sqsConnection.start(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Connection is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.start()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Connection is closed"); /* * Verify results @@ -550,7 +464,6 @@ public void testStartNoOpIfAlreadyClosed() throws JMSException { */ @Test public void testStartNoOpIfClosing() throws JMSException { - /* * Set up session */ @@ -559,12 +472,9 @@ public void testStartNoOpIfClosing() throws JMSException { /* * Start connection */ - try { - sqsConnection.start(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Connection is closed or closing", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.start()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Connection is closed or closing"); /* * Verify results @@ -578,7 +488,6 @@ public void testStartNoOpIfClosing() throws JMSException { */ @Test public void testStartNoOpIfRunning() throws JMSException { - /* * Set up session */ @@ -601,7 +510,6 @@ public void testStartNoOpIfRunning() throws JMSException { */ @Test public void testStartBlocksOnStateLock() throws InterruptedException, IllegalStateException { - /* * Set up the latches and mocks */ @@ -611,17 +519,14 @@ public void testStartBlocksOnStateLock() throws InterruptedException, IllegalSta final CountDownLatch passedConnectionStartCall = new CountDownLatch(1); // Run a thread to hold the stateLock - executorService.execute(new Runnable() { - @Override - public void run() { - try { - synchronized (sqsConnection.getStateLock()) { - holdStateLock.countDown(); - mainRelease.await(); - } - } catch (InterruptedException e) { - e.printStackTrace(); + executorService.execute(() -> { + try { + synchronized (sqsConnection.getStateLock()) { + holdStateLock.countDown(); + mainRelease.await(); } + } catch (InterruptedException e) { + e.printStackTrace(); } }); @@ -629,16 +534,13 @@ public void run() { holdStateLock.await(); // Run another thread that tries to start the connection while state lock is been held - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeConnectionStartCall.countDown(); - sqsConnection.start(); - passedConnectionStartCall.countDown(); - } catch (JMSException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeConnectionStartCall.countDown(); + sqsConnection.start(); + passedConnectionStartCall.countDown(); + } catch (JMSException e) { + e.printStackTrace(); } }); @@ -646,7 +548,7 @@ public void run() { Thread.sleep(10); // Ensure that we wait on state lock - assertEquals(false, passedConnectionStartCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedConnectionStartCall.await(2, TimeUnit.SECONDS)); // Release the thread holding the state lock mainRelease.countDown(); @@ -664,7 +566,6 @@ public void run() { */ @Test public void testCreateSessionNoOpIfAlreadyClosed() throws JMSException { - /* * Set up connection */ @@ -673,19 +574,13 @@ public void testCreateSessionNoOpIfAlreadyClosed() throws JMSException { /* * Create session */ - try { - sqsConnection.createSession(true, 1); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Connection is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.createSession(true, 1)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Connection is closed"); - try { - sqsConnection.createSession(false, 1); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Connection is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.createSession(false, 1)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Connection is closed"); /* * Verify results @@ -699,20 +594,13 @@ public void testCreateSessionNoOpIfAlreadyClosed() throws JMSException { */ @Test public void testCreateSessionUnsupportedFeatures() throws JMSException { + assertThatThrownBy(() -> sqsConnection.createSession(true, Session.AUTO_ACKNOWLEDGE)) + .isInstanceOf(JMSException.class) + .hasMessage("SQSSession does not support transacted"); - try { - sqsConnection.createSession(true, Session.AUTO_ACKNOWLEDGE); - fail(); - } catch(JMSException ise) { - assertEquals("SQSSession does not support transacted", ise.getMessage()); - } - - try { - sqsConnection.createSession(false, Session.SESSION_TRANSACTED); - fail(); - } catch(JMSException ise) { - assertEquals("SQSSession does not support transacted", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.createSession(false, Session.SESSION_TRANSACTED)) + .isInstanceOf(JMSException.class) + .hasMessage("SQSSession does not support transacted"); /* * Verify results @@ -725,8 +613,7 @@ public void testCreateSessionUnsupportedFeatures() throws JMSException { * Test create session when connection is closing */ @Test - public void testCreateSessionWhenClosing() throws JMSException { - + public void testCreateSessionWhenClosing() { /* * Set up connection */ @@ -735,12 +622,9 @@ public void testCreateSessionWhenClosing() throws JMSException { /* * Start connection */ - try { - sqsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Connection is closed or closing", ise.getMessage()); - } + assertThatThrownBy(() -> sqsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Connection is closed or closing"); /* * Verify results @@ -752,17 +636,13 @@ public void testCreateSessionWhenClosing() throws JMSException { * Test create session */ @Test - public void testCreateSessionUnknownAckMode() throws JMSException { - + public void testCreateSessionUnknownAckMode() { /* - * Craete session + * Create session */ - try { - sqsConnection.createSession(false, 42); - } catch (JMSException jmse) { - assertEquals("Unrecognized acknowledgeMode. Cannot create Session.", jmse.getMessage()); - } - + assertThatThrownBy(() -> sqsConnection.createSession(false, 42)) + .isInstanceOf(JMSException.class) + .hasMessage("Unrecognized acknowledgeMode. Cannot create Session."); /* * Verify results @@ -775,10 +655,9 @@ public void testCreateSessionUnknownAckMode() throws JMSException { */ @Test public void testCreateSessionWhenConnectionRunning() throws JMSException { - sqsConnection.setRunning(true); - SQSSession session = (SQSSession)sqsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + SQSSession session = (SQSSession) sqsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); assertEquals(Session.AUTO_ACKNOWLEDGE, session.getAcknowledgeMode()); assertEquals(sqsConnection, session.getParentConnection()); assertTrue(sqsConnection.getSessions().contains(session)); @@ -797,7 +676,7 @@ public void testCreateSessionWhenConnectionRunning() throws JMSException { assertTrue(session.isRunning()); session = (SQSSession) sqsConnection.createSession(false, SQSSession.UNORDERED_ACKNOWLEDGE); - session.isRunning(); + assertTrue(session.isRunning()); assertEquals(SQSSession.UNORDERED_ACKNOWLEDGE, session.getAcknowledgeMode()); assertEquals(sqsConnection, session.getParentConnection()); assertTrue(sqsConnection.getSessions().contains(session)); @@ -814,10 +693,9 @@ public void testCreateSessionWhenConnectionRunning() throws JMSException { */ @Test public void testCreateSessionWhenConnectionStopped() throws JMSException { - sqsConnection.setRunning(false); - SQSSession session = (SQSSession)sqsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + SQSSession session = (SQSSession) sqsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); assertEquals(Session.AUTO_ACKNOWLEDGE, session.getAcknowledgeMode()); assertEquals(sqsConnection, session.getParentConnection()); assertTrue(sqsConnection.getSessions().contains(session)); @@ -836,7 +714,7 @@ public void testCreateSessionWhenConnectionStopped() throws JMSException { assertFalse(session.isRunning()); session = (SQSSession) sqsConnection.createSession(false, SQSSession.UNORDERED_ACKNOWLEDGE); - session.isRunning(); + assertFalse(session.isRunning()); assertEquals(SQSSession.UNORDERED_ACKNOWLEDGE, session.getAcknowledgeMode()); assertEquals(sqsConnection, session.getParentConnection()); assertTrue(sqsConnection.getSessions().contains(session)); @@ -852,8 +730,7 @@ public void testCreateSessionWhenConnectionStopped() throws JMSException { * Test CreateSession blocks on state lock */ @Test - public void testCreateSessionBlocksOnStateLock() throws InterruptedException, IllegalStateException { - + public void testCreateSessionBlocksOnStateLock() throws InterruptedException { /* * Set up the latches and mocks */ @@ -863,17 +740,14 @@ public void testCreateSessionBlocksOnStateLock() throws InterruptedException, Il final CountDownLatch passedCreateSessionStartCall = new CountDownLatch(1); // Run a thread to hold the stateLock - executorService.execute(new Runnable() { - @Override - public void run() { - try { - synchronized (sqsConnection.getStateLock()) { - holdStateLock.countDown(); - mainRelease.await(); - } - } catch (InterruptedException e) { - e.printStackTrace(); + executorService.execute(() -> { + try { + synchronized (sqsConnection.getStateLock()) { + holdStateLock.countDown(); + mainRelease.await(); } + } catch (InterruptedException e) { + e.printStackTrace(); } }); @@ -881,16 +755,13 @@ public void run() { holdStateLock.await(); // Run another thread that tries to start the connection while state lock is been held - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeCreateSessionStartCall.countDown(); - sqsConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE); - passedCreateSessionStartCall.countDown(); - } catch (JMSException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeCreateSessionStartCall.countDown(); + sqsConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE); + passedCreateSessionStartCall.countDown(); + } catch (JMSException e) { + e.printStackTrace(); } }); @@ -898,7 +769,7 @@ public void run() { Thread.sleep(10); // Ensure that we wait on state lock - assertEquals(false, passedCreateSessionStartCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedCreateSessionStartCall.await(2, TimeUnit.SECONDS)); assertEquals(2, sqsConnection.getSessions().size()); // Release the thread holding the state lock diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchFifoTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchFifoTest.java index d08e85c..32ffd29 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchFifoTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchFifoTest.java @@ -14,11 +14,6 @@ */ package com.amazon.sqs.javamessaging; -import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; -import com.amazon.sqs.javamessaging.SQSConnection; -import com.amazon.sqs.javamessaging.SQSMessageConsumerPrefetch; -import com.amazon.sqs.javamessaging.SQSQueueDestination; -import com.amazon.sqs.javamessaging.SQSSessionCallbackScheduler; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; import com.amazon.sqs.javamessaging.message.SQSBytesMessage; @@ -26,103 +21,52 @@ import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; import com.amazon.sqs.javamessaging.util.ExponentialBackoffStrategy; - -import software.amazon.awssdk.services.sqs.model.Message; +import jakarta.jms.JMSException; +import jakarta.jms.ObjectMessage; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import software.amazon.awssdk.services.sqs.model.*; import software.amazon.awssdk.services.sqs.model.Message.Builder; -import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; -import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; -import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; -import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; import software.amazon.awssdk.utils.BinaryUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Stream; -import javax.jms.JMSException; -import javax.jms.ObjectMessage; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.mockito.ArgumentMatcher; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.*; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test the SQSMessageConsumerPrefetchTest class */ -@RunWith(Parameterized.class) public class SQSMessageConsumerPrefetchFifoTest { private static final String NAMESPACE = "123456789012"; private static final String QUEUE_NAME = "QueueName.fifo"; - private static final String QUEUE_URL = NAMESPACE + "/" + QUEUE_NAME; + private static final String QUEUE_URL = NAMESPACE + "/" + QUEUE_NAME; - private Acknowledger acknowledger; private NegativeAcknowledger negativeAcknowledger; - private SQSSessionCallbackScheduler sqsSessionRunnable; private SQSMessageConsumerPrefetch consumerPrefetch; - private ExponentialBackoffStrategy backoffStrategy; private AmazonSQSMessagingClientWrapper amazonSQSClient; - @Parameters - public static List getParameters() { - return Arrays.asList(new Object[][] { {0}, {1}, {5}, {10}, {15} }); - } - - private final int numberOfMessagesToPrefetch; - - public SQSMessageConsumerPrefetchFifoTest(int numberOfMessagesToPrefetch) { - this.numberOfMessagesToPrefetch = numberOfMessagesToPrefetch; - } - - @Before - public void setup() { - - amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); - - SQSConnection parentSQSConnection = mock(SQSConnection.class); - when(parentSQSConnection.getWrappedAmazonSQSClient()).thenReturn(amazonSQSClient); - - sqsSessionRunnable = mock(SQSSessionCallbackScheduler.class); - - acknowledger = mock(Acknowledger.class); - - negativeAcknowledger = mock(NegativeAcknowledger.class); - - backoffStrategy = mock(ExponentialBackoffStrategy.class); - - SQSQueueDestination sqsDestination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL); - - consumerPrefetch = - spy(new SQSMessageConsumerPrefetch(sqsSessionRunnable, acknowledger, negativeAcknowledger, - sqsDestination, amazonSQSClient, numberOfMessagesToPrefetch)); - - consumerPrefetch.backoffStrategy = backoffStrategy; - } - /** * Test one full prefetch operation works as expected */ - @Test - public void testOneFullPrefetch() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testOneFullPrefetch(int numberOfMessagesToPrefetch) throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -138,22 +82,27 @@ public void testOneFullPrefetch() throws InterruptedException, JMSException { // Mock SQS call for receive message and return messages final int receiveMessageLimit = Math.min(10, numMessages); - when(amazonSQSClient.receiveMessage(argThat(new ArgumentMatcher() { - @Override - public boolean matches(Object argument) { - if (!(argument instanceof ReceiveMessageRequest)) - return false; - ReceiveMessageRequest other = (ReceiveMessageRequest)argument; - - return other.queueUrl().equals(QUEUE_URL) - && other.maxNumberOfMessages() == receiveMessageLimit - && other.messageAttributeNames().size() == 1 - && other.messageAttributeNames().get(0).equals(SQSMessageConsumerPrefetch.ALL) - && other.waitTimeSeconds() == SQSMessageConsumerPrefetch.WAIT_TIME_SECONDS - && other.receiveRequestAttemptId() != null - && other.receiveRequestAttemptId().length() > 0; - } - }))) + when(amazonSQSClient.receiveMessage(argThat(new BaseMatcher<>() { + + @Override + public void describeTo(Description description) { + + } + + @Override + public boolean matches(Object argument) { + if (!(argument instanceof ReceiveMessageRequest other)) + return false; + + return other.queueUrl().equals(QUEUE_URL) + && other.maxNumberOfMessages() == receiveMessageLimit + && other.messageAttributeNames().size() == 1 + && other.messageAttributeNames().get(0).equals(SQSMessageConsumerPrefetch.ALL) + && other.waitTimeSeconds() == SQSMessageConsumerPrefetch.WAIT_TIME_SECONDS + && other.receiveRequestAttemptId() != null + && other.receiveRequestAttemptId().length() > 0; + } + }))) .thenReturn(ReceiveMessageResponse.builder().messages(messages).build()); // Mock isClosed and exit after a single prefetch loop @@ -167,7 +116,7 @@ public boolean matches(Object argument) { * Request a message (only relevant when prefetching is off). */ consumerPrefetch.requestMessage(); - + /* * Run the prefetch */ @@ -184,7 +133,7 @@ public boolean matches(Object argument) { verify(consumerPrefetch).waitForPrefetch(); // Ensure no message was nack - verify(negativeAcknowledger).action(QUEUE_URL, new ArrayList()); + verify(negativeAcknowledger).action(QUEUE_URL, new ArrayList<>()); // Ensure retries attempt was not increased assertEquals(0, consumerPrefetch.retriesAttempted); @@ -194,29 +143,28 @@ public boolean matches(Object argument) { int index = 0; for (SQSMessageConsumerPrefetch.MessageManager messageManager : consumerPrefetch.messageQueue) { Message mockedMessage = messages.get(index); - SQSMessage sqsMessage = (SQSMessage)messageManager.getMessage(); - assertEquals( - "Receipt handle is the same", - mockedMessage.receiptHandle(), sqsMessage.getReceiptHandle()); + SQSMessage sqsMessage = (SQSMessage) messageManager.message(); + assertEquals(mockedMessage.receiptHandle(), sqsMessage.getReceiptHandle(), + "Receipt handle is the same"); assertEquals( - "Group id is the same", mockedMessage .attributes() .get(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.MESSAGE_GROUP_ID)), - sqsMessage.getStringProperty(SQSMessagingClientConstants.JMSX_GROUP_ID)); + sqsMessage.getStringProperty(SQSMessagingClientConstants.JMSX_GROUP_ID), + "Group id is the same"); assertEquals( - "Sequence number is the same", mockedMessage .attributes() .get(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.SEQUENCE_NUMBER)), - sqsMessage.getStringProperty(SQSMessagingClientConstants.JMS_SQS_SEQUENCE_NUMBER)); + sqsMessage.getStringProperty(SQSMessagingClientConstants.JMS_SQS_SEQUENCE_NUMBER), + "Sequence number is the same"); assertEquals( - "Deduplication id is the same", mockedMessage .attributes() .get(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID)), - sqsMessage.getStringProperty(SQSMessagingClientConstants.JMS_SQS_DEDUPLICATION_ID)); - + sqsMessage.getStringProperty(SQSMessagingClientConstants.JMS_SQS_DEDUPLICATION_ID), + "Deduplication id is the same"); + index++; } } @@ -224,19 +172,21 @@ public boolean matches(Object argument) { /** * Test ConvertToJMSMessage when message type is not set in the message attribute */ - @Test - public void testConvertToJMSMessageNoTypeAttribute() throws JMSException { + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageNoTypeAttribute(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - // Return message attribute with no message type attribute - Message message = createValidFifoMessage(1, "G").body("MessageBody").build(); + // Return message attribute with no message type attribute + Message message = createValidFifoMessage(1, "G").body("MessageBody").build(); /* * Convert the SQS message to JMS Message */ - javax.jms.Message jmsMessage = consumerPrefetch.convertToJMSMessage(message); + jakarta.jms.Message jmsMessage = consumerPrefetch.convertToJMSMessage(message); /* * Verify results @@ -251,39 +201,40 @@ public void testConvertToJMSMessageNoTypeAttribute() throws JMSException { /** * Test ConvertToJMSMessage with byte message type */ - @Test - public void testConvertToJMSMessageByteTypeAttribute() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageByteTypeAttribute(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - // Return message attributes with message type 'BYTE' - MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); - - HashMap messageAttributes = new HashMap<>(); - messageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - - byte[] byteArray = new byte[] { 1, 0, 'a', 65 }; - - Message message = createValidFifoMessage(1, "G") - .messageAttributes(messageAttributes) - .body(BinaryUtils.toBase64(byteArray)) - .build(); - + // Return message attributes with message type 'BYTE' + MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() + .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); + + Map messageAttributes = Map.of( + SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); + + byte[] byteArray = new byte[]{1, 0, 'a', 65}; + + Message message = createValidFifoMessage(1, "G") + .messageAttributes(messageAttributes) + .body(BinaryUtils.toBase64(byteArray)) + .build(); + /* * Convert the SQS message to JMS Message */ - javax.jms.Message jmsMessage = consumerPrefetch.convertToJMSMessage(message); + jakarta.jms.Message jmsMessage = consumerPrefetch.convertToJMSMessage(message); /* * Verify results */ assertTrue(jmsMessage instanceof SQSBytesMessage); for (byte b : byteArray) { - assertEquals(b, ((SQSBytesMessage)jmsMessage).readByte()); + assertEquals(b, ((SQSBytesMessage) jmsMessage).readByte()); } assertEquals(message.attributes().get(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID)), jmsMessage.getStringProperty(SQSMessagingClientConstants.JMS_SQS_DEDUPLICATION_ID)); assertEquals(message.attributes().get(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.SEQUENCE_NUMBER)), jmsMessage.getStringProperty(SQSMessagingClientConstants.JMS_SQS_SEQUENCE_NUMBER)); @@ -293,72 +244,71 @@ public void testConvertToJMSMessageByteTypeAttribute() throws JMSException, IOEx /** * Test ConvertToJMSMessage with byte message that contains illegal sqs message body */ - @Test - public void testConvertToJMSMessageByteTypeIllegalBody() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageByteTypeIllegalBody(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - // Return message attributes with message type 'BYTE' - MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); - - HashMap messageAttributes = new HashMap<>(); - messageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - - // Return illegal message body for byte message type - Message message = createValidFifoMessage(1, "G") - .body("Text Message") - .messageAttributes(messageAttributes) - .build(); + // Return message attributes with message type 'BYTE' + MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() + .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); + + Map messageAttributes = Map.of( + SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); + + // Return illegal message body for byte message type + Message message = createValidFifoMessage(1, "G") + .body("Text Message") + .messageAttributes(messageAttributes) + .build(); /* * Convert the SQS message to JMS Message */ - try { - consumerPrefetch.convertToJMSMessage(message); - fail("Expect JMSException"); - } catch (JMSException jmse) { - // Expected JMS exception - } + assertThatThrownBy(() -> consumerPrefetch.convertToJMSMessage(message)) + .isInstanceOf(JMSException.class); } /** * Test ConvertToJMSMessage with an object message */ - @Test - public void testConvertToJMSMessageObjectTypeAttribute() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageObjectTypeAttribute(int numberOfMessagesToPrefetch) + throws JMSException, IOException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - // Return message attributes with message type 'OBJECT' - MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); - - HashMap messageAttributes = new HashMap<>(); - messageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - - // Encode an object to byte array - Integer integer = Integer.valueOf(10); - ByteArrayOutputStream array = new ByteArrayOutputStream(10); - ObjectOutputStream oStream = new ObjectOutputStream(array); - oStream.writeObject(integer); - oStream.close(); - - Message message = createValidFifoMessage(1, "G") - .messageAttributes(messageAttributes) - .body(BinaryUtils.toBase64(array.toByteArray())) - .build(); + // Return message attributes with message type 'OBJECT' + MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() + .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); + + Map messageAttributes = Map.of( + SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); + + // Encode an object to byte array + Integer integer = 10; + ByteArrayOutputStream array = new ByteArrayOutputStream(10); + ObjectOutputStream oStream = new ObjectOutputStream(array); + oStream.writeObject(integer); + oStream.close(); + + Message message = createValidFifoMessage(1, "G") + .messageAttributes(messageAttributes) + .body(BinaryUtils.toBase64(array.toByteArray())) + .build(); /* * Convert the SQS message to JMS Message */ - javax.jms.Message jmsMessage = consumerPrefetch.convertToJMSMessage(message); + jakarta.jms.Message jmsMessage = consumerPrefetch.convertToJMSMessage(message); /* * Verify results @@ -373,25 +323,26 @@ public void testConvertToJMSMessageObjectTypeAttribute() throws JMSException, IO /** * Test ConvertToJMSMessage with an object message that contains illegal sqs message body */ - @Test - public void testConvertToJMSMessageObjectIllegalBody() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + void testConvertToJMSMessageObjectIllegalBody(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - // Return message attributes with message type 'OBJECT' - MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); - - HashMap messageAttributes = new HashMap<>(); - messageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - - Message message = createValidFifoMessage(1, "G") - .messageAttributes(messageAttributes) - .body("Some text that does not represent an object") - .build(); + // Return message attributes with message type 'OBJECT' + MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() + .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); + + Map messageAttributes = Map.of( + SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); + + Message message = createValidFifoMessage(1, "G") + .messageAttributes(messageAttributes) + .body("Some text that does not represent an object") + .build(); /* * Convert the SQS message to JMS Message @@ -401,41 +352,37 @@ public void testConvertToJMSMessageObjectIllegalBody() throws JMSException, IOEx /* * Verify results */ - try { - jmsMessage.getObject(); - fail("Expect JMSException"); - } catch (JMSException jmse) { - // Expected JMS exception - } + assertThatThrownBy(jmsMessage::getObject).isInstanceOf(JMSException.class); } /** * Test ConvertToJMSMessage with text message with text type attribute */ - @Test - public void testConvertToJMSMessageTextTypeAttribute() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageTextTypeAttribute(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - // Return message attributes with message type 'TEXT' - MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.TEXT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); - - HashMap messageAttributes = new HashMap<>(); - messageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - - Message message = createValidFifoMessage(1, "G") - .messageAttributes(messageAttributes) - .body("MessageBody") - .build(); - + // Return message attributes with message type 'TEXT' + MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() + .stringValue(SQSMessage.TEXT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); + + Map messageAttributes = Map.of( + SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); + + Message message = createValidFifoMessage(1, "G") + .messageAttributes(messageAttributes) + .body("MessageBody") + .build(); + /* * Convert the SQS message to JMS Message */ - javax.jms.Message jmsMessage = consumerPrefetch.convertToJMSMessage(message); + jakarta.jms.Message jmsMessage = consumerPrefetch.convertToJMSMessage(message); /* * Verify results @@ -452,15 +399,44 @@ public void testConvertToJMSMessageTextTypeAttribute() throws JMSException, IOEx */ private Builder createValidFifoMessage(int messageNumber, String groupId) { - Map mapAttributes = new HashMap(); - mapAttributes.put(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "1"); - mapAttributes.put(SQSMessagingClientConstants.SEQUENCE_NUMBER, "10000000000000000000" + messageNumber); - mapAttributes.put(SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID, "d" + messageNumber); - mapAttributes.put(SQSMessagingClientConstants.MESSAGE_GROUP_ID, groupId); - + Map mapAttributes = Map.of( + SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "1", + SQSMessagingClientConstants.SEQUENCE_NUMBER, "10000000000000000000" + messageNumber, + SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID, "d" + messageNumber, + SQSMessagingClientConstants.MESSAGE_GROUP_ID, groupId); + return Message.builder() - .receiptHandle("r" + messageNumber) - .attributesWithStrings(mapAttributes); + .receiptHandle("r" + messageNumber) + .attributesWithStrings(mapAttributes); + } + + private static Stream prefetchParameters() { + return Stream.of( + Arguments.of(0), + Arguments.of(1), + Arguments.of(5), + Arguments.of(10), + Arguments.of(15) + ); + } + + void init(int numberOfMessagesToPrefetch) { + amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); + + SQSConnection parentSQSConnection = mock(SQSConnection.class); + when(parentSQSConnection.getWrappedAmazonSQSClient()).thenReturn(amazonSQSClient); + + SQSSessionCallbackScheduler sqsSessionRunnable = mock(SQSSessionCallbackScheduler.class); + Acknowledger acknowledger = mock(Acknowledger.class); + negativeAcknowledger = mock(NegativeAcknowledger.class); + ExponentialBackoffStrategy backoffStrategy = mock(ExponentialBackoffStrategy.class); + SQSQueueDestination sqsDestination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL); + + consumerPrefetch = + spy(new SQSMessageConsumerPrefetch(sqsSessionRunnable, acknowledger, negativeAcknowledger, + sqsDestination, amazonSQSClient, numberOfMessagesToPrefetch)); + + consumerPrefetch.backoffStrategy = backoffStrategy; } } diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchTest.java index 2e48a46..5d34779 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchTest.java @@ -14,91 +14,49 @@ */ package com.amazon.sqs.javamessaging; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; +import com.amazon.sqs.javamessaging.SQSMessageConsumerPrefetch.MessageManager; +import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; +import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; +import com.amazon.sqs.javamessaging.message.SQSBytesMessage; +import com.amazon.sqs.javamessaging.message.SQSMessage; +import com.amazon.sqs.javamessaging.message.SQSObjectMessage; +import com.amazon.sqs.javamessaging.message.SQSTextMessage; +import com.amazon.sqs.javamessaging.util.ExponentialBackoffStrategy; +import jakarta.jms.JMSException; +import jakarta.jms.MessageListener; +import jakarta.jms.ObjectMessage; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.ArgumentCaptor; +import org.mockito.stubbing.Answer; +import software.amazon.awssdk.services.sqs.model.*; +import software.amazon.awssdk.utils.BinaryUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.IntStream; +import java.util.stream.Stream; -import javax.jms.JMSException; -import javax.jms.MessageListener; -import javax.jms.ObjectMessage; - -import org.joda.time.DateTime; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import com.amazon.sqs.javamessaging.SQSMessageConsumerPrefetch.MessageManager; -import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; -import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; -import com.amazon.sqs.javamessaging.message.SQSBytesMessage; -import com.amazon.sqs.javamessaging.message.SQSMessage; -import com.amazon.sqs.javamessaging.message.SQSObjectMessage; -import com.amazon.sqs.javamessaging.message.SQSTextMessage; -import com.amazon.sqs.javamessaging.util.ExponentialBackoffStrategy; - -import software.amazon.awssdk.services.sqs.model.Message; -import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; -import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; -import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; -import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; -import software.amazon.awssdk.utils.BinaryUtils; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; /** * Test the SQSMessageConsumerPrefetchTest class */ -@SuppressWarnings("unchecked") -@RunWith(Parameterized.class) public class SQSMessageConsumerPrefetchTest { private static final String NAMESPACE = "123456789012"; private static final String QUEUE_NAME = "QueueName"; - private static final String QUEUE_URL = NAMESPACE + "/" + QUEUE_NAME; - - @Parameters - public static List getParameters() { - return Arrays.asList(new Object[][] { {0}, {1}, {5}, {10}, {15} }); - } - - private final int numberOfMessagesToPrefetch; + private static final String QUEUE_URL = NAMESPACE + "/" + QUEUE_NAME; private Acknowledger acknowledger; private NegativeAcknowledger negativeAcknowledger; @@ -106,43 +64,16 @@ public static List getParameters() { private SQSMessageConsumerPrefetch consumerPrefetch; private ExponentialBackoffStrategy backoffStrategy; - private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); private AmazonSQSMessagingClientWrapper amazonSQSClient; - public SQSMessageConsumerPrefetchTest(int numberOfMessagesToPrefetch) { - this.numberOfMessagesToPrefetch = numberOfMessagesToPrefetch; - } - - @Before - public void setup() { - - amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); - - SQSConnection parentSQSConnection = mock(SQSConnection.class); - when(parentSQSConnection.getWrappedAmazonSQSClient()).thenReturn(amazonSQSClient); - - sqsSessionRunnable = mock(SQSSessionCallbackScheduler.class); - - acknowledger = mock(Acknowledger.class); - - negativeAcknowledger = mock(NegativeAcknowledger.class); - - backoffStrategy = mock(ExponentialBackoffStrategy.class); - - SQSQueueDestination sqsDestination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL); - - consumerPrefetch = spy(new SQSMessageConsumerPrefetch(sqsSessionRunnable, acknowledger, negativeAcknowledger, - sqsDestination, amazonSQSClient, numberOfMessagesToPrefetch)); - - consumerPrefetch.backoffStrategy = backoffStrategy; - } - /** * Test one full prefetch operation works as expected */ - @Test - public void testEndToEnd() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testEndToEnd(int numberOfMessagesToPrefetch) throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -152,10 +83,7 @@ public void testEndToEnd() throws InterruptedException, JMSException { // Create messages return from SQS final int numMessages = numberOfMessagesToPrefetch > 0 ? numberOfMessagesToPrefetch : 1; - final List receipt = new ArrayList(); - for (int i = 0; i < numMessages; ++i) { - receipt.add("r" + i); - } + final List receipt = createReceiptHandlersList(numMessages); ReceiveMessageResponse receivedMessageResult = createReceiveMessageResult(receipt); // Mock SQS call for receive message and return messages @@ -174,27 +102,23 @@ public void testEndToEnd() throws InterruptedException, JMSException { .thenReturn(false) .thenReturn(false) .thenReturn(false) - .thenAnswer(new Answer() { - - @Override - public Boolean answer(InvocationOnMock invocation) throws Throwable { - // Ensure message queue was filled with expected messages - //after we return 'isClosed() == true' we will empty the prefetch queue while nacking messages - assertEquals(numMessages, consumerPrefetch.messageQueue.size()); - for (SQSMessageConsumerPrefetch.MessageManager messageManager : consumerPrefetch.messageQueue) { - SQSMessage sqsMessage = (SQSMessage)messageManager.getMessage(); - assertTrue(receipt.contains(sqsMessage.getReceiptHandle())); - } - - return true; + .thenAnswer((Answer) invocation -> { + // Ensure message queue was filled with expected messages + //after we return 'isClosed() == true' we will empty the prefetch queue while nacking messages + assertEquals(numMessages, consumerPrefetch.messageQueue.size()); + for (MessageManager messageManager : consumerPrefetch.messageQueue) { + SQSMessage sqsMessage = (SQSMessage) messageManager.message(); + assertTrue(receipt.contains(sqsMessage.getReceiptHandle())); } + + return true; }); /* * Request a message (only relevant when prefetching is off). */ consumerPrefetch.requestMessage(); - + /* * Run the prefetch */ @@ -211,7 +135,7 @@ public Boolean answer(InvocationOnMock invocation) throws Throwable { verify(consumerPrefetch).waitForPrefetch(); // Ensure no message was nack - verify(negativeAcknowledger).action(QUEUE_URL, new ArrayList()); + verify(negativeAcknowledger).action(QUEUE_URL, new ArrayList<>()); // Ensure retries attempt was not increased assertEquals(0, consumerPrefetch.retriesAttempted); @@ -219,7 +143,7 @@ public Boolean answer(InvocationOnMock invocation) throws Throwable { // Ensure message queue was filled with expected messages assertEquals(numMessages, consumerPrefetch.messageQueue.size()); for (SQSMessageConsumerPrefetch.MessageManager messageManager : consumerPrefetch.messageQueue) { - SQSMessage sqsMessage = (SQSMessage)messageManager.getMessage(); + SQSMessage sqsMessage = (SQSMessage) messageManager.message(); assertTrue(receipt.contains(sqsMessage.getReceiptHandle())); } } @@ -227,9 +151,11 @@ public Boolean answer(InvocationOnMock invocation) throws Throwable { /** * Test that a get message is not called when consumer is closed while waiting for prefetch */ - @Test - public void testStopWhenConsumerClosedDuringWaitForPrefetch() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStopWhenConsumerClosedDuringWaitForPrefetch(int numberOfMessagesToPrefetch) + throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -266,7 +192,7 @@ public void testStopWhenConsumerClosedDuringWaitForPrefetch() throws Interrupted verify(consumerPrefetch, never()).getMessages(anyInt(), anyInt()); // Ensure we do not process any messages - verify(consumerPrefetch, never()).processReceivedMessages(any(List.class)); + verify(consumerPrefetch, never()).processReceivedMessages(anyList()); // Ensure retries attempt was not increased assertEquals(0, consumerPrefetch.retriesAttempted); @@ -275,16 +201,17 @@ public void testStopWhenConsumerClosedDuringWaitForPrefetch() throws Interrupted /** * Test prefetch is stopped after Interrupt in waitForStart */ - @Test - public void testStopAfterInterruptWaitForStart() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStopAfterInterruptWaitForStart(int numberOfMessagesToPrefetch) + throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ consumerPrefetch.start(); - doThrow(new InterruptedException("Interrupt")) - .when(consumerPrefetch).waitForStart(); + doThrow(new InterruptedException("Interrupt")).when(consumerPrefetch).waitForStart(); /* * Run the prefetch @@ -300,7 +227,7 @@ public void testStopAfterInterruptWaitForStart() throws InterruptedException, JM verify(consumerPrefetch, never()).waitForPrefetch(); verify(consumerPrefetch, never()).getMessages(anyInt(), anyInt()); - verify(consumerPrefetch, never()).processReceivedMessages(any(List.class)); + verify(consumerPrefetch, never()).processReceivedMessages(anyList()); // Ensure retries attempt was not increased assertEquals(0, consumerPrefetch.retriesAttempted); @@ -309,26 +236,22 @@ public void testStopAfterInterruptWaitForStart() throws InterruptedException, JM /** * Test prefetch is stopped after Error in waitForStart */ - @Test - public void testStopAfterErrorWaitForStart() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStopAfterErrorWaitForStart(int numberOfMessagesToPrefetch) + throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ consumerPrefetch.start(); - doThrow(new Error("error")) - .when(consumerPrefetch).waitForStart(); + doThrow(new Error("error")).when(consumerPrefetch).waitForStart(); /* * Run the prefetch */ - try { - consumerPrefetch.run(); - fail("expect exception"); - } catch (RuntimeException e) { - // Expected exception - } + assertThatThrownBy(() -> consumerPrefetch.run()).isInstanceOf(RuntimeException.class); /* * Verify the results @@ -339,7 +262,7 @@ public void testStopAfterErrorWaitForStart() throws InterruptedException, JMSExc verify(consumerPrefetch, never()).waitForPrefetch(); verify(consumerPrefetch, never()).getMessages(anyInt(), anyInt()); - verify(consumerPrefetch, never()).processReceivedMessages(any(List.class)); + verify(consumerPrefetch, never()).processReceivedMessages(anyList()); // Ensure retries attempt was not increased assertEquals(0, consumerPrefetch.retriesAttempted); @@ -348,9 +271,11 @@ public void testStopAfterErrorWaitForStart() throws InterruptedException, JMSExc /** * Test prefetch is stopped after Interrupt in waitForPrefetch */ - @Test - public void testStopAfterInterruptWaitForPrefetch() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStopAfterInterruptWaitForPrefetch(int numberOfMessagesToPrefetch) + throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -375,7 +300,7 @@ public void testStopAfterInterruptWaitForPrefetch() throws InterruptedException, verify(consumerPrefetch).nackQueueMessages(); verify(consumerPrefetch, never()).getMessages(anyInt(), anyInt()); - verify(consumerPrefetch, never()).processReceivedMessages(any(List.class)); + verify(consumerPrefetch, never()).processReceivedMessages(anyList()); // Ensure retries attempt was not increased assertEquals(0, consumerPrefetch.retriesAttempted); @@ -384,9 +309,11 @@ public void testStopAfterInterruptWaitForPrefetch() throws InterruptedException, /** * Test prefetch is stopped after Error in waitForPrefetch */ - @Test - public void testStopAfterErrorWaitForPrefetch() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStopAfterErrorWaitForPrefetch(int numberOfMessagesToPrefetch) + throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -400,12 +327,7 @@ public void testStopAfterErrorWaitForPrefetch() throws InterruptedException, JMS /* * Run the prefetch */ - try { - consumerPrefetch.run(); - fail("expect error"); - } catch (RuntimeException e) { - // Expected exception - } + assertThatThrownBy(() -> consumerPrefetch.run()).isInstanceOf(RuntimeException.class); /* * Verify the results @@ -416,7 +338,7 @@ public void testStopAfterErrorWaitForPrefetch() throws InterruptedException, JMS verify(consumerPrefetch).nackQueueMessages(); verify(consumerPrefetch, never()).getMessages(anyInt(), anyInt()); - verify(consumerPrefetch, never()).processReceivedMessages(any(List.class)); + verify(consumerPrefetch, never()).processReceivedMessages(anyList()); // Ensure retries attempt was not increased assertEquals(0, consumerPrefetch.retriesAttempted); @@ -425,9 +347,10 @@ public void testStopAfterErrorWaitForPrefetch() throws InterruptedException, JMS /** * Test prefetch is stopped after Interrupt in getMessages */ - @Test - public void testStopAfterInterruptGetMessages() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStopAfterInterruptGetMessages(int numberOfMessagesToPrefetch) throws InterruptedException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -454,7 +377,7 @@ public void testStopAfterInterruptGetMessages() throws InterruptedException, JMS verify(consumerPrefetch).nackQueueMessages(); verify(consumerPrefetch).getMessagesWithBackoff(anyInt()); - verify(consumerPrefetch, never()).processReceivedMessages(any(List.class)); + verify(consumerPrefetch, never()).processReceivedMessages(anyList()); // Ensure retries attempt was not increased assertEquals(0, consumerPrefetch.retriesAttempted); @@ -463,9 +386,11 @@ public void testStopAfterInterruptGetMessages() throws InterruptedException, JMS /** * Test prefetch is stopped after Error in waitForPrefetch */ - @Test - public void testStopAfterErrorGetMessages() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStopAfterErrorGetMessages(int numberOfMessagesToPrefetch) + throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -481,12 +406,7 @@ public void testStopAfterErrorGetMessages() throws InterruptedException, JMSExce /* * Run the prefetch */ - try { - consumerPrefetch.run(); - fail("expect error"); - } catch (RuntimeException e) { - // Expected exception - } + assertThatThrownBy(() -> consumerPrefetch.run()).isInstanceOf(RuntimeException.class); /* * Verify the results @@ -497,7 +417,7 @@ public void testStopAfterErrorGetMessages() throws InterruptedException, JMSExce verify(consumerPrefetch).nackQueueMessages(); verify(consumerPrefetch).getMessages(anyInt(), anyInt()); - verify(consumerPrefetch, never()).processReceivedMessages(any(List.class)); + verify(consumerPrefetch, never()).processReceivedMessages(anyList()); // Ensure retries attempt was not increased assertEquals(0, consumerPrefetch.retriesAttempted); @@ -506,9 +426,10 @@ public void testStopAfterErrorGetMessages() throws InterruptedException, JMSExce /** * Test Run when consumer is closed */ - @Test - public void testRunExitOnClose() { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testRunExitOnClose(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); consumerPrefetch.close(); /* @@ -522,9 +443,10 @@ public void testRunExitOnClose() { /** * Test SetMessageListener to Null */ - @Test - public void testSetNullMessageListener() { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testSetNullMessageListener(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); consumerPrefetch.setMessageListener(null); verifyNoMoreInteractions(sqsSessionRunnable); } @@ -532,18 +454,12 @@ public void testSetNullMessageListener() { /** * Test SetMessageListener when message were prefetched */ - @Test - public void testSetMessageListener() { - - SQSMessageConsumerPrefetch.MessageManager msgManager1 = mock(SQSMessageConsumerPrefetch.MessageManager.class); - javax.jms.Message message1 = mock(javax.jms.Message.class); - when(msgManager1.getMessage()) - .thenReturn(message1); - - SQSMessageConsumerPrefetch.MessageManager msgManager2 = mock(SQSMessageConsumerPrefetch.MessageManager.class); - javax.jms.Message message2 = mock(javax.jms.Message.class); - when(msgManager2.getMessage()) - .thenReturn(message2); + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testSetMessageListener(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); + SQSMessageConsumerPrefetch.MessageManager msgManager1 = new SQSMessageConsumerPrefetch.MessageManager(null, mock(jakarta.jms.Message.class)); + SQSMessageConsumerPrefetch.MessageManager msgManager2 = new SQSMessageConsumerPrefetch.MessageManager(null, mock(jakarta.jms.Message.class)); consumerPrefetch.messageQueue.add(msgManager1); consumerPrefetch.messageQueue.add(msgManager2); @@ -551,12 +467,10 @@ public void testSetMessageListener() { MessageListener msgListener = mock(MessageListener.class); consumerPrefetch.running = true; consumerPrefetch.setMessageListener(msgListener); - + assertTrue(consumerPrefetch.messageQueue.isEmpty()); - List expectedList = new ArrayList(); - expectedList.add(msgManager1); - expectedList.add(msgManager2); + List expectedList = List.of(msgManager1, msgManager2); verify(sqsSessionRunnable).scheduleCallBacks(msgListener, expectedList); verifyNoMoreInteractions(sqsSessionRunnable); @@ -565,9 +479,10 @@ public void testSetMessageListener() { /** * Test getting message listener */ - @Test - public void testGetMessageListener() { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testGetMessageListener(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); MessageListener msgListener = mock(MessageListener.class); consumerPrefetch.setMessageListener(msgListener); @@ -575,11 +490,12 @@ public void testGetMessageListener() { } /** - * Test WaitForStart when preftech already started + * Test WaitForStart when prefetch already started */ - @Test - public void testWaitForStartCurrentStateStart() throws javax.jms.IllegalStateException, InterruptedException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testWaitForStartCurrentStateStart(int numberOfMessagesToPrefetch) throws InterruptedException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -589,32 +505,30 @@ public void testWaitForStartCurrentStateStart() throws javax.jms.IllegalStateExc /* * call waitForStart in different thread */ - executorService.execute(new Runnable() { - @Override - public void run() { - try { - consumerPrefetch.waitForStart(); + executorService.execute(() -> { + try { + consumerPrefetch.waitForStart(); - // Indicate that we no longer waiting - passedWaitForStartCall.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + // Indicate that we no longer waiting + passedWaitForStartCall.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); } }); /* * verify result */ - assertEquals(true, passedWaitForStartCall.await(10, TimeUnit.SECONDS)); + assertTrue(passedWaitForStartCall.await(10, TimeUnit.SECONDS)); } /** * Test WaitForStart when preftech already closed */ - @Test - public void testWaitForStartCurrentStateClose() throws javax.jms.IllegalStateException, InterruptedException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testWaitForStartCurrentStateClose(int numberOfMessagesToPrefetch) throws InterruptedException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -624,33 +538,31 @@ public void testWaitForStartCurrentStateClose() throws javax.jms.IllegalStateExc /* * call waitForStart in different thread */ - executorService.execute(new Runnable() { - @Override - public void run() { - try { - consumerPrefetch.waitForStart(); + executorService.execute(() -> { + try { + consumerPrefetch.waitForStart(); - // Indicate that we no longer waiting - passedWaitForStartCall.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + // Indicate that we no longer waiting + passedWaitForStartCall.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); } }); /* * verify result */ - assertEquals(true, passedWaitForStartCall.await(10, TimeUnit.SECONDS)); + assertTrue(passedWaitForStartCall.await(10, TimeUnit.SECONDS)); } /** - * Test WaitForStart when preftech state is updated to started while another thread is waiting + * Test WaitForStart when prefetch state is updated to started while another thread is waiting * for the prefetch to start */ - @Test - public void testWaitForStartUpdateStateToStart() throws javax.jms.IllegalStateException, InterruptedException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testWaitForStartUpdateStateToStart(int numberOfMessagesToPrefetch) throws InterruptedException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -660,21 +572,18 @@ public void testWaitForStartUpdateStateToStart() throws javax.jms.IllegalStateEx /* * call waitForStart in different thread */ - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeWaitForStartCall.countDown(); - consumerPrefetch.waitForStart(); - passedWaitForStart.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeWaitForStartCall.countDown(); + consumerPrefetch.waitForStart(); + passedWaitForStart.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); } }); // Yield execution to allow the consumer to wait - assertEquals(true, beforeWaitForStartCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeWaitForStartCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Update the state and notify @@ -685,15 +594,16 @@ public void run() { */ // Ensure consumer is not waiting to move to start state - assertEquals(false, passedWaitForStart.await(10, TimeUnit.SECONDS)); + assertFalse(passedWaitForStart.await(10, TimeUnit.SECONDS)); } /** * Test WaitForStart when waiting thread is interrupted */ - @Test - public void testWaitForStartInterrupted() throws javax.jms.IllegalStateException, InterruptedException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testWaitForStartInterrupted(int numberOfMessagesToPrefetch) throws InterruptedException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -703,23 +613,20 @@ public void testWaitForStartInterrupted() throws javax.jms.IllegalStateException /* * call waitForStart in different thread */ - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - beforeWaitForStartCall.countDown(); - consumerPrefetch.waitForStart(); - } catch (InterruptedException e) { - recvInterruptedExceptionLatch.countDown(); - e.printStackTrace(); - } + Thread t = new Thread(() -> { + try { + beforeWaitForStartCall.countDown(); + consumerPrefetch.waitForStart(); + } catch (InterruptedException e) { + recvInterruptedExceptionLatch.countDown(); + e.printStackTrace(); } }); t.start(); // Yield execution to allow the consumer to wait - assertEquals(true, beforeWaitForStartCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeWaitForStartCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Interrupt waiting thread @@ -728,15 +635,16 @@ public void run() { /* * verify result */ - assertEquals(true, recvInterruptedExceptionLatch.await(10, TimeUnit.SECONDS)); + assertTrue(recvInterruptedExceptionLatch.await(10, TimeUnit.SECONDS)); } /** * Test WaitForPrefetch and ensure that message are not prefetch when limit has already reached */ - @Test - public void testWaitForPrefetchLimitReached() throws InterruptedException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testWaitForPrefetchLimitReached(int numberOfMessagesToPrefetch) throws InterruptedException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -747,41 +655,39 @@ public void testWaitForPrefetchLimitReached() throws InterruptedException { /* * call waitForPrefetch in different thread */ - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeWaitForPrefetchCall.countDown(); - consumerPrefetch.waitForPrefetch(); - passedWaitForPrefetch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeWaitForPrefetchCall.countDown(); + consumerPrefetch.waitForPrefetch(); + passedWaitForPrefetch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); } }); // Yield execution to allow the consumer to wait - assertEquals(true, beforeWaitForPrefetchCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeWaitForPrefetchCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Release the local and ensure that we are still waiting since the prefetch message still equal to the limit consumerPrefetch.notifyStateChange(); - assertEquals(false, passedWaitForPrefetch.await(3, TimeUnit.SECONDS)); + assertFalse(passedWaitForPrefetch.await(3, TimeUnit.SECONDS)); // Simulate messages were processes consumerPrefetch.messagesPrefetched = numberOfMessagesToPrefetch - 1; // Release the local and ensure that we no longer waiting since the prefetch message is below the limit consumerPrefetch.notifyStateChange(); - assertEquals(true, passedWaitForPrefetch.await(3, TimeUnit.SECONDS)); + assertTrue(passedWaitForPrefetch.await(3, TimeUnit.SECONDS)); } /** * Test WaitForPrefetch when prefetch consumer is closed */ - @Test - public void testWaitForPrefetchIsClosed() throws InterruptedException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testWaitForPrefetchIsClosed(int numberOfMessagesToPrefetch) throws InterruptedException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -791,33 +697,31 @@ public void testWaitForPrefetchIsClosed() throws InterruptedException { final CountDownLatch beforeWaitForPrefetchCall = new CountDownLatch(1); final CountDownLatch passedWaitForPrefetch = new CountDownLatch(1); - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeWaitForPrefetchCall.countDown(); - consumerPrefetch.waitForPrefetch(); - passedWaitForPrefetch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeWaitForPrefetchCall.countDown(); + consumerPrefetch.waitForPrefetch(); + passedWaitForPrefetch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); } }); // Yield execution to allow the consumer to wait - assertEquals(true, beforeWaitForPrefetchCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeWaitForPrefetchCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Validate we do not wait when the consumer is closed - assertEquals(true, passedWaitForPrefetch.await(3, TimeUnit.SECONDS)); + assertTrue(passedWaitForPrefetch.await(3, TimeUnit.SECONDS)); } /** * Test WaitForPrefetch when waiting thread is interrupted */ - @Test - public void testWaitForPrefetchInterrupted() throws InterruptedException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testWaitForPrefetchInterrupted(int numberOfMessagesToPrefetch) throws InterruptedException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -825,52 +729,50 @@ public void testWaitForPrefetchInterrupted() throws InterruptedException { final CountDownLatch beforeWaitForPrefetchCall = new CountDownLatch(1); final CountDownLatch recvInterruptedExceptionLatch = new CountDownLatch(1); - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - beforeWaitForPrefetchCall.countDown(); - consumerPrefetch.waitForPrefetch(); - } catch (InterruptedException e) { - recvInterruptedExceptionLatch.countDown(); - e.printStackTrace(); - } + Thread t = new Thread(() -> { + try { + beforeWaitForPrefetchCall.countDown(); + consumerPrefetch.waitForPrefetch(); + } catch (InterruptedException e) { + recvInterruptedExceptionLatch.countDown(); + e.printStackTrace(); } }); t.start(); - assertEquals(true, beforeWaitForPrefetchCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeWaitForPrefetchCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); t.interrupt(); // Validate that we no longer waiting due to the interrupt - assertEquals(true, recvInterruptedExceptionLatch.await(10, TimeUnit.SECONDS)); + assertTrue(recvInterruptedExceptionLatch.await(10, TimeUnit.SECONDS)); } /** * Test ConvertToJMSMessage when message type is not set in the message attribute */ - @Test - public void testConvertToJMSMessageNoTypeAttribute() throws JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageNoTypeAttribute(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - Map mapAttributes = new HashMap<>(); - mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + Map mapAttributes = Map.of( + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); Message message = Message.builder() - .messageAttributes(new HashMap()) - .attributes(mapAttributes) - .body("MessageBody") - .build(); + .messageAttributes(new HashMap<>()) + .attributes(mapAttributes) + .body("MessageBody") + .build(); /* * Convert the SQS message to JMS Message */ - javax.jms.Message jsmMessage = consumerPrefetch.convertToJMSMessage(message); + jakarta.jms.Message jsmMessage = consumerPrefetch.convertToJMSMessage(message); /* * Verify results @@ -882,105 +784,105 @@ public void testConvertToJMSMessageNoTypeAttribute() throws JMSException { /** * Test ConvertToJMSMessage with byte message type */ - @Test - public void testConvertToJMSMessageByteTypeAttribute() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageByteTypeAttribute(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - Map mapMessageAttributes = new HashMap(); - MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); + Map mapMessageAttributes = new HashMap<>(); + MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() + .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - Map mapAttributes = new HashMap<>(); - mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); - - byte[] byteArray = new byte[] { 1, 0, 'a', 65 }; + Map mapAttributes = Map.of( + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + + byte[] byteArray = new byte[]{1, 0, 'a', 65}; Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body(BinaryUtils.toBase64(byteArray)) - .build(); + .messageAttributes(mapMessageAttributes) + .attributes(mapAttributes) + .body(BinaryUtils.toBase64(byteArray)) + .build(); /* * Convert the SQS message to JMS Message */ - javax.jms.Message jsmMessage = consumerPrefetch.convertToJMSMessage(message); + jakarta.jms.Message jsmMessage = consumerPrefetch.convertToJMSMessage(message); /* * Verify results */ assertTrue(jsmMessage instanceof SQSBytesMessage); for (byte b : byteArray) { - assertEquals(b, ((SQSBytesMessage)jsmMessage).readByte()); + assertEquals(b, ((SQSBytesMessage) jsmMessage).readByte()); } } /** * Test ConvertToJMSMessage with byte message that contains illegal sqs message body */ - @Test - public void testConvertToJMSMessageByteTypeIllegalBody() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageByteTypeIllegalBody(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - Map mapMessageAttributes = new HashMap(); + Map mapMessageAttributes = new HashMap<>(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); + .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - Map mapAttributes = new HashMap<>(); - mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + Map mapAttributes = Map.of( + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); // Return message attributes with message type 'BYTE' // Return illegal message body for byte message type Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body("Text Message") - .build(); + .messageAttributes(mapMessageAttributes) + .attributes(mapAttributes) + .body("Text Message") + .build(); /* * Convert the SQS message to JMS Message */ - try { - consumerPrefetch.convertToJMSMessage(message); - fail("Expect JMSException"); - } catch (JMSException jmse) { - // Expected JMS exception - } + assertThatThrownBy(() -> consumerPrefetch.convertToJMSMessage(message)) + .isInstanceOf(JMSException.class); } /** * Test ConvertToJMSMessage with an object message */ - @Test - public void testConvertToJMSMessageObjectTypeAttribute() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageObjectTypeAttribute(int numberOfMessagesToPrefetch) + throws JMSException, IOException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - Map mapMessageAttributes = new HashMap(); + Map mapMessageAttributes = new HashMap<>(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); + .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - Map mapAttributes = new HashMap<>(); - mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + Map mapAttributes = Map.of( + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); // Encode an object to byte array Integer integer = Integer.valueOf("10"); @@ -989,18 +891,18 @@ public void testConvertToJMSMessageObjectTypeAttribute() throws JMSException, IO oStream.writeObject(integer); oStream.close(); - + // Return message attributes with message type 'OBJECT' - Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body(BinaryUtils.toBase64(array.toByteArray())) - .build(); + Message message = Message.builder() + .messageAttributes(mapMessageAttributes) + .attributes(mapAttributes) + .body(BinaryUtils.toBase64(array.toByteArray())) + .build(); /* * Convert the SQS message to JMS Message */ - javax.jms.Message jsmMessage = consumerPrefetch.convertToJMSMessage(message); + jakarta.jms.Message jsmMessage = consumerPrefetch.convertToJMSMessage(message); /* * Verify results @@ -1012,30 +914,31 @@ public void testConvertToJMSMessageObjectTypeAttribute() throws JMSException, IO /** * Test ConvertToJMSMessage with an object message that contains illegal sqs message body */ - @Test - public void testConvertToJMSMessageObjectIllegalBody() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageObjectIllegalBody(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - Map mapMessageAttributes = new HashMap(); + Map mapMessageAttributes = new HashMap<>(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); + .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - Map mapAttributes = new HashMap<>(); - mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + Map mapAttributes = Map.of( + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); // Return message attributes with message type 'OBJECT' Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body("Some text that does not represent an object") - .build(); + .messageAttributes(mapMessageAttributes) + .attributes(mapAttributes) + .body("Some text that does not represent an object") + .build(); /* * Convert the SQS message to JMS Message @@ -1045,71 +948,68 @@ public void testConvertToJMSMessageObjectIllegalBody() throws JMSException, IOEx /* * Verify results */ - try { - jsmMessage.getObject(); - fail("Expect JMSException"); - } catch (JMSException jmse) { - // Expected JMS exception - } + assertThatThrownBy(jsmMessage::getObject).isInstanceOf(JMSException.class); } /** * Test ConvertToJMSMessage with text message with text type attribute */ - @Test - public void testConvertToJMSMessageTextTypeAttribute() throws JMSException, IOException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testConvertToJMSMessageTextTypeAttribute(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ - Map mapMessageAttributes = new HashMap(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.TEXT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); - mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - Map mapAttributes = new HashMap(); - mapAttributes.put(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "1"); - Long now = DateTime.now().getMillis(); - mapAttributes.put(SQSMessagingClientConstants.SENT_TIMESTAMP, now.toString()); + .stringValue(SQSMessage.TEXT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); + Map mapMessageAttributes = Map.of( + SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); + long now = System.currentTimeMillis(); + Map mapAttributes = Map.of( + SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "1", + SQSMessagingClientConstants.SENT_TIMESTAMP, Long.toString(now)); // Return message attributes with message type 'TEXT' Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributesWithStrings(mapAttributes) - .body("MessageBody") - .build(); + .messageAttributes(mapMessageAttributes) + .attributesWithStrings(mapAttributes) + .body("MessageBody") + .build(); /* * Convert the SQS message to JMS Message */ - javax.jms.Message jsmMessage = consumerPrefetch.convertToJMSMessage(message); + jakarta.jms.Message jsmMessage = consumerPrefetch.convertToJMSMessage(message); /* * Verify results */ assertTrue(jsmMessage instanceof SQSTextMessage); assertEquals(message.body(), "MessageBody"); - assertEquals(jsmMessage.getJMSTimestamp(), now.longValue()); + assertEquals(jsmMessage.getJMSTimestamp(), now); } /** * Test received messages when consumer prefetch has not started */ - @Test - public void testReceiveWhenNotStarted() throws JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testReceiveWhenNotStarted(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); consumerPrefetch.running = false; assertNull(consumerPrefetch.receive()); // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); - + assertNull(consumerPrefetch.receive(100)); // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); - + assertNull(consumerPrefetch.receiveNoWait()); // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); @@ -1118,19 +1018,20 @@ public void testReceiveWhenNotStarted() throws JMSException { /** * Test received messages when consumer prefetch has is closed */ - @Test - public void testReceiveWhenClosed() throws JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testReceiveWhenClosed(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); consumerPrefetch.closed = true; assertNull(consumerPrefetch.receive()); // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); - + assertNull(consumerPrefetch.receive(100)); // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); - + assertNull(consumerPrefetch.receiveNoWait()); // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); @@ -1139,9 +1040,10 @@ public void testReceiveWhenClosed() throws JMSException { /** * Test received messages */ - @Test - public void testReceiveMessagePrefetch() throws JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testReceiveMessagePrefetch(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -1154,15 +1056,15 @@ public void testReceiveMessagePrefetch() throws JMSException { /* * Call receive messages */ - SQSMessage msg = (SQSMessage)consumerPrefetch.receive(); + SQSMessage msg = (SQSMessage) consumerPrefetch.receive(); /* * Verify results */ - receiptHandlers.contains(msg.getReceiptHandle()); + assertTrue(receiptHandlers.contains(msg.getReceiptHandle())); verify(acknowledger).notifyMessageReceived(msg); verify(consumerPrefetch, times(2)).notifyStateChange(); - + // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); } @@ -1170,9 +1072,10 @@ public void testReceiveMessagePrefetch() throws JMSException { /** * Test received messages */ - @Test - public void testReceiveNoWaitPrefetch() throws JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testReceiveNoWaitPrefetch(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and mocks */ @@ -1185,15 +1088,15 @@ public void testReceiveNoWaitPrefetch() throws JMSException { /* * Call receive messages */ - SQSMessage msg = (SQSMessage)consumerPrefetch.receiveNoWait(); + SQSMessage msg = (SQSMessage) consumerPrefetch.receiveNoWait(); /* * Verify results */ - receiptHandlers.contains(msg.getReceiptHandle()); + assertTrue(receiptHandlers.contains(msg.getReceiptHandle())); verify(acknowledger).notifyMessageReceived(msg); verify(consumerPrefetch, times(2)).notifyStateChange(); - + // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); } @@ -1201,11 +1104,12 @@ public void testReceiveNoWaitPrefetch() throws JMSException { /** * Test received messages call wait for messages and exists when consumer prefterch is closed */ - @Test - public void testReceiveMessageEmptyThenClosed() throws InterruptedException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testReceiveMessageEmptyThenClosed(int numberOfMessagesToPrefetch) throws InterruptedException { + init(numberOfMessagesToPrefetch); /* - * Set up consumer prefetch and lactches + * Set up consumer prefetch and latches */ consumerPrefetch.running = true; final CountDownLatch beforeReceiveCall = new CountDownLatch(1); @@ -1215,34 +1119,31 @@ public void testReceiveMessageEmptyThenClosed() throws InterruptedException { /* * Call receive messages */ - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeReceiveCall.countDown(); - javax.jms.Message msg = consumerPrefetch.receive(0); - if (msg == null) { - noMessageReturned.set(true); - } - passedReceiveCall.countDown(); - } catch (JMSException e) { - e.printStackTrace(); + executorService.execute(() -> { + try { + beforeReceiveCall.countDown(); + jakarta.jms.Message msg = consumerPrefetch.receive(0); + if (msg == null) { + noMessageReturned.set(true); } + passedReceiveCall.countDown(); + } catch (JMSException e) { + e.printStackTrace(); } }); - assertEquals(true, beforeReceiveCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeReceiveCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Update the state and notify consumerPrefetch.close(); // Wait till receive execution finishes - assertEquals(true, passedReceiveCall.await(10, TimeUnit.SECONDS)); + assertTrue(passedReceiveCall.await(10, TimeUnit.SECONDS)); // Validate that after session is closed receive returns null - assertEquals(true, noMessageReturned.get()); - + assertTrue(noMessageReturned.get()); + // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); } @@ -1250,9 +1151,11 @@ public void run() { /** * Test received messages wait when no message are prefetch and return newly added message */ - @Test - public void testReceiveMessageEmptyThenAddMessage() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testReceiveMessageEmptyThenAddMessage(int numberOfMessagesToPrefetch) + throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and latches */ @@ -1266,37 +1169,34 @@ public void testReceiveMessageEmptyThenAddMessage() throws InterruptedException, /* * Call receive messages */ - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeReceiveCall.countDown(); - SQSMessage msg = (SQSMessage) consumerPrefetch.receive(0); - if ((msg != null) && (msg.getReceiptHandle().equals(receiptHandle))) { - messageReceived.set(true); - } - passedReceiveCall.countDown(); - } catch (JMSException e) { - e.printStackTrace(); + executorService.execute(() -> { + try { + beforeReceiveCall.countDown(); + SQSMessage msg = (SQSMessage) consumerPrefetch.receive(0); + if ((msg != null) && (msg.getReceiptHandle().equals(receiptHandle))) { + messageReceived.set(true); } + passedReceiveCall.countDown(); + } catch (JMSException e) { + e.printStackTrace(); } }); - assertEquals(true, beforeReceiveCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeReceiveCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Add message to the internal queue - List receiptHandlers = new ArrayList(); + List receiptHandlers = new ArrayList<>(); receiptHandlers.add(receiptHandle); addMessagesToQueue(receiptHandlers); consumerPrefetch.notifyStateChange(); // Wait till receive execution finishes - assertEquals(true, passedReceiveCall.await(10, TimeUnit.SECONDS)); + assertTrue(passedReceiveCall.await(10, TimeUnit.SECONDS)); + + // Validate that after adding a single message it was received correctly + assertTrue(messageReceived.get()); - // Validate that after adding a single message it was receive correctly - assertEquals(true, messageReceived.get()); - // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); } @@ -1304,9 +1204,10 @@ public void run() { /** * Test received messages with timeout */ - @Test - public void testReceiveMessageTimeout() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testReceiveMessageTimeout(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and time stamps */ @@ -1323,19 +1224,22 @@ public void testReceiveMessageTimeout() throws InterruptedException, JMSExceptio assertNull(msg); // verify that we did not exit early - long measuredTime = System.currentTimeMillis() - startTime; - assertTrue(String.format("Expected wait time = %1$s ms and has to be less than or equal to measured time = %2$s ms", waitTime, measuredTime), waitTime <= measuredTime); - + long measuredTime = System.currentTimeMillis() - startTime; + assertTrue(waitTime <= measuredTime, String.format( + "Expected wait time = %1$s ms and has to be less than or equal to measured time = %2$s ms", + waitTime, measuredTime)); + // Ensure the messagesRequested counter is reset correctly assertEquals(0, consumerPrefetch.messagesRequested); } - + /** * Test received messages with timeout */ - @Test - public void testReceiveNoWaitEmpty() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testReceiveNoWaitEmpty(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch and time stamps */ @@ -1345,7 +1249,7 @@ public void testReceiveNoWaitEmpty() throws InterruptedException, JMSException { when(amazonSQSClient.receiveMessage(any(ReceiveMessageRequest.class))) .thenReturn(ReceiveMessageResponse.builder().build()); } - + /* * Call receive messages */ @@ -1360,22 +1264,21 @@ public void testReceiveNoWaitEmpty() throws InterruptedException, JMSException { /** * Test process received messages with empty input */ - @Test - public void testProcessReceivedMessagesEmptyInput() { - - consumerPrefetch.processReceivedMessages(new ArrayList()); + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testProcessReceivedMessagesEmptyInput(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); + consumerPrefetch.processReceivedMessages(List.of()); verifyNoMoreInteractions(sqsSessionRunnable); } /** * Test process received messages */ - @Test - public void testProcessReceivedMessages() throws JMSException { - - Map mapAttributes = new HashMap(); - mapAttributes.put(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "1"); - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testProcessReceivedMessages(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); List receiptHandlers = createReceiptHandlersList(3); List messages = createSQSServiceMessages(receiptHandlers); @@ -1392,20 +1295,21 @@ public void testProcessReceivedMessages() throws JMSException { while (!consumerPrefetch.messageQueue.isEmpty()) { SQSMessageConsumerPrefetch.MessageManager msgManager = consumerPrefetch.messageQueue.pollFirst(); - SQSMessage msg = (SQSMessage)msgManager.getMessage(); - receiptHandlers.contains(msg.getReceiptHandle()); + SQSMessage msg = (SQSMessage) msgManager.message(); + assertTrue(receiptHandlers.contains(msg.getReceiptHandle())); } - verify(negativeAcknowledger).action(QUEUE_URL, new ArrayList()); + verify(negativeAcknowledger).action(QUEUE_URL, List.of()); } /** * Test process messages when message listener is set */ - @Test - public void testProcessReceivedMessagesWithMessageListener() throws JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testProcessReceivedMessagesWithMessageListener(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up mocks and consumer */ @@ -1413,9 +1317,6 @@ public void testProcessReceivedMessagesWithMessageListener() throws JMSException consumerPrefetch.setMessageListener(msgListener); // Create messages - Map mapAttributes = new HashMap(); - mapAttributes.put(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "1"); - List receiptHandlers = createReceiptHandlersList(3); List messages = createSQSServiceMessages(receiptHandlers); @@ -1428,7 +1329,7 @@ public void testProcessReceivedMessagesWithMessageListener() throws JMSException /* * Verify results */ - ArgumentCaptor captor = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); verify(sqsSessionRunnable, times(1)).scheduleCallBacks(eq(msgListener), captor.capture()); assertEquals(3, captor.getValue().size()); @@ -1436,23 +1337,19 @@ public void testProcessReceivedMessagesWithMessageListener() throws JMSException assertEquals(0, consumerPrefetch.messageQueue.size()); assertEquals(3, consumerPrefetch.messagesPrefetched); - verify(negativeAcknowledger).action(QUEUE_URL, new ArrayList()); + verify(negativeAcknowledger).action(QUEUE_URL, List.of()); } /** * Test process messages when message listener is set */ - @Test - public void testProcessReceivedMessagesThrowsException() throws JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testProcessReceivedMessagesThrowsException(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up mocks and consumer */ - - // Create messages - Map mapAttributes = new HashMap(); - mapAttributes.put(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "1"); - List receiptHandlers = createReceiptHandlersList(3); List messages = createSQSServiceMessages(receiptHandlers); @@ -1475,18 +1372,17 @@ public void testProcessReceivedMessagesThrowsException() throws JMSException { assertEquals(1, consumerPrefetch.messageQueue.size()); assertEquals(1, consumerPrefetch.messagesPrefetched); - List failedMessages = new ArrayList(); - failedMessages.add("r1"); - failedMessages.add("r2"); - verify(negativeAcknowledger).action(QUEUE_URL, failedMessages); + verify(negativeAcknowledger).action(QUEUE_URL, List.of("r1", "r2")); } /** * Test process messages when message listener is set */ - @Test - public void testProcessReceivedMessagesNegativeAcknowledgerThrowJMSException() throws JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testProcessReceivedMessagesNegativeAcknowledgerThrowJMSException(int numberOfMessagesToPrefetch) + throws JMSException { + init(numberOfMessagesToPrefetch); /* * Set up mocks and consumer */ @@ -1494,12 +1390,9 @@ public void testProcessReceivedMessagesNegativeAcknowledgerThrowJMSException() t consumerPrefetch.setMessageListener(msgListener); doThrow(new JMSException("Exception")) - .when(negativeAcknowledger).action(eq(QUEUE_URL), any(List.class)); + .when(negativeAcknowledger).action(eq(QUEUE_URL), anyList()); // Create messages - Map mapAttributes = new HashMap(); - mapAttributes.put(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "1"); - List receiptHandlers = createReceiptHandlersList(3); List messages = createSQSServiceMessages(receiptHandlers); @@ -1511,7 +1404,7 @@ public void testProcessReceivedMessagesNegativeAcknowledgerThrowJMSException() t /* * Verify results */ - ArgumentCaptor captor = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); verify(sqsSessionRunnable, times(1)).scheduleCallBacks(eq(msgListener), captor.capture()); assertEquals(3, captor.getValue().size()); @@ -1519,15 +1412,16 @@ public void testProcessReceivedMessagesNegativeAcknowledgerThrowJMSException() t assertEquals(0, consumerPrefetch.messageQueue.size()); assertEquals(3, consumerPrefetch.messagesPrefetched); - verify(negativeAcknowledger).action(QUEUE_URL, new ArrayList()); + verify(negativeAcknowledger).action(QUEUE_URL, List.of()); } /** * Test Get Messages */ - @Test - public void testGetMessages() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testGetMessages(int numberOfMessagesToPrefetch) throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up mocks and consumer */ @@ -1535,23 +1429,20 @@ public void testGetMessages() throws InterruptedException, JMSException { consumerPrefetch.retriesAttempted = 5; ReceiveMessageRequest receiveMessageRequest = ReceiveMessageRequest.builder() - .queueUrl(QUEUE_URL) + .queueUrl(QUEUE_URL) .maxNumberOfMessages(prefetchBatchSize) .attributeNamesWithStrings(SQSMessageConsumerPrefetch.ALL) .messageAttributeNames(SQSMessageConsumerPrefetch.ALL) .waitTimeSeconds(SQSMessageConsumerPrefetch.WAIT_TIME_SECONDS) .build(); - List messages = new ArrayList(); - messages.add(Message.builder().receiptHandle("r1").build()); - messages.add(Message.builder().receiptHandle("r2").build()); - messages.add(Message.builder().receiptHandle("r3").build()); - messages.add(Message.builder().receiptHandle("r4").build()); - messages.add(Message.builder().receiptHandle("r5").build()); + List messages = IntStream.range(1, 6) + .mapToObj(a -> Message.builder().receiptHandle("r" + a).build()) + .toList(); ReceiveMessageResponse receivedMessageResult = ReceiveMessageResponse.builder() - .messages(messages) - .build(); + .messages(messages) + .build(); when(amazonSQSClient.receiveMessage(receiveMessageRequest)) .thenReturn(receivedMessageResult); @@ -1571,31 +1462,25 @@ public void testGetMessages() throws InterruptedException, JMSException { /** * Test Get Messages with illegal prefetch size */ - @Test - public void testGetMessagesIllegalPrefetchSize() throws JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testGetMessagesIllegalPrefetchSize(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); int negativeSize = -10; - try { - consumerPrefetch.getMessages(negativeSize, 0); - fail(); - } catch(AssertionError ae) { - // expected exception - } + assertThatThrownBy(() -> consumerPrefetch.getMessages(negativeSize, 0)) + .isInstanceOf(AssertionError.class); - try { - consumerPrefetch.getMessages(0, 0); - fail(); - } catch(AssertionError ae) { - // expected exception - } + assertThatThrownBy(() -> consumerPrefetch.getMessages(0, 0)) + .isInstanceOf(AssertionError.class); } /** * Test Get Messages throws JMS exception */ - @Test - public void testGetMessagesJMSException() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testGetMessagesJMSException(int numberOfMessagesToPrefetch) throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up mocks and consumer */ @@ -1630,9 +1515,11 @@ public void testGetMessagesJMSException() throws InterruptedException, JMSExcept /** * Test Get Messages interrupted */ - @Test - public void testGetMessagesInterruptDuringBackoff() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testGetMessagesInterruptDuringBackoff(int numberOfMessagesToPrefetch) + throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); /* * Set up mocks and consumer */ @@ -1650,21 +1537,18 @@ public void testGetMessagesInterruptDuringBackoff() throws InterruptedException, /* * Get messages on a different execution thread */ - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - beforeGetMessagesCall.countDown(); - consumerPrefetch.getMessagesWithBackoff(prefetchBatchSize); - } catch (InterruptedException e) { - recvInterruptedExceptionLatch.countDown(); - e.printStackTrace(); - } + Thread t = new Thread(() -> { + try { + beforeGetMessagesCall.countDown(); + consumerPrefetch.getMessagesWithBackoff(prefetchBatchSize); + } catch (InterruptedException e) { + recvInterruptedExceptionLatch.countDown(); + e.printStackTrace(); } }); t.start(); - assertEquals(true, beforeGetMessagesCall.await(5, TimeUnit.SECONDS)); + assertTrue(beforeGetMessagesCall.await(5, TimeUnit.SECONDS)); Thread.sleep(10); /* @@ -1672,15 +1556,16 @@ public void run() { */ t.interrupt(); - assertEquals(true, recvInterruptedExceptionLatch.await(5, TimeUnit.SECONDS)); + assertTrue(recvInterruptedExceptionLatch.await(5, TimeUnit.SECONDS)); } /** * Test Get Messages throws error */ - @Test - public void testGetMessagesError() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testGetMessagesError(int numberOfMessagesToPrefetch) throws JMSException { + init(numberOfMessagesToPrefetch); int retriesAttempted = 3; int prefetchBatchSize = 5; consumerPrefetch.retriesAttempted = retriesAttempted; @@ -1688,19 +1573,17 @@ public void testGetMessagesError() throws InterruptedException, JMSException { when(amazonSQSClient.receiveMessage(any(ReceiveMessageRequest.class))) .thenThrow(new Error()); - try { - consumerPrefetch.getMessages(prefetchBatchSize, 0); - } catch (Error e) { - // Expected error exception - } + assertThatThrownBy(() -> consumerPrefetch.getMessages(prefetchBatchSize, 0)) + .isInstanceOf(Error.class); } /** * Test start when consumer prefetch is already closed */ - @Test - public void testStartAlreadyClosed() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStartAlreadyClosed(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch */ @@ -1720,9 +1603,10 @@ public void testStartAlreadyClosed() throws InterruptedException, JMSException { /** * Test start when consumer prefetch is already started */ - @Test - public void testStartAlreadyStarted() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStartAlreadyStarted(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch */ @@ -1742,9 +1626,10 @@ public void testStartAlreadyStarted() throws InterruptedException, JMSException /** * Test start update the state lock */ - @Test - public void testStart() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStart(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * CAll Start */ @@ -1753,16 +1638,17 @@ public void testStart() throws InterruptedException, JMSException { /* * Verify the results */ - // verify(consumerPrefetch).notifyStateChange(); + // verify(consumerPrefetch).notifyStateChange(); assertTrue(consumerPrefetch.running); } /** * Test stop when consumer prefetch is already closed */ - @Test - public void testStopAlreadyClosed() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStopAlreadyClosed(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch */ @@ -1782,9 +1668,10 @@ public void testStopAlreadyClosed() throws InterruptedException, JMSException { /** * Test stop when consumer prefetch is not started */ - @Test - public void testStopAlreadyStarted() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStopAlreadyStarted(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * CAll Start */ @@ -1799,9 +1686,10 @@ public void testStopAlreadyStarted() throws InterruptedException, JMSException { /** * Test stop update the state lock */ - @Test - public void testStop() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testStop(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch */ @@ -1822,9 +1710,10 @@ public void testStop() throws InterruptedException, JMSException { /** * Test stop when consumer prefetch is already closed */ - @Test - public void testCloseAlreadyClosed() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testCloseAlreadyClosed(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * Set up consumer prefetch */ @@ -1844,9 +1733,10 @@ public void testCloseAlreadyClosed() throws InterruptedException, JMSException { /** * Test stop when consumer prefetch is not started */ - @Test - public void testClose() throws InterruptedException, JMSException { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testClose(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); /* * CAll Start */ @@ -1863,73 +1753,61 @@ public void testClose() throws InterruptedException, JMSException { * Test that concurrent receive requests results in fetching more messages * from the queue with a single request, even if prefetching is set lower or even to 0. */ - @Test - public void testRequestedMessageTracking() throws InterruptedException, JMSException, ExecutionException { + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testRequestedMessageTracking(int numberOfMessagesToPrefetch) throws InterruptedException, JMSException { + init(numberOfMessagesToPrefetch); int concurrentReceives = 3; int receiveBatchSize = Math.min(SQSMessagingClientConstants.MAX_BATCH, Math.max(concurrentReceives, numberOfMessagesToPrefetch)); - + // Create messages return from SQS - final List receipt = new ArrayList(); - for (int i = 0; i < receiveBatchSize; ++i) { - receipt.add("r" + i); - } + List receipt = createReceiptHandlersList(receiveBatchSize); ReceiveMessageResponse receivedMessageResult = createReceiveMessageResult(receipt); // Mock SQS call for receive message and return messages when(amazonSQSClient.receiveMessage( eq(ReceiveMessageRequest.builder() - .queueUrl(QUEUE_URL) + .queueUrl(QUEUE_URL) .maxNumberOfMessages(receiveBatchSize) .attributeNamesWithStrings(SQSMessageConsumerPrefetch.ALL) .messageAttributeNames(SQSMessageConsumerPrefetch.ALL) .waitTimeSeconds(SQSMessageConsumerPrefetch.WAIT_TIME_SECONDS) .build()))) .thenReturn(receivedMessageResult); - + final CountDownLatch allReceivesWaiting = new CountDownLatch(concurrentReceives); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - invocation.callRealMethod(); - allReceivesWaiting.countDown(); - return null; - } + doAnswer((Answer) invocation -> { + invocation.callRealMethod(); + allReceivesWaiting.countDown(); + return null; }).when(consumerPrefetch).requestMessage(); - + // Close the prefetcher immediately after completing one loop - final List> receivedMessageFutures = new ArrayList<>(); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - invocation.callRealMethod(); - for (Future messageFuture : receivedMessageFutures) { - Assert.assertNotNull(messageFuture.get()); - } - consumerPrefetch.close(); - return null; + final List> receivedMessageFutures = new ArrayList<>(); + doAnswer((Answer) invocation -> { + invocation.callRealMethod(); + for (Future messageFuture : receivedMessageFutures) { + assertNotNull(messageFuture.get()); } - }).when(consumerPrefetch).processReceivedMessages(any(List.class)); - + consumerPrefetch.close(); + return null; + }).when(consumerPrefetch).processReceivedMessages(anyList()); + // Set running to true first so that the receive calls don't terminate early consumerPrefetch.running = true; - + ExecutorService receiveExecutor = Executors.newFixedThreadPool(concurrentReceives); for (int i = 0; i < concurrentReceives; i++) { - receivedMessageFutures.add(receiveExecutor.submit(new Callable() { - @Override - public javax.jms.Message call() throws Exception { - return consumerPrefetch.receive(); - } - })); + receivedMessageFutures.add(receiveExecutor.submit(() -> consumerPrefetch.receive())); } - - // Wait to make sure the receive calls have gotten far enough to + + // Wait to make sure the received calls have gotten far enough to // wait on the message queue allReceivesWaiting.await(); - - Assert.assertEquals(concurrentReceives, consumerPrefetch.messagesRequested); - + + assertEquals(concurrentReceives, consumerPrefetch.messagesRequested); + consumerPrefetch.run(); } @@ -1940,9 +1818,10 @@ public javax.jms.Message call() throws Exception { * do this work in order to get pre-fetch going even when * number of messages to pre-fetch is set to 0. */ - @Test - public void testSetMessageListenerBeforeStart() { - + @ParameterizedTest + @MethodSource("prefetchParameters") + public void testSetMessageListenerBeforeStart(int numberOfMessagesToPrefetch) { + init(numberOfMessagesToPrefetch); MessageListener msgListener = mock(MessageListener.class); consumerPrefetch.setMessageListener(msgListener); consumerPrefetch.start(); @@ -1954,60 +1833,68 @@ public void testSetMessageListenerBeforeStart() { */ private void addMessagesToQueue(List receiptHandlers) throws JMSException { - - Map mapAttributes = new HashMap<>(); - mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + Map mapAttributes = Map.of( + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); for (String receiptHandler : receiptHandlers) { - - SQSMessageConsumerPrefetch.MessageManager msgManager = mock(SQSMessageConsumerPrefetch.MessageManager.class); Message message = Message.builder() - .receiptHandle(receiptHandler) + .receiptHandle(receiptHandler) .attributes(mapAttributes) .build(); - javax.jms.Message m1 = consumerPrefetch.convertToJMSMessage(message); - when(msgManager.getMessage()).thenReturn(m1); + jakarta.jms.Message m1 = consumerPrefetch.convertToJMSMessage(message); + SQSMessageConsumerPrefetch.MessageManager msgManager = new SQSMessageConsumerPrefetch.MessageManager(null, m1); consumerPrefetch.messageQueue.add(msgManager); } } - private List createSQSServiceMessages(List receiptHandlers) throws JMSException { + private List createSQSServiceMessages(List receiptHandlers) { + Map mapAttributes = Map.of( + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + + return receiptHandlers.stream().map( + receiptHandler -> Message.builder().receiptHandle(receiptHandler).attributes(mapAttributes).build() + ).toList(); + } + + private ReceiveMessageResponse createReceiveMessageResult(List receiptList) { + List messages = createSQSServiceMessages(receiptList); + return ReceiveMessageResponse.builder().messages(messages).build(); + } - Map mapAttributes = new HashMap<>(); - mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + private List createReceiptHandlersList(int count) { + return IntStream.range(0, count).mapToObj(a -> "r" + a).toList(); + } - List resultList = - new ArrayList(); + void init(int numberOfMessagesToPrefetch) { + amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); - for (String receiptHandler : receiptHandlers) { + SQSConnection parentSQSConnection = mock(SQSConnection.class); + when(parentSQSConnection.getWrappedAmazonSQSClient()).thenReturn(amazonSQSClient); - resultList.add( - Message.builder().receiptHandle(receiptHandler) - .attributes(mapAttributes).build()); - } + sqsSessionRunnable = mock(SQSSessionCallbackScheduler.class); - return resultList; - } + acknowledger = mock(Acknowledger.class); - private ReceiveMessageResponse createReceiveMessageResult(List receiptList) { + negativeAcknowledger = mock(NegativeAcknowledger.class); - Map mapAttributes = new HashMap<>(); - mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + backoffStrategy = mock(ExponentialBackoffStrategy.class); - List messages = new ArrayList(); - for (String receipt : receiptList) { - messages.add(Message.builder().receiptHandle(receipt).attributes(mapAttributes).build()); - } + SQSQueueDestination sqsDestination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL); - return ReceiveMessageResponse.builder().messages(messages).build(); + consumerPrefetch = spy(new SQSMessageConsumerPrefetch(sqsSessionRunnable, acknowledger, negativeAcknowledger, + sqsDestination, amazonSQSClient, numberOfMessagesToPrefetch)); + + consumerPrefetch.backoffStrategy = backoffStrategy; } - private List createReceiptHandlersList(int count) { - List receiptHandlers = new ArrayList(); - for (int i = 0; i < count; ++i) { - receiptHandlers.add("r" + i); - } - return receiptHandlers; + private static Stream prefetchParameters() { + return Stream.of( + Arguments.of(0), + Arguments.of(1), + Arguments.of(5), + Arguments.of(10), + Arguments.of(15) + ); } } diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerTest.java index 9ffdc08..6567bd5 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerTest.java @@ -14,40 +14,23 @@ */ package com.amazon.sqs.javamessaging; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.jms.JMSException; -import javax.jms.MessageListener; - -import com.amazon.sqs.javamessaging.SQSConnection; -import com.amazon.sqs.javamessaging.SQSMessageConsumer; -import com.amazon.sqs.javamessaging.SQSMessageConsumerPrefetch; -import com.amazon.sqs.javamessaging.SQSQueueDestination; -import com.amazon.sqs.javamessaging.SQSSession; -import com.amazon.sqs.javamessaging.SQSSessionCallbackScheduler; import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; -import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; import com.amazon.sqs.javamessaging.util.SQSMessagingClientThreadFactory; +import jakarta.jms.JMSException; +import jakarta.jms.MessageListener; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -import org.junit.Before; -import org.junit.Test; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; /** * Test the SQSMessageConsumerPrefetchTest class @@ -55,7 +38,6 @@ public class SQSMessageConsumerTest { private static final String QUEUE_URL_1 = "QueueUrl1"; - private static final String QUEUE_URL_2 = "queueUrl2"; private static final String QUEUE_NAME = "QueueName"; private SQSMessageConsumer consumer; @@ -64,15 +46,14 @@ public class SQSMessageConsumerTest { private SQSSessionCallbackScheduler sqsSessionRunnable; private Acknowledger acknowledger; - private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5); + private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5); private SQSMessageConsumerPrefetch sqsMessageConsumerPrefetch; private NegativeAcknowledger negativeAcknowledger; private SQSMessagingClientThreadFactory threadFactory; private SQSQueueDestination destination; - @Before - public void setup() throws JMSException{ - + @BeforeEach + public void setup() throws JMSException { sqsConnection = mock(SQSConnection.class); sqsSession = spy(new SQSSession(sqsConnection, AcknowledgeMode.ACK_AUTO));//mock(SQSSession.class); @@ -87,7 +68,7 @@ public void setup() throws JMSException{ destination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL_1); consumer = spy(new SQSMessageConsumer(sqsConnection, sqsSession, sqsSessionRunnable, - destination, acknowledger, negativeAcknowledger, threadFactory)); + destination, acknowledger, negativeAcknowledger, threadFactory)); sqsMessageConsumerPrefetch = mock(SQSMessageConsumerPrefetch.class); @@ -98,13 +79,9 @@ public void setup() throws JMSException{ */ @Test public void testGetMessageSelectorNotSupported() { - - try { - consumer.getMessageSelector(); - fail(); - } catch(JMSException jmse) { - assertEquals("Unsupported Method", jmse.getMessage()); - } + assertThatThrownBy(() -> consumer.getMessageSelector()) + .isInstanceOf(JMSException.class) + .hasMessage("Unsupported Method"); } /** @@ -112,7 +89,6 @@ public void testGetMessageSelectorNotSupported() { */ @Test public void testStopNoOpIfAlreadyClosed() throws JMSException { - /* * Set up consumer */ @@ -134,7 +110,6 @@ public void testStopNoOpIfAlreadyClosed() throws JMSException { */ @Test public void testCloseBlocksInProgressCallback() throws InterruptedException, JMSException { - /* * Set up the latches */ @@ -148,24 +123,20 @@ public void testCloseBlocksInProgressCallback() throws InterruptedException, JMS sqsSession.startingCallback(consumer); // Run another thread that tries to close the consumer while activeConsumerInCallback is set - executorService.execute(new Runnable() { - - @Override - public void run() { - beforeConsumerStopCall.countDown(); - try { - consumer.close(); - } catch (JMSException e) { - fail(); - } - passedConsumerStopCall.countDown(); + executorService.execute(() -> { + beforeConsumerStopCall.countDown(); + try { + consumer.close(); + } catch (JMSException e) { + fail(); } + passedConsumerStopCall.countDown(); }); beforeConsumerStopCall.await(); Thread.sleep(10); // Ensure that we wait on activeConsumerInCallback - assertEquals(false, passedConsumerStopCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedConsumerStopCall.await(2, TimeUnit.SECONDS)); // Release the activeConsumerInCallback sqsSession.finishedCallback(); @@ -173,7 +144,7 @@ public void run() { // Ensure that the consumer close completed passedConsumerStopCall.await(); - assertEquals(true, consumer.closed); + assertTrue(consumer.closed); } @@ -182,7 +153,6 @@ public void run() { */ @Test public void testStartNoOpIfAlreadyClosed() throws JMSException { - /* * Set up consumer */ @@ -203,8 +173,7 @@ public void testStartNoOpIfAlreadyClosed() throws JMSException { * Test do close results in no op when the consumer is already closed */ @Test - public void testDoCloseNoOpWhenAlreadyClosed() throws InterruptedException, JMSException { - + public void testDoCloseNoOpWhenAlreadyClosed() { /* * Set up consumer */ @@ -226,8 +195,7 @@ public void testDoCloseNoOpWhenAlreadyClosed() throws InterruptedException, JMSE * Test do close */ @Test - public void testDoClose() throws InterruptedException, JMSException { - + public void testDoClose() { consumer = new SQSMessageConsumer(sqsConnection, sqsSession, sqsSessionRunnable, destination, acknowledger, negativeAcknowledger, threadFactory, sqsMessageConsumerPrefetch); @@ -248,8 +216,7 @@ public void testDoClose() throws InterruptedException, JMSException { * Test close results in no op when the consumer is already closed */ @Test - public void testCloseNoOpWhenAlreadyClosed() throws InterruptedException, JMSException { - + public void testCloseNoOpWhenAlreadyClosed() throws JMSException { /* * Set up consumer */ @@ -273,8 +240,7 @@ public void testCloseNoOpWhenAlreadyClosed() throws InterruptedException, JMSExc * we do not close but set a consumer close after callback */ @Test - public void testCloseCalledFromCallbackExecutionThread() throws InterruptedException, JMSException { - + public void testCloseCalledFromCallbackExecutionThread() throws JMSException { /* * Set up consumer */ @@ -300,8 +266,7 @@ public void testCloseCalledFromCallbackExecutionThread() throws InterruptedExcep * Test consumer close */ @Test - public void testClose() throws InterruptedException, JMSException { - + public void testClose() throws JMSException { /* * Set up consumer */ @@ -324,8 +289,7 @@ public void testClose() throws InterruptedException, JMSException { * Test set message listener fails when consumer is already closed */ @Test - public void testSetMessageListenerAlreadyClosed() throws InterruptedException, JMSException { - + public void testSetMessageListenerAlreadyClosed() throws JMSException { /* * Set up consumer */ @@ -339,20 +303,16 @@ public void testSetMessageListenerAlreadyClosed() throws InterruptedException, J /* * Set message listener on a consumer */ - try { - consumer.setMessageListener(msgListener); - fail(); - } catch (JMSException ex) { - assertEquals("Consumer is closed", ex.getMessage()); - } + assertThatThrownBy(() -> consumer.setMessageListener(msgListener)) + .isInstanceOf(JMSException.class) + .hasMessage("Consumer is closed"); } /** * Test receive fails when consumer is already closed */ @Test - public void testReceiveAlreadyClosed() throws InterruptedException, JMSException { - + public void testReceiveAlreadyClosed() throws JMSException { /* * Set up consumer */ @@ -364,13 +324,9 @@ public void testReceiveAlreadyClosed() throws InterruptedException, JMSException /* * Call receive */ - try { - consumer.receive(); - fail(); - } catch (JMSException ex) { - assertEquals("Consumer is closed", ex.getMessage()); - } - + assertThatThrownBy(() -> consumer.receive()) + .isInstanceOf(JMSException.class) + .hasMessage("Consumer is closed"); } @@ -378,14 +334,12 @@ public void testReceiveAlreadyClosed() throws InterruptedException, JMSException * Test set message listener fails when consumer is already closed */ @Test - public void testReceiveWithTimeoutAlreadyClosed() throws InterruptedException, JMSException { - + public void testReceiveWithTimeoutAlreadyClosed() throws JMSException { /* * Set up consumer */ consumer = spy(new SQSMessageConsumer(sqsConnection, sqsSession, sqsSessionRunnable, destination, acknowledger, negativeAcknowledger, threadFactory, sqsMessageConsumerPrefetch)); - consumer.close(); long timeout = 10; @@ -393,13 +347,9 @@ public void testReceiveWithTimeoutAlreadyClosed() throws InterruptedException, J /* * Call receive with timeout */ - try { - consumer.receive(timeout); - fail(); - } catch (JMSException ex) { - assertEquals("Consumer is closed", ex.getMessage()); - } - + assertThatThrownBy(() -> consumer.receive(timeout)) + .isInstanceOf(JMSException.class) + .hasMessage("Consumer is closed"); } @@ -407,40 +357,32 @@ public void testReceiveWithTimeoutAlreadyClosed() throws InterruptedException, J * Test set message listener fails when consumer is already closed */ @Test - public void testReceiveNoWaitAlreadyClosed() throws InterruptedException, JMSException { - + public void testReceiveNoWaitAlreadyClosed() throws JMSException { /* * Set up consumer */ consumer = spy(new SQSMessageConsumer(sqsConnection, sqsSession, sqsSessionRunnable, destination, acknowledger, negativeAcknowledger, threadFactory, sqsMessageConsumerPrefetch)); - consumer.close(); /* * Call receive no wait */ - try { - - consumer.receiveNoWait(); - fail(); - } catch (JMSException ex) { - assertEquals("Consumer is closed", ex.getMessage()); - } + assertThatThrownBy(() -> consumer.receiveNoWait()) + .isInstanceOf(JMSException.class) + .hasMessage("Consumer is closed"); } /** * Test set message listener */ @Test - public void testSetMessageListener() throws InterruptedException, JMSException { - + public void testSetMessageListener() throws JMSException { /* * Set up consumer */ consumer = spy(new SQSMessageConsumer(sqsConnection, sqsSession, sqsSessionRunnable, destination, acknowledger, negativeAcknowledger, threadFactory, sqsMessageConsumerPrefetch)); - MessageListener msgListener = mock(MessageListener.class); /* @@ -458,8 +400,7 @@ public void testSetMessageListener() throws InterruptedException, JMSException { * Test get message listener */ @Test - public void testGetMessageListener() throws InterruptedException, JMSException { - + public void testGetMessageListener() throws JMSException { /* * Set up consumer */ @@ -481,8 +422,7 @@ public void testGetMessageListener() throws InterruptedException, JMSException { * Test get message listener */ @Test - public void testGetQueue() throws InterruptedException, JMSException { - + public void testGetQueue() throws JMSException { /* * Set up consumer */ @@ -496,8 +436,7 @@ public void testGetQueue() throws InterruptedException, JMSException { * Test receive */ @Test - public void testReceive() throws InterruptedException, JMSException { - + public void testReceive() throws JMSException { /* * Set up consumer */ @@ -519,8 +458,7 @@ public void testReceive() throws InterruptedException, JMSException { * Test receive with timeout */ @Test - public void testReceiveWithTimeout() throws InterruptedException, JMSException { - + public void testReceiveWithTimeout() throws JMSException { /* * Set up consumer */ @@ -544,8 +482,7 @@ public void testReceiveWithTimeout() throws InterruptedException, JMSException { * Test receive no wait */ @Test - public void testReceiveNoWait() throws InterruptedException, JMSException { - + public void testReceiveNoWait() throws JMSException { /* * Set up consumer */ diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerFifoTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerFifoTest.java index 82feb03..a074c6c 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerFifoTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerFifoTest.java @@ -15,42 +15,30 @@ package com.amazon.sqs.javamessaging; -import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; -import com.amazon.sqs.javamessaging.SQSMessageProducer; -import com.amazon.sqs.javamessaging.SQSQueueDestination; -import com.amazon.sqs.javamessaging.SQSSession; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import com.amazon.sqs.javamessaging.message.SQSBytesMessage; import com.amazon.sqs.javamessaging.message.SQSMessage; import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; - -import software.amazon.awssdk.services.sqs.model.Message; -import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; -import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; -import software.amazon.awssdk.services.sqs.model.SendMessageRequest; -import software.amazon.awssdk.services.sqs.model.SendMessageResponse; +import jakarta.jms.JMSException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatcher; +import software.amazon.awssdk.services.sqs.model.*; import software.amazon.awssdk.utils.BinaryUtils; -import javax.jms.JMSException; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; +import java.io.Serializable; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentMatcher; +import java.util.Set; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.*; /** * Test the SQSMessageProducerTest class @@ -67,18 +55,16 @@ public class SQSMessageProducerFifoTest { private SQSMessageProducer producer; private SQSQueueDestination destination; - private SQSSession sqsSession; private AmazonSQSMessagingClientWrapper amazonSQSClient; private Acknowledger acknowledger; - @Before + @BeforeEach public void setup() throws JMSException { - amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); acknowledger = mock(Acknowledger.class); - sqsSession = mock(SQSSession.class); + SQSSession sqsSession = mock(SQSSession.class); destination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL); producer = spy(new SQSMessageProducer(amazonSQSClient, sqsSession, destination)); } @@ -88,7 +74,6 @@ public void setup() throws JMSException { */ @Test public void testPropertyToMessageAttributeWithEmpty() throws JMSException { - /* * Test Empty text message default attribute */ @@ -143,59 +128,59 @@ public void internalTestPropertyToMessageAttribute(SQSMessage sqsText) throws JM String objectProperty = "ObjectProperty"; sqsText.setBooleanProperty(booleanProperty, true); - sqsText.setByteProperty(byteProperty, (byte)1); + sqsText.setByteProperty(byteProperty, (byte) 1); sqsText.setShortProperty(shortProperty, (short) 2); sqsText.setIntProperty(intProperty, 3); sqsText.setLongProperty(longProperty, 4L); - sqsText.setFloatProperty(floatProperty, (float)5.0); + sqsText.setFloatProperty(floatProperty, (float) 5.0); sqsText.setDoubleProperty(doubleProperty, 6.0); sqsText.setStringProperty(stringProperty, "seven"); - sqsText.setObjectProperty(objectProperty, Integer.valueOf(8)); + sqsText.setObjectProperty(objectProperty, 8); MessageAttributeValue messageAttributeValueBoolean = MessageAttributeValue.builder() - .dataType("Number.Boolean") - .stringValue("1") - .build(); + .dataType("Number.Boolean") + .stringValue("1") + .build(); MessageAttributeValue messageAttributeValueByte = MessageAttributeValue.builder() - .dataType("Number.byte") - .stringValue("1") - .build(); + .dataType("Number.byte") + .stringValue("1") + .build(); MessageAttributeValue messageAttributeValueShort = MessageAttributeValue.builder() - .dataType("Number.short") - .stringValue("2") - .build(); - + .dataType("Number.short") + .stringValue("2") + .build(); + MessageAttributeValue messageAttributeValueInt = MessageAttributeValue.builder() - .dataType("Number.int") - .stringValue("3") - .build(); - + .dataType("Number.int") + .stringValue("3") + .build(); + MessageAttributeValue messageAttributeValueLong = MessageAttributeValue.builder() - .dataType("Number.long") - .stringValue("4") - .build(); - + .dataType("Number.long") + .stringValue("4") + .build(); + MessageAttributeValue messageAttributeValueFloat = MessageAttributeValue.builder() - .dataType("Number.float") - .stringValue("5.0") - .build(); + .dataType("Number.float") + .stringValue("5.0") + .build(); MessageAttributeValue messageAttributeValueDouble = MessageAttributeValue.builder() - .dataType("Number.double") - .stringValue("6.0") - .build(); - + .dataType("Number.double") + .stringValue("6.0") + .build(); + MessageAttributeValue messageAttributeValueString = MessageAttributeValue.builder() - .dataType("String") - .stringValue("seven") - .build(); + .dataType("String") + .stringValue("seven") + .build(); MessageAttributeValue messageAttributeValueObject = MessageAttributeValue.builder() - .dataType("Number.int") - .stringValue("8") - .build(); + .dataType("Number.int") + .stringValue("8") + .build(); /* * Convert property to sqs message attribute @@ -233,7 +218,8 @@ public void testSendInternalSQSTextMessage() throws JMSException { producer.sendInternal(destination, msg); - verify(amazonSQSClient).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, messageBody, SQSMessage.TEXT_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); + verify(amazonSQSClient).sendMessage(argThat(new SendMessageRequestMatcher( + QUEUE_URL, messageBody, SQSMessage.TEXT_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); verify(msg).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID); verify(msg).setSQSMessageId(MESSAGE_ID); @@ -245,16 +231,15 @@ public void testSendInternalSQSTextMessage() throws JMSException { */ @Test public void testSendInternalSQSTextMessageFromReceivedMessage() throws JMSException { - /* * Set up non JMS sqs message */ - Map mapMessageAttributes = new HashMap(); + Map mapMessageAttributes = new HashMap<>(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.TEXT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); - + .stringValue(SQSMessage.TEXT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); + mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); Map mapAttributes = new HashMap<>(); @@ -264,10 +249,10 @@ public void testSendInternalSQSTextMessageFromReceivedMessage() throws JMSExcept mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.SEQUENCE_NUMBER), SEQ_NUMBER); Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body("MessageBody") - .build(); + .messageAttributes(mapMessageAttributes) + .attributes(mapAttributes) + .body("MessageBody") + .build(); SQSTextMessage msg = spy(new SQSTextMessage(acknowledger, QUEUE_URL, message)); @@ -276,7 +261,8 @@ public void testSendInternalSQSTextMessageFromReceivedMessage() throws JMSExcept producer.sendInternal(destination, msg); - verify(amazonSQSClient).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, "MessageBody", SQSMessage.TEXT_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); + verify(amazonSQSClient).sendMessage(argThat(new SendMessageRequestMatcher( + QUEUE_URL, "MessageBody", SQSMessage.TEXT_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); verify(msg).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID); verify(msg).setSQSMessageId(MESSAGE_ID); @@ -288,11 +274,7 @@ public void testSendInternalSQSTextMessageFromReceivedMessage() throws JMSExcept */ @Test public void testSendInternalSQSObjectMessage() throws JMSException { - - HashSet set = new HashSet(); - set.add("data1"); - - SQSObjectMessage msg = spy(new SQSObjectMessage(set)); + SQSObjectMessage msg = spy(new SQSObjectMessage((Serializable) Set.of("data1"))); msg.setStringProperty(SQSMessagingClientConstants.JMSX_GROUP_ID, GROUP_ID); msg.setStringProperty(SQSMessagingClientConstants.JMS_SQS_DEDUPLICATION_ID, DEDUP_ID); String msgBody = msg.getMessageBody(); @@ -302,7 +284,8 @@ public void testSendInternalSQSObjectMessage() throws JMSException { producer.sendInternal(destination, msg); - verify(amazonSQSClient).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, msgBody, SQSMessage.OBJECT_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); + verify(amazonSQSClient).sendMessage(argThat(new SendMessageRequestMatcher( + QUEUE_URL, msgBody, SQSMessage.OBJECT_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); verify(msg).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID); verify(msg).setSQSMessageId(MESSAGE_ID); @@ -314,16 +297,15 @@ public void testSendInternalSQSObjectMessage() throws JMSException { */ @Test public void testSendInternalSQSObjectMessageFromReceivedMessage() throws JMSException, IOException { - /* * Set up non JMS sqs message */ - Map mapMessageAttributes = new HashMap(); + Map mapMessageAttributes = new HashMap<>(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); + .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); Map mapAttributes = new HashMap<>(); @@ -341,10 +323,10 @@ public void testSendInternalSQSObjectMessageFromReceivedMessage() throws JMSExce String messageBody = BinaryUtils.toBase64(array.toByteArray()); Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body(messageBody) - .build(); + .messageAttributes(mapMessageAttributes) + .attributes(mapAttributes) + .body(messageBody) + .build(); SQSObjectMessage msg = spy(new SQSObjectMessage(acknowledger, QUEUE_URL, message)); @@ -353,7 +335,8 @@ public void testSendInternalSQSObjectMessageFromReceivedMessage() throws JMSExce producer.sendInternal(destination, msg); - verify(amazonSQSClient).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, messageBody, SQSMessage.OBJECT_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); + verify(amazonSQSClient).sendMessage(argThat(new SendMessageRequestMatcher( + QUEUE_URL, messageBody, SQSMessage.OBJECT_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); verify(msg).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID); verify(msg).setSQSMessageId(MESSAGE_ID); @@ -365,11 +348,10 @@ public void testSendInternalSQSObjectMessageFromReceivedMessage() throws JMSExce */ @Test public void testSendInternalSQSByteMessage() throws JMSException { - SQSBytesMessage msg = spy(new SQSBytesMessage()); msg.setStringProperty(SQSMessagingClientConstants.JMSX_GROUP_ID, GROUP_ID); msg.setStringProperty(SQSMessagingClientConstants.JMS_SQS_DEDUPLICATION_ID, DEDUP_ID); - msg.writeByte((byte)0); + msg.writeByte((byte) 0); msg.reset(); when(amazonSQSClient.sendMessage(any(SendMessageRequest.class))) @@ -378,7 +360,8 @@ public void testSendInternalSQSByteMessage() throws JMSException { producer.sendInternal(destination, msg); String messageBody = "AA=="; - verify(amazonSQSClient).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, messageBody, SQSMessage.BYTE_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); + verify(amazonSQSClient).sendMessage(argThat(new SendMessageRequestMatcher( + QUEUE_URL, messageBody, SQSMessage.BYTE_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); verify(msg).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID); @@ -390,16 +373,15 @@ public void testSendInternalSQSByteMessage() throws JMSException { * Test sendInternal input with SQSByteMessage */ @Test - public void testSendInternalSQSByteMessageFromReceivedMessage() throws JMSException, IOException { - + public void testSendInternalSQSByteMessageFromReceivedMessage() throws JMSException { /* * Set up non JMS sqs message */ - Map mapMessageAttributes = new HashMap(); + Map mapMessageAttributes = new HashMap<>(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); + .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); Map mapAttributes = new HashMap<>(); @@ -408,13 +390,13 @@ public void testSendInternalSQSByteMessageFromReceivedMessage() throws JMSExcept mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID), DEDUP_ID); mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.SEQUENCE_NUMBER), SEQ_NUMBER); - byte[] byteArray = new byte[] { 1, 0, 'a', 65 }; + byte[] byteArray = new byte[]{1, 0, 'a', 65}; String messageBody = BinaryUtils.toBase64(byteArray); Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body(messageBody) - .build(); + .messageAttributes(mapMessageAttributes) + .attributes(mapAttributes) + .body(messageBody) + .build(); SQSBytesMessage msg = spy(new SQSBytesMessage(acknowledger, QUEUE_URL, message)); @@ -423,37 +405,19 @@ public void testSendInternalSQSByteMessageFromReceivedMessage() throws JMSExcept producer.sendInternal(destination, msg); - verify(amazonSQSClient).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, messageBody, SQSMessage.BYTE_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); + verify(amazonSQSClient).sendMessage(argThat(new SendMessageRequestMatcher( + QUEUE_URL, messageBody, SQSMessage.BYTE_MESSAGE_TYPE, GROUP_ID, DEDUP_ID))); verify(msg).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID); verify(msg).setSQSMessageId(MESSAGE_ID); verify(msg).setSequenceNumber(SEQ_NUMBER_2); } - private class sendMessageRequestMatcher extends ArgumentMatcher { - - private String queueUrl; - private String messagesBody; - private String messageType; - private String groupId; - private String deduplicationId; - - private sendMessageRequestMatcher(String queueUrl, String messagesBody, String messageType, String groupId, String deduplicationId) { - this.queueUrl = queueUrl; - this.messagesBody = messagesBody; - this.messageType = messageType; - this.groupId = groupId; - this.deduplicationId = deduplicationId; - } + private record SendMessageRequestMatcher(String queueUrl, String messagesBody, String messageType, String groupId, + String deduplicationId) implements ArgumentMatcher { @Override - public boolean matches(Object argument) { - - if (!(argument instanceof SendMessageRequest)) { - return false; - } - - SendMessageRequest request = (SendMessageRequest)argument; + public boolean matches(SendMessageRequest request) { assertEquals(queueUrl, request.queueUrl()); assertEquals(messagesBody, request.messageBody()); String messageType = request.messageAttributes().get(SQSMessage.JMS_SQS_MESSAGE_TYPE).stringValue(); diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java index cf71839..ee4b327 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java @@ -15,57 +15,34 @@ package com.amazon.sqs.javamessaging; -import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; -import com.amazon.sqs.javamessaging.SQSConnection; -import com.amazon.sqs.javamessaging.SQSMessageProducer; -import com.amazon.sqs.javamessaging.SQSQueueDestination; -import com.amazon.sqs.javamessaging.SQSSession; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import com.amazon.sqs.javamessaging.message.SQSBytesMessage; import com.amazon.sqs.javamessaging.message.SQSMessage; import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; - +import jakarta.jms.IllegalStateException; +import jakarta.jms.Queue; +import jakarta.jms.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; import software.amazon.awssdk.services.sqs.model.Message; -import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; -import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; -import software.amazon.awssdk.services.sqs.model.SendMessageRequest; -import software.amazon.awssdk.services.sqs.model.SendMessageResponse; +import software.amazon.awssdk.services.sqs.model.*; import software.amazon.awssdk.utils.BinaryUtils; -import javax.jms.InvalidDestinationException; -import javax.jms.JMSException; -import javax.jms.IllegalStateException; -import javax.jms.Queue; -import javax.jms.Destination; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.io.Serializable; +import java.lang.UnsupportedOperationException; +import java.util.*; import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.*; /** * Test the SQSMessageProducerTest class @@ -80,16 +57,12 @@ public class SQSMessageProducerTest { private SQSMessageProducer producer; private SQSQueueDestination destination; private SQSSession sqsSession; - private SQSConnection sqsConnection; private AmazonSQSMessagingClientWrapper amazonSQSClient; private Acknowledger acknowledger; - @Before + @BeforeEach public void setup() throws JMSException { - amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); - sqsConnection = mock(SQSConnection.class); - acknowledger = mock(Acknowledger.class); sqsSession = mock(SQSSession.class); @@ -102,12 +75,9 @@ public void setup() throws JMSException { */ @Test public void testCheckIfDestinationAlreadySet() throws JMSException { - - try { - producer.checkIfDestinationAlreadySet(); - } catch (UnsupportedOperationException uoe) { - assertEquals("MessageProducer already specified a destination at creation time.", uoe.getMessage()); - } + assertThatThrownBy(() -> producer.checkIfDestinationAlreadySet()) + .isInstanceOf(UnsupportedOperationException.class) + .hasMessage("MessageProducer already specified a destination at creation time."); producer = spy(new SQSMessageProducer(amazonSQSClient, sqsSession, null)); producer.checkIfDestinationAlreadySet(); @@ -118,16 +88,13 @@ public void testCheckIfDestinationAlreadySet() throws JMSException { */ @Test public void testCheckClosed() throws JMSException { - /* * Check exception is thrown when producer is closed */ producer.isClosed().set(true); - try { - producer.checkClosed(); - } catch (IllegalStateException ise) { - assertEquals("The producer is closed.", ise.getMessage()); - } + assertThatThrownBy(() -> producer.checkClosed()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("The producer is closed."); /* * Check no op when producer is closed @@ -141,7 +108,6 @@ public void testCheckClosed() throws JMSException { */ @Test public void testPropertyToMessageAttributeWithEmpty() throws JMSException { - /* * Test Empty text message default attribute */ @@ -161,12 +127,8 @@ public void testPropertyToMessageAttributeWithEmpty() throws JMSException { /* * Test Empty byte message default attribute */ - MessageAttributeValue messageAttributeValueByte = MessageAttributeValue.builder() - .dataType("String") - .stringValue("byte") - .build(); - SQSMessage sqsByte = new SQSBytesMessage(); + // TODO messageAttributeByte not verified Map messageAttributeByte = producer.propertyToMessageAttribute(sqsByte); assertEquals(0, messageAttributeObject.size()); @@ -201,64 +163,59 @@ public void internalTestPropertyToMessageAttribute(SQSMessage sqsText) throws JM String objectProperty = "ObjectProperty"; sqsText.setBooleanProperty(booleanProperty, true); - sqsText.setByteProperty(byteProperty, (byte)1); + sqsText.setByteProperty(byteProperty, (byte) 1); sqsText.setShortProperty(shortProperty, (short) 2); sqsText.setIntProperty(intProperty, 3); sqsText.setLongProperty(longProperty, 4L); - sqsText.setFloatProperty(floatProperty, (float)5.0); + sqsText.setFloatProperty(floatProperty, (float) 5.0); sqsText.setDoubleProperty(doubleProperty, 6.0); sqsText.setStringProperty(stringProperty, "seven"); - sqsText.setObjectProperty(objectProperty, Integer.valueOf(8)); + sqsText.setObjectProperty(objectProperty, 8); MessageAttributeValue messageAttributeValueBoolean = MessageAttributeValue.builder() - .dataType("Number.Boolean") - .stringValue("1") - .build(); + .dataType("Number.Boolean") + .stringValue("1") + .build(); MessageAttributeValue messageAttributeValueByte = MessageAttributeValue.builder() - .dataType("Number.byte") - .stringValue("1") - .build(); + .dataType("Number.byte") + .stringValue("1") + .build(); MessageAttributeValue messageAttributeValueShort = MessageAttributeValue.builder() - .dataType("Number.short") - .stringValue("2") - .build(); + .dataType("Number.short") + .stringValue("2") + .build(); MessageAttributeValue messageAttributeValueInt = MessageAttributeValue.builder() - .dataType("Number.int") - .stringValue("3") - .build(); + .dataType("Number.int") + .stringValue("3") + .build(); MessageAttributeValue messageAttributeValueLong = MessageAttributeValue.builder() - .dataType("Number.long") - .stringValue("4") - .build(); + .dataType("Number.long") + .stringValue("4") + .build(); MessageAttributeValue messageAttributeValueFloat = MessageAttributeValue.builder() - .dataType("Number.float") - .stringValue("5.0") - .build(); + .dataType("Number.float") + .stringValue("5.0") + .build(); MessageAttributeValue messageAttributeValueDouble = MessageAttributeValue.builder() - .dataType("Number.double") - .stringValue("6.0") - .build(); + .dataType("Number.double") + .stringValue("6.0") + .build(); MessageAttributeValue messageAttributeValueString = MessageAttributeValue.builder() - .dataType("String") - .stringValue("seven") - .build(); + .dataType("String") + .stringValue("seven") + .build(); MessageAttributeValue messageAttributeValueObject = MessageAttributeValue.builder() - .dataType("Number.int") - .stringValue("8") - .build(); - - MessageAttributeValue messageAttributeValueJMSSQSMessageType = MessageAttributeValue.builder() - .dataType("String") - .stringValue("text") - .build(); + .dataType("Number.int") + .stringValue("8") + .build(); /* * Convert property to sqs message attribute @@ -284,33 +241,21 @@ public void internalTestPropertyToMessageAttribute(SQSMessage sqsText) throws JM * Test sendInternal input of Non SQS message */ @Test - public void testSendInternalNonSQSMessage() throws JMSException { - - javax.jms.Message msg = mock(javax.jms.Message.class); + public void testSendInternalNonSQSMessage() { + jakarta.jms.Message msg = mock(jakarta.jms.Message.class); - try { - producer.sendInternal(destination, msg); - fail(); - } catch (JMSException jmse) { - // expected - } + assertThatThrownBy(() -> producer.sendInternal(destination, msg)).isInstanceOf(JMSException.class); } /** * Test sendInternal input of Non SQS message */ @Test - public void testSendInternalAlreadyClosed() throws JMSException { - + public void testSendInternalAlreadyClosed() { producer.isClosed().set(true); SQSMessage msg = mock(SQSMessage.class); - try { - producer.sendInternal(destination, msg); - fail(); - } catch (JMSException jmse) { - // expected - } + assertThatThrownBy(() -> producer.sendInternal(destination, msg)).isInstanceOf(JMSException.class); } /** @@ -318,15 +263,9 @@ public void testSendInternalAlreadyClosed() throws JMSException { */ @Test public void testSendInternalNoMessageBody() throws JMSException { - SQSMessage msg = mock(SQSMessage.class); - try { - producer.sendInternal(destination, msg); - fail(); - } catch (JMSException jmse) { - //expected - } + assertThatThrownBy(() -> producer.sendInternal(destination, msg)).isInstanceOf(JMSException.class); verify(msg).setJMSDestination(destination); } @@ -336,7 +275,6 @@ public void testSendInternalNoMessageBody() throws JMSException { */ @Test public void testSendInternalSQSTextMessage() throws JMSException { - String messageBody1 = "MyText1"; String messageBody2 = "MyText2"; SQSTextMessage msg = spy(new SQSTextMessage(messageBody1)); @@ -350,13 +288,14 @@ public void testSendInternalSQSTextMessage() throws JMSException { producer.sendInternal(destination, msg); /* - * Re send the message + * Resend the message */ msg.setText(messageBody2); producer.sendInternal(destination, msg); List messagesBody = Arrays.asList(messageBody1, messageBody2); - verify(amazonSQSClient, times(2)).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, messagesBody, messageAttributes))); + verify(amazonSQSClient, times(2)).sendMessage(argThat( + new SendMessageRequestMatcher(QUEUE_URL, messagesBody, messageAttributes))); verify(msg, times(2)).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID_1); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID_2); @@ -369,24 +308,23 @@ public void testSendInternalSQSTextMessage() throws JMSException { */ @Test public void testSendInternalSQSTextMessageFromReceivedMessage() throws JMSException { - /* * Set up non JMS sqs message */ - Map mapMessageAttributes = new HashMap(); + Map mapMessageAttributes = new HashMap<>(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.TEXT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); + .stringValue(SQSMessage.TEXT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); Map mapAttributes = new HashMap<>(); mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); Message message = Message.builder().messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body("MessageBody") - .build(); + .attributes(mapAttributes) + .body("MessageBody") + .build(); SQSTextMessage msg = spy(new SQSTextMessage(acknowledger, QUEUE_URL, message)); @@ -395,8 +333,9 @@ public void testSendInternalSQSTextMessageFromReceivedMessage() throws JMSExcept producer.sendInternal(destination, msg); - List messagesBody = Arrays.asList("MessageBody"); - verify(amazonSQSClient).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, messagesBody, mapMessageAttributes))); + List messagesBody = List.of("MessageBody"); + verify(amazonSQSClient).sendMessage(argThat( + new SendMessageRequestMatcher(QUEUE_URL, messagesBody, mapMessageAttributes))); verify(msg).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID_1); verify(msg).setSQSMessageId(MESSAGE_ID_1); @@ -407,34 +346,26 @@ public void testSendInternalSQSTextMessageFromReceivedMessage() throws JMSExcept */ @Test public void testSendInternalSQSObjectMessage() throws JMSException { - - HashSet set1 = new HashSet(); - set1.add("data1"); - HashSet set2 = new HashSet(); - set2.add("data2"); - - SQSObjectMessage msg = spy(new SQSObjectMessage(set1)); + SQSObjectMessage msg = spy(new SQSObjectMessage((Serializable) Set.of("data1"))); String megBody1 = msg.getMessageBody(); - Map messageAttributes = createMessageAttribute("object"); - when(amazonSQSClient.sendMessage(any(SendMessageRequest.class))) - .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_1).build()) - .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_2).build()); + .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_1).build()) + .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_2).build()); producer.sendInternal(destination, msg); /* - * Re send the message + * Resend the message */ msg.clearBody(); - msg.setObject(set2); + msg.setObject((Serializable) Set.of("data2")); String megBody2 = msg.getMessageBody(); producer.sendInternal(destination, msg); - + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(SendMessageRequest.class); verify(amazonSQSClient, times(2)).sendMessage(argumentCaptor.capture()); - + assertEquals(megBody1, argumentCaptor.getAllValues().get(0).messageBody()); assertEquals(megBody2, argumentCaptor.getAllValues().get(1).messageBody()); verify(msg, times(2)).setJMSDestination(destination); @@ -449,16 +380,15 @@ public void testSendInternalSQSObjectMessage() throws JMSException { */ @Test public void testSendInternalSQSObjectMessageFromReceivedMessage() throws JMSException, IOException { - /* * Set up non JMS sqs message */ - Map mapMessageAttributes = new HashMap(); + Map mapMessageAttributes = new HashMap<>(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); + .stringValue(SQSMessage.OBJECT_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); Map mapAttributes = new HashMap<>(); @@ -473,22 +403,22 @@ public void testSendInternalSQSObjectMessageFromReceivedMessage() throws JMSExce String messageBody = BinaryUtils.toBase64(array.toByteArray()); Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body(messageBody) - .build(); + .messageAttributes(mapMessageAttributes) + .attributes(mapAttributes) + .body(messageBody) + .build(); SQSObjectMessage msg = spy(new SQSObjectMessage(acknowledger, QUEUE_URL, message)); Map messageAttributes = createMessageAttribute("object"); when(amazonSQSClient.sendMessage(any(SendMessageRequest.class))) - .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_1).build()) - .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_2).build()); + .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_1).build()) + .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_2).build()); producer.sendInternal(destination, msg); - verify(amazonSQSClient).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, Arrays.asList(messageBody), + verify(amazonSQSClient).sendMessage(argThat(new SendMessageRequestMatcher(QUEUE_URL, List.of(messageBody), messageAttributes))); verify(msg).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID_1); @@ -500,14 +430,12 @@ public void testSendInternalSQSObjectMessageFromReceivedMessage() throws JMSExce */ @Test public void testSendInternalSQSByteMessage() throws JMSException { - SQSBytesMessage msg = spy(new SQSBytesMessage()); - msg.writeByte((byte)0); + msg.writeByte((byte) 0); msg.reset(); Map messageAttributes = createMessageAttribute("byte"); - String messageId = "MessageId"; when(amazonSQSClient.sendMessage(any(SendMessageRequest.class))) .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_1).build()) .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_2).build()); @@ -515,15 +443,15 @@ public void testSendInternalSQSByteMessage() throws JMSException { producer.sendInternal(destination, msg); /* - * Re send the message + * Resend the message */ msg.clearBody(); msg.writeInt(42); producer.sendInternal(destination, msg); List messagesBody = Arrays.asList("AA==", "AAAAKg=="); - verify(amazonSQSClient, times(2)).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, messagesBody, - messageAttributes))); + verify(amazonSQSClient, times(2)).sendMessage(argThat( + new SendMessageRequestMatcher(QUEUE_URL, messagesBody, messageAttributes))); verify(msg, times(2)).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID_1); @@ -536,28 +464,27 @@ public void testSendInternalSQSByteMessage() throws JMSException { * Test sendInternal input with SQSByteMessage */ @Test - public void testSendInternalSQSByteMessageFromReceivedMessage() throws JMSException, IOException { - + public void testSendInternalSQSByteMessageFromReceivedMessage() throws JMSException { /* * Set up non JMS sqs message */ - Map mapMessageAttributes = new HashMap(); + Map mapMessageAttributes = new HashMap<>(); MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) - .dataType(SQSMessagingClientConstants.STRING) - .build(); + .stringValue(SQSMessage.BYTE_MESSAGE_TYPE) + .dataType(SQSMessagingClientConstants.STRING) + .build(); mapMessageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); Map mapAttributes = new HashMap<>(); mapAttributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); - byte[] byteArray = new byte[] { 1, 0, 'a', 65 }; + byte[] byteArray = new byte[]{1, 0, 'a', 65}; String messageBody = BinaryUtils.toBase64(byteArray); Message message = Message.builder() - .messageAttributes(mapMessageAttributes) - .attributes(mapAttributes) - .body(messageBody) - .build(); + .messageAttributes(mapMessageAttributes) + .attributes(mapAttributes) + .body(messageBody) + .build(); SQSObjectMessage msg = spy(new SQSObjectMessage(acknowledger, QUEUE_URL, message)); @@ -569,8 +496,8 @@ public void testSendInternalSQSByteMessageFromReceivedMessage() throws JMSExcept producer.sendInternal(destination, msg); - verify(amazonSQSClient).sendMessage(argThat(new sendMessageRequestMatcher(QUEUE_URL, Arrays.asList(messageBody), - messageAttributes))); + verify(amazonSQSClient).sendMessage(argThat(new SendMessageRequestMatcher( + QUEUE_URL, List.of(messageBody), messageAttributes))); verify(msg).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID_1); verify(msg).setSQSMessageId(MESSAGE_ID_1); @@ -589,32 +516,15 @@ public void testGetQueue() throws JMSException { */ @Test public void testSendNonSQSDestination() throws JMSException { - Queue queue = mock(Queue.class); - SQSTextMessage msg = spy(new SQSTextMessage("MyText")); - try { - producer.send(queue, msg); - fail(); - } catch (InvalidDestinationException ide) { - // expected - } + assertThatThrownBy(() -> producer.send(queue, msg)).isInstanceOf(InvalidDestinationException.class); Destination destination = mock(Destination.class); - try { - producer.send(destination, msg); - fail(); - } catch (InvalidDestinationException ide) { - // expected - } + assertThatThrownBy(() -> producer.send(destination, msg)).isInstanceOf(InvalidDestinationException.class); - try { - producer.send(null, msg); - fail(); - } catch (InvalidDestinationException ide) { - // expected - } + assertThatThrownBy(() -> producer.send(null, msg)).isInstanceOf(InvalidDestinationException.class); } /** @@ -622,15 +532,9 @@ public void testSendNonSQSDestination() throws JMSException { */ @Test public void testSendDestinationAlreadySpecified() throws JMSException { - SQSTextMessage msg = spy(new SQSTextMessage("MyText")); - try { - producer.send(destination, msg); - fail(); - } catch (UnsupportedOperationException ide) { - // expected - } + assertThatThrownBy(() -> producer.send(destination, msg)).isInstanceOf(UnsupportedOperationException.class); verify(producer).checkIfDestinationAlreadySet(); } @@ -640,7 +544,6 @@ public void testSendDestinationAlreadySpecified() throws JMSException { */ @Test public void testSendWithDestination() throws JMSException { - SQSTextMessage msg = spy(new SQSTextMessage("MyText")); producer = spy(new SQSMessageProducer(amazonSQSClient, sqsSession, null)); @@ -658,7 +561,6 @@ public void testSendWithDestination() throws JMSException { */ @Test public void testSendDropUnsupportedFeatures() throws JMSException { - int deliveryMode = 1; int priority = 1; long timeToLive = 1; @@ -681,7 +583,6 @@ public void testSendDropUnsupportedFeatures() throws JMSException { */ @Test public void testSendWithoutDestination() throws JMSException { - SQSTextMessage msg = spy(new SQSTextMessage("MyText")); doNothing() @@ -696,7 +597,6 @@ public void testSendWithoutDestination() throws JMSException { */ @Test public void testCloseAlreadyClosed() throws JMSException { - producer.isClosed().set(true); producer.close(); @@ -709,7 +609,6 @@ public void testCloseAlreadyClosed() throws JMSException { */ @Test public void testClose() throws JMSException { - producer.close(); verify(sqsSession).removeProducer(producer); @@ -718,82 +617,51 @@ public void testClose() throws JMSException { @Test public void testSetDeliveryDelay() throws JMSException { assertEquals(0, producer.getDeliveryDelay()); - + producer.setDeliveryDelay(2000); - + assertEquals(2000, producer.getDeliveryDelay()); - + ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(SendMessageRequest.class); when(amazonSQSClient.sendMessage(requestCaptor.capture())) - .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_1).build()); + .thenReturn(SendMessageResponse.builder().messageId(MESSAGE_ID_1).build()); SQSTextMessage msg = new SQSTextMessage("Sorry I'm late!"); producer.send(msg); - + assertEquals(2, requestCaptor.getValue().delaySeconds().intValue()); } - - + + @Test - public void testSetDeliveryDelayInvalidDelays() throws JMSException { - try { - producer.setDeliveryDelay(-1); - fail(); - } catch (IllegalArgumentException ide) { - // expected - } - - try { - producer.setDeliveryDelay(TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); - fail(); - } catch (IllegalArgumentException ide) { - // expected - } - - try { - producer.setDeliveryDelay(20); - fail(); - } catch (IllegalArgumentException ide) { - // expected - } + public void testSetDeliveryDelayInvalidDelays() { + assertThatThrownBy(() -> producer.setDeliveryDelay(-1)).isInstanceOf(IllegalArgumentException.class); + + assertThatThrownBy(() -> producer.setDeliveryDelay(TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS))) + .isInstanceOf(IllegalArgumentException.class); + + assertThatThrownBy(() -> producer.setDeliveryDelay(20)).isInstanceOf(IllegalArgumentException.class); } - - + + private Map createMessageAttribute(String type) { MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder() - .dataType("String") - .stringValue(type) - .build(); + .dataType("String") + .stringValue(type) + .build(); - Map messageAttributes = new HashMap(); - messageAttributes.put(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); - return messageAttributes; + return Map.of(SQSMessage.JMS_SQS_MESSAGE_TYPE, messageAttributeValue); } - private class sendMessageRequestMatcher extends ArgumentMatcher { - - private String queueUrl; - private List messagesBody; - private Map messageAttributes; - - private sendMessageRequestMatcher(String queueUrl, List messagesBody, - Map messageAttributes) { - this.queueUrl = queueUrl; - this.messagesBody = messagesBody; - this.messageAttributes = messageAttributes; - } + private record SendMessageRequestMatcher(String queueUrl, List messagesBody, + Map messageAttributes) + implements ArgumentMatcher { @Override - public boolean matches(Object argument) { - - if (!(argument instanceof SendMessageRequest)) { - return false; - } - - SendMessageRequest reqeust = (SendMessageRequest)argument; - assertEquals(queueUrl, reqeust.queueUrl()); - assertTrue(messagesBody.contains(reqeust.messageBody())); - assertEquals(messageAttributes , reqeust.messageAttributes()); + public boolean matches(SendMessageRequest request) { + assertEquals(queueUrl, request.queueUrl()); + assertTrue(messagesBody.contains(request.messageBody())); + assertEquals(messageAttributes, request.messageAttributes()); return true; } } diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessagingClientUtilTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessagingClientUtilTest.java index 8d5a4be..8d5152a 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessagingClientUtilTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessagingClientUtilTest.java @@ -16,9 +16,9 @@ import com.amazon.sqs.javamessaging.util.SQSMessagingClientUtil; -import org.junit.Test; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * Test the SQSMessagingClientUtilTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSQueueDestinationTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSQueueDestinationTest.java index 7d81d79..da3f9d8 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSQueueDestinationTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSQueueDestinationTest.java @@ -14,13 +14,9 @@ */ package com.amazon.sqs.javamessaging; -import org.junit.Test; +import org.junit.jupiter.api.Test; -import com.amazon.sqs.javamessaging.SQSQueueDestination; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; /** * Test the SQSDestinationTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSSessionCallbackSchedulerTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSSessionCallbackSchedulerTest.java index 395eced..6bcc37a 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSSessionCallbackSchedulerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSSessionCallbackSchedulerTest.java @@ -14,56 +14,36 @@ */ package com.amazon.sqs.javamessaging; - -import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; -import com.amazon.sqs.javamessaging.PrefetchManager; -import com.amazon.sqs.javamessaging.SQSConnection; -import com.amazon.sqs.javamessaging.SQSMessageConsumer; -import com.amazon.sqs.javamessaging.SQSMessageConsumerPrefetch; -import com.amazon.sqs.javamessaging.SQSSession; -import com.amazon.sqs.javamessaging.SQSSessionCallbackScheduler; import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; import com.amazon.sqs.javamessaging.message.SQSMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; - +import jakarta.jms.JMSException; +import jakarta.jms.MessageListener; +import jakarta.jms.Session; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.junit.jupiter.MockitoExtension; import software.amazon.awssdk.services.sqs.model.Message; -import javax.jms.JMSException; -import javax.jms.MessageListener; -import javax.jms.Session; - import java.util.ArrayDeque; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import static junit.framework.Assert.fail; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyList; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; /** * Test the SQSSessionCallbackSchedulerTest class */ +@ExtendWith(MockitoExtension.class) public class SQSSessionCallbackSchedulerTest { private static final String QUEUE_URL_PREFIX = "QueueUrl"; @@ -73,31 +53,19 @@ public class SQSSessionCallbackSchedulerTest { private SQSSession sqsSession; private NegativeAcknowledger negativeAcknowledger; private SQSSessionCallbackScheduler sqsSessionRunnable; - private SQSConnection sqsConnection; - private AmazonSQSMessagingClientWrapper sqsClient; private ArrayDeque callbackQueue; private Acknowledger acknowledger; private SQSMessageConsumer consumer; - - @Before - public void setup() { - - sqsClient = mock(AmazonSQSMessagingClientWrapper.class); - sqsConnection = mock(SQSConnection.class); - when(sqsConnection.getWrappedAmazonSQSClient()) - .thenReturn(sqsClient); + @Captor + ArgumentCaptor> captor; + @BeforeEach + public void setup() { sqsSession = mock(SQSSession.class); - when(sqsSession.getParentConnection()) - .thenReturn(sqsConnection); - negativeAcknowledger = mock(NegativeAcknowledger.class); - callbackQueue = mock(ArrayDeque.class); - acknowledger = mock(Acknowledger.class); - consumer = mock(SQSMessageConsumer.class); sqsSessionRunnable = spy(new SQSSessionCallbackScheduler(sqsSession, @@ -111,7 +79,6 @@ public void setup() { */ @Test public void testNackQueueMessageWhenEmpty() throws JMSException { - when(callbackQueue.isEmpty()) .thenReturn(true); @@ -131,7 +98,6 @@ public void testNackQueueMessageWhenEmpty() throws JMSException { */ @Test public void testNackQueueMessageAcknowledgerThrowJMSException() throws JMSException { - MessageListener msgListener = mock(MessageListener.class); SQSMessage sqsMessage = mock(SQSMessage.class); @@ -142,12 +108,7 @@ public void testNackQueueMessageAcknowledgerThrowJMSException() throws JMSExcept when(sqsMessage.getQueueUrl()) .thenReturn(QUEUE_URL_1); - SQSMessageConsumerPrefetch.MessageManager msgManager = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager.getMessage()) - .thenReturn(sqsMessage); - - when(msgManager.getPrefetchManager()) - .thenReturn(mock(PrefetchManager.class)); + SQSMessageConsumerPrefetch.MessageManager msgManager = new SQSMessageConsumerPrefetch.MessageManager(mock(PrefetchManager.class), sqsMessage); SQSSession.CallbackEntry entry1 = new SQSSession.CallbackEntry(msgListener, msgManager); @@ -172,7 +133,6 @@ public void testNackQueueMessageAcknowledgerThrowJMSException() throws JMSExcept */ @Test public void testNackQueueMessageAcknowledgerThrowError() throws JMSException { - MessageListener msgListener = mock(MessageListener.class); SQSMessage sqsMessage = mock(SQSMessage.class); @@ -183,13 +143,7 @@ public void testNackQueueMessageAcknowledgerThrowError() throws JMSException { when(sqsMessage.getQueueUrl()) .thenReturn(QUEUE_URL_2); - SQSMessageConsumerPrefetch.MessageManager msgManager = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager.getMessage()) - .thenReturn(sqsMessage); - - when(msgManager.getPrefetchManager()) - .thenReturn(mock(PrefetchManager.class)); - + SQSMessageConsumerPrefetch.MessageManager msgManager = new SQSMessageConsumerPrefetch.MessageManager(mock(PrefetchManager.class), sqsMessage); SQSSession.CallbackEntry entry1 = new SQSSession.CallbackEntry(msgListener, msgManager); @@ -206,12 +160,7 @@ public void testNackQueueMessageAcknowledgerThrowError() throws JMSException { /* * Nack the messages, exception expected */ - try { - sqsSessionRunnable.nackQueuedMessages(); - fail(); - } catch(Error e) { - // expected error - } + assertThatThrownBy(() -> sqsSessionRunnable.nackQueuedMessages()).isInstanceOf(Error.class); } /** @@ -219,7 +168,6 @@ public void testNackQueueMessageAcknowledgerThrowError() throws JMSException { */ @Test public void testNackQueueMessage() throws JMSException { - /* * Set up mocks */ @@ -233,12 +181,7 @@ public void testNackQueueMessage() throws JMSException { when(sqsMessage1.getQueueUrl()) .thenReturn(QUEUE_URL_1); - SQSMessageConsumerPrefetch.MessageManager msgManager1 = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager1.getMessage()) - .thenReturn(sqsMessage1); - - when(msgManager1.getPrefetchManager()) - .thenReturn(mock(PrefetchManager.class)); + SQSMessageConsumerPrefetch.MessageManager msgManager1 = new SQSMessageConsumerPrefetch.MessageManager(mock(PrefetchManager.class), sqsMessage1); SQSMessage sqsMessage2 = mock(SQSMessage.class); when(sqsMessage2.getReceiptHandle()) @@ -248,12 +191,7 @@ public void testNackQueueMessage() throws JMSException { when(sqsMessage2.getQueueUrl()) .thenReturn(QUEUE_URL_2); - SQSMessageConsumerPrefetch.MessageManager msgManager2 = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager2.getMessage()) - .thenReturn(sqsMessage2); - - when(msgManager2.getPrefetchManager()) - .thenReturn(mock(PrefetchManager.class)); + SQSMessageConsumerPrefetch.MessageManager msgManager2 = new SQSMessageConsumerPrefetch.MessageManager(mock(PrefetchManager.class), sqsMessage2); SQSSession.CallbackEntry entry1 = new SQSSession.CallbackEntry(msgListener, msgManager1); SQSSession.CallbackEntry entry2 = new SQSSession.CallbackEntry(msgListener, msgManager2); @@ -267,9 +205,9 @@ public void testNackQueueMessage() throws JMSException { .thenReturn(entry1) .thenReturn(entry2); - List nackMessageIdentifiers = new ArrayList(); - nackMessageIdentifiers.add(new SQSMessageIdentifier(QUEUE_URL_1, "r1", "messageId1")); - nackMessageIdentifiers.add(new SQSMessageIdentifier(QUEUE_URL_2, "r2", "messageId2")); + List nackMessageIdentifiers = List.of( + new SQSMessageIdentifier(QUEUE_URL_1, "r1", "messageId1"), + new SQSMessageIdentifier(QUEUE_URL_2, "r2", "messageId2")); /* * Nack the messages @@ -287,7 +225,6 @@ public void testNackQueueMessage() throws JMSException { */ @Test public void testStartingCallbackThrowJMSException() throws JMSException, InterruptedException { - /* * Set up mocks */ @@ -301,11 +238,7 @@ public void testStartingCallbackThrowJMSException() throws JMSException, Interru when(prefetchManager.getMessageConsumer()) .thenReturn(consumer); - SQSMessageConsumerPrefetch.MessageManager msgManager1 = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager1.getMessage()) - .thenReturn(mock(SQSMessage.class)); - when(msgManager1.getPrefetchManager()) - .thenReturn(prefetchManager); + SQSMessageConsumerPrefetch.MessageManager msgManager1 = new SQSMessageConsumerPrefetch.MessageManager(prefetchManager, mock(SQSMessage.class)); SQSSession.CallbackEntry entry1 = new SQSSession.CallbackEntry(null, msgManager1); @@ -330,12 +263,11 @@ public void testStartingCallbackThrowJMSException() throws JMSException, Interru */ @Test public void testCallbackQueueEntryMessageListenerEmpty() throws JMSException, InterruptedException { - /* * Set up mocks */ doNothing() - .doThrow(new JMSException("Closing")) + .doThrow(new JMSException("Closing")) .when(sqsSession).startingCallback(any(SQSMessageConsumer.class)); SQSMessageConsumerPrefetch.MessageManager msgManager1 = createMessageManager(1); @@ -367,13 +299,12 @@ public void testCallbackQueueEntryMessageListenerEmpty() throws JMSException, In verify(sqsSessionRunnable).nackQueuedMessages(); // Verify that we nack the message - ArgumentCaptor captor = ArgumentCaptor.forClass(List.class); verify(negativeAcknowledger, times(2)).bulkAction(captor.capture(), eq(1)); - List allCaptured = captor.getAllValues(); - List captured = (List)allCaptured.get(0); + List> allCaptured = captor.getAllValues(); + List captured = allCaptured.get(0); assertEquals(QUEUE_URL_1, captured.get(0).getQueueUrl()); assertEquals("r1", captured.get(0).getReceiptHandle()); - captured = (List)allCaptured.get(1); + captured = allCaptured.get(1); assertEquals(QUEUE_URL_2, captured.get(0).getQueueUrl()); assertEquals("r2", captured.get(0).getReceiptHandle()); @@ -388,12 +319,11 @@ public void testCallbackQueueEntryMessageListenerEmpty() throws JMSException, In */ @Test public void testCallbackQueueEntryMessageAckThrowsJMSException() throws JMSException, InterruptedException { - /* * Set up mocks */ doNothing() - .doThrow(new JMSException("Closing")) + .doThrow(new JMSException("Closing")) .when(sqsSession).startingCallback(consumer); SQSMessage sqsMessage1 = mock(SQSMessage.class); @@ -408,11 +338,7 @@ public void testCallbackQueueEntryMessageAckThrowsJMSException() throws JMSExcep when(prefetchManager.getMessageConsumer()) .thenReturn(consumer); - SQSMessageConsumerPrefetch.MessageManager msgManager1 = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager1.getMessage()) - .thenReturn(sqsMessage1); - when(msgManager1.getPrefetchManager()) - .thenReturn(prefetchManager); + SQSMessageConsumerPrefetch.MessageManager msgManager1 = new SQSMessageConsumerPrefetch.MessageManager(prefetchManager, sqsMessage1); // Throw an exception when try to acknowledge the message doThrow(new JMSException("Exception")) @@ -444,13 +370,12 @@ public void testCallbackQueueEntryMessageAckThrowsJMSException() throws JMSExcep verify(sqsMessage1).acknowledge(); // Verify that we nack the message - ArgumentCaptor captor = ArgumentCaptor.forClass(List.class); verify(negativeAcknowledger, times(2)).bulkAction(captor.capture(), eq(1)); - List allCaptured = captor.getAllValues(); - List captured = (List)allCaptured.get(0); + List> allCaptured = captor.getAllValues(); + List captured = allCaptured.get(0); assertEquals(QUEUE_URL_1, captured.get(0).getQueueUrl()); assertEquals("r1", captured.get(0).getReceiptHandle()); - captured = (List)allCaptured.get(1); + captured = allCaptured.get(1); assertEquals(QUEUE_URL_2, captured.get(0).getQueueUrl()); assertEquals("r2", captured.get(0).getReceiptHandle()); @@ -463,12 +388,11 @@ public void testCallbackQueueEntryMessageAckThrowsJMSException() throws JMSExcep */ @Test public void testCallbackQueueEntryMessageNAckThrowsJMSException() throws JMSException, InterruptedException { - /* * Set up mocks */ doNothing() - .doThrow(new JMSException("Closing")) + .doThrow(new JMSException("Closing")) .when(sqsSession).startingCallback(consumer); SQSMessage sqsMessage1 = mock(SQSMessage.class); @@ -483,11 +407,7 @@ public void testCallbackQueueEntryMessageNAckThrowsJMSException() throws JMSExce when(prefetchManager.getMessageConsumer()) .thenReturn(consumer); - SQSMessageConsumerPrefetch.MessageManager msgManager1 = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager1.getMessage()) - .thenReturn(sqsMessage1); - when(msgManager1.getPrefetchManager()) - .thenReturn(prefetchManager); + SQSMessageConsumerPrefetch.MessageManager msgManager1 = new SQSMessageConsumerPrefetch.MessageManager(prefetchManager, sqsMessage1); // Set message listener as null to force a nack SQSSession.CallbackEntry entry1 = new SQSSession.CallbackEntry(null, msgManager1); @@ -501,10 +421,6 @@ public void testCallbackQueueEntryMessageNAckThrowsJMSException() throws JMSExce when(callbackQueue.isEmpty()) .thenReturn(true); - // Throw an exception when try to negative acknowledge the message - doThrow(new JMSException("Exception")) - .when(negativeAcknowledger).action(QUEUE_URL_1, Collections.singletonList("r1")); - /* * Nack the messages, exception expected */ @@ -515,17 +431,16 @@ public void testCallbackQueueEntryMessageNAckThrowsJMSException() throws JMSExce */ verify(sqsSession, times(2)).startingCallback(consumer); verify(sqsSessionRunnable).nackQueuedMessages(); - - ArgumentCaptor captor = ArgumentCaptor.forClass(List.class); + verify(negativeAcknowledger, times(2)).bulkAction(captor.capture(), eq(1)); - List allCaptured = captor.getAllValues(); - List captured = (List)allCaptured.get(0); + List> allCaptured = captor.getAllValues(); + List captured = allCaptured.get(0); assertEquals(QUEUE_URL_1, captured.get(0).getQueueUrl()); assertEquals("r1", captured.get(0).getReceiptHandle()); - captured = (List)allCaptured.get(1); + captured = allCaptured.get(1); assertEquals(QUEUE_URL_2, captured.get(0).getQueueUrl()); assertEquals("r2", captured.get(0).getReceiptHandle()); - + verify(sqsSession).finishedCallback(); } @@ -533,15 +448,14 @@ public void testCallbackQueueEntryMessageNAckThrowsJMSException() throws JMSExce * Test schedule callback */ @Test - public void testScheduleCallBack() throws JMSException, InterruptedException { - + public void testScheduleCallBack() { /* * Set up mocks */ - sqsSessionRunnable.callbackQueue = new ArrayDeque(); + sqsSessionRunnable.callbackQueue = new ArrayDeque<>(); MessageListener msgListener = mock(MessageListener.class); - SQSMessageConsumerPrefetch.MessageManager msgManager = mock(SQSMessageConsumerPrefetch.MessageManager.class); + SQSMessageConsumerPrefetch.MessageManager msgManager = new SQSMessageConsumerPrefetch.MessageManager(null, null); /* * Nack the messages, exception expected */ @@ -551,8 +465,8 @@ public void testScheduleCallBack() throws JMSException, InterruptedException { SQSSession.CallbackEntry entry = sqsSessionRunnable.callbackQueue.pollFirst(); - assertEquals(msgListener, entry.getMessageListener()); - assertEquals(msgManager, entry.getMessageManager()); + assertEquals(msgListener, entry.messageListener()); + assertEquals(msgManager, entry.messageManager()); } /** @@ -560,13 +474,12 @@ public void testScheduleCallBack() throws JMSException, InterruptedException { */ @Test public void testMessageNotAckWithClientAckMode() throws JMSException, InterruptedException { - - /** + /* * Set up mocks */ sqsSessionRunnable = spy(new SQSSessionCallbackScheduler(sqsSession, - AcknowledgeMode.ACK_AUTO.withOriginalAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE), - acknowledger, negativeAcknowledger)); + AcknowledgeMode.ACK_AUTO.withOriginalAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE), + acknowledger, negativeAcknowledger)); sqsSessionRunnable.callbackQueue = callbackQueue; doNothing() @@ -585,11 +498,7 @@ public void testMessageNotAckWithClientAckMode() throws JMSException, Interrupte when(prefetchManager.getMessageConsumer()) .thenReturn(consumer); - SQSMessageConsumerPrefetch.MessageManager msgManager1 = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager1.getMessage()) - .thenReturn(sqsMessage1); - when(msgManager1.getPrefetchManager()) - .thenReturn(prefetchManager); + SQSMessageConsumerPrefetch.MessageManager msgManager1 = new SQSMessageConsumerPrefetch.MessageManager(prefetchManager, sqsMessage1); MessageListener msgListener = mock(MessageListener.class); SQSSession.CallbackEntry entry1 = new SQSSession.CallbackEntry(msgListener, msgManager1); @@ -620,65 +529,64 @@ public void testMessageNotAckWithClientAckMode() throws JMSException, Interrupte * Test that no auto ack messages occurs when client acknowledge is set */ @Test - public void testWhenListenerThrowsWhenAutoAckThenCallbackQueuePurgedFromMessagesWithSameQueueAndGroup() throws JMSException, InterruptedException { - - /** + public void testWhenListenerThrowsWhenAutoAckThenCallbackQueuePurgedFromMessagesWithSameQueueAndGroup() + throws JMSException, InterruptedException { + /* * Set up mocks */ sqsSessionRunnable = spy(new SQSSessionCallbackScheduler(sqsSession, - AcknowledgeMode.ACK_AUTO.withOriginalAcknowledgeMode(Session.AUTO_ACKNOWLEDGE), - acknowledger, negativeAcknowledger)); + AcknowledgeMode.ACK_AUTO.withOriginalAcknowledgeMode(Session.AUTO_ACKNOWLEDGE), + acknowledger, negativeAcknowledger)); MessageListener messageListener = mock(MessageListener.class); doThrow(RuntimeException.class) - .when(messageListener).onMessage(any(javax.jms.Message.class)); - - List messages = new ArrayList(); - messages.add(createFifoMessageManager("queue1", "group1", "message1", "handle1")); - messages.add(createFifoMessageManager("queue1", "group1", "message2", "handle2")); - messages.add(createFifoMessageManager("queue2", "group1", "message3", "handle3")); - messages.add(createFifoMessageManager("queue1", "group2", "message4", "handle4")); - messages.add(createFifoMessageManager("queue1", "group1", "message5", "handle5")); - messages.add(createFifoMessageManager("queue2", "group2", "message6", "handle6")); + .when(messageListener).onMessage(any(jakarta.jms.Message.class)); + + List messages = List.of( + createFifoMessageManager("queue1", "group1", "message1", "handle1"), + createFifoMessageManager("queue1", "group1", "message2", "handle2"), + createFifoMessageManager("queue2", "group1", "message3", "handle3"), + createFifoMessageManager("queue1", "group2", "message4", "handle4"), + createFifoMessageManager("queue1", "group1", "message5", "handle5"), + createFifoMessageManager("queue2", "group2", "message6", "handle6")); sqsSessionRunnable.scheduleCallBacks(messageListener, messages); - + doNothing() - .doThrow(new JMSException("Closing")) - .when(sqsSession).startingCallback(consumer); - + .doThrow(new JMSException("Closing")) + .when(sqsSession).startingCallback(consumer); + sqsSessionRunnable.run(); - - ArgumentCaptor messageIdentifierListCaptor = ArgumentCaptor.forClass(List.class); + ArgumentCaptor indexOfMessageCaptor = ArgumentCaptor.forClass(Integer.class); - verify(negativeAcknowledger, times(3)).bulkAction(messageIdentifierListCaptor.capture(), indexOfMessageCaptor.capture()); - List nackedMessages = messageIdentifierListCaptor.getAllValues().get(0); - int nackedMessagesSize = indexOfMessageCaptor.getAllValues().get(0).intValue(); - + verify(negativeAcknowledger, times(3)).bulkAction( + captor.capture(), indexOfMessageCaptor.capture()); + List nackedMessages = captor.getAllValues().get(0); + int nackedMessagesSize = indexOfMessageCaptor.getAllValues().get(0); + //failing to process 'message1' should nack all messages for queue1 and group1, that is 'message1', 'message2' and 'message5' assertEquals(3, nackedMessagesSize); - assertEquals("message1", nackedMessages.get(0).getSQSMessageID()); - assertEquals("message2", nackedMessages.get(1).getSQSMessageID()); - assertEquals("message5", nackedMessages.get(2).getSQSMessageID()); + assertEquals("message1", nackedMessages.get(0).getSqsMessageId()); + assertEquals("message2", nackedMessages.get(1).getSqsMessageId()); + assertEquals("message5", nackedMessages.get(2).getSqsMessageId()); } - private SQSMessageConsumerPrefetch.MessageManager createFifoMessageManager(String queueUrl, String groupId, String messageId, String receiptHandle) throws JMSException { - Map attributes = new HashMap(); - attributes.put(SQSMessagingClientConstants.SEQUENCE_NUMBER, "728374687246872364"); - attributes.put(SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID, messageId); - attributes.put(SQSMessagingClientConstants.MESSAGE_GROUP_ID, groupId); - attributes.put(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "0"); + private SQSMessageConsumerPrefetch.MessageManager createFifoMessageManager( + String queueUrl, String groupId, String messageId, String receiptHandle) throws JMSException { + Map attributes = Map.of( + SQSMessagingClientConstants.SEQUENCE_NUMBER, "728374687246872364", + SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID, messageId, + SQSMessagingClientConstants.MESSAGE_GROUP_ID, groupId, + SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT, "0"); Message message = Message.builder() - .body("body") - .messageId(messageId) - .receiptHandle(receiptHandle) - .attributesWithStrings(attributes) - .build(); + .body("body") + .messageId(messageId) + .receiptHandle(receiptHandle) + .attributesWithStrings(attributes) + .build(); SQSMessage sqsMessage = new SQSTextMessage(acknowledger, queueUrl, message); PrefetchManager prefetchManager = mock(PrefetchManager.class); - when(prefetchManager.getMessageConsumer()) - .thenReturn(consumer); - SQSMessageConsumerPrefetch.MessageManager msgManager = new SQSMessageConsumerPrefetch.MessageManager(prefetchManager, sqsMessage); - return msgManager; + lenient().when(prefetchManager.getMessageConsumer()).thenReturn(consumer); + return new SQSMessageConsumerPrefetch.MessageManager(prefetchManager, sqsMessage); } private SQSMessageConsumerPrefetch.MessageManager createMessageManager(int index) { @@ -694,11 +602,6 @@ private SQSMessageConsumerPrefetch.MessageManager createMessageManager(int index when(prefetchManager.getMessageConsumer()) .thenReturn(consumer); - SQSMessageConsumerPrefetch.MessageManager msgManager = mock(SQSMessageConsumerPrefetch.MessageManager.class); - when(msgManager.getMessage()) - .thenReturn(sqsMessage); - when(msgManager.getPrefetchManager()) - .thenReturn(prefetchManager); - return msgManager; + return new SQSMessageConsumerPrefetch.MessageManager(prefetchManager, sqsMessage); } } diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSSessionTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSSessionTest.java index 628c875..2a08379 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSSessionTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSSessionTest.java @@ -14,62 +14,36 @@ */ package com.amazon.sqs.javamessaging; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; +import com.amazon.sqs.javamessaging.message.SQSObjectMessage; +import com.amazon.sqs.javamessaging.message.SQSTextMessage; +import jakarta.jms.IllegalStateException; +import jakarta.jms.Message; +import jakarta.jms.Queue; +import jakarta.jms.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; +import software.amazon.awssdk.services.sqs.model.*; + +import java.util.*; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; -import javax.jms.Destination; -import javax.jms.IllegalStateException; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.ObjectMessage; -import javax.jms.Queue; -import javax.jms.TextMessage; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; - -import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; -import com.amazon.sqs.javamessaging.message.SQSObjectMessage; -import com.amazon.sqs.javamessaging.message.SQSTextMessage; - -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequestEntry; -import software.amazon.awssdk.services.sqs.model.GetQueueUrlResponse; -import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; -import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; -import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.*; /** * Test the SQSSessionTest class */ -public class SQSSessionTest { +public class SQSSessionTest { private static final String QUEUE_URL = "queueUrl"; private static final String QUEUE_NAME = "queueName"; @@ -79,14 +53,14 @@ public class SQSSessionTest { private SQSConnection parentSQSConnection; private Set messageConsumers; private Set messageProducers; - private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); + private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); private SQSMessageConsumer consumer1; private SQSMessageConsumer consumer2; private SQSMessageProducer producer1; private SQSMessageProducer producer2; private AmazonSQSMessagingClientWrapper sqsClientJMSWrapper; - @Before + @BeforeEach public void setup() throws JMSException { sqsClientJMSWrapper = mock(AmazonSQSMessagingClientWrapper.class); @@ -95,23 +69,21 @@ public void setup() throws JMSException { when(parentSQSConnection.getWrappedAmazonSQSClient()) .thenReturn(sqsClientJMSWrapper); - messageConsumers = new HashSet(); - messageProducers = new HashSet(); - consumer1 = mock(SQSMessageConsumer.class); - when(consumer1.getQueue()).thenReturn(new SQSQueueDestination("name1", "url1")); consumer2 = mock(SQSMessageConsumer.class); + + when(consumer1.getQueue()).thenReturn(new SQSQueueDestination("name1", "url1")); when(consumer2.getQueue()).thenReturn(new SQSQueueDestination("name2", "url2")); - messageConsumers.add(consumer1); - messageConsumers.add(consumer2); + + messageConsumers = new HashSet<>(Set.of(consumer1, consumer2)); producer1 = mock(SQSMessageProducer.class); producer2 = mock(SQSMessageProducer.class); - messageProducers.add(producer1); - messageProducers.add(producer2); + + messageProducers = new HashSet<>(Set.of(producer1, producer2)); sqsSession = spy(new SQSSession(parentSQSConnection, AcknowledgeMode.ACK_AUTO, - messageConsumers, messageProducers)); + messageConsumers, messageProducers)); } /** @@ -119,7 +91,6 @@ public void setup() throws JMSException { */ @Test public void testStopNoOpIfAlreadyClosed() throws JMSException { - /* * Set up session */ @@ -129,12 +100,9 @@ public void testStopNoOpIfAlreadyClosed() throws JMSException { /* * stop consumer */ - try { - sqsSession.stop(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.stop()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed"); /* * Verify results @@ -147,8 +115,7 @@ public void testStopNoOpIfAlreadyClosed() throws JMSException { * Test stop is a no op if closing */ @Test - public void testStopNoOpIfClosing() throws JMSException { - + public void testStopNoOpIfClosing() { /* * Set up session */ @@ -157,12 +124,9 @@ public void testStopNoOpIfClosing() throws JMSException { /* * stop consumer */ - try { - sqsSession.stop(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed or closing", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.stop()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed or closing"); /* * Verify results @@ -175,8 +139,7 @@ public void testStopNoOpIfClosing() throws JMSException { * Test start is a no op if closing */ @Test - public void testStartNoOpIfClosing() throws JMSException { - + public void testStartNoOpIfClosing() { /* * Set up session */ @@ -185,12 +148,9 @@ public void testStartNoOpIfClosing() throws JMSException { /* * stop consumer */ - try { - sqsSession.start(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed or closing", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.start()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed or closing"); /* * Verify results @@ -204,7 +164,6 @@ public void testStartNoOpIfClosing() throws JMSException { */ @Test public void testStartNoOpIfAlreadyClosed() throws JMSException { - /* * Set up session */ @@ -218,12 +177,9 @@ public void testStartNoOpIfAlreadyClosed() throws JMSException { /* * stop consumer */ - try { - sqsSession.start(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.start()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed"); /* * Verify results @@ -237,7 +193,6 @@ public void testStartNoOpIfAlreadyClosed() throws JMSException { */ @Test public void testStopBlocksOnStateLock() throws InterruptedException { - /* * Set up the latches and mocks */ @@ -247,17 +202,14 @@ public void testStopBlocksOnStateLock() throws InterruptedException { final CountDownLatch passedSessionStopCall = new CountDownLatch(1); // Run a thread to hold the stateLock - executorService.execute(new Runnable() { - @Override - public void run() { - try { - synchronized (sqsSession.getStateLock()) { - holdStateLock.countDown(); - mainRelease.await(); - } - } catch (InterruptedException e) { - e.printStackTrace(); + executorService.execute(() -> { + try { + synchronized (sqsSession.getStateLock()) { + holdStateLock.countDown(); + mainRelease.await(); } + } catch (InterruptedException e) { + e.printStackTrace(); } }); @@ -265,16 +217,13 @@ public void run() { holdStateLock.await(); // Run another thread that tries to stop the session while state lock is been held - executorService.execute(new Runnable() { - @Override - public void run() { - beforeSessionStopCall.countDown(); - try { - sqsSession.stop(); - passedSessionStopCall.countDown(); - } catch (IllegalStateException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + beforeSessionStopCall.countDown(); + try { + sqsSession.stop(); + passedSessionStopCall.countDown(); + } catch (IllegalStateException e) { + e.printStackTrace(); } }); @@ -282,7 +231,7 @@ public void run() { Thread.sleep(10); // Ensure that we wait on state lock - assertEquals(false, passedSessionStopCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedSessionStopCall.await(2, TimeUnit.SECONDS)); // Release the thread holding the state lock mainRelease.countDown(); @@ -299,7 +248,6 @@ public void run() { */ @Test public void testStartBlocksOnStateLock() throws InterruptedException { - /* * Set up the latches and mocks */ @@ -309,17 +257,14 @@ public void testStartBlocksOnStateLock() throws InterruptedException { final CountDownLatch passedSessionStartCall = new CountDownLatch(1); // Run a thread to hold the stateLock - executorService.execute(new Runnable() { - @Override - public void run() { - try { - synchronized (sqsSession.getStateLock()) { - holdStateLock.countDown(); - mainRelease.await(); - } - } catch (InterruptedException e) { - e.printStackTrace(); + executorService.execute(() -> { + try { + synchronized (sqsSession.getStateLock()) { + holdStateLock.countDown(); + mainRelease.await(); } + } catch (InterruptedException e) { + e.printStackTrace(); } }); @@ -327,16 +272,13 @@ public void run() { holdStateLock.await(); // Run another thread that tries to start the session while state lock is been held - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeSessionStartCall.countDown(); - sqsSession.start(); - passedSessionStartCall.countDown(); - } catch (IllegalStateException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeSessionStartCall.countDown(); + sqsSession.start(); + passedSessionStartCall.countDown(); + } catch (IllegalStateException e) { + e.printStackTrace(); } }); @@ -344,7 +286,7 @@ public void run() { Thread.sleep(10); // Ensure that we wait on state lock - assertEquals(false, passedSessionStartCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedSessionStartCall.await(2, TimeUnit.SECONDS)); // Release the thread holding the state lock mainRelease.countDown(); @@ -363,103 +305,61 @@ public void run() { public void testUnsupportedFeature() throws JMSException { assertFalse(sqsSession.getTransacted()); - try { - sqsSession.commit(); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.commit()) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.rollback(); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.rollback()) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.unsubscribe("test"); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.unsubscribe("test")) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.createTopic("topic"); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createTopic("topic")) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.createDurableSubscriber(null, "name"); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createDurableSubscriber(null, "name")) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.createDurableSubscriber(null, "name", "messageSelector", false); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createDurableSubscriber(null, "name", "messageSelector", false)) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.createBrowser(null); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createBrowser(null)) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.createBrowser(null, "messageSelector"); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createBrowser(null, "messageSelector")) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.createTemporaryQueue(); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createTemporaryQueue()) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.createTemporaryTopic(); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createTemporaryTopic()) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.getMessageListener(); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.getMessageListener()) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.setMessageListener(null); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.setMessageListener(null)) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.createStreamMessage(); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createStreamMessage()) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); - try { - sqsSession.createMapMessage(); - fail(); - } catch (JMSException e) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, e.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createMapMessage()) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } /** @@ -467,7 +367,6 @@ public void testUnsupportedFeature() throws JMSException { */ @Test public void testWaitForAllCallbackCompleteBlocksOnStateLock() throws InterruptedException, JMSException { - /* * Set up the latches and mocks */ @@ -478,12 +377,10 @@ public void testWaitForAllCallbackCompleteBlocksOnStateLock() throws Interrupted sqsSession = new SQSSession(parentSQSConnection, AcknowledgeMode.ACK_AUTO, messageConsumers, messageProducers); sqsSession.start(); - MessageListener msgListener = mock(MessageListener.class); - SQSMessageConsumerPrefetch.MessageManager msgManager = mock(SQSMessageConsumerPrefetch.MessageManager.class); PrefetchManager prefetchManager = new PrefetchManager() { @Override - public void messageDispatched() { + public void messageDispatched() { holdStateLock.countDown(); try { mainRelease.await(); @@ -502,8 +399,7 @@ public SQSMessageConsumer getMessageConsumer() { } }; - when(msgManager.getPrefetchManager()) - .thenReturn(prefetchManager); + SQSMessageConsumerPrefetch.MessageManager msgManager = new SQSMessageConsumerPrefetch.MessageManager(prefetchManager, null); sqsSession.getSqsSessionRunnable().scheduleCallBacks(null, Collections.singletonList(msgManager)); @@ -511,21 +407,17 @@ public SQSMessageConsumer getMessageConsumer() { holdStateLock.await(); // Run another thread that tries to close the consumer while state lock is been held - executorService.execute(new Runnable() { - @Override - public void run() { - beforeSessionWaitCall.countDown(); - sqsSession.waitForCallbackComplete(); - passedSessionWaitCall.countDown(); - - } + executorService.execute(() -> { + beforeSessionWaitCall.countDown(); + sqsSession.waitForCallbackComplete(); + passedSessionWaitCall.countDown(); }); beforeSessionWaitCall.await(); Thread.sleep(10); // Ensure that we wait on state lock this time is longer then waitForAllCallbackComplete timeoutMillis input - assertEquals(false, passedSessionWaitCall.await(1, TimeUnit.SECONDS)); + assertFalse(passedSessionWaitCall.await(1, TimeUnit.SECONDS)); // Release the state lock mainRelease.countDown(); @@ -539,7 +431,6 @@ public void run() { */ @Test public void testWaitForAllCallbackComplete() throws InterruptedException, JMSException { - /* * Set up session and mocks */ @@ -552,24 +443,21 @@ public void testWaitForAllCallbackComplete() throws InterruptedException, JMSExc /* * call waitForAllCallbackComplete in different thread */ - executorService.execute(new Runnable() { - @Override - public void run() { - beforeWaitCall.countDown(); - sqsSession.waitForCallbackComplete(); - passedWaitCall.countDown(); - } + executorService.execute(() -> { + beforeWaitCall.countDown(); + sqsSession.waitForCallbackComplete(); + passedWaitCall.countDown(); }); // Yield execution to allow the consumer to wait - assertEquals(true, beforeWaitCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeWaitCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Release the lock and ensure that we are still waiting since the prefetch message still equal to the limit synchronized (sqsSession.getStateLock()) { sqsSession.getStateLock().notifyAll(); } - assertEquals(false, passedWaitCall.await(1, TimeUnit.SECONDS)); + assertFalse(passedWaitCall.await(1, TimeUnit.SECONDS)); // Simulate callback finished sqsSession.finishedCallback(); @@ -580,8 +468,7 @@ public void run() { * Test finishedCallback decrease callbackCounter */ @Test - public void testFinishedCallback() throws InterruptedException, JMSException { - + public void testFinishedCallback() throws JMSException { /* * Set up session */ @@ -595,7 +482,7 @@ public void testFinishedCallback() throws InterruptedException, JMSException { /* * verify result */ - assertEquals(false, sqsSession.isCallbackActive()); + assertFalse(sqsSession.isCallbackActive()); } /** @@ -603,12 +490,11 @@ public void testFinishedCallback() throws InterruptedException, JMSException { */ @Test public void testStartingCallbackNoOpIfAlreadyClosed() throws InterruptedException, JMSException { - /* * Set up session */ sqsSession.setClosed(true); - sqsSession.setActiveConsumerInCallback(null); + sqsSession.setActiveConsumerInCallback(null); /* * Start callback */ @@ -617,30 +503,24 @@ public void testStartingCallbackNoOpIfAlreadyClosed() throws InterruptedExceptio /* * Verify results */ - assertEquals(false, sqsSession.isCallbackActive()); + assertFalse(sqsSession.isCallbackActive()); } /** * Test startingCallback is a no op if closing */ @Test - public void testStartingCallbackNoOpIfClosing() throws InterruptedException { - + public void testStartingCallbackNoOpIfClosing() { /* * Set up session */ sqsSession.setClosing(true); sqsSession.setActiveConsumerInCallback(null); - + /* * Starting Callback */ - try { - sqsSession.startingCallback(consumer1); - fail(); - } catch (JMSException e) { - e.printStackTrace(); - } + assertThatThrownBy(() -> sqsSession.startingCallback(consumer1)).isInstanceOf(JMSException.class); } /** @@ -648,7 +528,6 @@ public void testStartingCallbackNoOpIfClosing() throws InterruptedException { */ @Test public void testStartingCallback() throws InterruptedException { - /* * Set up session and mocks */ @@ -659,30 +538,25 @@ public void testStartingCallback() throws InterruptedException { /* * call startingCallback in different thread */ - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeWaitCall.countDown(); - sqsSession.startingCallback(consumer1); - passedWaitCall.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (JMSException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeWaitCall.countDown(); + sqsSession.startingCallback(consumer1); + passedWaitCall.countDown(); + } catch (InterruptedException | JMSException e) { + e.printStackTrace(); } }); // Yield execution to allow the session to wait - assertEquals(true, beforeWaitCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeWaitCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Release the lock and ensure that we are still waiting since the did not run synchronized (sqsSession.getStateLock()) { sqsSession.getStateLock().notifyAll(); } - assertEquals(false, passedWaitCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedWaitCall.await(2, TimeUnit.SECONDS)); // Simulate callback finished sqsSession.setRunning(true); @@ -691,7 +565,7 @@ public void run() { sqsSession.getStateLock().notifyAll(); } passedWaitCall.await(); - assertEquals(true, sqsSession.isCallbackActive()); + assertTrue(sqsSession.isCallbackActive()); } /** @@ -699,7 +573,6 @@ public void run() { */ @Test public void testRemoveConsumer() { - assertEquals(2, messageConsumers.size()); /* @@ -719,7 +592,6 @@ public void testRemoveConsumer() { */ @Test public void testRemoveProducer() { - assertEquals(2, messageProducers.size()); /* @@ -739,8 +611,7 @@ public void testRemoveProducer() { * Test create queue when session is already closed */ @Test - public void testCreateQueueWhenAlreadyClosed() throws JMSException { - + public void testCreateQueueWhenAlreadyClosed() { /* * Set up session */ @@ -749,12 +620,9 @@ public void testCreateQueueWhenAlreadyClosed() throws JMSException { /* * Create queue */ - try { - sqsSession.createQueue("Test"); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createQueue("Test")) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed"); } /** @@ -762,8 +630,7 @@ public void testCreateQueueWhenAlreadyClosed() throws JMSException { */ @Test public void testCreateQueue() throws JMSException { - - GetQueueUrlResponse result = GetQueueUrlResponse.builder().queueUrl(QUEUE_URL).build(); + GetQueueUrlResponse result = GetQueueUrlResponse.builder().queueUrl(QUEUE_URL).build(); when(sqsClientJMSWrapper.getQueueUrl(QUEUE_NAME)) .thenReturn(result); @@ -775,17 +642,16 @@ public void testCreateQueue() throws JMSException { /* * Verify results */ - assert(queue instanceof SQSQueueDestination); + assert (queue instanceof SQSQueueDestination); assertEquals(QUEUE_NAME, queue.getQueueName()); assertEquals(QUEUE_URL, ((SQSQueueDestination) queue).getQueueUrl()); } - + /** * Test create queue when session is already closed */ @Test public void testCreateQueueWithOwnerAccountId() throws JMSException { - GetQueueUrlResponse result = GetQueueUrlResponse.builder().queueUrl(QUEUE_URL).build(); when(sqsClientJMSWrapper.getQueueUrl(QUEUE_NAME, OWNER_ACCOUNT_ID)) .thenReturn(result); @@ -798,7 +664,7 @@ public void testCreateQueueWithOwnerAccountId() throws JMSException { /* * Verify results */ - assert(queue instanceof SQSQueueDestination); + assert (queue instanceof SQSQueueDestination); assertEquals(QUEUE_NAME, queue.getQueueName()); assertEquals(QUEUE_URL, ((SQSQueueDestination) queue).getQueueUrl()); } @@ -807,42 +673,35 @@ public void testCreateQueueWithOwnerAccountId() throws JMSException { * Test create consumer when session is already closed */ @Test - public void testCreateConsumerProducerWhenAlreadyClosed() throws JMSException { - + public void testCreateConsumerProducerWhenAlreadyClosed() { /* * Set up session */ sqsSession.setClosed(true); - Destination destination = new Destination() {}; + Destination destination = new Destination() { + }; /* * Create consumer */ - try { - sqsSession.createConsumer(destination); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createConsumer(destination)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed"); /* * Create producer */ - try { - sqsSession.createProducer(destination); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createProducer(destination)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed"); } /** * Test create consumer when session is closing */ @Test - public void testCreateConsumerProducerWhenClosing() throws JMSException { - + public void testCreateConsumerProducerWhenClosing() { /* * Set up session */ @@ -852,54 +711,42 @@ public void testCreateConsumerProducerWhenClosing() throws JMSException { /* * Create consumer */ - try { - sqsSession.createConsumer(destination); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed or closing", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createConsumer(destination)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed or closing"); /* * Create producer */ - try { - sqsSession.createProducer(destination); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed or closing", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createProducer(destination)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed or closing"); } /** * Test create consumer when destination is non SQSQueueDestination */ @Test - public void testCreateConsumerProducerNonSQSQueueDestination() throws JMSException { - + public void testCreateConsumerProducerNonSQSQueueDestination() { /* * Set up session */ - Destination destination = new Destination() {}; + Destination destination = new Destination() { + }; /* * Create consumer */ - try { - sqsSession.createConsumer(destination); - fail(); - } catch(JMSException jmse) { - assertEquals("Actual type of Destination/Queue has to be SQSQueueDestination", jmse.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createConsumer(destination)) + .isInstanceOf(JMSException.class) + .hasMessage("Actual type of Destination/Queue has to be SQSQueueDestination"); - /* + /* * Create producer */ - try { - sqsSession.createProducer(destination); - fail(); - } catch(JMSException jmse) { - assertEquals("Actual type of Destination/Queue has to be SQSQueueDestination", jmse.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createProducer(destination)) + .isInstanceOf(JMSException.class) + .hasMessage("Actual type of Destination/Queue has to be SQSQueueDestination"); } /** @@ -907,7 +754,6 @@ public void testCreateConsumerProducerNonSQSQueueDestination() throws JMSExcepti */ @Test public void testCreateConsumerNotRunning() throws JMSException { - /* * Set up session */ @@ -935,7 +781,6 @@ public void testCreateConsumerNotRunning() throws JMSException { */ @Test public void testCreateConsumerRunning() throws JMSException { - /* * Set up session */ @@ -962,8 +807,7 @@ public void testCreateConsumerRunning() throws JMSException { * Test create consumer with non null message selector */ @Test - public void testCreateConsumerNonNullMessageSelector() throws JMSException { - + public void testCreateConsumerNonNullMessageSelector() { /* * Set up session */ @@ -976,19 +820,13 @@ public void testCreateConsumerNonNullMessageSelector() throws JMSException { /* * Create consumer */ - try { - sqsSession.createConsumer(destination, "Selector"); - fail(); - } catch(JMSException jmse) { - assertEquals("SQSSession does not support MessageSelector. This should be null.", jmse.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createConsumer(destination, "Selector")) + .isInstanceOf(JMSException.class) + .hasMessage("SQSSession does not support MessageSelector. This should be null."); - try { - sqsSession.createConsumer(destination, "Selector", true); - fail(); - } catch(JMSException jmse) { - assertEquals("SQSSession does not support MessageSelector. This should be null.", jmse.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createConsumer(destination, "Selector", true)) + .isInstanceOf(JMSException.class) + .hasMessage("SQSSession does not support MessageSelector. This should be null."); } /** @@ -996,7 +834,6 @@ public void testCreateConsumerNonNullMessageSelector() throws JMSException { */ @Test public void testCreateConsumerWithMessageSelector() throws JMSException { - /* * Set up session */ @@ -1010,7 +847,7 @@ public void testCreateConsumerWithMessageSelector() throws JMSException { * Create consumer */ sqsSession.createConsumer(destination, null); - sqsSession.createConsumer(destination, null,true); + sqsSession.createConsumer(destination, null, true); /* * Verify results @@ -1023,7 +860,6 @@ public void testCreateConsumerWithMessageSelector() throws JMSException { */ @Test public void testCreateProducer() throws JMSException { - /* * Set up session */ @@ -1050,44 +886,41 @@ public void testRecover() throws JMSException, InterruptedException { when(parentSQSConnection.getNumberOfMessagesToPrefetch()).thenReturn(4); when(sqsClientJMSWrapper.getQueueUrl("queue1")) - .thenReturn(GetQueueUrlResponse.builder().queueUrl("queueUrl1").build()); + .thenReturn(GetQueueUrlResponse.builder().queueUrl("queueUrl1").build()); when(sqsClientJMSWrapper.receiveMessage(argThat(new ReceiveRequestMatcher("queueUrl1")))) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group1", "message1", "queue1-group1-message1")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group2", "message2", "queue1-group2-message2")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group3", "message3", "queue1-group3-message3")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group1", "message4", "queue1-group1-message4")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group2", "message5", "queue1-group2-message5")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group3", "message6", "queue1-group3-message6")).build()) - .thenReturn(ReceiveMessageResponse.builder().build()); - + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group1", "message1", "queue1-group1-message1")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group2", "message2", "queue1-group2-message2")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group3", "message3", "queue1-group3-message3")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group1", "message4", "queue1-group1-message4")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group2", "message5", "queue1-group2-message5")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group3", "message6", "queue1-group3-message6")).build()) + .thenReturn(ReceiveMessageResponse.builder().build()); + when(sqsClientJMSWrapper.getQueueUrl("queue2")) - .thenReturn(GetQueueUrlResponse.builder().queueUrl("queueUrl2").build()); + .thenReturn(GetQueueUrlResponse.builder().queueUrl("queueUrl2").build()); when(sqsClientJMSWrapper.receiveMessage(argThat(new ReceiveRequestMatcher("queueUrl2")))) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group1", "message1", "queue2-group1-message1")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group2", "message2", "queue2-group2-message2")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group3", "message3", "queue2-group3-message3")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group1", "message4", "queue2-group1-message4")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group2", "message5", "queue2-group2-message5")).build()) - .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group3", "message6", "queue2-group3-message6")).build()) - .thenReturn(ReceiveMessageResponse.builder().build()); - + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group1", "message1", "queue2-group1-message1")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group2", "message2", "queue2-group2-message2")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group3", "message3", "queue2-group3-message3")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group1", "message4", "queue2-group1-message4")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group2", "message5", "queue2-group2-message5")).build()) + .thenReturn(ReceiveMessageResponse.builder().messages(createFifoMessage("group3", "message6", "queue2-group3-message6")).build()) + .thenReturn(ReceiveMessageResponse.builder().build()); + MessageConsumer consumer1 = sqsSession.createConsumer(sqsSession.createQueue("queue1")); MessageConsumer consumer2 = sqsSession.createConsumer(sqsSession.createQueue("queue2")); final CountDownLatch listenerRelease = new CountDownLatch(1); - consumer2.setMessageListener(new MessageListener() { - @Override - public void onMessage(Message message) { - try { - listenerRelease.await(); - } catch (InterruptedException e) { - } + consumer2.setMessageListener(message -> { + try { + listenerRelease.await(); + } catch (InterruptedException ignored) { } }); - + sqsSession.start(); - + Message message1 = consumer1.receive(); - + //let's give a moment for the background threads to: //prefetch another message for queue1 //dispatch message to listener for queue2 @@ -1097,7 +930,7 @@ public void onMessage(Message message) { * Recover */ sqsSession.recover(); - + //at this point we have two unacked messages: //queue1-group1-message1 //queue2-group1-message1 @@ -1116,68 +949,56 @@ public void onMessage(Message message) { //queue2-group1-message1 //queue1-group1-message4 //queue2-group1-message4 - + ArgumentCaptor changeVisibilityCaptor = ArgumentCaptor.forClass(ChangeMessageVisibilityBatchRequest.class); verify(sqsClientJMSWrapper, times(2)).changeMessageVisibilityBatch(changeVisibilityCaptor.capture()); - List changeVisibilityRequests = changeVisibilityCaptor.getAllValues(); - - Set handles = new HashSet(); - for (ChangeMessageVisibilityBatchRequest request : changeVisibilityRequests) { - for (ChangeMessageVisibilityBatchRequestEntry entry : request.entries()) { - handles.add(entry.receiptHandle()); - } - } - + + Set handles = changeVisibilityCaptor.getAllValues().stream() + .map(ChangeMessageVisibilityBatchRequest::entries) + .flatMap(Collection::stream) + .map(ChangeMessageVisibilityBatchRequestEntry::receiptHandle) + .collect(Collectors.toSet()); + assertEquals(4, handles.size()); assertTrue(handles.contains("queue1-group1-message1")); assertTrue(handles.contains("queue1-group1-message4")); assertTrue(handles.contains("queue2-group1-message1")); assertTrue(handles.contains("queue2-group1-message4")); - + listenerRelease.countDown(); - + sqsSession.close(); } - - private static class ReceiveRequestMatcher extends ArgumentMatcher { - private String queueUrl; - - public ReceiveRequestMatcher(String queueUrl) { - this.queueUrl = queueUrl; - } + + private record ReceiveRequestMatcher(String queueUrl) implements ArgumentMatcher { @Override - public boolean matches(Object argument) { - if (argument instanceof ReceiveMessageRequest) { - ReceiveMessageRequest request = (ReceiveMessageRequest)argument; - return queueUrl.equals(request.queueUrl()); - } else { - return false; - } + public boolean matches(ReceiveMessageRequest request) { + return request != null && queueUrl.equals(request.queueUrl()); } - + } - private software.amazon.awssdk.services.sqs.model.Message createFifoMessage(String groupId, String messageId, String receiptHandle) throws JMSException { - Map attributes = new HashMap<>(); - attributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.SEQUENCE_NUMBER), "728374687246872364"); - attributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID), messageId); - attributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.MESSAGE_GROUP_ID), groupId); - attributes.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "0"); - - return software.amazon.awssdk.services.sqs.model.Message.builder() - .body("body") - .messageId(messageId) - .receiptHandle(receiptHandle) - .attributes(attributes).build(); + private software.amazon.awssdk.services.sqs.model.Message createFifoMessage( + String groupId, String messageId, String receiptHandle) { + Map attributes = Map.of( + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.SEQUENCE_NUMBER), "728374687246872364", + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID), messageId, + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.MESSAGE_GROUP_ID), groupId, + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "0"); + + return software.amazon.awssdk.services.sqs.model.Message.builder() + .body("body") + .messageId(messageId) + .receiptHandle(receiptHandle) + .attributes(attributes).build(); } /** * Test recover when session is already closed */ @Test - public void testRecoverWhenAlreadyClosed() throws JMSException { - + public void testRecoverWhenAlreadyClosed() { /* * Set up session */ @@ -1186,12 +1007,9 @@ public void testRecoverWhenAlreadyClosed() throws JMSException { /* * Recover */ - try { - sqsSession.recover(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.recover()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed"); } /** @@ -1199,7 +1017,6 @@ public void testRecoverWhenAlreadyClosed() throws JMSException { */ @Test public void testDoCloseWhenAlreadyClosed() throws JMSException { - /* * Set up session */ @@ -1225,8 +1042,7 @@ public void testDoCloseWhenAlreadyClosed() throws JMSException { * Test close when session is closing */ @Test - public void testDoCloseWhenClosing() throws JMSException, InterruptedException { - + public void testDoCloseWhenClosing() throws InterruptedException { /* * Set up session and mocks */ @@ -1237,28 +1053,25 @@ public void testDoCloseWhenClosing() throws JMSException, InterruptedException { /* * call doClose in different thread */ - executorService.execute(new Runnable() { - @Override - public void run() { - try { - beforeDoCloseCall.countDown(); - sqsSession.doClose(); - passedDoCloseCall.countDown(); - } catch (JMSException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + try { + beforeDoCloseCall.countDown(); + sqsSession.doClose(); + passedDoCloseCall.countDown(); + } catch (JMSException e) { + e.printStackTrace(); } }); // Yield execution to allow the session to wait - assertEquals(true, beforeDoCloseCall.await(10, TimeUnit.SECONDS)); + assertTrue(beforeDoCloseCall.await(10, TimeUnit.SECONDS)); Thread.sleep(10); // Release the lock and ensure that we are still waiting since the did not run synchronized (sqsSession.getStateLock()) { sqsSession.getStateLock().notifyAll(); } - assertEquals(false, passedDoCloseCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedDoCloseCall.await(2, TimeUnit.SECONDS)); // Simulate session closed sqsSession.setClosed(true); @@ -1267,15 +1080,13 @@ public void run() { sqsSession.getStateLock().notifyAll(); } passedDoCloseCall.await(); - } /** * Test do close */ @Test - public void testDoClose() throws JMSException, InterruptedException { - + public void testDoClose() throws JMSException { sqsSession = new SQSSession(parentSQSConnection, AcknowledgeMode.ACK_AUTO, messageConsumers, messageProducers); /* * Do close @@ -1300,7 +1111,6 @@ public void testDoClose() throws JMSException, InterruptedException { */ @Test public void testCloseWhenAlreadyClosed() throws JMSException { - /* * Set up session */ @@ -1322,7 +1132,6 @@ public void testCloseWhenAlreadyClosed() throws JMSException { */ @Test public void testClose() throws JMSException, InterruptedException { - /* * Set up the latches and mocks */ @@ -1332,23 +1141,20 @@ public void testClose() throws JMSException, InterruptedException { sqsSession.setActiveConsumerInCallback(consumer1); // Run thread that tries to close the session while activeConsumerInCallback is set - executorService.execute(new Runnable() { - @Override - public void run() { - beforeCloseCall.countDown(); - try { - sqsSession.close(); - passedCloseCall.countDown(); - } catch (JMSException e) { - e.printStackTrace(); - } + executorService.execute(() -> { + beforeCloseCall.countDown(); + try { + sqsSession.close(); + passedCloseCall.countDown(); + } catch (JMSException e) { + e.printStackTrace(); } }); beforeCloseCall.await(); // Ensure that we wait on activeConsumerInCallback - assertEquals(false, passedCloseCall.await(2, TimeUnit.SECONDS)); + assertFalse(passedCloseCall.await(2, TimeUnit.SECONDS)); // Release the activeConsumerInCallback sqsSession.finishedCallback(); @@ -1356,7 +1162,7 @@ public void run() { // Ensure that the session close completed passedCloseCall.await(); - assertEquals(true, sqsSession.isClosed()); + assertTrue(sqsSession.isClosed()); } /** @@ -1364,7 +1170,6 @@ public void run() { */ @Test public void testCloseFromActiveCallbackThread() throws JMSException, InterruptedException { - /* * Set up session */ @@ -1374,19 +1179,14 @@ public void testCloseFromActiveCallbackThread() throws JMSException, Interrupted /* * Verify result */ - try { - sqsSession.close(); - fail(); - } catch (IllegalStateException ise) { - // expected - } + assertThatThrownBy(() -> sqsSession.close()).isInstanceOf(IllegalStateException.class); } /** * Test create receiver */ @Test - public void testCreateReceiver() throws JMSException, InterruptedException { + public void testCreateReceiver() throws JMSException { SQSQueueDestination destination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL); /* @@ -1405,7 +1205,7 @@ public void testCreateReceiver() throws JMSException, InterruptedException { * Test create sender */ @Test - public void testCreateSender() throws JMSException, InterruptedException { + public void testCreateSender() throws JMSException { SQSQueueDestination destination = new SQSQueueDestination(QUEUE_NAME, QUEUE_URL); /* @@ -1423,36 +1223,28 @@ public void testCreateSender() throws JMSException, InterruptedException { * Test create message */ @Test - public void testCreateMessage() throws JMSException, InterruptedException { - + public void testCreateMessage() { /* * Create message */ - try { - sqsSession.createMessage(); - fail(); - } catch(JMSException jsme) { - assertEquals(SQSMessagingClientConstants.UNSUPPORTED_METHOD, jsme.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createMessage()) + .isInstanceOf(JMSException.class) + .hasMessage(SQSMessagingClientConstants.UNSUPPORTED_METHOD); } /** * Test create byte message */ @Test - public void testCreateObjectMessage() throws JMSException, InterruptedException { - + public void testCreateObjectMessage() throws JMSException { sqsSession.setClosed(true); /* * Create bytes message */ - try { - sqsSession.createObjectMessage(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createObjectMessage()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed"); sqsSession.setClosed(false); @@ -1472,19 +1264,15 @@ public void testCreateObjectMessage() throws JMSException, InterruptedException * Test create byte message */ @Test - public void testCreateTextMessage() throws JMSException, InterruptedException { - + public void testCreateTextMessage() throws JMSException { sqsSession.setClosed(true); /* * Create bytes message */ - try { - sqsSession.createTextMessage(); - fail(); - } catch(IllegalStateException ise) { - assertEquals("Session is closed", ise.getMessage()); - } + assertThatThrownBy(() -> sqsSession.createTextMessage()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("Session is closed"); sqsSession.setClosed(false); diff --git a/src/test/java/com/amazon/sqs/javamessaging/UnorderedAcknowledgerTest.java b/src/test/java/com/amazon/sqs/javamessaging/UnorderedAcknowledgerTest.java index 1be0e50..349da35 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/UnorderedAcknowledgerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/UnorderedAcknowledgerTest.java @@ -14,35 +14,28 @@ */ package com.amazon.sqs.javamessaging; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import javax.jms.JMSException; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; -import com.amazon.sqs.javamessaging.SQSSession; import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; import com.amazon.sqs.javamessaging.message.SQSMessage; - +import jakarta.jms.JMSException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; import java.util.ArrayList; import java.util.List; import java.util.Random; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.*; + /** * Test the UnorderedAcknowledgerTest class */ public class UnorderedAcknowledgerTest extends AcknowledgerCommon { - @Before + @BeforeEach public void setupUnordered() throws JMSException { amazonSQSClient = mock(AmazonSQSMessagingClientWrapper.class); acknowledger = AcknowledgeMode.ACK_UNORDERED.createAcknowledger(amazonSQSClient, mock(SQSSession.class)); @@ -69,7 +62,7 @@ public void testAcknowledge() throws JMSException { populateMessage(populateMessageSize); int counter = 0; - List populatedMessagesCopy = new ArrayList(populatedMessages); + List populatedMessagesCopy = new ArrayList<>(populatedMessages); while (!populatedMessagesCopy.isEmpty()) { int rand = new Random().nextInt(populatedMessagesCopy.size()); diff --git a/src/test/java/com/amazon/sqs/javamessaging/message/SQSBytesMessageTest.java b/src/test/java/com/amazon/sqs/javamessaging/message/SQSBytesMessageTest.java index 6aa6b0a..4d13749 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/message/SQSBytesMessageTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/message/SQSBytesMessageTest.java @@ -14,56 +14,34 @@ */ package com.amazon.sqs.javamessaging.message; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -import javax.jms.JMSException; -import javax.jms.MessageEOFException; -import javax.jms.MessageFormatException; -import javax.jms.MessageNotReadableException; -import javax.jms.MessageNotWriteableException; - -import org.junit.Before; -import org.junit.Test; - import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; import com.amazon.sqs.javamessaging.SQSSession; - +import jakarta.jms.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import software.amazon.awssdk.services.sqs.model.Message; import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; import software.amazon.awssdk.utils.BinaryUtils; +import java.io.*; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + /** * Test the SQSBytesMessageTest class */ public class SQSBytesMessageTest { - + private SQSSession mockSQSSession; - - private final static Map MESSAGE_SYSTEM_ATTRIBUTES; - static { - MESSAGE_SYSTEM_ATTRIBUTES = new HashMap<>(); - MESSAGE_SYSTEM_ATTRIBUTES.put(MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); - } - @Before + private final static Map MESSAGE_SYSTEM_ATTRIBUTES = Map.of( + MessageSystemAttributeName.fromValue(SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT), "1"); + + @BeforeEach public void setUp() { mockSQSSession = mock(SQSSession.class); } @@ -75,8 +53,8 @@ public void setUp() { public void testReadWrite() throws JMSException { when(mockSQSSession.createBytesMessage()).thenReturn(new SQSBytesMessage()); SQSBytesMessage msg = (SQSBytesMessage) mockSQSSession.createBytesMessage(); - - byte[] byteArray = new byte[] { 1, 0, 'a', 65 }; + + byte[] byteArray = new byte[]{1, 0, 'a', 65}; byte byteData = 'a'; short shortVal = 123; @@ -91,7 +69,7 @@ public void testReadWrite() throws JMSException { msg.writeByte(byteData); msg.writeUTF("UTF-String"); msg.writeObject("test"); - + msg.reset(); int length = (int) msg.getBodyLength(); @@ -102,10 +80,10 @@ public void testReadWrite() throws JMSException { } Message message = Message.builder() - .body(BinaryUtils.toBase64(body)) - .attributes(MESSAGE_SYSTEM_ATTRIBUTES) - .build(); - + .body(BinaryUtils.toBase64(body)) + .attributes(MESSAGE_SYSTEM_ATTRIBUTES) + .build(); + SQSBytesMessage receivedByteMsg = new SQSBytesMessage(null, "", message); byte[] byteArray1 = new byte[4]; receivedByteMsg.readBytes(byteArray1); @@ -125,77 +103,21 @@ public void testReadWrite() throws JMSException { assertEquals("UTF-String", receivedByteMsg.readUTF()); assertEquals("test", receivedByteMsg.readUTF()); - /* - * Validate MessageEOFException is thrown when reaching end of file - */ - try { - receivedByteMsg.readBoolean(); - fail(); - } catch (MessageEOFException exception) { - } - - try { - receivedByteMsg.readUnsignedByte(); - fail(); - } catch (MessageEOFException exception) { - } + assertThatThrownBy(receivedByteMsg::readBoolean).isInstanceOf(MessageEOFException.class); + assertThatThrownBy(receivedByteMsg::readUnsignedByte).isInstanceOf(MessageEOFException.class); byte[] arr = new byte[10]; assertEquals(-1, receivedByteMsg.readBytes(arr, 10)); - try { - receivedByteMsg.readByte(); - fail(); - } catch (MessageEOFException exception) { - } - - try { - receivedByteMsg.readShort(); - fail(); - } catch (MessageEOFException exception) { - } - - try { - receivedByteMsg.readUnsignedShort(); - fail(); - } catch (MessageEOFException exception) { - } - - try { - receivedByteMsg.readInt(); - fail(); - } catch (MessageEOFException exception) { - } - - try { - receivedByteMsg.readLong(); - fail(); - } catch (MessageEOFException exception) { - } - - try { - receivedByteMsg.readFloat(); - fail(); - } catch (MessageEOFException exception) { - } - - try { - receivedByteMsg.readDouble(); - fail(); - } catch (MessageEOFException exception) { - } - - try { - receivedByteMsg.readChar(); - fail(); - } catch (MessageEOFException exception) { - } - - try { - receivedByteMsg.readUTF(); - fail(); - } catch (MessageEOFException exception) { - } + assertThatThrownBy(receivedByteMsg::readByte).isInstanceOf(MessageEOFException.class); + assertThatThrownBy(receivedByteMsg::readShort).isInstanceOf(MessageEOFException.class); + assertThatThrownBy(receivedByteMsg::readUnsignedShort).isInstanceOf(MessageEOFException.class); + assertThatThrownBy(receivedByteMsg::readInt).isInstanceOf(MessageEOFException.class); + assertThatThrownBy(receivedByteMsg::readLong).isInstanceOf(MessageEOFException.class); + assertThatThrownBy(receivedByteMsg::readFloat).isInstanceOf(MessageEOFException.class); + assertThatThrownBy(receivedByteMsg::readDouble).isInstanceOf(MessageEOFException.class); + assertThatThrownBy(receivedByteMsg::readChar).isInstanceOf(MessageEOFException.class); + assertThatThrownBy(receivedByteMsg::readUTF).isInstanceOf(MessageEOFException.class); } /** @@ -203,7 +125,6 @@ public void testReadWrite() throws JMSException { */ @Test public void testReadIOException() throws JMSException, IOException { - /* * Set up mocks */ @@ -224,82 +145,17 @@ public void testReadIOException() throws JMSException, IOException { msg.setDataIn(dis); - try { - msg.readBoolean(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readByte(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readUnsignedByte(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readShort(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readUnsignedShort(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readInt(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readLong(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readFloat(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readDouble(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readChar(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } - - try { - msg.readUTF(); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } + assertThatThrownBy(msg::readBoolean).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readByte).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readUnsignedByte).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readShort).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readUnsignedShort).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readInt).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readLong).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readFloat).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readDouble).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readChar).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); + assertThatThrownBy(msg::readUTF).isInstanceOf(JMSException.class).cause().isEqualTo(ioException); } /** @@ -307,7 +163,6 @@ public void testReadIOException() throws JMSException, IOException { */ @Test public void testWriteIOException() throws JMSException, IOException { - /* * Set up mocks */ @@ -316,8 +171,6 @@ public void testWriteIOException() throws JMSException, IOException { OutputStream os = mock(OutputStream.class); DataOutputStream dos = new DataOutputStream(os); - - SQSBytesMessage msg = spy(new SQSBytesMessage()); doNothing() .when(msg).checkCanRead(); @@ -336,71 +189,47 @@ public void testWriteIOException() throws JMSException, IOException { assertEquals(ioException, exception.getCause()); } - try { - msg.writeByte((byte)1); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } + assertThatThrownBy(() -> msg.writeByte((byte) 1)) + .isInstanceOf(JMSException.class) + .cause().isEqualTo(ioException); - try { - msg.writeShort((short)1); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } + assertThatThrownBy(() -> msg.writeShort((short) 1)) + .isInstanceOf(JMSException.class) + .cause().isEqualTo(ioException); - try { - msg.writeInt(1); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } + assertThatThrownBy(() -> msg.writeInt(1)) + .isInstanceOf(JMSException.class) + .cause().isEqualTo(ioException); - try { - msg.writeLong(1290772974281L); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } + assertThatThrownBy(() -> msg.writeLong(1290772974281L)) + .isInstanceOf(JMSException.class) + .cause().isEqualTo(ioException); - try { - msg.writeFloat(3.1457f); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } + assertThatThrownBy(() -> msg.writeFloat(3.1457f)) + .isInstanceOf(JMSException.class) + .cause().isEqualTo(ioException); - try { - msg.writeDouble(2.1768); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } + assertThatThrownBy(() -> msg.writeDouble(2.1768)) + .isInstanceOf(JMSException.class) + .cause().isEqualTo(ioException); - try { - msg.writeChar('a'); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } + assertThatThrownBy(() -> msg.writeChar('a')) + .isInstanceOf(JMSException.class) + .cause().isEqualTo(ioException); - try { - msg.writeUTF("test"); - fail(); - } catch (JMSException exception) { - assertEquals(ioException, exception.getCause()); - } + assertThatThrownBy(() -> msg.writeUTF("test")) + .isInstanceOf(JMSException.class) + .cause().isEqualTo(ioException); } /** * Test write object function */ @Test - public void testWriteObject() throws JMSException, IOException { + public void testWriteObject() throws JMSException { SQSBytesMessage msg = new SQSBytesMessage(); - byte[] byteArray = new byte[] { 1, 0, 'a', 65 }; + byte[] byteArray = new byte[]{1, 0, 'a', 65}; byte byteData = 'a'; short shortVal = 123; @@ -425,9 +254,9 @@ public void testWriteObject() throws JMSException, IOException { } Message message = Message.builder() - .attributes(MESSAGE_SYSTEM_ATTRIBUTES) - .body(BinaryUtils.toBase64(body)) - .build(); + .attributes(MESSAGE_SYSTEM_ATTRIBUTES) + .body(BinaryUtils.toBase64(body)) + .build(); SQSBytesMessage receivedByteMsg = new SQSBytesMessage(null, "", message); byte[] byteArray1 = new byte[4]; receivedByteMsg.readBytes(byteArray1); @@ -449,33 +278,22 @@ public void testWriteObject() throws JMSException, IOException { /* * Check write object error cases */ - try { - msg.writeObject(new HashSet()); - fail(); - } catch(MessageFormatException exception) { - // expected - } + assertThatThrownBy(() -> msg.writeObject(Set.of())).isInstanceOf(MessageFormatException.class); /* * Check write object error cases */ - try { - msg.writeObject(null); - fail(); - } catch(NullPointerException exception) { - // expected - } + assertThatThrownBy(() -> msg.writeObject(null)).isInstanceOf(NullPointerException.class); } /** * Test clear body */ @Test - public void testClearBody() throws JMSException, IOException { - + public void testClearBody() throws JMSException { SQSBytesMessage msg = new SQSBytesMessage(); - byte[] byteArray = new byte[] { 1, 0, 'a', 65 }; + byte[] byteArray = new byte[]{1, 0, 'a', 65}; msg.writeBytes(byteArray); msg.clearBody(); @@ -485,11 +303,9 @@ public void testClearBody() throws JMSException, IOException { /* * Verify message is in write-only mode */ - try { - msg.readBytes(readByteArray); - } catch(MessageNotReadableException exception) { - assertEquals("Message is not readable", exception.getMessage()); - } + assertThatThrownBy(() -> msg.readBytes(readByteArray)) + .isInstanceOf(MessageNotReadableException.class) + .hasMessage("Message is not readable"); msg.writeBytes(byteArray); } @@ -497,28 +313,30 @@ public void testClearBody() throws JMSException, IOException { /** * Test after reset the message is read only mode */ - @Test(expected = MessageNotWriteableException.class) + @Test public void testNotWriteable() throws JMSException { SQSBytesMessage msg = new SQSBytesMessage(); - byte[] byteArray = new byte[] { 'a', 0, 34, 65 }; + byte[] byteArray = new byte[]{'a', 0, 34, 65}; msg.writeBytes(byteArray); msg.reset(); assertEquals('a', msg.readByte()); - msg.writeInt(10); + + assertThatThrownBy(() -> msg.writeInt(10)) + .isInstanceOf(MessageNotWriteableException.class); } /** * Test before reset the message is not readable */ - @Test(expected = MessageNotReadableException.class) + @Test public void testReadable() throws JMSException { when(mockSQSSession.createBytesMessage()).thenReturn(new SQSBytesMessage()); - SQSBytesMessage msg = (SQSBytesMessage) mockSQSSession.createBytesMessage(); - - byte[] byteArray = new byte[] { 'a', 0, 34, 65 }; + SQSBytesMessage msg = (SQSBytesMessage) mockSQSSession.createBytesMessage(); + + byte[] byteArray = new byte[]{'a', 0, 34, 65}; msg.writeBytes(byteArray); - - msg.readInt(); + + assertThatThrownBy(msg::readInt).isInstanceOf(MessageNotReadableException.class); } } diff --git a/src/test/java/com/amazon/sqs/javamessaging/message/SQSMessageTest.java b/src/test/java/com/amazon/sqs/javamessaging/message/SQSMessageTest.java index 81cfc38..0f5c46e 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/message/SQSMessageTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/message/SQSMessageTest.java @@ -14,32 +14,26 @@ */ package com.amazon.sqs.javamessaging.message; -import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT; -import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.JMSX_DELIVERY_COUNT; -import static org.junit.Assert.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import javax.jms.JMSException; - import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; import com.amazon.sqs.javamessaging.SQSSession; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; -import com.amazon.sqs.javamessaging.message.SQSMessage; -import org.junit.Before; -import org.junit.Test; - -import javax.jms.Message; -import javax.jms.MessageFormatException; -import javax.jms.MessageNotWriteableException; - -import junit.framework.Assert; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageFormatException; +import jakarta.jms.MessageNotWriteableException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; import java.util.*; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.JMSX_DELIVERY_COUNT; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + /** * Test the SQSMessageTest class */ @@ -57,7 +51,7 @@ public class SQSMessageTest { final String myCustomString = "myCustomString"; final String myNumber = "myNumber"; - @Before + @BeforeEach public void setup() { mockSQSSession = mock(SQSSession.class); } @@ -81,53 +75,53 @@ public void testProperty() throws JMSException { message.setStringProperty("myString", "StringValue"); message.setStringProperty("myNumber", "500"); - Assert.assertTrue(message.propertyExists("myTrueBoolean")); - Assert.assertEquals(message.getObjectProperty("myTrueBoolean"), true); - Assert.assertEquals(message.getBooleanProperty("myTrueBoolean"), true); - - Assert.assertTrue(message.propertyExists("myFalseBoolean")); - Assert.assertEquals(message.getObjectProperty("myFalseBoolean"), false); - Assert.assertEquals(message.getBooleanProperty("myFalseBoolean"), false); - - Assert.assertTrue(message.propertyExists("myInteger")); - Assert.assertEquals(message.getObjectProperty("myInteger"), 100); - Assert.assertEquals(message.getIntProperty("myInteger"), 100); - - Assert.assertTrue(message.propertyExists("myDouble")); - Assert.assertEquals(message.getObjectProperty("myDouble"), 2.1768); - Assert.assertEquals(message.getDoubleProperty("myDouble"), 2.1768); - - Assert.assertTrue(message.propertyExists("myFloat")); - Assert.assertEquals(message.getObjectProperty("myFloat"), 3.1457f); - Assert.assertEquals(message.getFloatProperty("myFloat"), 3.1457f); - - Assert.assertTrue(message.propertyExists("myLong")); - Assert.assertEquals(message.getObjectProperty("myLong"), 1290772974281L); - Assert.assertEquals(message.getLongProperty("myLong"), 1290772974281L); - - Assert.assertTrue(message.propertyExists("myShort")); - Assert.assertEquals(message.getObjectProperty("myShort"), (short) 123); - Assert.assertEquals(message.getShortProperty("myShort"), (short) 123); - - Assert.assertTrue(message.propertyExists("myByteProperty")); - Assert.assertEquals(message.getObjectProperty("myByteProperty"), (byte) 'a'); - Assert.assertEquals(message.getByteProperty("myByteProperty"), (byte) 'a'); - - Assert.assertTrue(message.propertyExists("myString")); - Assert.assertEquals(message.getObjectProperty("myString"), "StringValue"); - Assert.assertEquals(message.getStringProperty("myString"), "StringValue"); - - Assert.assertTrue(message.propertyExists("myNumber")); - Assert.assertEquals(message.getObjectProperty("myNumber"), "500"); - Assert.assertEquals(message.getStringProperty("myNumber"), "500"); - Assert.assertEquals(message.getLongProperty("myNumber"), 500L); - Assert.assertEquals(message.getFloatProperty("myNumber"), 500f); - Assert.assertEquals(message.getShortProperty("myNumber"), (short) 500); - Assert.assertEquals(message.getDoubleProperty("myNumber"), 500d); - Assert.assertEquals(message.getIntProperty("myNumber"), 500); + assertTrue(message.propertyExists("myTrueBoolean")); + assertEquals(message.getObjectProperty("myTrueBoolean"), true); + assertTrue(message.getBooleanProperty("myTrueBoolean")); + + assertTrue(message.propertyExists("myFalseBoolean")); + assertEquals(message.getObjectProperty("myFalseBoolean"), false); + assertFalse(message.getBooleanProperty("myFalseBoolean")); + + assertTrue(message.propertyExists("myInteger")); + assertEquals(message.getObjectProperty("myInteger"), 100); + assertEquals(message.getIntProperty("myInteger"), 100); + + assertTrue(message.propertyExists("myDouble")); + assertEquals(message.getObjectProperty("myDouble"), 2.1768); + assertEquals(message.getDoubleProperty("myDouble"), 2.1768, 0.0); + + assertTrue(message.propertyExists("myFloat")); + assertEquals(message.getObjectProperty("myFloat"), 3.1457f); + assertEquals(message.getFloatProperty("myFloat"), 3.1457f, 0.0); + + assertTrue(message.propertyExists("myLong")); + assertEquals(message.getObjectProperty("myLong"), 1290772974281L); + assertEquals(message.getLongProperty("myLong"), 1290772974281L); + + assertTrue(message.propertyExists("myShort")); + assertEquals(message.getObjectProperty("myShort"), (short) 123); + assertEquals(message.getShortProperty("myShort"), (short) 123); + + assertTrue(message.propertyExists("myByteProperty")); + assertEquals(message.getObjectProperty("myByteProperty"), (byte) 'a'); + assertEquals(message.getByteProperty("myByteProperty"), (byte) 'a'); + + assertTrue(message.propertyExists("myString")); + assertEquals(message.getObjectProperty("myString"), "StringValue"); + assertEquals(message.getStringProperty("myString"), "StringValue"); + + assertTrue(message.propertyExists("myNumber")); + assertEquals(message.getObjectProperty("myNumber"), "500"); + assertEquals(message.getStringProperty("myNumber"), "500"); + assertEquals(message.getLongProperty("myNumber"), 500L); + assertEquals(message.getFloatProperty("myNumber"), 500f, 0.0); + assertEquals(message.getShortProperty("myNumber"), (short) 500); + assertEquals(message.getDoubleProperty("myNumber"), 500d, 0.0); + assertEquals(message.getIntProperty("myNumber"), 500); // Validate property names - Set propertyNamesSet = new HashSet(Arrays.asList( + Set propertyNamesSet = Set.of( "myTrueBoolean", "myFalseBoolean", "myInteger", @@ -137,26 +131,26 @@ public void testProperty() throws JMSException { "myShort", "myByteProperty", "myNumber", - "myString")); + "myString"); - Enumeration propertyNames = message.getPropertyNames(); + Enumeration propertyNames = message.getPropertyNames(); int counter = 0; while (propertyNames.hasMoreElements()) { assertTrue(propertyNamesSet.contains(propertyNames.nextElement())); counter++; } assertEquals(propertyNamesSet.size(), counter); - + message.clearProperties(); - Assert.assertFalse(message.propertyExists("myTrueBoolean")); - Assert.assertFalse(message.propertyExists("myInteger")); - Assert.assertFalse(message.propertyExists("myDouble")); - Assert.assertFalse(message.propertyExists("myFloat")); - Assert.assertFalse(message.propertyExists("myLong")); - Assert.assertFalse(message.propertyExists("myShort")); - Assert.assertFalse(message.propertyExists("myByteProperty")); - Assert.assertFalse(message.propertyExists("myString")); - Assert.assertFalse(message.propertyExists("myNumber")); + assertFalse(message.propertyExists("myTrueBoolean")); + assertFalse(message.propertyExists("myInteger")); + assertFalse(message.propertyExists("myDouble")); + assertFalse(message.propertyExists("myFloat")); + assertFalse(message.propertyExists("myLong")); + assertFalse(message.propertyExists("myShort")); + assertFalse(message.propertyExists("myByteProperty")); + assertFalse(message.propertyExists("myString")); + assertFalse(message.propertyExists("myNumber")); propertyNames = message.getPropertyNames(); assertFalse(propertyNames.hasMoreElements()); @@ -167,28 +161,20 @@ public void testProperty() throws JMSException { */ @Test public void testCheckPropertyWritePermissions() throws JMSException { - SQSMessage msg = new SQSMessage(); - - + SQSMessage msg = new SQSMessage(); msg.checkBodyWritePermissions(); - msg.setBodyWritePermissions(false); - try { - msg.checkBodyWritePermissions(); - } catch (MessageNotWriteableException exception) { - assertEquals("Message body is not writable", exception.getMessage()); - } + assertThatThrownBy(msg::checkBodyWritePermissions) + .isInstanceOf(MessageNotWriteableException.class) + .hasMessage("Message body is not writable"); msg.checkPropertyWritePermissions(); - msg.setWritePermissionsForProperties(false); - try { - msg.checkPropertyWritePermissions(); - } catch (MessageNotWriteableException exception) { - assertEquals("Message properties are not writable", exception.getMessage()); - } + assertThatThrownBy(msg::checkPropertyWritePermissions) + .isInstanceOf(MessageNotWriteableException.class) + .hasMessage("Message properties are not writable"); } /** @@ -196,33 +182,24 @@ public void testCheckPropertyWritePermissions() throws JMSException { */ @Test public void testGetPrimitiveProperty() throws JMSException { - SQSMessage msg = spy(new SQSMessage()); - when(msg.getObjectProperty("testProperty")) - .thenReturn(null); - - try { - msg.getPrimitiveProperty(null, String.class); - } catch (NullPointerException npe) { - assertEquals("Property name is null", npe.getMessage()); - } + SQSMessage msg = spy(new SQSMessage()); + when(msg.getObjectProperty("testProperty")).thenReturn(null); - try { - msg.getPrimitiveProperty("testProperty", List.class); - } catch (NumberFormatException exp) { - assertEquals("Value of property with name testProperty is null.", exp.getMessage()); - } + assertThatThrownBy(() -> msg.getPrimitiveProperty(null, String.class)) + .isInstanceOf(NullPointerException.class) + .hasMessage("Property name is null"); - try { - msg.getPrimitiveProperty("testProperty", Double.class); - } catch (NullPointerException exp) { - assertEquals("Value of property with name testProperty is null.", exp.getMessage()); - } + assertThatThrownBy(() -> msg.getPrimitiveProperty("testProperty", List.class)) + .isInstanceOf(NumberFormatException.class) + .hasMessage("Value of property with name testProperty is null."); - try { - msg.getPrimitiveProperty("testProperty", Float.class); - } catch (NullPointerException exp) { - assertEquals("Value of property with name testProperty is null.", exp.getMessage()); - } + assertThatThrownBy(() -> msg.getPrimitiveProperty("testProperty", Double.class)) + .isInstanceOf(NullPointerException.class) + .hasMessage("Value of property with name testProperty is null."); + + assertThatThrownBy(() -> msg.getPrimitiveProperty("testProperty", Float.class)) + .isInstanceOf(NullPointerException.class) + .hasMessage("Value of property with name testProperty is null."); assertFalse(msg.getPrimitiveProperty("testProperty", Boolean.class)); assertNull(msg.getPrimitiveProperty("testProperty", String.class)); @@ -233,45 +210,33 @@ public void testGetPrimitiveProperty() throws JMSException { */ @Test public void testSetObjectProperty() throws JMSException { - SQSMessage msg = spy(new SQSMessage()); + SQSMessage msg = spy(new SQSMessage()); - try { - msg.setObjectProperty(null, 1); - } catch (IllegalArgumentException exception) { - assertEquals("Property name can not be null or empty.", exception.getMessage()); - } + assertThatThrownBy(() -> msg.setObjectProperty(null, 1)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Property name can not be null or empty."); - try { - msg.setObjectProperty("", 1); - } catch (IllegalArgumentException exception) { - assertEquals("Property name can not be null or empty.", exception.getMessage()); - } + assertThatThrownBy(() -> msg.setObjectProperty("", 1)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Property name can not be null or empty."); - try { - msg.setObjectProperty("Property", null); - } catch (IllegalArgumentException exception) { - assertEquals("Property value can not be null or empty.", exception.getMessage()); - } + assertThatThrownBy(() -> msg.setObjectProperty("Property", null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Property value can not be null or empty."); - try { - msg.setObjectProperty("Property", ""); - } catch (IllegalArgumentException exception) { - assertEquals("Property value can not be null or empty.", exception.getMessage()); - } + assertThatThrownBy(() -> msg.setObjectProperty("Property", "")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Property value can not be null or empty."); - try { - msg.setObjectProperty("Property", new HashSet()); - } catch (MessageFormatException exception) { - assertEquals("Value of property with name Property has incorrect type java.util.HashSet.", - exception.getMessage()); - } + assertThatThrownBy(() -> msg.setObjectProperty("Property", new HashSet<>())) + .isInstanceOf(MessageFormatException.class) + .hasMessage("Value of property with name Property has incorrect type java.util.HashSet."); msg.setWritePermissionsForProperties(false); - try { - msg.setObjectProperty("Property", "1"); - } catch (MessageNotWriteableException exception) { - assertEquals("Message properties are not writable", exception.getMessage()); - } + + assertThatThrownBy(() -> msg.setObjectProperty("Property", "1")) + .isInstanceOf(MessageNotWriteableException.class) + .hasMessage("Message properties are not writable"); msg.setWritePermissionsForProperties(true); msg.setObjectProperty("Property", "1"); @@ -284,68 +249,67 @@ public void testSetObjectProperty() throws JMSException { */ @Test public void testSQSMessageAttributeToProperty() throws JMSException { - Acknowledger ack = mock(Acknowledger.class); Map systemAttributes = new HashMap<>(); systemAttributes.put(MessageSystemAttributeName.fromValue(APPROXIMATE_RECEIVE_COUNT), "100"); - Map messageAttributes = new HashMap(); + Map messageAttributes = new HashMap<>(); messageAttributes.put(myTrueBoolean, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.BOOLEAN) - .stringValue("1") - .build()); + .dataType(SQSMessagingClientConstants.BOOLEAN) + .stringValue("1") + .build()); messageAttributes.put(myFalseBoolean, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.BOOLEAN) - .stringValue("0") - .build()); + .dataType(SQSMessagingClientConstants.BOOLEAN) + .stringValue("0") + .build()); messageAttributes.put(myInteger, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.INT) - .stringValue("100") - .build()); + .dataType(SQSMessagingClientConstants.INT) + .stringValue("100") + .build()); messageAttributes.put(myDouble, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.DOUBLE) - .stringValue("2.1768") - .build()); + .dataType(SQSMessagingClientConstants.DOUBLE) + .stringValue("2.1768") + .build()); messageAttributes.put(myFloat, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.FLOAT) - .stringValue("3.1457") - .build()); + .dataType(SQSMessagingClientConstants.FLOAT) + .stringValue("3.1457") + .build()); messageAttributes.put(myLong, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.LONG) - .stringValue("1290772974281") - .build()); + .dataType(SQSMessagingClientConstants.LONG) + .stringValue("1290772974281") + .build()); messageAttributes.put(myShort, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.SHORT) - .stringValue("123") - .build()); + .dataType(SQSMessagingClientConstants.SHORT) + .stringValue("123") + .build()); messageAttributes.put(myByte, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.BYTE) - .stringValue("1") - .build()); + .dataType(SQSMessagingClientConstants.BYTE) + .stringValue("1") + .build()); messageAttributes.put(myString, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.STRING) - .stringValue("StringValue") - .build()); + .dataType(SQSMessagingClientConstants.STRING) + .stringValue("StringValue") + .build()); messageAttributes.put(myCustomString, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.NUMBER + ".custom") - .stringValue("['one', 'two']") - .build()); + .dataType(SQSMessagingClientConstants.NUMBER + ".custom") + .stringValue("['one', 'two']") + .build()); messageAttributes.put(myNumber, MessageAttributeValue.builder() - .dataType(SQSMessagingClientConstants.NUMBER) - .stringValue("500") - .build()); + .dataType(SQSMessagingClientConstants.NUMBER) + .stringValue("500") + .build()); software.amazon.awssdk.services.sqs.model.Message sqsMessage = software.amazon.awssdk.services.sqs.model.Message.builder() .messageAttributes(messageAttributes) @@ -356,58 +320,58 @@ public void testSQSMessageAttributeToProperty() throws JMSException { SQSMessage message = new SQSMessage(ack, "QueueUrl", sqsMessage); - Assert.assertTrue(message.propertyExists(myTrueBoolean)); - Assert.assertEquals(message.getObjectProperty(myTrueBoolean), true); - Assert.assertEquals(message.getBooleanProperty(myTrueBoolean), true); + assertTrue(message.propertyExists(myTrueBoolean)); + assertEquals(message.getObjectProperty(myTrueBoolean), true); + assertTrue(message.getBooleanProperty(myTrueBoolean)); - Assert.assertTrue(message.propertyExists(myFalseBoolean)); - Assert.assertEquals(message.getObjectProperty(myFalseBoolean), false); - Assert.assertEquals(message.getBooleanProperty(myFalseBoolean), false); + assertTrue(message.propertyExists(myFalseBoolean)); + assertEquals(message.getObjectProperty(myFalseBoolean), false); + assertFalse(message.getBooleanProperty(myFalseBoolean)); - Assert.assertTrue(message.propertyExists(myInteger)); - Assert.assertEquals(message.getObjectProperty(myInteger), 100); - Assert.assertEquals(message.getIntProperty(myInteger), 100); + assertTrue(message.propertyExists(myInteger)); + assertEquals(message.getObjectProperty(myInteger), 100); + assertEquals(message.getIntProperty(myInteger), 100); - Assert.assertTrue(message.propertyExists(myDouble)); - Assert.assertEquals(message.getObjectProperty(myDouble), 2.1768); - Assert.assertEquals(message.getDoubleProperty(myDouble), 2.1768); + assertTrue(message.propertyExists(myDouble)); + assertEquals(message.getObjectProperty(myDouble), 2.1768); + assertEquals(message.getDoubleProperty(myDouble), 2.1768, 0.0); - Assert.assertTrue(message.propertyExists(myFloat)); - Assert.assertEquals(message.getObjectProperty(myFloat), 3.1457f); - Assert.assertEquals(message.getFloatProperty(myFloat), 3.1457f); + assertTrue(message.propertyExists(myFloat)); + assertEquals(message.getObjectProperty(myFloat), 3.1457f); + assertEquals(message.getFloatProperty(myFloat), 3.1457f, 0.0); - Assert.assertTrue(message.propertyExists(myLong)); - Assert.assertEquals(message.getObjectProperty(myLong), 1290772974281L); - Assert.assertEquals(message.getLongProperty(myLong), 1290772974281L); + assertTrue(message.propertyExists(myLong)); + assertEquals(message.getObjectProperty(myLong), 1290772974281L); + assertEquals(message.getLongProperty(myLong), 1290772974281L); - Assert.assertTrue(message.propertyExists(myShort)); - Assert.assertEquals(message.getObjectProperty(myShort), (short) 123); - Assert.assertEquals(message.getShortProperty(myShort), (short) 123); + assertTrue(message.propertyExists(myShort)); + assertEquals(message.getObjectProperty(myShort), (short) 123); + assertEquals(message.getShortProperty(myShort), (short) 123); - Assert.assertTrue(message.propertyExists(myByte)); - Assert.assertEquals(message.getObjectProperty(myByte), (byte) 1); - Assert.assertEquals(message.getByteProperty(myByte), (byte) 1); + assertTrue(message.propertyExists(myByte)); + assertEquals(message.getObjectProperty(myByte), (byte) 1); + assertEquals(message.getByteProperty(myByte), (byte) 1); - Assert.assertTrue(message.propertyExists(myString)); - Assert.assertEquals(message.getObjectProperty(myString), "StringValue"); - Assert.assertEquals(message.getStringProperty(myString), "StringValue"); + assertTrue(message.propertyExists(myString)); + assertEquals(message.getObjectProperty(myString), "StringValue"); + assertEquals(message.getStringProperty(myString), "StringValue"); - Assert.assertTrue(message.propertyExists(myCustomString)); - Assert.assertEquals(message.getObjectProperty(myCustomString), "['one', 'two']"); - Assert.assertEquals(message.getStringProperty(myCustomString), "['one', 'two']"); + assertTrue(message.propertyExists(myCustomString)); + assertEquals(message.getObjectProperty(myCustomString), "['one', 'two']"); + assertEquals(message.getStringProperty(myCustomString), "['one', 'two']"); - Assert.assertTrue(message.propertyExists(myNumber)); - Assert.assertEquals(message.getObjectProperty(myNumber), "500"); - Assert.assertEquals(message.getStringProperty(myNumber), "500"); - Assert.assertEquals(message.getIntProperty(myNumber), 500); - Assert.assertEquals(message.getShortProperty(myNumber), (short) 500); - Assert.assertEquals(message.getLongProperty(myNumber), 500l); - Assert.assertEquals(message.getFloatProperty(myNumber), 500f); - Assert.assertEquals(message.getDoubleProperty(myNumber), 500d); + assertTrue(message.propertyExists(myNumber)); + assertEquals(message.getObjectProperty(myNumber), "500"); + assertEquals(message.getStringProperty(myNumber), "500"); + assertEquals(message.getIntProperty(myNumber), 500); + assertEquals(message.getShortProperty(myNumber), (short) 500); + assertEquals(message.getLongProperty(myNumber), 500L); + assertEquals(message.getFloatProperty(myNumber), 500f, 0.0); + assertEquals(message.getDoubleProperty(myNumber), 500d, 0.0); // Validate property names - Set propertyNamesSet = new HashSet(Arrays.asList( + Set propertyNamesSet = Set.of( myTrueBoolean, myFalseBoolean, myInteger, @@ -419,9 +383,9 @@ public void testSQSMessageAttributeToProperty() throws JMSException { myString, myCustomString, myNumber, - JMSX_DELIVERY_COUNT)); + JMSX_DELIVERY_COUNT); - Enumeration propertyNames = message.getPropertyNames(); + Enumeration propertyNames = message.getPropertyNames(); int counter = 0; while (propertyNames.hasMoreElements()) { assertTrue(propertyNamesSet.contains(propertyNames.nextElement())); @@ -430,15 +394,15 @@ public void testSQSMessageAttributeToProperty() throws JMSException { assertEquals(propertyNamesSet.size(), counter); message.clearProperties(); - Assert.assertFalse(message.propertyExists("myTrueBoolean")); - Assert.assertFalse(message.propertyExists("myInteger")); - Assert.assertFalse(message.propertyExists("myDouble")); - Assert.assertFalse(message.propertyExists("myFloat")); - Assert.assertFalse(message.propertyExists("myLong")); - Assert.assertFalse(message.propertyExists("myShort")); - Assert.assertFalse(message.propertyExists("myByteProperty")); - Assert.assertFalse(message.propertyExists("myString")); - Assert.assertFalse(message.propertyExists("myNumber")); + assertFalse(message.propertyExists("myTrueBoolean")); + assertFalse(message.propertyExists("myInteger")); + assertFalse(message.propertyExists("myDouble")); + assertFalse(message.propertyExists("myFloat")); + assertFalse(message.propertyExists("myLong")); + assertFalse(message.propertyExists("myShort")); + assertFalse(message.propertyExists("myByteProperty")); + assertFalse(message.propertyExists("myString")); + assertFalse(message.propertyExists("myNumber")); propertyNames = message.getPropertyNames(); assertFalse(propertyNames.hasMoreElements()); diff --git a/src/test/java/com/amazon/sqs/javamessaging/message/SQSObjectMessageTest.java b/src/test/java/com/amazon/sqs/javamessaging/message/SQSObjectMessageTest.java index 67fe82b..1f4b9b7 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/message/SQSObjectMessageTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/message/SQSObjectMessageTest.java @@ -14,22 +14,16 @@ */ package com.amazon.sqs.javamessaging.message; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; +import jakarta.jms.JMSException; +import jakarta.jms.ObjectMessage; +import org.junit.jupiter.api.Test; import java.io.Serializable; import java.util.HashMap; import java.util.Map; -import javax.jms.JMSException; -import javax.jms.ObjectMessage; - -import org.junit.Assert; -import org.junit.Test; - -import com.amazon.sqs.javamessaging.message.SQSObjectMessage; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; /** * Test the SQSObjectMessageTest class @@ -41,13 +35,12 @@ public class SQSObjectMessageTest { */ @Test public void testSetObject() throws JMSException { - Map expectedPayload = new HashMap(); - expectedPayload.put("testKey", "testValue"); + Map expectedPayload = Map.of("testKey", "testValue"); ObjectMessage objectMessage = new SQSObjectMessage(); objectMessage.setObject((Serializable) expectedPayload); - Map actualPayload = (HashMap) objectMessage.getObject(); + Map actualPayload = (Map) objectMessage.getObject(); assertEquals(expectedPayload, actualPayload); } @@ -56,12 +49,11 @@ public void testSetObject() throws JMSException { */ @Test public void testCreateMessageWithObject() throws JMSException { - Map expectedPayload = new HashMap(); - expectedPayload.put("testKey", "testValue"); + Map expectedPayload = Map.of("testKey", "testValue"); ObjectMessage objectMessage = new SQSObjectMessage((Serializable) expectedPayload); - Map actualPayload = (HashMap) objectMessage.getObject(); + Map actualPayload = (Map) objectMessage.getObject(); assertEquals(expectedPayload, actualPayload); } @@ -70,20 +62,20 @@ public void testCreateMessageWithObject() throws JMSException { */ @Test public void testObjectSerialization() throws JMSException { - Map expectedPayload = new HashMap(); + Map expectedPayload = new HashMap<>(); expectedPayload.put("testKey", "testValue"); SQSObjectMessage sqsObjectMessage = new SQSObjectMessage(); - String serialized = sqsObjectMessage.serialize((Serializable) expectedPayload); + String serialized = SQSObjectMessage.serialize((Serializable) expectedPayload); - assertNotNull("Serialized object should not be null.", serialized); - Assert.assertFalse("Serialized object should not be empty.", "".equals(serialized)); + assertNotNull(serialized, "Serialized object should not be null."); + assertNotEquals("", serialized, "Serialized object should not be empty."); - Map deserialized = (Map) sqsObjectMessage.deserialize(serialized); + Map deserialized = (Map) SQSObjectMessage.deserialize(serialized); - assertNotNull("Deserialized object should not be null.", deserialized); - assertEquals("Serialized object should be equal to original object.", expectedPayload, deserialized); + assertNotNull(deserialized, "Deserialized object should not be null."); + assertEquals(expectedPayload, deserialized, "Serialized object should be equal to original object."); sqsObjectMessage.clearBody(); @@ -96,17 +88,10 @@ public void testObjectSerialization() throws JMSException { */ @Test public void testDeserializeIllegalInput() throws JMSException { - String wrongString = "Wrong String"; - SQSObjectMessage sqsObjectMessage = new SQSObjectMessage(); - - try { - sqsObjectMessage.deserialize(wrongString); - fail(); - } catch (JMSException exception) { - } - - assertNull(sqsObjectMessage.deserialize(null)); + assertThatThrownBy(() -> SQSObjectMessage.deserialize("Wrong String")) + .isInstanceOf(JMSException.class); - assertNull(sqsObjectMessage.serialize(null)); + assertNull(SQSObjectMessage.deserialize(null)); + assertNull(SQSObjectMessage.serialize(null)); } } diff --git a/src/test/java/com/amazon/sqs/javamessaging/message/SQSTextMessageTest.java b/src/test/java/com/amazon/sqs/javamessaging/message/SQSTextMessageTest.java index d1f5b9b..51f3911 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/message/SQSTextMessageTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/message/SQSTextMessageTest.java @@ -14,12 +14,12 @@ */ package com.amazon.sqs.javamessaging.message; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; -import javax.jms.JMSException; +import jakarta.jms.JMSException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import com.amazon.sqs.javamessaging.message.SQSTextMessage; From 41f5c1d833c56f051aae112af4d6e4f013391dca Mon Sep 17 00:00:00 2001 From: armogur Date: Tue, 28 Feb 2023 08:58:33 +0100 Subject: [PATCH 2/4] Organize imports and replace * with explicit imports. Rename variable in SQSConnection. --- .gitignore | 1 + .../AmazonSQSMessagingClientWrapper.java | 16 ++++++++- .../sqs/javamessaging/SQSConnection.java | 33 ++++++++---------- .../javamessaging/SQSConnectionFactory.java | 7 +++- .../sqs/javamessaging/SQSMessageConsumer.java | 20 +++++------ .../SQSMessageConsumerPrefetch.java | 31 ++++++++--------- .../sqs/javamessaging/SQSMessageProducer.java | 10 +++++- .../amazon/sqs/javamessaging/SQSSession.java | 28 +++++++++++++-- .../SQSSessionCallbackScheduler.java | 28 +++++++-------- .../acknowledge/Acknowledger.java | 5 ++- .../acknowledge/AutoAcknowledger.java | 1 - .../acknowledge/BulkSQSOperation.java | 7 ++-- .../acknowledge/NegativeAcknowledger.java | 14 ++++---- .../acknowledge/RangedAcknowledger.java | 19 +++++------ .../acknowledge/UnorderedAcknowledger.java | 14 ++++---- .../message/SQSBytesMessage.java | 21 +++++------- .../sqs/javamessaging/message/SQSMessage.java | 33 +++++++++++++++--- .../message/SQSObjectMessage.java | 19 +++++------ .../javamessaging/message/SQSTextMessage.java | 4 +-- .../sqs/javamessaging/AcknowledgerCommon.java | 14 ++++---- .../AmazonSQSMessagingClientWrapperTest.java | 18 ++++++++-- .../javamessaging/AutoAcknowledgerTest.java | 6 +++- ...essageListenerConcurrentOperationTest.java | 6 ++-- .../NegativeAcknowledgerTest.java | 10 +++++- .../javamessaging/RangedAcknowledgerTest.java | 9 +++-- .../sqs/javamessaging/SQSConnectionTest.java | 16 +++++++-- .../SQSMessageConsumerPrefetchFifoTest.java | 11 ++++-- .../SQSMessageConsumerPrefetchTest.java | 34 ++++++++++++++++--- .../javamessaging/SQSMessageConsumerTest.java | 13 +++++-- .../SQSMessageProducerFifoTest.java | 11 ++++-- .../javamessaging/SQSMessageProducerTest.java | 26 +++++++++++--- .../SQSMessagingClientUtilTest.java | 1 - .../SQSQueueDestinationTest.java | 4 ++- .../SQSSessionCallbackSchedulerTest.java | 14 +++++++- .../sqs/javamessaging/SQSSessionTest.java | 34 +++++++++++++++---- .../UnorderedAcknowledgerTest.java | 4 ++- .../message/SQSBytesMessageTest.java | 24 ++++++++++--- .../javamessaging/message/SQSMessageTest.java | 16 +++++++-- .../message/SQSObjectMessageTest.java | 5 ++- .../message/SQSTextMessageTest.java | 7 ++-- 40 files changed, 405 insertions(+), 189 deletions(-) diff --git a/.gitignore b/.gitignore index 2f7896d..07827cc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ target/ +.idea/ \ No newline at end of file diff --git a/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java b/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java index 8f09507..ed8b49e 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java +++ b/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java @@ -25,7 +25,21 @@ import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.exception.SdkException; import software.amazon.awssdk.services.sqs.SqsClient; -import software.amazon.awssdk.services.sqs.model.*; +import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; +import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchResponse; +import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityRequest; +import software.amazon.awssdk.services.sqs.model.CreateQueueRequest; +import software.amazon.awssdk.services.sqs.model.CreateQueueResponse; +import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest; +import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchResponse; +import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; +import software.amazon.awssdk.services.sqs.model.GetQueueUrlRequest; +import software.amazon.awssdk.services.sqs.model.GetQueueUrlResponse; +import software.amazon.awssdk.services.sqs.model.QueueDoesNotExistException; +import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; +import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; +import software.amazon.awssdk.services.sqs.model.SendMessageRequest; +import software.amazon.awssdk.services.sqs.model.SendMessageResponse; import java.util.Set; diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSConnection.java b/src/main/java/com/amazon/sqs/javamessaging/SQSConnection.java index 2bd94cf..da4dd14 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSConnection.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSConnection.java @@ -14,16 +14,13 @@ */ package com.amazon.sqs.javamessaging; -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import jakarta.jms.IllegalStateException; +import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; import jakarta.jms.Connection; import jakarta.jms.ConnectionConsumer; import jakarta.jms.ConnectionMetaData; import jakarta.jms.Destination; import jakarta.jms.ExceptionListener; +import jakarta.jms.IllegalStateException; import jakarta.jms.InvalidClientIDException; import jakarta.jms.JMSException; import jakarta.jms.Queue; @@ -32,14 +29,14 @@ import jakarta.jms.ServerSessionPool; import jakarta.jms.Session; import jakarta.jms.Topic; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; - import software.amazon.awssdk.services.sqs.SqsClient; +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + /** * This is a logical connection entity, which encapsulates the logic to create * sessions. @@ -167,7 +164,7 @@ public QueueSession createQueueSession(boolean transacted, int acknowledgeMode) * * @param transacted * Only false is supported. - * @param sessionMode + * @param acknowledgeMode * Legal values are Session.AUTO_ACKNOWLEDGE, * Session.CLIENT_ACKNOWLEDGE, * Session.DUPS_OK_ACKNOWLEDGE, and @@ -179,19 +176,19 @@ public QueueSession createQueueSession(boolean transacted, int acknowledgeMode) * transaction and acknowledge mode. */ @Override - public Session createSession(boolean transacted, int sessionMode) throws JMSException { + public Session createSession(boolean transacted, int acknowledgeMode) throws JMSException { checkClosed(); actionOnConnectionTaken = true; - if (transacted || sessionMode == Session.SESSION_TRANSACTED) + if (transacted || acknowledgeMode == Session.SESSION_TRANSACTED) throw new JMSException("SQSSession does not support transacted"); SQSSession sqsSession; - if (sessionMode == Session.AUTO_ACKNOWLEDGE) { - sqsSession = new SQSSession(this, AcknowledgeMode.ACK_AUTO.withOriginalAcknowledgeMode(sessionMode)); - } else if (sessionMode == Session.CLIENT_ACKNOWLEDGE || sessionMode == Session.DUPS_OK_ACKNOWLEDGE) { - sqsSession = new SQSSession(this, AcknowledgeMode.ACK_RANGE.withOriginalAcknowledgeMode(sessionMode)); - } else if (sessionMode == SQSSession.UNORDERED_ACKNOWLEDGE) { - sqsSession = new SQSSession(this, AcknowledgeMode.ACK_UNORDERED.withOriginalAcknowledgeMode(sessionMode)); + if (acknowledgeMode == Session.AUTO_ACKNOWLEDGE) { + sqsSession = new SQSSession(this, AcknowledgeMode.ACK_AUTO.withOriginalAcknowledgeMode(acknowledgeMode)); + } else if (acknowledgeMode == Session.CLIENT_ACKNOWLEDGE || acknowledgeMode == Session.DUPS_OK_ACKNOWLEDGE) { + sqsSession = new SQSSession(this, AcknowledgeMode.ACK_RANGE.withOriginalAcknowledgeMode(acknowledgeMode)); + } else if (acknowledgeMode == SQSSession.UNORDERED_ACKNOWLEDGE) { + sqsSession = new SQSSession(this, AcknowledgeMode.ACK_UNORDERED.withOriginalAcknowledgeMode(acknowledgeMode)); } else { LOG.error("Unrecognized acknowledgeMode. Cannot create Session."); throw new JMSException("Unrecognized acknowledgeMode. Cannot create Session."); diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionFactory.java b/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionFactory.java index ebdc3d3..726700d 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionFactory.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSConnectionFactory.java @@ -14,7 +14,12 @@ */ package com.amazon.sqs.javamessaging; -import jakarta.jms.*; +import jakarta.jms.ConnectionFactory; +import jakarta.jms.JMSContext; +import jakarta.jms.JMSException; +import jakarta.jms.JMSRuntimeException; +import jakarta.jms.QueueConnection; +import jakarta.jms.QueueConnectionFactory; import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumer.java b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumer.java index 2be04b8..9370903 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumer.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumer.java @@ -14,13 +14,9 @@ */ package com.amazon.sqs.javamessaging; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - +import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; +import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; +import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; import jakarta.jms.IllegalStateException; import jakarta.jms.JMSException; import jakarta.jms.Message; @@ -28,13 +24,15 @@ import jakarta.jms.MessageListener; import jakarta.jms.Queue; import jakarta.jms.QueueReceiver; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; -import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; -import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; /** * A client uses a MessageConsumer object to receive messages from a diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetch.java b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetch.java index aa96434..6207c43 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetch.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetch.java @@ -14,22 +14,6 @@ */ package com.amazon.sqs.javamessaging; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import jakarta.jms.Destination; -import jakarta.jms.JMSException; -import jakarta.jms.MessageListener; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; @@ -38,13 +22,26 @@ import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; import com.amazon.sqs.javamessaging.util.ExponentialBackoffStrategy; - +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.MessageListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import software.amazon.awssdk.services.sqs.model.Message; import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest.Builder; import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + /** * Used internally to prefetch messages to internal buffer on a background * thread for better receive turn around times. diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageProducer.java b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageProducer.java index 2175819..1bed84c 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSMessageProducer.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSMessageProducer.java @@ -19,8 +19,16 @@ import com.amazon.sqs.javamessaging.message.SQSMessage.JMSMessagePropertyValue; import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; +import jakarta.jms.CompletionListener; +import jakarta.jms.Destination; import jakarta.jms.IllegalStateException; -import jakarta.jms.*; +import jakarta.jms.InvalidDestinationException; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageFormatException; +import jakarta.jms.MessageProducer; +import jakarta.jms.Queue; +import jakarta.jms.QueueSender; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSSession.java b/src/main/java/com/amazon/sqs/javamessaging/SQSSession.java index 03fcfb6..927ea17 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSSession.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSSession.java @@ -23,14 +23,38 @@ import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; import com.amazon.sqs.javamessaging.util.SQSMessagingClientThreadFactory; +import jakarta.jms.BytesMessage; +import jakarta.jms.Destination; import jakarta.jms.IllegalStateException; +import jakarta.jms.JMSException; +import jakarta.jms.MapMessage; +import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageListener; +import jakarta.jms.MessageProducer; +import jakarta.jms.ObjectMessage; import jakarta.jms.Queue; -import jakarta.jms.*; +import jakarta.jms.QueueBrowser; +import jakarta.jms.QueueReceiver; +import jakarta.jms.QueueSender; +import jakarta.jms.QueueSession; +import jakarta.jms.Session; +import jakarta.jms.StreamMessage; +import jakarta.jms.TemporaryQueue; +import jakarta.jms.TemporaryTopic; +import jakarta.jms.TextMessage; +import jakarta.jms.Topic; +import jakarta.jms.TopicSubscriber; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/src/main/java/com/amazon/sqs/javamessaging/SQSSessionCallbackScheduler.java b/src/main/java/com/amazon/sqs/javamessaging/SQSSessionCallbackScheduler.java index ddb4688..77fcc61 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/SQSSessionCallbackScheduler.java +++ b/src/main/java/com/amazon/sqs/javamessaging/SQSSessionCallbackScheduler.java @@ -14,21 +14,6 @@ */ package com.amazon.sqs.javamessaging; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import jakarta.jms.JMSException; -import jakarta.jms.MessageListener; -import jakarta.jms.Session; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.amazon.sqs.javamessaging.SQSMessageConsumerPrefetch.MessageManager; import com.amazon.sqs.javamessaging.SQSSession.CallbackEntry; import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; @@ -36,6 +21,19 @@ import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; import com.amazon.sqs.javamessaging.acknowledge.SQSMessageIdentifier; import com.amazon.sqs.javamessaging.message.SQSMessage; +import jakarta.jms.JMSException; +import jakarta.jms.MessageListener; +import jakarta.jms.Session; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * Used internally to guarantee serial execution of message processing on diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/Acknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/Acknowledger.java index a453707..9c2db6e 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/Acknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/Acknowledger.java @@ -14,11 +14,10 @@ */ package com.amazon.sqs.javamessaging.acknowledge; -import java.util.List; - +import com.amazon.sqs.javamessaging.message.SQSMessage; import jakarta.jms.JMSException; -import com.amazon.sqs.javamessaging.message.SQSMessage; +import java.util.List; public interface Acknowledger { diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/AutoAcknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/AutoAcknowledger.java index df5c3bf..f155a2a 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/AutoAcknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/AutoAcknowledger.java @@ -21,7 +21,6 @@ import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/BulkSQSOperation.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/BulkSQSOperation.java index fb338a0..2c9b56f 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/BulkSQSOperation.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/BulkSQSOperation.java @@ -14,16 +14,15 @@ */ package com.amazon.sqs.javamessaging.acknowledge; +import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; +import jakarta.jms.JMSException; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import jakarta.jms.JMSException; - -import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; - /** * This is used by different acknowledgers that requires partitioning of the * list, and execute actions on the partitions diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/NegativeAcknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/NegativeAcknowledger.java index 9dfbf40..4b4b581 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/NegativeAcknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/NegativeAcknowledger.java @@ -14,20 +14,18 @@ */ package com.amazon.sqs.javamessaging.acknowledge; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.List; - -import jakarta.jms.JMSException; - import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; -import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; import com.amazon.sqs.javamessaging.SQSMessageConsumerPrefetch.MessageManager; +import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; import com.amazon.sqs.javamessaging.message.SQSMessage; - +import jakarta.jms.JMSException; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequestEntry; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; + /** * Used to negative acknowledge of group of messages. *

        diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/RangedAcknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/RangedAcknowledger.java index a0e2bea..ece1699 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/RangedAcknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/RangedAcknowledger.java @@ -14,23 +14,20 @@ */ package com.amazon.sqs.javamessaging.acknowledge; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; - -import jakarta.jms.JMSException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; import com.amazon.sqs.javamessaging.SQSSession; import com.amazon.sqs.javamessaging.message.SQSMessage; - +import jakarta.jms.JMSException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest; import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequestEntry; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + /** * Used to acknowledge group of messages. Acknowledging a consumed message * acknowledges all messages that the session has consumed before and including diff --git a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/UnorderedAcknowledger.java b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/UnorderedAcknowledger.java index 499896d..c77469c 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/acknowledge/UnorderedAcknowledger.java +++ b/src/main/java/com/amazon/sqs/javamessaging/acknowledge/UnorderedAcknowledger.java @@ -14,19 +14,17 @@ */ package com.amazon.sqs.javamessaging.acknowledge; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import jakarta.jms.JMSException; - import com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper; import com.amazon.sqs.javamessaging.SQSSession; import com.amazon.sqs.javamessaging.message.SQSMessage; - +import jakarta.jms.JMSException; import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * Used to acknowledge messages in any order one at a time. *

        diff --git a/src/main/java/com/amazon/sqs/javamessaging/message/SQSBytesMessage.java b/src/main/java/com/amazon/sqs/javamessaging/message/SQSBytesMessage.java index 4f720ba..c09b7f8 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/message/SQSBytesMessage.java +++ b/src/main/java/com/amazon/sqs/javamessaging/message/SQSBytesMessage.java @@ -14,29 +14,26 @@ */ package com.amazon.sqs.javamessaging.message; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.EOFException; -import java.io.IOException; -import java.util.Arrays; - +import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import jakarta.jms.BytesMessage; import jakarta.jms.JMSException; import jakarta.jms.MessageEOFException; import jakarta.jms.MessageFormatException; import jakarta.jms.MessageNotReadableException; import jakarta.jms.MessageNotWriteableException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; - import software.amazon.awssdk.services.sqs.model.Message; import software.amazon.awssdk.utils.BinaryUtils; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.util.Arrays; + /** * This class borrows from ActiveMQStreamMessage, which is also * licensed under Apache2.0. Its methods are based largely on those found in diff --git a/src/main/java/com/amazon/sqs/javamessaging/message/SQSMessage.java b/src/main/java/com/amazon/sqs/javamessaging/message/SQSMessage.java index a121267..6ce3b48 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/message/SQSMessage.java +++ b/src/main/java/com/amazon/sqs/javamessaging/message/SQSMessage.java @@ -18,17 +18,42 @@ import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; import com.amazon.sqs.javamessaging.SQSQueueDestination; import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; -import jakarta.jms.*; +import jakarta.jms.Destination; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageFormatException; +import jakarta.jms.MessageNotWriteableException; import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; -import java.lang.IllegalStateException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import java.util.Map.Entry; -import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.*; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.BOOLEAN; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.BYTE; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.DOUBLE; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.FLOAT; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.INT; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.INT_FALSE; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.INT_TRUE; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.JMSX_DELIVERY_COUNT; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.JMSX_GROUP_ID; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.JMS_SQS_DEDUPLICATION_ID; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.JMS_SQS_SEQUENCE_NUMBER; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.LONG; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.MESSAGE_DEDUPLICATION_ID; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.MESSAGE_GROUP_ID; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.NUMBER; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.SEQUENCE_NUMBER; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.SHORT; +import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.STRING; /** * The SQSMessage is the root class of all SQS JMS messages and implements JMS diff --git a/src/main/java/com/amazon/sqs/javamessaging/message/SQSObjectMessage.java b/src/main/java/com/amazon/sqs/javamessaging/message/SQSObjectMessage.java index b9a8f87..974e770 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/message/SQSObjectMessage.java +++ b/src/main/java/com/amazon/sqs/javamessaging/message/SQSObjectMessage.java @@ -14,24 +14,21 @@ */ package com.amazon.sqs.javamessaging.message; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - +import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import jakarta.jms.JMSException; import jakarta.jms.ObjectMessage; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; - import software.amazon.awssdk.services.sqs.model.Message; import software.amazon.awssdk.utils.BinaryUtils; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + /** * An ObjectMessage object is used to send a message that contains a Java * serializable object. diff --git a/src/main/java/com/amazon/sqs/javamessaging/message/SQSTextMessage.java b/src/main/java/com/amazon/sqs/javamessaging/message/SQSTextMessage.java index 7bdad8a..0e0aa1c 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/message/SQSTextMessage.java +++ b/src/main/java/com/amazon/sqs/javamessaging/message/SQSTextMessage.java @@ -14,11 +14,9 @@ */ package com.amazon.sqs.javamessaging.message; +import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import jakarta.jms.JMSException; import jakarta.jms.TextMessage; - -import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; - import software.amazon.awssdk.services.sqs.model.Message; /** diff --git a/src/test/java/com/amazon/sqs/javamessaging/AcknowledgerCommon.java b/src/test/java/com/amazon/sqs/javamessaging/AcknowledgerCommon.java index 8764ba3..a73f837 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/AcknowledgerCommon.java +++ b/src/test/java/com/amazon/sqs/javamessaging/AcknowledgerCommon.java @@ -14,20 +14,18 @@ */ package com.amazon.sqs.javamessaging; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import jakarta.jms.JMSException; - import com.amazon.sqs.javamessaging.acknowledge.Acknowledger; import com.amazon.sqs.javamessaging.message.SQSMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; - +import jakarta.jms.JMSException; import software.amazon.awssdk.services.sqs.model.Message; import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import static org.junit.jupiter.api.Assertions.assertEquals; /** diff --git a/src/test/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapperTest.java b/src/test/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapperTest.java index 863b3d6..69fd08f 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapperTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapperTest.java @@ -21,12 +21,24 @@ import software.amazon.awssdk.core.exception.SdkException; import software.amazon.awssdk.core.exception.SdkServiceException; import software.amazon.awssdk.services.sqs.SqsClient; -import software.amazon.awssdk.services.sqs.model.*; +import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; +import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityRequest; +import software.amazon.awssdk.services.sqs.model.CreateQueueRequest; +import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest; +import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; +import software.amazon.awssdk.services.sqs.model.GetQueueUrlRequest; +import software.amazon.awssdk.services.sqs.model.QueueDoesNotExistException; +import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; +import software.amazon.awssdk.services.sqs.model.SendMessageRequest; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; /** * Test the AmazonSQSMessagingClientWrapper class diff --git a/src/test/java/com/amazon/sqs/javamessaging/AutoAcknowledgerTest.java b/src/test/java/com/amazon/sqs/javamessaging/AutoAcknowledgerTest.java index 559f125..05c6cb9 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/AutoAcknowledgerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/AutoAcknowledgerTest.java @@ -26,7 +26,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * Test the AutoAcknowledger class diff --git a/src/test/java/com/amazon/sqs/javamessaging/MessageListenerConcurrentOperationTest.java b/src/test/java/com/amazon/sqs/javamessaging/MessageListenerConcurrentOperationTest.java index 9a22ff0..045e776 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/MessageListenerConcurrentOperationTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/MessageListenerConcurrentOperationTest.java @@ -19,7 +19,10 @@ import com.amazon.sqs.javamessaging.acknowledge.NegativeAcknowledger; import com.amazon.sqs.javamessaging.message.SQSMessage; import jakarta.jms.IllegalStateException; -import jakarta.jms.*; +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; +import jakarta.jms.Session; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,7 +34,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * Test concurrent operation of message listener on session and connections diff --git a/src/test/java/com/amazon/sqs/javamessaging/NegativeAcknowledgerTest.java b/src/test/java/com/amazon/sqs/javamessaging/NegativeAcknowledgerTest.java index 013e518..ef19c6e 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/NegativeAcknowledgerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/NegativeAcknowledgerTest.java @@ -29,7 +29,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyList; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * Test the NegativeAcknowledger class diff --git a/src/test/java/com/amazon/sqs/javamessaging/RangedAcknowledgerTest.java b/src/test/java/com/amazon/sqs/javamessaging/RangedAcknowledgerTest.java index 7d3039b..1a855e4 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/RangedAcknowledgerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/RangedAcknowledgerTest.java @@ -28,8 +28,13 @@ import java.util.List; import java.util.Map; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; /** diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionTest.java index 678f9e9..c2a7b43 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSConnectionTest.java @@ -14,8 +14,13 @@ */ package com.amazon.sqs.javamessaging; +import jakarta.jms.ExceptionListener; import jakarta.jms.IllegalStateException; -import jakarta.jms.*; +import jakarta.jms.InvalidClientIDException; +import jakarta.jms.JMSException; +import jakarta.jms.Queue; +import jakarta.jms.Session; +import jakarta.jms.Topic; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,8 +31,13 @@ import java.util.concurrent.atomic.AtomicBoolean; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; /** * Test the SQSConnectionTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchFifoTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchFifoTest.java index 32ffd29..a6d079d 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchFifoTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchFifoTest.java @@ -28,8 +28,12 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import software.amazon.awssdk.services.sqs.model.*; +import software.amazon.awssdk.services.sqs.model.Message; import software.amazon.awssdk.services.sqs.model.Message.Builder; +import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; +import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; +import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; +import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; import software.amazon.awssdk.utils.BinaryUtils; import java.io.ByteArrayOutputStream; @@ -43,7 +47,10 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchTest.java index 5d34779..4d52c70 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerPrefetchTest.java @@ -30,7 +30,11 @@ import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; import org.mockito.stubbing.Answer; -import software.amazon.awssdk.services.sqs.model.*; +import software.amazon.awssdk.services.sqs.model.Message; +import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; +import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; +import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; +import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; import software.amazon.awssdk.utils.BinaryUtils; import java.io.ByteArrayOutputStream; @@ -40,14 +44,36 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.IntStream; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyList; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; /** * Test the SQSMessageConsumerPrefetchTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerTest.java index 6567bd5..bbda3b7 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageConsumerTest.java @@ -29,8 +29,17 @@ import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; /** * Test the SQSMessageConsumerPrefetchTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerFifoTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerFifoTest.java index a074c6c..3fa1b98 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerFifoTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerFifoTest.java @@ -24,7 +24,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatcher; -import software.amazon.awssdk.services.sqs.model.*; +import software.amazon.awssdk.services.sqs.model.Message; +import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; +import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; +import software.amazon.awssdk.services.sqs.model.SendMessageRequest; +import software.amazon.awssdk.services.sqs.model.SendMessageResponse; import software.amazon.awssdk.utils.BinaryUtils; import java.io.ByteArrayOutputStream; @@ -38,7 +42,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * Test the SQSMessageProducerTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java index ee4b327..6d4cff4 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java @@ -20,29 +20,45 @@ import com.amazon.sqs.javamessaging.message.SQSMessage; import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; +import jakarta.jms.Destination; import jakarta.jms.IllegalStateException; +import jakarta.jms.InvalidDestinationException; +import jakarta.jms.JMSException; import jakarta.jms.Queue; -import jakarta.jms.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import software.amazon.awssdk.services.sqs.model.Message; -import software.amazon.awssdk.services.sqs.model.*; +import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; +import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; +import software.amazon.awssdk.services.sqs.model.SendMessageRequest; +import software.amazon.awssdk.services.sqs.model.SendMessageResponse; import software.amazon.awssdk.utils.BinaryUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; -import java.lang.UnsupportedOperationException; -import java.util.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * Test the SQSMessageProducerTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessagingClientUtilTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessagingClientUtilTest.java index 8d5152a..440dfa7 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessagingClientUtilTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessagingClientUtilTest.java @@ -15,7 +15,6 @@ package com.amazon.sqs.javamessaging; import com.amazon.sqs.javamessaging.util.SQSMessagingClientUtil; - import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSQueueDestinationTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSQueueDestinationTest.java index da3f9d8..f8b3b25 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSQueueDestinationTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSQueueDestinationTest.java @@ -16,7 +16,9 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Test the SQSDestinationTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSSessionCallbackSchedulerTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSSessionCallbackSchedulerTest.java index 6bcc37a..a888f91 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSSessionCallbackSchedulerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSSessionCallbackSchedulerTest.java @@ -38,7 +38,19 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyList; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * Test the SQSSessionCallbackSchedulerTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSSessionTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSSessionTest.java index 2a08379..5dc4b51 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSSessionTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSSessionTest.java @@ -17,17 +17,31 @@ import com.amazon.sqs.javamessaging.acknowledge.AcknowledgeMode; import com.amazon.sqs.javamessaging.message.SQSObjectMessage; import com.amazon.sqs.javamessaging.message.SQSTextMessage; +import jakarta.jms.Destination; import jakarta.jms.IllegalStateException; +import jakarta.jms.JMSException; import jakarta.jms.Message; +import jakarta.jms.MessageConsumer; +import jakarta.jms.MessageProducer; +import jakarta.jms.ObjectMessage; import jakarta.jms.Queue; -import jakarta.jms.*; +import jakarta.jms.TextMessage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; -import software.amazon.awssdk.services.sqs.model.*; - -import java.util.*; +import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; +import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequestEntry; +import software.amazon.awssdk.services.sqs.model.GetQueueUrlResponse; +import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; +import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; +import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -35,10 +49,18 @@ import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * Test the SQSSessionTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/UnorderedAcknowledgerTest.java b/src/test/java/com/amazon/sqs/javamessaging/UnorderedAcknowledgerTest.java index 349da35..9415679 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/UnorderedAcknowledgerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/UnorderedAcknowledgerTest.java @@ -28,7 +28,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; /** * Test the UnorderedAcknowledgerTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/message/SQSBytesMessageTest.java b/src/test/java/com/amazon/sqs/javamessaging/message/SQSBytesMessageTest.java index 4d13749..7e73473 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/message/SQSBytesMessageTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/message/SQSBytesMessageTest.java @@ -16,20 +16,36 @@ import com.amazon.sqs.javamessaging.SQSMessagingClientConstants; import com.amazon.sqs.javamessaging.SQSSession; -import jakarta.jms.*; +import jakarta.jms.JMSException; +import jakarta.jms.MessageEOFException; +import jakarta.jms.MessageFormatException; +import jakarta.jms.MessageNotReadableException; +import jakarta.jms.MessageNotWriteableException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import software.amazon.awssdk.services.sqs.model.Message; import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; import software.amazon.awssdk.utils.BinaryUtils; -import java.io.*; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Map; import java.util.Set; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; /** * Test the SQSBytesMessageTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/message/SQSMessageTest.java b/src/test/java/com/amazon/sqs/javamessaging/message/SQSMessageTest.java index 0f5c46e..d454388 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/message/SQSMessageTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/message/SQSMessageTest.java @@ -26,13 +26,23 @@ import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; import software.amazon.awssdk.services.sqs.model.MessageSystemAttributeName; -import java.util.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.APPROXIMATE_RECEIVE_COUNT; import static com.amazon.sqs.javamessaging.SQSMessagingClientConstants.JMSX_DELIVERY_COUNT; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; /** * Test the SQSMessageTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/message/SQSObjectMessageTest.java b/src/test/java/com/amazon/sqs/javamessaging/message/SQSObjectMessageTest.java index 1f4b9b7..41f650c 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/message/SQSObjectMessageTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/message/SQSObjectMessageTest.java @@ -23,7 +23,10 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; /** * Test the SQSObjectMessageTest class diff --git a/src/test/java/com/amazon/sqs/javamessaging/message/SQSTextMessageTest.java b/src/test/java/com/amazon/sqs/javamessaging/message/SQSTextMessageTest.java index 51f3911..982e242 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/message/SQSTextMessageTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/message/SQSTextMessageTest.java @@ -14,14 +14,11 @@ */ package com.amazon.sqs.javamessaging.message; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - import jakarta.jms.JMSException; - import org.junit.jupiter.api.Test; -import com.amazon.sqs.javamessaging.message.SQSTextMessage; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; /** * Test the SQSTextMessageTest class From b51d7debb9b4e03331bcc7835ad5d761129b6441 Mon Sep 17 00:00:00 2001 From: armogur Date: Tue, 28 Feb 2023 10:04:23 +0100 Subject: [PATCH 3/4] Removed unnecessary semicolon. --- .../sqs/javamessaging/AmazonSQSMessagingClientWrapper.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java b/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java index ed8b49e..bc4ca04 100644 --- a/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java +++ b/src/main/java/com/amazon/sqs/javamessaging/AmazonSQSMessagingClientWrapper.java @@ -59,7 +59,6 @@ public class AmazonSQSMessagingClientWrapper { */ private static final Set SECURITY_EXCEPTION_ERROR_CODES = Set.of("MissingClientTokenId", "InvalidClientTokenId", "MissingAuthenticationToken", "AccessDenied"); - ; private final SqsClient amazonSQSClient; private final AwsCredentialsProvider credentialsProvider; From f8e90ba79a65e8097f45621637396a84909857d7 Mon Sep 17 00:00:00 2001 From: armogur Date: Thu, 2 Mar 2023 09:01:59 +0100 Subject: [PATCH 4/4] Fixed a TODO. Replaced JUnit's assertEquals with assertJ's assertThat. --- .../javamessaging/SQSMessageProducerTest.java | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java index 6d4cff4..ace019a 100644 --- a/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java +++ b/src/test/java/com/amazon/sqs/javamessaging/SQSMessageProducerTest.java @@ -47,9 +47,8 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.argThat; import static org.mockito.Mockito.doNothing; @@ -130,7 +129,7 @@ public void testPropertyToMessageAttributeWithEmpty() throws JMSException { SQSMessage sqsText = new SQSTextMessage(); Map messageAttributeText = producer.propertyToMessageAttribute(sqsText); - assertEquals(0, messageAttributeText.size()); + assertThat(messageAttributeText).isEmpty(); /* * Test Empty object message default attribute @@ -138,16 +137,15 @@ public void testPropertyToMessageAttributeWithEmpty() throws JMSException { SQSMessage sqsObject = new SQSObjectMessage(); Map messageAttributeObject = producer.propertyToMessageAttribute(sqsObject); - assertEquals(0, messageAttributeObject.size()); + assertThat(messageAttributeObject).isEmpty(); /* * Test Empty byte message default attribute */ SQSMessage sqsByte = new SQSBytesMessage(); - // TODO messageAttributeByte not verified Map messageAttributeByte = producer.propertyToMessageAttribute(sqsByte); - assertEquals(0, messageAttributeObject.size()); + assertThat(messageAttributeByte).isEmpty(); } /** @@ -241,15 +239,15 @@ public void internalTestPropertyToMessageAttribute(SQSMessage sqsText) throws JM /* * Verify results */ - assertEquals(messageAttributeValueBoolean, messageAttribute.get(booleanProperty)); - assertEquals(messageAttributeValueByte, messageAttribute.get(byteProperty)); - assertEquals(messageAttributeValueShort, messageAttribute.get(shortProperty)); - assertEquals(messageAttributeValueInt, messageAttribute.get(intProperty)); - assertEquals(messageAttributeValueLong, messageAttribute.get(longProperty)); - assertEquals(messageAttributeValueFloat, messageAttribute.get(floatProperty)); - assertEquals(messageAttributeValueDouble, messageAttribute.get(doubleProperty)); - assertEquals(messageAttributeValueString, messageAttribute.get(stringProperty)); - assertEquals(messageAttributeValueObject, messageAttribute.get(objectProperty)); + assertThat(messageAttributeValueBoolean).isEqualTo(messageAttribute.get(booleanProperty)); + assertThat(messageAttributeValueByte).isEqualTo(messageAttribute.get(byteProperty)); + assertThat(messageAttributeValueShort).isEqualTo(messageAttribute.get(shortProperty)); + assertThat(messageAttributeValueInt).isEqualTo(messageAttribute.get(intProperty)); + assertThat(messageAttributeValueLong).isEqualTo(messageAttribute.get(longProperty)); + assertThat(messageAttributeValueFloat).isEqualTo(messageAttribute.get(floatProperty)); + assertThat(messageAttributeValueDouble).isEqualTo(messageAttribute.get(doubleProperty)); + assertThat(messageAttributeValueString).isEqualTo(messageAttribute.get(stringProperty)); + assertThat(messageAttributeValueObject).isEqualTo(messageAttribute.get(objectProperty)); } @@ -382,8 +380,8 @@ public void testSendInternalSQSObjectMessage() throws JMSException { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(SendMessageRequest.class); verify(amazonSQSClient, times(2)).sendMessage(argumentCaptor.capture()); - assertEquals(megBody1, argumentCaptor.getAllValues().get(0).messageBody()); - assertEquals(megBody2, argumentCaptor.getAllValues().get(1).messageBody()); + assertThat(megBody1).isEqualTo(argumentCaptor.getAllValues().get(0).messageBody()); + assertThat(megBody2).isEqualTo(argumentCaptor.getAllValues().get(1).messageBody()); verify(msg, times(2)).setJMSDestination(destination); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID_1); verify(msg).setJMSMessageID("ID:" + MESSAGE_ID_2); @@ -524,7 +522,7 @@ public void testSendInternalSQSByteMessageFromReceivedMessage() throws JMSExcept */ @Test public void testGetQueue() throws JMSException { - assertEquals(destination, producer.getQueue()); + assertThat(destination).isEqualTo(producer.getQueue()); } /** @@ -632,11 +630,11 @@ public void testClose() throws JMSException { @Test public void testSetDeliveryDelay() throws JMSException { - assertEquals(0, producer.getDeliveryDelay()); + assertThat(producer.getDeliveryDelay()).isZero(); producer.setDeliveryDelay(2000); - assertEquals(2000, producer.getDeliveryDelay()); + assertThat(producer.getDeliveryDelay()).isEqualTo(2000); ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(SendMessageRequest.class); when(amazonSQSClient.sendMessage(requestCaptor.capture())) @@ -645,7 +643,7 @@ public void testSetDeliveryDelay() throws JMSException { SQSTextMessage msg = new SQSTextMessage("Sorry I'm late!"); producer.send(msg); - assertEquals(2, requestCaptor.getValue().delaySeconds().intValue()); + assertThat(requestCaptor.getValue().delaySeconds().intValue()).isEqualTo(2); } @@ -675,9 +673,9 @@ private record SendMessageRequestMatcher(String queueUrl, List messagesB @Override public boolean matches(SendMessageRequest request) { - assertEquals(queueUrl, request.queueUrl()); - assertTrue(messagesBody.contains(request.messageBody())); - assertEquals(messageAttributes, request.messageAttributes()); + assertThat(queueUrl).isEqualTo(request.queueUrl()); + assertThat(messagesBody).contains(request.messageBody()); + assertThat(messageAttributes).isEqualTo(request.messageAttributes()); return true; } }