Search in sources :

Example 46 with Connection

use of jakarta.jms.Connection in project spring-framework by spring-projects.

the class AbstractPollingMessageListenerContainer method doReceiveAndExecute.

/**
 * Actually execute the listener for a message received from the given consumer,
 * fetching all requires resources and invoking the listener.
 * @param session the JMS Session to work on
 * @param consumer the MessageConsumer to work on
 * @param status the TransactionStatus (may be {@code null})
 * @return whether a message has been received
 * @throws JMSException if thrown by JMS methods
 * @see #doExecuteListener(jakarta.jms.Session, jakarta.jms.Message)
 */
protected boolean doReceiveAndExecute(Object invoker, @Nullable Session session, @Nullable MessageConsumer consumer, @Nullable TransactionStatus status) throws JMSException {
    Connection conToClose = null;
    Session sessionToClose = null;
    MessageConsumer consumerToClose = null;
    try {
        Session sessionToUse = session;
        boolean transactional = false;
        if (sessionToUse == null) {
            sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(obtainConnectionFactory(), this.transactionalResourceFactory, true);
            transactional = (sessionToUse != null);
        }
        if (sessionToUse == null) {
            Connection conToUse;
            if (sharedConnectionEnabled()) {
                conToUse = getSharedConnection();
            } else {
                conToUse = createConnection();
                conToClose = conToUse;
                conToUse.start();
            }
            sessionToUse = createSession(conToUse);
            sessionToClose = sessionToUse;
        }
        MessageConsumer consumerToUse = consumer;
        if (consumerToUse == null) {
            consumerToUse = createListenerConsumer(sessionToUse);
            consumerToClose = consumerToUse;
        }
        Message message = receiveMessage(consumerToUse);
        if (message != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Received message of type [" + message.getClass() + "] from consumer [" + consumerToUse + "] of " + (transactional ? "transactional " : "") + "session [" + sessionToUse + "]");
            }
            messageReceived(invoker, sessionToUse);
            boolean exposeResource = (!transactional && isExposeListenerSession() && !TransactionSynchronizationManager.hasResource(obtainConnectionFactory()));
            if (exposeResource) {
                TransactionSynchronizationManager.bindResource(obtainConnectionFactory(), new LocallyExposedJmsResourceHolder(sessionToUse));
            }
            try {
                doExecuteListener(sessionToUse, message);
            } catch (Throwable ex) {
                if (status != null) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Rolling back transaction because of listener exception thrown: " + ex);
                    }
                    status.setRollbackOnly();
                }
                handleListenerException(ex);
                // that may have to trigger recovery...
                if (ex instanceof JMSException) {
                    throw (JMSException) ex;
                }
            } finally {
                if (exposeResource) {
                    TransactionSynchronizationManager.unbindResource(obtainConnectionFactory());
                }
            }
            // Indicate that a message has been received.
            return true;
        } else {
            if (logger.isTraceEnabled()) {
                logger.trace("Consumer [" + consumerToUse + "] of " + (transactional ? "transactional " : "") + "session [" + sessionToUse + "] did not receive a message");
            }
            noMessageReceived(invoker, sessionToUse);
            // Nevertheless call commit, in order to reset the transaction timeout (if any).
            if (shouldCommitAfterNoMessageReceived(sessionToUse)) {
                commitIfNecessary(sessionToUse, null);
            }
            // Indicate that no message has been received.
            return false;
        }
    } finally {
        JmsUtils.closeMessageConsumer(consumerToClose);
        JmsUtils.closeSession(sessionToClose);
        ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), true);
    }
}
Also used : MessageConsumer(jakarta.jms.MessageConsumer) Message(jakarta.jms.Message) Connection(jakarta.jms.Connection) JMSException(jakarta.jms.JMSException) Session(jakarta.jms.Session)

Example 47 with Connection

use of jakarta.jms.Connection in project spring-framework by spring-projects.

the class SimpleMessageListenerContainer method initializeConsumers.

/**
 * Initialize the JMS Sessions and MessageConsumers for this container.
 * @throws JMSException in case of setup failure
 */
protected void initializeConsumers() throws JMSException {
    // Register Sessions and MessageConsumers.
    synchronized (this.consumersMonitor) {
        if (this.consumers == null) {
            this.sessions = new HashSet<>(this.concurrentConsumers);
            this.consumers = new HashSet<>(this.concurrentConsumers);
            Connection con = getSharedConnection();
            for (int i = 0; i < this.concurrentConsumers; i++) {
                Session session = createSession(con);
                MessageConsumer consumer = createListenerConsumer(session);
                this.sessions.add(session);
                this.consumers.add(consumer);
            }
        }
    }
}
Also used : MessageConsumer(jakarta.jms.MessageConsumer) Connection(jakarta.jms.Connection) Session(jakarta.jms.Session)

Example 48 with Connection

use of jakarta.jms.Connection in project spring-framework by spring-projects.

the class JmsTemplate method execute.

/**
 * Execute the action specified by the given action object within a
 * JMS Session. Generalized version of {@code execute(SessionCallback)},
 * allowing the JMS Connection to be started on the fly.
 * <p>Use {@code execute(SessionCallback)} for the general case.
 * Starting the JMS Connection is just necessary for receiving messages,
 * which is preferably achieved through the {@code receive} methods.
 * @param action callback object that exposes the Session
 * @param startConnection whether to start the Connection
 * @return the result object from working with the Session
 * @throws JmsException if there is any problem
 * @see #execute(SessionCallback)
 * @see #receive
 */
