ARTEMIS-1123 Major AMQP Test Suite refactoring

Refactor the AMQP test suite grouping tests into more logical unit
tests and adding additional coverage in many areas.  Adds some negative
validation tests to cover features that were only partially tested.

Brings in tests from ActiveMQ 5.x that were not yet ported to Artemis
to increase coverage amd test scenarios previously seen to have issues
in the 5.x broker.

Improve tests that were failing sporadically due to not waiting for
broker stats to be updated after async calls were made.
This commit is contained in:
Timothy Bish 2017-04-26 18:36:32 -04:00 committed by Martyn Taylor
parent 60036c93b0
commit bad6acb58f
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 * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
@ -28,9 +28,8 @@ import org.slf4j.LoggerFactory;
/** /**
* Abstract base for all AmqpResource implementations to extend. * Abstract base for all AmqpResource implementations to extend.
* *
* This abstract class wraps up the basic state management bits so that the concrete * This abstract class wraps up the basic state management bits so that the concrete object
* object don't have to reproduce it. Provides hooks for the subclasses to initialize * don't have to reproduce it. Provides hooks for the subclasses to initialize and shutdown.
* and shutdown.
*/ */
public abstract class AmqpAbstractResource<E extends Endpoint> implements AmqpResource { public abstract class AmqpAbstractResource<E extends Endpoint> implements AmqpResource {
@ -243,7 +242,6 @@ public abstract class AmqpAbstractResource<E extends Endpoint> implements AmqpRe
@Override @Override
public void processDeliveryUpdates(AmqpConnection connection, Delivery delivery) throws IOException { public void processDeliveryUpdates(AmqpConnection connection, Delivery delivery) throws IOException {
doDeliveryUpdate(delivery);
} }
@Override @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 * Perform the open operation on the managed endpoint. A subclass may override this method to
* override this method to provide additional open actions or configuration * provide additional open actions or configuration updates.
* updates.
*/ */
protected void doOpen() { protected void doOpen() {
getEndpoint().open(); getEndpoint().open();
} }
/** /**
* Perform the close operation on the managed endpoint. A subclass may * Perform the close operation on the managed endpoint. A subclass may override this method
* override this method to provide additional close actions or alter the * to provide additional close actions or alter the standard close path such as endpoint
* standard close path such as endpoint detach etc. * detach etc.
*/ */
protected void doClose() { protected void doClose() {
getEndpoint().close(); getEndpoint().close();
@ -271,17 +268,16 @@ public abstract class AmqpAbstractResource<E extends Endpoint> implements AmqpRe
/** /**
* Perform the detach operation on the managed endpoint. * Perform the detach operation on the managed endpoint.
* *
* By default this method throws an UnsupportedOperationException, a subclass * By default this method throws an UnsupportedOperationException, a subclass must implement
* must implement this and do a detach if its resource supports that. * this and do a detach if its resource supports that.
*/ */
protected void doDetach() { protected void doDetach() {
throw new UnsupportedOperationException("Endpoint cannot be detached."); throw new UnsupportedOperationException("Endpoint cannot be detached.");
} }
/** /**
* Complete the open operation on the managed endpoint. A subclass may * Complete the open operation on the managed endpoint. A subclass may override this method
* override this method to provide additional verification actions or configuration * to provide additional verification actions or configuration updates.
* updates.
*/ */
protected void doOpenCompletion() { protected void doOpenCompletion() {
LOG.debug("{} is now open: ", this); 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, * When aborting the open operation, and there isn't an error condition, provided by the
* provided by the peer, the returned exception will be used instead. * peer, the returned exception will be used instead. A subclass may override this method to
* A subclass may override this method to provide alternative behaviour. * provide alternative behaviour.
*/ */
protected Exception getOpenAbortException() { protected Exception getOpenAbortException() {
return new IOException("Open failed unexpectedly."); return new IOException("Open failed unexpectedly.");
} }
// TODO - Fina a more generic way to do this.
protected abstract void doOpenInspection(); protected abstract void doOpenInspection();
protected abstract void doClosedInspection(); protected abstract void doClosedInspection();
@ -305,18 +300,7 @@ public abstract class AmqpAbstractResource<E extends Endpoint> implements AmqpRe
protected void doDetachedInspection() { protected void doDetachedInspection() {
} }
protected void doDeliveryUpdate(Delivery delivery) { // ----- Private implementation utility methods ---------------------------//
AmqpValidator validator = getStateInspector();
if (validator != null) {
try {
validator.inspectDeliveryUpdate(delivery);
} catch (Throwable error) {
validator.markAsInvalid(error.getMessage());
}
}
}
//----- Private implementation utility methods ---------------------------//
private boolean isAwaitingOpen() { private boolean isAwaitingOpen() {
return this.openRequest != null; return this.openRequest != null;

View File

@ -128,9 +128,12 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
/** /**
* Create a new receiver instance. * Create a new receiver instance.
* *
* @param session The parent session that created the receiver. * @param session
* @param source The Source instance to use instead of creating and configuring one. * The parent session that created the receiver.
* @param receiverId The unique ID assigned to this 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) { 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 * Close the receiver, a closed receiver will throw exceptions if any further send calls are
* calls are made. * 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 { public void close() throws IOException {
if (closed.compareAndSet(false, true)) { 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 * Detach the receiver, a closed receiver will throw exceptions if any further send calls are
* calls are made. * 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 { public void detach() throws IOException {
if (closed.compareAndSet(false, true)) { 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 * Attempts to wait on a message to be delivered to this receiver. The receive call will wait
* call will wait indefinitely for a message to be delivered. * indefinitely for a message to be delivered.
* *
* @return a newly received message sent to this receiver. * @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 { public AmqpMessage receive() throws Exception {
checkClosed(); checkClosed();
@ -219,13 +225,16 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
} }
/** /**
* Attempts to receive a message sent to this receiver, waiting for the given * Attempts to receive a message sent to this receiver, waiting for the given timeout value
* timeout value before giving up and returning null. * before giving up and returning null.
* *
* @param timeout the time to wait for a new message to arrive. * @param timeout
* @param unit the unit of time that the timeout value represents. * 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. * @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 { public AmqpMessage receive(long timeout, TimeUnit unit) throws Exception {
checkClosed(); checkClosed();
@ -233,11 +242,12 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
} }
/** /**
* If a message is already available in this receiver's prefetch buffer then * If a message is already available in this receiver's prefetch buffer then it is returned
* it is returned immediately otherwise this methods return null without waiting. * immediately otherwise this methods return null without waiting.
* *
* @return a newly received message or null if there is no currently available message. * @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 { public AmqpMessage receiveNoWait() throws Exception {
checkClosed(); 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. * 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. * @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 { public AmqpMessage pull() throws IOException {
return pull(-1, TimeUnit.MILLISECONDS); 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. * 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. * @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 { public AmqpMessage pullImmediate() throws IOException {
return pull(0, TimeUnit.MILLISECONDS); return pull(0, TimeUnit.MILLISECONDS);
@ -273,10 +285,13 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
* *
* The timeout value when positive is given in milliseconds. * 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 timeout
* @param unit the unit of measure that the timeout represents. * 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. * @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 { public AmqpMessage pull(final long timeout, final TimeUnit unit) throws IOException {
checkClosed(); checkClosed();
@ -342,8 +357,10 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
/** /**
* Controls the amount of credit given to the receiver link. * Controls the amount of credit given to the receiver link.
* *
* @param credit the amount of credit to grant. * @param credit
* @throws IOException if an error occurs while sending the flow. * the amount of credit to grant.
* @throws IOException
* if an error occurs while sending the flow.
*/ */
public void flow(final int credit) throws IOException { public void flow(final int credit) throws IOException {
checkClosed(); checkClosed();
@ -369,8 +386,10 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
/** /**
* Attempts to drain a given amount of credit from the link. * Attempts to drain a given amount of credit from the link.
* *
* @param credit the amount of credit to drain. * @param credit
* @throws IOException if an error occurs while sending the drain. * the amount of credit to drain.
* @throws IOException
* if an error occurs while sending the drain.
*/ */
public void drain(final int credit) throws IOException { public void drain(final int credit) throws IOException {
checkClosed(); 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. * 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 { public void stop() throws IOException {
checkClosed(); 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 * @param delivery
* the Delivery instance to accept. * 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 { public void accept(Delivery delivery) throws IOException {
accept(delivery, this.session, true); accept(delivery, this.session, true);
@ -438,25 +460,28 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
* @param settle * @param settle
* true if the receiver should settle the delivery or just send the disposition. * 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 { public void accept(Delivery delivery, boolean settle) throws IOException {
accept(delivery, this.session, settle); 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 * 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 * caller. This allows for an accepted message to be involved in a transaction that is being
* being managed by some other session other than the one that created this receiver. * managed by some other session other than the one that created this receiver.
* *
* @param delivery * @param delivery
* the Delivery instance to accept. * the Delivery instance to accept.
* @param session * @param session
* the session under which the message is being accepted. * 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 { public void accept(final Delivery delivery, final AmqpSession session) throws IOException {
accept(delivery, session, true); 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. * 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 * 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 * caller. This allows for an accepted message to be involved in a transaction that is being
* being managed by some other session other than the one that created this receiver. * managed by some other session other than the one that created this receiver.
* *
* @param delivery * @param delivery
* the Delivery instance to accept. * the Delivery instance to accept.
@ -476,7 +501,8 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
* @param settle * @param settle
* true if the receiver should settle the delivery or just send the disposition. * 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 { public void accept(final Delivery delivery, final AmqpSession session, final boolean settle) throws IOException {
checkClosed(); checkClosed();
@ -532,14 +558,16 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
/** /**
* Mark a message that was dispatched under the given Delivery instance as Modified. * Mark a message that was dispatched under the given Delivery instance as Modified.
* *
* @param delivery the Delivery instance to mark modified. * @param delivery
* @param deliveryFailed indicates that the delivery failed for some reason. * the Delivery instance to mark modified.
* @param undeliverableHere marks the delivery as not being able to be process by link it was sent to. * @param deliveryFailed
* @throws IOException if an error occurs while sending the reject. * 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, public void modified(final Delivery delivery, final Boolean deliveryFailed, final Boolean undeliverableHere) throws IOException {
final Boolean deliveryFailed,
final Boolean undeliverableHere) throws IOException {
checkClosed(); checkClosed();
if (delivery == null) { if (delivery == null) {
@ -574,8 +602,10 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
/** /**
* Release a message that was dispatched under the given Delivery instance. * Release a message that was dispatched under the given Delivery instance.
* *
* @param delivery the Delivery instance to release. * @param delivery
* @throws IOException if an error occurs while sending the release. * the Delivery instance to release.
* @throws IOException
* if an error occurs while sending the release.
*/ */
public void release(final Delivery delivery) throws IOException { public void release(final Delivery delivery) throws IOException {
checkClosed(); checkClosed();
@ -609,8 +639,10 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
/** /**
* Reject a message that was dispatched under the given Delivery instance. * Reject a message that was dispatched under the given Delivery instance.
* *
* @param delivery the Delivery instance to reject. * @param delivery
* @throws IOException if an error occurs while sending the release. * the Delivery instance to reject.
* @throws IOException
* if an error occurs while sending the release.
*/ */
public void reject(final Delivery delivery) throws IOException { public void reject(final Delivery delivery) throws IOException {
checkClosed(); checkClosed();
@ -648,7 +680,7 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
return new UnmodifiableReceiver(getEndpoint()); return new UnmodifiableReceiver(getEndpoint());
} }
//----- Receiver configuration properties --------------------------------// // ----- Receiver configuration properties --------------------------------//
public boolean isPresettle() { public boolean isPresettle() {
return presettle; return presettle;
@ -690,7 +722,7 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
return session.getConnection().getDrainTimeout(); return session.getConnection().getDrainTimeout();
} }
//----- Internal implementation ------------------------------------------// // ----- Internal implementation ------------------------------------------//
@Override @Override
protected void doOpen() { protected void doOpen() {
@ -802,7 +834,7 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
protected void configureSource(Source source) { protected void configureSource(Source source) {
Map<Symbol, DescribedType> filters = new HashMap<>(); 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()) { if (getSubscriptionName() != null && !getSubscriptionName().isEmpty()) {
source.setExpiryPolicy(TerminusExpiryPolicy.NEVER); source.setExpiryPolicy(TerminusExpiryPolicy.NEVER);
@ -868,6 +900,8 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
} }
private void processDelivery(Delivery incoming) throws Exception { private void processDelivery(Delivery incoming) throws Exception {
doDeliveryInspection(incoming);
Message message = null; Message message = null;
try { try {
message = decodeIncomingMessage(incoming); 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 @Override
public void processFlowUpdates(AmqpConnection connection) throws IOException { public void processFlowUpdates(AmqpConnection connection) throws IOException {
if (pullRequest != null || stopRequest != null) { 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() { void preCommit() {
} }
@ -1027,7 +1069,7 @@ public class AmqpReceiver extends AmqpAbstractResource<Receiver> {
void postRollback() { void postRollback() {
} }
//----- Inner classes used in message pull operations --------------------// // ----- Inner classes used in message pull operations --------------------//
protected static final class ScheduledRequest implements AsyncResult { protected static final class ScheduledRequest implements AsyncResult {

View File

@ -56,7 +56,7 @@ import org.slf4j.LoggerFactory;
public class AmqpSender extends AmqpAbstractResource<Sender> { public class AmqpSender extends AmqpAbstractResource<Sender> {
private static final Logger LOG = LoggerFactory.getLogger(AmqpSender.class); 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; 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. * Create a new sender instance using the given Target when creating the link.
* *
* @param session The parent session that created the session. * @param session
* @param target The target that this sender produces to. * The parent session that created the session.
* @param senderId The unique ID assigned to this sender. * @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) { 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. * Sends the given message to this senders assigned address.
* *
* @param message the message to send. * @param message
* @throws IOException if an error occurs during the send. * the message to send.
* @throws IOException
* if an error occurs during the send.
*/ */
public void send(final AmqpMessage message) throws IOException { public void send(final AmqpMessage message) throws IOException {
checkClosed(); 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 message
* @param txId the transaction ID to assign the outgoing send. * the message to send.
* @throws IOException if an error occurs during the 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 { public void send(final AmqpMessage message, final AmqpTransactionId txId) throws IOException {
checkClosed(); checkClosed();
@ -188,10 +197,11 @@ public class AmqpSender extends AmqpAbstractResource<Sender> {
} }
/** /**
* Close the sender, a closed sender will throw exceptions if any further send * Close the sender, a closed sender will throw exceptions if any further send calls are
* calls are made. * 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 { public void close() throws IOException {
if (closed.compareAndSet(false, true)) { if (closed.compareAndSet(false, true)) {
@ -231,7 +241,7 @@ public class AmqpSender extends AmqpAbstractResource<Sender> {
return address; return address;
} }
//----- Sender configuration ---------------------------------------------// // ----- Sender configuration ---------------------------------------------//
/** /**
* @return will messages be settle on send. * @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. * 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) { public void setPresettle(boolean presettle) {
this.presettle = 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. * 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) { public void setSendTimeout(long sendTimeout) {
this.sendTimeout = sendTimeout; this.sendTimeout = sendTimeout;
} }
public void setDesiredCapabilities(Symbol[] desiredCapabilities) { public void setDesiredCapabilities(Symbol[] desiredCapabilities) {
if (getEndpoint() != null) { if (getEndpoint() != null) {
throw new IllegalStateException("Endpoint already established"); throw new IllegalStateException("Endpoint already established");
@ -290,7 +301,7 @@ public class AmqpSender extends AmqpAbstractResource<Sender> {
this.properties = properties; this.properties = properties;
} }
//----- Private Sender implementation ------------------------------------// // ----- Private Sender implementation ------------------------------------//
private void checkClosed() { private void checkClosed() {
if (isClosed()) { if (isClosed()) {
@ -301,7 +312,7 @@ public class AmqpSender extends AmqpAbstractResource<Sender> {
@Override @Override
protected void doOpen() { 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 source = new Source();
source.setAddress(senderId); source.setAddress(senderId);
source.setOutcomes(outcomes); 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 @Override
protected Exception getOpenAbortException() { protected Exception getOpenAbortException() {
// Verify the attach response contained a non-null target // Verify the attach response contained a non-null target
@ -470,6 +489,8 @@ public class AmqpSender extends AmqpAbstractResource<Sender> {
continue; continue;
} }
doDeliveryUpdateInspection(delivery);
Outcome outcome = null; Outcome outcome = null;
if (state instanceof TransactionalState) { if (state instanceof TransactionalState) {
LOG.trace("State of delivery is Transactional, retrieving outcome: {}", state); LOG.trace("State of delivery is Transactional, retrieving outcome: {}", state);
@ -516,8 +537,6 @@ public class AmqpSender extends AmqpAbstractResource<Sender> {
tagGenerator.returnTag(delivery.getTag()); tagGenerator.returnTag(delivery.getTag());
delivery.settle(); delivery.settle();
toRemove.add(delivery); toRemove.add(delivery);
doDeliveryUpdate(delivery);
} }
pending.removeAll(toRemove); pending.removeAll(toRemove);

View File

@ -1,4 +1,4 @@
/** /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * 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; 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 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.RoutingType;
import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.TransportConfiguration; 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.config.CoreAddressConfiguration; import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.core.config.CoreQueueConfiguration;
import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.Queue; 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.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.jms.server.JMSServerManager; import org.apache.activemq.artemis.protocol.amqp.converter.AMQPMessageSupport;
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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpMessage;
@ -44,16 +53,26 @@ import org.junit.Before;
*/ */
public class AmqpClientTestSupport extends AmqpTestSupport { public class AmqpClientTestSupport extends AmqpTestSupport {
protected static Symbol SHARED = Symbol.getSymbol("shared"); protected static final Symbol SHARED = Symbol.getSymbol("shared");
protected static Symbol GLOBAL = Symbol.getSymbol("global"); 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 ActiveMQServer server;
protected MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer();
@Before @Before
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
server = createServer(); server = createServer();
} }
@ -69,18 +88,13 @@ public class AmqpClientTestSupport extends AmqpTestSupport {
} }
connections.clear(); connections.clear();
if (serverManager != null) { try {
try { if (server != null) {
serverManager.stop(); server.stop();
} catch (Throwable ignored) {
ignored.printStackTrace();
} }
serverManager = null; } finally {
super.tearDown();
} }
server.stop();
super.tearDown();
} }
protected boolean isAutoCreateQueues() { protected boolean isAutoCreateQueues() {
@ -91,6 +105,10 @@ public class AmqpClientTestSupport extends AmqpTestSupport {
return true; return true;
} }
protected boolean isSecurityEnabled() {
return false;
}
protected String getDeadLetterAddress() { protected String getDeadLetterAddress() {
return "ActiveMQ.DLQ"; return "ActiveMQ.DLQ";
} }
@ -99,48 +117,129 @@ public class AmqpClientTestSupport extends AmqpTestSupport {
return 10; return 10;
} }
public URI getBrokerOpenWireConnectionURI() {
return getBrokerAmqpConnectionURI();
}
protected ActiveMQServer createServer() throws Exception { protected ActiveMQServer createServer() throws Exception {
ActiveMQServer server = createServer(true, true); return createServer(AMQP_PORT);
serverManager = new JMSServerManagerImpl(server); }
Configuration serverConfig = server.getConfiguration();
// Address 1 protected ActiveMQServer createServer(int port) throws Exception {
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);
// Address 1....N final ActiveMQServer server = this.createServer(true, true);
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);
}
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 // Address configuration
AddressSettings addressSettings = new AddressSettings(); AddressSettings addressSettings = new AddressSettings();
addressSettings.setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
addressSettings.setAutoCreateQueues(isAutoCreateQueues()); addressSettings.setAutoCreateQueues(isAutoCreateQueues());
addressSettings.setAutoCreateAddresses(isAutoCreateQueues()); addressSettings.setAutoCreateAddresses(isAutoCreateQueues());
addressSettings.setDeadLetterAddress(new SimpleString(getDeadLetterAddress())); addressSettings.setDeadLetterAddress(SimpleString.toSimpleString(getDeadLetterAddress()));
addressSettings.setExpiryAddress(SimpleString.toSimpleString(getDeadLetterAddress()));
serverConfig.getAddressesSettings().put("#", addressSettings); server.getConfiguration().getAddressesSettings().put("#", addressSettings);
serverConfig.setSecurityEnabled(false); Set<TransportConfiguration> acceptors = server.getConfiguration().getAcceptorConfigurations();
Set<TransportConfiguration> acceptors = serverConfig.getAcceptorConfigurations();
for (TransportConfiguration tc : acceptors) { for (TransportConfiguration tc : acceptors) {
if (tc.getName().equals("netty")) { if (tc.getName().equals("netty-acceptor")) {
tc.getExtraParams().put("anycastPrefix", "anycast://"); tc.getExtraParams().put("anycastPrefix", "anycast://");
tc.getExtraParams().put("multicastPrefix", "multicast://"); 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) { public Queue getProxyToQueue(String queueName) {
@ -151,6 +250,10 @@ public class AmqpClientTestSupport extends AmqpTestSupport {
return getName(); return getName();
} }
public String getTopicName() {
return getName() + "-Topic";
}
public String getQueueName() { public String getQueueName() {
return getName(); return getName();
} }
@ -166,17 +269,45 @@ public class AmqpClientTestSupport extends AmqpTestSupport {
this.useSSL = useSSL; 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(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());
AmqpSession session = connection.createSession(); try {
AmqpSender sender = session.createSender(address); AmqpSession session = connection.createSession();
for (int i = 0; i < numMessages; i++) { AmqpSender sender = session.createSender(destinationName);
AmqpMessage message = new AmqpMessage();
message.setText("message-" + i); for (int i = 0; i < count; ++i) {
sender.send(message); 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.ActiveMQConnectionFactory;
import org.apache.activemq.artemis.core.server.Queue; 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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpMessage; 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 * Test that the broker can pass through an AMQP message with a described type in the message
* body regardless of transformer in use. * body regardless of transformer in use.
*/ */
public class AmqpDescribedTypePayloadTest extends AmqpClientTestSupport { public class AmqpDescribedTypePayloadTest extends JMSClientTestSupport {
@Test(timeout = 60000) @Test(timeout = 60000)
public void testSendMessageWithDescribedTypeInBody() throws Exception { public void testSendMessageWithDescribedTypeInBody() throws Exception {
@ -87,7 +88,7 @@ public class AmqpDescribedTypePayloadTest extends AmqpClientTestSupport {
Queue queue = getProxyToQueue(getQueueName()); Queue queue = getProxyToQueue(getQueueName());
assertEquals(1, queue.getMessageCount()); assertEquals(1, queue.getMessageCount());
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(getBrokerOpenWireConnectionURI());
Connection jmsConnection = factory.createConnection(); Connection jmsConnection = factory.createConnection();
try { try {
Session jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
@ -118,10 +119,10 @@ public class AmqpDescribedTypePayloadTest extends AmqpClientTestSupport {
sender.close(); sender.close();
Queue queue = getProxyToQueue(getQueueName()); 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 // Receive and resend with Qpid JMS client
JmsConnectionFactory factory = new JmsConnectionFactory("amqp://localhost:61616"); JmsConnectionFactory factory = new JmsConnectionFactory(getBrokerQpidJMSConnectionURI());
Connection jmsConnection = factory.createConnection(); Connection jmsConnection = factory.createConnection();
try { try {
Session jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); 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.api.core.SimpleString;
import org.apache.activemq.artemis.core.postoffice.Binding; 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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpFrameValidator; import org.apache.activemq.transport.amqp.client.AmqpFrameValidator;
@ -53,13 +51,6 @@ public class AmqpDurableReceiverTest extends AmqpClientTestSupport {
private final String SELECTOR_STRING = "color = red"; 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) @Test(timeout = 60000)
public void testCreateDurableReceiver() throws Exception { public void testCreateDurableReceiver() throws Exception {
@ -365,15 +356,11 @@ public class AmqpDurableReceiverTest extends AmqpClientTestSupport {
return null; return null;
} }
public String getContainerID() { private String getContainerID() {
return "myContainerID"; return "myContainerID";
} }
public String getSubscriptionName() { private String getSubscriptionName() {
return "mySubscription"; 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 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.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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpMessage;
import org.apache.activemq.transport.amqp.client.AmqpReceiver; import org.apache.activemq.transport.amqp.client.AmqpReceiver;
import org.apache.activemq.transport.amqp.client.AmqpSender; import org.apache.activemq.transport.amqp.client.AmqpSender;
import org.apache.activemq.transport.amqp.client.AmqpSession; import org.apache.activemq.transport.amqp.client.AmqpSession;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
public class AmqpExpiredMessageTest extends AmqpClientTestSupport { public class AmqpExpiredMessageTest extends AmqpClientTestSupport {
@ -55,7 +58,7 @@ public class AmqpExpiredMessageTest extends AmqpClientTestSupport {
AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS); AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS);
assertNull(received); assertNull(received);
assertEquals(1, queueView.getMessagesExpired()); assertTrue("Message should have expired", Wait.waitFor(() -> queueView.getMessagesExpired() == 1));
connection.close(); connection.close();
} }
@ -119,7 +122,7 @@ public class AmqpExpiredMessageTest extends AmqpClientTestSupport {
AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS); AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS);
assertNull(received); assertNull(received);
assertEquals(1, queueView.getMessagesExpired()); assertTrue("Message should have expired", Wait.waitFor(() -> queueView.getMessagesExpired() == 1));
connection.close(); connection.close();
} }
@ -154,7 +157,7 @@ public class AmqpExpiredMessageTest extends AmqpClientTestSupport {
AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS); AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS);
assertNull(received); assertNull(received);
assertEquals(1, queueView.getMessagesExpired()); assertTrue("Message should have expired", Wait.waitFor(() -> queueView.getMessagesExpired() == 1));
connection.close(); connection.close();
} }
@ -253,8 +256,64 @@ public class AmqpExpiredMessageTest extends AmqpClientTestSupport {
AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS); AmqpMessage received = receiver.receive(1, TimeUnit.SECONDS);
assertNull(received); assertNull(received);
assertEquals(1, queueView.getMessagesExpired()); assertTrue("Message should have expired", Wait.waitFor(() -> queueView.getMessagesExpired() == 1));
connection.close(); 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; 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.RoutingType;
import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.TransportConfiguration; 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.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator; 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.Binding;
import org.apache.activemq.artemis.core.postoffice.Bindings; import org.apache.activemq.artemis.core.postoffice.Bindings;
import org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding; 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.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.activemq.artemis.utils.CompositeAddress;
import org.apache.qpid.jms.JmsConnectionFactory;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import javax.jms.Connection; public class AmqpFullyQualifiedNameTest extends JMSClientTestSupport {
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";
private SimpleString anycastAddress = new SimpleString("address.anycast"); private SimpleString anycastAddress = new SimpleString("address.anycast");
private SimpleString multicastAddress = new SimpleString("address.multicast"); private SimpleString multicastAddress = new SimpleString("address.multicast");
@ -57,7 +53,6 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase {
private SimpleString anycastQ2 = new SimpleString("q2"); private SimpleString anycastQ2 = new SimpleString("q2");
private SimpleString anycastQ3 = new SimpleString("q3"); private SimpleString anycastQ3 = new SimpleString("q3");
JmsConnectionFactory factory = new JmsConnectionFactory(amqpConnectionUri);
private ServerLocator locator; private ServerLocator locator;
@Override @Override
@ -65,36 +60,20 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase {
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); 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(); locator = createNettyNonHALocator();
} }
@Override @Override
@After protected void addAdditionalAcceptors(ActiveMQServer server) throws Exception {
public void tearDown() throws Exception { server.getConfiguration().addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, new HashMap<String, Object>(), "netty", new HashMap<String, Object>()));
super.tearDown();
} }
@Override @Test(timeout = 60000)
protected void configureServer(Configuration serverConfig) {
serverConfig.addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, new HashMap<String, Object>(), "netty", new HashMap<String, Object>()));
}
@Test
//there isn't much use of FQQN for topics //there isn't much use of FQQN for topics
//however we can test query functionality //however we can test query functionality
public void testTopic() throws Exception { public void testTopic() throws Exception {
Connection connection = factory.createConnection(); Connection connection = createConnection(false);
try { try {
connection.setClientID("FQQNconn"); connection.setClientID("FQQNconn");
connection.start(); 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, anycastQ2, null, true, false, -1, false, true);
server.createQueue(anycastAddress, RoutingType.ANYCAST, anycastQ3, 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 { try {
connection.start(); connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue q1 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ1).toString()); javax.jms.Queue q1 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ1).toString());
Queue q2 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ2).toString()); javax.jms.Queue q2 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ2).toString());
Queue q3 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ3).toString()); javax.jms.Queue q3 = session.createQueue(CompositeAddress.toFullQN(anycastAddress, anycastQ3).toString());
//send 3 messages to anycastAddress //send 3 messages to anycastAddress
ClientSessionFactory cf = createSessionFactory(locator); ClientSessionFactory cf = createSessionFactory(locator);
@ -167,18 +146,25 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase {
assertNotNull(consumer2.receive(2000)); assertNotNull(consumer2.receive(2000));
assertNotNull(consumer3.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(); connection.close();
//queues are empty now //queues are empty now
for (SimpleString q : new SimpleString[]{anycastQ1, anycastQ2, anycastQ3}) { for (SimpleString q : new SimpleString[]{anycastQ1, anycastQ2, anycastQ3}) {
//FQQN query //FQQN query
QueueQueryResult query = server.queueQuery(CompositeAddress.toFullQN(anycastAddress, q)); final QueueQueryResult query = server.queueQuery(CompositeAddress.toFullQN(anycastAddress, q));
assertTrue(query.isExists()); assertTrue(query.isExists());
assertEquals(anycastAddress, query.getAddress()); assertEquals(anycastAddress, query.getAddress());
assertEquals(CompositeAddress.toFullQN(anycastAddress, q), query.getName()); assertEquals(CompositeAddress.toFullQN(anycastAddress, q), query.getName());
assertEquals(0, query.getMessageCount()); assertEquals("Message not consumed", 0, query.getMessageCount());
//try query again using qName //try query again using qName
query = server.queueQuery(q); QueueQueryResult qNameQuery = server.queueQuery(q);
assertEquals(q, query.getName()); assertEquals(q, qNameQuery.getName());
} }
} finally { } finally {
connection.close(); connection.close();
@ -189,14 +175,14 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase {
public void testQueueSpecial() throws Exception { public void testQueueSpecial() throws Exception {
server.createQueue(anycastAddress, RoutingType.ANYCAST, anycastQ1, null, true, false, -1, false, true); server.createQueue(anycastAddress, RoutingType.ANYCAST, anycastQ1, null, true, false, -1, false, true);
Connection connection = factory.createConnection(); Connection connection = createConnection();
try { try {
connection.start(); connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//::queue ok! //::queue ok!
String specialName = CompositeAddress.toFullQN(new SimpleString(""), anycastQ1).toString(); String specialName = CompositeAddress.toFullQN(new SimpleString(""), anycastQ1).toString();
Queue q1 = session.createQueue(specialName); javax.jms.Queue q1 = session.createQueue(specialName);
ClientSessionFactory cf = createSessionFactory(locator); ClientSessionFactory cf = createSessionFactory(locator);
ClientSession coreSession = cf.createSession(); ClientSession coreSession = cf.createSession();
@ -228,10 +214,8 @@ public class ProtonFullQualifiedNameTest extends ProtonTestBase {
} catch (InvalidDestinationException e) { } catch (InvalidDestinationException e) {
//expected //expected
} }
} finally { } finally {
connection.close(); connection.close();
} }
} }
} }

View File

@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport; 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.tests.util.Wait;
import org.apache.activemq.artemis.utils.VersionLoader; import org.apache.activemq.artemis.utils.VersionLoader;
import org.apache.activemq.transport.amqp.client.AmqpClient; 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 BROKER_NAME = "localhost";
private static final String PRODUCT_NAME = "apache-activemq-artemis"; 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 { public void testBrokerContainerId() throws Exception {
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
assertNotNull(client); assertNotNull(client);
@ -77,7 +98,7 @@ public class AmqpInboundConnectionTest extends AmqpClientTestSupport {
} }
} }
@Test @Test(timeout = 60000)
public void testBrokerConnectionProperties() throws Exception { public void testBrokerConnectionProperties() throws Exception {
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();

View File

@ -31,7 +31,7 @@ import org.junit.Test;
public class AmqpManagementTest extends AmqpClientTestSupport { public class AmqpManagementTest extends AmqpClientTestSupport {
@Test @Test(timeout = 60000)
public void testManagementQueryOverAMQP() throws Throwable { public void testManagementQueryOverAMQP() throws Throwable {
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());

View File

@ -16,7 +16,6 @@
*/ */
package org.apache.activemq.artemis.tests.integration.amqp; package org.apache.activemq.artemis.tests.integration.amqp;
import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; 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.apache.qpid.proton.message.impl.MessageImpl;
import org.junit.Test; import org.junit.Test;
public class ProtonMaxFrameSizeTest extends ProtonTestBase { public class AmqpMaxFrameSizeTest extends AmqpClientTestSupport {
private static final int FRAME_SIZE = 512; private static final int FRAME_SIZE = 512;
@Override @Override
protected void configureAmqp(Map<String, Object> params) { protected void configureAMQPAcceptorParameters(Map<String, Object> params) {
params.put("maxFrameSize", FRAME_SIZE); params.put("maxFrameSize", FRAME_SIZE);
} }
@Test @Test(timeout = 60000)
public void testMultipleTransfers() throws Exception { public void testMultipleTransfers() throws Exception {
String testQueueName = "ConnectionFrameSize"; String testQueueName = "ConnectionFrameSize";
int nMsgs = 200; int nMsgs = 200;
AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect());
AmqpConnection amqpConnection = client.createConnection();
try { try {
amqpConnection.connect(); connection.connect();
AmqpSession session = amqpConnection.createSession(); AmqpSession session = connection.createSession();
AmqpSender sender = session.createSender(testQueueName); AmqpSender sender = session.createSender(testQueueName);
final int payload = FRAME_SIZE * 16; final int payload = FRAME_SIZE * 16;
@ -79,7 +77,7 @@ public class ProtonMaxFrameSizeTest extends ProtonTestBase {
} }
} finally { } finally {
amqpConnection.close(); connection.close();
} }
} }
@ -92,5 +90,4 @@ public class ProtonMaxFrameSizeTest extends ProtonTestBase {
message.setBytes(payload); message.setBytes(payload);
return message; 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 java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.core.server.Queue; 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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpMessage;
@ -192,7 +193,7 @@ public class AmqpPresettledReceiverTest extends AmqpClientTestSupport {
message.setText("Test-Message"); message.setText("Test-Message");
sender.send(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); AmqpReceiver receiver = session.createReceiver(getQueueName(), null, false, true);
@ -228,7 +229,7 @@ public class AmqpPresettledReceiverTest extends AmqpClientTestSupport {
message.setText("Test-Message"); message.setText("Test-Message");
sender.send(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); AmqpReceiver receiver = session.createReceiver(getQueueName(), null, false, true);
@ -250,21 +251,4 @@ public class AmqpPresettledReceiverTest extends AmqpClientTestSupport {
sender.close(); sender.close();
connection.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.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.TimeUnit; 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.integration.IntegrationTestLogger;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.artemis.tests.util.Wait;
import org.fusesource.hawtbuf.Buffer; import org.fusesource.hawtbuf.Buffer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
public class ProtonTestForHeader extends ActiveMQTestBase { public class AmqpProtocolHeaderHandlingTest extends AmqpClientTestSupport {
private ActiveMQServer server;
@Override @Override
@Before protected boolean isSecurityEnabled() {
public void setUp() throws Exception { return true;
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");
} }
@Override @Test(timeout = 60000)
@After public void testNonSaslHeaderRejectedOnConnect() throws Exception {
public void tearDown() throws Exception {
try {
server.stop();
} finally {
super.tearDown();
}
}
@Test
public void testSimpleBytes() throws Exception {
final AmqpHeader header = new AmqpHeader(); final AmqpHeader header = new AmqpHeader();
header.setProtocolId(0); header.setProtocolId(0);
@ -76,13 +44,15 @@ public class ProtonTestForHeader extends ActiveMQTestBase {
header.setRevision(0); header.setRevision(0);
final ClientConnection connection = new ClientConnection(); final ClientConnection connection = new ClientConnection();
connection.open("localhost", 5672); connection.open("localhost", AMQP_PORT);
connection.send(header); connection.send(header);
AmqpHeader response = connection.readAmqpHeader(); AmqpHeader response = connection.readAmqpHeader();
assertNotNull(response); assertNotNull(response);
assertEquals(3, response.getProtocolId());
IntegrationTestLogger.LOGGER.info("Broker responded with: " + response); 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() { assertTrue("Broker should have closed client connection", Wait.waitFor(new Wait.Condition() {
@Override @Override
@ -128,6 +98,7 @@ public class ProtonTestForHeader extends ActiveMQTestBase {
} }
} }
@SuppressWarnings("unused")
private class AmqpHeader { private class AmqpHeader {
final Buffer PREFIX = new Buffer(new byte[]{'A', 'M', 'Q', 'P'}); 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.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpMessage;
import org.apache.activemq.transport.amqp.client.AmqpReceiver; 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.activemq.transport.amqp.client.AmqpSession;
import org.apache.qpid.proton.message.Message; import org.apache.qpid.proton.message.Message;
import org.junit.Test; import org.junit.Test;
@ -57,7 +56,6 @@ public class AmqpReceiverDispositionTest extends AmqpClientTestSupport {
receiver2.flow(1); receiver2.flow(1);
message.release(); message.release();
// Read the message again and validate its state // Read the message again and validate its state
message = receiver2.receive(10, TimeUnit.SECONDS); message = receiver2.receive(10, TimeUnit.SECONDS);
assertNotNull("did not receive message again", message); assertNotNull("did not receive message again", message);
@ -172,21 +170,4 @@ public class AmqpReceiverDispositionTest extends AmqpClientTestSupport {
connection.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

@ -19,11 +19,11 @@ package org.apache.activemq.artemis.tests.integration.amqp;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.core.server.Queue; 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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpMessage;
import org.apache.activemq.transport.amqp.client.AmqpReceiver; 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.activemq.transport.amqp.client.AmqpSession;
import org.junit.Test; import org.junit.Test;
@ -33,46 +33,81 @@ import org.junit.Test;
public class AmqpReceiverDrainTest extends AmqpClientTestSupport { public class AmqpReceiverDrainTest extends AmqpClientTestSupport {
@Test(timeout = 60000) @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; int MSG_COUNT = 20;
sendMessages(getQueueName(), MSG_COUNT);
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = client.connect(); AmqpConnection connection = addConnection(client.connect());
AmqpSession session = connection.createSession(); 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(MSG_COUNT, queueView.getMessageCount());
assertEquals(0, queueView.getDeliveringCount());
receiver.drain(MSG_COUNT); receiver.drain(MSG_COUNT);
for (int i = 0; i < MSG_COUNT; ++i) { for (int i = 0; i < MSG_COUNT; ++i) {
AmqpMessage message = receiver.receive(5, TimeUnit.SECONDS); 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(); message.accept();
} }
receiver.close(); receiver.close();
assertEquals(0, queueView.getMessageCount());
connection.close(); connection.close();
} }
@Test(timeout = 60000) @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(); AmqpClient client = createAmqpClient();
AmqpConnection connection = client.connect(); AmqpConnection connection = addConnection(client.connect());
AmqpSession session = connection.createSession(); AmqpSession session = connection.createSession();
AmqpReceiver receiver = session.createReceiver(getQueueName()); AmqpReceiver receiver = session.createReceiver(destinationName);
receiver.flow(10); receiver.flow(10);
Queue queueView = getProxyToQueue(getQueueName()); Queue queueView = getProxyToQueue(destinationName);
assertEquals(0, queueView.getMessageCount()); assertEquals(0, queueView.getMessageCount());
assertEquals(0, queueView.getDeliveringCount()); assertEquals(0, queueView.getMessagesAcknowledged());
assertEquals(10, receiver.getReceiver().getRemoteCredit()); assertEquals(10, receiver.getReceiver().getRemoteCredit());
@ -84,18 +119,36 @@ public class AmqpReceiverDrainTest extends AmqpClientTestSupport {
} }
@Test(timeout = 60000) @Test(timeout = 60000)
public void testPullOneFromRemote() throws Exception { public void testPullOneFromRemoteQueue() throws Exception {
int MSG_COUNT = 20; doTestPullOneFromRemote(false);
sendMessages(getQueueName(), MSG_COUNT); }
@Test(timeout = 60000)
public void testPullOneFromRemoteTopic() throws Exception {
doTestPullOneFromRemote(true);
}
private void doTestPullOneFromRemote(boolean topic) throws Exception {
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = client.connect(); AmqpConnection connection = addConnection(client.connect());
AmqpSession session = connection.createSession(); 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(MSG_COUNT, queueView.getMessageCount());
assertEquals(0, queueView.getDeliveringCount());
assertEquals(0, receiver.getReceiver().getRemoteCredit()); assertEquals(0, receiver.getReceiver().getRemoteCredit());
@ -107,24 +160,39 @@ public class AmqpReceiverDrainTest extends AmqpClientTestSupport {
receiver.close(); receiver.close();
assertEquals(MSG_COUNT - 1, queueView.getMessageCount());
assertEquals(1, queueView.getMessagesAcknowledged());
connection.close(); connection.close();
} }
@Test(timeout = 60000) @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(); AmqpClient client = createAmqpClient();
AmqpConnection connection = client.connect(); AmqpConnection connection = addConnection(client.connect());
AmqpSession session = connection.createSession(); 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); receiver.flow(10);
Queue queueView = getProxyToQueue(getQueueName()); Queue queueView = getProxyToQueue(destinationName);
assertEquals(0, queueView.getMessageCount()); assertEquals(0, queueView.getMessageCount());
assertEquals(0, queueView.getDeliveringCount());
assertEquals(10, receiver.getReceiver().getRemoteCredit()); assertEquals(10, receiver.getReceiver().getRemoteCredit());
@ -139,27 +207,4 @@ public class AmqpReceiverDrainTest extends AmqpClientTestSupport {
connection.close(); 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; 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.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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpReceiver; import org.apache.activemq.transport.amqp.client.AmqpReceiver;
import org.apache.activemq.transport.amqp.client.AmqpSession; 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.ReceiverSettleMode;
import org.apache.qpid.proton.amqp.transport.SenderSettleMode; 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; import org.junit.Test;
/** /**
@ -30,6 +55,119 @@ import org.junit.Test;
*/ */
public class AmqpReceiverTest extends AmqpClientTestSupport { 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) @Test(timeout = 60000)
public void testSenderSettlementModeSettledIsHonored() throws Exception { public void testSenderSettlementModeSettledIsHonored() throws Exception {
doTestSenderSettlementModeIsHonored(SenderSettleMode.SETTLED); doTestSenderSettlementModeIsHonored(SenderSettleMode.SETTLED);
@ -96,4 +234,164 @@ public class AmqpReceiverTest extends AmqpClientTestSupport {
receiver.close(); receiver.close();
connection.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 { public void testScheduleWithDelay() throws Exception {
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());

View File

@ -17,21 +17,9 @@
package org.apache.activemq.artemis.tests.integration.amqp; package org.apache.activemq.artemis.tests.integration.amqp;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; 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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpMessage; 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.AmqpSession;
import org.apache.activemq.transport.amqp.client.AmqpValidator; import org.apache.activemq.transport.amqp.client.AmqpValidator;
import org.apache.qpid.proton.engine.Delivery; import org.apache.qpid.proton.engine.Delivery;
import org.apache.qpid.proton.engine.Sender;
import org.junit.Test; import org.junit.Test;
public class AmqpSecurityTest extends AmqpClientTestSupport { public class AmqpSecurityTest extends AmqpClientTestSupport {
private String user1 = "user1";
private String password1 = "password1";
@Override @Override
protected ActiveMQServer createServer() throws Exception { protected boolean isSecurityEnabled() {
ActiveMQServer server = createServer(true, true); return 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;
} }
@Test(timeout = 60000) @Test(timeout = 60000)
public void testSaslAuthWithInvalidCredentials() throws Exception { public void testSaslAuthWithInvalidCredentials() throws Exception {
AmqpConnection connection = null; AmqpConnection connection = null;
AmqpClient client = createAmqpClient("foo", "foo"); AmqpClient client = createAmqpClient(fullUser, guestUser);
try { try {
connection = client.connect(); connection = client.connect();
fail("Should authenticate even with authzid set"); fail("Should not authenticate when invalid credentials provided");
} catch (Exception ex) { } catch (Exception ex) {
// Expected
} finally { } finally {
if (connection != null) { if (connection != null) {
connection.close(); connection.close();
@ -87,8 +57,8 @@ public class AmqpSecurityTest extends AmqpClientTestSupport {
@Test(timeout = 60000) @Test(timeout = 60000)
public void testSaslAuthWithAuthzid() throws Exception { public void testSaslAuthWithAuthzid() throws Exception {
AmqpConnection connection = null; AmqpConnection connection = null;
AmqpClient client = createAmqpClient("foo", "bar"); AmqpClient client = createAmqpClient(guestUser, guestPass);
client.setAuthzid("foo"); client.setAuthzid(guestUser);
try { try {
connection = client.connect(); connection = client.connect();
@ -104,7 +74,7 @@ public class AmqpSecurityTest extends AmqpClientTestSupport {
@Test(timeout = 60000) @Test(timeout = 60000)
public void testSaslAuthWithoutAuthzid() throws Exception { public void testSaslAuthWithoutAuthzid() throws Exception {
AmqpConnection connection = null; AmqpConnection connection = null;
AmqpClient client = createAmqpClient("foo", "bar"); AmqpClient client = createAmqpClient(guestUser, guestPass);
try { try {
connection = client.connect(); connection = client.connect();
@ -119,20 +89,22 @@ public class AmqpSecurityTest extends AmqpClientTestSupport {
@Test(timeout = 60000) @Test(timeout = 60000)
public void testSendAndRejected() throws Exception { public void testSendAndRejected() throws Exception {
AmqpConnection connection = null;
AmqpClient client = createAmqpClient("foo", "bar");
CountDownLatch latch = new CountDownLatch(1); CountDownLatch latch = new CountDownLatch(1);
AmqpClient client = createAmqpClient(guestUser, guestPass);
client.setValidator(new AmqpValidator() { client.setValidator(new AmqpValidator() {
@Override @Override
public void inspectDeliveryUpdate(Delivery delivery) { public void inspectDeliveryUpdate(Sender sender, Delivery delivery) {
super.inspectDeliveryUpdate(delivery);
if (!delivery.remotelySettled()) { if (!delivery.remotelySettled()) {
markAsInvalid("delivery is not remotely settled"); markAsInvalid("delivery is not remotely settled");
} }
latch.countDown(); latch.countDown();
} }
}); });
connection = addConnection(client.connect());
AmqpConnection connection = addConnection(client.connect());
AmqpSession session = connection.createSession(); AmqpSession session = connection.createSession();
AmqpSender sender = session.createSender(getQueueName()); AmqpSender sender = session.createSender(getQueueName());
@ -145,8 +117,8 @@ public class AmqpSecurityTest extends AmqpClientTestSupport {
try { try {
sender.send(message); sender.send(message);
} catch (IOException e) { } catch (IOException e) {
//
} }
assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS));
connection.getStateInspector().assertValid(); connection.getStateInspector().assertValid();
connection.close(); connection.close();
@ -154,11 +126,9 @@ public class AmqpSecurityTest extends AmqpClientTestSupport {
@Test(timeout = 60000) @Test(timeout = 60000)
public void testSendMessageFailsOnAnonymousRelayWhenNotAuthorizedToSendToAddress() throws Exception { public void testSendMessageFailsOnAnonymousRelayWhenNotAuthorizedToSendToAddress() throws Exception {
server.addAddressInfo(new AddressInfo(SimpleString.toSimpleString(getQueueName()), RoutingType.ANYCAST)); AmqpClient client = createAmqpClient(guestUser, guestPass);
server.createQueue(new SimpleString(getQueueName()), RoutingType.ANYCAST, new SimpleString(getQueueName()), null, true, false);
AmqpClient client = createAmqpClient(user1, password1);
AmqpConnection connection = client.connect(); AmqpConnection connection = client.connect();
try { try {
AmqpSession session = connection.createSession(); AmqpSession session = connection.createSession();
@ -181,5 +151,4 @@ public class AmqpSecurityTest extends AmqpClientTestSupport {
connection.close(); connection.close();
} }
} }
} }

View File

@ -16,28 +16,23 @@
*/ */
package org.apache.activemq.artemis.tests.integration.amqp; 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.contains;
import static org.apache.activemq.transport.amqp.AmqpSupport.findFilter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; 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.RoutingType;
import org.apache.activemq.artemis.api.core.SimpleString; 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.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.protocol.amqp.proton.AmqpSupport;
import org.apache.activemq.artemis.tests.util.Wait; import org.apache.activemq.artemis.tests.util.Wait;
import org.apache.activemq.transport.amqp.client.AmqpClient; 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.AmqpSession;
import org.apache.activemq.transport.amqp.client.AmqpValidator; import org.apache.activemq.transport.amqp.client.AmqpValidator;
import org.apache.qpid.proton.amqp.Symbol; 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.apache.qpid.proton.engine.Sender;
import org.jgroups.util.UUID; import org.jgroups.util.UUID;
import org.junit.Test; import org.junit.Test;
@ -63,19 +56,14 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport {
protected static final Logger LOG = LoggerFactory.getLogger(AmqpSendReceiveTest.class); protected static final Logger LOG = LoggerFactory.getLogger(AmqpSendReceiveTest.class);
@Test(timeout = 60000) @Override
public void testCreateQueueReceiver() throws Exception { protected boolean isAutoCreateQueues() {
AmqpClient client = createAmqpClient(); return false;
AmqpConnection connection = addConnection(client.connect()); }
AmqpSession session = connection.createSession();
AmqpReceiver receiver = session.createReceiver(getQueueName()); @Override
protected boolean isAutoCreateAddresses() {
Queue queue = getProxyToQueue(getQueueName()); return false;
assertNotNull(queue);
receiver.close();
connection.close();
} }
@Test(timeout = 60000) @Test(timeout = 60000)
@ -103,90 +91,6 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport {
assertEquals(0, queue.getMessageCount()); 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) @Test(timeout = 60000)
public void testQueueReceiverReadMessage() throws Exception { public void testQueueReceiverReadMessage() throws Exception {
sendMessages(getQueueName(), 1); sendMessages(getQueueName(), 1);
@ -209,108 +113,6 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport {
connection.close(); 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) @Test(timeout = 60000)
public void testMessageDurableFalse() throws Exception { public void testMessageDurableFalse() throws Exception {
sendMessages(getQueueName(), 1, false); sendMessages(getQueueName(), 1, false);
@ -870,7 +672,7 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport {
message1.setMessageId("ID:Message:1"); message1.setMessageId("ID:Message:1");
sender.send(message1); sender.send(message1);
assertEquals(1, queue.getMessageCount()); assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1));
receiver1.flow(1); receiver1.flow(1);
message1 = receiver1.receive(50, TimeUnit.SECONDS); message1 = receiver1.receive(50, TimeUnit.SECONDS);
assertNotNull("Should have read a message", message1); assertNotNull("Should have read a message", message1);
@ -884,7 +686,7 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport {
message2.setMessageId("ID:Message:2"); message2.setMessageId("ID:Message:2");
sender.send(message2); sender.send(message2);
assertEquals(1, queue.getMessageCount()); assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1));
receiver1.flow(1); receiver1.flow(1);
message2 = receiver1.receive(50, TimeUnit.SECONDS); message2 = receiver1.receive(50, TimeUnit.SECONDS);
assertNotNull("Should have read a message", message2); assertNotNull("Should have read a message", message2);
@ -1018,7 +820,7 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport {
connection.close(); connection.close();
} }
@Test @Test(timeout = 60000)
public void testDeliveryDelayOfferedWhenRequested() throws Exception { public void testDeliveryDelayOfferedWhenRequested() throws Exception {
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
client.setValidator(new AmqpValidator() { client.setValidator(new AmqpValidator() {
@ -1036,7 +838,7 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport {
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());
AmqpSession session = connection.createSession(); 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); assertNotNull(sender);
connection.getStateInspector().assertValid(); connection.getStateInspector().assertValid();
@ -1100,45 +902,119 @@ public class AmqpSendReceiveTest extends AmqpClientTestSupport {
connection.close(); connection.close();
} }
public void sendMessages(String destinationName, int count) throws Exception { @Test(timeout = 60000)
sendMessages(destinationName, count, null); public void testLinkDetatchErrorIsCorrectWhenQueueDoesNotExists() throws Exception {
}
public void sendMessages(String destinationName, int count, RoutingType routingType) throws Exception {
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); 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 { try {
AmqpSession session = connection.createSession(); 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();
AmqpMessage message = new AmqpMessage(); message.setText("TestPayload");
message.setMessageId("MessageID:" + i); sender.send(message);
if (routingType != null) {
message.setMessageAnnotation(AMQPMessageSupport.ROUTING_TYPE.toString(), routingType.getType()); 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 { for (int i = 0; i < MSG_COUNT; i++) {
AmqpClient client = createAmqpClient(); AmqpMessage message = new AmqpMessage();
AmqpConnection connection = addConnection(client.connect()); message.setMessageId("msg" + i);
try { sender.send(message);
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();
} }
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; 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.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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpMessage;
import org.apache.activemq.transport.amqp.client.AmqpSender; import org.apache.activemq.transport.amqp.client.AmqpSender;
import org.apache.activemq.transport.amqp.client.AmqpSession; 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.ReceiverSettleMode;
import org.apache.qpid.proton.amqp.transport.SenderSettleMode; 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; import org.junit.Test;
/** /**
@ -101,4 +109,74 @@ public class AmqpSenderTest extends AmqpClientTestSupport {
connection.close(); 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 { public class AmqpTestSupport extends ActiveMQTestBase {
protected static final int AMQP_PORT = 5672;
protected LinkedList<AmqpConnection> connections = new LinkedList<>(); protected LinkedList<AmqpConnection> connections = new LinkedList<>();
protected boolean useSSL; protected boolean useSSL;
@ -65,7 +67,7 @@ public class AmqpTestSupport extends ActiveMQTestBase {
boolean webSocket = false; boolean webSocket = false;
try { try {
int port = 61616; int port = AMQP_PORT;
String uri = null; String uri = null;

View File

@ -1,4 +1,4 @@
/** /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.activemq.artemis.tests.integration.amqp; package org.apache.activemq.artemis.tests.integration.amqp;
import java.io.IOException; 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.RoutingType;
import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.server.Queue; 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.AmqpClient;
import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpConnection;
import org.apache.activemq.transport.amqp.client.AmqpMessage; 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.transaction.TransactionalState;
import org.apache.qpid.proton.amqp.transport.DeliveryState; import org.apache.qpid.proton.amqp.transport.DeliveryState;
import org.apache.qpid.proton.engine.Delivery; import org.apache.qpid.proton.engine.Delivery;
import org.apache.qpid.proton.engine.Sender;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -98,7 +99,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport {
sender.setStateInspector(new AmqpValidator() { sender.setStateInspector(new AmqpValidator() {
@Override @Override
public void inspectDeliveryUpdate(Delivery delivery) { public void inspectDeliveryUpdate(Sender sender, Delivery delivery) {
if (delivery.remotelySettled()) { if (delivery.remotelySettled()) {
DeliveryState state = delivery.getRemoteState(); DeliveryState state = delivery.getRemoteState();
if (state instanceof TransactionalState) { if (state instanceof TransactionalState) {
@ -161,7 +162,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport {
session.commit(); session.commit();
assertEquals(1, queue.getMessageCount()); assertTrue("Message was not queued", Wait.waitFor(() -> queue.getMessageCount() == 1));
sender.close(); sender.close();
connection.close(); connection.close();
@ -205,7 +206,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport {
message.setText("Test-Message"); message.setText("Test-Message");
sender.send(message); sender.send(message);
assertEquals(1, queue.getMessageCount()); assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1));
AmqpReceiver receiver = session.createReceiver(getQueueName()); AmqpReceiver receiver = session.createReceiver(getQueueName());
@ -237,7 +238,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport {
message.setText("Test-Message"); message.setText("Test-Message");
sender.send(message); sender.send(message);
assertEquals(1, queue.getMessageCount()); assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1));
AmqpReceiver receiver = session.createReceiver(getQueueName()); AmqpReceiver receiver = session.createReceiver(getQueueName());
@ -281,7 +282,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport {
message.setText("Test-Message"); message.setText("Test-Message");
sender.send(message); sender.send(message);
assertEquals(1, queue.getMessageCount()); assertTrue("Message did not arrive", Wait.waitFor(() -> queue.getMessageCount() == 1));
AmqpReceiver receiver = session.createReceiver(getQueueName()); AmqpReceiver receiver = session.createReceiver(getQueueName());
@ -853,10 +854,10 @@ public class AmqpTransactionTest extends AmqpClientTestSupport {
@Test(timeout = 120000) @Test(timeout = 120000)
public void testSendPersistentTX() throws Exception { public void testSendPersistentTX() throws Exception {
int MESSAGE_COUNT = 100000; int MESSAGE_COUNT = 2000;
AtomicInteger errors = new AtomicInteger(0); AtomicInteger errors = new AtomicInteger(0);
server.createQueue(SimpleString.toSimpleString("q1"), RoutingType.ANYCAST, SimpleString.toSimpleString("q1"), null, true, false, 1, false, true); 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 sendConnection = factory.createConnection();
Connection consumerConnection = factory.createConnection(); Connection consumerConnection = factory.createConnection();
try { try {
@ -939,7 +940,7 @@ public class AmqpTransactionTest extends AmqpClientTestSupport {
receiver.setStateInspector(new AmqpValidator() { receiver.setStateInspector(new AmqpValidator() {
@Override @Override
public void inspectDeliveryUpdate(Delivery delivery) { public void inspectDeliveryUpdate(Sender sender, Delivery delivery) {
if (delivery.remotelySettled()) { if (delivery.remotelySettled()) {
LOG.info("Receiver got delivery update for: {}", delivery); LOG.info("Receiver got delivery update for: {}", delivery);
if (!(delivery.getRemoteState() instanceof TransactionalState)) { if (!(delivery.getRemoteState() instanceof TransactionalState)) {

View File

@ -1,4 +1,4 @@
/** /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
@ -16,8 +16,13 @@
*/ */
package org.apache.activemq.artemis.tests.integration.amqp; 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.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.AddressInfo;
import org.apache.activemq.artemis.core.server.impl.QueueImpl; import org.apache.activemq.artemis.core.server.impl.QueueImpl;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings; 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.apache.qpid.proton.amqp.messaging.Source;
import org.junit.Test; 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 { public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport {
SimpleString address = new SimpleString("testAddress"); SimpleString address = new SimpleString("testAddress");
@ -46,7 +45,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport {
server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST)); server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST));
server.createQueue(address, RoutingType.ANYCAST, address, null, true, false); server.createQueue(address, RoutingType.ANYCAST, address, null, true, false);
sendMessages(1, address.toString()); sendMessages(address.toString(), 1);
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); 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, queue1, null, true, false);
server.createQueue(address, RoutingType.ANYCAST, address, null, true, false); server.createQueue(address, RoutingType.ANYCAST, address, null, true, false);
sendMessages(2, address.toString()); sendMessages(address.toString(), 2);
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());
@ -89,7 +88,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport {
server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST)); server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST));
server.createQueue(address, RoutingType.ANYCAST, queue1, null, true, false); server.createQueue(address, RoutingType.ANYCAST, queue1, null, true, false);
sendMessages(1, address.toString()); sendMessages(address.toString(), 1);
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); 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, queue1, null, true, false);
server.createQueue(address, RoutingType.ANYCAST, queue2, null, true, false); server.createQueue(address, RoutingType.ANYCAST, queue2, null, true, false);
sendMessages(1, address.toString()); sendMessages(address.toString(), 1);
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());
@ -132,7 +131,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport {
server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST)); server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST));
server.createQueue(address, RoutingType.ANYCAST, queue1, null, true, false); server.createQueue(address, RoutingType.ANYCAST, queue1, null, true, false);
sendMessages(1, address.toString()); sendMessages(address.toString(), 1);
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());
@ -152,7 +151,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport {
public void testConsumeWhenOnlyMulticast() throws Exception { public void testConsumeWhenOnlyMulticast() throws Exception {
server.addAddressInfo(new AddressInfo(address, RoutingType.MULTICAST)); server.addAddressInfo(new AddressInfo(address, RoutingType.MULTICAST));
sendMessages(1, address.toString()); sendMessages(address.toString(), 1);
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());
@ -195,7 +194,7 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport {
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());
AmqpSession session = connection.createSession(); AmqpSession session = connection.createSession();
AmqpReceiver receiver = session.createReceiver(address.toString()); AmqpReceiver receiver = session.createReceiver(address.toString());
sendMessages(1, address.toString()); sendMessages(address.toString(), 1);
receiver.flow(1); receiver.flow(1);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
@ -223,7 +222,6 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport {
connection.close(); connection.close();
} }
protected Source createJmsSource(boolean topic) { protected Source createJmsSource(boolean topic) {
Source source = new Source(); Source source = new Source();
@ -236,5 +234,4 @@ public class BrokerDefinedAnycastConsumerTest extends AmqpClientTestSupport {
return source; return source;
} }
} }

View File

@ -1,4 +1,4 @@
/** /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
@ -16,8 +16,13 @@
*/ */
package org.apache.activemq.artemis.tests.integration.amqp; 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.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.AddressInfo;
import org.apache.activemq.artemis.core.server.impl.QueueImpl; import org.apache.activemq.artemis.core.server.impl.QueueImpl;
import org.apache.activemq.transport.amqp.client.AmqpClient; 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.apache.qpid.proton.amqp.messaging.Source;
import org.junit.Test; 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 { public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport {
SimpleString address = new SimpleString("testAddress"); SimpleString address = new SimpleString("testAddress");
@ -45,7 +44,7 @@ public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport {
server.addAddressInfo(new AddressInfo(address, RoutingType.MULTICAST)); server.addAddressInfo(new AddressInfo(address, RoutingType.MULTICAST));
server.createQueue(address, RoutingType.MULTICAST, address, null, true, false); server.createQueue(address, RoutingType.MULTICAST, address, null, true, false);
sendMessages(1, address.toString()); sendMessages(address.toString(), 1);
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());
@ -65,7 +64,7 @@ public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport {
public void testConsumeWhenOnlyAnycast() throws Exception { public void testConsumeWhenOnlyAnycast() throws Exception {
server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST)); server.addAddressInfo(new AddressInfo(address, RoutingType.ANYCAST));
sendMessages(1, address.toString()); sendMessages(address.toString(), 1);
AmqpClient client = createAmqpClient(); AmqpClient client = createAmqpClient();
AmqpConnection connection = addConnection(client.connect()); AmqpConnection connection = addConnection(client.connect());
@ -102,7 +101,6 @@ public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport {
connection.close(); connection.close();
} }
protected Source createJmsSource(boolean topic) { protected Source createJmsSource(boolean topic) {
Source source = new Source(); Source source = new Source();
@ -115,5 +113,4 @@ public class BrokerDefinedMulticastConsumerTest extends AmqpClientTestSupport {
return source; return source;
} }
} }

View File

@ -1,4 +1,4 @@
/** /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
@ -16,6 +16,8 @@
*/ */
package org.apache.activemq.artemis.tests.integration.amqp; 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.api.core.SimpleString;
import org.apache.activemq.artemis.core.server.impl.QueueImpl; import org.apache.activemq.artemis.core.server.impl.QueueImpl;
import org.apache.activemq.transport.amqp.client.AmqpClient; 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.apache.activemq.transport.amqp.client.AmqpSession;
import org.junit.Test; import org.junit.Test;
import java.util.concurrent.TimeUnit;
public class ClientDefinedAnycastConsumerTest extends AmqpClientTestSupport { public class ClientDefinedAnycastConsumerTest extends AmqpClientTestSupport {
SimpleString address = new SimpleString("testAddress"); SimpleString address = new SimpleString("testAddress");
@ -39,7 +39,7 @@ public class ClientDefinedAnycastConsumerTest extends AmqpClientTestSupport {
AmqpSession session = connection.createSession(); AmqpSession session = connection.createSession();
AmqpReceiver receiver = session.createReceiver(address.toString()); AmqpReceiver receiver = session.createReceiver(address.toString());
sendMessages(1, address.toString()); sendMessages(address.toString(), 1);
receiver.flow(1); receiver.flow(1);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
@ -48,5 +48,4 @@ public class ClientDefinedAnycastConsumerTest extends AmqpClientTestSupport {
receiver.close(); receiver.close();
connection.close(); connection.close();
} }
} }

View File

@ -1,4 +1,4 @@
/** /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
@ -16,8 +16,12 @@
*/ */
package org.apache.activemq.artemis.tests.integration.amqp; 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.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.AddressInfo;
import org.apache.activemq.artemis.core.server.impl.QueueImpl; import org.apache.activemq.artemis.core.server.impl.QueueImpl;
import org.apache.activemq.artemis.tests.util.Wait; 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.apache.qpid.proton.amqp.messaging.TerminusDurability;
import org.junit.Test; 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 { public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
SimpleString address = new SimpleString("testAddress"); SimpleString address = new SimpleString("testAddress");
@ -52,7 +52,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2");
receiver.flow(1); receiver.flow(1);
receiver2.flow(1); receiver2.flow(1);
sendMessages(2, address.toString()); sendMessages(address.toString(), 2);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS);
@ -86,7 +86,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|1"); AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|1");
receiver.flow(1); receiver.flow(1);
receiver2.flow(1); receiver2.flow(1);
sendMessages(2, address.toString()); sendMessages(address.toString(), 2);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS);
@ -114,7 +114,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2");
receiver.flow(1); receiver.flow(1);
receiver2.flow(1); receiver2.flow(1);
sendMessages(2, address.toString()); sendMessages(address.toString(), 2);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS);
@ -145,7 +145,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2");
receiver.flow(1); receiver.flow(1);
receiver2.flow(1); receiver2.flow(1);
sendMessages(2, address.toString()); sendMessages(address.toString(), 2);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS);
@ -178,7 +178,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2");
receiver.flow(1); receiver.flow(1);
receiver2.flow(1); receiver2.flow(1);
sendMessages(2, address.toString()); sendMessages(address.toString(), 2);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS);
@ -206,7 +206,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2");
receiver.flow(1); receiver.flow(1);
receiver2.flow(1); receiver2.flow(1);
sendMessages(2, address.toString()); sendMessages(address.toString(), 2);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS);
@ -244,7 +244,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2");
receiver.flow(1); receiver.flow(1);
receiver2.flow(1); receiver2.flow(1);
sendMessages(2, address.toString()); sendMessages(address.toString(), 2);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS);
@ -282,7 +282,7 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2"); AmqpReceiver receiver2 = session.createMulticastReceiver(source, "myReceiverID", "mySub|2");
receiver.flow(1); receiver.flow(1);
receiver2.flow(1); receiver2.flow(1);
sendMessages(2, address.toString()); sendMessages(address.toString(), 2);
AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS); AmqpMessage amqpMessage = receiver.receive(5, TimeUnit.SECONDS);
assertNotNull(amqpMessage); assertNotNull(amqpMessage);
amqpMessage = receiver2.receive(5, TimeUnit.SECONDS); amqpMessage = receiver2.receive(5, TimeUnit.SECONDS);
@ -313,7 +313,10 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
fail("Exception expected"); fail("Exception expected");
} catch (Exception e) { } catch (Exception e) {
//expected //expected
} finally {
receiver.close();
} }
connection.close(); connection.close();
} }
@ -331,7 +334,10 @@ public class ClientDefinedMultiConsumerTest extends AmqpClientTestSupport {
fail("Exception expected"); fail("Exception expected");
} catch (Exception e) { } catch (Exception e) {
//expected //expected
} finally {
receiver.close();
} }
connection.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;
}
}