mirror of https://github.com/apache/activemq.git
Allow for durable topic consumers to use individual ack mode.
This commit is contained in:
parent
d60022ec65
commit
a88e19e7cd
|
@ -90,7 +90,6 @@ import org.apache.activemq.thread.Scheduler;
|
||||||
import org.apache.activemq.transaction.Synchronization;
|
import org.apache.activemq.transaction.Synchronization;
|
||||||
import org.apache.activemq.usage.MemoryUsage;
|
import org.apache.activemq.usage.MemoryUsage;
|
||||||
import org.apache.activemq.util.Callback;
|
import org.apache.activemq.util.Callback;
|
||||||
import org.apache.activemq.util.JMSExceptionSupport;
|
|
||||||
import org.apache.activemq.util.LongSequenceGenerator;
|
import org.apache.activemq.util.LongSequenceGenerator;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -291,6 +290,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
*
|
*
|
||||||
* @see org.apache.activemq.management.StatsCapable#getStats()
|
* @see org.apache.activemq.management.StatsCapable#getStats()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public StatsImpl getStats() {
|
public StatsImpl getStats() {
|
||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
@ -313,6 +313,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException if the JMS provider fails to create this message due
|
* @throws JMSException if the JMS provider fails to create this message due
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public BytesMessage createBytesMessage() throws JMSException {
|
public BytesMessage createBytesMessage() throws JMSException {
|
||||||
ActiveMQBytesMessage message = new ActiveMQBytesMessage();
|
ActiveMQBytesMessage message = new ActiveMQBytesMessage();
|
||||||
configureMessage(message);
|
configureMessage(message);
|
||||||
|
@ -329,6 +330,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException if the JMS provider fails to create this message due
|
* @throws JMSException if the JMS provider fails to create this message due
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public MapMessage createMapMessage() throws JMSException {
|
public MapMessage createMapMessage() throws JMSException {
|
||||||
ActiveMQMapMessage message = new ActiveMQMapMessage();
|
ActiveMQMapMessage message = new ActiveMQMapMessage();
|
||||||
configureMessage(message);
|
configureMessage(message);
|
||||||
|
@ -346,6 +348,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException if the JMS provider fails to create this message due
|
* @throws JMSException if the JMS provider fails to create this message due
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Message createMessage() throws JMSException {
|
public Message createMessage() throws JMSException {
|
||||||
ActiveMQMessage message = new ActiveMQMessage();
|
ActiveMQMessage message = new ActiveMQMessage();
|
||||||
configureMessage(message);
|
configureMessage(message);
|
||||||
|
@ -361,6 +364,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException if the JMS provider fails to create this message due
|
* @throws JMSException if the JMS provider fails to create this message due
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public ObjectMessage createObjectMessage() throws JMSException {
|
public ObjectMessage createObjectMessage() throws JMSException {
|
||||||
ActiveMQObjectMessage message = new ActiveMQObjectMessage();
|
ActiveMQObjectMessage message = new ActiveMQObjectMessage();
|
||||||
configureMessage(message);
|
configureMessage(message);
|
||||||
|
@ -377,6 +381,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException if the JMS provider fails to create this message due
|
* @throws JMSException if the JMS provider fails to create this message due
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public ObjectMessage createObjectMessage(Serializable object) throws JMSException {
|
public ObjectMessage createObjectMessage(Serializable object) throws JMSException {
|
||||||
ActiveMQObjectMessage message = new ActiveMQObjectMessage();
|
ActiveMQObjectMessage message = new ActiveMQObjectMessage();
|
||||||
configureMessage(message);
|
configureMessage(message);
|
||||||
|
@ -393,6 +398,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException if the JMS provider fails to create this message due
|
* @throws JMSException if the JMS provider fails to create this message due
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public StreamMessage createStreamMessage() throws JMSException {
|
public StreamMessage createStreamMessage() throws JMSException {
|
||||||
ActiveMQStreamMessage message = new ActiveMQStreamMessage();
|
ActiveMQStreamMessage message = new ActiveMQStreamMessage();
|
||||||
configureMessage(message);
|
configureMessage(message);
|
||||||
|
@ -408,6 +414,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException if the JMS provider fails to create this message due
|
* @throws JMSException if the JMS provider fails to create this message due
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public TextMessage createTextMessage() throws JMSException {
|
public TextMessage createTextMessage() throws JMSException {
|
||||||
ActiveMQTextMessage message = new ActiveMQTextMessage();
|
ActiveMQTextMessage message = new ActiveMQTextMessage();
|
||||||
configureMessage(message);
|
configureMessage(message);
|
||||||
|
@ -424,6 +431,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException if the JMS provider fails to create this message due
|
* @throws JMSException if the JMS provider fails to create this message due
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public TextMessage createTextMessage(String text) throws JMSException {
|
public TextMessage createTextMessage(String text) throws JMSException {
|
||||||
ActiveMQTextMessage message = new ActiveMQTextMessage();
|
ActiveMQTextMessage message = new ActiveMQTextMessage();
|
||||||
message.setText(text);
|
message.setText(text);
|
||||||
|
@ -519,6 +527,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @return true if the session is in transacted mode
|
* @return true if the session is in transacted mode
|
||||||
* @throws JMSException if there is some internal error.
|
* @throws JMSException if there is some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean getTransacted() throws JMSException {
|
public boolean getTransacted() throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return isTransacted();
|
return isTransacted();
|
||||||
|
@ -536,6 +545,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @see javax.jms.Connection#createSession(boolean,int)
|
* @see javax.jms.Connection#createSession(boolean,int)
|
||||||
* @since 1.1 exception JMSException if there is some internal error.
|
* @since 1.1 exception JMSException if there is some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public int getAcknowledgeMode() throws JMSException {
|
public int getAcknowledgeMode() throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return this.acknowledgementMode;
|
return this.acknowledgementMode;
|
||||||
|
@ -552,6 +562,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws javax.jms.IllegalStateException if the method is not called by a
|
* @throws javax.jms.IllegalStateException if the method is not called by a
|
||||||
* transacted session.
|
* transacted session.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void commit() throws JMSException {
|
public void commit() throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
if (!getTransacted()) {
|
if (!getTransacted()) {
|
||||||
|
@ -572,6 +583,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws javax.jms.IllegalStateException if the method is not called by a
|
* @throws javax.jms.IllegalStateException if the method is not called by a
|
||||||
* transacted session.
|
* transacted session.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void rollback() throws JMSException {
|
public void rollback() throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
if (!getTransacted()) {
|
if (!getTransacted()) {
|
||||||
|
@ -611,6 +623,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException if the JMS provider fails to close the session due
|
* @throws JMSException if the JMS provider fails to close the session due
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void close() throws JMSException {
|
public void close() throws JMSException {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
if (getTransactionContext().isInXATransaction()) {
|
if (getTransactionContext().isInXATransaction()) {
|
||||||
|
@ -787,6 +800,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws IllegalStateException if the method is called by a transacted
|
* @throws IllegalStateException if the method is called by a transacted
|
||||||
* session.
|
* session.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void recover() throws JMSException {
|
public void recover() throws JMSException {
|
||||||
|
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
@ -811,6 +825,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @see javax.jms.ServerSessionPool
|
* @see javax.jms.ServerSessionPool
|
||||||
* @see javax.jms.ServerSession
|
* @see javax.jms.ServerSession
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public MessageListener getMessageListener() throws JMSException {
|
public MessageListener getMessageListener() throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return this.messageListener;
|
return this.messageListener;
|
||||||
|
@ -837,6 +852,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @see javax.jms.ServerSessionPool
|
* @see javax.jms.ServerSessionPool
|
||||||
* @see javax.jms.ServerSession
|
* @see javax.jms.ServerSession
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void setMessageListener(MessageListener listener) throws JMSException {
|
public void setMessageListener(MessageListener listener) throws JMSException {
|
||||||
// only check for closed if we set a new listener, as we allow to clear
|
// only check for closed if we set a new listener, as we allow to clear
|
||||||
// the listener, such as when an application is shutting down, and is
|
// the listener, such as when an application is shutting down, and is
|
||||||
|
@ -857,6 +873,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
*
|
*
|
||||||
* @see javax.jms.ServerSession
|
* @see javax.jms.ServerSession
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
MessageDispatch messageDispatch;
|
MessageDispatch messageDispatch;
|
||||||
while ((messageDispatch = executor.dequeueNoWait()) != null) {
|
while ((messageDispatch = executor.dequeueNoWait()) != null) {
|
||||||
|
@ -885,6 +902,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
|
|
||||||
if (isClientAcknowledge()||isIndividualAcknowledge()) {
|
if (isClientAcknowledge()||isIndividualAcknowledge()) {
|
||||||
message.setAcknowledgeCallback(new Callback() {
|
message.setAcknowledgeCallback(new Callback() {
|
||||||
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -905,6 +923,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
getTransactionContext().addSynchronization(new Synchronization() {
|
getTransactionContext().addSynchronization(new Synchronization() {
|
||||||
|
|
||||||
final int clearRequestCount = (clearRequestsCounter.get() == Integer.MAX_VALUE ? clearRequestsCounter.incrementAndGet() : clearRequestsCounter.get());
|
final int clearRequestCount = (clearRequestsCounter.get() == Integer.MAX_VALUE ? clearRequestsCounter.incrementAndGet() : clearRequestsCounter.get());
|
||||||
|
@Override
|
||||||
public void beforeEnd() throws Exception {
|
public void beforeEnd() throws Exception {
|
||||||
// validate our consumer so we don't push stale acks that get ignored
|
// validate our consumer so we don't push stale acks that get ignored
|
||||||
if (ack.getTransactionId().isXATransaction() && !connection.hasDispatcher(ack.getConsumerId())) {
|
if (ack.getTransactionId().isXATransaction() && !connection.hasDispatcher(ack.getConsumerId())) {
|
||||||
|
@ -961,6 +980,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
}
|
}
|
||||||
connection.getScheduler().executeAfterDelay(new Runnable() {
|
connection.getScheduler().executeAfterDelay(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
((ActiveMQDispatcher)md.getConsumer()).dispatch(md);
|
((ActiveMQDispatcher)md.getConsumer()).dispatch(md);
|
||||||
}
|
}
|
||||||
|
@ -1017,6 +1037,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* specified.
|
* specified.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public MessageProducer createProducer(Destination destination) throws JMSException {
|
public MessageProducer createProducer(Destination destination) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
if (destination instanceof CustomDestination) {
|
if (destination instanceof CustomDestination) {
|
||||||
|
@ -1041,6 +1062,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* specified.
|
* specified.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public MessageConsumer createConsumer(Destination destination) throws JMSException {
|
public MessageConsumer createConsumer(Destination destination) throws JMSException {
|
||||||
return createConsumer(destination, (String) null);
|
return createConsumer(destination, (String) null);
|
||||||
}
|
}
|
||||||
|
@ -1068,6 +1090,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws InvalidSelectorException if the message selector is invalid.
|
* @throws InvalidSelectorException if the message selector is invalid.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public MessageConsumer createConsumer(Destination destination, String messageSelector) throws JMSException {
|
public MessageConsumer createConsumer(Destination destination, String messageSelector) throws JMSException {
|
||||||
return createConsumer(destination, messageSelector, false);
|
return createConsumer(destination, messageSelector, false);
|
||||||
}
|
}
|
||||||
|
@ -1155,6 +1178,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws InvalidSelectorException if the message selector is invalid.
|
* @throws InvalidSelectorException if the message selector is invalid.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal) throws JMSException {
|
public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal) throws JMSException {
|
||||||
return createConsumer(destination, messageSelector, noLocal, null);
|
return createConsumer(destination, messageSelector, noLocal, null);
|
||||||
}
|
}
|
||||||
|
@ -1236,6 +1260,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* internal error.
|
* internal error.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Queue createQueue(String queueName) throws JMSException {
|
public Queue createQueue(String queueName) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
if (queueName.startsWith(ActiveMQDestination.TEMP_DESTINATION_NAME_PREFIX)) {
|
if (queueName.startsWith(ActiveMQDestination.TEMP_DESTINATION_NAME_PREFIX)) {
|
||||||
|
@ -1264,6 +1289,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* internal error.
|
* internal error.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Topic createTopic(String topicName) throws JMSException {
|
public Topic createTopic(String topicName) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
if (topicName.startsWith(ActiveMQDestination.TEMP_DESTINATION_NAME_PREFIX)) {
|
if (topicName.startsWith(ActiveMQDestination.TEMP_DESTINATION_NAME_PREFIX)) {
|
||||||
|
@ -1315,6 +1341,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws InvalidDestinationException if an invalid topic is specified.
|
* @throws InvalidDestinationException if an invalid topic is specified.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException {
|
public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return createDurableSubscriber(topic, name, null, false);
|
return createDurableSubscriber(topic, name, null, false);
|
||||||
|
@ -1360,6 +1387,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws InvalidSelectorException if the message selector is invalid.
|
* @throws InvalidSelectorException if the message selector is invalid.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal) throws JMSException {
|
public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|
||||||
|
@ -1367,11 +1395,6 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
throw new InvalidDestinationException("Topic cannot be null");
|
throw new InvalidDestinationException("Topic cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isIndividualAcknowledge()) {
|
|
||||||
throw JMSExceptionSupport.create("Cannot create a durable consumer for a Session in "+
|
|
||||||
"INDIVIDUAL_ACKNOWLEDGE mode.", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (topic instanceof CustomDestination) {
|
if (topic instanceof CustomDestination) {
|
||||||
CustomDestination customDestination = (CustomDestination)topic;
|
CustomDestination customDestination = (CustomDestination)topic;
|
||||||
return customDestination.createDurableSubscriber(this, name, messageSelector, noLocal);
|
return customDestination.createDurableSubscriber(this, name, messageSelector, noLocal);
|
||||||
|
@ -1397,6 +1420,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* specified
|
* specified
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public QueueBrowser createBrowser(Queue queue) throws JMSException {
|
public QueueBrowser createBrowser(Queue queue) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return createBrowser(queue, null);
|
return createBrowser(queue, null);
|
||||||
|
@ -1419,6 +1443,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws InvalidSelectorException if the message selector is invalid.
|
* @throws InvalidSelectorException if the message selector is invalid.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public QueueBrowser createBrowser(Queue queue, String messageSelector) throws JMSException {
|
public QueueBrowser createBrowser(Queue queue, String messageSelector) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return new ActiveMQQueueBrowser(this, getNextConsumerId(), ActiveMQMessageTransformation.transformDestination(queue), messageSelector, asyncDispatch);
|
return new ActiveMQQueueBrowser(this, getNextConsumerId(), ActiveMQMessageTransformation.transformDestination(queue), messageSelector, asyncDispatch);
|
||||||
|
@ -1433,6 +1458,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public TemporaryQueue createTemporaryQueue() throws JMSException {
|
public TemporaryQueue createTemporaryQueue() throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return (TemporaryQueue)connection.createTempDestination(false);
|
return (TemporaryQueue)connection.createTempDestination(false);
|
||||||
|
@ -1447,6 +1473,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* to some internal error.
|
* to some internal error.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public TemporaryTopic createTemporaryTopic() throws JMSException {
|
public TemporaryTopic createTemporaryTopic() throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return (TemporaryTopic)connection.createTempDestination(true);
|
return (TemporaryTopic)connection.createTempDestination(true);
|
||||||
|
@ -1463,6 +1490,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws JMSException
|
* @throws JMSException
|
||||||
* @throws InvalidDestinationException if an invalid queue is specified.
|
* @throws InvalidDestinationException if an invalid queue is specified.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public QueueReceiver createReceiver(Queue queue) throws JMSException {
|
public QueueReceiver createReceiver(Queue queue) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return createReceiver(queue, null);
|
return createReceiver(queue, null);
|
||||||
|
@ -1483,6 +1511,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws InvalidDestinationException if an invalid queue is specified.
|
* @throws InvalidDestinationException if an invalid queue is specified.
|
||||||
* @throws InvalidSelectorException if the message selector is invalid.
|
* @throws InvalidSelectorException if the message selector is invalid.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException {
|
public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|
||||||
|
@ -1507,6 +1536,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* internal error.
|
* internal error.
|
||||||
* @throws InvalidDestinationException if an invalid queue is specified.
|
* @throws InvalidDestinationException if an invalid queue is specified.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public QueueSender createSender(Queue queue) throws JMSException {
|
public QueueSender createSender(Queue queue) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
if (queue instanceof CustomDestination) {
|
if (queue instanceof CustomDestination) {
|
||||||
|
@ -1537,6 +1567,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* some internal error.
|
* some internal error.
|
||||||
* @throws InvalidDestinationException if an invalid topic is specified.
|
* @throws InvalidDestinationException if an invalid topic is specified.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public TopicSubscriber createSubscriber(Topic topic) throws JMSException {
|
public TopicSubscriber createSubscriber(Topic topic) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
return createSubscriber(topic, null, false);
|
return createSubscriber(topic, null, false);
|
||||||
|
@ -1575,6 +1606,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* @throws InvalidDestinationException if an invalid topic is specified.
|
* @throws InvalidDestinationException if an invalid topic is specified.
|
||||||
* @throws InvalidSelectorException if the message selector is invalid.
|
* @throws InvalidSelectorException if the message selector is invalid.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException {
|
public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|
||||||
|
@ -1603,6 +1635,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* some internal error.
|
* some internal error.
|
||||||
* @throws InvalidDestinationException if an invalid topic is specified.
|
* @throws InvalidDestinationException if an invalid topic is specified.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public TopicPublisher createPublisher(Topic topic) throws JMSException {
|
public TopicPublisher createPublisher(Topic topic) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|
||||||
|
@ -1633,11 +1666,13 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
||||||
* specified.
|
* specified.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void unsubscribe(String name) throws JMSException {
|
public void unsubscribe(String name) throws JMSException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
connection.unsubscribe(name);
|
connection.unsubscribe(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void dispatch(MessageDispatch messageDispatch) {
|
public void dispatch(MessageDispatch messageDispatch) {
|
||||||
try {
|
try {
|
||||||
executor.execute(messageDispatch);
|
executor.execute(messageDispatch);
|
||||||
|
|
|
@ -24,7 +24,6 @@ import javax.jms.MessageProducer;
|
||||||
import javax.jms.Queue;
|
import javax.jms.Queue;
|
||||||
import javax.jms.Session;
|
import javax.jms.Session;
|
||||||
import javax.jms.TextMessage;
|
import javax.jms.TextMessage;
|
||||||
import javax.jms.Topic;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -33,6 +32,7 @@ public class JMSIndividualAckTest extends TestSupport {
|
||||||
|
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
connection = createConnection();
|
connection = createConnection();
|
||||||
|
@ -41,6 +41,7 @@ public class JMSIndividualAckTest extends TestSupport {
|
||||||
/**
|
/**
|
||||||
* @see junit.framework.TestCase#tearDown()
|
* @see junit.framework.TestCase#tearDown()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
connection.close();
|
connection.close();
|
||||||
|
@ -154,25 +155,7 @@ public class JMSIndividualAckTest extends TestSupport {
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests that a durable consumer cannot be created for Individual Ack mode.
|
|
||||||
*
|
|
||||||
* @throws JMSException
|
|
||||||
*/
|
|
||||||
public void testCreateDurableConsumerFails() throws JMSException {
|
|
||||||
connection.start();
|
|
||||||
Session session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
|
|
||||||
Topic dest = session.createTopic(getName());
|
|
||||||
|
|
||||||
try {
|
|
||||||
session.createDurableSubscriber(dest, getName());
|
|
||||||
fail("Should not be able to create duable subscriber.");
|
|
||||||
} catch(Exception e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getQueueName() {
|
protected String getQueueName() {
|
||||||
return getClass().getName() + "." + getName();
|
return getClass().getName() + "." + getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,13 @@ import javax.jms.Topic;
|
||||||
import javax.jms.TopicSubscriber;
|
import javax.jms.TopicSubscriber;
|
||||||
|
|
||||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||||
|
import org.apache.activemq.ActiveMQSession;
|
||||||
import org.apache.activemq.TestSupport;
|
import org.apache.activemq.TestSupport;
|
||||||
import org.apache.activemq.broker.BrokerService;
|
import org.apache.activemq.broker.BrokerService;
|
||||||
import org.apache.activemq.store.PersistenceAdapter;
|
import org.apache.activemq.store.PersistenceAdapter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
||||||
|
|
||||||
|
@ -44,21 +45,25 @@ public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
||||||
private MessageProducer producer;
|
private MessageProducer producer;
|
||||||
private BrokerService broker;
|
private BrokerService broker;
|
||||||
|
|
||||||
|
@Override
|
||||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
||||||
return new ActiveMQConnectionFactory("vm://durable-broker");
|
return new ActiveMQConnectionFactory("vm://durable-broker");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected Connection createConnection() throws Exception {
|
protected Connection createConnection() throws Exception {
|
||||||
Connection rc = super.createConnection();
|
Connection rc = super.createConnection();
|
||||||
rc.setClientID(getName());
|
rc.setClientID(getName());
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
createBroker();
|
createBroker();
|
||||||
super.setUp();
|
super.setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
destroyBroker();
|
destroyBroker();
|
||||||
|
@ -104,7 +109,7 @@ public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract PersistenceAdapter createPersistenceAdapter() throws Exception;
|
protected abstract PersistenceAdapter createPersistenceAdapter() throws Exception;
|
||||||
|
|
||||||
public void testMessageExpire() throws Exception {
|
public void testMessageExpire() throws Exception {
|
||||||
session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
|
session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
|
||||||
Topic topic = session.createTopic("TestTopic");
|
Topic topic = session.createTopic("TestTopic");
|
||||||
|
@ -117,12 +122,12 @@ public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
||||||
// Make sure it works when the durable sub is active.
|
// Make sure it works when the durable sub is active.
|
||||||
producer.send(session.createTextMessage("Msg:1"));
|
producer.send(session.createTextMessage("Msg:1"));
|
||||||
assertTextMessageEquals("Msg:1", consumer.receive(1000));
|
assertTextMessageEquals("Msg:1", consumer.receive(1000));
|
||||||
|
|
||||||
consumer.close();
|
consumer.close();
|
||||||
|
|
||||||
producer.send(session.createTextMessage("Msg:2"));
|
producer.send(session.createTextMessage("Msg:2"));
|
||||||
producer.send(session.createTextMessage("Msg:3"));
|
producer.send(session.createTextMessage("Msg:3"));
|
||||||
|
|
||||||
consumer = session.createDurableSubscriber(topic, "sub1");
|
consumer = session.createDurableSubscriber(topic, "sub1");
|
||||||
|
|
||||||
// Try to get the message.
|
// Try to get the message.
|
||||||
|
@ -225,7 +230,7 @@ public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
||||||
assertTextMessageEquals("Msg:2", consumer.receive(5000));
|
assertTextMessageEquals("Msg:2", consumer.receive(5000));
|
||||||
assertNull(consumer.receive(5000));
|
assertNull(consumer.receive(5000));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDurableSubscriptionBrokerRestart() throws Exception {
|
public void testDurableSubscriptionBrokerRestart() throws Exception {
|
||||||
|
|
||||||
// Create the durable sub.
|
// Create the durable sub.
|
||||||
|
@ -235,12 +240,12 @@ public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
||||||
// Ensure that consumer will receive messages sent before it was created
|
// Ensure that consumer will receive messages sent before it was created
|
||||||
Topic topic = session.createTopic("TestTopic?consumer.retroactive=true");
|
Topic topic = session.createTopic("TestTopic?consumer.retroactive=true");
|
||||||
consumer = session.createDurableSubscriber(topic, "sub1");
|
consumer = session.createDurableSubscriber(topic, "sub1");
|
||||||
|
|
||||||
producer = session.createProducer(topic);
|
producer = session.createProducer(topic);
|
||||||
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
|
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
|
||||||
producer.send(session.createTextMessage("Msg:1"));
|
producer.send(session.createTextMessage("Msg:1"));
|
||||||
assertTextMessageEquals("Msg:1", consumer.receive(5000));
|
assertTextMessageEquals("Msg:1", consumer.receive(5000));
|
||||||
|
|
||||||
// Make sure cleanup kicks in
|
// Make sure cleanup kicks in
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
@ -428,8 +433,7 @@ public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
||||||
consumer = session.createDurableSubscriber(topic, "sub1");
|
consumer = session.createDurableSubscriber(topic, "sub1");
|
||||||
Message msg = consumer.receive(1000);
|
Message msg = consumer.receive(1000);
|
||||||
assertNotNull(msg);
|
assertNotNull(msg);
|
||||||
assertEquals("Message 1", ((TextMessage)msg).getText());
|
assertEquals("Message 1", ((TextMessage) msg).getText());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDurableSubWorksInNewConnection() throws Exception {
|
public void testDurableSubWorksInNewConnection() throws Exception {
|
||||||
|
@ -459,8 +463,56 @@ public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
||||||
consumer = session.createDurableSubscriber(topic, "sub1");
|
consumer = session.createDurableSubscriber(topic, "sub1");
|
||||||
Message msg = consumer.receive(1000);
|
Message msg = consumer.receive(1000);
|
||||||
assertNotNull(msg);
|
assertNotNull(msg);
|
||||||
assertEquals("Message 1", ((TextMessage)msg).getText());
|
assertEquals("Message 1", ((TextMessage) msg).getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIndividualAckWithDurableSubs() throws Exception {
|
||||||
|
// Create the consumer.
|
||||||
|
connection.start();
|
||||||
|
|
||||||
|
Session session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
|
||||||
|
Topic topic = session.createTopic("topic-" + getName());
|
||||||
|
MessageConsumer consumer = session.createDurableSubscriber(topic, "sub1");
|
||||||
|
// Drain any messages that may allready be in the sub
|
||||||
|
while (consumer.receive(1000) != null) {
|
||||||
|
}
|
||||||
|
consumer.close();
|
||||||
|
|
||||||
|
MessageProducer producer = session.createProducer(topic);
|
||||||
|
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
|
||||||
|
producer.send(session.createTextMessage("Message 1"));
|
||||||
|
producer.send(session.createTextMessage("Message 2"));
|
||||||
|
producer.send(session.createTextMessage("Message 3"));
|
||||||
|
producer.close();
|
||||||
|
|
||||||
|
connection.close();
|
||||||
|
connection = createConnection();
|
||||||
|
connection.start();
|
||||||
|
|
||||||
|
session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
|
||||||
|
consumer = session.createDurableSubscriber(topic, "sub1");
|
||||||
|
|
||||||
|
Message message = null;
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
message = consumer.receive(5000);
|
||||||
|
assertNotNull(message);
|
||||||
|
assertEquals("Message " + (i + 1), ((TextMessage) message).getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
message.acknowledge();
|
||||||
|
|
||||||
|
connection.close();
|
||||||
|
connection = createConnection();
|
||||||
|
connection.start();
|
||||||
|
|
||||||
|
session = connection.createSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
|
||||||
|
consumer = session.createDurableSubscriber(topic, "sub1");
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
message = consumer.receive(5000);
|
||||||
|
assertNotNull(message);
|
||||||
|
assertEquals("Message " + (i + 1), ((TextMessage) message).getText());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MessageProducer createProducer(Session session, Destination queue) throws JMSException {
|
private MessageProducer createProducer(Session session, Destination queue) throws JMSException {
|
||||||
|
@ -476,7 +528,7 @@ public abstract class DurableSubscriptionTestSupport extends TestSupport {
|
||||||
private void assertTextMessageEquals(String string, Message message) throws JMSException {
|
private void assertTextMessageEquals(String string, Message message) throws JMSException {
|
||||||
assertNotNull("Message was null", message);
|
assertNotNull("Message was null", message);
|
||||||
assertTrue("Message is not a TextMessage", message instanceof TextMessage);
|
assertTrue("Message is not a TextMessage", message instanceof TextMessage);
|
||||||
assertEquals(string, ((TextMessage)message).getText());
|
assertEquals(string, ((TextMessage) message).getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue