Example usage for org.springframework.amqp.rabbit.connection RabbitResourceHolder RabbitResourceHolder

List of usage examples for org.springframework.amqp.rabbit.connection RabbitResourceHolder RabbitResourceHolder

Introduction

In this page you can find the example usage for org.springframework.amqp.rabbit.connection RabbitResourceHolder RabbitResourceHolder.

Prototype

public RabbitResourceHolder(Channel channel, boolean releaseAfterCompletion) 

Source Link

Document

Construct an instance for the channel.

Usage

From source file:org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.java

/**
 * Invoke the specified listener: either as standard MessageListener or (preferably) as SessionAwareMessageListener.
 * @param channel the Rabbit Channel to operate on
 * @param message the received Rabbit Message
 * @throws Exception if thrown by Rabbit API methods
 * @see #setMessageListener/*from  ww w .  j av a  2s  .c o  m*/
 */
protected void actualInvokeListener(Channel channel, Message message) throws Exception {
    Object listener = getMessageListener();
    if (listener instanceof ChannelAwareMessageListener) {
        doInvokeListener((ChannelAwareMessageListener) listener, channel, message);
    } else if (listener instanceof MessageListener) {
        boolean bindChannel = isExposeListenerChannel() && isChannelLocallyTransacted();
        if (bindChannel) {
            RabbitResourceHolder resourceHolder = new RabbitResourceHolder(channel, false);
            resourceHolder.setSynchronizedWithTransaction(true);
            TransactionSynchronizationManager.bindResource(this.getConnectionFactory(), resourceHolder);
        }
        try {
            doInvokeListener((MessageListener) listener, message);
        } finally {
            if (bindChannel) {
                // unbind if we bound
                TransactionSynchronizationManager.unbindResource(this.getConnectionFactory());
            }
        }
    } else if (listener != null) {
        throw new FatalListenerExecutionException(
                "Only MessageListener and SessionAwareMessageListener supported: " + listener);
    } else {
        throw new FatalListenerExecutionException(
                "No message listener specified - see property 'messageListener'");
    }
}

From source file:org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.java

/**
 * Invoke the specified listener as Spring ChannelAwareMessageListener, exposing a new Rabbit Session (potentially
 * with its own transaction) to the listener if demanded.
 * @param listener the Spring ChannelAwareMessageListener to invoke
 * @param channel the Rabbit Channel to operate on
 * @param message the received Rabbit Message
 * @throws Exception if thrown by Rabbit API methods or listener itself.
 * <p>/* ww  w. ja  v  a 2s.c  o m*/
 * Exception thrown from listener will be wrapped to {@link ListenerExecutionFailedException}.
 * @see ChannelAwareMessageListener
 * @see #setExposeListenerChannel(boolean)
 */
protected void doInvokeListener(ChannelAwareMessageListener listener, Channel channel, Message message)
        throws Exception {

    RabbitResourceHolder resourceHolder = null;
    Channel channelToUse = channel;
    boolean boundHere = false;
    try {
        if (!isExposeListenerChannel()) {
            // We need to expose a separate Channel.
            resourceHolder = getTransactionalResourceHolder();
            channelToUse = resourceHolder.getChannel();
            /*
             * If there is a real transaction, the resource will have been bound; otherwise
             * we need to bind it temporarily here. Any work done on this channel
             * will be committed in the finally block.
             */
            if (isChannelLocallyTransacted()
                    && !TransactionSynchronizationManager.isActualTransactionActive()) {
                resourceHolder.setSynchronizedWithTransaction(true);
                TransactionSynchronizationManager.bindResource(this.getConnectionFactory(), resourceHolder);
                boundHere = true;
            }
        } else {
            // if locally transacted, bind the current channel to make it available to RabbitTemplate
            if (isChannelLocallyTransacted()) {
                RabbitResourceHolder localResourceHolder = new RabbitResourceHolder(channelToUse, false);
                localResourceHolder.setSynchronizedWithTransaction(true);
                TransactionSynchronizationManager.bindResource(this.getConnectionFactory(),
                        localResourceHolder);
                boundHere = true;
            }
        }
        // Actually invoke the message listener...
        try {
            listener.onMessage(message, channelToUse);
        } catch (Exception e) {
            throw wrapToListenerExecutionFailedExceptionIfNeeded(e, message);
        }
    } finally {
        if (resourceHolder != null && boundHere) {
            // so the channel exposed (because exposeListenerChannel is false) will be closed
            resourceHolder.setSynchronizedWithTransaction(false);
        }
        ConnectionFactoryUtils.releaseResources(resourceHolder);
        if (boundHere) {
            // unbind if we bound
            TransactionSynchronizationManager.unbindResource(this.getConnectionFactory());
            if (!isExposeListenerChannel() && isChannelLocallyTransacted()) {
                /*
                 *  commit the temporary channel we exposed; the consumer's channel
                 *  will be committed later. Note that when exposing a different channel
                 *  when there's no transaction manager, the exposed channel is committed
                 *  on each message, and not based on txSize.
                 */
                RabbitUtils.commitIfNecessary(channelToUse);
            }
        }
    }
}

From source file:org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.java

private boolean receiveAndExecute(final BlockingQueueConsumer consumer) throws Throwable {

    if (this.transactionManager != null) {
        try {//from  www.jav  a2  s . c o  m
            return new TransactionTemplate(this.transactionManager, this.transactionAttribute)
                    .execute(new TransactionCallback<Boolean>() {
                        @Override
                        public Boolean doInTransaction(TransactionStatus status) {
                            ConnectionFactoryUtils.bindResourceToTransaction(
                                    new RabbitResourceHolder(consumer.getChannel(), false),
                                    getConnectionFactory(), true);
                            try {
                                return doReceiveAndExecute(consumer);
                            } catch (RuntimeException e) {
                                throw e;
                            } catch (Throwable e) { //NOSONAR
                                // ok to catch Throwable here because we re-throw it below
                                throw new WrappedTransactionException(e);
                            }
                        }
                    });
        } catch (WrappedTransactionException e) {
            throw e.getCause();
        }
    }

    return doReceiveAndExecute(consumer);

}