This commit is contained in:
Martyn Taylor 2017-04-28 10:16:21 +01:00
commit 0e800d81a7
48 changed files with 4554 additions and 3107 deletions

View File

@ -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<E extends Endpoint> implements AmqpResource {
@ -243,7 +242,6 @@ public abstract class AmqpAbstractResource<E extends Endpoint> implements AmqpRe
@Override
public void processDeliveryUpdates(AmqpConnection connection, Delivery delivery) throws IOException {
doDeliveryUpdate(delivery);
}
@Override
@ -251,18 +249,17 @@ public abstract class AmqpAbstractResource<E extends Endpoint> 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<E extends Endpoint> 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<E extends Endpoint> 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<E extends Endpoint> 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;

View File

@ -128,9 +128,12 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
/**
* 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<Receiver> {
}
/**
* 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<Receiver> {
}
/**
* 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<Receiver> {
}
/**
* 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<Receiver> {
}
/**
* 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<Receiver> {
}
/**
* 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<Receiver> {
* 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<Receiver> {
* 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<Receiver> {
*
* 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<Receiver> {
/**
* 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<Receiver> {
/**
* 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<Receiver> {
/**
* 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<Receiver> {
}
/**
* 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<Receiver> {
* @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<Receiver> {
* 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<Receiver> {
* @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<Receiver> {
/**
* 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<Receiver> {
/**
* 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<Receiver> {
/**
* 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<Receiver> {
return new UnmodifiableReceiver(getEndpoint());
}
//----- Receiver configuration properties --------------------------------//
// ----- Receiver configuration properties --------------------------------//
public boolean isPresettle() {
return presettle;
@ -690,7 +722,7 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
return session.getConnection().getDrainTimeout();
}
//----- Internal implementation ------------------------------------------//
// ----- Internal implementation ------------------------------------------//
@Override
protected void doOpen() {
@ -802,7 +834,7 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
protected void configureSource(Source source) {
Map<Symbol, DescribedType> 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<Receiver> {
}
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<Receiver> {
}
}
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<Receiver> {
}
}
//----- Internal Transaction state callbacks -----------------------------//
// ----- Internal Transaction state callbacks -----------------------------//
void preCommit() {
}
@ -1027,7 +1069,7 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
void postRollback() {
}
//----- Inner classes used in message pull operations --------------------//
// ----- Inner classes used in message pull operations --------------------//
protected static final class ScheduledRequest implements AsyncResult {

View File

@ -56,7 +56,7 @@ import org.slf4j.LoggerFactory;
public class AmqpSender extends AmqpAbstractResource<Sender> {
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<Sender> {
/**
* 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<Sender> {
/**
* 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<Sender> {
}
/**
* 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<Sender> {
}
/**
* 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<Sender> {
return address;
}
//----- Sender configuration ---------------------------------------------//
// ----- Sender configuration ---------------------------------------------//
/**
* @return will messages be settle on send.
@ -243,7 +253,8 @@ public class AmqpSender extends AmqpAbstractResource<Sender> {
/**
* 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<Sender> {
/**
* 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<Sender> {
this.properties = properties;
}
//----- Private Sender implementation ------------------------------------//
// ----- Private Sender implementation ------------------------------------//
private void checkClosed() {
if (isClosed()) {
@ -301,7 +312,7 @@ public class AmqpSender extends AmqpAbstractResource<Sender> {
@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<Sender> {
}
}
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<Sender> {
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<Sender> {
tagGenerator.returnTag(delivery.getTag());
delivery.settle();
toRemove.add(delivery);
doDeliveryUpdate(delivery);
}
pending.removeAll(toRemove);

View File

@ -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) {
}

View File

@ -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<String, Object> params = new HashMap<>();
params.put(TransportConstants.PORT_PROP_NAME, String.valueOf(port));
params.put(TransportConstants.PROTOCOLS_PROP_NAME, getConfiguredProtocols());
HashMap<String, Object> 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<TransportConfiguration> acceptors = serverConfig.getAcceptorConfigurations();
server.getConfiguration().getAddressesSettings().put("#", addressSettings);
Set<TransportConfiguration> 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<Set<Role>> securityRepository = server.getSecurityRepository();
HashSet<Role> 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<String, Object> 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();
}
}

View File

@ -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);

View File

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

View File

@ -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();
}
}
}

View File

@ -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());
}
}
}

View File

@ -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<String, AddressSettings> 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<String, Object>(), "netty", new HashMap<String, Object>()));
}
@Override
protected void configureServer(Configuration serverConfig) {
serverConfig.addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, new HashMap<String, Object>(), "netty", new HashMap<String, Object>()));
}
@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();
}
}
}

View File

@ -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();

View File

@ -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());

View File

@ -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<String, Object> params) {
protected void configureAMQPAcceptorParameters(Map<String, Object> 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;
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}
}

View File

@ -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<String, Object> 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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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<String, Object> 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'});

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}
}

View File

@ -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<Symbol, Object> 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<Symbol, Object> 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<Symbol, Object> filters = source.getFilter();
if (findFilter(filters, AmqpUnknownFilterType.UNKNOWN_FILTER_IDS) != null) {
markAsInvalid("Broker should not return unsupported filter on attach.");
}
}
});
Map<Symbol, DescribedType> 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();
}
}

View File

@ -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());

View File

@ -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<Set<Role>> securityRepository = server.getSecurityRepository();
HashSet<Role> 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();
}
}
}

View File

@ -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<Symbol, Object> 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<Symbol, Object> 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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -30,6 +30,8 @@ import org.junit.After;
*/
public class AmqpTestSupport extends ActiveMQTestBase {
protected static final int AMQP_PORT = 5672;
protected LinkedList<AmqpConnection> 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;

View File

@ -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)) {

View File

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

View File

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

View File

@ -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();
}
}

View File

@ -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();
}

View File

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

View File

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

View File

@ -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();
}
}
}

View File

@ -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<Message> 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<Message> 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();
}
}
}

View File

@ -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<Throwable> 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();
}
}
}

View File

@ -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();
}
}

View File

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

View File

@ -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<String> 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<String> received = (ArrayList<String>) 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();
}
}

View File

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

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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<Integer> 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());
}
}

View File

@ -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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<String, Object> 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();
}
}
}

View File

@ -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<String, Object> params = new HashMap<>();
params.put(TransportConstants.PORT_PROP_NAME, String.valueOf(port));
params.put(TransportConstants.PROTOCOLS_PROP_NAME, "AMQP");
HashMap<String, Object> 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<String, Object> params) {
}
@Override
@After
public void tearDown() throws Exception {
try {
server.stop();
} finally {
super.tearDown();
}
}
}

View File

@ -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<TransportConfiguration> 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<AddressSettings> 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<AddressSettings> 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;
}
}