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; - } - -}