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);
}
}
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);
}
}
}
}
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);
}
}
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();
}
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();
}
Aggregations