From bad6acb58f8aed7845276aae119d72dbcb6d6b79 Mon Sep 17 00:00:00 2001 From: Timothy Bish Date: Wed, 26 Apr 2017 18:36:32 -0400 Subject: [PATCH] ARTEMIS-1123 Major AMQP Test Suite refactoring Refactor the AMQP test suite grouping tests into more logical unit tests and adding additional coverage in many areas. Adds some negative validation tests to cover features that were only partially tested. Brings in tests from ActiveMQ 5.x that were not yet ported to Artemis to increase coverage amd test scenarios previously seen to have issues in the 5.x broker. Improve tests that were failing sporadically due to not waiting for broker stats to be updated after async calls were made. --- .../amqp/client/AmqpAbstractResource.java | 48 +- .../transport/amqp/client/AmqpReceiver.java | 154 +- .../transport/amqp/client/AmqpSender.java | 61 +- .../transport/amqp/client/AmqpValidator.java | 8 +- .../amqp/AmqpClientTestSupport.java | 239 ++- .../amqp/AmqpDescribedTypePayloadTest.java | 11 +- .../amqp/AmqpDurableReceiverTest.java | 17 +- .../amqp/AmqpExpiredMessageTest.java | 67 +- .../integration/amqp/AmqpFlowControlTest.java | 284 +++ ...t.java => AmqpFullyQualifiedNameTest.java} | 86 +- .../amqp/AmqpInboundConnectionTest.java | 25 +- .../integration/amqp/AmqpManagementTest.java | 2 +- ...izeTest.java => AmqpMaxFrameSizeTest.java} | 19 +- .../amqp/AmqpMessageDivertsTest.java | 59 + .../amqp/AmqpMessageRoutingTest.java | 162 ++ .../amqp/AmqpOutboundConnectionTest.java | 70 + .../amqp/AmqpPresettledReceiverTest.java | 22 +- ...va => AmqpProtocolHeaderHandlingTest.java} | 47 +- .../amqp/AmqpReceiverDispositionTest.java | 19 - .../amqp/AmqpReceiverDrainTest.java | 145 +- .../integration/amqp/AmqpReceiverTest.java | 298 +++ .../amqp/AmqpScheduledMessageTest.java | 2 +- .../integration/amqp/AmqpSecurityTest.java | 69 +- .../integration/amqp/AmqpSendReceiveTest.java | 362 ++-- .../integration/amqp/AmqpSenderTest.java | 78 + .../integration/amqp/AmqpSessionTest.java | 75 + .../integration/amqp/AmqpTestSupport.java | 4 +- .../integration/amqp/AmqpTransactionTest.java | 21 +- .../BrokerDefinedAnycastConsumerTest.java | 31 +- .../BrokerDefinedMulticastConsumerTest.java | 21 +- .../ClientDefinedAnycastConsumerTest.java | 9 +- .../amqp/ClientDefinedMultiConsumerTest.java | 34 +- .../amqp/JMSClientTestSupport.java | 151 ++ .../integration/amqp/JMSConnectionTest.java | 118 ++ .../amqp/JMSConnectionWithSecurityTest.java | 157 ++ .../amqp/JMSDurableConsumerTest.java | 202 ++ .../amqp/JMSMessageConsumerTest.java | 500 +++++ .../amqp/JMSMessageGroupsTest.java | 102 + .../amqp/JMSMessageProducerTest.java | 221 ++ .../integration/amqp/JMSMessageTypesTest.java | 394 ++++ .../integration/amqp/JMSQueueBrowserTest.java | 296 +++ .../amqp/JMSTemporaryDestinationTest.java | 137 ++ .../amqp/JMSTopicConsumerTest.java | 244 +++ .../integration/amqp/JMSTransactionTest.java | 216 ++ .../integration/amqp/ProtonPubSubTest.java | 271 --- .../tests/integration/amqp/ProtonTest.java | 1788 ----------------- .../integration/amqp/ProtonTestBase.java | 91 - .../amqp/SendingAndReceivingTest.java | 224 --- 48 files changed, 4554 insertions(+), 3107 deletions(-) create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpFlowControlTest.java rename tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/{ProtonFullQualifiedNameTest.java => AmqpFullyQualifiedNameTest.java} (78%) rename tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/{ProtonMaxFrameSizeTest.java => AmqpMaxFrameSizeTest.java} (87%) create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMessageDivertsTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMessageRoutingTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpOutboundConnectionTest.java rename tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/{ProtonTestForHeader.java => AmqpProtocolHeaderHandlingTest.java} (77%) create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSessionTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSClientTestSupport.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionWithSecurityTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSDurableConsumerTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageConsumerTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageGroupsTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageProducerTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageTypesTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSQueueBrowserTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTemporaryDestinationTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTopicConsumerTest.java create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTransactionTest.java delete mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonPubSubTest.java delete mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTest.java delete mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestBase.java delete mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/SendingAndReceivingTest.java diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpAbstractResource.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpAbstractResource.java index 691c11f0ef..73288049c7 100644 --- a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpAbstractResource.java +++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpAbstractResource.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -28,9 +28,8 @@ import org.slf4j.LoggerFactory; /** * Abstract base for all AmqpResource implementations to extend. * - * This abstract class wraps up the basic state management bits so that the concrete - * object don't have to reproduce it. Provides hooks for the subclasses to initialize - * and shutdown. + * This abstract class wraps up the basic state management bits so that the concrete object + * don't have to reproduce it. Provides hooks for the subclasses to initialize and shutdown. */ public abstract class AmqpAbstractResource implements AmqpResource { @@ -243,7 +242,6 @@ public abstract class AmqpAbstractResource implements AmqpRe @Override public void processDeliveryUpdates(AmqpConnection connection, Delivery delivery) throws IOException { - doDeliveryUpdate(delivery); } @Override @@ -251,18 +249,17 @@ public abstract class AmqpAbstractResource implements AmqpRe } /** - * Perform the open operation on the managed endpoint. A subclass may - * override this method to provide additional open actions or configuration - * updates. + * Perform the open operation on the managed endpoint. A subclass may override this method to + * provide additional open actions or configuration updates. */ protected void doOpen() { getEndpoint().open(); } /** - * Perform the close operation on the managed endpoint. A subclass may - * override this method to provide additional close actions or alter the - * standard close path such as endpoint detach etc. + * Perform the close operation on the managed endpoint. A subclass may override this method + * to provide additional close actions or alter the standard close path such as endpoint + * detach etc. */ protected void doClose() { getEndpoint().close(); @@ -271,17 +268,16 @@ public abstract class AmqpAbstractResource implements AmqpRe /** * Perform the detach operation on the managed endpoint. * - * By default this method throws an UnsupportedOperationException, a subclass - * must implement this and do a detach if its resource supports that. + * By default this method throws an UnsupportedOperationException, a subclass must implement + * this and do a detach if its resource supports that. */ protected void doDetach() { throw new UnsupportedOperationException("Endpoint cannot be detached."); } /** - * Complete the open operation on the managed endpoint. A subclass may - * override this method to provide additional verification actions or configuration - * updates. + * Complete the open operation on the managed endpoint. A subclass may override this method + * to provide additional verification actions or configuration updates. */ protected void doOpenCompletion() { LOG.debug("{} is now open: ", this); @@ -289,15 +285,14 @@ public abstract class AmqpAbstractResource implements AmqpRe } /** - * When aborting the open operation, and there isn't an error condition, - * provided by the peer, the returned exception will be used instead. - * A subclass may override this method to provide alternative behaviour. + * When aborting the open operation, and there isn't an error condition, provided by the + * peer, the returned exception will be used instead. A subclass may override this method to + * provide alternative behaviour. */ protected Exception getOpenAbortException() { return new IOException("Open failed unexpectedly."); } - // TODO - Fina a more generic way to do this. protected abstract void doOpenInspection(); protected abstract void doClosedInspection(); @@ -305,18 +300,7 @@ public abstract class AmqpAbstractResource implements AmqpRe protected void doDetachedInspection() { } - protected void doDeliveryUpdate(Delivery delivery) { - AmqpValidator validator = getStateInspector(); - if (validator != null) { - try { - validator.inspectDeliveryUpdate(delivery); - } catch (Throwable error) { - validator.markAsInvalid(error.getMessage()); - } - } - } - - //----- Private implementation utility methods ---------------------------// + // ----- Private implementation utility methods ---------------------------// private boolean isAwaitingOpen() { return this.openRequest != null; diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpReceiver.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpReceiver.java index 9de2fcefe8..8653cffa12 100644 --- a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpReceiver.java +++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpReceiver.java @@ -128,9 +128,12 @@ public class AmqpReceiver extends AmqpAbstractResource { /** * Create a new receiver instance. * - * @param session The parent session that created the receiver. - * @param source The Source instance to use instead of creating and configuring one. - * @param receiverId The unique ID assigned to this receiver. + * @param session + * The parent session that created the receiver. + * @param source + * The Source instance to use instead of creating and configuring one. + * @param receiverId + * The unique ID assigned to this receiver. */ public AmqpReceiver(AmqpSession session, Source source, String receiverId) { @@ -147,10 +150,11 @@ public class AmqpReceiver extends AmqpAbstractResource { } /** - * Close the receiver, a closed receiver will throw exceptions if any further send - * calls are made. + * Close the receiver, a closed receiver will throw exceptions if any further send calls are + * made. * - * @throws IOException if an error occurs while closing the receiver. + * @throws IOException + * if an error occurs while closing the receiver. */ public void close() throws IOException { if (closed.compareAndSet(false, true)) { @@ -170,10 +174,11 @@ public class AmqpReceiver extends AmqpAbstractResource { } /** - * Detach the receiver, a closed receiver will throw exceptions if any further send - * calls are made. + * Detach the receiver, a closed receiver will throw exceptions if any further send calls are + * made. * - * @throws IOException if an error occurs while closing the receiver. + * @throws IOException + * if an error occurs while closing the receiver. */ public void detach() throws IOException { if (closed.compareAndSet(false, true)) { @@ -207,11 +212,12 @@ public class AmqpReceiver extends AmqpAbstractResource { } /** - * Attempts to wait on a message to be delivered to this receiver. The receive - * call will wait indefinitely for a message to be delivered. + * Attempts to wait on a message to be delivered to this receiver. The receive call will wait + * indefinitely for a message to be delivered. * * @return a newly received message sent to this receiver. - * @throws Exception if an error occurs during the receive attempt. + * @throws Exception + * if an error occurs during the receive attempt. */ public AmqpMessage receive() throws Exception { checkClosed(); @@ -219,13 +225,16 @@ public class AmqpReceiver extends AmqpAbstractResource { } /** - * Attempts to receive a message sent to this receiver, waiting for the given - * timeout value before giving up and returning null. + * Attempts to receive a message sent to this receiver, waiting for the given timeout value + * before giving up and returning null. * - * @param timeout the time to wait for a new message to arrive. - * @param unit the unit of time that the timeout value represents. + * @param timeout + * the time to wait for a new message to arrive. + * @param unit + * the unit of time that the timeout value represents. * @return a newly received message or null if the time to wait period expires. - * @throws Exception if an error occurs during the receive attempt. + * @throws Exception + * if an error occurs during the receive attempt. */ public AmqpMessage receive(long timeout, TimeUnit unit) throws Exception { checkClosed(); @@ -233,11 +242,12 @@ public class AmqpReceiver extends AmqpAbstractResource { } /** - * If a message is already available in this receiver's prefetch buffer then - * it is returned immediately otherwise this methods return null without waiting. + * If a message is already available in this receiver's prefetch buffer then it is returned + * immediately otherwise this methods return null without waiting. * * @return a newly received message or null if there is no currently available message. - * @throws Exception if an error occurs during the receive attempt. + * @throws Exception + * if an error occurs during the receive attempt. */ public AmqpMessage receiveNoWait() throws Exception { checkClosed(); @@ -248,7 +258,8 @@ public class AmqpReceiver extends AmqpAbstractResource { * Request a remote peer send a Message to this client waiting until one arrives. * * @return the pulled AmqpMessage or null if none was pulled from the remote. - * @throws IOException if an error occurs + * @throws IOException + * if an error occurs */ public AmqpMessage pull() throws IOException { return pull(-1, TimeUnit.MILLISECONDS); @@ -258,7 +269,8 @@ public class AmqpReceiver extends AmqpAbstractResource { * Request a remote peer send a Message to this client using an immediate drain request. * * @return the pulled AmqpMessage or null if none was pulled from the remote. - * @throws IOException if an error occurs + * @throws IOException + * if an error occurs */ public AmqpMessage pullImmediate() throws IOException { return pull(0, TimeUnit.MILLISECONDS); @@ -273,10 +285,13 @@ public class AmqpReceiver extends AmqpAbstractResource { * * The timeout value when positive is given in milliseconds. * - * @param timeout the amount of time to tell the remote peer to keep this pull request valid. - * @param unit the unit of measure that the timeout represents. + * @param timeout + * the amount of time to tell the remote peer to keep this pull request valid. + * @param unit + * the unit of measure that the timeout represents. * @return the pulled AmqpMessage or null if none was pulled from the remote. - * @throws IOException if an error occurs + * @throws IOException + * if an error occurs */ public AmqpMessage pull(final long timeout, final TimeUnit unit) throws IOException { checkClosed(); @@ -342,8 +357,10 @@ public class AmqpReceiver extends AmqpAbstractResource { /** * Controls the amount of credit given to the receiver link. * - * @param credit the amount of credit to grant. - * @throws IOException if an error occurs while sending the flow. + * @param credit + * the amount of credit to grant. + * @throws IOException + * if an error occurs while sending the flow. */ public void flow(final int credit) throws IOException { checkClosed(); @@ -369,8 +386,10 @@ public class AmqpReceiver extends AmqpAbstractResource { /** * Attempts to drain a given amount of credit from the link. * - * @param credit the amount of credit to drain. - * @throws IOException if an error occurs while sending the drain. + * @param credit + * the amount of credit to drain. + * @throws IOException + * if an error occurs while sending the drain. */ public void drain(final int credit) throws IOException { checkClosed(); @@ -396,7 +415,8 @@ public class AmqpReceiver extends AmqpAbstractResource { /** * Stops the receiver, using all link credit and waiting for in-flight messages to arrive. * - * @throws IOException if an error occurs while sending the drain. + * @throws IOException + * if an error occurs while sending the drain. */ public void stop() throws IOException { checkClosed(); @@ -419,12 +439,14 @@ public class AmqpReceiver extends AmqpAbstractResource { } /** - * Accepts a message that was dispatched under the given Delivery instance and settles the delivery. + * Accepts a message that was dispatched under the given Delivery instance and settles the + * delivery. * * @param delivery * the Delivery instance to accept. * - * @throws IOException if an error occurs while sending the accept. + * @throws IOException + * if an error occurs while sending the accept. */ public void accept(Delivery delivery) throws IOException { accept(delivery, this.session, true); @@ -438,25 +460,28 @@ public class AmqpReceiver extends AmqpAbstractResource { * @param settle * true if the receiver should settle the delivery or just send the disposition. * - * @throws IOException if an error occurs while sending the accept. + * @throws IOException + * if an error occurs while sending the accept. */ public void accept(Delivery delivery, boolean settle) throws IOException { accept(delivery, this.session, settle); } /** - * Accepts a message that was dispatched under the given Delivery instance and settles the delivery. + * Accepts a message that was dispatched under the given Delivery instance and settles the + * delivery. * * This method allows for the session that is used in the accept to be specified by the - * caller. This allows for an accepted message to be involved in a transaction that is - * being managed by some other session other than the one that created this receiver. + * caller. This allows for an accepted message to be involved in a transaction that is being + * managed by some other session other than the one that created this receiver. * * @param delivery * the Delivery instance to accept. * @param session * the session under which the message is being accepted. * - * @throws IOException if an error occurs while sending the accept. + * @throws IOException + * if an error occurs while sending the accept. */ public void accept(final Delivery delivery, final AmqpSession session) throws IOException { accept(delivery, session, true); @@ -466,8 +491,8 @@ public class AmqpReceiver extends AmqpAbstractResource { * Accepts a message that was dispatched under the given Delivery instance. * * This method allows for the session that is used in the accept to be specified by the - * caller. This allows for an accepted message to be involved in a transaction that is - * being managed by some other session other than the one that created this receiver. + * caller. This allows for an accepted message to be involved in a transaction that is being + * managed by some other session other than the one that created this receiver. * * @param delivery * the Delivery instance to accept. @@ -476,7 +501,8 @@ public class AmqpReceiver extends AmqpAbstractResource { * @param settle * true if the receiver should settle the delivery or just send the disposition. * - * @throws IOException if an error occurs while sending the accept. + * @throws IOException + * if an error occurs while sending the accept. */ public void accept(final Delivery delivery, final AmqpSession session, final boolean settle) throws IOException { checkClosed(); @@ -532,14 +558,16 @@ public class AmqpReceiver extends AmqpAbstractResource { /** * Mark a message that was dispatched under the given Delivery instance as Modified. * - * @param delivery the Delivery instance to mark modified. - * @param deliveryFailed indicates that the delivery failed for some reason. - * @param undeliverableHere marks the delivery as not being able to be process by link it was sent to. - * @throws IOException if an error occurs while sending the reject. + * @param delivery + * the Delivery instance to mark modified. + * @param deliveryFailed + * indicates that the delivery failed for some reason. + * @param undeliverableHere + * marks the delivery as not being able to be process by link it was sent to. + * @throws IOException + * if an error occurs while sending the reject. */ - public void modified(final Delivery delivery, - final Boolean deliveryFailed, - final Boolean undeliverableHere) throws IOException { + public void modified(final Delivery delivery, final Boolean deliveryFailed, final Boolean undeliverableHere) throws IOException { checkClosed(); if (delivery == null) { @@ -574,8 +602,10 @@ public class AmqpReceiver extends AmqpAbstractResource { /** * Release a message that was dispatched under the given Delivery instance. * - * @param delivery the Delivery instance to release. - * @throws IOException if an error occurs while sending the release. + * @param delivery + * the Delivery instance to release. + * @throws IOException + * if an error occurs while sending the release. */ public void release(final Delivery delivery) throws IOException { checkClosed(); @@ -609,8 +639,10 @@ public class AmqpReceiver extends AmqpAbstractResource { /** * Reject a message that was dispatched under the given Delivery instance. * - * @param delivery the Delivery instance to reject. - * @throws IOException if an error occurs while sending the release. + * @param delivery + * the Delivery instance to reject. + * @throws IOException + * if an error occurs while sending the release. */ public void reject(final Delivery delivery) throws IOException { checkClosed(); @@ -648,7 +680,7 @@ public class AmqpReceiver extends AmqpAbstractResource { return new UnmodifiableReceiver(getEndpoint()); } - //----- Receiver configuration properties --------------------------------// + // ----- Receiver configuration properties --------------------------------// public boolean isPresettle() { return presettle; @@ -690,7 +722,7 @@ public class AmqpReceiver extends AmqpAbstractResource { return session.getConnection().getDrainTimeout(); } - //----- Internal implementation ------------------------------------------// + // ----- Internal implementation ------------------------------------------// @Override protected void doOpen() { @@ -802,7 +834,7 @@ public class AmqpReceiver extends AmqpAbstractResource { protected void configureSource(Source source) { Map filters = new HashMap<>(); - Symbol[] outcomes = new Symbol[]{Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL, Released.DESCRIPTOR_SYMBOL, Modified.DESCRIPTOR_SYMBOL}; + Symbol[] outcomes = new Symbol[] {Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL, Released.DESCRIPTOR_SYMBOL, Modified.DESCRIPTOR_SYMBOL}; if (getSubscriptionName() != null && !getSubscriptionName().isEmpty()) { source.setExpiryPolicy(TerminusExpiryPolicy.NEVER); @@ -868,6 +900,8 @@ public class AmqpReceiver extends AmqpAbstractResource { } private void processDelivery(Delivery incoming) throws Exception { + doDeliveryInspection(incoming); + Message message = null; try { message = decodeIncomingMessage(incoming); @@ -890,6 +924,14 @@ public class AmqpReceiver extends AmqpAbstractResource { } } + private void doDeliveryInspection(Delivery delivery) { + try { + getStateInspector().inspectDelivery(getReceiver(), delivery); + } catch (Throwable error) { + getStateInspector().markAsInvalid(error.getMessage()); + } + } + @Override public void processFlowUpdates(AmqpConnection connection) throws IOException { if (pullRequest != null || stopRequest != null) { @@ -1013,7 +1055,7 @@ public class AmqpReceiver extends AmqpAbstractResource { } } - //----- Internal Transaction state callbacks -----------------------------// + // ----- Internal Transaction state callbacks -----------------------------// void preCommit() { } @@ -1027,7 +1069,7 @@ public class AmqpReceiver extends AmqpAbstractResource { void postRollback() { } - //----- Inner classes used in message pull operations --------------------// + // ----- Inner classes used in message pull operations --------------------// protected static final class ScheduledRequest implements AsyncResult { diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpSender.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpSender.java index c9bc0d6ba3..03bd28e846 100644 --- a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpSender.java +++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpSender.java @@ -56,7 +56,7 @@ import org.slf4j.LoggerFactory; public class AmqpSender extends AmqpAbstractResource { private static final Logger LOG = LoggerFactory.getLogger(AmqpSender.class); - private static final byte[] EMPTY_BYTE_ARRAY = new byte[]{}; + private static final byte[] EMPTY_BYTE_ARRAY = new byte[] {}; public static final long DEFAULT_SEND_TIMEOUT = 15000; @@ -126,9 +126,12 @@ public class AmqpSender extends AmqpAbstractResource { /** * Create a new sender instance using the given Target when creating the link. * - * @param session The parent session that created the session. - * @param target The target that this sender produces to. - * @param senderId The unique ID assigned to this sender. + * @param session + * The parent session that created the session. + * @param target + * The target that this sender produces to. + * @param senderId + * The unique ID assigned to this sender. */ public AmqpSender(AmqpSession session, Target target, String senderId) { @@ -147,8 +150,10 @@ public class AmqpSender extends AmqpAbstractResource { /** * Sends the given message to this senders assigned address. * - * @param message the message to send. - * @throws IOException if an error occurs during the send. + * @param message + * the message to send. + * @throws IOException + * if an error occurs during the send. */ public void send(final AmqpMessage message) throws IOException { checkClosed(); @@ -156,11 +161,15 @@ public class AmqpSender extends AmqpAbstractResource { } /** - * Sends the given message to this senders assigned address using the supplied transaction ID. + * Sends the given message to this senders assigned address using the supplied transaction + * ID. * - * @param message the message to send. - * @param txId the transaction ID to assign the outgoing send. - * @throws IOException if an error occurs during the send. + * @param message + * the message to send. + * @param txId + * the transaction ID to assign the outgoing send. + * @throws IOException + * if an error occurs during the send. */ public void send(final AmqpMessage message, final AmqpTransactionId txId) throws IOException { checkClosed(); @@ -188,10 +197,11 @@ public class AmqpSender extends AmqpAbstractResource { } /** - * Close the sender, a closed sender will throw exceptions if any further send - * calls are made. + * Close the sender, a closed sender will throw exceptions if any further send calls are + * made. * - * @throws IOException if an error occurs while closing the sender. + * @throws IOException + * if an error occurs while closing the sender. */ public void close() throws IOException { if (closed.compareAndSet(false, true)) { @@ -231,7 +241,7 @@ public class AmqpSender extends AmqpAbstractResource { return address; } - //----- Sender configuration ---------------------------------------------// + // ----- Sender configuration ---------------------------------------------// /** * @return will messages be settle on send. @@ -243,7 +253,8 @@ public class AmqpSender extends AmqpAbstractResource { /** * Configure is sent messages are marked as settled on send, defaults to false. * - * @param presettle configure if this sender will presettle all sent messages. + * @param presettle + * configure if this sender will presettle all sent messages. */ public void setPresettle(boolean presettle) { this.presettle = presettle; @@ -259,13 +270,13 @@ public class AmqpSender extends AmqpAbstractResource { /** * Sets the amount of time the sender will block on a send before failing. * - * @param sendTimeout time in milliseconds to wait. + * @param sendTimeout + * time in milliseconds to wait. */ public void setSendTimeout(long sendTimeout) { this.sendTimeout = sendTimeout; } - public void setDesiredCapabilities(Symbol[] desiredCapabilities) { if (getEndpoint() != null) { throw new IllegalStateException("Endpoint already established"); @@ -290,7 +301,7 @@ public class AmqpSender extends AmqpAbstractResource { this.properties = properties; } - //----- Private Sender implementation ------------------------------------// + // ----- Private Sender implementation ------------------------------------// private void checkClosed() { if (isClosed()) { @@ -301,7 +312,7 @@ public class AmqpSender extends AmqpAbstractResource { @Override protected void doOpen() { - Symbol[] outcomes = new Symbol[]{Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL}; + Symbol[] outcomes = new Symbol[] {Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL}; Source source = new Source(); source.setAddress(senderId); source.setOutcomes(outcomes); @@ -384,6 +395,14 @@ public class AmqpSender extends AmqpAbstractResource { } } + protected void doDeliveryUpdateInspection(Delivery delivery) { + try { + getStateInspector().inspectDeliveryUpdate(getSender(), delivery); + } catch (Throwable error) { + getStateInspector().markAsInvalid(error.getMessage()); + } + } + @Override protected Exception getOpenAbortException() { // Verify the attach response contained a non-null target @@ -470,6 +489,8 @@ public class AmqpSender extends AmqpAbstractResource { continue; } + doDeliveryUpdateInspection(delivery); + Outcome outcome = null; if (state instanceof TransactionalState) { LOG.trace("State of delivery is Transactional, retrieving outcome: {}", state); @@ -516,8 +537,6 @@ public class AmqpSender extends AmqpAbstractResource { tagGenerator.returnTag(delivery.getTag()); delivery.settle(); toRemove.add(delivery); - - doDeliveryUpdate(delivery); } pending.removeAll(toRemove); diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpValidator.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpValidator.java index 236dc606d9..291c690f1a 100644 --- a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpValidator.java +++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpValidator.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -72,7 +72,11 @@ public class AmqpValidator { } - public void inspectDeliveryUpdate(Delivery delivery) { + public void inspectDelivery(Receiver receiver, Delivery delivery) { + + } + + public void inspectDeliveryUpdate(Sender sender, Delivery delivery) { } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpClientTestSupport.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpClientTestSupport.java index 02b1b99a57..b8d3b1c231 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpClientTestSupport.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpClientTestSupport.java @@ -16,19 +16,28 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; +import java.net.URI; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import java.util.Set; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; + import org.apache.activemq.artemis.api.core.RoutingType; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.TransportConfiguration; -import org.apache.activemq.artemis.core.config.Configuration; -import org.apache.activemq.artemis.core.config.CoreAddressConfiguration; -import org.apache.activemq.artemis.core.config.CoreQueueConfiguration; +import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants; +import org.apache.activemq.artemis.core.security.Role; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.core.server.impl.AddressInfo; +import org.apache.activemq.artemis.core.settings.HierarchicalRepository; +import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; -import org.apache.activemq.artemis.jms.server.JMSServerManager; -import org.apache.activemq.artemis.jms.server.impl.JMSServerManagerImpl; +import org.apache.activemq.artemis.protocol.amqp.converter.AMQPMessageSupport; +import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; @@ -44,16 +53,26 @@ import org.junit.Before; */ public class AmqpClientTestSupport extends AmqpTestSupport { - protected static Symbol SHARED = Symbol.getSymbol("shared"); - protected static Symbol GLOBAL = Symbol.getSymbol("global"); + protected static final Symbol SHARED = Symbol.getSymbol("shared"); + protected static final Symbol GLOBAL = Symbol.getSymbol("global"); + + protected static final String BROKER_NAME = "localhost"; + + protected String guestUser = "guest"; + protected String guestPass = "guest"; + + protected String fullUser = "user"; + protected String fullPass = "pass"; - protected JMSServerManager serverManager; protected ActiveMQServer server; + protected MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer(); + @Before @Override public void setUp() throws Exception { super.setUp(); + server = createServer(); } @@ -69,18 +88,13 @@ public class AmqpClientTestSupport extends AmqpTestSupport { } connections.clear(); - if (serverManager != null) { - try { - serverManager.stop(); - } catch (Throwable ignored) { - ignored.printStackTrace(); + try { + if (server != null) { + server.stop(); } - serverManager = null; + } finally { + super.tearDown(); } - - server.stop(); - - super.tearDown(); } protected boolean isAutoCreateQueues() { @@ -91,6 +105,10 @@ public class AmqpClientTestSupport extends AmqpTestSupport { return true; } + protected boolean isSecurityEnabled() { + return false; + } + protected String getDeadLetterAddress() { return "ActiveMQ.DLQ"; } @@ -99,48 +117,129 @@ public class AmqpClientTestSupport extends AmqpTestSupport { return 10; } + public URI getBrokerOpenWireConnectionURI() { + return getBrokerAmqpConnectionURI(); + } + protected ActiveMQServer createServer() throws Exception { - ActiveMQServer server = createServer(true, true); - serverManager = new JMSServerManagerImpl(server); - Configuration serverConfig = server.getConfiguration(); + return createServer(AMQP_PORT); + } - // Address 1 - CoreAddressConfiguration address = new CoreAddressConfiguration(); - address.setName(getQueueName()).getRoutingTypes().add(RoutingType.ANYCAST); - CoreQueueConfiguration queueConfig = new CoreQueueConfiguration(); - queueConfig.setName(getQueueName()).setAddress(getQueueName()).setRoutingType(RoutingType.ANYCAST); - address.getQueueConfigurations().add(queueConfig); - serverConfig.addAddressConfiguration(address); + protected ActiveMQServer createServer(int port) throws Exception { - // Address 1....N - for (int i = 0; i < getPrecreatedQueueSize(); ++i) { - CoreAddressConfiguration address2 = new CoreAddressConfiguration(); - address2.setName(getQueueName(i)).getRoutingTypes().add(RoutingType.ANYCAST); - CoreQueueConfiguration queueConfig2 = new CoreQueueConfiguration(); - queueConfig2.setName(getQueueName(i)).setAddress(getQueueName(i)).setRoutingType(RoutingType.ANYCAST); - address2.getQueueConfigurations().add(queueConfig2); - serverConfig.addAddressConfiguration(address2); - } + final ActiveMQServer server = this.createServer(true, true); + server.getConfiguration().getAcceptorConfigurations().clear(); + server.getConfiguration().getAcceptorConfigurations().add(addAcceptorConfiguration(server, port)); + server.getConfiguration().setName(BROKER_NAME); + server.getConfiguration().setJournalDirectory(server.getConfiguration().getJournalDirectory() + port); + server.getConfiguration().setBindingsDirectory(server.getConfiguration().getBindingsDirectory() + port); + server.getConfiguration().setPagingDirectory(server.getConfiguration().getPagingDirectory() + port); + server.getConfiguration().setJMXManagementEnabled(true); + server.getConfiguration().setMessageExpiryScanPeriod(5000); + server.setMBeanServer(mBeanServer); + + // Add any additional Acceptors needed for tests + addAdditionalAcceptors(server); + + // Address configuration + configureAddressPolicy(server); + + // Add optional security for tests that need it + configureBrokerSecurity(server); + + server.start(); + + // Prepare all addresses and queues for client tests. + createAddressAndQueues(server); + + return server; + } + + protected TransportConfiguration addAcceptorConfiguration(ActiveMQServer server, int port) { + HashMap params = new HashMap<>(); + params.put(TransportConstants.PORT_PROP_NAME, String.valueOf(port)); + params.put(TransportConstants.PROTOCOLS_PROP_NAME, getConfiguredProtocols()); + + HashMap amqpParams = new HashMap<>(); + configureAMQPAcceptorParameters(amqpParams); + + return new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params, "netty-acceptor", amqpParams); + } + + protected String getConfiguredProtocols() { + return "AMQP,OPENWIRE"; + } + + protected void configureAddressPolicy(ActiveMQServer server) { // Address configuration AddressSettings addressSettings = new AddressSettings(); + addressSettings.setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE); addressSettings.setAutoCreateQueues(isAutoCreateQueues()); addressSettings.setAutoCreateAddresses(isAutoCreateQueues()); - addressSettings.setDeadLetterAddress(new SimpleString(getDeadLetterAddress())); + addressSettings.setDeadLetterAddress(SimpleString.toSimpleString(getDeadLetterAddress())); + addressSettings.setExpiryAddress(SimpleString.toSimpleString(getDeadLetterAddress())); - serverConfig.getAddressesSettings().put("#", addressSettings); - serverConfig.setSecurityEnabled(false); - Set acceptors = serverConfig.getAcceptorConfigurations(); + server.getConfiguration().getAddressesSettings().put("#", addressSettings); + Set acceptors = server.getConfiguration().getAcceptorConfigurations(); for (TransportConfiguration tc : acceptors) { - if (tc.getName().equals("netty")) { + if (tc.getName().equals("netty-acceptor")) { tc.getExtraParams().put("anycastPrefix", "anycast://"); tc.getExtraParams().put("multicastPrefix", "multicast://"); } } - serverManager.start(); - server.start(); - return server; + } + + protected void createAddressAndQueues(ActiveMQServer server) throws Exception { + // Default DLQ + server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(getQueueName()), RoutingType.ANYCAST)); + server.createQueue(SimpleString.toSimpleString(getQueueName()), RoutingType.ANYCAST, SimpleString.toSimpleString(getQueueName()), null, true, false, -1, false, true); + + // Default Queue + server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(getDeadLetterAddress()), RoutingType.ANYCAST)); + server.createQueue(SimpleString.toSimpleString(getDeadLetterAddress()), RoutingType.ANYCAST, SimpleString.toSimpleString(getDeadLetterAddress()), null, true, false, -1, false, true); + + // Default Topic + server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(getTopicName()), RoutingType.MULTICAST)); + server.createQueue(SimpleString.toSimpleString(getTopicName()), RoutingType.MULTICAST, SimpleString.toSimpleString(getTopicName()), null, true, false, -1, false, true); + + // Additional Test Queues + for (int i = 0; i < getPrecreatedQueueSize(); ++i) { + server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(getQueueName(i)), RoutingType.ANYCAST)); + server.createQueue(SimpleString.toSimpleString(getQueueName(i)), RoutingType.ANYCAST, SimpleString.toSimpleString(getQueueName(i)), null, true, false, -1, false, true); + } + } + + protected void addAdditionalAcceptors(ActiveMQServer server) throws Exception { + // None by default + } + + protected void configureBrokerSecurity(ActiveMQServer server) { + if (isSecurityEnabled()) { + ActiveMQJAASSecurityManager securityManager = (ActiveMQJAASSecurityManager) server.getSecurityManager(); + + // User additions + securityManager.getConfiguration().addUser(guestUser, guestPass); + securityManager.getConfiguration().addRole(guestUser, "guest"); + securityManager.getConfiguration().addUser(fullUser, fullPass); + securityManager.getConfiguration().addRole(fullUser, "full"); + + // Configure roles + HierarchicalRepository> securityRepository = server.getSecurityRepository(); + HashSet value = new HashSet<>(); + value.add(new Role("guest", false, true, true, true, true, true, true, true)); + value.add(new Role("full", true, true, true, true, true, true, true, true)); + securityRepository.addMatch(getQueueName(), value); + + server.getConfiguration().setSecurityEnabled(true); + } else { + server.getConfiguration().setSecurityEnabled(false); + } + } + + protected void configureAMQPAcceptorParameters(Map params) { + // None by default } public Queue getProxyToQueue(String queueName) { @@ -151,6 +250,10 @@ public class AmqpClientTestSupport extends AmqpTestSupport { return getName(); } + public String getTopicName() { + return getName() + "-Topic"; + } + public String getQueueName() { return getName(); } @@ -166,17 +269,45 @@ public class AmqpClientTestSupport extends AmqpTestSupport { this.useSSL = useSSL; } - protected void sendMessages(int numMessages, String address) throws Exception { + protected void sendMessages(String destinationName, int count) throws Exception { + sendMessages(destinationName, count, null); + } + + protected void sendMessages(String destinationName, int count, RoutingType routingType) throws Exception { AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); - AmqpSession session = connection.createSession(); - AmqpSender sender = session.createSender(address); - for (int i = 0; i < numMessages; i++) { - AmqpMessage message = new AmqpMessage(); - message.setText("message-" + i); - sender.send(message); + try { + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(destinationName); + + for (int i = 0; i < count; ++i) { + AmqpMessage message = new AmqpMessage(); + message.setMessageId("MessageID:" + i); + if (routingType != null) { + message.setMessageAnnotation(AMQPMessageSupport.ROUTING_TYPE.toString(), routingType.getType()); + } + sender.send(message); + } + } finally { + connection.close(); + } + } + + protected void sendMessages(String destinationName, int count, boolean durable) throws Exception { + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + try { + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(destinationName); + + for (int i = 0; i < count; ++i) { + AmqpMessage message = new AmqpMessage(); + message.setMessageId("MessageID:" + i); + message.setDurable(durable); + sender.send(message); + } + } finally { + connection.close(); } - sender.close(); - connection.connect(); } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpDescribedTypePayloadTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpDescribedTypePayloadTest.java index 4b9213be09..e8c44321b8 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpDescribedTypePayloadTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpDescribedTypePayloadTest.java @@ -29,6 +29,7 @@ import javax.jms.Session; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; @@ -43,7 +44,7 @@ import org.junit.Test; * Test that the broker can pass through an AMQP message with a described type in the message * body regardless of transformer in use. */ -public class AmqpDescribedTypePayloadTest extends AmqpClientTestSupport { +public class AmqpDescribedTypePayloadTest extends JMSClientTestSupport { @Test(timeout = 60000) public void testSendMessageWithDescribedTypeInBody() throws Exception { @@ -87,7 +88,7 @@ public class AmqpDescribedTypePayloadTest extends AmqpClientTestSupport { Queue queue = getProxyToQueue(getQueueName()); assertEquals(1, queue.getMessageCount()); - ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); + ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(getBrokerOpenWireConnectionURI()); Connection jmsConnection = factory.createConnection(); try { Session jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); @@ -118,10 +119,10 @@ public class AmqpDescribedTypePayloadTest extends AmqpClientTestSupport { sender.close(); Queue queue = getProxyToQueue(getQueueName()); - assertEquals(1, queue.getMessageCount()); + assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1)); - // Receive and resend with OpenWire JMS client - JmsConnectionFactory factory = new JmsConnectionFactory("amqp://localhost:61616"); + // Receive and resend with Qpid JMS client + JmsConnectionFactory factory = new JmsConnectionFactory(getBrokerQpidJMSConnectionURI()); Connection jmsConnection = factory.createConnection(); try { Session jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpDurableReceiverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpDurableReceiverTest.java index 19d4847e4d..d6593066c7 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpDurableReceiverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpDurableReceiverTest.java @@ -24,8 +24,6 @@ import java.util.concurrent.TimeUnit; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.postoffice.Binding; -import org.apache.activemq.artemis.api.core.RoutingType; -import org.apache.activemq.artemis.core.server.impl.AddressInfo; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpFrameValidator; @@ -53,13 +51,6 @@ public class AmqpDurableReceiverTest extends AmqpClientTestSupport { private final String SELECTOR_STRING = "color = red"; - @Override - public void setUp() throws Exception { - super.setUp(); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(getTopicName()), RoutingType.MULTICAST)); - server.createQueue(new SimpleString(getTopicName()), RoutingType.MULTICAST, new SimpleString(getTopicName()), null, true, false); - } - @Test(timeout = 60000) public void testCreateDurableReceiver() throws Exception { @@ -365,15 +356,11 @@ public class AmqpDurableReceiverTest extends AmqpClientTestSupport { return null; } - public String getContainerID() { + private String getContainerID() { return "myContainerID"; } - public String getSubscriptionName() { + private String getSubscriptionName() { return "mySubscription"; } - - public String getTopicName() { - return "myTopic"; - } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpExpiredMessageTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpExpiredMessageTest.java index 440de12534..42bc160884 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpExpiredMessageTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpExpiredMessageTest.java @@ -18,13 +18,16 @@ package org.apache.activemq.artemis.tests.integration.amqp; import java.util.concurrent.TimeUnit; +import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpReceiver; import org.apache.activemq.transport.amqp.client.AmqpSender; import org.apache.activemq.transport.amqp.client.AmqpSession; +import org.junit.Assert; import org.junit.Test; public class AmqpExpiredMessageTest extends AmqpClientTestSupport { @@ -55,7 +58,7 @@ public class AmqpExpiredMessageTest extends AmqpClientTestSupport { AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS); assertNull(received); - assertEquals(1, queueView.getMessagesExpired()); + assertTrue("Message should have expired", Wait.waitFor(() -> queueView.getMessagesExpired() == 1)); connection.close(); } @@ -119,7 +122,7 @@ public class AmqpExpiredMessageTest extends AmqpClientTestSupport { AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS); assertNull(received); - assertEquals(1, queueView.getMessagesExpired()); + assertTrue("Message should have expired", Wait.waitFor(() -> queueView.getMessagesExpired() == 1)); connection.close(); } @@ -154,7 +157,7 @@ public class AmqpExpiredMessageTest extends AmqpClientTestSupport { AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS); assertNull(received); - assertEquals(1, queueView.getMessagesExpired()); + assertTrue("Message should have expired", Wait.waitFor(() -> queueView.getMessagesExpired() == 1)); connection.close(); } @@ -253,8 +256,64 @@ public class AmqpExpiredMessageTest extends AmqpClientTestSupport { AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS); assertNull(received); - assertEquals(1, queueView.getMessagesExpired()); + assertTrue("Message should have expired", Wait.waitFor(() -> queueView.getMessagesExpired() == 1)); connection.close(); } + + @Test(timeout = 60000) + public void testExpiredMessageLandsInDLQ() throws Throwable { + internalSendExpiry(false); + } + + @Test(timeout = 60000) + public void testExpiredMessageLandsInDLQAndExistsAfterRestart() throws Throwable { + internalSendExpiry(true); + } + + public void internalSendExpiry(boolean restartServer) throws Throwable { + AmqpClient client = createAmqpClient(); + AmqpConnection connection = client.connect(); + + try { + + // Normal Session which won't create an TXN itself + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(getQueueName()); + + AmqpMessage message = new AmqpMessage(); + message.setDurable(true); + message.setText("Test-Message"); + message.setDeliveryAnnotation("shouldDisappear", 1); + message.setAbsoluteExpiryTime(System.currentTimeMillis() + 1000); + sender.send(message); + + org.apache.activemq.artemis.core.server.Queue dlq = server.locateQueue(SimpleString.toSimpleString(getDeadLetterAddress())); + + assertTrue("Message not movied to DLQ", Wait.waitFor(() -> dlq.getMessageCount() > 0, 5000, 500)); + + connection.close(); + + if (restartServer) { + server.stop(); + server.start(); + } + + connection = client.connect(); + session = connection.createSession(); + + // Read all messages from the Queue + AmqpReceiver receiver = session.createReceiver(getDeadLetterAddress()); + receiver.flow(20); + + message = receiver.receive(5, TimeUnit.SECONDS); + Assert.assertNotNull(message); + Assert.assertEquals(getQueueName(), message.getMessageAnnotation(org.apache.activemq.artemis.api.core.Message.HDR_ORIGINAL_ADDRESS.toString())); + Assert.assertNull(message.getDeliveryAnnotation("shouldDisappear")); + Assert.assertNull(receiver.receiveNoWait()); + + } finally { + connection.close(); + } + } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpFlowControlTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpFlowControlTest.java new file mode 100644 index 0000000000..03db6d788b --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpFlowControlTest.java @@ -0,0 +1,284 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.io.IOException; +import java.net.URI; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.jms.Connection; +import javax.jms.Destination; +import javax.jms.MessageProducer; +import javax.jms.ResourceAllocationException; +import javax.jms.Session; + +import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.core.server.ActiveMQServer; +import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy; +import org.apache.activemq.artemis.core.settings.impl.AddressSettings; +import org.apache.activemq.transport.amqp.client.AmqpClient; +import org.apache.activemq.transport.amqp.client.AmqpConnection; +import org.apache.activemq.transport.amqp.client.AmqpMessage; +import org.apache.activemq.transport.amqp.client.AmqpReceiver; +import org.apache.activemq.transport.amqp.client.AmqpSender; +import org.apache.activemq.transport.amqp.client.AmqpSession; +import org.junit.Assert; +import org.junit.Test; + +public class AmqpFlowControlTest extends JMSClientTestSupport { + + private static final long MAX_SIZE_BYTES = 1 * 1024 * 1024; + private static final long MAX_SIZE_BYTES_REJECT_THRESHOLD = 2 * 1024 * 1024; + + private String singleCreditAcceptorURI = new String("tcp://localhost:" + (AMQP_PORT + 8)); + private int messagesSent; + + @Override + public void setUp() throws Exception { + super.setUp(); + + messagesSent = 0; + } + + @Override + protected void addAdditionalAcceptors(ActiveMQServer server) throws Exception { + server.getConfiguration().addAcceptorConfiguration("flow", singleCreditAcceptorURI + "?protocols=AMQP;useEpoll=false;amqpCredits=1;amqpMinCredits=1"); + } + + @Override + protected void configureAddressPolicy(ActiveMQServer server) { + // For BLOCK tests + AddressSettings addressSettings = server.getAddressSettingsRepository().getMatch("#"); + addressSettings.setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK); + addressSettings.setMaxSizeBytes(MAX_SIZE_BYTES); + addressSettings.setMaxSizeBytesRejectThreshold(MAX_SIZE_BYTES_REJECT_THRESHOLD); + server.getAddressSettingsRepository().addMatch("#", addressSettings); + } + + @Test(timeout = 60000) + public void testCreditsAreAllocatedOnceOnLinkCreated() throws Exception { + AmqpClient client = createAmqpClient(new URI(singleCreditAcceptorURI)); + AmqpConnection connection = addConnection(client.connect()); + + try { + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(getQueueName()); + assertEquals("Should only be issued one credit", 1, sender.getSender().getCredit()); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testCreditsAreNotAllocatedWhenAddressIsFull() throws Exception { + AmqpClient client = createAmqpClient(new URI(singleCreditAcceptorURI)); + AmqpConnection connection = addConnection(client.connect()); + + try { + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(getQueueName()); + + // Use blocking send to ensure buffered messages do not interfere with credit. + sender.setSendTimeout(-1); + sendUntilFull(sender); + + // This should be -1. A single message is buffered in the client, and 0 credit has been allocated. + assertTrue(sender.getSender().getCredit() == -1); + + long addressSize = server.getPagingManager().getPageStore(new SimpleString(getQueueName())).getAddressSize(); + assertTrue(addressSize >= MAX_SIZE_BYTES && addressSize <= MAX_SIZE_BYTES_REJECT_THRESHOLD); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testAddressIsBlockedForOtherProdudersWhenFull() throws Exception { + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Destination d = session.createQueue(getQueueName()); + MessageProducer p = session.createProducer(d); + + fillAddress(getQueueName()); + + Exception e = null; + try { + p.send(session.createBytesMessage()); + } catch (ResourceAllocationException rae) { + e = rae; + } + assertTrue(e instanceof ResourceAllocationException); + assertTrue(e.getMessage().contains("resource-limit-exceeded")); + + long addressSize = server.getPagingManager().getPageStore(new SimpleString(getQueueName())).getAddressSize(); + assertTrue(addressSize >= MAX_SIZE_BYTES_REJECT_THRESHOLD); + } + + @Test(timeout = 60000) + public void testCreditsAreRefreshedWhenAddressIsUnblocked() throws Exception { + fillAddress(getQueueName()); + + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + + try { + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(getQueueName()); + + // Wait for a potential flow frame. + Thread.sleep(500); + assertEquals(0, sender.getSender().getCredit()); + + // Empty Address except for 1 message used later. + AmqpReceiver receiver = session.createReceiver(getQueueName()); + receiver.flow(100); + + AmqpMessage m; + for (int i = 0; i < messagesSent - 1; i++) { + m = receiver.receive(5000, TimeUnit.MILLISECONDS); + m.accept(); + } + + // Wait for address to unblock and flow frame to arrive + Thread.sleep(500); + + assertTrue(sender.getSender().getCredit() >= 0); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testNewLinkAttachAreNotAllocatedCreditsWhenAddressIsBlocked() throws Exception { + fillAddress(getQueueName()); + + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + + try { + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(getQueueName()); + + // Wait for a potential flow frame. + Thread.sleep(1000); + assertEquals(0, sender.getSender().getCredit()); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testTxIsRolledBackOnRejectedPreSettledMessage() throws Throwable { + + // Create the link attach before filling the address to ensure the link is allocated credit. + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(getQueueName()); + sender.setPresettle(true); + + fillAddress(getQueueName()); + + final AmqpMessage message = new AmqpMessage(); + byte[] payload = new byte[50 * 1024]; + message.setBytes(payload); + + Exception expectedException = null; + try { + session.begin(); + sender.send(message); + session.commit(); + } catch (Exception e) { + expectedException = e; + } finally { + connection.close(); + } + + assertNotNull(expectedException); + assertTrue(expectedException.getMessage().contains("resource-limit-exceeded")); + assertTrue(expectedException.getMessage().contains("Address is full: " + getQueueName())); + } + + /* + * Fills an address. Careful when using this method. Only use when rejected messages are switched on. + */ + private void fillAddress(String address) throws Exception { + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + Exception exception = null; + try { + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(address); + sendUntilFull(sender); + } catch (Exception e) { + exception = e; + } finally { + connection.close(); + } + + // Should receive a rejected error + assertNotNull(exception); + assertTrue(exception.getMessage().contains("amqp:resource-limit-exceeded")); + } + + private void sendUntilFull(final AmqpSender sender) throws Exception { + final AmqpMessage message = new AmqpMessage(); + byte[] payload = new byte[50 * 1024]; + message.setBytes(payload); + + final int maxMessages = 50; + final AtomicInteger sentMessages = new AtomicInteger(0); + final Exception[] errors = new Exception[1]; + final CountDownLatch timeout = new CountDownLatch(1); + + Runnable sendMessages = new Runnable() { + @Override + public void run() { + try { + for (int i = 0; i < maxMessages; i++) { + sender.send(message); + System.out.println("Sent " + i); + sentMessages.getAndIncrement(); + } + timeout.countDown(); + } catch (IOException e) { + errors[0] = e; + } + } + }; + + Thread t = new Thread(sendMessages); + + try { + t.start(); + + timeout.await(1, TimeUnit.SECONDS); + + messagesSent = sentMessages.get(); + if (errors[0] != null) { + throw errors[0]; + } + } finally { + t.interrupt(); + t.join(1000); + Assert.assertFalse(t.isAlive()); + } + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonFullQualifiedNameTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpFullyQualifiedNameTest.java similarity index 78% rename from tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonFullQualifiedNameTest.java rename to tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpFullyQualifiedNameTest.java index 22ba64dfc2..65b0f7f028 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonFullQualifiedNameTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpFullyQualifiedNameTest.java @@ -16,6 +16,16 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; +import java.util.HashMap; + +import javax.jms.Connection; +import javax.jms.InvalidDestinationException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.Topic; + import org.apache.activemq.artemis.api.core.RoutingType; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.TransportConfiguration; @@ -23,32 +33,18 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; -import org.apache.activemq.artemis.core.config.Configuration; import org.apache.activemq.artemis.core.postoffice.Binding; import org.apache.activemq.artemis.core.postoffice.Bindings; import org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding; +import org.apache.activemq.artemis.core.server.ActiveMQServer; +import org.apache.activemq.artemis.core.server.Queue; import org.apache.activemq.artemis.core.server.QueueQueryResult; -import org.apache.activemq.artemis.core.settings.impl.AddressSettings; +import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.artemis.utils.CompositeAddress; -import org.apache.qpid.jms.JmsConnectionFactory; -import org.junit.After; import org.junit.Before; import org.junit.Test; -import javax.jms.Connection; -import javax.jms.InvalidDestinationException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.Topic; -import java.util.HashMap; -import java.util.Map; - -public class ProtonFullQualifiedNameTest extends ProtonTestBase { - - private static final String amqpConnectionUri = "amqp://localhost:5672"; +public class AmqpFullyQualifiedNameTest extends JMSClientTestSupport { private SimpleString anycastAddress = new SimpleString("address.anycast"); private SimpleString multicastAddress = new SimpleString("address.multicast"); @@ -57,7 +53,6 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase { private SimpleString anycastQ2 = new SimpleString("q2"); private SimpleString anycastQ3 = new SimpleString("q3"); - JmsConnectionFactory factory = new JmsConnectionFactory(amqpConnectionUri); private ServerLocator locator; @Override @@ -65,36 +60,20 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase { public void setUp() throws Exception { super.setUp(); - Configuration serverConfig = server.getConfiguration(); - - Map settings = serverConfig.getAddressesSettings(); - assertNotNull(settings); - AddressSettings addressSetting = settings.get("#"); - if (addressSetting == null) { - addressSetting = new AddressSettings(); - settings.put("#", addressSetting); - } - addressSetting.setAutoCreateQueues(true); locator = createNettyNonHALocator(); } @Override - @After - public void tearDown() throws Exception { - super.tearDown(); + protected void addAdditionalAcceptors(ActiveMQServer server) throws Exception { + server.getConfiguration().addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, new HashMap(), "netty", new HashMap())); } - @Override - protected void configureServer(Configuration serverConfig) { - serverConfig.addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, new HashMap(), "netty", new HashMap())); - } - - @Test + @Test(timeout = 60000) //there isn't much use of FQQN for topics //however we can test query functionality public void testTopic() throws Exception { - Connection connection = factory.createConnection(); + Connection connection = createConnection(false); try { connection.setClientID("FQQNconn"); connection.start(); @@ -141,14 +120,14 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase { server.createQueue(anycastAddress, RoutingType.ANYCAST, anycastQ2, null, true, false, -1, false, true); server.createQueue(anycastAddress, RoutingType.ANYCAST, anycastQ3, null, true, false, -1, false, true); - Connection connection = factory.createConnection(); + Connection connection = createConnection(); try { connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - Queue q1 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ1).toString()); - Queue q2 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ2).toString()); - Queue q3 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ3).toString()); + javax.jms.Queue q1 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ1).toString()); + javax.jms.Queue q2 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ2).toString()); + javax.jms.Queue q3 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ3).toString()); //send 3 messages to anycastAddress ClientSessionFactory cf = createSessionFactory(locator); @@ -167,18 +146,25 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase { assertNotNull(consumer2.receive(2000)); assertNotNull(consumer3.receive(2000)); + Queue queue1 = getProxyToQueue(anycastQ1.toString()); + assertTrue("Message not consumed on Q1", Wait.waitFor(() -> queue1.getMessageCount() == 0)); + Queue queue2 = getProxyToQueue(anycastQ2.toString()); + assertTrue("Message not consumed on Q2", Wait.waitFor(() -> queue2.getMessageCount() == 0)); + Queue queue3 = getProxyToQueue(anycastQ3.toString()); + assertTrue("Message not consumed on Q3", Wait.waitFor(() -> queue3.getMessageCount() == 0)); + connection.close(); //queues are empty now for (SimpleString q : new SimpleString[]{anycastQ1, anycastQ2, anycastQ3}) { //FQQN query - QueueQueryResult query = server.queueQuery(CompositeAddress.toFullQN(anycastAddress, q)); + final QueueQueryResult query = server.queueQuery(CompositeAddress.toFullQN(anycastAddress, q)); assertTrue(query.isExists()); assertEquals(anycastAddress, query.getAddress()); assertEquals(CompositeAddress.toFullQN(anycastAddress, q), query.getName()); - assertEquals(0, query.getMessageCount()); + assertEquals("Message not consumed", 0, query.getMessageCount()); //try query again using qName - query = server.queueQuery(q); - assertEquals(q, query.getName()); + QueueQueryResult qNameQuery = server.queueQuery(q); + assertEquals(q, qNameQuery.getName()); } } finally { connection.close(); @@ -189,14 +175,14 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase { public void testQueueSpecial() throws Exception { server.createQueue(anycastAddress, RoutingType.ANYCAST, anycastQ1, null, true, false, -1, false, true); - Connection connection = factory.createConnection(); + Connection connection = createConnection(); try { connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //::queue ok! String specialName = CompositeAddress.toFullQN(new SimpleString(""), anycastQ1).toString(); - Queue q1 = session.createQueue(specialName); + javax.jms.Queue q1 = session.createQueue(specialName); ClientSessionFactory cf = createSessionFactory(locator); ClientSession coreSession = cf.createSession(); @@ -228,10 +214,8 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase { } catch (InvalidDestinationException e) { //expected } - } finally { connection.close(); } } - } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpInboundConnectionTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpInboundConnectionTest.java index 79bdf590b9..93ceeb3649 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpInboundConnectionTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpInboundConnectionTest.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport; +import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.artemis.utils.VersionLoader; import org.apache.activemq.transport.amqp.client.AmqpClient; @@ -53,7 +54,27 @@ public class AmqpInboundConnectionTest extends AmqpClientTestSupport { private static final String BROKER_NAME = "localhost"; private static final String PRODUCT_NAME = "apache-activemq-artemis"; - @Test + @Test(timeout = 60000) + public void testCloseIsSentOnConnectionClose() throws Exception { + AmqpClient client = createAmqpClient(); + AmqpConnection amqpConnection = client.connect(); + + try { + for (RemotingConnection connection : server.getRemotingService().getConnections()) { + server.getRemotingService().removeConnection(connection); + connection.disconnect(true); + } + + Wait.waitFor(amqpConnection::isClosed); + + assertTrue(amqpConnection.isClosed()); + assertEquals(AmqpSupport.CONNECTION_FORCED, amqpConnection.getConnection().getRemoteCondition().getCondition()); + } finally { + amqpConnection.close(); + } + } + + @Test(timeout = 60000) public void testBrokerContainerId() throws Exception { AmqpClient client = createAmqpClient(); assertNotNull(client); @@ -77,7 +98,7 @@ public class AmqpInboundConnectionTest extends AmqpClientTestSupport { } } - @Test + @Test(timeout = 60000) public void testBrokerConnectionProperties() throws Exception { AmqpClient client = createAmqpClient(); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpManagementTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpManagementTest.java index c84a590595..9b8ddfee13 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpManagementTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpManagementTest.java @@ -31,7 +31,7 @@ import org.junit.Test; public class AmqpManagementTest extends AmqpClientTestSupport { - @Test + @Test(timeout = 60000) public void testManagementQueryOverAMQP() throws Throwable { AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonMaxFrameSizeTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMaxFrameSizeTest.java similarity index 87% rename from tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonMaxFrameSizeTest.java rename to tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMaxFrameSizeTest.java index 851ee2f82d..778cd40de3 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonMaxFrameSizeTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMaxFrameSizeTest.java @@ -16,7 +16,6 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; -import java.net.URI; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -30,29 +29,28 @@ import org.apache.qpid.proton.amqp.messaging.Data; import org.apache.qpid.proton.message.impl.MessageImpl; import org.junit.Test; -public class ProtonMaxFrameSizeTest extends ProtonTestBase { +public class AmqpMaxFrameSizeTest extends AmqpClientTestSupport { private static final int FRAME_SIZE = 512; @Override - protected void configureAmqp(Map params) { + protected void configureAMQPAcceptorParameters(Map params) { params.put("maxFrameSize", FRAME_SIZE); } - @Test + @Test(timeout = 60000) public void testMultipleTransfers() throws Exception { String testQueueName = "ConnectionFrameSize"; int nMsgs = 200; - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - - AmqpConnection amqpConnection = client.createConnection(); + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); try { - amqpConnection.connect(); + connection.connect(); - AmqpSession session = amqpConnection.createSession(); + AmqpSession session = connection.createSession(); AmqpSender sender = session.createSender(testQueueName); final int payload = FRAME_SIZE * 16; @@ -79,7 +77,7 @@ public class ProtonMaxFrameSizeTest extends ProtonTestBase { } } finally { - amqpConnection.close(); + connection.close(); } } @@ -92,5 +90,4 @@ public class ProtonMaxFrameSizeTest extends ProtonTestBase { message.setBytes(payload); return message; } - } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMessageDivertsTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMessageDivertsTest.java new file mode 100644 index 0000000000..f895c86d25 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMessageDivertsTest.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.concurrent.TimeUnit; + +import org.apache.activemq.artemis.api.core.RoutingType; +import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.core.server.DivertConfigurationRoutingType; +import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.transport.amqp.client.AmqpClient; +import org.apache.activemq.transport.amqp.client.AmqpConnection; +import org.apache.activemq.transport.amqp.client.AmqpReceiver; +import org.apache.activemq.transport.amqp.client.AmqpSession; +import org.junit.Test; + +public class AmqpMessageDivertsTest extends AmqpClientTestSupport { + + @Test(timeout = 60000) + public void testQueueReceiverReadMessageWithDivert() throws Exception { + final String forwardingAddress = getQueueName() + "Divert"; + final SimpleString simpleForwardingAddress = SimpleString.toSimpleString(forwardingAddress); + server.createQueue(simpleForwardingAddress, RoutingType.ANYCAST, simpleForwardingAddress, null, true, false); + server.getActiveMQServerControl().createDivert("name", "routingName", getQueueName(), forwardingAddress, true, null, null, DivertConfigurationRoutingType.ANYCAST.toString()); + + sendMessages(getQueueName(), 1); + + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + AmqpReceiver receiver = session.createReceiver(forwardingAddress); + + Queue queueView = getProxyToQueue(forwardingAddress); + assertEquals(1, queueView.getMessageCount()); + + receiver.flow(1); + assertNotNull(receiver.receive(5, TimeUnit.SECONDS)); + receiver.close(); + + assertEquals(1, queueView.getMessageCount()); + + connection.close(); + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMessageRoutingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMessageRoutingTest.java new file mode 100644 index 0000000000..fcce0abc12 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpMessageRoutingTest.java @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import javax.jms.Connection; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.Topic; + +import org.apache.activemq.artemis.api.core.RoutingType; +import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl; +import org.apache.activemq.artemis.core.server.impl.AddressInfo; +import org.apache.activemq.artemis.utils.UUIDGenerator; +import org.junit.Test; + +public class AmqpMessageRoutingTest extends JMSClientTestSupport { + + @Override + protected boolean isAutoCreateQueues() { + return false; + } + + @Override + protected boolean isAutoCreateAddresses() { + return false; + } + + @Test(timeout = 60000) + public void testAnycastMessageRoutingExclusivityUsingPrefix() throws Exception { + final String addressA = "addressA"; + final String queueA = "queueA"; + final String queueB = "queueB"; + final String queueC = "queueC"; + + ActiveMQServerControl serverControl = server.getActiveMQServerControl(); + serverControl.createAddress(addressA, RoutingType.ANYCAST.toString() + "," + RoutingType.MULTICAST.toString()); + serverControl.createQueue(addressA, queueA, RoutingType.ANYCAST.toString()); + serverControl.createQueue(addressA, queueB, RoutingType.ANYCAST.toString()); + serverControl.createQueue(addressA, queueC, RoutingType.MULTICAST.toString()); + + sendMessages("anycast://" + addressA, 1); + + assertEquals(1, server.locateQueue(SimpleString.toSimpleString(queueA)).getMessageCount() + server.locateQueue(SimpleString.toSimpleString(queueB)).getMessageCount()); + assertEquals(0, server.locateQueue(SimpleString.toSimpleString(queueC)).getMessageCount()); + } + + @Test(timeout = 60000) + public void testAnycastMessageRoutingExclusivityUsingProperty() throws Exception { + final String addressA = "addressA"; + final String queueA = "queueA"; + final String queueB = "queueB"; + final String queueC = "queueC"; + + ActiveMQServerControl serverControl = server.getActiveMQServerControl(); + serverControl.createAddress(addressA, RoutingType.ANYCAST.toString() + "," + RoutingType.MULTICAST.toString()); + serverControl.createQueue(addressA, queueA, RoutingType.ANYCAST.toString()); + serverControl.createQueue(addressA, queueB, RoutingType.ANYCAST.toString()); + serverControl.createQueue(addressA, queueC, RoutingType.MULTICAST.toString()); + + sendMessages(addressA, 1, RoutingType.ANYCAST); + + assertEquals(1, server.locateQueue(SimpleString.toSimpleString(queueA)).getMessageCount() + server.locateQueue(SimpleString.toSimpleString(queueB)).getMessageCount()); + assertEquals(0, server.locateQueue(SimpleString.toSimpleString(queueC)).getMessageCount()); + } + + @Test(timeout = 60000) + public void testMulticastMessageRoutingExclusivityUsingPrefix() throws Exception { + final String addressA = "addressA"; + final String queueA = "queueA"; + final String queueB = "queueB"; + final String queueC = "queueC"; + + ActiveMQServerControl serverControl = server.getActiveMQServerControl(); + serverControl.createAddress(addressA, RoutingType.ANYCAST.toString() + "," + RoutingType.MULTICAST.toString()); + serverControl.createQueue(addressA, queueA, RoutingType.ANYCAST.toString()); + serverControl.createQueue(addressA, queueB, RoutingType.MULTICAST.toString()); + serverControl.createQueue(addressA, queueC, RoutingType.MULTICAST.toString()); + + sendMessages("multicast://" + addressA, 1); + + assertEquals(0, server.locateQueue(SimpleString.toSimpleString(queueA)).getMessageCount()); + assertEquals(2, server.locateQueue(SimpleString.toSimpleString(queueC)).getMessageCount() + server.locateQueue(SimpleString.toSimpleString(queueB)).getMessageCount()); + } + + @Test(timeout = 60000) + public void testMulticastMessageRoutingExclusivityUsingProperty() throws Exception { + final String addressA = "addressA"; + final String queueA = "queueA"; + final String queueB = "queueB"; + final String queueC = "queueC"; + + ActiveMQServerControl serverControl = server.getActiveMQServerControl(); + serverControl.createAddress(addressA, RoutingType.ANYCAST.toString() + "," + RoutingType.MULTICAST.toString()); + serverControl.createQueue(addressA, queueA, RoutingType.ANYCAST.toString()); + serverControl.createQueue(addressA, queueB, RoutingType.MULTICAST.toString()); + serverControl.createQueue(addressA, queueC, RoutingType.MULTICAST.toString()); + + sendMessages(addressA, 1, RoutingType.MULTICAST); + + assertEquals(0, server.locateQueue(SimpleString.toSimpleString(queueA)).getMessageCount()); + assertEquals(2, server.locateQueue(SimpleString.toSimpleString(queueC)).getMessageCount() + server.locateQueue(SimpleString.toSimpleString(queueB)).getMessageCount()); + } + + /** + * If we have an address configured with both ANYCAST and MULTICAST routing types enabled, we must ensure that any + * messages sent specifically to MULTICAST (e.g. JMS TopicProducer) are only delivered to MULTICAST queues (e.g. + * i.e. subscription queues) and **NOT** to ANYCAST queues (e.g. JMS Queue). + * + * @throws Exception + */ + @Test(timeout = 60000) + public void testRoutingExclusivity() throws Exception { + + // Create Address with both ANYCAST and MULTICAST enabled + String testAddress = "testRoutingExclusivity-mixed-mode"; + SimpleString ssTestAddress = new SimpleString(testAddress); + + AddressInfo addressInfo = new AddressInfo(ssTestAddress); + addressInfo.addRoutingType(RoutingType.MULTICAST); + addressInfo.addRoutingType(RoutingType.ANYCAST); + + server.addAddressInfo(addressInfo); + server.createQueue(ssTestAddress, RoutingType.ANYCAST, ssTestAddress, null, true, false); + + Connection connection = createConnection(UUIDGenerator.getInstance().generateStringUUID()); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Topic topic = session.createTopic(testAddress); + javax.jms.Queue queue = session.createQueue(testAddress); + + MessageProducer producer = session.createProducer(topic); + + MessageConsumer queueConsumer = session.createConsumer(queue); + MessageConsumer topicConsumer = session.createConsumer(topic); + + producer.send(session.createTextMessage("testMessage")); + + assertNotNull(topicConsumer.receive(1000)); + assertNull(queueConsumer.receive(1000)); + } finally { + connection.close(); + } + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpOutboundConnectionTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpOutboundConnectionTest.java new file mode 100644 index 0000000000..3d8be493a0 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpOutboundConnectionTest.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; + +import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector; +import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants; +import org.apache.activemq.artemis.core.server.ActiveMQServer; +import org.apache.activemq.artemis.protocol.amqp.broker.ProtonProtocolManagerFactory; +import org.apache.activemq.artemis.protocol.amqp.client.AMQPClientConnectionFactory; +import org.apache.activemq.artemis.protocol.amqp.client.ProtonClientConnectionManager; +import org.apache.activemq.artemis.protocol.amqp.client.ProtonClientProtocolManager; +import org.apache.activemq.artemis.tests.util.Wait; +import org.apache.qpid.proton.amqp.Symbol; +import org.junit.Test; + +public class AmqpOutboundConnectionTest extends AmqpClientTestSupport { + + @Test(timeout = 60000) + public void testOutboundConnection() throws Throwable { + final ActiveMQServer remote = createServer(AMQP_PORT + 1); + remote.start(); + try { + Wait.waitFor(remote::isActive); + } catch (Exception e) { + remote.stop(); + throw e; + } + + final Map config = new LinkedHashMap<>(); + config.put(TransportConstants.HOST_PROP_NAME, "localhost"); + config.put(TransportConstants.PORT_PROP_NAME, String.valueOf(AMQP_PORT + 1)); + ProtonClientConnectionManager lifeCycleListener = new ProtonClientConnectionManager(new AMQPClientConnectionFactory(server, "myid", Collections.singletonMap(Symbol.getSymbol("myprop"), "propvalue"), 5000), Optional.empty()); + ProtonClientProtocolManager protocolManager = new ProtonClientProtocolManager(new ProtonProtocolManagerFactory(), server); + NettyConnector connector = new NettyConnector(config, lifeCycleListener, lifeCycleListener, server.getExecutorFactory().getExecutor(), server.getExecutorFactory().getExecutor(), server.getScheduledPool(), protocolManager); + connector.start(); + connector.createConnection(); + + try { + Wait.waitFor(() -> remote.getConnectionCount() > 0); + assertEquals(1, remote.getConnectionCount()); + + lifeCycleListener.stop(); + + Wait.waitFor(() -> remote.getConnectionCount() == 0); + assertEquals(0, remote.getConnectionCount()); + } finally { + lifeCycleListener.stop(); + remote.stop(); + } + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpPresettledReceiverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpPresettledReceiverTest.java index 422e23e236..3fd21b1649 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpPresettledReceiverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpPresettledReceiverTest.java @@ -19,6 +19,7 @@ package org.apache.activemq.artemis.tests.integration.amqp; import java.util.concurrent.TimeUnit; import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; @@ -192,7 +193,7 @@ public class AmqpPresettledReceiverTest extends AmqpClientTestSupport { message.setText("Test-Message"); sender.send(message); - assertEquals(1, queue.getMessageCount()); + assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1)); AmqpReceiver receiver = session.createReceiver(getQueueName(), null, false, true); @@ -228,7 +229,7 @@ public class AmqpPresettledReceiverTest extends AmqpClientTestSupport { message.setText("Test-Message"); sender.send(message); - assertEquals(1, queue.getMessageCount()); + assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1)); AmqpReceiver receiver = session.createReceiver(getQueueName(), null, false, true); @@ -250,21 +251,4 @@ public class AmqpPresettledReceiverTest extends AmqpClientTestSupport { sender.close(); connection.close(); } - - public void sendMessages(String destinationName, int count) throws Exception { - AmqpClient client = createAmqpClient(); - AmqpConnection connection = addConnection(client.connect()); - try { - AmqpSession session = connection.createSession(); - AmqpSender sender = session.createSender(destinationName); - - for (int i = 0; i < count; ++i) { - AmqpMessage message = new AmqpMessage(); - message.setMessageId("MessageID:" + i); - sender.send(message); - } - } finally { - connection.close(); - } - } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestForHeader.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpProtocolHeaderHandlingTest.java similarity index 77% rename from tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestForHeader.java rename to tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpProtocolHeaderHandlingTest.java index dffc12eff9..e16fd46667 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestForHeader.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpProtocolHeaderHandlingTest.java @@ -20,54 +20,22 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; -import java.util.HashMap; import java.util.concurrent.TimeUnit; -import org.apache.activemq.artemis.api.core.TransportConfiguration; -import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants; -import org.apache.activemq.artemis.core.server.ActiveMQServer; -import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager; import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; -import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.apache.activemq.artemis.tests.util.Wait; import org.fusesource.hawtbuf.Buffer; -import org.junit.After; -import org.junit.Before; import org.junit.Test; -public class ProtonTestForHeader extends ActiveMQTestBase { - - private ActiveMQServer server; +public class AmqpProtocolHeaderHandlingTest extends AmqpClientTestSupport { @Override - @Before - public void setUp() throws Exception { - super.setUp(); - server = this.createServer(true, true); - HashMap params = new HashMap<>(); - params.put(TransportConstants.PORT_PROP_NAME, "5672"); - params.put(TransportConstants.PROTOCOLS_PROP_NAME, "AMQP"); - TransportConfiguration transportConfiguration = new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params); - - server.getConfiguration().getAcceptorConfigurations().add(transportConfiguration); - server.getConfiguration().setSecurityEnabled(true); - server.start(); - ActiveMQJAASSecurityManager securityManager = (ActiveMQJAASSecurityManager) server.getSecurityManager(); - securityManager.getConfiguration().addUser("auser", "pass"); + protected boolean isSecurityEnabled() { + return true; } - @Override - @After - public void tearDown() throws Exception { - try { - server.stop(); - } finally { - super.tearDown(); - } - } - - @Test - public void testSimpleBytes() throws Exception { + @Test(timeout = 60000) + public void testNonSaslHeaderRejectedOnConnect() throws Exception { final AmqpHeader header = new AmqpHeader(); header.setProtocolId(0); @@ -76,13 +44,15 @@ public class ProtonTestForHeader extends ActiveMQTestBase { header.setRevision(0); final ClientConnection connection = new ClientConnection(); - connection.open("localhost", 5672); + connection.open("localhost", AMQP_PORT); connection.send(header); AmqpHeader response = connection.readAmqpHeader(); assertNotNull(response); + assertEquals(3, response.getProtocolId()); IntegrationTestLogger.LOGGER.info("Broker responded with: " + response); + // pump some bytes down the wire until broker closes the connection assertTrue("Broker should have closed client connection", Wait.waitFor(new Wait.Condition() { @Override @@ -128,6 +98,7 @@ public class ProtonTestForHeader extends ActiveMQTestBase { } } + @SuppressWarnings("unused") private class AmqpHeader { final Buffer PREFIX = new Buffer(new byte[]{'A', 'M', 'Q', 'P'}); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverDispositionTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverDispositionTest.java index 9cd8f50f96..e636d83695 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverDispositionTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverDispositionTest.java @@ -22,7 +22,6 @@ import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpReceiver; -import org.apache.activemq.transport.amqp.client.AmqpSender; import org.apache.activemq.transport.amqp.client.AmqpSession; import org.apache.qpid.proton.message.Message; import org.junit.Test; @@ -57,7 +56,6 @@ public class AmqpReceiverDispositionTest extends AmqpClientTestSupport { receiver2.flow(1); message.release(); - // Read the message again and validate its state message = receiver2.receive(10, TimeUnit.SECONDS); assertNotNull("did not receive message again", message); @@ -172,21 +170,4 @@ public class AmqpReceiverDispositionTest extends AmqpClientTestSupport { connection.close(); } - - public void sendMessages(String destinationName, int count) throws Exception { - AmqpClient client = createAmqpClient(); - AmqpConnection connection = addConnection(client.connect()); - try { - AmqpSession session = connection.createSession(); - AmqpSender sender = session.createSender(destinationName); - - for (int i = 0; i < count; ++i) { - AmqpMessage message = new AmqpMessage(); - message.setMessageId("MessageID:" + i); - sender.send(message); - } - } finally { - connection.close(); - } - } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverDrainTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverDrainTest.java index 681ffbdf4b..edf9459126 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverDrainTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverDrainTest.java @@ -19,11 +19,11 @@ package org.apache.activemq.artemis.tests.integration.amqp; import java.util.concurrent.TimeUnit; import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpReceiver; -import org.apache.activemq.transport.amqp.client.AmqpSender; import org.apache.activemq.transport.amqp.client.AmqpSession; import org.junit.Test; @@ -33,46 +33,81 @@ import org.junit.Test; public class AmqpReceiverDrainTest extends AmqpClientTestSupport { @Test(timeout = 60000) - public void testReceiverCanDrainMessages() throws Exception { + public void testReceiverCanDrainMessagesQueue() throws Exception { + doTestReceiverCanDrainMessages(false); + } + + @Test(timeout = 60000) + public void testReceiverCanDrainMessagesTopic() throws Exception { + doTestReceiverCanDrainMessages(true); + } + + private void doTestReceiverCanDrainMessages(boolean topic) throws Exception { + final String destinationName; + if (topic) { + destinationName = getTopicName(); + } else { + destinationName = getQueueName(); + } + int MSG_COUNT = 20; - sendMessages(getQueueName(), MSG_COUNT); AmqpClient client = createAmqpClient(); - AmqpConnection connection = client.connect(); + AmqpConnection connection = addConnection(client.connect()); AmqpSession session = connection.createSession(); - AmqpReceiver receiver = session.createReceiver(getQueueName()); + AmqpReceiver receiver = session.createReceiver(destinationName); + + sendMessages(destinationName, MSG_COUNT); + + Queue queueView = getProxyToQueue(destinationName); - Queue queueView = getProxyToQueue(getQueueName()); assertEquals(MSG_COUNT, queueView.getMessageCount()); + assertEquals(0, queueView.getDeliveringCount()); receiver.drain(MSG_COUNT); for (int i = 0; i < MSG_COUNT; ++i) { AmqpMessage message = receiver.receive(5, TimeUnit.SECONDS); - assertNotNull(message); + assertNotNull("Failed to read message: " + (i + 1), message); + IntegrationTestLogger.LOGGER.info("Read message: " + message.getMessageId()); message.accept(); } receiver.close(); - assertEquals(0, queueView.getMessageCount()); - connection.close(); } @Test(timeout = 60000) - public void testPullWithNoMessageGetDrained() throws Exception { + public void testPullWithNoMessageGetDrainedQueue() throws Exception { + doTestPullWithNoMessageGetDrained(false); + } + + @Test(timeout = 60000) + public void testPullWithNoMessageGetDrainedTopic() throws Exception { + doTestPullWithNoMessageGetDrained(true); + } + + private void doTestPullWithNoMessageGetDrained(boolean topic) throws Exception { + + final String destinationName; + if (topic) { + destinationName = getTopicName(); + } else { + destinationName = getQueueName(); + } AmqpClient client = createAmqpClient(); - AmqpConnection connection = client.connect(); + AmqpConnection connection = addConnection(client.connect()); AmqpSession session = connection.createSession(); - AmqpReceiver receiver = session.createReceiver(getQueueName()); + AmqpReceiver receiver = session.createReceiver(destinationName); receiver.flow(10); - Queue queueView = getProxyToQueue(getQueueName()); + Queue queueView = getProxyToQueue(destinationName); + assertEquals(0, queueView.getMessageCount()); - assertEquals(0, queueView.getDeliveringCount()); + assertEquals(0, queueView.getMessagesAcknowledged()); assertEquals(10, receiver.getReceiver().getRemoteCredit()); @@ -84,18 +119,36 @@ public class AmqpReceiverDrainTest extends AmqpClientTestSupport { } @Test(timeout = 60000) - public void testPullOneFromRemote() throws Exception { - int MSG_COUNT = 20; - sendMessages(getQueueName(), MSG_COUNT); + public void testPullOneFromRemoteQueue() throws Exception { + doTestPullOneFromRemote(false); + } + + @Test(timeout = 60000) + public void testPullOneFromRemoteTopic() throws Exception { + doTestPullOneFromRemote(true); + } + + private void doTestPullOneFromRemote(boolean topic) throws Exception { AmqpClient client = createAmqpClient(); - AmqpConnection connection = client.connect(); + AmqpConnection connection = addConnection(client.connect()); AmqpSession session = connection.createSession(); - AmqpReceiver receiver = session.createReceiver(getQueueName()); + final String destinationName; + if (topic) { + destinationName = getTopicName(); + } else { + destinationName = getQueueName(); + } - Queue queueView = getProxyToQueue(getQueueName()); + AmqpReceiver receiver = session.createReceiver(destinationName); + + int MSG_COUNT = 20; + sendMessages(destinationName, MSG_COUNT); + + Queue queueView = getProxyToQueue(destinationName); assertEquals(MSG_COUNT, queueView.getMessageCount()); + assertEquals(0, queueView.getDeliveringCount()); assertEquals(0, receiver.getReceiver().getRemoteCredit()); @@ -107,24 +160,39 @@ public class AmqpReceiverDrainTest extends AmqpClientTestSupport { receiver.close(); - assertEquals(MSG_COUNT - 1, queueView.getMessageCount()); - assertEquals(1, queueView.getMessagesAcknowledged()); - connection.close(); } @Test(timeout = 60000) - public void testMultipleZeroResultPulls() throws Exception { + public void testMultipleZeroResultPullsQueue() throws Exception { + doTestMultipleZeroResultPulls(false); + } + + @Test(timeout = 60000) + public void testMultipleZeroResultPullsTopic() throws Exception { + doTestMultipleZeroResultPulls(true); + } + + private void doTestMultipleZeroResultPulls(boolean topic) throws Exception { + AmqpClient client = createAmqpClient(); - AmqpConnection connection = client.connect(); + AmqpConnection connection = addConnection(client.connect()); AmqpSession session = connection.createSession(); - AmqpReceiver receiver = session.createReceiver(getQueueName()); + final String destinationName; + if (topic) { + destinationName = getTopicName(); + } else { + destinationName = getQueueName(); + } + + AmqpReceiver receiver = session.createReceiver(destinationName); receiver.flow(10); - Queue queueView = getProxyToQueue(getQueueName()); + Queue queueView = getProxyToQueue(destinationName); assertEquals(0, queueView.getMessageCount()); + assertEquals(0, queueView.getDeliveringCount()); assertEquals(10, receiver.getReceiver().getRemoteCredit()); @@ -139,27 +207,4 @@ public class AmqpReceiverDrainTest extends AmqpClientTestSupport { connection.close(); } - - public void sendMessages(String destinationName, int count) throws Exception { - AmqpClient client = createAmqpClient(); - AmqpConnection connection = null; - - try { - connection = client.connect(); - AmqpSession session = connection.createSession(); - AmqpSender sender = session.createSender(destinationName); - - for (int i = 0; i < count; ++i) { - AmqpMessage message = new AmqpMessage(); - message.setText("Test-Message-" + i); - sender.send(message); - } - - sender.close(); - } finally { - if (connection != null) { - connection.close(); - } - } - } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverTest.java index b47ad505eb..3aff0300cb 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpReceiverTest.java @@ -16,13 +16,38 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; +import static org.apache.activemq.transport.amqp.AmqpSupport.JMS_SELECTOR_FILTER_IDS; +import static org.apache.activemq.transport.amqp.AmqpSupport.NO_LOCAL_FILTER_IDS; +import static org.apache.activemq.transport.amqp.AmqpSupport.findFilter; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.jms.JMSException; + +import org.apache.activemq.artemis.api.core.RoutingType; +import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.core.server.impl.AddressInfo; +import org.apache.activemq.artemis.core.settings.impl.AddressSettings; +import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; +import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpReceiver; import org.apache.activemq.transport.amqp.client.AmqpSession; +import org.apache.activemq.transport.amqp.client.AmqpUnknownFilterType; +import org.apache.activemq.transport.amqp.client.AmqpValidator; +import org.apache.qpid.proton.amqp.DescribedType; +import org.apache.qpid.proton.amqp.Symbol; +import org.apache.qpid.proton.amqp.messaging.Source; +import org.apache.qpid.proton.amqp.messaging.TerminusDurability; +import org.apache.qpid.proton.amqp.messaging.TerminusExpiryPolicy; import org.apache.qpid.proton.amqp.transport.ReceiverSettleMode; import org.apache.qpid.proton.amqp.transport.SenderSettleMode; +import org.apache.qpid.proton.engine.Receiver; +import org.apache.qpid.proton.engine.Session; import org.junit.Test; /** @@ -30,6 +55,119 @@ import org.junit.Test; */ public class AmqpReceiverTest extends AmqpClientTestSupport { + @Test(timeout = 60000) + public void testCreateQueueReceiver() throws Exception { + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + AmqpReceiver receiver = session.createReceiver(getQueueName()); + + Queue queue = getProxyToQueue(getQueueName()); + assertNotNull(queue); + + receiver.close(); + connection.close(); + } + + @Test(timeout = 60000) + public void testCreateTopicReceiver() throws Exception { + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + AmqpReceiver receiver = session.createReceiver(getTopicName()); + + Queue queue = getProxyToQueue(getQueueName()); + assertNotNull(queue); + + receiver.close(); + + connection.close(); + } + + @Test(timeout = 60000) + public void testCreateQueueReceiverWithNoLocalSet() throws Exception { + AmqpClient client = createAmqpClient(); + + client.setValidator(new AmqpValidator() { + + @SuppressWarnings("unchecked") + @Override + public void inspectOpenedResource(Receiver receiver) { + + if (receiver.getRemoteSource() == null) { + markAsInvalid("Link opened with null source."); + } + + Source source = (Source) receiver.getRemoteSource(); + Map filters = source.getFilter(); + + // Currently don't support noLocal on a Queue + if (findFilter(filters, NO_LOCAL_FILTER_IDS) != null) { + markAsInvalid("Broker did not return the NoLocal Filter on Attach"); + } + } + }); + + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + session.createReceiver(getQueueName(), null, true); + + connection.getStateInspector().assertValid(); + connection.close(); + } + + @Test(timeout = 60000) + public void testCreateQueueReceiverWithJMSSelector() throws Exception { + AmqpClient client = createAmqpClient(); + + client.setValidator(new AmqpValidator() { + + @SuppressWarnings("unchecked") + @Override + public void inspectOpenedResource(Receiver receiver) { + + if (receiver.getRemoteSource() == null) { + markAsInvalid("Link opened with null source."); + } + + Source source = (Source) receiver.getRemoteSource(); + Map filters = source.getFilter(); + + if (findFilter(filters, JMS_SELECTOR_FILTER_IDS) == null) { + markAsInvalid("Broker did not return the JMS Filter on Attach"); + } + } + }); + + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + session.createReceiver(getQueueName(), "JMSPriority > 8"); + + connection.getStateInspector().assertValid(); + connection.close(); + } + + @Test(timeout = 60000) + public void testInvalidFilter() throws Exception { + AmqpClient client = createAmqpClient(); + + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + try { + session.createReceiver(getQueueName(), "null = 'f''", true); + fail("should throw exception"); + } catch (Exception e) { + assertTrue(e.getCause() instanceof JMSException); + } + + connection.close(); + } + @Test(timeout = 60000) public void testSenderSettlementModeSettledIsHonored() throws Exception { doTestSenderSettlementModeIsHonored(SenderSettleMode.SETTLED); @@ -96,4 +234,164 @@ public class AmqpReceiverTest extends AmqpClientTestSupport { receiver.close(); connection.close(); } + + @Test(timeout = 60000) + public void testClientIdIsSetInSubscriptionList() throws Exception { + server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString("mytopic"), RoutingType.ANYCAST)); + + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + connection.setContainerId("testClient"); + connection.connect(); + + try { + AmqpSession session = connection.createSession(); + + Source source = new Source(); + source.setDurable(TerminusDurability.UNSETTLED_STATE); + source.setCapabilities(Symbol.getSymbol("topic")); + source.setAddress("mytopic"); + session.createReceiver(source, "testSub"); + + SimpleString fo = new SimpleString("testClient.testSub:mytopic"); + assertNotNull(server.locateQueue(fo)); + + } catch (Exception e) { + e.printStackTrace(); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testLinkDetachSentWhenQueueDeleted() throws Exception { + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + + try { + AmqpSession session = connection.createSession(); + AmqpReceiver receiver = session.createReceiver(getQueueName()); + + server.destroyQueue(new SimpleString(getQueueName()), null, false, true); + + assertTrue("Receiver should have closed", Wait.waitFor(receiver::isClosed)); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testLinkDetatchErrorIsCorrectWhenQueueDoesNotExists() throws Exception { + AddressSettings value = new AddressSettings(); + value.setAutoCreateQueues(false); + value.setAutoCreateAddresses(false); + server.getAddressSettingsRepository().addMatch("AnAddressThatDoesNotExist", value); + + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + + try { + AmqpSession session = connection.createSession(); + + Exception expectedException = null; + try { + session.createSender("AnAddressThatDoesNotExist"); + fail("Creating a sender here on an address that doesn't exist should fail"); + } catch (Exception e) { + expectedException = e; + } + + assertNotNull(expectedException); + assertTrue(expectedException.getMessage().contains("amqp:not-found")); + assertTrue(expectedException.getMessage().contains("target address does not exist")); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testUnsupportedFiltersAreNotListedAsSupported() throws Exception { + AmqpClient client = createAmqpClient(); + + client.setValidator(new AmqpValidator() { + + @SuppressWarnings("unchecked") + @Override + public void inspectOpenedResource(Receiver receiver) { + + if (receiver.getRemoteSource() == null) { + markAsInvalid("Link opened with null source."); + } + + Source source = (Source) receiver.getRemoteSource(); + Map filters = source.getFilter(); + + if (findFilter(filters, AmqpUnknownFilterType.UNKNOWN_FILTER_IDS) != null) { + markAsInvalid("Broker should not return unsupported filter on attach."); + } + } + }); + + Map filters = new HashMap<>(); + filters.put(AmqpUnknownFilterType.UNKNOWN_FILTER_NAME, AmqpUnknownFilterType.UNKNOWN_FILTER); + + Source source = new Source(); + source.setAddress(getQueueName()); + source.setFilter(filters); + source.setDurable(TerminusDurability.NONE); + source.setExpiryPolicy(TerminusExpiryPolicy.LINK_DETACH); + + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + assertEquals(0, server.getTotalConsumerCount()); + + session.createReceiver(source); + + assertEquals(1, server.getTotalConsumerCount()); + + connection.getStateInspector().assertValid(); + connection.close(); + } + + @Test(timeout = 60000) + public void testReceiverCloseSendsRemoteClose() throws Exception { + AmqpClient client = createAmqpClient(); + assertNotNull(client); + + final AtomicBoolean closed = new AtomicBoolean(); + + client.setValidator(new AmqpValidator() { + + @Override + public void inspectClosedResource(Session session) { + IntegrationTestLogger.LOGGER.info("Session closed: " + session.getContext()); + } + + @Override + public void inspectDetachedResource(Receiver receiver) { + markAsInvalid("Broker should not detach receiver linked to closed session."); + } + + @Override + public void inspectClosedResource(Receiver receiver) { + IntegrationTestLogger.LOGGER.info("Receiver closed: " + receiver.getContext()); + closed.set(true); + } + }); + + AmqpConnection connection = addConnection(client.connect()); + assertNotNull(connection); + AmqpSession session = connection.createSession(); + assertNotNull(session); + AmqpReceiver receiver = session.createReceiver(getQueueName()); + assertNotNull(receiver); + + receiver.close(); + + assertTrue("Did not process remote close as expected", closed.get()); + connection.getStateInspector().assertValid(); + + connection.close(); + } } \ No newline at end of file diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpScheduledMessageTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpScheduledMessageTest.java index 748f10afa1..6459e76a2a 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpScheduledMessageTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpScheduledMessageTest.java @@ -104,7 +104,7 @@ public class AmqpScheduledMessageTest extends AmqpClientTestSupport { } } - @Test + @Test(timeout = 60000) public void testScheduleWithDelay() throws Exception { AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSecurityTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSecurityTest.java index 8e41d71cc7..f99fc14af5 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSecurityTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSecurityTest.java @@ -17,21 +17,9 @@ package org.apache.activemq.artemis.tests.integration.amqp; import java.io.IOException; -import java.util.HashSet; -import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.apache.activemq.artemis.api.core.RoutingType; -import org.apache.activemq.artemis.api.core.SimpleString; -import org.apache.activemq.artemis.core.config.Configuration; -import org.apache.activemq.artemis.core.security.Role; -import org.apache.activemq.artemis.core.server.ActiveMQServer; -import org.apache.activemq.artemis.core.server.impl.AddressInfo; -import org.apache.activemq.artemis.core.settings.HierarchicalRepository; -import org.apache.activemq.artemis.core.settings.impl.AddressSettings; -import org.apache.activemq.artemis.jms.server.impl.JMSServerManagerImpl; -import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; @@ -39,44 +27,26 @@ import org.apache.activemq.transport.amqp.client.AmqpSender; import org.apache.activemq.transport.amqp.client.AmqpSession; import org.apache.activemq.transport.amqp.client.AmqpValidator; import org.apache.qpid.proton.engine.Delivery; +import org.apache.qpid.proton.engine.Sender; import org.junit.Test; public class AmqpSecurityTest extends AmqpClientTestSupport { - private String user1 = "user1"; - private String password1 = "password1"; - @Override - protected ActiveMQServer createServer() throws Exception { - ActiveMQServer server = createServer(true, true); - ActiveMQJAASSecurityManager securityManager = (ActiveMQJAASSecurityManager) server.getSecurityManager(); - securityManager.getConfiguration().addUser("foo", "bar"); - securityManager.getConfiguration().addRole("foo", "none"); - securityManager.getConfiguration().addUser(user1, password1); - securityManager.getConfiguration().addRole(user1, "none"); - HierarchicalRepository> securityRepository = server.getSecurityRepository(); - HashSet value = new HashSet<>(); - value.add(new Role("none", false, true, true, true, true, true, true, true)); - securityRepository.addMatch(getQueueName(), value); - - serverManager = new JMSServerManagerImpl(server); - Configuration serverConfig = server.getConfiguration(); - serverConfig.getAddressesSettings().put("jms.queue.#", new AddressSettings().setAutoCreateJmsQueues(true).setDeadLetterAddress(new SimpleString("jms.queue.ActiveMQ.DLQ"))); - serverConfig.setSecurityEnabled(true); - serverManager.start(); - server.start(); - return server; + protected boolean isSecurityEnabled() { + return true; } @Test(timeout = 60000) public void testSaslAuthWithInvalidCredentials() throws Exception { AmqpConnection connection = null; - AmqpClient client = createAmqpClient("foo", "foo"); + AmqpClient client = createAmqpClient(fullUser, guestUser); try { connection = client.connect(); - fail("Should authenticate even with authzid set"); + fail("Should not authenticate when invalid credentials provided"); } catch (Exception ex) { + // Expected } finally { if (connection != null) { connection.close(); @@ -87,8 +57,8 @@ public class AmqpSecurityTest extends AmqpClientTestSupport { @Test(timeout = 60000) public void testSaslAuthWithAuthzid() throws Exception { AmqpConnection connection = null; - AmqpClient client = createAmqpClient("foo", "bar"); - client.setAuthzid("foo"); + AmqpClient client = createAmqpClient(guestUser, guestPass); + client.setAuthzid(guestUser); try { connection = client.connect(); @@ -104,7 +74,7 @@ public class AmqpSecurityTest extends AmqpClientTestSupport { @Test(timeout = 60000) public void testSaslAuthWithoutAuthzid() throws Exception { AmqpConnection connection = null; - AmqpClient client = createAmqpClient("foo", "bar"); + AmqpClient client = createAmqpClient(guestUser, guestPass); try { connection = client.connect(); @@ -119,20 +89,22 @@ public class AmqpSecurityTest extends AmqpClientTestSupport { @Test(timeout = 60000) public void testSendAndRejected() throws Exception { - AmqpConnection connection = null; - AmqpClient client = createAmqpClient("foo", "bar"); CountDownLatch latch = new CountDownLatch(1); + + AmqpClient client = createAmqpClient(guestUser, guestPass); client.setValidator(new AmqpValidator() { + @Override - public void inspectDeliveryUpdate(Delivery delivery) { - super.inspectDeliveryUpdate(delivery); + public void inspectDeliveryUpdate(Sender sender, Delivery delivery) { if (!delivery.remotelySettled()) { markAsInvalid("delivery is not remotely settled"); } + latch.countDown(); } }); - connection = addConnection(client.connect()); + + AmqpConnection connection = addConnection(client.connect()); AmqpSession session = connection.createSession(); AmqpSender sender = session.createSender(getQueueName()); @@ -145,8 +117,8 @@ public class AmqpSecurityTest extends AmqpClientTestSupport { try { sender.send(message); } catch (IOException e) { - // } + assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); connection.getStateInspector().assertValid(); connection.close(); @@ -154,11 +126,9 @@ public class AmqpSecurityTest extends AmqpClientTestSupport { @Test(timeout = 60000) public void testSendMessageFailsOnAnonymousRelayWhenNotAuthorizedToSendToAddress() throws Exception { - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(getQueueName()), RoutingType.ANYCAST)); - server.createQueue(new SimpleString(getQueueName()), RoutingType.ANYCAST, new SimpleString(getQueueName()), null, true, false); - - AmqpClient client = createAmqpClient(user1, password1); + AmqpClient client = createAmqpClient(guestUser, guestPass); AmqpConnection connection = client.connect(); + try { AmqpSession session = connection.createSession(); @@ -181,5 +151,4 @@ public class AmqpSecurityTest extends AmqpClientTestSupport { connection.close(); } } - } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSendReceiveTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSendReceiveTest.java index 9cf256a679..0cae79ffde 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSendReceiveTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSendReceiveTest.java @@ -16,28 +16,23 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; -import static org.apache.activemq.transport.amqp.AmqpSupport.JMS_SELECTOR_FILTER_IDS; -import static org.apache.activemq.transport.amqp.AmqpSupport.NO_LOCAL_FILTER_IDS; import static org.apache.activemq.transport.amqp.AmqpSupport.contains; -import static org.apache.activemq.transport.amqp.AmqpSupport.findFilter; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; -import javax.jms.JMSException; +import javax.jms.Topic; import org.apache.activemq.artemis.api.core.RoutingType; import org.apache.activemq.artemis.api.core.SimpleString; -import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl; -import org.apache.activemq.artemis.core.server.DivertConfigurationRoutingType; import org.apache.activemq.artemis.core.server.Queue; -import org.apache.activemq.artemis.protocol.amqp.converter.AMQPMessageSupport; +import org.apache.activemq.artemis.core.server.impl.AddressInfo; import org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport; import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.transport.amqp.client.AmqpClient; @@ -48,8 +43,6 @@ import org.apache.activemq.transport.amqp.client.AmqpSender; import org.apache.activemq.transport.amqp.client.AmqpSession; import org.apache.activemq.transport.amqp.client.AmqpValidator; import org.apache.qpid.proton.amqp.Symbol; -import org.apache.qpid.proton.amqp.messaging.Source; -import org.apache.qpid.proton.engine.Receiver; import org.apache.qpid.proton.engine.Sender; import org.jgroups.util.UUID; import org.junit.Test; @@ -63,19 +56,14 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport { protected static final Logger LOG = LoggerFactory.getLogger(AmqpSendReceiveTest.class); - @Test(timeout = 60000) - public void testCreateQueueReceiver() throws Exception { - AmqpClient client = createAmqpClient(); - AmqpConnection connection = addConnection(client.connect()); - AmqpSession session = connection.createSession(); + @Override + protected boolean isAutoCreateQueues() { + return false; + } - AmqpReceiver receiver = session.createReceiver(getQueueName()); - - Queue queue = getProxyToQueue(getQueueName()); - assertNotNull(queue); - - receiver.close(); - connection.close(); + @Override + protected boolean isAutoCreateAddresses() { + return false; } @Test(timeout = 60000) @@ -103,90 +91,6 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport { assertEquals(0, queue.getMessageCount()); } - - @Test(timeout = 60000) - public void testCreateQueueReceiverWithJMSSelector() throws Exception { - AmqpClient client = createAmqpClient(); - - client.setValidator(new AmqpValidator() { - - @SuppressWarnings("unchecked") - @Override - public void inspectOpenedResource(Receiver receiver) { - - if (receiver.getRemoteSource() == null) { - markAsInvalid("Link opened with null source."); - } - - Source source = (Source) receiver.getRemoteSource(); - Map filters = source.getFilter(); - - if (findFilter(filters, JMS_SELECTOR_FILTER_IDS) == null) { - markAsInvalid("Broker did not return the JMS Filter on Attach"); - } - } - }); - - AmqpConnection connection = addConnection(client.connect()); - AmqpSession session = connection.createSession(); - - session.createReceiver(getQueueName(), "JMSPriority > 8"); - - connection.getStateInspector().assertValid(); - connection.close(); - } - - @Test(timeout = 60000) - public void testCreateQueueReceiverWithNoLocalSet() throws Exception { - AmqpClient client = createAmqpClient(); - - client.setValidator(new AmqpValidator() { - - @SuppressWarnings("unchecked") - @Override - public void inspectOpenedResource(Receiver receiver) { - - if (receiver.getRemoteSource() == null) { - markAsInvalid("Link opened with null source."); - } - - Source source = (Source) receiver.getRemoteSource(); - Map filters = source.getFilter(); - - // Currently don't support noLocal on a Queue - if (findFilter(filters, NO_LOCAL_FILTER_IDS) != null) { - markAsInvalid("Broker did not return the NoLocal Filter on Attach"); - } - } - }); - - AmqpConnection connection = addConnection(client.connect()); - AmqpSession session = connection.createSession(); - - session.createReceiver(getQueueName(), null, true); - - connection.getStateInspector().assertValid(); - connection.close(); - } - - @Test(timeout = 60000) - public void testInvalidFilter() throws Exception { - AmqpClient client = createAmqpClient(); - - AmqpConnection connection = addConnection(client.connect()); - AmqpSession session = connection.createSession(); - - try { - session.createReceiver(getQueueName(), "null = 'f''", true); - fail("should throw exception"); - } catch (Exception e) { - assertTrue(e.getCause() instanceof JMSException); - //passed - } - - connection.close(); - } - @Test(timeout = 60000) public void testQueueReceiverReadMessage() throws Exception { sendMessages(getQueueName(), 1); @@ -209,108 +113,6 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport { connection.close(); } - @Test(timeout = 60000) - public void testQueueReceiverReadMessageWithDivert() throws Exception { - final String forwardingAddress = getQueueName() + "Divert"; - final SimpleString simpleForwardingAddress = SimpleString.toSimpleString(forwardingAddress); - server.createQueue(simpleForwardingAddress, RoutingType.ANYCAST, simpleForwardingAddress, null, true, false); - server.getActiveMQServerControl().createDivert("name", "routingName", getQueueName(), forwardingAddress, true, null, null, DivertConfigurationRoutingType.ANYCAST.toString()); - sendMessages(getQueueName(), 1); - - AmqpClient client = createAmqpClient(); - AmqpConnection connection = addConnection(client.connect()); - AmqpSession session = connection.createSession(); - - AmqpReceiver receiver = session.createReceiver(forwardingAddress); - - Queue queueView = getProxyToQueue(forwardingAddress); - assertEquals(1, queueView.getMessageCount()); - - receiver.flow(1); - assertNotNull(receiver.receive(5, TimeUnit.SECONDS)); - receiver.close(); - - assertEquals(1, queueView.getMessageCount()); - - connection.close(); - } - - @Test(timeout = 60000) - public void testAnycastMessageRoutingExclusivityUsingPrefix() throws Exception { - final String addressA = "addressA"; - final String queueA = "queueA"; - final String queueB = "queueB"; - final String queueC = "queueC"; - - ActiveMQServerControl serverControl = server.getActiveMQServerControl(); - serverControl.createAddress(addressA, RoutingType.ANYCAST.toString() + "," + RoutingType.MULTICAST.toString()); - serverControl.createQueue(addressA, queueA, RoutingType.ANYCAST.toString()); - serverControl.createQueue(addressA, queueB, RoutingType.ANYCAST.toString()); - serverControl.createQueue(addressA, queueC, RoutingType.MULTICAST.toString()); - - sendMessages("anycast://" + addressA, 1); - - assertEquals(1, server.locateQueue(SimpleString.toSimpleString(queueA)).getMessageCount() + server.locateQueue(SimpleString.toSimpleString(queueB)).getMessageCount()); - assertEquals(0, server.locateQueue(SimpleString.toSimpleString(queueC)).getMessageCount()); - } - - @Test(timeout = 60000) - public void testAnycastMessageRoutingExclusivityUsingProperty() throws Exception { - final String addressA = "addressA"; - final String queueA = "queueA"; - final String queueB = "queueB"; - final String queueC = "queueC"; - - ActiveMQServerControl serverControl = server.getActiveMQServerControl(); - serverControl.createAddress(addressA, RoutingType.ANYCAST.toString() + "," + RoutingType.MULTICAST.toString()); - serverControl.createQueue(addressA, queueA, RoutingType.ANYCAST.toString()); - serverControl.createQueue(addressA, queueB, RoutingType.ANYCAST.toString()); - serverControl.createQueue(addressA, queueC, RoutingType.MULTICAST.toString()); - - sendMessages(addressA, 1, RoutingType.ANYCAST); - - assertEquals(1, server.locateQueue(SimpleString.toSimpleString(queueA)).getMessageCount() + server.locateQueue(SimpleString.toSimpleString(queueB)).getMessageCount()); - assertEquals(0, server.locateQueue(SimpleString.toSimpleString(queueC)).getMessageCount()); - } - - @Test - public void testMulticastMessageRoutingExclusivityUsingPrefix() throws Exception { - final String addressA = "addressA"; - final String queueA = "queueA"; - final String queueB = "queueB"; - final String queueC = "queueC"; - - ActiveMQServerControl serverControl = server.getActiveMQServerControl(); - serverControl.createAddress(addressA, RoutingType.ANYCAST.toString() + "," + RoutingType.MULTICAST.toString()); - serverControl.createQueue(addressA, queueA, RoutingType.ANYCAST.toString()); - serverControl.createQueue(addressA, queueB, RoutingType.MULTICAST.toString()); - serverControl.createQueue(addressA, queueC, RoutingType.MULTICAST.toString()); - - sendMessages("multicast://" + addressA, 1); - - assertEquals(0, server.locateQueue(SimpleString.toSimpleString(queueA)).getMessageCount()); - assertEquals(2, server.locateQueue(SimpleString.toSimpleString(queueC)).getMessageCount() + server.locateQueue(SimpleString.toSimpleString(queueB)).getMessageCount()); - } - - @Test - public void testMulticastMessageRoutingExclusivityUsingProperty() throws Exception { - final String addressA = "addressA"; - final String queueA = "queueA"; - final String queueB = "queueB"; - final String queueC = "queueC"; - - ActiveMQServerControl serverControl = server.getActiveMQServerControl(); - serverControl.createAddress(addressA, RoutingType.ANYCAST.toString() + "," + RoutingType.MULTICAST.toString()); - serverControl.createQueue(addressA, queueA, RoutingType.ANYCAST.toString()); - serverControl.createQueue(addressA, queueB, RoutingType.MULTICAST.toString()); - serverControl.createQueue(addressA, queueC, RoutingType.MULTICAST.toString()); - - sendMessages(addressA, 1, RoutingType.MULTICAST); - - assertEquals(0, server.locateQueue(SimpleString.toSimpleString(queueA)).getMessageCount()); - assertEquals(2, server.locateQueue(SimpleString.toSimpleString(queueC)).getMessageCount() + server.locateQueue(SimpleString.toSimpleString(queueB)).getMessageCount()); - } - @Test(timeout = 60000) public void testMessageDurableFalse() throws Exception { sendMessages(getQueueName(), 1, false); @@ -870,7 +672,7 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport { message1.setMessageId("ID:Message:1"); sender.send(message1); - assertEquals(1, queue.getMessageCount()); + assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1)); receiver1.flow(1); message1 = receiver1.receive(50, TimeUnit.SECONDS); assertNotNull("Should have read a message", message1); @@ -884,7 +686,7 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport { message2.setMessageId("ID:Message:2"); sender.send(message2); - assertEquals(1, queue.getMessageCount()); + assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1)); receiver1.flow(1); message2 = receiver1.receive(50, TimeUnit.SECONDS); assertNotNull("Should have read a message", message2); @@ -1018,7 +820,7 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport { connection.close(); } - @Test + @Test(timeout = 60000) public void testDeliveryDelayOfferedWhenRequested() throws Exception { AmqpClient client = createAmqpClient(); client.setValidator(new AmqpValidator() { @@ -1036,7 +838,7 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport { AmqpConnection connection = addConnection(client.connect()); AmqpSession session = connection.createSession(); - AmqpSender sender = session.createSender("queue://" + getQueueName(), new Symbol[] {AmqpSupport.DELAYED_DELIVERY}); + AmqpSender sender = session.createSender(getQueueName(), new Symbol[] {AmqpSupport.DELAYED_DELIVERY}); assertNotNull(sender); connection.getStateInspector().assertValid(); @@ -1100,45 +902,119 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport { connection.close(); } - public void sendMessages(String destinationName, int count) throws Exception { - sendMessages(destinationName, count, null); - } - - public void sendMessages(String destinationName, int count, RoutingType routingType) throws Exception { + @Test(timeout = 60000) + public void testLinkDetatchErrorIsCorrectWhenQueueDoesNotExists() throws Exception { AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + Exception expectedException = null; + try { + session.createSender("AnAddressThatDoesNotExist"); + fail("Creating a sender here on an address that doesn't exist should fail"); + } catch (Exception e) { + expectedException = e; + } + + assertNotNull(expectedException); + assertTrue(expectedException.getMessage().contains("amqp:not-found")); + assertTrue(expectedException.getMessage().contains("target address does not exist")); + + connection.close(); + } + + @Test(timeout = 60000) + public void testSendingAndReceivingToQueueWithDifferentAddressAndQueueName() throws Exception { + String queueName = "TestQueueName"; + String address = "TestAddress"; + server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(address), RoutingType.ANYCAST)); + server.createQueue(new SimpleString(address), RoutingType.ANYCAST, new SimpleString(queueName), null, true, false); + + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + try { AmqpSession session = connection.createSession(); - AmqpSender sender = session.createSender(destinationName); + AmqpSender sender = session.createSender(address); + AmqpReceiver receiver = session.createReceiver(address); + receiver.flow(1); - for (int i = 0; i < count; ++i) { - AmqpMessage message = new AmqpMessage(); - message.setMessageId("MessageID:" + i); - if (routingType != null) { - message.setMessageAnnotation(AMQPMessageSupport.ROUTING_TYPE.toString(), routingType.getType()); + AmqpMessage message = new AmqpMessage(); + message.setText("TestPayload"); + sender.send(message); + + AmqpMessage receivedMessage = receiver.receive(5000, TimeUnit.MILLISECONDS); + assertNotNull(receivedMessage); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testSendReceiveLotsOfDurableMessagesOnQueue() throws Exception { + doTestSendReceiveLotsOfDurableMessages(Queue.class); + } + + @Test(timeout = 60000) + public void testSendReceiveLotsOfDurableMessagesOnTopic() throws Exception { + doTestSendReceiveLotsOfDurableMessages(Topic.class); + } + + private void doTestSendReceiveLotsOfDurableMessages(Class destType) throws Exception { + final int MSG_COUNT = 1000; + + AmqpClient client = createAmqpClient(); + + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + final CountDownLatch done = new CountDownLatch(MSG_COUNT); + final AtomicBoolean error = new AtomicBoolean(false); + final ExecutorService executor = Executors.newSingleThreadExecutor(); + + final String address; + if (Queue.class.equals(destType)) { + address = getQueueName(); + } else { + address = getTopicName(); + } + + final AmqpReceiver receiver = session.createReceiver(address); + receiver.flow(MSG_COUNT); + + AmqpSender sender = session.createSender(address); + + Queue queueView = getProxyToQueue(address); + + executor.execute(new Runnable() { + + @Override + public void run() { + for (int i = 0; i < MSG_COUNT; i++) { + try { + AmqpMessage received = receiver.receive(5, TimeUnit.SECONDS); + received.accept(); + done.countDown(); + } catch (Exception ex) { + LOG.info("Caught error: {}", ex.getClass().getSimpleName()); + error.set(true); + } } - sender.send(message); } - } finally { - connection.close(); - } - } + }); - public void sendMessages(String destinationName, int count, boolean durable) throws Exception { - AmqpClient client = createAmqpClient(); - AmqpConnection connection = addConnection(client.connect()); - try { - AmqpSession session = connection.createSession(); - AmqpSender sender = session.createSender(destinationName); - - for (int i = 0; i < count; ++i) { - AmqpMessage message = new AmqpMessage(); - message.setMessageId("MessageID:" + i); - message.setDurable(durable); - sender.send(message); - } - } finally { - connection.close(); + for (int i = 0; i < MSG_COUNT; i++) { + AmqpMessage message = new AmqpMessage(); + message.setMessageId("msg" + i); + sender.send(message); } + + assertTrue("did not read all messages, waiting on: " + done.getCount(), done.await(10, TimeUnit.SECONDS)); + assertFalse("should not be any errors on receive", error.get()); + assertTrue("Should be no inflight messages.", Wait.waitFor(() -> queueView.getDeliveringCount() == 0)); + + sender.close(); + receiver.close(); + connection.close(); } } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSenderTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSenderTest.java index 7b8cbefeea..8c95064998 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSenderTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSenderTest.java @@ -16,14 +16,22 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; +import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpSender; import org.apache.activemq.transport.amqp.client.AmqpSession; +import org.apache.activemq.transport.amqp.client.AmqpValidator; import org.apache.qpid.proton.amqp.transport.ReceiverSettleMode; import org.apache.qpid.proton.amqp.transport.SenderSettleMode; +import org.apache.qpid.proton.engine.Delivery; +import org.apache.qpid.proton.engine.Sender; import org.junit.Test; /** @@ -101,4 +109,74 @@ public class AmqpSenderTest extends AmqpClientTestSupport { connection.close(); } + + @Test(timeout = 60000) + public void testUnsettledSender() throws Exception { + final int MSG_COUNT = 1000; + + final CountDownLatch settled = new CountDownLatch(MSG_COUNT); + + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + + connection.setStateInspector(new AmqpValidator() { + + @Override + public void inspectDeliveryUpdate(Sender sender, Delivery delivery) { + if (delivery.remotelySettled()) { + IntegrationTestLogger.LOGGER.trace("Remote settled message for sender: " + sender.getName()); + settled.countDown(); + } + } + }); + + AmqpSession session = connection.createSession(); + AmqpSender sender = session.createSender(getQueueName(), false); + + for (int i = 1; i <= MSG_COUNT; ++i) { + AmqpMessage message = new AmqpMessage(); + message.setText("Test-Message: " + i); + sender.send(message); + + if (i % 1000 == 0) { + IntegrationTestLogger.LOGGER.info("Sent message: " + i); + } + } + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("All messages should arrive", Wait.waitFor(() -> queueView.getMessageCount() == MSG_COUNT)); + + sender.close(); + + assertTrue("Remote should have settled all deliveries", settled.await(5, TimeUnit.MINUTES)); + + connection.close(); + } + + @Test(timeout = 60000) + public void testPresettledSender() throws Exception { + final int MSG_COUNT = 1000; + + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + + AmqpSender sender = session.createSender(getQueueName(), true); + + for (int i = 1; i <= MSG_COUNT; ++i) { + AmqpMessage message = new AmqpMessage(); + message.setText("Test-Message: " + i); + sender.send(message); + + if (i % 1000 == 0) { + IntegrationTestLogger.LOGGER.info("Sent message: " + i); + } + } + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("All messages should arrive", Wait.waitFor(() -> queueView.getMessageCount() == MSG_COUNT)); + + sender.close(); + connection.close(); + } } \ No newline at end of file diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSessionTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSessionTest.java new file mode 100644 index 0000000000..0048be55c3 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSessionTest.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; +import org.apache.activemq.transport.amqp.client.AmqpClient; +import org.apache.activemq.transport.amqp.client.AmqpConnection; +import org.apache.activemq.transport.amqp.client.AmqpReceiver; +import org.apache.activemq.transport.amqp.client.AmqpSession; +import org.apache.activemq.transport.amqp.client.AmqpValidator; +import org.apache.qpid.proton.engine.Receiver; +import org.apache.qpid.proton.engine.Session; +import org.junit.Test; + +public class AmqpSessionTest extends AmqpClientTestSupport { + + @Test(timeout = 60000) + public void testCreateSession() throws Exception { + AmqpClient client = createAmqpClient(); + AmqpConnection connection = addConnection(client.connect()); + AmqpSession session = connection.createSession(); + assertNotNull(session); + connection.close(); + } + + @Test(timeout = 60000) + public void testSessionClosedDoesNotGetReceiverDetachFromRemote() throws Exception { + AmqpClient client = createAmqpClient(); + assertNotNull(client); + + client.setValidator(new AmqpValidator() { + + @Override + public void inspectClosedResource(Session session) { + IntegrationTestLogger.LOGGER.info("Session closed: " + session.getContext()); + } + + @Override + public void inspectDetachedResource(Receiver receiver) { + markAsInvalid("Broker should not detach receiver linked to closed session."); + } + + @Override + public void inspectClosedResource(Receiver receiver) { + markAsInvalid("Broker should not close receiver linked to closed session."); + } + }); + + AmqpConnection connection = addConnection(client.connect()); + assertNotNull(connection); + AmqpSession session = connection.createSession(); + assertNotNull(session); + AmqpReceiver receiver = session.createReceiver(getQueueName()); + assertNotNull(receiver); + + session.close(); + + connection.getStateInspector().assertValid(); + connection.close(); + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpTestSupport.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpTestSupport.java index a360eb817e..216b0ecdcf 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpTestSupport.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpTestSupport.java @@ -30,6 +30,8 @@ import org.junit.After; */ public class AmqpTestSupport extends ActiveMQTestBase { + protected static final int AMQP_PORT = 5672; + protected LinkedList connections = new LinkedList<>(); protected boolean useSSL; @@ -65,7 +67,7 @@ public class AmqpTestSupport extends ActiveMQTestBase { boolean webSocket = false; try { - int port = 61616; + int port = AMQP_PORT; String uri = null; diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpTransactionTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpTransactionTest.java index 3b231fa09f..493079ad05 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpTransactionTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpTransactionTest.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.activemq.artemis.tests.integration.amqp; import java.io.IOException; @@ -33,6 +32,7 @@ import javax.jms.Session; import org.apache.activemq.artemis.api.core.RoutingType; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; @@ -45,6 +45,7 @@ import org.apache.qpid.proton.amqp.messaging.Accepted; import org.apache.qpid.proton.amqp.transaction.TransactionalState; import org.apache.qpid.proton.amqp.transport.DeliveryState; import org.apache.qpid.proton.engine.Delivery; +import org.apache.qpid.proton.engine.Sender; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; @@ -98,7 +99,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport { sender.setStateInspector(new AmqpValidator() { @Override - public void inspectDeliveryUpdate(Delivery delivery) { + public void inspectDeliveryUpdate(Sender sender, Delivery delivery) { if (delivery.remotelySettled()) { DeliveryState state = delivery.getRemoteState(); if (state instanceof TransactionalState) { @@ -161,7 +162,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport { session.commit(); - assertEquals(1, queue.getMessageCount()); + assertTrue("Message was not queued", Wait.waitFor(() -> queue.getMessageCount() == 1)); sender.close(); connection.close(); @@ -205,7 +206,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport { message.setText("Test-Message"); sender.send(message); - assertEquals(1, queue.getMessageCount()); + assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1)); AmqpReceiver receiver = session.createReceiver(getQueueName()); @@ -237,7 +238,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport { message.setText("Test-Message"); sender.send(message); - assertEquals(1, queue.getMessageCount()); + assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1)); AmqpReceiver receiver = session.createReceiver(getQueueName()); @@ -281,7 +282,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport { message.setText("Test-Message"); sender.send(message); - assertEquals(1, queue.getMessageCount()); + assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1)); AmqpReceiver receiver = session.createReceiver(getQueueName()); @@ -853,10 +854,10 @@ public class AmqpTransactionTest extends AmqpClientTestSupport { @Test(timeout = 120000) public void testSendPersistentTX() throws Exception { - int MESSAGE_COUNT = 100000; + int MESSAGE_COUNT = 2000; AtomicInteger errors = new AtomicInteger(0); server.createQueue(SimpleString.toSimpleString("q1"), RoutingType.ANYCAST, SimpleString.toSimpleString("q1"), null, true, false, 1, false, true); - ConnectionFactory factory = new JmsConnectionFactory("amqp://localhost:61616"); + ConnectionFactory factory = new JmsConnectionFactory("amqp://localhost:" + AMQP_PORT); Connection sendConnection = factory.createConnection(); Connection consumerConnection = factory.createConnection(); try { @@ -939,7 +940,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport { receiver.setStateInspector(new AmqpValidator() { @Override - public void inspectDeliveryUpdate(Delivery delivery) { + public void inspectDeliveryUpdate(Sender sender, Delivery delivery) { if (delivery.remotelySettled()) { LOG.info("Receiver got delivery update for: {}", delivery); if (!(delivery.getRemoteState() instanceof TransactionalState)) { diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/BrokerDefinedAnycastConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/BrokerDefinedAnycastConsumerTest.java index a0f0393121..e10c73d97b 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/BrokerDefinedAnycastConsumerTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/BrokerDefinedAnycastConsumerTest.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -16,8 +16,13 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; -import org.apache.activemq.artemis.api.core.SimpleString; +import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.QUEUE_CAPABILITY; +import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.TOPIC_CAPABILITY; + +import java.util.concurrent.TimeUnit; + import org.apache.activemq.artemis.api.core.RoutingType; +import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.server.impl.AddressInfo; import org.apache.activemq.artemis.core.server.impl.QueueImpl; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; @@ -29,12 +34,6 @@ import org.apache.activemq.transport.amqp.client.AmqpSession; import org.apache.qpid.proton.amqp.messaging.Source; import org.junit.Test; -import java.util.concurrent.TimeUnit; - -import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.QUEUE_CAPABILITY; -import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.TOPIC_CAPABILITY; - - public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { SimpleString address = new SimpleString("testAddress"); @@ -46,7 +45,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST)); server.createQueue(address, RoutingType.ANYCAST, address, null, true, false); - sendMessages(1, address.toString()); + sendMessages(address.toString(), 1); AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); @@ -68,7 +67,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { server.createQueue(address, RoutingType.ANYCAST, queue1, null, true, false); server.createQueue(address, RoutingType.ANYCAST, address, null, true, false); - sendMessages(2, address.toString()); + sendMessages(address.toString(), 2); AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); @@ -89,7 +88,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST)); server.createQueue(address, RoutingType.ANYCAST, queue1, null, true, false); - sendMessages(1, address.toString()); + sendMessages(address.toString(), 1); AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); @@ -111,7 +110,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { server.createQueue(address, RoutingType.ANYCAST, queue1, null, true, false); server.createQueue(address, RoutingType.ANYCAST, queue2, null, true, false); - sendMessages(1, address.toString()); + sendMessages(address.toString(), 1); AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); @@ -132,7 +131,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST)); server.createQueue(address, RoutingType.ANYCAST, queue1, null, true, false); - sendMessages(1, address.toString()); + sendMessages(address.toString(), 1); AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); @@ -152,7 +151,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { public void testConsumeWhenOnlyMulticast() throws Exception { server.addAddressInfo(new AddressInfo(address, RoutingType.MULTICAST)); - sendMessages(1, address.toString()); + sendMessages(address.toString(), 1); AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); @@ -195,7 +194,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { AmqpConnection connection = addConnection(client.connect()); AmqpSession session = connection.createSession(); AmqpReceiver receiver = session.createReceiver(address.toString()); - sendMessages(1, address.toString()); + sendMessages(address.toString(), 1); receiver.flow(1); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); @@ -223,7 +222,6 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { connection.close(); } - protected Source createJmsSource(boolean topic) { Source source = new Source(); @@ -236,5 +234,4 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport { return source; } - } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/BrokerDefinedMulticastConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/BrokerDefinedMulticastConsumerTest.java index b413ad80d1..bdf6258e26 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/BrokerDefinedMulticastConsumerTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/BrokerDefinedMulticastConsumerTest.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -16,8 +16,13 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; -import org.apache.activemq.artemis.api.core.SimpleString; +import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.QUEUE_CAPABILITY; +import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.TOPIC_CAPABILITY; + +import java.util.concurrent.TimeUnit; + import org.apache.activemq.artemis.api.core.RoutingType; +import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.server.impl.AddressInfo; import org.apache.activemq.artemis.core.server.impl.QueueImpl; import org.apache.activemq.transport.amqp.client.AmqpClient; @@ -28,12 +33,6 @@ import org.apache.activemq.transport.amqp.client.AmqpSession; import org.apache.qpid.proton.amqp.messaging.Source; import org.junit.Test; -import java.util.concurrent.TimeUnit; - -import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.QUEUE_CAPABILITY; -import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.TOPIC_CAPABILITY; - - public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport { SimpleString address = new SimpleString("testAddress"); @@ -45,7 +44,7 @@ public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport { server.addAddressInfo(new AddressInfo(address, RoutingType.MULTICAST)); server.createQueue(address, RoutingType.MULTICAST, address, null, true, false); - sendMessages(1, address.toString()); + sendMessages(address.toString(), 1); AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); @@ -65,7 +64,7 @@ public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport { public void testConsumeWhenOnlyAnycast() throws Exception { server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST)); - sendMessages(1, address.toString()); + sendMessages(address.toString(), 1); AmqpClient client = createAmqpClient(); AmqpConnection connection = addConnection(client.connect()); @@ -102,7 +101,6 @@ public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport { connection.close(); } - protected Source createJmsSource(boolean topic) { Source source = new Source(); @@ -115,5 +113,4 @@ public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport { return source; } - } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ClientDefinedAnycastConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ClientDefinedAnycastConsumerTest.java index 377cf86751..3e504d7895 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ClientDefinedAnycastConsumerTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ClientDefinedAnycastConsumerTest.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -16,6 +16,8 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; +import java.util.concurrent.TimeUnit; + import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.server.impl.QueueImpl; import org.apache.activemq.transport.amqp.client.AmqpClient; @@ -25,8 +27,6 @@ import org.apache.activemq.transport.amqp.client.AmqpReceiver; import org.apache.activemq.transport.amqp.client.AmqpSession; import org.junit.Test; -import java.util.concurrent.TimeUnit; - public class ClientDefinedAnycastConsumerTest extends AmqpClientTestSupport { SimpleString address = new SimpleString("testAddress"); @@ -39,7 +39,7 @@ public class ClientDefinedAnycastConsumerTest extends AmqpClientTestSupport { AmqpSession session = connection.createSession(); AmqpReceiver receiver = session.createReceiver(address.toString()); - sendMessages(1, address.toString()); + sendMessages(address.toString(), 1); receiver.flow(1); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); @@ -48,5 +48,4 @@ public class ClientDefinedAnycastConsumerTest extends AmqpClientTestSupport { receiver.close(); connection.close(); } - } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ClientDefinedMultiConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ClientDefinedMultiConsumerTest.java index 84bdb869c1..51c70ee47c 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ClientDefinedMultiConsumerTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ClientDefinedMultiConsumerTest.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -16,8 +16,12 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; -import org.apache.activemq.artemis.api.core.SimpleString; +import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.TOPIC_CAPABILITY; + +import java.util.concurrent.TimeUnit; + import org.apache.activemq.artemis.api.core.RoutingType; +import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.server.impl.AddressInfo; import org.apache.activemq.artemis.core.server.impl.QueueImpl; import org.apache.activemq.artemis.tests.util.Wait; @@ -30,10 +34,6 @@ import org.apache.qpid.proton.amqp.messaging.Source; import org.apache.qpid.proton.amqp.messaging.TerminusDurability; import org.junit.Test; -import java.util.concurrent.TimeUnit; - -import static org.apache.qpid.jms.provider.amqp.message.AmqpDestinationHelper.TOPIC_CAPABILITY; - public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { SimpleString address = new SimpleString("testAddress"); @@ -52,7 +52,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); receiver.flow(1); receiver2.flow(1); - sendMessages(2, address.toString()); + sendMessages(address.toString(), 2); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); @@ -86,7 +86,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|1"); receiver.flow(1); receiver2.flow(1); - sendMessages(2, address.toString()); + sendMessages(address.toString(), 2); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); @@ -114,7 +114,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); receiver.flow(1); receiver2.flow(1); - sendMessages(2, address.toString()); + sendMessages(address.toString(), 2); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); @@ -145,7 +145,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); receiver.flow(1); receiver2.flow(1); - sendMessages(2, address.toString()); + sendMessages(address.toString(), 2); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); @@ -178,7 +178,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); receiver.flow(1); receiver2.flow(1); - sendMessages(2, address.toString()); + sendMessages(address.toString(), 2); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); @@ -206,7 +206,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); receiver.flow(1); receiver2.flow(1); - sendMessages(2, address.toString()); + sendMessages(address.toString(), 2); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); @@ -244,7 +244,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); receiver.flow(1); receiver2.flow(1); - sendMessages(2, address.toString()); + sendMessages(address.toString(), 2); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); @@ -282,7 +282,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); receiver.flow(1); receiver2.flow(1); - sendMessages(2, address.toString()); + sendMessages(address.toString(), 2); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); assertNotNull(amqpMessage); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); @@ -313,7 +313,10 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { fail("Exception expected"); } catch (Exception e) { //expected + } finally { + receiver.close(); } + connection.close(); } @@ -331,7 +334,10 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport { fail("Exception expected"); } catch (Exception e) { //expected + } finally { + receiver.close(); } + connection.close(); } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSClientTestSupport.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSClientTestSupport.java new file mode 100644 index 0000000000..7de05aad20 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSClientTestSupport.java @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.net.URI; +import java.util.LinkedList; + +import javax.jms.Connection; +import javax.jms.ExceptionListener; +import javax.jms.JMSException; + +import org.apache.qpid.jms.JmsConnectionFactory; +import org.junit.After; +import org.junit.Before; + +public abstract class JMSClientTestSupport extends AmqpClientTestSupport { + + protected LinkedList jmsConnections = new LinkedList<>(); + + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + + // Bug in Qpid JMS not shutting down a connection thread on certain errors + // TODO - Reevaluate after Qpid JMS 0.23.0 is released. + disableCheckThread(); + } + + @After + @Override + public void tearDown() throws Exception { + for (Connection connection : jmsConnections) { + try { + connection.close(); + } catch (Throwable ignored) { + ignored.printStackTrace(); + } + } + jmsConnections.clear(); + + super.tearDown(); + } + + protected Connection trackJMSConnection(Connection connection) { + jmsConnections.add(connection); + + return connection; + } + + protected String getJmsConnectionURIOptions() { + return ""; + } + + protected URI getBrokerQpidJMSConnectionURI() { + boolean webSocket = false; + + try { + int port = AMQP_PORT; + + String uri = null; + + if (isUseSSL()) { + if (webSocket) { + uri = "amqpwss://127.0.0.1:" + port; + } else { + uri = "amqps://127.0.0.1:" + port; + } + } else { + if (webSocket) { + uri = "amqpws://127.0.0.1:" + port; + } else { + uri = "amqp://127.0.0.1:" + port; + } + } + + if (!getJmsConnectionURIOptions().isEmpty()) { + uri = uri + "?" + getJmsConnectionURIOptions(); + } + + return new URI(uri); + } catch (Exception e) { + throw new RuntimeException(); + } + } + + protected Connection createConnection() throws JMSException { + return createConnection(getBrokerQpidJMSConnectionURI(), null, null, null, true); + } + + protected Connection createConnection(boolean start) throws JMSException { + return createConnection(getBrokerQpidJMSConnectionURI(), null, null, null, start); + } + + protected Connection createConnection(String clientId) throws JMSException { + return createConnection(getBrokerQpidJMSConnectionURI(), null, null, clientId, true); + } + + protected Connection createConnection(String clientId, boolean start) throws JMSException { + return createConnection(getBrokerQpidJMSConnectionURI(), null, null, clientId, start); + } + + protected Connection createConnection(String username, String password) throws JMSException { + return createConnection(getBrokerQpidJMSConnectionURI(), username, password, null, true); + } + + protected Connection createConnection(String username, String password, String clientId) throws JMSException { + return createConnection(getBrokerQpidJMSConnectionURI(), username, password, clientId, true); + } + + protected Connection createConnection(String username, String password, String clientId, boolean start) throws JMSException { + return createConnection(getBrokerQpidJMSConnectionURI(), username, password, clientId, start); + } + + private Connection createConnection(URI remoteURI, String username, String password, String clientId, boolean start) throws JMSException { + JmsConnectionFactory factory = new JmsConnectionFactory(remoteURI); + + Connection connection = trackJMSConnection(factory.createConnection(username, password)); + + connection.setExceptionListener(new ExceptionListener() { + @Override + public void onException(JMSException exception) { + exception.printStackTrace(); + } + }); + + if (clientId != null && !clientId.isEmpty()) { + connection.setClientID(clientId); + } + + if (start) { + connection.start(); + } + + return connection; + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionTest.java new file mode 100644 index 0000000000..e261468e42 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionTest.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import javax.jms.Connection; +import javax.jms.InvalidClientIDException; +import javax.jms.JMSException; +import javax.jms.Session; + +import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.util.Wait; +import org.junit.Test; + +public class JMSConnectionTest extends JMSClientTestSupport { + + @Test(timeout = 60000) + public void testConnection() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + session.createConsumer(queue); + + Queue queueView = getProxyToQueue(getQueueName()); + + assertTrue("Connection not counted", Wait.waitFor(() -> server.getConnectionCount() == 1)); + assertTrue("Consumer not counted", Wait.waitFor(() -> queueView.getConsumerCount() == 1)); + + assertEquals(1, queueView.getConsumerCount()); + + connection.close(); + + assertTrue("Consumer not closed", Wait.waitFor(() -> queueView.getConsumerCount() == 0)); + assertTrue("Connection not released", Wait.waitFor(() -> server.getConnectionCount() == 0)); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testClientIDsAreExclusive() throws Exception { + Connection testConn1 = createConnection(false); + Connection testConn2 = createConnection(false); + + try { + testConn1.setClientID("client-id1"); + try { + testConn1.setClientID("client-id2"); + fail("didn't get expected exception"); + } catch (javax.jms.IllegalStateException e) { + // expected + } + + try { + testConn2.setClientID("client-id1"); + fail("didn't get expected exception"); + } catch (InvalidClientIDException e) { + // expected + } + } finally { + testConn1.close(); + testConn2.close(); + } + + try { + testConn1 = createConnection(false); + testConn2 = createConnection(false); + testConn1.setClientID("client-id1"); + testConn2.setClientID("client-id2"); + } finally { + testConn1.close(); + testConn2.close(); + } + } + + @Test(timeout = 60000) + public void testParallelConnections() throws Exception { + final int numThreads = 40; + ExecutorService executorService = Executors.newFixedThreadPool(numThreads); + for (int i = 0; i < numThreads; i++) { + executorService.execute(new Runnable() { + @Override + public void run() { + + try { + Connection connection = createConnection(fullUser, fullPass); + connection.start(); + connection.close(); + } catch (JMSException e) { + e.printStackTrace(); + } + } + }); + } + + executorService.shutdown(); + assertTrue("executor done on time", executorService.awaitTermination(30, TimeUnit.SECONDS)); + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionWithSecurityTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionWithSecurityTest.java new file mode 100644 index 0000000000..bfd31acbe1 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionWithSecurityTest.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.JMSSecurityException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; + +import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; +import org.junit.Test; + +public class JMSConnectionWithSecurityTest extends JMSClientTestSupport { + + @Override + protected boolean isSecurityEnabled() { + return true; + } + + @Test(timeout = 10000) + public void testNoUserOrPassword() throws Exception { + try { + Connection connection = createConnection("", "", null, false); + connection.start(); + fail("Expected JMSException"); + } catch (JMSSecurityException ex) { + IntegrationTestLogger.LOGGER.debug("Failed to authenticate connection with no user / password."); + } + } + + @Test(timeout = 10000) + public void testUnknownUser() throws Exception { + try { + Connection connection = createConnection("nosuchuser", "blah", null, false); + connection.start(); + fail("Expected JMSException"); + } catch (JMSSecurityException ex) { + IntegrationTestLogger.LOGGER.debug("Failed to authenticate connection with unknown user ID"); + } + } + + @Test(timeout = 10000) + public void testKnownUserWrongPassword() throws Exception { + try { + Connection connection = createConnection(fullUser, "wrongPassword", null, false); + connection.start(); + fail("Expected JMSException"); + } catch (JMSSecurityException ex) { + IntegrationTestLogger.LOGGER.debug("Failed to authenticate connection with incorrect password."); + } + } + + @Test(timeout = 30000) + public void testRepeatedWrongPasswordAttempts() throws Exception { + for (int i = 0; i < 25; ++i) { + Connection connection = null; + try { + connection = createConnection(fullUser, "wrongPassword", null, false); + connection.start(); + fail("Expected JMSException"); + } catch (JMSSecurityException ex) { + IntegrationTestLogger.LOGGER.debug("Failed to authenticate connection with incorrect password."); + } finally { + if (connection != null) { + connection.close(); + } + } + } + } + + @Test(timeout = 30000) + public void testSendReceive() throws Exception { + Connection connection = createConnection(fullUser, fullPass); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + MessageProducer p = session.createProducer(queue); + TextMessage message = null; + message = session.createTextMessage(); + String messageText = "hello sent at " + new java.util.Date().toString(); + message.setText(messageText); + p.send(message); + + // Get the message we just sent + MessageConsumer consumer = session.createConsumer(queue); + connection.start(); + Message msg = consumer.receive(5000); + assertNotNull(msg); + assertTrue(msg instanceof TextMessage); + TextMessage textMessage = (TextMessage) msg; + assertEquals(messageText, textMessage.getText()); + } finally { + connection.close(); + } + } + + @Test(timeout = 30000) + public void testCreateTemporaryQueueNotAuthorized() throws JMSException { + Connection connection = createConnection(guestUser, guestPass); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + try { + session.createTemporaryQueue(); + } catch (JMSSecurityException jmsse) { + } catch (JMSException jmse) { + IntegrationTestLogger.LOGGER.info("Client should have thrown a JMSSecurityException but only threw JMSException"); + } + + // Should not be fatal + assertNotNull(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)); + } finally { + connection.close(); + } + } + + @Test(timeout = 30000) + public void testCreateTemporaryTopicNotAuthorized() throws JMSException { + Connection connection = createConnection(guestUser, guestPass); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + try { + session.createTemporaryTopic(); + } catch (JMSSecurityException jmsse) { + } catch (JMSException jmse) { + IntegrationTestLogger.LOGGER.info("Client should have thrown a JMSSecurityException but only threw JMSException"); + } + + // Should not be fatal + assertNotNull(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)); + } finally { + connection.close(); + } + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSDurableConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSDurableConsumerTest.java new file mode 100644 index 0000000000..26097f6d37 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSDurableConsumerTest.java @@ -0,0 +1,202 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import javax.jms.Connection; +import javax.jms.DeliveryMode; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.jms.Topic; + +import org.apache.activemq.artemis.tests.util.Wait; +import org.junit.Test; + +public class JMSDurableConsumerTest extends JMSClientTestSupport { + + @Test(timeout = 30000) + public void testDurableConsumerAsync() throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + final AtomicReference received = new AtomicReference<>(); + String durableClientId = getTopicName() + "-ClientId"; + + Connection connection = createConnection(durableClientId); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + MessageConsumer consumer = session.createDurableSubscriber(topic, "DurbaleTopic"); + consumer.setMessageListener(new MessageListener() { + + @Override + public void onMessage(Message message) { + received.set(message); + latch.countDown(); + } + }); + + MessageProducer producer = session.createProducer(topic); + producer.setDeliveryMode(DeliveryMode.PERSISTENT); + connection.start(); + + TextMessage message = session.createTextMessage(); + message.setText("hello"); + producer.send(message); + + assertTrue(latch.await(10, TimeUnit.SECONDS)); + assertNotNull("Should have received a message by now.", received.get()); + assertTrue("Should be an instance of TextMessage", received.get() instanceof TextMessage); + } finally { + connection.close(); + } + } + + @Test(timeout = 30000) + public void testDurableConsumerSync() throws Exception { + String durableClientId = getTopicName() + "-ClientId"; + + Connection connection = createConnection(durableClientId); + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + final MessageConsumer consumer = session.createDurableSubscriber(topic, "DurbaleTopic"); + MessageProducer producer = session.createProducer(topic); + producer.setDeliveryMode(DeliveryMode.PERSISTENT); + connection.start(); + + TextMessage message = session.createTextMessage(); + message.setText("hello"); + producer.send(message); + + final AtomicReference msg = new AtomicReference<>(); + assertTrue(Wait.waitFor(new Wait.Condition() { + + @Override + public boolean isSatisfied() throws Exception { + msg.set(consumer.receiveNoWait()); + return msg.get() != null; + } + }, TimeUnit.SECONDS.toMillis(25), TimeUnit.MILLISECONDS.toMillis(200))); + + assertNotNull("Should have received a message by now.", msg.get()); + assertTrue("Should be an instance of TextMessage", msg.get() instanceof TextMessage); + } finally { + connection.close(); + } + } + + @Test(timeout = 30000) + public void testDurableConsumerUnsubscribe() throws Exception { + String durableClientId = getTopicName() + "-ClientId"; + + Connection connection = createConnection(durableClientId); + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + MessageConsumer consumer = session.createDurableSubscriber(topic, "DurbaleTopic"); + + assertTrue(Wait.waitFor(new Wait.Condition() { + + @Override + public boolean isSatisfied() throws Exception { + return server.getTotalConsumerCount() == 1; + } + }, TimeUnit.SECONDS.toMillis(20), TimeUnit.MILLISECONDS.toMillis(250))); + + consumer.close(); + + assertTrue(Wait.waitFor(new Wait.Condition() { + + @Override + public boolean isSatisfied() throws Exception { + return server.getTotalConsumerCount() == 0; + } + }, TimeUnit.SECONDS.toMillis(20), TimeUnit.MILLISECONDS.toMillis(250))); + + session.unsubscribe("DurbaleTopic"); + assertTrue(Wait.waitFor(new Wait.Condition() { + + @Override + public boolean isSatisfied() throws Exception { + return server.getTotalConsumerCount() == 0; + } + }, TimeUnit.SECONDS.toMillis(20), TimeUnit.MILLISECONDS.toMillis(250))); + } finally { + connection.close(); + } + } + + @Test(timeout = 30000) + public void testDurableConsumerUnsubscribeWhileNoSubscription() throws Exception { + Connection connection = createConnection(); + + try { + connection.start(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + assertTrue(Wait.waitFor(new Wait.Condition() { + + @Override + public boolean isSatisfied() throws Exception { + return server.getTotalConsumerCount() == 0; + } + }, TimeUnit.SECONDS.toMillis(20), TimeUnit.MILLISECONDS.toMillis(250))); + + try { + session.unsubscribe("DurbaleTopic"); + fail("Should have thrown as subscription is in use."); + } catch (JMSException ex) { + } + } finally { + connection.close(); + } + } + + @Test(timeout = 30000) + public void testDurableConsumerUnsubscribeWhileActive() throws Exception { + String durableClientId = getTopicName() + "-ClientId"; + + Connection connection = createConnection(durableClientId); + try { + connection.start(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + MessageConsumer consumer = session.createDurableSubscriber(topic, "DurbaleTopic"); + + assertNotNull(consumer); + assertNull(consumer.receive(10)); + + try { + session.unsubscribe("DurbaleTopic"); + fail("Should have thrown as subscription is in use."); + } catch (JMSException ex) { + } + } finally { + connection.close(); + } + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageConsumerTest.java new file mode 100644 index 0000000000..c5372accb3 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageConsumerTest.java @@ -0,0 +1,500 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import javax.jms.BytesMessage; +import javax.jms.Connection; +import javax.jms.DeliveryMode; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.MessageProducer; +import javax.jms.QueueBrowser; +import javax.jms.Session; +import javax.jms.TextMessage; + +import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.util.Wait; +import org.apache.qpid.jms.JmsConnection; +import org.apache.qpid.jms.policy.JmsDefaultPrefetchPolicy; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JMSMessageConsumerTest extends JMSClientTestSupport { + + protected static final Logger LOG = LoggerFactory.getLogger(JMSMessageConsumerTest.class); + + @Test(timeout = 60000) + public void testSelector() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + MessageProducer producer = session.createProducer(queue); + + TextMessage message = session.createTextMessage(); + message.setText("msg:0"); + producer.send(message); + message = session.createTextMessage(); + message.setText("msg:1"); + message.setStringProperty("color", "RED"); + producer.send(message); + + connection.start(); + + MessageConsumer messageConsumer = session.createConsumer(queue, "color = 'RED'"); + TextMessage m = (TextMessage) messageConsumer.receive(5000); + assertNotNull(m); + assertEquals("msg:1", m.getText()); + assertEquals(m.getStringProperty("color"), "RED"); + } finally { + connection.close(); + } + } + + @SuppressWarnings("rawtypes") + @Test(timeout = 30000) + public void testSelectorsWithJMSType() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + MessageProducer p = session.createProducer(queue); + + TextMessage message = session.createTextMessage(); + message.setText("text"); + p.send(message, DeliveryMode.NON_PERSISTENT, Message.DEFAULT_PRIORITY, Message.DEFAULT_TIME_TO_LIVE); + + TextMessage message2 = session.createTextMessage(); + String type = "myJMSType"; + message2.setJMSType(type); + message2.setText("text + type"); + p.send(message2, DeliveryMode.NON_PERSISTENT, Message.DEFAULT_PRIORITY, Message.DEFAULT_TIME_TO_LIVE); + + QueueBrowser browser = session.createBrowser(queue); + Enumeration enumeration = browser.getEnumeration(); + int count = 0; + while (enumeration.hasMoreElements()) { + Message m = (Message) enumeration.nextElement(); + assertTrue(m instanceof TextMessage); + count++; + } + + assertEquals(2, count); + + MessageConsumer consumer = session.createConsumer(queue, "JMSType = '" + type + "'"); + Message msg = consumer.receive(2000); + assertNotNull(msg); + assertTrue(msg instanceof TextMessage); + assertEquals("Unexpected JMSType value", type, msg.getJMSType()); + assertEquals("Unexpected message content", "text + type", ((TextMessage) msg).getText()); + } finally { + connection.close(); + } + } + + @SuppressWarnings("rawtypes") + @Test(timeout = 30000) + public void testSelectorsWithJMSPriority() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + MessageProducer p = session.createProducer(queue); + + TextMessage message = session.createTextMessage(); + message.setText("hello"); + p.send(message, DeliveryMode.PERSISTENT, 5, 0); + + message = session.createTextMessage(); + message.setText("hello + 9"); + p.send(message, DeliveryMode.PERSISTENT, 9, 0); + + QueueBrowser browser = session.createBrowser(queue); + Enumeration enumeration = browser.getEnumeration(); + int count = 0; + while (enumeration.hasMoreElements()) { + Message m = (Message) enumeration.nextElement(); + assertTrue(m instanceof TextMessage); + count++; + } + + assertEquals(2, count); + + MessageConsumer consumer = session.createConsumer(queue, "JMSPriority > 8"); + Message msg = consumer.receive(2000); + assertNotNull(msg); + assertTrue(msg instanceof TextMessage); + assertEquals("hello + 9", ((TextMessage) msg).getText()); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testJMSSelectorFiltersJMSMessageID() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + MessageProducer producer = session.createProducer(queue); + + // Send one to receive + TextMessage message = session.createTextMessage(); + producer.send(message); + + // Send another to filter + producer.send(session.createTextMessage()); + + connection.start(); + + // First one should make it through + MessageConsumer messageConsumer = session.createConsumer(queue, "JMSMessageID = '" + message.getJMSMessageID() + "'"); + TextMessage m = (TextMessage) messageConsumer.receive(5000); + assertNotNull(m); + assertEquals(message.getJMSMessageID(), m.getJMSMessageID()); + + // The second one should not be received. + assertNull(messageConsumer.receive(1000)); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testZeroPrefetchWithTwoConsumers() throws Exception { + JmsConnection connection = (JmsConnection) createConnection(); + ((JmsDefaultPrefetchPolicy) connection.getPrefetchPolicy()).setAll(0); + connection.start(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + + MessageProducer producer = session.createProducer(queue); + producer.send(session.createTextMessage("Msg1")); + producer.send(session.createTextMessage("Msg2")); + + // now lets receive it + MessageConsumer consumer1 = session.createConsumer(queue); + MessageConsumer consumer2 = session.createConsumer(queue); + TextMessage answer = (TextMessage) consumer1.receive(5000); + assertNotNull(answer); + assertEquals("Should have received a message!", answer.getText(), "Msg1"); + answer = (TextMessage) consumer2.receive(5000); + assertNotNull(answer); + assertEquals("Should have received a message!", answer.getText(), "Msg2"); + + answer = (TextMessage) consumer2.receiveNoWait(); + assertNull("Should have not received a message!", answer); + } + + @Test(timeout = 30000) + public void testProduceAndConsumeLargeNumbersOfTopicMessagesClientAck() throws Exception { + doTestProduceAndConsumeLargeNumbersOfMessages(true, Session.CLIENT_ACKNOWLEDGE); + } + + @Test(timeout = 30000) + public void testProduceAndConsumeLargeNumbersOfQueueMessagesClientAck() throws Exception { + doTestProduceAndConsumeLargeNumbersOfMessages(false, Session.CLIENT_ACKNOWLEDGE); + } + + @Test(timeout = 30000) + public void testProduceAndConsumeLargeNumbersOfTopicMessagesAutoAck() throws Exception { + doTestProduceAndConsumeLargeNumbersOfMessages(true, Session.AUTO_ACKNOWLEDGE); + } + + @Test(timeout = 30000) + public void testProduceAndConsumeLargeNumbersOfQueueMessagesAutoAck() throws Exception { + doTestProduceAndConsumeLargeNumbersOfMessages(false, Session.AUTO_ACKNOWLEDGE); + } + + public void doTestProduceAndConsumeLargeNumbersOfMessages(boolean topic, int ackMode) throws Exception { + + final int MSG_COUNT = 1000; + final CountDownLatch done = new CountDownLatch(MSG_COUNT); + + JmsConnection connection = (JmsConnection) createConnection(); + connection.setForceAsyncSend(true); + connection.start(); + + Session session = connection.createSession(false, ackMode); + final Destination destination; + if (topic) { + destination = session.createTopic(getTopicName()); + } else { + destination = session.createQueue(getQueueName()); + } + + MessageConsumer consumer = session.createConsumer(destination); + consumer.setMessageListener(new MessageListener() { + + @Override + public void onMessage(Message message) { + try { + message.acknowledge(); + done.countDown(); + } catch (JMSException ex) { + LOG.info("Caught exception.", ex); + } + } + }); + + MessageProducer producer = session.createProducer(destination); + + TextMessage textMessage = session.createTextMessage(); + textMessage.setText("messageText"); + + for (int i = 0; i < MSG_COUNT; i++) { + producer.send(textMessage); + } + + assertTrue("Did not receive all messages: " + MSG_COUNT, done.await(15, TimeUnit.SECONDS)); + } + + @Test(timeout = 60000) + public void testPrefetchedMessagesAreNotConsumedOnConsumerClose() throws Exception { + final int NUM_MESSAGES = 10; + + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + MessageProducer producer = session.createProducer(queue); + + byte[] bytes = new byte[2048]; + new Random().nextBytes(bytes); + for (int i = 0; i < NUM_MESSAGES; i++) { + TextMessage message = session.createTextMessage(); + message.setText("msg:" + i); + producer.send(message); + } + + connection.close(); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Not all messages were enqueud", Wait.waitFor(() -> queueView.getMessageCount() == NUM_MESSAGES)); + + // Create a consumer and prefetch the messages + connection = createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageConsumer consumer = session.createConsumer(queue); + + Thread.sleep(100); + + consumer.close(); + connection.close(); + + assertTrue("Not all messages were enqueud", Wait.waitFor(() -> queueView.getMessageCount() == NUM_MESSAGES)); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testMessagesReceivedInParallel() throws Throwable { + final int numMessages = 50000; + long time = System.currentTimeMillis(); + + final ArrayList exceptions = new ArrayList<>(); + + Thread t = new Thread(new Runnable() { + @Override + public void run() { + Connection connectionConsumer = null; + try { + connectionConsumer = createConnection(); + connectionConsumer.start(); + Session sessionConsumer = connectionConsumer.createSession(false, Session.AUTO_ACKNOWLEDGE); + final javax.jms.Queue queue = sessionConsumer.createQueue(getQueueName()); + final MessageConsumer consumer = sessionConsumer.createConsumer(queue); + + long n = 0; + int count = numMessages; + while (count > 0) { + try { + if (++n % 1000 == 0) { + System.out.println("received " + n + " messages"); + } + + Message m = consumer.receive(5000); + Assert.assertNotNull("Could not receive message count=" + count + " on consumer", m); + count--; + } catch (JMSException e) { + e.printStackTrace(); + break; + } + } + } catch (Throwable e) { + exceptions.add(e); + e.printStackTrace(); + } finally { + try { + connectionConsumer.close(); + } catch (Throwable ignored) { + // NO OP + } + } + } + }); + + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + + t.start(); + + MessageProducer p = session.createProducer(queue); + p.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + for (int i = 0; i < numMessages; i++) { + BytesMessage message = session.createBytesMessage(); + message.writeUTF("Hello world!!!!" + i); + message.setIntProperty("count", i); + p.send(message); + } + + // Wait for the consumer thread to completely read the Queue + t.join(); + + if (!exceptions.isEmpty()) { + throw exceptions.get(0); + } + + Queue queueView = getProxyToQueue(getQueueName()); + + connection.close(); + assertTrue("Not all messages consumed", Wait.waitFor(() -> queueView.getMessageCount() == 0)); + + long taken = (System.currentTimeMillis() - time); + System.out.println("Microbenchamrk ran in " + taken + " milliseconds, sending/receiving " + numMessages); + + double messagesPerSecond = ((double) numMessages / (double) taken) * 1000; + + System.out.println(((int) messagesPerSecond) + " messages per second"); + } + + @Test(timeout = 60000) + public void testClientAckMessages() throws Exception { + final int numMessages = 10; + + Connection connection = createConnection(); + + try { + long time = System.currentTimeMillis(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + MessageProducer producer = session.createProducer(queue); + + byte[] bytes = new byte[2048]; + new Random().nextBytes(bytes); + for (int i = 0; i < numMessages; i++) { + TextMessage message = session.createTextMessage(); + message.setText("msg:" + i); + producer.send(message); + } + connection.close(); + Queue queueView = getProxyToQueue(getQueueName()); + + assertTrue("Not all messages enqueued", Wait.waitFor(() -> queueView.getMessageCount() == numMessages)); + + // Now create a new connection and receive and acknowledge + connection = createConnection(); + session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); + MessageConsumer consumer = session.createConsumer(queue); + + for (int i = 0; i < numMessages; i++) { + Message msg = consumer.receive(5000); + if (msg == null) { + System.out.println("ProtonTest.testManyMessages"); + } + Assert.assertNotNull("" + i, msg); + Assert.assertTrue("" + msg, msg instanceof TextMessage); + String text = ((TextMessage) msg).getText(); + // System.out.println("text = " + text); + Assert.assertEquals(text, "msg:" + i); + msg.acknowledge(); + } + + consumer.close(); + connection.close(); + + // Wait for Acks to be processed and message removed from queue. + Thread.sleep(500); + + assertTrue("Not all messages consumed", Wait.waitFor(() -> queueView.getMessageCount() == 0)); + long taken = (System.currentTimeMillis() - time) / 1000; + System.out.println("taken = " + taken); + } finally { + connection.close(); + } + } + + @Test(timeout = 240000) + public void testTimedOutWaitingForWriteLogOnConsumer() throws Throwable { + String name = "exampleQueue1"; + + final int numMessages = 40; + + Connection connection = createConnection(); + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(name); + MessageProducer producer = session.createProducer(queue); + for (int i = 0; i < numMessages; i++) { + TextMessage message = session.createTextMessage(); + message.setText("Message temporary"); + producer.send(message); + } + producer.close(); + session.close(); + + for (int i = 0; i < numMessages; i++) { + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + queue = session.createQueue(name); + MessageConsumer c = session.createConsumer(queue); + c.receive(1000); + producer.close(); + session.close(); + } + + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + queue = session.createQueue(name); + MessageConsumer c = session.createConsumer(queue); + for (int i = 0; i < numMessages; i++) { + c.receive(1000); + } + producer.close(); + session.close(); + } finally { + connection.close(); + } + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageGroupsTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageGroupsTest.java new file mode 100644 index 0000000000..628c814e8d --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageGroupsTest.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.concurrent.atomic.AtomicInteger; + +import javax.jms.BytesMessage; +import javax.jms.Connection; +import javax.jms.DeliveryMode; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JMSMessageGroupsTest extends JMSClientTestSupport { + + protected static final Logger LOG = LoggerFactory.getLogger(JMSMessageGroupsTest.class); + + private static final int ITERATIONS = 10; + private static final int MESSAGE_COUNT = 10; + private static final int MESSAGE_SIZE = 10 * 1024; + private static final int RECEIVE_TIMEOUT = 3000; + private static final String JMSX_GROUP_ID = "JmsGroupsTest"; + + @Test(timeout = 60000) + public void testGroupSeqIsNeverLost() throws Exception { + AtomicInteger sequenceCounter = new AtomicInteger(); + + for (int i = 0; i < ITERATIONS; ++i) { + Connection connection = createConnection(); + try { + sendMessagesToBroker(connection, MESSAGE_COUNT, sequenceCounter); + readMessagesOnBroker(connection, MESSAGE_COUNT); + } finally { + connection.close(); + } + } + } + + protected void readMessagesOnBroker(Connection connection, int count) throws Exception { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + MessageConsumer consumer = session.createConsumer(queue); + + for (int i = 0; i < MESSAGE_COUNT; ++i) { + Message message = consumer.receive(RECEIVE_TIMEOUT); + assertNotNull(message); + LOG.debug("Read message #{}: type = {}", i, message.getClass().getSimpleName()); + String gid = message.getStringProperty("JMSXGroupID"); + String seq = message.getStringProperty("JMSXGroupSeq"); + LOG.debug("Message assigned JMSXGroupID := {}", gid); + LOG.debug("Message assigned JMSXGroupSeq := {}", seq); + } + + session.close(); + } + + protected void sendMessagesToBroker(Connection connection, int count, AtomicInteger sequence) throws Exception { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + MessageProducer producer = session.createProducer(queue); + + byte[] buffer = new byte[MESSAGE_SIZE]; + for (count = 0; count < MESSAGE_SIZE; count++) { + String s = String.valueOf(count % 10); + Character c = s.charAt(0); + int value = c.charValue(); + buffer[count] = (byte) value; + } + + LOG.debug("Sending {} messages to destination: {}", MESSAGE_COUNT, queue); + for (int i = 1; i <= MESSAGE_COUNT; i++) { + BytesMessage message = session.createBytesMessage(); + message.setJMSDeliveryMode(DeliveryMode.PERSISTENT); + message.setStringProperty("JMSXGroupID", JMSX_GROUP_ID); + message.setIntProperty("JMSXGroupSeq", sequence.incrementAndGet()); + message.writeBytes(buffer); + producer.send(message); + } + + session.close(); + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageProducerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageProducerTest.java new file mode 100644 index 0000000000..2287238bfc --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageProducerTest.java @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.Random; + +import javax.jms.Connection; +import javax.jms.Destination; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TemporaryQueue; +import javax.jms.TextMessage; + +import org.junit.Assert; +import org.junit.Test; + +public class JMSMessageProducerTest extends JMSClientTestSupport { + + @Test(timeout = 30000) + public void testAnonymousProducer() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue1 = session.createQueue(getQueueName(1)); + Queue queue2 = session.createQueue(getQueueName(2)); + MessageProducer p = session.createProducer(null); + + TextMessage message = session.createTextMessage(); + message.setText("hello"); + p.send(queue1, message); + p.send(queue2, message); + + { + MessageConsumer consumer = session.createConsumer(queue1); + Message msg = consumer.receive(2000); + assertNotNull(msg); + assertTrue(msg instanceof TextMessage); + consumer.close(); + } + { + MessageConsumer consumer = session.createConsumer(queue2); + Message msg = consumer.receive(2000); + assertNotNull(msg); + assertTrue(msg instanceof TextMessage); + consumer.close(); + } + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testAnonymousProducerAcrossManyDestinations() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageProducer p = session.createProducer(null); + + for (int i = 1; i <= getPrecreatedQueueSize(); i++) { + javax.jms.Queue target = session.createQueue(getQueueName(i)); + TextMessage message = session.createTextMessage("message for " + target.getQueueName()); + p.send(target, message); + } + + connection.start(); + + MessageConsumer messageConsumer = session.createConsumer(session.createQueue(getQueueName())); + Message m = messageConsumer.receive(200); + Assert.assertNull(m); + + for (int i = 1; i <= getPrecreatedQueueSize(); i++) { + javax.jms.Queue target = session.createQueue(getQueueName(i)); + MessageConsumer consumer = session.createConsumer(target); + TextMessage tm = (TextMessage) consumer.receive(2000); + assertNotNull(tm); + assertEquals("message for " + target.getQueueName(), tm.getText()); + consumer.close(); + } + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testSendingBigMessage() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + MessageProducer sender = session.createProducer(queue); + + String body = createMessage(10240); + sender.send(session.createTextMessage(body)); + connection.start(); + + MessageConsumer consumer = session.createConsumer(queue); + TextMessage m = (TextMessage) consumer.receive(5000); + + assertEquals(body, m.getText()); + } finally { + if (connection != null) { + connection.close(); + } + } + } + + @Test(timeout = 60000) + public void testSendWithTimeToLiveExpiresToDLQ() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + + MessageProducer sender = session.createProducer(queue); + sender.setTimeToLive(1); + + Message message = session.createMessage(); + sender.send(message); + connection.start(); + + MessageConsumer consumer = session.createConsumer(session.createQueue(getDeadLetterAddress())); + Message m = consumer.receive(10000); + assertNotNull(m); + consumer.close(); + + consumer = session.createConsumer(queue); + m = consumer.receiveNoWait(); + assertNull(m); + consumer.close(); + } finally { + if (connection != null) { + connection.close(); + } + } + } + + @Test(timeout = 60000) + public void testReplyToUsingQueue() throws Throwable { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + TemporaryQueue queue = session.createTemporaryQueue(); + MessageProducer p = session.createProducer(queue); + + TextMessage message = session.createTextMessage(); + message.setText("Message temporary"); + message.setJMSReplyTo(session.createQueue(getQueueName())); + p.send(message); + + MessageConsumer cons = session.createConsumer(queue); + connection.start(); + + message = (TextMessage) cons.receive(5000); + assertNotNull(message); + Destination jmsReplyTo = message.getJMSReplyTo(); + assertNotNull(jmsReplyTo); + assertNotNull(message); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testReplyToUsingTempQueue() throws Throwable { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + TemporaryQueue queue = session.createTemporaryQueue(); + MessageProducer p = session.createProducer(queue); + + TextMessage message = session.createTextMessage(); + message.setText("Message temporary"); + message.setJMSReplyTo(session.createTemporaryQueue()); + p.send(message); + + MessageConsumer cons = session.createConsumer(queue); + connection.start(); + + message = (TextMessage) cons.receive(5000); + Destination jmsReplyTo = message.getJMSReplyTo(); + assertNotNull(jmsReplyTo); + assertNotNull(message); + } finally { + connection.close(); + } + } + + private static String createMessage(int messageSize) { + final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + Random rnd = new Random(); + StringBuilder sb = new StringBuilder(messageSize); + for (int j = 0; j < messageSize; j++) { + sb.append(AB.charAt(rnd.nextInt(AB.length()))); + } + String body = sb.toString(); + return body; + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageTypesTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageTypesTest.java new file mode 100644 index 0000000000..9c7488b878 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSMessageTypesTest.java @@ -0,0 +1,394 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.io.Serializable; +import java.util.ArrayList; + +import javax.jms.BytesMessage; +import javax.jms.Connection; +import javax.jms.MapMessage; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.StreamMessage; +import javax.jms.TextMessage; + +import org.apache.activemq.artemis.api.core.RoutingType; +import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.api.core.management.AddressControl; +import org.apache.activemq.artemis.tests.integration.management.ManagementControlHelper; +import org.apache.activemq.artemis.tests.util.Wait; +import org.apache.activemq.artemis.utils.Base64; +import org.apache.activemq.artemis.utils.ByteUtil; +import org.apache.activemq.artemis.utils.RandomUtil; +import org.junit.Assert; +import org.junit.Test; + +/** + * Test that various message types are handled as expected with an AMQP JMS client. + */ +public class JMSMessageTypesTest extends JMSClientTestSupport { + + final int NUM_MESSAGES = 10; + + @Test(timeout = 60000) + public void testAddressControlSendMessage() throws Exception { + SimpleString address = RandomUtil.randomSimpleString(); + server.createQueue(address, RoutingType.ANYCAST, address, null, true, false); + + AddressControl addressControl = ManagementControlHelper.createAddressControl(address, mBeanServer); + Assert.assertEquals(1, addressControl.getQueueNames().length); + addressControl.sendMessage(null, org.apache.activemq.artemis.api.core.Message.BYTES_TYPE, Base64.encodeBytes("test".getBytes()), false, fullUser, fullPass); + + Wait.waitFor(() -> addressControl.getMessageCount() == 1); + + Assert.assertEquals(1, addressControl.getMessageCount()); + + Connection connection = createConnection("myClientId"); + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(address.toString()); + MessageConsumer consumer = session.createConsumer(queue); + Message message = consumer.receive(500); + assertNotNull(message); + byte[] buffer = new byte[(int)((BytesMessage)message).getBodyLength()]; + ((BytesMessage)message).readBytes(buffer); + assertEquals("test", new String(buffer)); + session.close(); + connection.close(); + } finally { + if (connection != null) { + connection.close(); + } + } + } + + @Test(timeout = 60000) + public void testAddressControlSendMessageWithText() throws Exception { + SimpleString address = RandomUtil.randomSimpleString(); + server.createQueue(address, RoutingType.ANYCAST, address, null, true, false); + + AddressControl addressControl = ManagementControlHelper.createAddressControl(address, mBeanServer); + Assert.assertEquals(1, addressControl.getQueueNames().length); + addressControl.sendMessage(null, org.apache.activemq.artemis.api.core.Message.TEXT_TYPE, "test", false, fullUser, fullPass); + + Wait.waitFor(() -> addressControl.getMessageCount() == 1); + + Assert.assertEquals(1, addressControl.getMessageCount()); + + Connection connection = createConnection("myClientId"); + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(address.toString()); + MessageConsumer consumer = session.createConsumer(queue); + Message message = consumer.receive(500); + assertNotNull(message); + String text = ((TextMessage) message).getText(); + assertEquals("test", text); + session.close(); + connection.close(); + } finally { + if (connection != null) { + connection.close(); + } + } + } + + @Test(timeout = 60000) + public void testBytesMessageSendReceive() throws Throwable { + long time = System.currentTimeMillis(); + + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + + byte[] bytes = new byte[0xf + 1]; + for (int i = 0; i <= 0xf; i++) { + bytes[i] = (byte) i; + } + + MessageProducer producer = session.createProducer(queue); + for (int i = 0; i < NUM_MESSAGES; i++) { + System.out.println("Sending " + i); + BytesMessage message = session.createBytesMessage(); + + message.writeBytes(bytes); + message.setIntProperty("count", i); + producer.send(message); + } + + Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + final MessageConsumer consumer = sessionConsumer.createConsumer(queue); + + for (int i = 0; i < NUM_MESSAGES; i++) { + BytesMessage m = (BytesMessage) consumer.receive(5000); + Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); + + m.reset(); + + long size = m.getBodyLength(); + byte[] bytesReceived = new byte[(int) size]; + m.readBytes(bytesReceived); + + System.out.println("Received " + ByteUtil.bytesToHex(bytesReceived, 1) + " count - " + m.getIntProperty("count")); + + Assert.assertArrayEquals(bytes, bytesReceived); + } + + long taken = (System.currentTimeMillis() - time) / 1000; + System.out.println("taken = " + taken); + } + + @Test(timeout = 60000) + public void testMessageSendReceive() throws Throwable { + long time = System.currentTimeMillis(); + + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + + byte[] bytes = new byte[0xf + 1]; + for (int i = 0; i <= 0xf; i++) { + bytes[i] = (byte) i; + } + + MessageProducer producer = session.createProducer(queue); + for (int i = 0; i < NUM_MESSAGES; i++) { + System.out.println("Sending " + i); + Message message = session.createMessage(); + + message.setIntProperty("count", i); + producer.send(message); + } + + Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + final MessageConsumer consumer = sessionConsumer.createConsumer(queue); + + for (int i = 0; i < NUM_MESSAGES; i++) { + Message m = consumer.receive(5000); + Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); + } + + long taken = (System.currentTimeMillis() - time) / 1000; + System.out.println("taken = " + taken); + } + + @Test(timeout = 60000) + public void testMapMessageSendReceive() throws Throwable { + long time = System.currentTimeMillis(); + + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + + MessageProducer producer = session.createProducer(queue); + for (int i = 0; i < NUM_MESSAGES; i++) { + System.out.println("Sending " + i); + MapMessage message = session.createMapMessage(); + + message.setInt("i", i); + message.setIntProperty("count", i); + producer.send(message); + } + + Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + final MessageConsumer consumer = sessionConsumer.createConsumer(queue); + + for (int i = 0; i < NUM_MESSAGES; i++) { + MapMessage m = (MapMessage) consumer.receive(5000); + Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); + + Assert.assertEquals(i, m.getInt("i")); + Assert.assertEquals(i, m.getIntProperty("count")); + } + + long taken = (System.currentTimeMillis() - time) / 1000; + System.out.println("taken = " + taken); + } + + @Test(timeout = 60000) + public void testTextMessageSendReceive() throws Throwable { + long time = System.currentTimeMillis(); + + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + + MessageProducer producer = session.createProducer(queue); + for (int i = 0; i < NUM_MESSAGES; i++) { + System.out.println("Sending " + i); + TextMessage message = session.createTextMessage("text" + i); + message.setStringProperty("text", "text" + i); + producer.send(message); + } + + Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + final MessageConsumer consumer = sessionConsumer.createConsumer(queue); + + for (int i = 0; i < NUM_MESSAGES; i++) { + TextMessage m = (TextMessage) consumer.receive(5000); + Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); + Assert.assertEquals("text" + i, m.getText()); + } + + long taken = (System.currentTimeMillis() - time) / 1000; + System.out.println("taken = " + taken); + } + + @Test(timeout = 60000) + public void testStreamMessageSendReceive() throws Throwable { + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + + MessageProducer producer = session.createProducer(queue); + for (int i = 0; i < NUM_MESSAGES; i++) { + StreamMessage message = session.createStreamMessage(); + message.writeInt(i); + message.writeBoolean(true); + message.writeString("test"); + producer.send(message); + } + + Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + final MessageConsumer consumer = sessionConsumer.createConsumer(queue); + + for (int i = 0; i < NUM_MESSAGES; i++) { + StreamMessage m = (StreamMessage) consumer.receive(5000); + Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); + + Assert.assertEquals(i, m.readInt()); + Assert.assertEquals(true, m.readBoolean()); + Assert.assertEquals("test", m.readString()); + } + } + + @Test(timeout = 60000) + public void testObjectMessageWithArrayListPayload() throws Throwable { + ArrayList payload = new ArrayList<>(); + payload.add("aString"); + + Connection connection = createConnection(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + MessageProducer producer = session.createProducer(queue); + ObjectMessage objectMessage = session.createObjectMessage(payload); + producer.send(objectMessage); + session.close(); + + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageConsumer cons = session.createConsumer(queue); + connection.start(); + + objectMessage = (ObjectMessage) cons.receive(5000); + assertNotNull(objectMessage); + @SuppressWarnings("unchecked") + ArrayList received = (ArrayList) objectMessage.getObject(); + assertEquals(received.get(0), "aString"); + + connection.close(); + } + + @Test(timeout = 60000) + public void testObjectMessageUsingCustomType() throws Throwable { + long time = System.currentTimeMillis(); + + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = session.createQueue(getQueueName()); + + MessageProducer producer = session.createProducer(queue); + for (int i = 0; i < NUM_MESSAGES; i++) { + System.out.println("Sending " + i); + ObjectMessage message = session.createObjectMessage(new AnythingSerializable(i)); + producer.send(message); + } + + Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + final MessageConsumer consumer = sessionConsumer.createConsumer(queue); + + for (int i = 0; i < NUM_MESSAGES; i++) { + ObjectMessage msg = (ObjectMessage) consumer.receive(5000); + Assert.assertNotNull("Could not receive message count=" + i + " on consumer", msg); + + AnythingSerializable someSerialThing = (AnythingSerializable) msg.getObject(); + Assert.assertEquals(i, someSerialThing.getCount()); + } + + long taken = (System.currentTimeMillis() - time) / 1000; + System.out.println("taken = " + taken); + } + + public static class AnythingSerializable implements Serializable { + private static final long serialVersionUID = 5972085029690947807L; + + private int count; + + public AnythingSerializable(int count) { + this.count = count; + } + + public int getCount() { + return count; + } + } + + @Test(timeout = 60000) + public void testPropertiesArePreserved() throws Exception { + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Queue queue = session.createQueue(getQueueName()); + MessageProducer producer = session.createProducer(queue); + TextMessage message = session.createTextMessage(); + message.setText("msg:0"); + message.setBooleanProperty("true", true); + message.setBooleanProperty("false", false); + message.setStringProperty("foo", "bar"); + message.setDoubleProperty("double", 66.6); + message.setFloatProperty("float", 56.789f); + message.setIntProperty("int", 8); + message.setByteProperty("byte", (byte) 10); + + producer.send(message); + producer.send(message); + + connection.start(); + + MessageConsumer messageConsumer = session.createConsumer(queue); + TextMessage received = (TextMessage) messageConsumer.receive(5000); + Assert.assertNotNull(received); + Assert.assertEquals("msg:0", received.getText()); + Assert.assertEquals(received.getBooleanProperty("true"), true); + Assert.assertEquals(received.getBooleanProperty("false"), false); + Assert.assertEquals(received.getStringProperty("foo"), "bar"); + Assert.assertEquals(received.getDoubleProperty("double"), 66.6, 0.0001); + Assert.assertEquals(received.getFloatProperty("float"), 56.789f, 0.0001); + Assert.assertEquals(received.getIntProperty("int"), 8); + Assert.assertEquals(received.getByteProperty("byte"), (byte) 10); + + received = (TextMessage) messageConsumer.receive(5000); + Assert.assertNotNull(received); + + connection.close(); + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSQueueBrowserTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSQueueBrowserTest.java new file mode 100644 index 0000000000..45bec32573 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSQueueBrowserTest.java @@ -0,0 +1,296 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.Enumeration; +import java.util.concurrent.TimeUnit; + +import javax.jms.Connection; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.QueueBrowser; +import javax.jms.Session; +import javax.jms.TextMessage; + +import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.util.Wait; +import org.apache.qpid.jms.JmsConnection; +import org.apache.qpid.jms.policy.JmsDefaultPrefetchPolicy; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tests for various QueueBrowser scenarios with an AMQP JMS client. + */ +public class JMSQueueBrowserTest extends JMSClientTestSupport { + + protected static final Logger LOG = LoggerFactory.getLogger(JMSQueueBrowserTest.class); + + @Test(timeout = 60000) + public void testBrowseAllInQueueZeroPrefetch() throws Exception { + + final int MSG_COUNT = 5; + + JmsConnection connection = (JmsConnection) createConnection(); + ((JmsDefaultPrefetchPolicy) connection.getPrefetchPolicy()).setAll(0); + + connection.start(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + assertNotNull(session); + javax.jms.Queue queue = session.createQueue(getQueueName()); + sendMessages(name.getMethodName(), MSG_COUNT, false); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages did not arrive", Wait.waitFor(() -> queueView.getMessageCount() == MSG_COUNT)); + + QueueBrowser browser = session.createBrowser(queue); + assertNotNull(browser); + Enumeration enumeration = browser.getEnumeration(); + int count = 0; + while (count < MSG_COUNT && enumeration.hasMoreElements()) { + Message msg = (Message) enumeration.nextElement(); + assertNotNull(msg); + LOG.debug("Recv: {}", msg); + count++; + } + + LOG.debug("Received all expected message, checking that hasMoreElements returns false"); + assertFalse(enumeration.hasMoreElements()); + assertEquals(5, count); + } + + @Test(timeout = 40000) + public void testCreateQueueBrowser() throws Exception { + Connection connection = createConnection(); + connection.start(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + assertNotNull(session); + javax.jms.Queue queue = session.createQueue(getQueueName()); + session.createConsumer(queue).close(); + + QueueBrowser browser = session.createBrowser(queue); + assertNotNull(browser); + + Queue queueView = getProxyToQueue(getQueueName()); + assertEquals(0, queueView.getMessageCount()); + } + + @Test(timeout = 40000) + public void testNoMessagesBrowserHasNoElements() throws Exception { + Connection connection = createConnection(); + connection.start(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + assertNotNull(session); + javax.jms.Queue queue = session.createQueue(getQueueName()); + session.createConsumer(queue).close(); + + QueueBrowser browser = session.createBrowser(queue); + assertNotNull(browser); + + Queue queueView = getProxyToQueue(getQueueName()); + assertEquals(0, queueView.getMessageCount()); + + Enumeration enumeration = browser.getEnumeration(); + assertFalse(enumeration.hasMoreElements()); + } + + @Test(timeout = 30000) + public void testBroseOneInQueue() throws Exception { + Connection connection = createConnection(); + connection.start(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + MessageProducer producer = session.createProducer(queue); + producer.send(session.createTextMessage("hello")); + producer.close(); + + QueueBrowser browser = session.createBrowser(queue); + Enumeration enumeration = browser.getEnumeration(); + while (enumeration.hasMoreElements()) { + Message m = (Message) enumeration.nextElement(); + assertTrue(m instanceof TextMessage); + LOG.debug("Browsed message {} from Queue {}", m, queue); + } + + browser.close(); + + MessageConsumer consumer = session.createConsumer(queue); + Message msg = consumer.receive(5000); + assertNotNull(msg); + assertTrue(msg instanceof TextMessage); + } + + @Test(timeout = 60000) + public void testBrowseAllInQueue() throws Exception { + Connection connection = createConnection(); + connection.start(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + assertNotNull(session); + javax.jms.Queue queue = session.createQueue(getQueueName()); + sendMessages(name.getMethodName(), 5, false); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages did not arrive", Wait.waitFor(() -> queueView.getMessageCount() == 5)); + + QueueBrowser browser = session.createBrowser(queue); + assertNotNull(browser); + Enumeration enumeration = browser.getEnumeration(); + int count = 0; + while (enumeration.hasMoreElements()) { + Message msg = (Message) enumeration.nextElement(); + assertNotNull(msg); + LOG.debug("Recv: {}", msg); + count++; + TimeUnit.MILLISECONDS.sleep(50); + } + assertFalse(enumeration.hasMoreElements()); + assertEquals(5, count); + } + + @Test(timeout = 60000) + public void testBrowseAllInQueuePrefetchOne() throws Exception { + Connection connection = createConnection(); + connection.start(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + assertNotNull(session); + javax.jms.Queue queue = session.createQueue(getQueueName()); + sendMessages(name.getMethodName(), 5, false); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages did not arrive", Wait.waitFor(() -> queueView.getMessageCount() == 5)); + + QueueBrowser browser = session.createBrowser(queue); + assertNotNull(browser); + Enumeration enumeration = browser.getEnumeration(); + int count = 0; + while (enumeration.hasMoreElements()) { + Message msg = (Message) enumeration.nextElement(); + assertNotNull(msg); + LOG.debug("Recv: {}", msg); + count++; + } + assertFalse(enumeration.hasMoreElements()); + assertEquals(5, count); + } + + @Test(timeout = 40000) + public void testBrowseAllInQueueTxSession() throws Exception { + Connection connection = createConnection(); + connection.start(); + + Session session = connection.createSession(true, Session.SESSION_TRANSACTED); + assertNotNull(session); + javax.jms.Queue queue = session.createQueue(getQueueName()); + sendMessages(name.getMethodName(), 5, false); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages did not arrive", Wait.waitFor(() -> queueView.getMessageCount() == 5)); + + QueueBrowser browser = session.createBrowser(queue); + assertNotNull(browser); + Enumeration enumeration = browser.getEnumeration(); + int count = 0; + while (enumeration.hasMoreElements()) { + Message msg = (Message) enumeration.nextElement(); + assertNotNull(msg); + LOG.debug("Recv: {}", msg); + count++; + } + assertFalse(enumeration.hasMoreElements()); + assertEquals(5, count); + } + + @Test(timeout = 40000) + public void testQueueBrowserInTxSessionLeavesOtherWorkUnaffected() throws Exception { + Connection connection = createConnection(); + connection.start(); + + Session session = connection.createSession(true, Session.SESSION_TRANSACTED); + assertNotNull(session); + javax.jms.Queue queue = session.createQueue(getQueueName()); + sendMessages(name.getMethodName(), 5, false); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages did not arrive", Wait.waitFor(() -> queueView.getMessageCount() == 5)); + + // Send some TX work but don't commit. + MessageProducer txProducer = session.createProducer(queue); + for (int i = 0; i < 5; ++i) { + txProducer.send(session.createMessage()); + } + + assertEquals(5, queueView.getMessageCount()); + + QueueBrowser browser = session.createBrowser(queue); + assertNotNull(browser); + Enumeration enumeration = browser.getEnumeration(); + int count = 0; + while (enumeration.hasMoreElements()) { + Message msg = (Message) enumeration.nextElement(); + assertNotNull(msg); + LOG.debug("Recv: {}", msg); + count++; + } + + assertFalse(enumeration.hasMoreElements()); + assertEquals(5, count); + + browser.close(); + + // Now check that all browser work did not affect the session transaction. + assertEquals(5, queueView.getMessageCount()); + session.commit(); + assertEquals(10, queueView.getMessageCount()); + } + + @Test(timeout = 60000) + public void testBrowseAllInQueueSmallPrefetch() throws Exception { + Connection connection = createConnection(); + connection.start(); + + final int MSG_COUNT = 30; + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + assertNotNull(session); + javax.jms.Queue queue = session.createQueue(getQueueName()); + sendMessages(name.getMethodName(), MSG_COUNT, false); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages did not arrive", Wait.waitFor(() -> queueView.getMessageCount() == MSG_COUNT)); + + QueueBrowser browser = session.createBrowser(queue); + assertNotNull(browser); + Enumeration enumeration = browser.getEnumeration(); + int count = 0; + while (enumeration.hasMoreElements()) { + Message msg = (Message) enumeration.nextElement(); + assertNotNull(msg); + LOG.debug("Recv: {}", msg); + count++; + } + assertFalse(enumeration.hasMoreElements()); + assertEquals(MSG_COUNT, count); + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTemporaryDestinationTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTemporaryDestinationTest.java new file mode 100644 index 0000000000..776d55350b --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTemporaryDestinationTest.java @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.concurrent.TimeUnit; + +import javax.jms.Connection; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TemporaryQueue; +import javax.jms.TemporaryTopic; +import javax.jms.TextMessage; + +import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.util.Wait; +import org.junit.Test; + +public class JMSTemporaryDestinationTest extends JMSClientTestSupport { + + @Test(timeout = 60000) + public void testCreateTemporaryQueue() throws Throwable { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + TemporaryQueue queue = session.createTemporaryQueue(); + System.out.println("queue:" + queue.getQueueName()); + MessageProducer producer = session.createProducer(queue); + + TextMessage message = session.createTextMessage(); + message.setText("Message temporary"); + producer.send(message); + + MessageConsumer consumer = session.createConsumer(queue); + connection.start(); + + message = (TextMessage) consumer.receive(5000); + + assertNotNull(message); + } finally { + connection.close(); + } + } + + @Test(timeout = 30000) + public void testDeleteTemporaryQueue() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + final javax.jms.Queue queue = session.createTemporaryQueue(); + assertNotNull(queue); + assertTrue(queue instanceof TemporaryQueue); + + Queue queueView = getProxyToQueue(queue.getQueueName()); + assertNotNull(queueView); + + TemporaryQueue tempQueue = (TemporaryQueue) queue; + tempQueue.delete(); + + assertTrue("Temp Queue should be deleted.", Wait.waitFor(new Wait.Condition() { + + @Override + public boolean isSatisfied() throws Exception { + return getProxyToQueue(queue.getQueueName()) == null; + } + }, TimeUnit.SECONDS.toMillis(30), TimeUnit.MILLISECONDS.toMillis(50))); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testCreateTemporaryTopic() throws Throwable { + Connection connection = createConnection(); + + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + TemporaryTopic topic = session.createTemporaryTopic(); + + System.out.println("topic:" + topic.getTopicName()); + MessageConsumer consumer = session.createConsumer(topic); + MessageProducer producer = session.createProducer(topic); + + TextMessage message = session.createTextMessage(); + message.setText("Message temporary"); + producer.send(message); + + connection.start(); + + message = (TextMessage) consumer.receive(5000); + + assertNotNull(message); + } + + @Test(timeout = 30000) + public void testDeleteTemporaryTopic() throws Exception { + Connection connection = createConnection(); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + final javax.jms.Topic topic = session.createTemporaryTopic(); + assertNotNull(topic); + assertTrue(topic instanceof TemporaryTopic); + + Queue queueView = getProxyToQueue(topic.getTopicName()); + assertNotNull(queueView); + + TemporaryTopic tempTopic = (TemporaryTopic) topic; + tempTopic.delete(); + + assertTrue("Temp Queue should be deleted.", Wait.waitFor(new Wait.Condition() { + + @Override + public boolean isSatisfied() throws Exception { + return getProxyToQueue(topic.getTopicName()) == null; + } + }, TimeUnit.SECONDS.toMillis(30), TimeUnit.MILLISECONDS.toMillis(50))); + } finally { + connection.close(); + } + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTopicConsumerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTopicConsumerTest.java new file mode 100644 index 0000000000..52bd24754f --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTopicConsumerTest.java @@ -0,0 +1,244 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import javax.jms.Connection; +import javax.jms.ExceptionListener; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.jms.Topic; +import javax.jms.TopicPublisher; +import javax.jms.TopicSession; +import javax.jms.TopicSubscriber; + +import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.core.postoffice.Bindings; +import org.apache.activemq.artemis.core.remoting.CloseListener; +import org.junit.Assert; +import org.junit.Test; + +public class JMSTopicConsumerTest extends JMSClientTestSupport { + + @Test(timeout = 60000) + public void testSendAndReceiveOnTopic() throws Exception { + Connection connection = createConnection("myClientId"); + + try { + TopicSession session = (TopicSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + TopicSubscriber consumer = session.createSubscriber(topic); + TopicPublisher producer = session.createPublisher(topic); + + TextMessage message = session.createTextMessage("test-message"); + producer.send(message); + + producer.close(); + connection.start(); + + message = (TextMessage) consumer.receive(1000); + + assertNotNull(message); + assertNotNull(message.getText()); + assertEquals("test-message", message.getText()); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testSendWithMultipleReceiversOnTopic() throws Exception { + Connection connection = createConnection(); + + try { + TopicSession session = (TopicSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + TopicSubscriber consumer1 = session.createSubscriber(topic); + TopicSubscriber consumer2 = session.createSubscriber(topic); + TopicPublisher producer = session.createPublisher(topic); + + TextMessage message = session.createTextMessage("test-message"); + producer.send(message); + + producer.close(); + connection.start(); + + message = (TextMessage) consumer1.receive(1000); + + assertNotNull(message); + assertNotNull(message.getText()); + assertEquals("test-message", message.getText()); + + message = (TextMessage) consumer2.receive(1000); + + assertNotNull(message); + assertNotNull(message.getText()); + assertEquals("test-message", message.getText()); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testDurableSubscriptionUnsubscribe() throws Exception { + Connection connection = createConnection("myClientId"); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + TopicSubscriber myDurSub = session.createDurableSubscriber(topic, "myDurSub"); + session.close(); + connection.close(); + + connection = createConnection("myClientId"); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + myDurSub = session.createDurableSubscriber(topic, "myDurSub"); + myDurSub.close(); + + Assert.assertNotNull(server.getPostOffice().getBinding(new SimpleString("myClientId.myDurSub"))); + session.unsubscribe("myDurSub"); + Assert.assertNull(server.getPostOffice().getBinding(new SimpleString("myClientId.myDurSub"))); + session.close(); + connection.close(); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testTemporarySubscriptionDeleted() throws Exception { + Connection connection = createConnection(); + + try { + TopicSession session = (TopicSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + TopicSubscriber myNonDurSub = session.createSubscriber(topic); + assertNotNull(myNonDurSub); + + Bindings bindingsForAddress = server.getPostOffice().getBindingsForAddress(new SimpleString(getTopicName())); + Assert.assertEquals(2, bindingsForAddress.getBindings().size()); + session.close(); + + final CountDownLatch latch = new CountDownLatch(1); + server.getRemotingService().getConnections().iterator().next().addCloseListener(new CloseListener() { + @Override + public void connectionClosed() { + latch.countDown(); + } + }); + + connection.close(); + latch.await(5, TimeUnit.SECONDS); + bindingsForAddress = server.getPostOffice().getBindingsForAddress(new SimpleString(getTopicName())); + Assert.assertEquals(1, bindingsForAddress.getBindings().size()); + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testMultipleDurableConsumersSendAndReceive() throws Exception { + Connection connection = createConnection("myClientId"); + + try { + TopicSession session = (TopicSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + + int numMessages = 100; + TopicSubscriber sub1 = session.createDurableSubscriber(topic, "myPubId1"); + TopicSubscriber sub2 = session.createDurableSubscriber(topic, "myPubId2"); + TopicSubscriber sub3 = session.createDurableSubscriber(topic, "myPubId3"); + + Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageProducer producer = sendSession.createProducer(topic); + connection.start(); + for (int i = 0; i < numMessages; i++) { + producer.send(sendSession.createTextMessage("message:" + i)); + } + + for (int i = 0; i < numMessages; i++) { + TextMessage receive = (TextMessage) sub1.receive(5000); + Assert.assertNotNull(receive); + Assert.assertEquals(receive.getText(), "message:" + i); + receive = (TextMessage) sub2.receive(5000); + Assert.assertNotNull(receive); + Assert.assertEquals(receive.getText(), "message:" + i); + receive = (TextMessage) sub3.receive(5000); + Assert.assertNotNull(receive); + Assert.assertEquals(receive.getText(), "message:" + i); + } + } finally { + connection.close(); + } + } + + @Test(timeout = 60000) + public void testDurableSubscriptionReconnection() throws Exception { + Connection connection = createConnection("myClientId"); + + try { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(getTopicName()); + + int numMessages = 100; + TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId"); + + Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageProducer producer = sendSession.createProducer(topic); + connection.start(); + + for (int i = 0; i < numMessages; i++) { + producer.send(sendSession.createTextMessage("message:" + i)); + } + + for (int i = 0; i < numMessages; i++) { + TextMessage receive = (TextMessage) sub.receive(5000); + Assert.assertNotNull(receive); + Assert.assertEquals(receive.getText(), "message:" + i); + } + + connection.close(); + connection = createConnection("myClientId"); + connection.setExceptionListener(new ExceptionListener() { + @Override + public void onException(JMSException exception) { + exception.printStackTrace(); + } + }); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + sub = session.createDurableSubscriber(topic, "myPubId"); + + sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + producer = sendSession.createProducer(topic); + connection.start(); + for (int i = 0; i < numMessages; i++) { + producer.send(sendSession.createTextMessage("message:" + i)); + } + for (int i = 0; i < numMessages; i++) { + TextMessage receive = (TextMessage) sub.receive(5000); + Assert.assertNotNull(receive); + Assert.assertEquals(receive.getText(), "message:" + i); + } + } finally { + connection.close(); + } + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTransactionTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTransactionTest.java new file mode 100644 index 0000000000..c7f73c1eee --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSTransactionTest.java @@ -0,0 +1,216 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.tests.integration.amqp; + +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +import javax.jms.Connection; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; + +import org.apache.activemq.artemis.core.server.Queue; +import org.apache.activemq.artemis.tests.util.Wait; +import org.junit.Assert; +import org.junit.Test; + +public class JMSTransactionTest extends JMSClientTestSupport { + + @Test(timeout = 60000) + public void testProduceMessageAndCommit() throws Throwable { + Connection connection = createConnection(); + Session session = connection.createSession(true, Session.SESSION_TRANSACTED); + javax.jms.Queue queue = session.createQueue(getQueueName()); + + System.out.println("queue:" + queue.getQueueName()); + MessageProducer p = session.createProducer(queue); + for (int i = 0; i < 10; i++) { + TextMessage message = session.createTextMessage(); + message.setText("Message:" + i); + p.send(message); + } + + session.commit(); + session.close(); + + Queue queueView = getProxyToQueue(getQueueName()); + + assertTrue("Message didn't arrive on queue", Wait.waitFor(() -> queueView.getMessageCount() == 10)); + } + + @Test(timeout = 60000) + public void testProduceMessageAndRollback() throws Throwable { + Connection connection = createConnection(); + Session session = connection.createSession(true, Session.SESSION_TRANSACTED); + javax.jms.Queue queue = session.createQueue(getQueueName()); + + System.out.println("queue:" + queue.getQueueName()); + MessageProducer p = session.createProducer(queue); + for (int i = 0; i < 10; i++) { + TextMessage message = session.createTextMessage(); + message.setText("Message:" + i); + p.send(message); + } + + session.rollback(); + session.close(); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages arrived on queue", Wait.waitFor(() -> queueView.getMessageCount() == 0)); + } + + @Test(timeout = 60000) + public void testProducedMessageAreRolledBackOnSessionClose() throws Exception { + int numMessages = 10; + + Connection connection = createConnection(); + Session session = connection.createSession(true, Session.SESSION_TRANSACTED); + javax.jms.Queue queue = session.createQueue(getQueueName()); + + MessageProducer p = session.createProducer(queue); + byte[] bytes = new byte[2048]; + new Random().nextBytes(bytes); + for (int i = 0; i < numMessages; i++) { + TextMessage message = session.createTextMessage(); + message.setText("msg:" + i); + p.send(message); + } + + session.close(); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages arrived on queue", Wait.waitFor(() -> queueView.getMessageCount() == 0)); + } + + @Test(timeout = 60000) + public void testConsumeMessagesAndCommit() throws Throwable { + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + + System.out.println("queue:" + queue.getQueueName()); + MessageProducer p = session.createProducer(queue); + for (int i = 0; i < 10; i++) { + TextMessage message = session.createTextMessage(); + message.setText("Message:" + i); + p.send(message); + } + session.close(); + + session = connection.createSession(true, Session.SESSION_TRANSACTED); + MessageConsumer cons = session.createConsumer(queue); + connection.start(); + + for (int i = 0; i < 10; i++) { + TextMessage message = (TextMessage) cons.receive(5000); + Assert.assertNotNull(message); + Assert.assertEquals("Message:" + i, message.getText()); + } + session.commit(); + session.close(); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages not consumed", Wait.waitFor(() -> queueView.getMessageCount() == 0)); + } + + @Test(timeout = 60000) + public void testConsumeMessagesAndRollback() throws Throwable { + Connection connection = createConnection(); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + javax.jms.Queue queue = session.createQueue(getQueueName()); + + MessageProducer p = session.createProducer(queue); + for (int i = 0; i < 10; i++) { + TextMessage message = session.createTextMessage(); + message.setText("Message:" + i); + p.send(message); + } + session.close(); + + session = connection.createSession(true, Session.SESSION_TRANSACTED); + MessageConsumer cons = session.createConsumer(queue); + connection.start(); + + for (int i = 0; i < 10; i++) { + TextMessage message = (TextMessage) cons.receive(5000); + Assert.assertNotNull(message); + Assert.assertEquals("Message:" + i, message.getText()); + } + + session.rollback(); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages consumed", Wait.waitFor(() -> queueView.getMessageCount() == 10)); + } + + @Test(timeout = 60000) + public void testRollbackSomeThenReceiveAndCommit() throws Exception { + final int MSG_COUNT = 5; + final int consumeBeforeRollback = 2; + + Connection connection = createConnection(); + Session session = connection.createSession(true, Session.SESSION_TRANSACTED); + javax.jms.Queue queue = session.createQueue(getQueueName()); + + MessageProducer p = session.createProducer(queue); + for (int i = 0; i < MSG_COUNT; i++) { + TextMessage message = session.createTextMessage(); + message.setText("Message:" + i); + message.setIntProperty("MESSAGE_NUMBER", i + 1); + p.send(message); + } + + session.commit(); + + Queue queueView = getProxyToQueue(getQueueName()); + assertTrue("Messages not enqueued", Wait.waitFor(() -> queueView.getMessageCount() == MSG_COUNT)); + + MessageConsumer consumer = session.createConsumer(queue); + + for (int i = 1; i <= consumeBeforeRollback; i++) { + Message message = consumer.receive(1000); + assertNotNull(message); + assertEquals("Unexpected message number", i, message.getIntProperty("MESSAGE_NUMBER")); + } + + session.rollback(); + + assertEquals(MSG_COUNT, queueView.getMessageCount()); + + // Consume again..check we receive all the messages. + Set messageNumbers = new HashSet<>(); + for (int i = 1; i <= MSG_COUNT; i++) { + messageNumbers.add(i); + } + + for (int i = 1; i <= MSG_COUNT; i++) { + Message message = consumer.receive(1000); + assertNotNull(message); + int msgNum = message.getIntProperty("MESSAGE_NUMBER"); + messageNumbers.remove(msgNum); + } + + session.commit(); + + assertTrue("Did not consume all expected messages, missing messages: " + messageNumbers, messageNumbers.isEmpty()); + assertEquals("Queue should have no messages left after commit", 0, queueView.getMessageCount()); + } +} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonPubSubTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonPubSubTest.java deleted file mode 100644 index 42f30acc3b..0000000000 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonPubSubTest.java +++ /dev/null @@ -1,271 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.activemq.artemis.tests.integration.amqp; - -import javax.jms.Connection; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Session; -import javax.jms.TextMessage; -import javax.jms.Topic; -import javax.jms.TopicConnection; -import javax.jms.TopicSession; -import javax.jms.TopicSubscriber; -import java.util.Map; - -import org.apache.activemq.artemis.api.core.SimpleString; -import org.apache.activemq.artemis.api.core.RoutingType; -import org.apache.activemq.artemis.core.postoffice.Bindings; -import org.apache.activemq.artemis.core.server.impl.AddressInfo; -import org.apache.qpid.jms.JmsConnectionFactory; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class ProtonPubSubTest extends ProtonTestBase { - - private final String prefix = "foo.bar."; - private final String pubAddress = "pubAddress"; - private final String prefixedPubAddress = prefix + "pubAddress"; - private final SimpleString ssPubAddress = new SimpleString(pubAddress); - private final SimpleString ssprefixedPubAddress = new SimpleString(prefixedPubAddress); - private Connection connection; - private JmsConnectionFactory factory; - - @Override - protected void configureAmqp(Map params) { - params.put("pubSubPrefix", prefix); - } - - @Override - @Before - public void setUp() throws Exception { - super.setUp(); - server.addAddressInfo(new AddressInfo(ssPubAddress, RoutingType.MULTICAST)); - server.addAddressInfo(new AddressInfo(ssprefixedPubAddress, RoutingType.MULTICAST)); - server.createQueue(ssPubAddress, RoutingType.MULTICAST, ssPubAddress, new SimpleString("foo=bar"), false, true); - server.createQueue(ssprefixedPubAddress, RoutingType.MULTICAST, ssprefixedPubAddress, new SimpleString("foo=bar"), false, true); - factory = new JmsConnectionFactory("amqp://localhost:5672"); - factory.setClientID("myClientID"); - connection = factory.createConnection(); - connection.setExceptionListener(new ExceptionListener() { - @Override - public void onException(JMSException exception) { - exception.printStackTrace(); - } - }); - - } - - @Override - @After - public void tearDown() throws Exception { - try { - Thread.sleep(250); - if (connection != null) { - connection.close(); - } - } finally { - super.tearDown(); - } - } - - @Test - public void testNonDurablePubSub() throws Exception { - int numMessages = 100; - Topic topic = createTopic(pubAddress); - TopicSession session = ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - MessageConsumer sub = session.createSubscriber(topic); - - Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer producer = sendSession.createProducer(topic); - connection.start(); - for (int i = 0; i < numMessages; i++) { - producer.send(sendSession.createTextMessage("message:" + i)); - } - for (int i = 0; i < numMessages; i++) { - TextMessage receive = (TextMessage) sub.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - } - } - - @Test - public void testNonDurablePubSubQueueDeleted() throws Exception { - int numMessages = 100; - Topic topic = createTopic(pubAddress); - TopicSession session = ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - MessageConsumer sub = session.createSubscriber(topic); - Bindings bindingsForAddress = server.getPostOffice().getBindingsForAddress(new SimpleString(pubAddress)); - assertEquals(2, bindingsForAddress.getBindings().size()); - sub.close(); - Thread.sleep(1000); - assertEquals(1, bindingsForAddress.getBindings().size()); - } - - @Test - public void testNonDurableMultiplePubSub() throws Exception { - int numMessages = 100; - Topic topic = createTopic(pubAddress); - TopicSession session = ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - MessageConsumer sub = session.createSubscriber(topic); - MessageConsumer sub2 = session.createSubscriber(topic); - MessageConsumer sub3 = session.createSubscriber(topic); - - Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer producer = sendSession.createProducer(topic); - connection.start(); - for (int i = 0; i < numMessages; i++) { - producer.send(sendSession.createTextMessage("message:" + i)); - } - for (int i = 0; i < numMessages; i++) { - TextMessage receive = (TextMessage) sub.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - receive = (TextMessage) sub2.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - receive = (TextMessage) sub3.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - } - } - - @Test - public void testDurablePubSub() throws Exception { - int numMessages = 100; - Topic topic = createTopic(pubAddress); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId"); - - Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer producer = sendSession.createProducer(topic); - connection.start(); - for (int i = 0; i < numMessages; i++) { - producer.send(sendSession.createTextMessage("message:" + i)); - } - for (int i = 0; i < numMessages; i++) { - TextMessage receive = (TextMessage) sub.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - } - } - - @Test - public void testDurableMultiplePubSub() throws Exception { - int numMessages = 100; - Topic topic = createTopic(pubAddress); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId"); - TopicSubscriber sub2 = session.createDurableSubscriber(topic, "myPubId2"); - TopicSubscriber sub3 = session.createDurableSubscriber(topic, "myPubId3"); - - Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer producer = sendSession.createProducer(topic); - connection.start(); - for (int i = 0; i < numMessages; i++) { - producer.send(sendSession.createTextMessage("message:" + i)); - } - for (int i = 0; i < numMessages; i++) { - TextMessage receive = (TextMessage) sub.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - receive = (TextMessage) sub2.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - receive = (TextMessage) sub3.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - } - } - - @Test - public void testDurablePubSubReconnect() throws Exception { - int numMessages = 100; - Topic topic = createTopic(pubAddress); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId"); - - Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer producer = sendSession.createProducer(topic); - connection.start(); - for (int i = 0; i < numMessages; i++) { - producer.send(sendSession.createTextMessage("message:" + i)); - } - for (int i = 0; i < numMessages; i++) { - TextMessage receive = (TextMessage) sub.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - } - connection.close(); - connection = factory.createConnection(); - connection.setExceptionListener(new ExceptionListener() { - @Override - public void onException(JMSException exception) { - exception.printStackTrace(); - } - }); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - sub = session.createDurableSubscriber(topic, "myPubId"); - - sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - producer = sendSession.createProducer(topic); - connection.start(); - for (int i = 0; i < numMessages; i++) { - producer.send(sendSession.createTextMessage("message:" + i)); - } - for (int i = 0; i < numMessages; i++) { - TextMessage receive = (TextMessage) sub.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - } - } - - @Test - public void testDurablePubSubUnsubscribe() throws Exception { - int numMessages = 100; - Topic topic = createTopic(pubAddress); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId"); - - Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer producer = sendSession.createProducer(topic); - connection.start(); - for (int i = 0; i < numMessages; i++) { - producer.send(sendSession.createTextMessage("message:" + i)); - } - for (int i = 0; i < numMessages; i++) { - TextMessage receive = (TextMessage) sub.receive(5000); - Assert.assertNotNull(receive); - Assert.assertEquals(receive.getText(), "message:" + i); - } - sub.close(); - session.unsubscribe("myPubId"); - } - - private javax.jms.Topic createTopic(String address) throws Exception { - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - try { - return session.createTopic(address); - } finally { - session.close(); - } - } -} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTest.java deleted file mode 100644 index 7933fecae1..0000000000 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTest.java +++ /dev/null @@ -1,1788 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.activemq.artemis.tests.integration.amqp; - -import java.io.IOException; -import java.io.Serializable; -import java.net.URI; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Optional; -import java.util.Random; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.jms.BytesMessage; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.DeliveryMode; -import javax.jms.Destination; -import javax.jms.ExceptionListener; -import javax.jms.InvalidClientIDException; -import javax.jms.JMSException; -import javax.jms.MapMessage; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.ObjectMessage; -import javax.jms.QueueBrowser; -import javax.jms.ResourceAllocationException; -import javax.jms.Session; -import javax.jms.StreamMessage; -import javax.jms.TemporaryQueue; -import javax.jms.TextMessage; -import javax.jms.Topic; -import javax.jms.TopicPublisher; -import javax.jms.TopicSession; -import javax.jms.TopicSubscriber; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; - -import org.apache.activemq.artemis.api.core.RoutingType; -import org.apache.activemq.artemis.api.core.SimpleString; -import org.apache.activemq.artemis.api.core.management.AddressControl; -import org.apache.activemq.artemis.core.config.Configuration; -import org.apache.activemq.artemis.core.postoffice.Bindings; -import org.apache.activemq.artemis.core.remoting.CloseListener; -import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector; -import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants; -import org.apache.activemq.artemis.core.server.ActiveMQServer; -import org.apache.activemq.artemis.core.server.Queue; -import org.apache.activemq.artemis.core.server.impl.AddressInfo; -import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy; -import org.apache.activemq.artemis.core.settings.impl.AddressSettings; -import org.apache.activemq.artemis.protocol.amqp.broker.ProtonProtocolManagerFactory; -import org.apache.activemq.artemis.protocol.amqp.client.AMQPClientConnectionFactory; -import org.apache.activemq.artemis.protocol.amqp.client.ProtonClientConnectionManager; -import org.apache.activemq.artemis.protocol.amqp.client.ProtonClientProtocolManager; -import org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport; -import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; -import org.apache.activemq.artemis.tests.integration.management.ManagementControlHelper; -import org.apache.activemq.artemis.tests.util.Wait; -import org.apache.activemq.artemis.utils.Base64; -import org.apache.activemq.artemis.utils.ByteUtil; -import org.apache.activemq.artemis.utils.RandomUtil; -import org.apache.activemq.artemis.utils.TimeUtils; -import org.apache.activemq.artemis.utils.UUIDGenerator; -import org.apache.activemq.transport.amqp.client.AmqpClient; -import org.apache.activemq.transport.amqp.client.AmqpConnection; -import org.apache.activemq.transport.amqp.client.AmqpMessage; -import org.apache.activemq.transport.amqp.client.AmqpReceiver; -import org.apache.activemq.transport.amqp.client.AmqpSender; -import org.apache.activemq.transport.amqp.client.AmqpSession; -import org.apache.qpid.jms.JmsConnectionFactory; -import org.apache.qpid.proton.amqp.Symbol; -import org.apache.qpid.proton.amqp.messaging.Source; -import org.apache.qpid.proton.amqp.messaging.TerminusDurability; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -@RunWith(Parameterized.class) -public class ProtonTest extends ProtonTestBase { - - private static final String amqpConnectionUri = "amqp://localhost:5672"; - - private static final String tcpAmqpConnectionUri = "tcp://localhost:5672"; - - private static final long maxSizeBytes = 1 * 1024 * 1024; - - private static final long maxSizeBytesRejectThreshold = 2 * 1024 * 1024; - - private MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer(); - - private int messagesSent = 0; - - // this will ensure that all tests in this class are run twice, - // once with "true" passed to the class' constructor and once with "false" - @Parameterized.Parameters(name = "{0}") - public static Collection getParameters() { - - // these 3 are for comparison - return Arrays.asList(new Object[][]{{"AMQP", 0}, {"AMQP_ANONYMOUS", 3}}); - } - - - ConnectionFactory factory; - - private final int protocol; - - public ProtonTest(String name, int protocol) { - this.coreAddress = "exampleQueue"; - this.protocol = protocol; - if (protocol == 0 || protocol == 3) { - this.address = coreAddress; - } else { - this.address = "exampleQueue"; - } - } - - private final String coreAddress; - private final String address; - private Connection connection; - - - @Override - protected ActiveMQServer createAMQPServer(int port) throws Exception { - ActiveMQServer server = super.createAMQPServer(port); - server.getConfiguration().addAcceptorConfiguration("flow", "tcp://localhost:" + (8 + port) + "?protocols=AMQP;useEpoll=false;amqpCredits=1;amqpMinCredits=1"); - server.setMBeanServer(mBeanServer); - server.getConfiguration().setJMXManagementEnabled(true); - return server; - } - - @Override - @Before - public void setUp() throws Exception { - super.setUp(); - - Configuration serverConfig = server.getConfiguration(); - Map settings = serverConfig.getAddressesSettings(); - assertNotNull(settings); - AddressSettings addressSetting = settings.get("#"); - if (addressSetting == null) { - addressSetting = new AddressSettings(); - settings.put("#", addressSetting); - } - addressSetting.setAutoCreateQueues(false); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "1"), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "2"), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "3"), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "4"), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "5"), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "6"), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "7"), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "8"), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "9"), RoutingType.ANYCAST)); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(coreAddress + "10"), RoutingType.ANYCAST)); - server.createQueue(new SimpleString(coreAddress), RoutingType.ANYCAST, new SimpleString(coreAddress), null, true, false); - server.createQueue(new SimpleString(coreAddress + "1"), RoutingType.ANYCAST, new SimpleString(coreAddress + "1"), null, true, false); - server.createQueue(new SimpleString(coreAddress + "2"), RoutingType.ANYCAST, new SimpleString(coreAddress + "2"), null, true, false); - server.createQueue(new SimpleString(coreAddress + "3"), RoutingType.ANYCAST, new SimpleString(coreAddress + "3"), null, true, false); - server.createQueue(new SimpleString(coreAddress + "4"), RoutingType.ANYCAST, new SimpleString(coreAddress + "4"), null, true, false); - server.createQueue(new SimpleString(coreAddress + "5"), RoutingType.ANYCAST, new SimpleString(coreAddress + "5"), null, true, false); - server.createQueue(new SimpleString(coreAddress + "6"), RoutingType.ANYCAST, new SimpleString(coreAddress + "6"), null, true, false); - server.createQueue(new SimpleString(coreAddress + "7"), RoutingType.ANYCAST, new SimpleString(coreAddress + "7"), null, true, false); - server.createQueue(new SimpleString(coreAddress + "8"), RoutingType.ANYCAST, new SimpleString(coreAddress + "8"), null, true, false); - server.createQueue(new SimpleString(coreAddress + "9"), RoutingType.ANYCAST, new SimpleString(coreAddress + "9"), null, true, false); - server.createQueue(new SimpleString(coreAddress + "10"), RoutingType.ANYCAST, new SimpleString(coreAddress + "10"), null, true, false); - server.addAddressInfo(new AddressInfo(new SimpleString("amqp_testtopic"), RoutingType.MULTICAST)); - server.createQueue(new SimpleString("amqp_testtopic"), RoutingType.MULTICAST, new SimpleString("amqp_testtopic"), null, true, false); - /* server.createQueue(new SimpleString("amqp_testtopic" + "1"), new SimpleString("amqp_testtopic" + "1"), null, true, false); - server.createQueue(new SimpleString("amqp_testtopic" + "2"), new SimpleString("amqp_testtopic" + "2"), null, true, false); - server.createQueue(new SimpleString("amqp_testtopic" + "3"), new SimpleString("amqp_testtopic" + "3"), null, true, false); - server.createQueue(new SimpleString("amqp_testtopic" + "4"), new SimpleString("amqp_testtopic" + "4"), null, true, false); - server.createQueue(new SimpleString("amqp_testtopic" + "5"), new SimpleString("amqp_testtopic" + "5"), null, true, false); - server.createQueue(new SimpleString("amqp_testtopic" + "6"), new SimpleString("amqp_testtopic" + "6"), null, true, false); - server.createQueue(new SimpleString("amqp_testtopic" + "7"), new SimpleString("amqp_testtopic" + "7"), null, true, false); - server.createQueue(new SimpleString("amqp_testtopic" + "8"), new SimpleString("amqp_testtopic" + "8"), null, true, false); - server.createQueue(new SimpleString("amqp_testtopic" + "9"), new SimpleString("amqp_testtopic" + "9"), null, true, false); - server.createQueue(new SimpleString("amqp_testtopic" + "10"), new SimpleString("amqp_testtopic" + "10"), null, true, false);*/ - - connection = createConnection(); - - } - - @Override - @After - public void tearDown() throws Exception { - try { - Thread.sleep(250); - if (connection != null) { - connection.close(); - } - } finally { - super.tearDown(); - } - } - - @Test - public void testSendAndReceiveOnTopic() throws Exception { - Connection connection = createConnection("myClientId"); - try { - TopicSession session = (TopicSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - Topic topic = session.createTopic("amqp_testtopic"); - TopicSubscriber consumer = session.createSubscriber(topic); - TopicPublisher producer = session.createPublisher(topic); - - TextMessage message = session.createTextMessage("test-message"); - producer.send(message); - - producer.close(); - - connection.start(); - - message = (TextMessage) consumer.receive(1000); - assertNotNull(message); - assertNotNull(message.getText()); - } finally { - if (connection != null) { - connection.close(); - } - } - } - - @Test - public void testAddressControlSendMessage() throws Exception { - SimpleString address = RandomUtil.randomSimpleString(); - server.createQueue(address, RoutingType.ANYCAST, address, null, true, false); - - AddressControl addressControl = ManagementControlHelper.createAddressControl(address, mBeanServer); - Assert.assertEquals(1, addressControl.getQueueNames().length); - addressControl.sendMessage(null, org.apache.activemq.artemis.api.core.Message.BYTES_TYPE, Base64.encodeBytes("test".getBytes()), false, userName, password); - - Wait.waitFor(() -> addressControl.getMessageCount() == 1); - - Assert.assertEquals(1, addressControl.getMessageCount()); - - Connection connection = createConnection("myClientId"); - try { - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - javax.jms.Queue queue = session.createQueue(address.toString()); - MessageConsumer consumer = session.createConsumer(queue); - Message message = consumer.receive(500); - assertNotNull(message); - byte[] buffer = new byte[(int)((BytesMessage)message).getBodyLength()]; - ((BytesMessage)message).readBytes(buffer); - assertEquals("test", new String(buffer)); - session.close(); - connection.close(); - } finally { - if (connection != null) { - connection.close(); - } - } - } - - @Test - public void testAddressControlSendMessageWithText() throws Exception { - SimpleString address = RandomUtil.randomSimpleString(); - server.createQueue(address, RoutingType.ANYCAST, address, null, true, false); - - AddressControl addressControl = ManagementControlHelper.createAddressControl(address, mBeanServer); - Assert.assertEquals(1, addressControl.getQueueNames().length); - addressControl.sendMessage(null, org.apache.activemq.artemis.api.core.Message.TEXT_TYPE, "test", false, userName, password); - - Wait.waitFor(() -> addressControl.getMessageCount() == 1); - - Assert.assertEquals(1, addressControl.getMessageCount()); - - Connection connection = createConnection("myClientId"); - try { - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - javax.jms.Queue queue = session.createQueue(address.toString()); - MessageConsumer consumer = session.createConsumer(queue); - Message message = consumer.receive(500); - assertNotNull(message); - String text = ((TextMessage) message).getText(); - assertEquals("test", text); - session.close(); - connection.close(); - } finally { - if (connection != null) { - connection.close(); - } - } - } - - @Test - public void testDurableSubscriptionUnsubscribe() throws Exception { - Connection connection = createConnection("myClientId"); - try { - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - Topic topic = session.createTopic("amqp_testtopic"); - TopicSubscriber myDurSub = session.createDurableSubscriber(topic, "myDurSub"); - session.close(); - connection.close(); - connection = createConnection("myClientId"); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - myDurSub = session.createDurableSubscriber(topic, "myDurSub"); - myDurSub.close(); - Assert.assertNotNull(server.getPostOffice().getBinding(new SimpleString("myClientId.myDurSub"))); - session.unsubscribe("myDurSub"); - Assert.assertNull(server.getPostOffice().getBinding(new SimpleString("myClientId.myDurSub"))); - session.close(); - connection.close(); - } finally { - if (connection != null) { - connection.close(); - } - } - } - - @Test - public void testTemporarySubscriptionDeleted() throws Exception { - try { - TopicSession session = (TopicSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - Topic topic = session.createTopic("amqp_testtopic"); - TopicSubscriber myDurSub = session.createSubscriber(topic); - Bindings bindingsForAddress = server.getPostOffice().getBindingsForAddress(new SimpleString("amqp_testtopic")); - Assert.assertEquals(2, bindingsForAddress.getBindings().size()); - session.close(); - final CountDownLatch latch = new CountDownLatch(1); - server.getRemotingService().getConnections().iterator().next().addCloseListener(new CloseListener() { - @Override - public void connectionClosed() { - latch.countDown(); - } - }); - connection.close(); - latch.await(5, TimeUnit.SECONDS); - bindingsForAddress = server.getPostOffice().getBindingsForAddress(new SimpleString("amqp_testtopic")); - Assert.assertEquals(1, bindingsForAddress.getBindings().size()); - } finally { - if (connection != null) { - connection.close(); - } - } - } - - @Test - public void testCreditsAreAllocatedOnlyOnceOnLinkCreate() throws Exception { - - String destinationAddress = address + 1; - AmqpClient client = new AmqpClient(new URI("tcp://localhost:5680"), userName, password); - AmqpConnection amqpConnection = client.connect(); - try { - AmqpSession session = amqpConnection.createSession(); - AmqpSender sender = session.createSender(destinationAddress); - assertTrue(sender.getSender().getCredit() == 1); - } finally { - amqpConnection.close(); - } - } - - @Test - public void testTemporaryQueue() throws Throwable { - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - TemporaryQueue queue = session.createTemporaryQueue(); - System.out.println("queue:" + queue.getQueueName()); - MessageProducer p = session.createProducer(queue); - - TextMessage message = session.createTextMessage(); - message.setText("Message temporary"); - p.send(message); - - MessageConsumer cons = session.createConsumer(queue); - connection.start(); - - message = (TextMessage) cons.receive(5000); - Assert.assertNotNull(message); - } - - @Test - public void testCommitProducer() throws Throwable { - - Session session = connection.createSession(true, Session.SESSION_TRANSACTED); - javax.jms.Queue queue = createQueue(address); - System.out.println("queue:" + queue.getQueueName()); - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < 10; i++) { - TextMessage message = session.createTextMessage(); - message.setText("Message:" + i); - p.send(message); - } - session.commit(); - session.close(); - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - //because tx commit is executed async on broker, we use a timed wait. - assertTrue(TimeUtils.waitOnBoolean(true, 10000, () -> q.getMessageCount() == 10)); - } - - @Test - public void testRollbackProducer() throws Throwable { - - Session session = connection.createSession(true, Session.SESSION_TRANSACTED); - javax.jms.Queue queue = createQueue(address); - System.out.println("queue:" + queue.getQueueName()); - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < 10; i++) { - TextMessage message = session.createTextMessage(); - message.setText("Message:" + i); - p.send(message); - } - session.rollback(); - session.close(); - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - Assert.assertEquals(q.getMessageCount(), 0); - } - - @Test - public void testCommitConsumer() throws Throwable { - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - javax.jms.Queue queue = createQueue(address); - System.out.println("queue:" + queue.getQueueName()); - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < 10; i++) { - TextMessage message = session.createTextMessage(); - message.setText("Message:" + i); - p.send(message); - } - session.close(); - - session = connection.createSession(true, Session.SESSION_TRANSACTED); - MessageConsumer cons = session.createConsumer(queue); - connection.start(); - - for (int i = 0; i < 10; i++) { - TextMessage message = (TextMessage) cons.receive(5000); - Assert.assertNotNull(message); - Assert.assertEquals("Message:" + i, message.getText()); - } - session.commit(); - session.close(); - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - Assert.assertEquals(q.getMessageCount(), 0); - } - - @Test - public void testRollbackConsumer() throws Throwable { - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - javax.jms.Queue queue = createQueue(address); - System.out.println("queue:" + queue.getQueueName()); - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < 10; i++) { - TextMessage message = session.createTextMessage(); - message.setText("Message:" + i); - p.send(message); - } - session.close(); - - session = connection.createSession(true, Session.SESSION_TRANSACTED); - MessageConsumer cons = session.createConsumer(queue); - connection.start(); - - for (int i = 0; i < 10; i++) { - TextMessage message = (TextMessage) cons.receive(5000); - Assert.assertNotNull(message); - Assert.assertEquals("Message:" + i, message.getText()); - } - session.rollback(); - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - //because tx rollback is executed async on broker, we use a timed wait. - assertTrue(TimeUtils.waitOnBoolean(true, 10000, () -> q.getMessageCount() == 10)); - - } - - @Test - public void testObjectMessage() throws Throwable { - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - javax.jms.Queue queue = createQueue(address); - MessageProducer p = session.createProducer(queue); - ArrayList list = new ArrayList<>(); - list.add("aString"); - ObjectMessage objectMessage = session.createObjectMessage(list); - p.send(objectMessage); - session.close(); - - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageConsumer cons = session.createConsumer(queue); - connection.start(); - - objectMessage = (ObjectMessage) cons.receive(5000); - assertNotNull(objectMessage); - list = (ArrayList) objectMessage.getObject(); - assertEquals(list.get(0), "aString"); - connection.close(); - } - - @Test - public void testResourceLimitExceptionOnAddressFull() throws Exception { - setAddressFullBlockPolicy(); - String destinationAddress = address + 1; - fillAddress(destinationAddress); - - long addressSize = server.getPagingManager().getPageStore(new SimpleString(destinationAddress)).getAddressSize(); - assertTrue(addressSize >= maxSizeBytesRejectThreshold); - } - - @Test - public void testAddressIsBlockedForOtherProdudersWhenFull() throws Exception { - setAddressFullBlockPolicy(); - - String destinationAddress = address + 1; - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - Destination d = session.createQueue(destinationAddress); - MessageProducer p = session.createProducer(d); - - fillAddress(destinationAddress); - - Exception e = null; - try { - p.send(session.createBytesMessage()); - } catch (ResourceAllocationException rae) { - e = rae; - } - assertTrue(e instanceof ResourceAllocationException); - assertTrue(e.getMessage().contains("resource-limit-exceeded")); - - long addressSize = server.getPagingManager().getPageStore(new SimpleString(destinationAddress)).getAddressSize(); - assertTrue(addressSize >= maxSizeBytesRejectThreshold); - } - - @Test(timeout = 10000) - public void testCreditsAreNotAllocatedWhenAddressIsFull() throws Exception { - setAddressFullBlockPolicy(); - - - String destinationAddress = address + 1; - AmqpClient client = new AmqpClient(new URI("tcp://localhost:5680"), userName, password); - AmqpConnection amqpConnection = client.connect(); - try { - AmqpSession session = amqpConnection.createSession(); - AmqpSender sender = session.createSender(destinationAddress); - - // Use blocking send to ensure buffered messages do not interfere with credit. - sender.setSendTimeout(-1); - sendUntilFull(sender); - - // This should be -1. A single message is buffered in the client, and 0 credit has been allocated. - assertTrue(sender.getSender().getCredit() == -1); - - long addressSize = server.getPagingManager().getPageStore(new SimpleString(destinationAddress)).getAddressSize(); - assertTrue(addressSize >= maxSizeBytes && addressSize <= maxSizeBytesRejectThreshold); - } finally { - amqpConnection.close(); - } - } - - @Test - public void testCreditsAreRefreshedWhenAddressIsUnblocked() throws Exception { - setAddressFullBlockPolicy(); - - String destinationAddress = address + 1; - fillAddress(destinationAddress); - - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - AmqpConnection amqpConnection = client.connect(); - try { - AmqpSession session = amqpConnection.createSession(); - AmqpSender sender = session.createSender(destinationAddress); - - // Wait for a potential flow frame. - Thread.sleep(500); - assertEquals(0, sender.getSender().getCredit()); - - // Empty Address except for 1 message used later. - AmqpReceiver receiver = session.createReceiver(destinationAddress); - receiver.flow(100); - - AmqpMessage m; - for (int i = 0; i < messagesSent - 1; i++) { - m = receiver.receive(5000, TimeUnit.MILLISECONDS); - m.accept(); - } - - // Wait for address to unblock and flow frame to arrive - Thread.sleep(500); - - assertTrue(sender.getSender().getCredit() >= 0); - } finally { - amqpConnection.close(); - } - } - - @Test - public void testNewLinkAttachAreNotAllocatedCreditsWhenAddressIsBlocked() throws Exception { - setAddressFullBlockPolicy(); - - fillAddress(address + 1); - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - AmqpConnection amqpConnection = client.connect(); - try { - AmqpSession session = amqpConnection.createSession(); - AmqpSender sender = session.createSender(address + 1); - // Wait for a potential flow frame. - Thread.sleep(1000); - assertEquals(0, sender.getSender().getCredit()); - } finally { - amqpConnection.close(); - } - } - - @Test - public void testTxIsRolledBackOnRejectedPreSettledMessage() throws Throwable { - setAddressFullBlockPolicy(); - - // Create the link attach before filling the address to ensure the link is allocated credit. - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - AmqpConnection amqpConnection = client.connect(); - - AmqpSession session = amqpConnection.createSession(); - AmqpSender sender = session.createSender(address); - sender.setPresettle(true); - - fillAddress(address); - - final AmqpMessage message = new AmqpMessage(); - byte[] payload = new byte[50 * 1024]; - message.setBytes(payload); - - Exception expectedException = null; - try { - session.begin(); - sender.send(message); - session.commit(); - } catch (Exception e) { - expectedException = e; - } finally { - amqpConnection.close(); - } - - assertNotNull(expectedException); - assertTrue(expectedException.getMessage().contains("resource-limit-exceeded")); - assertTrue(expectedException.getMessage().contains("Address is full: " + address)); - } - - /** - * Fills an address. Careful when using this method. Only use when rejected messages are switched on. - * - * @param address - * @return - * @throws Exception - */ - private void fillAddress(String address) throws Exception { - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - AmqpConnection amqpConnection = client.connect(); - Exception exception = null; - try { - AmqpSession session = amqpConnection.createSession(); - AmqpSender sender = session.createSender(address); - sendUntilFull(sender); - } catch (Exception e) { - exception = e; - } finally { - amqpConnection.close(); - } - - // Should receive a rejected error - assertNotNull(exception); - assertTrue(exception.getMessage().contains("amqp:resource-limit-exceeded")); - } - - private void sendUntilFull(final AmqpSender sender) throws Exception { - final AmqpMessage message = new AmqpMessage(); - byte[] payload = new byte[50 * 1024]; - message.setBytes(payload); - - final int maxMessages = 50; - final AtomicInteger sentMessages = new AtomicInteger(0); - final Exception[] errors = new Exception[1]; - final CountDownLatch timeout = new CountDownLatch(1); - - Runnable sendMessages = new Runnable() { - @Override - public void run() { - try { - for (int i = 0; i < maxMessages; i++) { - sender.send(message); - System.out.println("Sent " + i); - sentMessages.getAndIncrement(); - } - timeout.countDown(); - } catch (IOException e) { - errors[0] = e; - } - } - }; - - Thread t = new Thread(sendMessages); - - try { - t.start(); - - timeout.await(1, TimeUnit.SECONDS); - - messagesSent = sentMessages.get(); - if (errors[0] != null) { - throw errors[0]; - } - } finally { - t.interrupt(); - t.join(1000); - Assert.assertFalse(t.isAlive()); - } - } - - @Test - public void testLinkDetatchErrorIsCorrectWhenQueueDoesNotExists() throws Exception { - AddressSettings value = new AddressSettings(); - value.setAutoCreateJmsQueues(false); - value.setAutoCreateQueues(false); - value.setAutoCreateAddresses(false); - value.setAutoCreateJmsTopics(false); - server.getAddressSettingsRepository().addMatch("AnAddressThatDoesNotExist", value); - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - AmqpConnection amqpConnection = client.connect(); - AmqpSession session = amqpConnection.createSession(); - - Exception expectedException = null; - try { - session.createSender("AnAddressThatDoesNotExist"); - fail("Creating a sender here on an address that doesn't exist should fail"); - } catch (Exception e) { - expectedException = e; - } - - assertNotNull(expectedException); - assertTrue(expectedException.getMessage().contains("amqp:not-found")); - assertTrue(expectedException.getMessage().contains("target address does not exist")); - amqpConnection.close(); - } - - @Test - public void testLinkDetachSentWhenQueueDeleted() throws Exception { - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - final AmqpConnection amqpConnection = client.connect(); - try { - AmqpSession session = amqpConnection.createSession(); - - AmqpReceiver receiver = session.createReceiver(coreAddress); - server.destroyQueue(new SimpleString(coreAddress), null, false, true); - - Wait.waitFor(receiver::isClosed); - assertTrue(receiver.isClosed()); - } finally { - amqpConnection.close(); - } - } - - @Test - public void testCloseIsSentOnConnectionClose() throws Exception { - connection.close(); - - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - final AmqpConnection amqpConnection = client.connect(); - try { - for (RemotingConnection connection : server.getRemotingService().getConnections()) { - server.getRemotingService().removeConnection(connection); - connection.disconnect(true); - } - - Wait.waitFor(amqpConnection::isClosed); - - assertTrue(amqpConnection.isClosed()); - assertEquals(AmqpSupport.CONNECTION_FORCED, amqpConnection.getConnection().getRemoteCondition().getCondition()); - } finally { - amqpConnection.close(); - } - } - - - @Test - public void testClientIdIsSetInSubscriptionList() throws Exception { - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString("mytopic"), RoutingType.ANYCAST)); - AmqpConnection amqpConnection = client.createConnection(); - amqpConnection.setContainerId("testClient"); - amqpConnection.setOfferedCapabilities(Arrays.asList(Symbol.getSymbol("topic"))); - amqpConnection.connect(); - try { - AmqpSession session = amqpConnection.createSession(); - - Source source = new Source(); - source.setDurable(TerminusDurability.UNSETTLED_STATE); - source.setCapabilities(Symbol.getSymbol("topic")); - source.setAddress("mytopic"); - AmqpReceiver receiver = session.createReceiver(source, "testSub"); - - SimpleString fo = new SimpleString("testClient.testSub:mytopic"); - assertNotNull(server.locateQueue(fo)); - - } catch (Exception e) { - e.printStackTrace(); - } finally { - amqpConnection.close(); - } - } - - @Test - public void testSendingAndReceivingToQueueWithDifferentAddressAndQueueName() throws Exception { - - String queueName = "TestQueueName"; - String address = "TestAddress"; - server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(address), RoutingType.ANYCAST)); - server.createQueue(new SimpleString(address), RoutingType.ANYCAST, new SimpleString(queueName), null, true, false); - - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - AmqpConnection amqpConnection = client.connect(); - AmqpSession session = amqpConnection.createSession(); - AmqpSender sender = session.createSender(address); - AmqpReceiver receiver = session.createReceiver(address); - receiver.flow(1); - - AmqpMessage message = new AmqpMessage(); - message.setText("TestPayload"); - sender.send(message); - - AmqpMessage receivedMessage = receiver.receive(5000, TimeUnit.MILLISECONDS); - assertNotNull(receivedMessage); - amqpConnection.close(); - } - - @Test - public void testReplyTo() throws Throwable { - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - TemporaryQueue queue = session.createTemporaryQueue(); - MessageProducer p = session.createProducer(queue); - - TextMessage message = session.createTextMessage(); - message.setText("Message temporary"); - message.setJMSReplyTo(createQueue(address)); - p.send(message); - - MessageConsumer cons = session.createConsumer(queue); - connection.start(); - - message = (TextMessage) cons.receive(5000); - assertNotNull(message); - Destination jmsReplyTo = message.getJMSReplyTo(); - Assert.assertNotNull(jmsReplyTo); - Assert.assertNotNull(message); - } - - @Test - public void testReplyToNonJMS() throws Throwable { - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - TemporaryQueue queue = session.createTemporaryQueue(); - System.out.println("queue:" + queue.getQueueName()); - MessageProducer p = session.createProducer(queue); - - TextMessage message = session.createTextMessage(); - message.setText("Message temporary"); - message.setJMSReplyTo(createQueue("someaddress")); - p.send(message); - - MessageConsumer cons = session.createConsumer(queue); - connection.start(); - - message = (TextMessage) cons.receive(5000); - Destination jmsReplyTo = message.getJMSReplyTo(); - Assert.assertNotNull(jmsReplyTo); - Assert.assertNotNull(message); - - } - - @Test - public void testOutboundConnection() throws Throwable { - final ActiveMQServer remote = createAMQPServer(5673); - remote.start(); - try { - Wait.waitFor(remote::isActive); - } catch (Exception e) { - remote.stop(); - throw e; - } - - final Map config = new LinkedHashMap<>(); - config.put(TransportConstants.HOST_PROP_NAME, "localhost"); - config.put(TransportConstants.PORT_PROP_NAME, "5673"); - ProtonClientConnectionManager lifeCycleListener = new ProtonClientConnectionManager(new AMQPClientConnectionFactory(server, "myid", Collections.singletonMap(Symbol.getSymbol("myprop"), "propvalue"), 5000), Optional.empty()); - ProtonClientProtocolManager protocolManager = new ProtonClientProtocolManager(new ProtonProtocolManagerFactory(), server); - NettyConnector connector = new NettyConnector(config, lifeCycleListener, lifeCycleListener, server.getExecutorFactory().getExecutor(), server.getExecutorFactory().getExecutor(), server.getScheduledPool(), protocolManager); - connector.start(); - connector.createConnection(); - - try { - Wait.waitFor(new Wait.Condition() { - @Override - public boolean isSatisfied() throws Exception { - return remote.getConnectionCount() > 0; - } - }); - assertEquals(1, remote.getConnectionCount()); - - lifeCycleListener.stop(); - Wait.waitFor(new Wait.Condition() { - @Override - public boolean isSatisfied() throws Exception { - return remote.getConnectionCount() == 0; - } - }); - assertEquals(0, remote.getConnectionCount()); - } finally { - lifeCycleListener.stop(); - remote.stop(); - } - } - - /* - // Uncomment testLoopBrowser to validate the hunging on the test - @Test - public void testLoopBrowser() throws Throwable { - for (int i = 0 ; i < 1000; i++) { - System.out.println("#test " + i); - testBrowser(); - tearDown(); - setUp(); - } - } */ - - /** - * This test eventually fails because of: https://issues.apache.org/jira/browse/QPID-4901 - * - * @throws Throwable - */ - //@Test // TODO: re-enable this when we can get a version free of QPID-4901 bug - public void testBrowser() throws Throwable { - - boolean success = false; - - for (int i = 0; i < 10; i++) { - // As this test was hunging, we added a protection here to fail it instead. - // it seems something on the qpid client, so this failure belongs to them and we can ignore it on - // our side (ActiveMQ) - success = runWithTimeout(new RunnerWithEX() { - @Override - public void run() throws Throwable { - int numMessages = 50; - javax.jms.Queue queue = createQueue(address); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < numMessages; i++) { - TextMessage message = session.createTextMessage(); - message.setText("msg:" + i); - p.send(message); - } - - connection.close(); - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - - connection = createConnection(); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - QueueBrowser browser = session.createBrowser(queue); - Enumeration enumeration = browser.getEnumeration(); - int count = 0; - while (enumeration.hasMoreElements()) { - Message msg = (Message) enumeration.nextElement(); - Assert.assertNotNull("" + count, msg); - Assert.assertTrue("" + msg, msg instanceof TextMessage); - String text = ((TextMessage) msg).getText(); - Assert.assertEquals(text, "msg:" + count++); - } - Assert.assertEquals(count, numMessages); - connection.close(); - Assert.assertEquals(getMessageCount(q), numMessages); - } - }, 5000); - - if (success) { - break; - } else { - System.err.println("Had to make it fail!!!"); - tearDown(); - setUp(); - } - } - - // There is a bug on the qpid client library currently, we can expect having to interrupt the thread on browsers. - // but we can't have it on 10 iterations... something must be broken if that's the case - Assert.assertTrue("Test had to interrupt on all occasions.. this is beyond the expected for the test", success); - } - - @Test - public void testConnection() throws Exception { - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - MessageConsumer cons = session.createConsumer(createQueue(address)); - - org.apache.activemq.artemis.core.server.Queue serverQueue = server.locateQueue(SimpleString.toSimpleString(coreAddress)); - - assertEquals(1, serverQueue.getConsumerCount()); - - cons.close(); - - for (int i = 0; i < 100 && serverQueue.getConsumerCount() != 0; i++) { - Thread.sleep(500); - } - - assertEquals(0, serverQueue.getConsumerCount()); - - session.close(); - - } - - @Test - public void testMessagesSentTransactional() throws Exception { - int numMessages = 1000; - javax.jms.Queue queue = createQueue(address); - Session session = connection.createSession(true, Session.SESSION_TRANSACTED); - MessageProducer p = session.createProducer(queue); - byte[] bytes = new byte[2048]; - new Random().nextBytes(bytes); - for (int i = 0; i < numMessages; i++) { - TextMessage message = session.createTextMessage(); - message.setText("msg:" + i); - p.send(message); - } - session.commit(); - connection.close(); - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(q) != numMessages; ) { - Thread.sleep(1); - } - Assert.assertEquals(numMessages, getMessageCount(q)); - } - - @Test - public void testMessagesSentTransactionalRolledBack() throws Exception { - int numMessages = 1; - javax.jms.Queue queue = createQueue(address); - Session session = connection.createSession(true, Session.SESSION_TRANSACTED); - MessageProducer p = session.createProducer(queue); - byte[] bytes = new byte[2048]; - new Random().nextBytes(bytes); - for (int i = 0; i < numMessages; i++) { - TextMessage message = session.createTextMessage(); - message.setText("msg:" + i); - p.send(message); - } - session.close(); - connection.close(); - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - Assert.assertEquals(getMessageCount(q), 0); - } - - @Test - public void testCancelMessages() throws Exception { - int numMessages = 10; - long time = System.currentTimeMillis(); - javax.jms.Queue queue = createQueue(address); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer p = session.createProducer(queue); - byte[] bytes = new byte[2048]; - new Random().nextBytes(bytes); - for (int i = 0; i < numMessages; i++) { - TextMessage message = session.createTextMessage(); - message.setText("msg:" + i); - p.send(message); - } - connection.close(); - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - - for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(q) != numMessages; ) { - Thread.sleep(1); - } - - Assert.assertEquals(numMessages, getMessageCount(q)); - //now create a new connection and receive - connection = createConnection(); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageConsumer consumer = session.createConsumer(queue); - Thread.sleep(100); - consumer.close(); - connection.close(); - Assert.assertEquals(numMessages, getMessageCount(q)); - long taken = (System.currentTimeMillis() - time) / 1000; - System.out.println("taken = " + taken); - } - - @Test - public void testClientAckMessages() throws Exception { - int numMessages = 10; - long time = System.currentTimeMillis(); - javax.jms.Queue queue = createQueue(address); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer p = session.createProducer(queue); - byte[] bytes = new byte[2048]; - new Random().nextBytes(bytes); - for (int i = 0; i < numMessages; i++) { - TextMessage message = session.createTextMessage(); - message.setText("msg:" + i); - p.send(message); - } - connection.close(); - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - - for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(q) != numMessages; ) { - Thread.sleep(1); - } - Assert.assertEquals(numMessages, getMessageCount(q)); - //now create a new connection and receive - connection = createConnection(); - session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); - MessageConsumer consumer = session.createConsumer(queue); - for (int i = 0; i < numMessages; i++) { - Message msg = consumer.receive(5000); - if (msg == null) { - System.out.println("ProtonTest.testManyMessages"); - } - Assert.assertNotNull("" + i, msg); - Assert.assertTrue("" + msg, msg instanceof TextMessage); - String text = ((TextMessage) msg).getText(); - //System.out.println("text = " + text); - Assert.assertEquals(text, "msg:" + i); - msg.acknowledge(); - } - - consumer.close(); - connection.close(); - - // Wait for Acks to be processed and message removed from queue. - Thread.sleep(500); - - Assert.assertEquals(0, getMessageCount(q)); - long taken = (System.currentTimeMillis() - time) / 1000; - System.out.println("taken = " + taken); - } - - @Test - public void testMessagesReceivedInParallel() throws Throwable { - final int numMessages = 50000; - long time = System.currentTimeMillis(); - final javax.jms.Queue queue = createQueue(address); - - final ArrayList exceptions = new ArrayList<>(); - - Thread t = new Thread(new Runnable() { - @Override - public void run() { - Connection connectionConsumer = null; - try { - // TODO the test may starve if using the same connection (dead lock maybe?) - connectionConsumer = createConnection(); - // connectionConsumer = connection; - connectionConsumer.start(); - Session sessionConsumer = connectionConsumer.createSession(false, Session.AUTO_ACKNOWLEDGE); - final MessageConsumer consumer = sessionConsumer.createConsumer(queue); - - long n = 0; - int count = numMessages; - while (count > 0) { - try { - if (++n % 1000 == 0) { - System.out.println("received " + n + " messages"); - } - - Message m = consumer.receive(5000); - Assert.assertNotNull("Could not receive message count=" + count + " on consumer", m); - count--; - } catch (JMSException e) { - e.printStackTrace(); - break; - } - } - } catch (Throwable e) { - exceptions.add(e); - e.printStackTrace(); - } finally { - try { - // if the createconnecion wasn't commented out - if (connectionConsumer != connection) { - connectionConsumer.close(); - } - } catch (Throwable ignored) { - // NO OP - } - } - } - }); - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - t.start(); - - MessageProducer p = session.createProducer(queue); - p.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - for (int i = 0; i < numMessages; i++) { - BytesMessage message = session.createBytesMessage(); - message.writeUTF("Hello world!!!!" + i); - message.setIntProperty("count", i); - p.send(message); - } - t.join(); - - for (Throwable e : exceptions) { - throw e; - } - Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable(); - - connection.close(); - Assert.assertEquals(0, getMessageCount(q)); - - long taken = (System.currentTimeMillis() - time); - System.out.println("Microbenchamrk ran in " + taken + " milliseconds, sending/receiving " + numMessages); - - double messagesPerSecond = ((double) numMessages / (double) taken) * 1000; - - System.out.println(((int) messagesPerSecond) + " messages per second"); - - } - - @Test - public void testSimpleBinary() throws Throwable { - final int numMessages = 500; - long time = System.currentTimeMillis(); - final javax.jms.Queue queue = createQueue(address); - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - byte[] bytes = new byte[0xf + 1]; - for (int i = 0; i <= 0xf; i++) { - bytes[i] = (byte) i; - } - - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < numMessages; i++) { - System.out.println("Sending " + i); - BytesMessage message = session.createBytesMessage(); - - message.writeBytes(bytes); - message.setIntProperty("count", i); - p.send(message); - } - - Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - final MessageConsumer consumer = sessionConsumer.createConsumer(queue); - - for (int i = 0; i < numMessages; i++) { - BytesMessage m = (BytesMessage) consumer.receive(5000); - Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); - - m.reset(); - - long size = m.getBodyLength(); - byte[] bytesReceived = new byte[(int) size]; - m.readBytes(bytesReceived); - - System.out.println("Received " + ByteUtil.bytesToHex(bytesReceived, 1) + " count - " + m.getIntProperty("count")); - - Assert.assertArrayEquals(bytes, bytesReceived); - } - - // assertEquals(0, q.getMessageCount()); - long taken = (System.currentTimeMillis() - time) / 1000; - System.out.println("taken = " + taken); - } - - @Test - public void testSimpleDefault() throws Throwable { - final int numMessages = 500; - long time = System.currentTimeMillis(); - final javax.jms.Queue queue = createQueue(address); - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - byte[] bytes = new byte[0xf + 1]; - for (int i = 0; i <= 0xf; i++) { - bytes[i] = (byte) i; - } - - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < numMessages; i++) { - System.out.println("Sending " + i); - Message message = session.createMessage(); - - message.setIntProperty("count", i); - p.send(message); - } - - Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - final MessageConsumer consumer = sessionConsumer.createConsumer(queue); - - for (int i = 0; i < numMessages; i++) { - Message m = consumer.receive(5000); - Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); - } - - // assertEquals(0, q.getMessageCount()); - long taken = (System.currentTimeMillis() - time) / 1000; - System.out.println("taken = " + taken); - } - - @Test - public void testSimpleMap() throws Throwable { - final int numMessages = 100; - long time = System.currentTimeMillis(); - final javax.jms.Queue queue = createQueue(address); - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < numMessages; i++) { - System.out.println("Sending " + i); - MapMessage message = session.createMapMessage(); - - message.setInt("i", i); - message.setIntProperty("count", i); - p.send(message); - } - - Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - final MessageConsumer consumer = sessionConsumer.createConsumer(queue); - - for (int i = 0; i < numMessages; i++) { - MapMessage m = (MapMessage) consumer.receive(5000); - Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); - - Assert.assertEquals(i, m.getInt("i")); - Assert.assertEquals(i, m.getIntProperty("count")); - } - - // assertEquals(0, q.getMessageCount()); - long taken = (System.currentTimeMillis() - time) / 1000; - System.out.println("taken = " + taken); - } - - @Test - public void testSimpleStream() throws Throwable { - final int numMessages = 100; - final javax.jms.Queue queue = createQueue(address); - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < numMessages; i++) { - StreamMessage message = session.createStreamMessage(); - message.writeInt(i); - message.writeBoolean(true); - message.writeString("test"); - p.send(message); - } - - Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - final MessageConsumer consumer = sessionConsumer.createConsumer(queue); - - for (int i = 0; i < numMessages; i++) { - StreamMessage m = (StreamMessage) consumer.receive(5000); - Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); - - Assert.assertEquals(i, m.readInt()); - Assert.assertEquals(true, m.readBoolean()); - Assert.assertEquals("test", m.readString()); - } - - } - - @Test - public void testSimpleText() throws Throwable { - final int numMessages = 100; - long time = System.currentTimeMillis(); - final javax.jms.Queue queue = createQueue(address); - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < numMessages; i++) { - System.out.println("Sending " + i); - TextMessage message = session.createTextMessage("text" + i); - message.setStringProperty("text", "text" + i); - p.send(message); - } - - Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - final MessageConsumer consumer = sessionConsumer.createConsumer(queue); - - for (int i = 0; i < numMessages; i++) { - TextMessage m = (TextMessage) consumer.receive(5000); - Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m); - Assert.assertEquals("text" + i, m.getText()); - } - - // assertEquals(0, q.getMessageCount()); - long taken = (System.currentTimeMillis() - time) / 1000; - System.out.println("taken = " + taken); - } - - @Test - public void testTimedOutWaitingForWriteLogOnConsumer() throws Throwable { - String name = "exampleQueue1"; - - int numMessages = 50; - - System.out.println("1. Send messages into queue"); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - javax.jms.Queue queue = session.createQueue(name); - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < numMessages; i++) { - TextMessage message = session.createTextMessage(); - message.setText("Message temporary"); - p.send(message); - } - p.close(); - session.close(); - - System.out.println("2. Receive one by one, each in its own session"); - for (int i = 0; i < numMessages; i++) { - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - queue = session.createQueue(name); - MessageConsumer c = session.createConsumer(queue); - Message m = c.receive(1000); - p.close(); - session.close(); - } - - System.out.println("3. Try to receive 10 in the same session"); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - queue = session.createQueue(name); - MessageConsumer c = session.createConsumer(queue); - for (int i = 0; i < numMessages; i++) { - Message m = c.receive(1000); - } - p.close(); - session.close(); - } - - @Test - public void testSimpleObject() throws Throwable { - final int numMessages = 1; - long time = System.currentTimeMillis(); - final javax.jms.Queue queue = createQueue(address); - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - MessageProducer p = session.createProducer(queue); - for (int i = 0; i < numMessages; i++) { - System.out.println("Sending " + i); - ObjectMessage message = session.createObjectMessage(new AnythingSerializable(i)); - p.send(message); - } - - Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - final MessageConsumer consumer = sessionConsumer.createConsumer(queue); - - for (int i = 0; i < numMessages; i++) { - ObjectMessage msg = (ObjectMessage) consumer.receive(5000); - Assert.assertNotNull("Could not receive message count=" + i + " on consumer", msg); - - AnythingSerializable someSerialThing = (AnythingSerializable) msg.getObject(); - Assert.assertEquals(i, someSerialThing.getCount()); - } - - // assertEquals(0, q.getMessageCount()); - long taken = (System.currentTimeMillis() - time) / 1000; - System.out.println("taken = " + taken); - } - - @Test - public void testSelector() throws Exception { - javax.jms.Queue queue = createQueue(address); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer p = session.createProducer(queue); - TextMessage message = session.createTextMessage(); - message.setText("msg:0"); - p.send(message); - message = session.createTextMessage(); - message.setText("msg:1"); - message.setStringProperty("color", "RED"); - p.send(message); - connection.start(); - MessageConsumer messageConsumer = session.createConsumer(queue, "color = 'RED'"); - TextMessage m = (TextMessage) messageConsumer.receive(5000); - Assert.assertNotNull(m); - Assert.assertEquals("msg:1", m.getText()); - Assert.assertEquals(m.getStringProperty("color"), "RED"); - connection.close(); - } - - @Test - public void testProperties() throws Exception { - javax.jms.Queue queue = createQueue(address); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer p = session.createProducer(queue); - TextMessage message = session.createTextMessage(); - message.setText("msg:0"); - message.setBooleanProperty("true", true); - message.setBooleanProperty("false", false); - message.setStringProperty("foo", "bar"); - message.setDoubleProperty("double", 66.6); - message.setFloatProperty("float", 56.789f); - message.setIntProperty("int", 8); - message.setByteProperty("byte", (byte) 10); - p.send(message); - p.send(message); - connection.start(); - MessageConsumer messageConsumer = session.createConsumer(queue); - TextMessage m = (TextMessage) messageConsumer.receive(5000); - Assert.assertNotNull(m); - Assert.assertEquals("msg:0", m.getText()); - Assert.assertEquals(m.getBooleanProperty("true"), true); - Assert.assertEquals(m.getBooleanProperty("false"), false); - Assert.assertEquals(m.getStringProperty("foo"), "bar"); - Assert.assertEquals(m.getDoubleProperty("double"), 66.6, 0.0001); - Assert.assertEquals(m.getFloatProperty("float"), 56.789f, 0.0001); - Assert.assertEquals(m.getIntProperty("int"), 8); - Assert.assertEquals(m.getByteProperty("byte"), (byte) 10); - m = (TextMessage) messageConsumer.receive(5000); - Assert.assertNotNull(m); - connection.close(); - } - - @Test - public void testClientID() throws Exception { - Connection testConn1 = createConnection(false); - Connection testConn2 = createConnection(false); - try { - testConn1.setClientID("client-id1"); - try { - testConn1.setClientID("client-id2"); - fail("didn't get expected exception"); - } catch (javax.jms.IllegalStateException e) { - //expected - } - - try { - testConn2.setClientID("client-id1"); - fail("didn't get expected exception"); - } catch (InvalidClientIDException e) { - //expected - } - } finally { - testConn1.close(); - testConn2.close(); - } - - try { - testConn1 = createConnection(false); - testConn2 = createConnection(false); - testConn1.setClientID("client-id1"); - testConn2.setClientID("client-id2"); - } finally { - testConn1.close(); - testConn2.close(); - } - } - - @Test - public void testFilterJMSMessageID() throws Exception { - javax.jms.Queue queue = createQueue(address); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer p = session.createProducer(queue); - TextMessage message = session.createTextMessage(); - p.send(message); - System.out.println("get mid: " + message.getJMSMessageID()); - connection.start(); - MessageConsumer messageConsumer = session.createConsumer(queue, "JMSMessageID = '" + message.getJMSMessageID() + "'"); - TextMessage m = (TextMessage) messageConsumer.receive(5000); - Assert.assertNotNull(m); - assertEquals(message.getJMSMessageID(), m.getJMSMessageID()); - connection.close(); - } - - @Test - public void testProducerWithoutUsingDefaultDestination() throws Exception { - - try { - javax.jms.Queue queue = createQueue(coreAddress); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - MessageProducer p = session.createProducer(null); - - for (int i = 1; i <= 10; i++) { - String targetName = coreAddress + i; - javax.jms.Queue target = createQueue(targetName); - TextMessage message = session.createTextMessage("message for " + targetName); - p.send(target, message); - } - connection.start(); - MessageConsumer messageConsumer = session.createConsumer(queue); - Message m = messageConsumer.receive(200); - Assert.assertNull(m); - - for (int i = 1; i <= 10; i++) { - String targetName = coreAddress + i; - javax.jms.Queue target = createQueue(targetName); - MessageConsumer consumer = session.createConsumer(target); - TextMessage tm = (TextMessage) consumer.receive(2000); - assertNotNull(tm); - assertEquals("message for " + targetName, tm.getText()); - consumer.close(); - } - } finally { - connection.close(); - } - } - - private javax.jms.Queue createQueue(String address) throws Exception { - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - try { - return session.createQueue(address); - } finally { - session.close(); - } - } - - private Connection createConnection() throws JMSException { - return this.createConnection(true); - } - - private javax.jms.Connection createConnection(boolean isStart) throws JMSException { - Connection connection; - if (protocol == 3) { - factory = new JmsConnectionFactory(amqpConnectionUri); - connection = factory.createConnection(); - } else if (protocol == 0) { - factory = new JmsConnectionFactory(userName, password, amqpConnectionUri); - connection = factory.createConnection(); - } else { - Assert.fail("protocol = " + protocol + " not supported"); - return null; // just to compile, the previous statement will throw an exception - } - if (isStart) { - connection.setExceptionListener(new ExceptionListener() { - @Override - public void onException(JMSException exception) { - exception.printStackTrace(); - } - }); - connection.start(); - } - - return connection; - } - - private javax.jms.Connection createConnection(String clientId) throws JMSException { - Connection connection; - if (protocol == 3) { - factory = new JmsConnectionFactory(amqpConnectionUri); - connection = factory.createConnection(); - connection.setExceptionListener(new ExceptionListener() { - @Override - public void onException(JMSException exception) { - exception.printStackTrace(); - } - }); - connection.setClientID(clientId); - connection.start(); - } else if (protocol == 0) { - factory = new JmsConnectionFactory(userName, password, amqpConnectionUri); - connection = factory.createConnection(); - connection.setExceptionListener(new ExceptionListener() { - @Override - public void onException(JMSException exception) { - exception.printStackTrace(); - } - }); - connection.setClientID(clientId); - connection.start(); - } else { - Assert.fail("protocol = " + protocol + " not supported"); - return null; // just to compile, the previous statement will throw an exception - } - - return connection; - } - - private void setAddressFullBlockPolicy() { - // For BLOCK tests - AddressSettings addressSettings = server.getAddressSettingsRepository().getMatch("#"); - addressSettings.setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK); - addressSettings.setMaxSizeBytes(maxSizeBytes); - addressSettings.setMaxSizeBytesRejectThreshold(maxSizeBytesRejectThreshold); - server.getAddressSettingsRepository().addMatch("#", addressSettings); - } - - public static class AnythingSerializable implements Serializable { - - private int count; - - public AnythingSerializable(int count) { - this.count = count; - } - - public int getCount() { - return count; - } - } - - /** - * If we have an address configured with both ANYCAST and MULTICAST routing types enabled, we must ensure that any - * messages sent specifically to MULTICAST (e.g. JMS TopicProducer) are only delivered to MULTICAST queues (e.g. - * i.e. subscription queues) and **NOT** to ANYCAST queues (e.g. JMS Queue). - * - * @throws Exception - */ - @Test - public void testRoutingExclusivity() throws Exception { - - // Create Address with both ANYCAST and MULTICAST enabled - String testAddress = "testRoutingExclusivity"; - SimpleString ssTestAddress = new SimpleString(testAddress); - - AddressInfo addressInfo = new AddressInfo(ssTestAddress); - addressInfo.addRoutingType(RoutingType.MULTICAST); - addressInfo.addRoutingType(RoutingType.ANYCAST); - - server.addAddressInfo(addressInfo); - server.createQueue(ssTestAddress, RoutingType.ANYCAST, ssTestAddress, null, true, false); - - Connection connection = createConnection(UUIDGenerator.getInstance().generateStringUUID()); - - try { - - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - Topic topic = session.createTopic(testAddress); - javax.jms.Queue queue = session.createQueue(testAddress); - - MessageProducer producer = session.createProducer(topic); - - MessageConsumer queueConsumer = session.createConsumer(queue); - MessageConsumer topicConsumer = session.createConsumer(topic); - - producer.send(session.createTextMessage("testMessage")); - - assertNotNull(topicConsumer.receive(1000)); - assertNull(queueConsumer.receive(1000)); - } finally { - connection.close(); - } - } - - @Test - public void testReleaseDisposition() throws Exception { - AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); - AmqpConnection connection = client.connect(); - try { - AmqpSession session = connection.createSession(); - - AmqpSender sender = session.createSender(address); - AmqpMessage message = new AmqpMessage(); - message.setText("Test-Message"); - sender.send(message); - - AmqpReceiver receiver = session.createReceiver(address); - receiver.flow(10); - - AmqpMessage m1 = receiver.receive(5, TimeUnit.SECONDS); - assertNotNull(m1); - m1.release(); - - //receiver.flow(10); - AmqpMessage m2 = receiver.receive(5, TimeUnit.SECONDS); - assertNotNull(m2); - m2.accept(); - } finally { - connection.close(); - } - } -} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestBase.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestBase.java deleted file mode 100644 index ab8d2d3ced..0000000000 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestBase.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.activemq.artemis.tests.integration.amqp; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.activemq.artemis.api.core.TransportConfiguration; -import org.apache.activemq.artemis.core.config.Configuration; -import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants; -import org.apache.activemq.artemis.core.server.ActiveMQServer; -import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy; -import org.apache.activemq.artemis.core.settings.impl.AddressSettings; -import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; -import org.junit.After; -import org.junit.Before; - -public class ProtonTestBase extends ActiveMQTestBase { - - protected String brokerName = "localhost"; - protected ActiveMQServer server; - - protected String tcpAmqpConnectionUri = "tcp://localhost:5672"; - protected String userName = "guest"; - protected String password = "guest"; - - @Override - @Before - public void setUp() throws Exception { - super.setUp(); - - server = this.createAMQPServer(5672); - server.start(); - } - - protected ActiveMQServer createAMQPServer(int port) throws Exception { - final ActiveMQServer amqpServer = this.createServer(true, true); - HashMap params = new HashMap<>(); - params.put(TransportConstants.PORT_PROP_NAME, String.valueOf(port)); - params.put(TransportConstants.PROTOCOLS_PROP_NAME, "AMQP"); - HashMap amqpParams = new HashMap<>(); - configureAmqp(amqpParams); - - amqpServer.getConfiguration().getAcceptorConfigurations().clear(); - - TransportConfiguration transportConfiguration = new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params, "amqp-acceptor", amqpParams); - - amqpServer.getConfiguration().getAcceptorConfigurations().add(transportConfiguration); - amqpServer.getConfiguration().setName(brokerName); - amqpServer.getConfiguration().setJournalDirectory(amqpServer.getConfiguration().getJournalDirectory() + port); - amqpServer.getConfiguration().setBindingsDirectory(amqpServer.getConfiguration().getBindingsDirectory() + port); - amqpServer.getConfiguration().setPagingDirectory(amqpServer.getConfiguration().getPagingDirectory() + port); - - // Default Page - AddressSettings addressSettings = new AddressSettings(); - addressSettings.setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE); - amqpServer.getConfiguration().getAddressesSettings().put("#", addressSettings); - configureServer(amqpServer.getConfiguration()); - return amqpServer; - } - - protected void configureServer(Configuration serverConfig) { - } - - protected void configureAmqp(Map params) { - } - - @Override - @After - public void tearDown() throws Exception { - try { - server.stop(); - } finally { - super.tearDown(); - } - } -} diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/SendingAndReceivingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/SendingAndReceivingTest.java deleted file mode 100644 index 87a4710813..0000000000 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/SendingAndReceivingTest.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.activemq.artemis.tests.integration.amqp; - -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import org.apache.activemq.artemis.api.core.RoutingType; -import org.apache.activemq.artemis.api.core.SimpleString; -import org.apache.activemq.artemis.api.core.TransportConfiguration; -import org.apache.activemq.artemis.core.server.ActiveMQServer; -import org.apache.activemq.artemis.core.settings.HierarchicalRepository; -import org.apache.activemq.artemis.core.settings.impl.AddressSettings; -import org.apache.activemq.artemis.tests.util.Wait; -import org.apache.activemq.transport.amqp.client.AmqpClient; -import org.apache.activemq.transport.amqp.client.AmqpConnection; -import org.apache.activemq.transport.amqp.client.AmqpMessage; -import org.apache.activemq.transport.amqp.client.AmqpReceiver; -import org.apache.activemq.transport.amqp.client.AmqpSender; -import org.apache.activemq.transport.amqp.client.AmqpSession; -import org.apache.qpid.jms.JmsConnectionFactory; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class SendingAndReceivingTest extends AmqpTestSupport { - - private ActiveMQServer server; - - @Before - @Override - public void setUp() throws Exception { - super.setUp(); - server = createServer(true, true); - Set acceptors = server.getConfiguration().getAcceptorConfigurations(); - for (TransportConfiguration tc : acceptors) { - if (tc.getName().equals("netty")) { - tc.getExtraParams().put("anycastPrefix", "anycast://"); - tc.getExtraParams().put("multicastPrefix", "multicast://"); - } - } - server.getConfiguration().setMessageExpiryScanPeriod(1); - server.start(); - server.createQueue(SimpleString.toSimpleString("exampleQueue"), RoutingType.ANYCAST, SimpleString.toSimpleString("exampleQueue"), null, true, false, -1, false, true); - server.createQueue(SimpleString.toSimpleString("DLQ"), RoutingType.ANYCAST, SimpleString.toSimpleString("DLQ"), null, true, false, -1, false, true); - - AddressSettings as = new AddressSettings(); - as.setExpiryAddress(SimpleString.toSimpleString("DLQ")); - HierarchicalRepository repos = server.getAddressSettingsRepository(); - repos.addMatch("#", as); - } - - @After - @Override - public void tearDown() throws Exception { - try { - server.stop(); - } finally { - super.tearDown(); - } - } - - //https://issues.apache.org/jira/browse/ARTEMIS-214 - @Test - public void testSendingBigMessage() throws Exception { - Connection connection = null; - ConnectionFactory connectionFactory = new JmsConnectionFactory("amqp://localhost:61616"); - - try { - connection = connectionFactory.createConnection(); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - Queue queue = session.createQueue("anycast://exampleQueue"); - MessageProducer sender = session.createProducer(queue); - - String body = createMessage(10240); - sender.send(session.createTextMessage(body)); - connection.start(); - - MessageConsumer consumer = session.createConsumer(queue); - TextMessage m = (TextMessage) consumer.receive(5000); - - Assert.assertEquals(body, m.getText()); - } finally { - if (connection != null) { - connection.close(); - } - } - } - - @Test(timeout = 60000) - public void testSendMessageThenAllowToExpireUsingTimeToLive() throws Exception { - AddressSettings as = new AddressSettings(); - as.setExpiryAddress(SimpleString.toSimpleString("DLQ")); - HierarchicalRepository repos = server.getAddressSettingsRepository(); - repos.addMatch("exampleQueue", as); - - Connection connection = null; - ConnectionFactory connectionFactory = new JmsConnectionFactory("amqp://localhost:61616"); - - try { - connection = connectionFactory.createConnection(); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - String address = "exampleQueue"; - Queue queue = session.createQueue(address); - - MessageProducer sender = session.createProducer(queue); - sender.setTimeToLive(1); - - Message message = session.createMessage(); - sender.send(message); - connection.start(); - - MessageConsumer consumer = session.createConsumer(session.createQueue("DLQ")); - Message m = consumer.receive(10000); - Assert.assertNotNull(m); - consumer.close(); - - - consumer = session.createConsumer(queue); - m = consumer.receiveNoWait(); - Assert.assertNull(m); - consumer.close(); - - - } finally { - if (connection != null) { - connection.close(); - } - } - } - - @Test(timeout = 60000) - public void testSendExpiry() throws Throwable { - internalSendExpiry(false); - } - - @Test(timeout = 60000) - public void testSendExpiryRestartServer() throws Throwable { - internalSendExpiry(true); - } - - public void internalSendExpiry(boolean restartServer) throws Throwable { - AmqpClient client = createAmqpClient(); - AmqpConnection connection = client.connect(); - - try { - - // Normal Session which won't create an TXN itself - AmqpSession session = connection.createSession(); - AmqpSender sender = session.createSender("exampleQueue"); - - AmqpMessage message = new AmqpMessage(); - message.setDurable(true); - message.setText("Test-Message"); - message.setDeliveryAnnotation("shouldDisappear", 1); - message.setAbsoluteExpiryTime(System.currentTimeMillis() + 1000); - sender.send(message); - - org.apache.activemq.artemis.core.server.Queue dlq = server.locateQueue(SimpleString.toSimpleString("DLQ")); - - Wait.waitFor(() -> dlq.getMessageCount() > 0, 5000, 500); - - connection.close(); - - if (restartServer) { - server.stop(); - server.start(); - } - - connection = client.connect(); - session = connection.createSession(); - - // Read all messages from the Queue, do not accept them yet. - AmqpReceiver receiver = session.createReceiver("DLQ"); - receiver.flow(20); - message = receiver.receive(5, TimeUnit.SECONDS); - Assert.assertNotNull(message); - Assert.assertEquals("exampleQueue", message.getMessageAnnotation(org.apache.activemq.artemis.api.core.Message.HDR_ORIGINAL_ADDRESS.toString())); - Assert.assertNull(message.getDeliveryAnnotation("shouldDisappear")); - Assert.assertNull(receiver.receiveNoWait()); - - } finally { - connection.close(); - } - } - - - - private static String createMessage(int messageSize) { - final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - Random rnd = new Random(); - StringBuilder sb = new StringBuilder(messageSize); - for (int j = 0; j < messageSize; j++) { - sb.append(AB.charAt(rnd.nextInt(AB.length()))); - } - String body = sb.toString(); - return body; - } - -}