@Nullable
public <T> T execute(SessionCallback<T> action, boolean startConnection) throws JmsException {
    Assert.notNull(action, "Callback object must not be null");
    Connection conToClose = null;
    Session sessionToClose = null;
    try {
        Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(obtainConnectionFactory(), this.transactionalResourceFactory, startConnection);
        if (sessionToUse == null) {
            conToClose = createConnection();
            sessionToClose = createSession(conToClose);
            if (startConnection) {
                conToClose.start();
            }
            sessionToUse = sessionToClose;
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Executing callback on JMS Session: " + sessionToUse);
        }
        return action.doInJms(sessionToUse);
    } catch (JMSException ex) {
        throw convertJmsAccessException(ex);
    } finally {
        JmsUtils.closeSession(sessionToClose);
        ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);
    }
}
Also used : Connection(jakarta.jms.Connection) JMSException(jakarta.jms.JMSException) Session(jakarta.jms.Session) Nullable(org.springframework.lang.Nullable)

Example 49 with Connection

use of jakarta.jms.Connection in project spring-framework by spring-projects.

the class SimpleMessageListenerContainerTests method testTaskExecutorCorrectlyInvokedWhenSpecified.

@Test
public void testTaskExecutorCorrectlyInvokedWhenSpecified() throws Exception {
    final SimpleMessageConsumer messageConsumer = new SimpleMessageConsumer();
    final Session session = mock(Session.class);
    given(session.createQueue(DESTINATION_NAME)).willReturn(QUEUE_DESTINATION);
    // no MessageSelector...
    given(session.createConsumer(QUEUE_DESTINATION, null)).willReturn(messageConsumer);
    given(session.getTransacted()).willReturn(false);
    given(session.getAcknowledgeMode()).willReturn(Session.AUTO_ACKNOWLEDGE);
    Connection connection = mock(Connection.class);
    given(connection.createSession(this.container.isSessionTransacted(), this.container.getSessionAcknowledgeMode())).willReturn(session);
    final ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
    given(connectionFactory.createConnection()).willReturn(connection);
    final TestMessageListener listener = new TestMessageListener();
    this.container.setConnectionFactory(connectionFactory);
    this.container.setDestinationName(DESTINATION_NAME);
    this.container.setMessageListener(listener);
    this.container.setTaskExecutor(task -> {
        listener.executorInvoked = true;
        assertThat(listener.listenerInvoked).isFalse();
        task.run();
        assertThat(listener.listenerInvoked).isTrue();
    });
    this.container.afterPropertiesSet();
    this.container.start();
    final Message message = mock(Message.class);
    messageConsumer.sendMessage(message);
    assertThat(listener.executorInvoked).isTrue();
    assertThat(listener.listenerInvoked).isTrue();
    verify(connection).setExceptionListener(this.container);
    verify(connection).start();
}
Also used : ConnectionFactory(jakarta.jms.ConnectionFactory) Message(jakarta.jms.Message) Connection(jakarta.jms.Connection) Session(jakarta.jms.Session) Test(org.junit.jupiter.api.Test)

Example 50 with Connection

use of jakarta.jms.Connection in project spring-framework by spring-projects.

the class SimpleMessageListenerContainerTests method testDestroyClosesConsumersSessionsAndConnectionInThatOrder.

@Test
public void testDestroyClosesConsumersSessionsAndConnectionInThatOrder() throws Exception {
    MessageConsumer messageConsumer = mock(MessageConsumer.class);
    Session session = mock(Session.class);
    // Queue gets created in order to create MessageConsumer for that Destination...
    given(session.createQueue(DESTINATION_NAME)).willReturn(QUEUE_DESTINATION);
    // and then the MessageConsumer gets created...
    // no MessageSelector...
    given(session.createConsumer(QUEUE_DESTINATION, null)).willReturn(messageConsumer);
    Connection connection = mock(Connection.class);
    // session gets created in order to register MessageListener...
    given(connection.createSession(this.container.isSessionTransacted(), this.container.getSessionAcknowledgeMode())).willReturn(session);
    // and the connection is start()ed after the listener is registered...
    ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
    given(connectionFactory.createConnection()).willReturn(connection);
    this.container.setConnectionFactory(connectionFactory);
    this.container.setDestinationName(DESTINATION_NAME);
    this.container.setMessageListener(new TestMessageListener());
    this.container.afterPropertiesSet();
    this.container.start();
    this.container.destroy();
    verify(messageConsumer).close();
    verify(session).close();
    verify(connection).setExceptionListener(this.container);
    verify(connection).start();
    verify(connection).close();
}
Also used : MessageConsumer(jakarta.jms.MessageConsumer) ConnectionFactory(jakarta.jms.ConnectionFactory) Connection(jakarta.jms.Connection) Session(jakarta.jms.Session) Test(org.junit.jupiter.api.Test)

Aggregations

Connection (jakarta.jms.Connection)52 Test (org.junit.jupiter.api.Test)40 ConnectionFactory (jakarta.jms.ConnectionFactory)31 Session (jakarta.jms.Session)29 JMSException (jakarta.jms.JMSException)22 QueueConnection (jakarta.jms.QueueConnection)21 TopicConnection (jakarta.jms.TopicConnection)21 Message (jakarta.jms.Message)16 QueueConnectionFactory (jakarta.jms.QueueConnectionFactory)11 TopicConnectionFactory (jakarta.jms.TopicConnectionFactory)11 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)10 BDDMockito.given (org.mockito.BDDMockito.given)10 Mockito.mock (org.mockito.Mockito.mock)10 Mockito.verify (org.mockito.Mockito.verify)10 StubQueue (org.springframework.jms.StubQueue)10 Destination (jakarta.jms.Destination)9 MessageProducer (jakarta.jms.MessageProducer)9 MessageConsumer (jakarta.jms.MessageConsumer)8 Assertions.assertThatExceptionOfType (org.assertj.core.api.Assertions.assertThatExceptionOfType)8 JmsTemplate (org.springframework.jms.core.JmsTemplate)8