org.skyscreamer.nevado.jms.NevadoMessageConsumer Maven / Gradle / Ivy
package org.skyscreamer.nevado.jms;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.skyscreamer.nevado.jms.destination.NevadoDestination;
import org.skyscreamer.nevado.jms.destination.NevadoQueue;
import org.skyscreamer.nevado.jms.destination.NevadoTemporaryQueue;
import org.skyscreamer.nevado.jms.destination.NevadoTopic;
import org.skyscreamer.nevado.jms.message.NevadoMessage;
import javax.jms.*;
import javax.jms.IllegalStateException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
public class NevadoMessageConsumer implements MessageConsumer, QueueReceiver, TopicSubscriber {
private final Log _log = LogFactory.getLog(getClass());
private boolean _closed = false;
private final NevadoSession _session;
private final NevadoDestination _destination;
private final String _selector;
private final boolean _noLocal;
private volatile MessageListener _messageListener;
private final AtomicReference _messageParking = new AtomicReference();
public NevadoMessageConsumer(NevadoSession session, NevadoDestination destination, String selector, boolean noLocal)
throws JMSException
{
_session = session;
if (destination instanceof NevadoTopic)
{
NevadoTemporaryQueue topicEndpoint = _session.getConnection().createTemporaryQueue();
String subscriptionArn = _session.getConnection().subscribe((NevadoTopic)destination, topicEndpoint);
_destination = new NevadoTopic((NevadoTopic)destination, topicEndpoint, subscriptionArn, false);
}
else
{
_destination = destination;
}
_selector = selector;
_noLocal = noLocal;
}
public NevadoMessageConsumer(NevadoSession session, NevadoTopic topic, String durableSubscriptionName,
String selector, boolean noLocal)
throws JMSException
{
_session = session;
NevadoQueue topicEndpoint
= _session.createInternalQueue(_session.getDurableEndpointQueueName(durableSubscriptionName));
String subscriptionArn = _session.getConnection().subscribe(topic, topicEndpoint);
_destination = new NevadoTopic(topic, topicEndpoint, subscriptionArn, true);
_selector = selector;
_noLocal = noLocal;
}
public String getMessageSelector() throws JMSException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public MessageListener getMessageListener() {
return _messageListener;
}
public void setMessageListener(MessageListener messageListener) throws JMSException {
checkClosed();
_messageListener = messageListener;
}
@Override
public NevadoMessage receive() throws JMSException {
return receive(-1);
}
@Override
public NevadoMessage receive(long timeoutMs) throws JMSException {
checkClosed();
checkAsync();
NevadoMessage message;
try {
message = _session.receiveMessage(_destination, timeoutMs, _noLocal);
}
catch(InterruptedException e) {
Thread.currentThread().interrupt();
return null;
}
tryAutoAck(message);
return message;
}
@Override
public NevadoMessage receiveNoWait() throws JMSException {
return receive(0);
}
public synchronized void close() throws JMSException {
if (!_closed)
{
List exceptions = new ArrayList();
if (_destination instanceof NevadoTopic && !((NevadoTopic)_destination).isDurable())
{
try {
_session.getConnection().unsubscribe((NevadoTopic)_destination);
} catch (JMSException e) {
_log.warn("Exception thrown trying to unsubscribe. Will continue trying to close then will throw " +
"exception. (First one if multiple.)", e);
exceptions.add(e);
}
}
NevadoMessage parkedMessage;
if ((parkedMessage = _messageParking.getAndSet(null)) != null)
{
_session.resetMessage(parkedMessage);
}
_messageListener = null;
_closed = true;
if (exceptions.size() > 0) {
throw exceptions.get(0);
}
}
}
protected boolean processAsyncMessage() throws JMSException, InterruptedException {
checkClosed();
boolean messageProcessed = false;
// First check for a parked message
NevadoMessage message;
if ((message = _messageParking.getAndSet(null)) == null)
{
message = _session.receiveMessage(_destination, 0, _noLocal);
}
if (message != null) {
try {
getMessageListener().onMessage(message);
tryAutoAck(message);
messageProcessed = true;
}
catch(Throwable t) {
if (_session.getAcknowledgeMode() == Session.AUTO_ACKNOWLEDGE
|| _session.getAcknowledgeMode() == Session.DUPS_OK_ACKNOWLEDGE)
{
NevadoMessage parkedMessage;
if ((parkedMessage = _messageParking.getAndSet(message)) != null) {
_log.error("Stepped on an unexpected parked message. Resetting it: " + parkedMessage);
_session.resetMessage(parkedMessage);
}
}
}
}
return messageProcessed;
}
private void tryAutoAck(NevadoMessage message) throws JMSException {
if (message != null && _session.getAcknowledgeMode() == Session.AUTO_ACKNOWLEDGE)
{
message.acknowledge();
}
}
private void checkAsync() throws IllegalStateException
{
if (_messageListener != null)
{
throw new IllegalStateException("Synchronous message delivery cannot be requested from a consumer after " +
"a message listener has been registered");
}
}
public Queue getQueue() throws JMSException {
if (_destination instanceof Queue)
{
return (Queue)_destination;
}
else
{
throw new IllegalStateException("getQueue() can only be called for a QueueSender");
}
}
protected Destination getDestination()
{
return _destination;
}
public boolean isClosed()
{
return _closed;
}
private void checkClosed() throws IllegalStateException
{
if (_closed)
{
throw new IllegalStateException("This consumer has been closed");
}
}
public Topic getTopic() throws JMSException {
if (_destination instanceof Topic)
{
return (Topic)_destination;
}
else
{
throw new IllegalStateException("getTopic() can only be called for a TopicSubscriber");
}
}
public boolean getNoLocal() throws JMSException {
return _noLocal;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy