mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-27 01:19:02 +00:00
Introduce JmsClient with configurable settings per operation
Closes gh-32501 Closes gh-26840
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jms.core;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import jakarta.jms.ConnectionFactory;
|
||||
import jakarta.jms.Destination;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.jms.support.JmsAccessor;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* The default implementation of {@link JmsClient},
|
||||
* as created by the static factory methods.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 7.0
|
||||
* @see JmsClient#create(ConnectionFactory)
|
||||
* @see JmsClient#create(ConnectionFactory, MessageConverter)
|
||||
* @see JmsClient#create(JmsOperations)
|
||||
* @see JmsClient#create(JmsOperations, MessageConverter)
|
||||
*/
|
||||
class DefaultJmsClient implements JmsClient {
|
||||
|
||||
private final JmsOperations jmsTemplate;
|
||||
|
||||
private final @Nullable MessageConverter messageConverter;
|
||||
|
||||
|
||||
public DefaultJmsClient(ConnectionFactory connectionFactory, @Nullable MessageConverter messageConverter) {
|
||||
this.jmsTemplate = new JmsTemplate(connectionFactory);
|
||||
this.messageConverter = messageConverter;
|
||||
}
|
||||
|
||||
public DefaultJmsClient(JmsOperations jmsTemplate, @Nullable MessageConverter messageConverter) {
|
||||
Assert.notNull(jmsTemplate, "JmsTemplate must not be null");
|
||||
this.jmsTemplate = jmsTemplate;
|
||||
this.messageConverter = messageConverter;
|
||||
}
|
||||
|
||||
|
||||
public OperationSpec destination(Destination destination) {
|
||||
return new DefaultOperationSpec(destination);
|
||||
}
|
||||
|
||||
public OperationSpec destination(String destinationName) {
|
||||
return new DefaultOperationSpec(destinationName);
|
||||
}
|
||||
|
||||
private JmsMessagingTemplate newDelegate() {
|
||||
JmsMessagingTemplate delegate = new JmsMessagingTemplate(DefaultJmsClient.this.jmsTemplate);
|
||||
MessageConverter converter = DefaultJmsClient.this.messageConverter;
|
||||
if (converter != null) {
|
||||
delegate.setMessageConverter(converter);
|
||||
}
|
||||
return delegate;
|
||||
}
|
||||
|
||||
|
||||
private class DefaultOperationSpec implements OperationSpec {
|
||||
|
||||
private final JmsMessagingTemplate delegate;
|
||||
|
||||
private @Nullable JmsTemplate customTemplate;
|
||||
|
||||
public DefaultOperationSpec(Destination destination) {
|
||||
this.delegate = newDelegate();
|
||||
this.delegate.setDefaultDestination(destination);
|
||||
}
|
||||
|
||||
public DefaultOperationSpec(String destinationName) {
|
||||
this.delegate = newDelegate();
|
||||
this.delegate.setDefaultDestinationName(destinationName);
|
||||
}
|
||||
|
||||
private JmsTemplate enforceCustomTemplate(boolean qos) {
|
||||
if (this.customTemplate == null) {
|
||||
JmsOperations jmsOperations = DefaultJmsClient.this.jmsTemplate;
|
||||
if (!(jmsOperations instanceof JmsAccessor original)) {
|
||||
throw new IllegalStateException(
|
||||
"Needs to be bound to a JmsAccessor for custom settings support: " + jmsOperations);
|
||||
}
|
||||
this.customTemplate = new JmsTemplate(original);
|
||||
this.delegate.setJmsTemplate(this.customTemplate);
|
||||
}
|
||||
if (qos) {
|
||||
this.customTemplate.setExplicitQosEnabled(true);
|
||||
}
|
||||
return this.customTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationSpec withReceiveTimeout(long receiveTimeout) {
|
||||
enforceCustomTemplate(false).setReceiveTimeout(receiveTimeout);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationSpec withDeliveryDelay(long deliveryDelay) {
|
||||
enforceCustomTemplate(false).setDeliveryDelay(deliveryDelay);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationSpec withDeliveryPersistent(boolean persistent) {
|
||||
enforceCustomTemplate(true).setDeliveryPersistent(persistent);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationSpec withPriority(int priority) {
|
||||
enforceCustomTemplate(true).setPriority(priority);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationSpec withTimeToLive(long timeToLive) {
|
||||
enforceCustomTemplate(true).setTimeToLive(timeToLive);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Message<?> message) throws MessagingException {
|
||||
this.delegate.send(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object payload) throws MessagingException {
|
||||
this.delegate.convertAndSend(payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object payload, Map<String, Object> headers) throws MessagingException {
|
||||
this.delegate.convertAndSend(payload, headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Message<?>> receive() throws MessagingException {
|
||||
return Optional.ofNullable(this.delegate.receive());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> receive(Class<T> targetClass) throws MessagingException {
|
||||
return Optional.ofNullable(this.delegate.receiveAndConvert(targetClass));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Message<?>> receive(String messageSelector) throws MessagingException {
|
||||
return Optional.ofNullable(this.delegate.receiveSelected(messageSelector));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> receive(String messageSelector, Class<T> targetClass) throws MessagingException {
|
||||
return Optional.ofNullable(this.delegate.receiveSelectedAndConvert(messageSelector, targetClass));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Message<?>> sendAndReceive(Message<?> requestMessage) throws MessagingException {
|
||||
return Optional.ofNullable(this.delegate.sendAndReceive(requestMessage));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> sendAndReceive(Object request, Class<T> targetClass) throws MessagingException {
|
||||
return Optional.ofNullable(this.delegate.convertSendAndReceive(request, targetClass));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> sendAndReceive(Object request, Map<String, Object> headers, Class<T> targetClass)
|
||||
throws MessagingException {
|
||||
|
||||
return Optional.ofNullable(this.delegate.convertSendAndReceive(request, headers, targetClass));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jms.core;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import jakarta.jms.ConnectionFactory;
|
||||
import jakarta.jms.Destination;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
|
||||
/**
|
||||
* A fluent {@code JmsClient} with common send and receive operations against a JMS
|
||||
* destination. This is effectively an alternative to {@link JmsMessagingTemplate},
|
||||
* also delegating to Spring's {@link JmsTemplate} for performing actual operations.
|
||||
*
|
||||
* <p>Note: Operations in this interface throw {@link MessagingException} instead of
|
||||
* the JMS-specific {@link org.springframework.jms.JmsException}, aligning with the
|
||||
* {@code spring-messaging} module and its other client operation handles.
|
||||
*
|
||||
* <p>This client provides reusable operation handles which can be configured with
|
||||
* custom QoS settings. Note that any use of such explicit settings will override
|
||||
* administrative provider settings (see {@link JmsTemplate#setExplicitQosEnabled}).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 7.0
|
||||
* @see JmsTemplate
|
||||
* @see JmsMessagingTemplate
|
||||
*/
|
||||
interface JmsClient {
|
||||
|
||||
/**
|
||||
* Provide an operation handle for the given JMS destination.
|
||||
* @param destination the JMS {@code Destination} object
|
||||
* @return a reusable operation handle bound to the destination
|
||||
*/
|
||||
OperationSpec destination(Destination destination);
|
||||
|
||||
/**
|
||||
* Provide an operation handle for the specified JMS destination.
|
||||
* @param destinationName a name resolving to a JMS {@code Destination}
|
||||
* @return a reusable operation handle bound to the destination
|
||||
* @see org.springframework.jms.support.destination.DestinationResolver
|
||||
*/
|
||||
OperationSpec destination(String destinationName);
|
||||
|
||||
|
||||
// Static factory methods
|
||||
|
||||
/**
|
||||
* Create a new {@code JmsClient} for the given {@link ConnectionFactory}.
|
||||
* @param connectionFactory the factory to obtain JMS connections from
|
||||
*/
|
||||
static JmsClient create(ConnectionFactory connectionFactory) {
|
||||
return new DefaultJmsClient(connectionFactory, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code JmsClient} for the given {@link ConnectionFactory}.
|
||||
* @param connectionFactory the factory to obtain JMS connections from
|
||||
* @param messageConverter the message converter for payload objects
|
||||
*/
|
||||
static JmsClient create(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
|
||||
return new DefaultJmsClient(connectionFactory, messageConverter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code JmsClient} for the given {@link ConnectionFactory}.
|
||||
* @param jmsTemplate the {@link JmsTemplate} to use for performing operations
|
||||
* (can be a custom {@link JmsOperations} implementation as well)
|
||||
*/
|
||||
static JmsClient create(JmsOperations jmsTemplate) {
|
||||
return new DefaultJmsClient(jmsTemplate, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code JmsClient} for the given {@link ConnectionFactory}.
|
||||
* @param jmsTemplate the {@link JmsTemplate} to use for performing operations
|
||||
* (can be a custom {@link JmsOperations} implementation as well)
|
||||
* @param messageConverter the message converter for payload objects
|
||||
*/
|
||||
static JmsClient create(JmsOperations jmsTemplate, MessageConverter messageConverter) {
|
||||
return new DefaultJmsClient(jmsTemplate, messageConverter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Common JMS send and receive operations with various settings.
|
||||
*/
|
||||
interface OperationSpec {
|
||||
|
||||
/**
|
||||
* Apply the given timeout to any subsequent receive operations.
|
||||
* @param receiveTimeout the timeout in milliseconds
|
||||
* @see JmsTemplate#setReceiveTimeout
|
||||
*/
|
||||
OperationSpec withReceiveTimeout(long receiveTimeout);
|
||||
|
||||
/**
|
||||
* Apply the given delivery delay to any subsequent send operations.
|
||||
* @param deliveryDelay the delay in milliseconds
|
||||
* @see JmsTemplate#setDeliveryDelay
|
||||
*/
|
||||
OperationSpec withDeliveryDelay(long deliveryDelay);
|
||||
|
||||
/**
|
||||
* Set whether message delivery should be persistent or non-persistent.
|
||||
* @param persistent to choose between delivery mode "PERSISTENT"
|
||||
* ({@code true}) or "NON_PERSISTENT" ({@code false})
|
||||
* @see JmsTemplate#setDeliveryPersistent
|
||||
*/
|
||||
OperationSpec withDeliveryPersistent(boolean persistent);
|
||||
|
||||
/**
|
||||
* Apply the given priority to any subsequent send operations.
|
||||
* @param priority the priority value
|
||||
* @see JmsTemplate#setPriority
|
||||
*/
|
||||
OperationSpec withPriority(int priority);
|
||||
|
||||
/**
|
||||
* Apply the given time-to-live to any subsequent send operations.
|
||||
* @param timeToLive the message lifetime in milliseconds
|
||||
* @see JmsTemplate#setTimeToLive
|
||||
*/
|
||||
OperationSpec withTimeToLive(long timeToLive);
|
||||
|
||||
/**
|
||||
* Send the given {@link Message} to the pre-bound destination.
|
||||
* @param message the spring-messaging {@link Message} to send
|
||||
* @see #withDeliveryDelay
|
||||
* @see #withDeliveryPersistent
|
||||
* @see #withPriority
|
||||
* @see #withTimeToLive
|
||||
*/
|
||||
void send(Message<?> message) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Send a message with the given payload to the pre-bound destination.
|
||||
* @param payload the payload to convert into a {@link Message}
|
||||
* @see #withDeliveryDelay
|
||||
* @see #withDeliveryPersistent
|
||||
* @see #withPriority
|
||||
* @see #withTimeToLive
|
||||
*/
|
||||
void send(Object payload) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Send a message with the given payload to the pre-bound destination.
|
||||
* @param payload the payload to convert into a {@link Message}
|
||||
* @param headers the message headers to apply to the {@link Message}
|
||||
* @see #withDeliveryDelay
|
||||
* @see #withDeliveryPersistent
|
||||
* @see #withPriority
|
||||
* @see #withTimeToLive
|
||||
*/
|
||||
void send(Object payload, Map<String, Object> headers) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a {@link Message} from the pre-bound destination.
|
||||
* @return the spring-messaging {@link Message} received,
|
||||
* or {@link Optional#empty()} if none
|
||||
* @see #withReceiveTimeout
|
||||
*/
|
||||
Optional<Message<?>> receive() throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a {@link Message} from the pre-bound destination,
|
||||
* extracting and converting its payload.
|
||||
* @param targetClass the class to convert the payload to
|
||||
* @return the payload of the {@link Message} received,
|
||||
* or {@link Optional#empty()} if none
|
||||
* @see #withReceiveTimeout
|
||||
*/
|
||||
<T> Optional<T> receive(Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a {@link Message} from the pre-bound destination.
|
||||
* @param messageSelector the JMS message selector to apply
|
||||
* @return the spring-messaging {@link Message} received,
|
||||
* or {@link Optional#empty()} if none
|
||||
* @see #withReceiveTimeout
|
||||
*/
|
||||
Optional<Message<?>> receive(String messageSelector) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a {@link Message} from the pre-bound destination,
|
||||
* extracting and converting its payload.
|
||||
* @param targetClass the class to convert the payload to
|
||||
* @return the payload of the {@link Message} received,
|
||||
* or {@link Optional#empty()} if none
|
||||
* @param messageSelector the JMS message selector to apply
|
||||
* @see #withReceiveTimeout
|
||||
*/
|
||||
<T> Optional<T> receive(String messageSelector, Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Send a request message and receive the reply from the given destination.
|
||||
* @param requestMessage the spring-messaging {@link Message} to send
|
||||
* @return the spring-messaging {@link Message} received as a reply,
|
||||
* or {@link Optional#empty()} if none
|
||||
* @see #withReceiveTimeout
|
||||
*/
|
||||
Optional<Message<?>> sendAndReceive(Message<?> requestMessage) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Send a request message and receive the reply from the given destination.
|
||||
* @param request the payload to convert into a request {@link Message}
|
||||
* @param targetClass the class to convert the reply's payload to
|
||||
* @return the payload of the {@link Message} received as a reply,
|
||||
* or {@link Optional#empty()} if none
|
||||
* @see #withTimeToLive
|
||||
* @see #withReceiveTimeout
|
||||
*/
|
||||
<T> Optional<T> sendAndReceive(Object request, Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Send a request message and receive the reply from the given destination.
|
||||
* @param request the payload to convert into a request {@link Message}
|
||||
* @param headers the message headers to apply to the request {@link Message}
|
||||
* @param targetClass the class to convert the reply's payload to
|
||||
* @return the payload of the {@link Message} received as a reply,
|
||||
* or {@link Optional#empty()} if none
|
||||
* @see #withTimeToLive
|
||||
* @see #withReceiveTimeout
|
||||
*/
|
||||
<T> Optional<T> sendAndReceive(Object request, Map<String, Object> headers, Class<T> targetClass)
|
||||
throws MessagingException;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,10 +30,15 @@ import org.springframework.messaging.core.MessageSendingOperations;
|
||||
|
||||
/**
|
||||
* A specialization of {@link MessageSendingOperations}, {@link MessageReceivingOperations}
|
||||
* and {@link MessageRequestReplyOperations} for JMS related operations that allow to specify
|
||||
* a destination name rather than the actual {@link jakarta.jms.Destination}.
|
||||
* and {@link MessageRequestReplyOperations} for JMS related operations that allow to
|
||||
* specify a destination name rather than the actual {@link jakarta.jms.Destination}.
|
||||
*
|
||||
* <p>Note: Operations in this interface throw {@link MessagingException} instead of
|
||||
* the JMS-specific {@link org.springframework.jms.JmsException}, aligning with the
|
||||
* {@code spring-messaging} module and its other client operation handles.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.1
|
||||
* @see org.springframework.jms.core.JmsTemplate
|
||||
* @see org.springframework.messaging.core.MessageSendingOperations
|
||||
@@ -68,30 +73,30 @@ public interface JmsMessageOperations extends MessageSendingOperations<Destinati
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers the headers for the message to send
|
||||
*/
|
||||
void convertAndSend(String destinationName, Object payload, Map<String, Object> headers)
|
||||
void convertAndSend(String destinationName, Object payload, @Nullable Map<String, Object> headers)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message, apply the given post processor, and send
|
||||
* wrap it as a message, apply the given post-processor, and send
|
||||
* the resulting message to the given destination.
|
||||
* @param destinationName the name of the target destination
|
||||
* @param payload the Object to use as payload
|
||||
* @param postProcessor the post processor to apply to the message
|
||||
* @param postProcessor the post-processor to apply to the message
|
||||
*/
|
||||
void convertAndSend(String destinationName, Object payload, MessagePostProcessor postProcessor)
|
||||
void convertAndSend(String destinationName, Object payload, @Nullable MessagePostProcessor postProcessor)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message with the given headers, apply the given post processor,
|
||||
* wrap it as a message with the given headers, apply the given post-processor,
|
||||
* and send the resulting message to the given destination.
|
||||
* @param destinationName the name of the target destination
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers the headers for the message to send
|
||||
* @param postProcessor the post processor to apply to the message
|
||||
* @param postProcessor the post-processor to apply to the message
|
||||
*/
|
||||
void convertAndSend(String destinationName, Object payload, @Nullable Map<String, Object> headers,
|
||||
@Nullable MessagePostProcessor postProcessor) throws MessagingException;
|
||||
@@ -114,6 +119,81 @@ public interface JmsMessageOperations extends MessageSendingOperations<Destinati
|
||||
*/
|
||||
<T> @Nullable T receiveAndConvert(String destinationName, Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a message from the default destination.
|
||||
* @param messageSelector the JMS message selector expression (or {@code null} if none).
|
||||
* See the JMS specification for a detailed definition of selector expressions.
|
||||
* @return the received message, possibly {@code null} if the message could not
|
||||
* be received, for example due to a timeout
|
||||
* @since 7.0
|
||||
*/
|
||||
@Nullable Message<?> receiveSelected(@Nullable String messageSelector) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a message from the given destination.
|
||||
* @param destination the target destination
|
||||
* @param messageSelector the JMS message selector expression (or {@code null} if none).
|
||||
* See the JMS specification for a detailed definition of selector expressions.
|
||||
* @return the received message, possibly {@code null} if the message could not
|
||||
* be received, for example due to a timeout
|
||||
* @since 7.0
|
||||
*/
|
||||
@Nullable Message<?> receiveSelected(Destination destination, @Nullable String messageSelector)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a message from the given destination.
|
||||
* @param destinationName the name of the target destination
|
||||
* @param messageSelector the JMS message selector expression (or {@code null} if none).
|
||||
* See the JMS specification for a detailed definition of selector expressions.
|
||||
* @return the received message, possibly {@code null} if the message could not
|
||||
* be received, for example due to a timeout
|
||||
* @since 7.0
|
||||
*/
|
||||
@Nullable Message<?> receiveSelected(String destinationName, @Nullable String messageSelector)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a message from the default destination and convert its payload to the
|
||||
* specified target class.
|
||||
* @param messageSelector the JMS message selector expression (or {@code null} if none).
|
||||
* See the JMS specification for a detailed definition of selector expressions.
|
||||
* @param targetClass the target class to convert the payload to
|
||||
* @return the converted payload of the reply message, possibly {@code null} if
|
||||
* the message could not be received, for example due to a timeout
|
||||
* @since 7.0
|
||||
*/
|
||||
<T> @Nullable T receiveSelectedAndConvert(@Nullable String messageSelector, Class<T> targetClass)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a message from the given destination and convert its payload to the
|
||||
* specified target class.
|
||||
* @param destination the target destination
|
||||
* @param messageSelector the JMS message selector expression (or {@code null} if none).
|
||||
* See the JMS specification for a detailed definition of selector expressions.
|
||||
* @param targetClass the target class to convert the payload to
|
||||
* @return the converted payload of the reply message, possibly {@code null} if
|
||||
* the message could not be received, for example due to a timeout
|
||||
* @since 7.0
|
||||
*/
|
||||
<T> @Nullable T receiveSelectedAndConvert(Destination destination, @Nullable String messageSelector,
|
||||
Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Receive a message from the given destination and convert its payload to the
|
||||
* specified target class.
|
||||
* @param destinationName the name of the target destination
|
||||
* @param messageSelector the JMS message selector expression (or {@code null} if none).
|
||||
* See the JMS specification for a detailed definition of selector expressions.
|
||||
* @param targetClass the target class to convert the payload to
|
||||
* @return the converted payload of the reply message, possibly {@code null} if
|
||||
* the message could not be received, for example due to a timeout
|
||||
* @since 7.0
|
||||
*/
|
||||
<T> @Nullable T receiveSelectedAndConvert(String destinationName, @Nullable String messageSelector,
|
||||
Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Send a request message and receive the reply from the given destination.
|
||||
* @param destinationName the name of the target destination
|
||||
@@ -121,7 +201,8 @@ public interface JmsMessageOperations extends MessageSendingOperations<Destinati
|
||||
* @return the reply, possibly {@code null} if the message could not be received,
|
||||
* for example due to a timeout
|
||||
*/
|
||||
@Nullable Message<?> sendAndReceive(String destinationName, Message<?> requestMessage) throws MessagingException;
|
||||
@Nullable Message<?> sendAndReceive(String destinationName, Message<?> requestMessage)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
@@ -134,7 +215,8 @@ public interface JmsMessageOperations extends MessageSendingOperations<Destinati
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
<T> @Nullable T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass) throws MessagingException;
|
||||
<T> @Nullable T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
@@ -148,13 +230,13 @@ public interface JmsMessageOperations extends MessageSendingOperations<Destinati
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
<T> @Nullable T convertSendAndReceive(String destinationName, Object request, @Nullable Map<String, Object> headers, Class<T> targetClass)
|
||||
throws MessagingException;
|
||||
<T> @Nullable T convertSendAndReceive(String destinationName, Object request,
|
||||
@Nullable Map<String, Object> headers, Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* apply the given post processor and send the resulting {@link Message} to the
|
||||
* apply the given post-processor and send the resulting {@link Message} to the
|
||||
* given destination, receive the reply and convert its body of the given
|
||||
* target class.
|
||||
* @param destinationName the name of the target destination
|
||||
@@ -165,12 +247,12 @@ public interface JmsMessageOperations extends MessageSendingOperations<Destinati
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
<T> @Nullable T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass,
|
||||
MessagePostProcessor requestPostProcessor) throws MessagingException;
|
||||
@Nullable MessagePostProcessor requestPostProcessor) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message with the given headers, apply the given post processor
|
||||
* wrap it as a message with the given headers, apply the given post-processor
|
||||
* and send the resulting {@link Message} to the specified destination, receive
|
||||
* the reply and convert its body of the given target class.
|
||||
* @param destinationName the name of the target destination
|
||||
@@ -180,7 +262,8 @@ public interface JmsMessageOperations extends MessageSendingOperations<Destinati
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
<T> @Nullable T convertSendAndReceive(String destinationName, Object request, Map<String, Object> headers,
|
||||
Class<T> targetClass, MessagePostProcessor requestPostProcessor) throws MessagingException;
|
||||
<T> @Nullable T convertSendAndReceive(String destinationName, Object request,
|
||||
@Nullable Map<String, Object> headers, Class<T> targetClass,
|
||||
@Nullable MessagePostProcessor requestPostProcessor) throws MessagingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jms.InvalidDestinationException;
|
||||
import org.springframework.jms.JmsException;
|
||||
import org.springframework.jms.support.JmsAccessor;
|
||||
import org.springframework.jms.support.converter.MessageConverter;
|
||||
import org.springframework.jms.support.converter.MessagingMessageConverter;
|
||||
import org.springframework.jms.support.converter.SimpleMessageConverter;
|
||||
@@ -39,16 +40,24 @@ import org.springframework.messaging.core.MessagePostProcessor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An implementation of {@link JmsMessageOperations}.
|
||||
* An implementation of {@link JmsMessageOperations}, as a wrapper on top of Spring's
|
||||
* traditional {@link JmsTemplate}. Aligned with the {@code spring-messaging} module
|
||||
* and {@link org.springframework.messaging.core.GenericMessagingTemplate}.
|
||||
*
|
||||
* <p>Note: Operations in this interface throw {@link MessagingException} instead of
|
||||
* the JMS-specific {@link org.springframework.jms.JmsException}, aligning with the
|
||||
* {@code spring-messaging} module and its other client operation handles.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.1
|
||||
* @see JmsTemplate
|
||||
* @see JmsClient
|
||||
*/
|
||||
public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
implements JmsMessageOperations, InitializingBean {
|
||||
|
||||
private @Nullable JmsTemplate jmsTemplate;
|
||||
private @Nullable JmsOperations jmsTemplate;
|
||||
|
||||
private MessageConverter jmsMessageConverter = new MessagingMessageConverter();
|
||||
|
||||
@@ -73,12 +82,20 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
this.jmsTemplate = new JmsTemplate(connectionFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code JmsMessagingTemplate} instance with the {@link JmsOperations} to use.
|
||||
* @since 7.0
|
||||
*/
|
||||
public JmsMessagingTemplate(JmsOperations jmsTemplate) {
|
||||
Assert.notNull(jmsTemplate, "JmsTemplate must not be null");
|
||||
this.jmsTemplate = jmsTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code JmsMessagingTemplate} instance with the {@link JmsTemplate} to use.
|
||||
*/
|
||||
public JmsMessagingTemplate(JmsTemplate jmsTemplate) {
|
||||
Assert.notNull(jmsTemplate, "JmsTemplate must not be null");
|
||||
this.jmsTemplate = jmsTemplate;
|
||||
this((JmsOperations) jmsTemplate);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,8 +104,8 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public void setConnectionFactory(ConnectionFactory connectionFactory) {
|
||||
if (this.jmsTemplate != null) {
|
||||
this.jmsTemplate.setConnectionFactory(connectionFactory);
|
||||
if (this.jmsTemplate instanceof JmsAccessor template) {
|
||||
template.setConnectionFactory(connectionFactory);
|
||||
}
|
||||
else {
|
||||
this.jmsTemplate = new JmsTemplate(connectionFactory);
|
||||
@@ -100,7 +117,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public @Nullable ConnectionFactory getConnectionFactory() {
|
||||
return (this.jmsTemplate != null ? this.jmsTemplate.getConnectionFactory() : null);
|
||||
return (this.jmsTemplate instanceof JmsTemplate template ? template.getConnectionFactory() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,14 +131,14 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
* Return the configured {@link JmsTemplate}.
|
||||
*/
|
||||
public @Nullable JmsTemplate getJmsTemplate() {
|
||||
return this.jmsTemplate;
|
||||
return (this.jmsTemplate instanceof JmsTemplate template ? template : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link MessageConverter} to use to convert a {@link Message} from
|
||||
* the messaging to and from a {@link jakarta.jms.Message}. By default, a
|
||||
* {@link MessagingMessageConverter} is defined using a {@link SimpleMessageConverter}
|
||||
* to convert the payload of the message.
|
||||
* Set the {@link MessageConverter} to use to convert a {@link Message}
|
||||
* to and from a {@link jakarta.jms.Message}.
|
||||
* <p>By default, a {@link MessagingMessageConverter} is defined using a
|
||||
* {@link SimpleMessageConverter} to convert the payload of the message.
|
||||
* <p>Consider configuring a {@link MessagingMessageConverter} with a different
|
||||
* {@link MessagingMessageConverter#setPayloadConverter(MessageConverter) payload converter}
|
||||
* for more advanced scenarios.
|
||||
@@ -135,7 +152,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
|
||||
/**
|
||||
* Return the {@link MessageConverter} to use to convert a {@link Message}
|
||||
* from the messaging to and from a {@link jakarta.jms.Message}.
|
||||
* to and from a {@link jakarta.jms.Message}.
|
||||
*/
|
||||
public MessageConverter getJmsMessageConverter() {
|
||||
return this.jmsMessageConverter;
|
||||
@@ -161,20 +178,19 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.notNull(this.jmsTemplate, "Property 'connectionFactory' or 'jmsTemplate' is required");
|
||||
if (!this.converterSet && this.jmsTemplate.getMessageConverter() != null) {
|
||||
((MessagingMessageConverter) this.jmsMessageConverter)
|
||||
.setPayloadConverter(this.jmsTemplate.getMessageConverter());
|
||||
if (!this.converterSet && this.jmsTemplate instanceof JmsTemplate template) {
|
||||
((MessagingMessageConverter) this.jmsMessageConverter).setPayloadConverter(template.getMessageConverter());
|
||||
}
|
||||
}
|
||||
|
||||
private JmsTemplate obtainJmsTemplate() {
|
||||
JmsOperations obtainJmsTemplate() {
|
||||
Assert.state(this.jmsTemplate != null, "No JmsTemplate set");
|
||||
return this.jmsTemplate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void send(Message<?> message) {
|
||||
public void send(Message<?> message) throws MessagingException {
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
send(defaultDestination, message);
|
||||
@@ -185,13 +201,15 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(Object payload, @Nullable MessagePostProcessor postProcessor) throws MessagingException {
|
||||
public void convertAndSend(Object payload, @Nullable Map<String, Object> headers,
|
||||
@Nullable MessagePostProcessor postProcessor) throws MessagingException {
|
||||
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
convertAndSend(defaultDestination, payload, postProcessor);
|
||||
convertAndSend(defaultDestination, payload, headers, postProcessor);
|
||||
}
|
||||
else {
|
||||
convertAndSend(getRequiredDefaultDestinationName(), payload, postProcessor);
|
||||
convertAndSend(getRequiredDefaultDestinationName(), payload, headers, postProcessor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +246,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Message<?> receive() {
|
||||
public @Nullable Message<?> receive() throws MessagingException {
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
return receive(defaultDestination);
|
||||
@@ -239,7 +257,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T receiveAndConvert(Class<T> targetClass) {
|
||||
public <T> @Nullable T receiveAndConvert(Class<T> targetClass) throws MessagingException {
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
return receiveAndConvert(defaultDestination, targetClass);
|
||||
@@ -266,7 +284,71 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Message<?> sendAndReceive(Message<?> requestMessage) {
|
||||
public @Nullable Message<?> receiveSelected(@Nullable String messageSelector) throws MessagingException {
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
return receiveSelected(defaultDestination, messageSelector);
|
||||
}
|
||||
else {
|
||||
return receiveSelected(getRequiredDefaultDestinationName(), messageSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Message<?> receiveSelected(Destination destination, @Nullable String messageSelector)
|
||||
throws MessagingException {
|
||||
|
||||
return doReceiveSelected(destination, messageSelector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Message<?> receiveSelected(String destinationName, @Nullable String messageSelector)
|
||||
throws MessagingException {
|
||||
|
||||
return doReceiveSelected(destinationName, messageSelector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T receiveSelectedAndConvert(@Nullable String messageSelector, Class<T> targetClass)
|
||||
throws MessagingException {
|
||||
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
return receiveSelectedAndConvert(defaultDestination, messageSelector, targetClass);
|
||||
}
|
||||
else {
|
||||
return receiveSelectedAndConvert(getRequiredDefaultDestinationName(), messageSelector, targetClass);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T receiveSelectedAndConvert(Destination destination, @Nullable String messageSelector,
|
||||
Class<T> targetClass) throws MessagingException {
|
||||
|
||||
Message<?> message = doReceiveSelected(destination, messageSelector);
|
||||
if (message != null) {
|
||||
return doConvert(message, targetClass);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T receiveSelectedAndConvert(String destinationName, @Nullable String messageSelector,
|
||||
Class<T> targetClass) throws MessagingException {
|
||||
|
||||
Message<?> message = doReceiveSelected(destinationName, messageSelector);
|
||||
if (message != null) {
|
||||
return doConvert(message, targetClass);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Message<?> sendAndReceive(Message<?> requestMessage) throws MessagingException {
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
return sendAndReceive(defaultDestination, requestMessage);
|
||||
@@ -277,7 +359,9 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Message<?> sendAndReceive(String destinationName, Message<?> requestMessage) throws MessagingException {
|
||||
public @Nullable Message<?> sendAndReceive(String destinationName, Message<?> requestMessage)
|
||||
throws MessagingException {
|
||||
|
||||
return doSendAndReceive(destinationName, requestMessage);
|
||||
}
|
||||
|
||||
@@ -289,7 +373,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(Object request, Class<T> targetClass) {
|
||||
public <T> @Nullable T convertSendAndReceive(Object request, Class<T> targetClass) throws MessagingException {
|
||||
return convertSendAndReceive(request, targetClass, null);
|
||||
}
|
||||
|
||||
@@ -301,7 +385,9 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(Object request, Class<T> targetClass, @Nullable MessagePostProcessor postProcessor) {
|
||||
public <T> @Nullable T convertSendAndReceive(Object request, Class<T> targetClass,
|
||||
@Nullable MessagePostProcessor postProcessor) throws MessagingException {
|
||||
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
return convertSendAndReceive(defaultDestination, request, targetClass, postProcessor);
|
||||
@@ -320,14 +406,16 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(String destinationName, Object request, @Nullable Map<String, Object> headers,
|
||||
Class<T> targetClass, @Nullable MessagePostProcessor postProcessor) {
|
||||
public <T> @Nullable T convertSendAndReceive(String destinationName, Object request,
|
||||
@Nullable Map<String, Object> headers, Class<T> targetClass,
|
||||
@Nullable MessagePostProcessor postProcessor) throws MessagingException {
|
||||
|
||||
Message<?> requestMessage = doConvert(request, headers, postProcessor);
|
||||
Message<?> replyMessage = sendAndReceive(destinationName, requestMessage);
|
||||
return (replyMessage != null ? (T) getMessageConverter().fromMessage(replyMessage, targetClass) : null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doSend(Destination destination, Message<?> message) {
|
||||
try {
|
||||
@@ -368,6 +456,26 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
|
||||
}
|
||||
}
|
||||
|
||||
protected @Nullable Message<?> doReceiveSelected(Destination destination, @Nullable String messageSelector) {
|
||||
try {
|
||||
jakarta.jms.Message jmsMessage = obtainJmsTemplate().receiveSelected(destination, messageSelector);
|
||||
return convertJmsMessage(jmsMessage);
|
||||
}
|
||||
catch (JmsException ex) {
|
||||
throw convertJmsException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected @Nullable Message<?> doReceiveSelected(String destinationName, @Nullable String messageSelector) {
|
||||
try {
|
||||
jakarta.jms.Message jmsMessage = obtainJmsTemplate().receiveSelected(destinationName, messageSelector);
|
||||
return convertJmsMessage(jmsMessage);
|
||||
}
|
||||
catch (JmsException ex) {
|
||||
throw convertJmsException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Message<?> doSendAndReceive(Destination destination, Message<?> requestMessage) {
|
||||
try {
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.jms.JmsException;
|
||||
import org.springframework.jms.connection.ConnectionFactoryUtils;
|
||||
import org.springframework.jms.connection.JmsResourceHolder;
|
||||
import org.springframework.jms.support.JmsAccessor;
|
||||
import org.springframework.jms.support.JmsUtils;
|
||||
import org.springframework.jms.support.QosSettings;
|
||||
import org.springframework.jms.support.converter.MessageConverter;
|
||||
@@ -47,10 +48,9 @@ import org.springframework.util.ClassUtils;
|
||||
/**
|
||||
* Helper class that simplifies synchronous JMS access code.
|
||||
*
|
||||
* <p>If you want to use dynamic destination creation, you must specify
|
||||
* the type of JMS destination to create, using the "pubSubDomain" property.
|
||||
* For other operations, this is not necessary. Point-to-Point (Queues) is the default
|
||||
* domain.
|
||||
* <p>If you want to use dynamic destination creation, you must specify the type of
|
||||
* JMS destination to create, using the "pubSubDomain" property. For other operations,
|
||||
* this is not necessary. Point-to-Point (Queues) is the default domain.
|
||||
*
|
||||
* <p>Default settings for JMS Sessions are "not transacted" and "auto-acknowledge".
|
||||
* As defined by the Jakarta EE specification, the transaction and acknowledgement
|
||||
@@ -89,6 +89,8 @@ import org.springframework.util.ClassUtils;
|
||||
* @see #setMessageConverter
|
||||
* @see jakarta.jms.MessageProducer
|
||||
* @see jakarta.jms.MessageConsumer
|
||||
* @see JmsMessagingTemplate
|
||||
* @see JmsClient
|
||||
*/
|
||||
public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations {
|
||||
|
||||
@@ -101,8 +103,7 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
|
||||
private @Nullable Object defaultDestination;
|
||||
|
||||
private @Nullable MessageConverter messageConverter;
|
||||
|
||||
private MessageConverter messageConverter = new SimpleMessageConverter();
|
||||
|
||||
private boolean messageIdEnabled = true;
|
||||
|
||||
@@ -114,7 +115,6 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
|
||||
private long deliveryDelay = -1;
|
||||
|
||||
|
||||
private boolean explicitQosEnabled = false;
|
||||
|
||||
private int deliveryMode = Message.DEFAULT_DELIVERY_MODE;
|
||||
@@ -134,7 +134,6 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
* @see #setConnectionFactory
|
||||
*/
|
||||
public JmsTemplate() {
|
||||
initDefaultStrategies();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,21 +141,37 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
* @param connectionFactory the ConnectionFactory to obtain Connections from
|
||||
*/
|
||||
public JmsTemplate(ConnectionFactory connectionFactory) {
|
||||
this();
|
||||
setConnectionFactory(connectionFactory);
|
||||
afterPropertiesSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the default implementations for the template's strategies:
|
||||
* DynamicDestinationResolver and SimpleMessageConverter.
|
||||
* @see #setDestinationResolver
|
||||
* @see #setMessageConverter
|
||||
* @see org.springframework.jms.support.destination.DynamicDestinationResolver
|
||||
* @see org.springframework.jms.support.converter.SimpleMessageConverter
|
||||
* Copy constructor for a derived JmsTemplate.
|
||||
* @param original the original template to copy from
|
||||
* @since 7.0
|
||||
*/
|
||||
protected void initDefaultStrategies() {
|
||||
setMessageConverter(new SimpleMessageConverter());
|
||||
public JmsTemplate(JmsAccessor original) {
|
||||
setConnectionFactory(original.getConnectionFactory());
|
||||
setSessionTransacted(original.isSessionTransacted());
|
||||
setSessionAcknowledgeMode(original.getSessionAcknowledgeMode());
|
||||
if (original instanceof JmsDestinationAccessor destinationAccessor) {
|
||||
setDestinationResolver(destinationAccessor.getDestinationResolver());
|
||||
setPubSubDomain(destinationAccessor.isPubSubDomain());
|
||||
}
|
||||
if (original instanceof JmsTemplate originalTemplate) {
|
||||
setDefaultDestination(originalTemplate.getDefaultDestination());
|
||||
setMessageConverter(originalTemplate.getMessageConverter());
|
||||
setMessageIdEnabled(originalTemplate.isMessageIdEnabled());
|
||||
setMessageTimestampEnabled(originalTemplate.isMessageTimestampEnabled());
|
||||
setPubSubNoLocal(originalTemplate.isPubSubNoLocal());
|
||||
setReceiveTimeout(originalTemplate.getReceiveTimeout());
|
||||
setDeliveryDelay(originalTemplate.getDeliveryDelay());
|
||||
setExplicitQosEnabled(originalTemplate.isExplicitQosEnabled());
|
||||
setDeliveryMode(originalTemplate.getDeliveryMode());
|
||||
setPriority(originalTemplate.getPriority());
|
||||
setTimeToLive(originalTemplate.getTimeToLive());
|
||||
setObservationRegistry(originalTemplate.getObservationRegistry());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -236,26 +251,18 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
* @see #receiveAndConvert
|
||||
* @see org.springframework.jms.support.converter.SimpleMessageConverter
|
||||
*/
|
||||
public void setMessageConverter(@Nullable MessageConverter messageConverter) {
|
||||
public void setMessageConverter(MessageConverter messageConverter) {
|
||||
Assert.notNull(messageConverter, "MessageConverter must not be null");
|
||||
this.messageConverter = messageConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the message converter for this template.
|
||||
*/
|
||||
public @Nullable MessageConverter getMessageConverter() {
|
||||
public MessageConverter getMessageConverter() {
|
||||
return this.messageConverter;
|
||||
}
|
||||
|
||||
private MessageConverter getRequiredMessageConverter() throws IllegalStateException {
|
||||
MessageConverter converter = getMessageConverter();
|
||||
if (converter == null) {
|
||||
throw new IllegalStateException("No 'messageConverter' specified. Check configuration of JmsTemplate.");
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether message IDs are enabled. Default is "true".
|
||||
* <p>This is only a hint to the JMS producer.
|
||||
@@ -345,7 +352,6 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
return this.deliveryDelay;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set if the QOS values (deliveryMode, priority, timeToLive)
|
||||
* should be used for sending a message.
|
||||
@@ -447,7 +453,7 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
* Set the time-to-live of the message when sending.
|
||||
* <p>Since a default value may be defined administratively,
|
||||
* this is only used when "isExplicitQosEnabled" equals "true".
|
||||
* @param timeToLive the message's lifetime (in milliseconds)
|
||||
* @param timeToLive the message lifetime (in milliseconds)
|
||||
* @see #isExplicitQosEnabled
|
||||
* @see jakarta.jms.Message#DEFAULT_TIME_TO_LIVE
|
||||
* @see jakarta.jms.MessageProducer#send(jakarta.jms.Message, int, int, long)
|
||||
@@ -465,14 +471,23 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
|
||||
/**
|
||||
* Configure the {@link ObservationRegistry} to use for recording JMS observations.
|
||||
* @param observationRegistry the observation registry to use.
|
||||
* @param observationRegistry the observation registry to use
|
||||
* @since 6.1
|
||||
* @see io.micrometer.jakarta9.instrument.jms.JmsInstrumentation
|
||||
*/
|
||||
public void setObservationRegistry(ObservationRegistry observationRegistry) {
|
||||
public void setObservationRegistry(@Nullable ObservationRegistry observationRegistry) {
|
||||
this.observationRegistry = observationRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link ObservationRegistry} to use for recording JMS observations.
|
||||
* @since 7.0
|
||||
*/
|
||||
public @Nullable ObservationRegistry getObservationRegistry() {
|
||||
return this.observationRegistry;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// JmsOperations execute methods
|
||||
//---------------------------------------------------------------------------------------
|
||||
@@ -667,12 +682,12 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
|
||||
@Override
|
||||
public void convertAndSend(Destination destination, Object message) throws JmsException {
|
||||
send(destination, session -> getRequiredMessageConverter().toMessage(message, session));
|
||||
send(destination, session -> getMessageConverter().toMessage(message, session));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(String destinationName, Object message) throws JmsException {
|
||||
send(destinationName, session -> getRequiredMessageConverter().toMessage(message, session));
|
||||
send(destinationName, session -> getMessageConverter().toMessage(message, session));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -687,23 +702,21 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(
|
||||
Destination destination, Object message, MessagePostProcessor postProcessor)
|
||||
public void convertAndSend(Destination destination, Object message, MessagePostProcessor postProcessor)
|
||||
throws JmsException {
|
||||
|
||||
send(destination, session -> {
|
||||
Message msg = getRequiredMessageConverter().toMessage(message, session);
|
||||
Message msg = getMessageConverter().toMessage(message, session);
|
||||
return postProcessor.postProcessMessage(msg);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(
|
||||
String destinationName, Object message, MessagePostProcessor postProcessor)
|
||||
throws JmsException {
|
||||
public void convertAndSend(String destinationName, Object message, MessagePostProcessor postProcessor)
|
||||
throws JmsException {
|
||||
|
||||
send(destinationName, session -> {
|
||||
Message msg = getRequiredMessageConverter().toMessage(message, session);
|
||||
Message msg = getMessageConverter().toMessage(message, session);
|
||||
return postProcessor.postProcessMessage(msg);
|
||||
});
|
||||
}
|
||||
@@ -855,7 +868,7 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
protected @Nullable Object doConvertFromMessage(@Nullable Message message) {
|
||||
if (message != null) {
|
||||
try {
|
||||
return getRequiredMessageConverter().fromMessage(message);
|
||||
return getMessageConverter().fromMessage(message);
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
throw convertJmsAccessException(ex);
|
||||
@@ -1178,6 +1191,7 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private abstract static class MicrometerInstrumentation {
|
||||
|
||||
static Session instrumentSession(Session session, ObservationRegistry registry) {
|
||||
|
||||
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jms.core;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.jms.Connection;
|
||||
import jakarta.jms.ConnectionFactory;
|
||||
import jakarta.jms.DeliveryMode;
|
||||
import jakarta.jms.Destination;
|
||||
import jakarta.jms.JMSException;
|
||||
import jakarta.jms.MessageConsumer;
|
||||
import jakarta.jms.MessageProducer;
|
||||
import jakarta.jms.Queue;
|
||||
import jakarta.jms.Session;
|
||||
import jakarta.jms.TextMessage;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.jms.InvalidDestinationException;
|
||||
import org.springframework.jms.MessageNotReadableException;
|
||||
import org.springframework.jms.StubTextMessage;
|
||||
import org.springframework.jms.support.destination.DestinationResolutionException;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.converter.GenericMessageConverter;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.willThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link JmsClient}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 7.0
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class JmsClientTests {
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<MessageCreator> messageCreator;
|
||||
|
||||
@Mock
|
||||
private JmsTemplate jmsTemplate;
|
||||
|
||||
private JmsClient jmsClient;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.jmsClient = JmsClient.create(this.jmsTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
void send() {
|
||||
Destination destination = new Destination() {};
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
this.jmsClient.destination(destination).send(message);
|
||||
verify(this.jmsTemplate).send(eq(destination), this.messageCreator.capture());
|
||||
assertTextMessage(this.messageCreator.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendName() {
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
this.jmsClient.destination("myQueue").send(message);
|
||||
verify(this.jmsTemplate).send(eq("myQueue"), this.messageCreator.capture());
|
||||
assertTextMessage(this.messageCreator.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertAndSendPayload() throws JMSException {
|
||||
Destination destination = new Destination() {};
|
||||
|
||||
this.jmsClient.destination(destination).send("my Payload");
|
||||
verify(this.jmsTemplate).send(eq(destination), this.messageCreator.capture());
|
||||
TextMessage textMessage = createTextMessage(this.messageCreator.getValue());
|
||||
assertThat(textMessage.getText()).isEqualTo("my Payload");
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertAndSendPayloadName() throws JMSException {
|
||||
this.jmsClient.destination("myQueue").send("my Payload");
|
||||
verify(this.jmsTemplate).send(eq("myQueue"), this.messageCreator.capture());
|
||||
TextMessage textMessage = createTextMessage(this.messageCreator.getValue());
|
||||
assertThat(textMessage.getText()).isEqualTo("my Payload");
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertAndSendPayloadAndHeaders() {
|
||||
Destination destination = new Destination() {};
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
headers.put("foo", "bar");
|
||||
|
||||
this.jmsClient.destination(destination).send("Hello", headers);
|
||||
verify(this.jmsTemplate).send(eq(destination), this.messageCreator.capture());
|
||||
assertTextMessage(this.messageCreator.getValue()); // see createTextMessage
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertAndSendPayloadAndHeadersName() {
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
headers.put("foo", "bar");
|
||||
|
||||
this.jmsClient.destination("myQueue").send("Hello", headers);
|
||||
verify(this.jmsTemplate).send(eq("myQueue"), this.messageCreator.capture());
|
||||
assertTextMessage(this.messageCreator.getValue()); // see createTextMessage
|
||||
}
|
||||
|
||||
@Test
|
||||
void receive() {
|
||||
Destination destination = new Destination() {};
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.receive(destination)).willReturn(jmsMessage);
|
||||
|
||||
Message<?> message = this.jmsClient.destination(destination).receive().get();
|
||||
verify(this.jmsTemplate).receive(destination);
|
||||
assertTextMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveName() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage);
|
||||
|
||||
Message<?> message = this.jmsClient.destination("myQueue").receive().get();
|
||||
verify(this.jmsTemplate).receive("myQueue");
|
||||
assertTextMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelected() {
|
||||
Destination destination = new Destination() {};
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.receiveSelected(destination, "selector")).willReturn(jmsMessage);
|
||||
|
||||
Message<?> message = this.jmsClient.destination(destination).receive("selector").get();
|
||||
verify(this.jmsTemplate).receiveSelected(destination, "selector");
|
||||
assertTextMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedName() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
Message<?> message = this.jmsClient.destination("myQueue").receive("selector").get();
|
||||
verify(this.jmsTemplate).receiveSelected("myQueue", "selector");
|
||||
assertTextMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveAndConvert() {
|
||||
Destination destination = new Destination() {};
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload");
|
||||
given(this.jmsTemplate.receive(destination)).willReturn(jmsMessage);
|
||||
|
||||
String payload = this.jmsClient.destination(destination).receive(String.class).get();
|
||||
assertThat(payload).isEqualTo("my Payload");
|
||||
verify(this.jmsTemplate).receive(destination);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveAndConvertName() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload");
|
||||
given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage);
|
||||
|
||||
String payload = this.jmsClient.destination("myQueue").receive(String.class).get();
|
||||
assertThat(payload).isEqualTo("my Payload");
|
||||
verify(this.jmsTemplate).receive("myQueue");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveAndConvertWithConversion() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("123");
|
||||
given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage);
|
||||
|
||||
this.jmsClient = JmsClient.create(this.jmsTemplate, new GenericMessageConverter());
|
||||
|
||||
Integer payload = this.jmsClient.destination("myQueue").receive(Integer.class).get();
|
||||
assertThat(payload).isEqualTo(Integer.valueOf(123));
|
||||
verify(this.jmsTemplate).receive("myQueue");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveAndConvertNoConverter() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("Hello");
|
||||
given(this.jmsTemplate.receive("myQueue")).willReturn(jmsMessage);
|
||||
|
||||
assertThatExceptionOfType(org.springframework.messaging.converter.MessageConversionException.class).isThrownBy(() ->
|
||||
this.jmsClient.destination("myQueue").receive(Writer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveAndConvertNoInput() {
|
||||
given(this.jmsTemplate.receive("myQueue")).willReturn(null);
|
||||
|
||||
assertThat(this.jmsClient.destination("myQueue").receive(String.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvert() {
|
||||
Destination destination = new Destination() {};
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload");
|
||||
given(this.jmsTemplate.receiveSelected(destination, "selector")).willReturn(jmsMessage);
|
||||
|
||||
String payload = this.jmsClient.destination(destination).receive("selector", String.class).get();
|
||||
assertThat(payload).isEqualTo("my Payload");
|
||||
verify(this.jmsTemplate).receiveSelected(destination, "selector");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertName() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload");
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
String payload = this.jmsClient.destination("myQueue").receive("selector", String.class).get();
|
||||
assertThat(payload).isEqualTo("my Payload");
|
||||
verify(this.jmsTemplate).receiveSelected("myQueue", "selector");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertWithConversion() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("123");
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
this.jmsClient = JmsClient.create(this.jmsTemplate, new GenericMessageConverter());
|
||||
|
||||
Integer payload = this.jmsClient.destination("myQueue").receive("selector", Integer.class).get();
|
||||
assertThat(payload).isEqualTo(Integer.valueOf(123));
|
||||
verify(this.jmsTemplate).receiveSelected("myQueue", "selector");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertNoConverter() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("Hello");
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
assertThatExceptionOfType(org.springframework.messaging.converter.MessageConversionException.class).isThrownBy(() ->
|
||||
this.jmsClient.destination("myQueue").receive("selector", Writer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertNoInput() {
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(null);
|
||||
|
||||
assertThat(this.jmsClient.destination("myQueue").receive("selector", String.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendAndReceive() {
|
||||
Destination destination = new Destination() {};
|
||||
Message<String> request = createTextMessage();
|
||||
jakarta.jms.Message replyJmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.sendAndReceive(eq(destination), any())).willReturn(replyJmsMessage);
|
||||
|
||||
Message<?> actual = this.jmsClient.destination(destination).sendAndReceive(request).get();
|
||||
verify(this.jmsTemplate, times(1)).sendAndReceive(eq(destination), any());
|
||||
assertTextMessage(actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendAndReceiveName() {
|
||||
Message<String> request = createTextMessage();
|
||||
jakarta.jms.Message replyJmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.sendAndReceive(eq("myQueue"), any())).willReturn(replyJmsMessage);
|
||||
|
||||
Message<?> actual = this.jmsClient.destination("myQueue").sendAndReceive(request).get();
|
||||
verify(this.jmsTemplate, times(1)).sendAndReceive(eq("myQueue"), any());
|
||||
assertTextMessage(actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertSendAndReceivePayload() {
|
||||
Destination destination = new Destination() {};
|
||||
jakarta.jms.Message replyJmsMessage = createJmsTextMessage("My reply");
|
||||
given(this.jmsTemplate.sendAndReceive(eq(destination), any())).willReturn(replyJmsMessage);
|
||||
|
||||
String reply = this.jmsClient.destination(destination).sendAndReceive("my Payload", String.class).get();
|
||||
verify(this.jmsTemplate, times(1)).sendAndReceive(eq(destination), any());
|
||||
assertThat(reply).isEqualTo("My reply");
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertSendAndReceivePayloadName() {
|
||||
jakarta.jms.Message replyJmsMessage = createJmsTextMessage("My reply");
|
||||
given(this.jmsTemplate.sendAndReceive(eq("myQueue"), any())).willReturn(replyJmsMessage);
|
||||
|
||||
String reply = this.jmsClient.destination("myQueue").sendAndReceive("my Payload", String.class).get();
|
||||
verify(this.jmsTemplate, times(1)).sendAndReceive(eq("myQueue"), any());
|
||||
assertThat(reply).isEqualTo("My reply");
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertMessageNotReadableException() {
|
||||
willThrow(MessageNotReadableException.class).given(this.jmsTemplate).receive("myQueue");
|
||||
|
||||
assertThatExceptionOfType(MessagingException.class).isThrownBy(() ->
|
||||
this.jmsClient.destination("myQueue").receive());
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertDestinationResolutionExceptionOnSend() {
|
||||
Destination destination = new Destination() {};
|
||||
willThrow(DestinationResolutionException.class).given(this.jmsTemplate).send(eq(destination), any());
|
||||
|
||||
assertThatExceptionOfType(org.springframework.messaging.core.DestinationResolutionException.class).isThrownBy(() ->
|
||||
this.jmsClient.destination(destination).send(createTextMessage()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertDestinationResolutionExceptionOnReceive() {
|
||||
Destination destination = new Destination() {};
|
||||
willThrow(DestinationResolutionException.class).given(this.jmsTemplate).receive(destination);
|
||||
|
||||
assertThatExceptionOfType(org.springframework.messaging.core.DestinationResolutionException.class).isThrownBy(() ->
|
||||
this.jmsClient.destination(destination).receive());
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertInvalidDestinationExceptionOnSendAndReceiveWithName() {
|
||||
willThrow(InvalidDestinationException.class).given(this.jmsTemplate).sendAndReceive(eq("unknownQueue"), any());
|
||||
|
||||
assertThatExceptionOfType(org.springframework.messaging.core.DestinationResolutionException.class).isThrownBy(() ->
|
||||
this.jmsClient.destination("unknownQueue").sendAndReceive(createTextMessage()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertInvalidDestinationExceptionOnSendAndReceive() {
|
||||
Destination destination = new Destination() {};
|
||||
willThrow(InvalidDestinationException.class).given(this.jmsTemplate).sendAndReceive(eq(destination), any());
|
||||
|
||||
assertThatExceptionOfType(org.springframework.messaging.core.DestinationResolutionException.class).isThrownBy(() ->
|
||||
this.jmsClient.destination(destination).sendAndReceive(createTextMessage()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendWithDefaults() throws Exception {
|
||||
ConnectionFactory connectionFactory = mock();
|
||||
Connection connection = mock();
|
||||
Session session = mock();
|
||||
Queue queue = mock();
|
||||
MessageProducer messageProducer = mock();
|
||||
TextMessage textMessage = mock();
|
||||
|
||||
given(connectionFactory.createConnection()).willReturn(connection);
|
||||
given(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)).willReturn(session);
|
||||
given(session.createProducer(queue)).willReturn(messageProducer);
|
||||
given(session.createTextMessage("just testing")).willReturn(textMessage);
|
||||
|
||||
JmsClient.create(connectionFactory).destination(queue)
|
||||
.send("just testing");
|
||||
|
||||
verify(messageProducer).send(textMessage);
|
||||
verify(messageProducer).close();
|
||||
verify(session).close();
|
||||
verify(connection).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendWithCustomSettings() throws Exception {
|
||||
ConnectionFactory connectionFactory = mock();
|
||||
Connection connection = mock();
|
||||
Session session = mock();
|
||||
Queue queue = mock();
|
||||
MessageProducer messageProducer = mock();
|
||||
TextMessage textMessage = mock();
|
||||
|
||||
given(connectionFactory.createConnection()).willReturn(connection);
|
||||
given(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)).willReturn(session);
|
||||
given(session.createProducer(queue)).willReturn(messageProducer);
|
||||
given(session.createTextMessage("just testing")).willReturn(textMessage);
|
||||
|
||||
JmsClient.create(connectionFactory).destination(queue)
|
||||
.withDeliveryDelay(0).withDeliveryPersistent(false).withPriority(2).withTimeToLive(3)
|
||||
.send("just testing");
|
||||
|
||||
verify(messageProducer).setDeliveryDelay(0);
|
||||
verify(messageProducer).send(textMessage, DeliveryMode.NON_PERSISTENT, 2, 3);
|
||||
verify(messageProducer).close();
|
||||
verify(session).close();
|
||||
verify(connection).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveWithDefaults() throws Exception {
|
||||
ConnectionFactory connectionFactory = mock();
|
||||
Connection connection = mock();
|
||||
Session session = mock();
|
||||
Queue queue = mock();
|
||||
MessageConsumer messageConsumer = mock();
|
||||
TextMessage textMessage = mock();
|
||||
|
||||
given(connectionFactory.createConnection()).willReturn(connection);
|
||||
given(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)).willReturn(session);
|
||||
given(session.createConsumer(queue, null)).willReturn(messageConsumer);
|
||||
given(messageConsumer.receive()).willReturn(textMessage);
|
||||
given(textMessage.getText()).willReturn("Hello World!");
|
||||
|
||||
String result = JmsClient.create(connectionFactory).destination(queue)
|
||||
.receive(String.class).get();
|
||||
assertThat(result).isEqualTo("Hello World!");
|
||||
|
||||
verify(connection).start();
|
||||
verify(messageConsumer).close();
|
||||
verify(session).close();
|
||||
verify(connection).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveWithCustomTimeout() throws Exception {
|
||||
ConnectionFactory connectionFactory = mock();
|
||||
Connection connection = mock();
|
||||
Session session = mock();
|
||||
Queue queue = mock();
|
||||
MessageConsumer messageConsumer = mock();
|
||||
TextMessage textMessage = mock();
|
||||
|
||||
given(connectionFactory.createConnection()).willReturn(connection);
|
||||
given(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)).willReturn(session);
|
||||
given(session.createConsumer(queue, null)).willReturn(messageConsumer);
|
||||
given(messageConsumer.receive(10)).willReturn(textMessage);
|
||||
given(textMessage.getText()).willReturn("Hello World!");
|
||||
|
||||
String result = JmsClient.create(connectionFactory).destination(queue)
|
||||
.withReceiveTimeout(10).receive(String.class).get();
|
||||
assertThat(result).isEqualTo("Hello World!");
|
||||
|
||||
verify(connection).start();
|
||||
verify(messageConsumer).close();
|
||||
verify(session).close();
|
||||
verify(connection).close();
|
||||
}
|
||||
|
||||
|
||||
private Message<String> createTextMessage(String payload) {
|
||||
return MessageBuilder.withPayload(payload).setHeader("foo", "bar").build();
|
||||
}
|
||||
|
||||
private Message<String> createTextMessage() {
|
||||
return createTextMessage("Hello");
|
||||
}
|
||||
|
||||
private jakarta.jms.Message createJmsTextMessage(String payload) {
|
||||
StubTextMessage jmsMessage = new StubTextMessage(payload);
|
||||
jmsMessage.setStringProperty("foo", "bar");
|
||||
return jmsMessage;
|
||||
}
|
||||
|
||||
private jakarta.jms.Message createJmsTextMessage() {
|
||||
return createJmsTextMessage("Hello");
|
||||
}
|
||||
|
||||
private void assertTextMessage(MessageCreator messageCreator) {
|
||||
try {
|
||||
TextMessage jmsMessage = createTextMessage(messageCreator);
|
||||
assertThat(jmsMessage.getText()).as("Wrong body message").isEqualTo("Hello");
|
||||
assertThat(jmsMessage.getStringProperty("foo")).as("Invalid foo property").isEqualTo("bar");
|
||||
}
|
||||
catch (JMSException e) {
|
||||
throw new IllegalStateException("Wrong text message", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertTextMessage(Message<?> message) {
|
||||
assertThat(message).as("message should not be null").isNotNull();
|
||||
assertThat(message.getPayload()).as("Wrong payload").isEqualTo("Hello");
|
||||
assertThat(message.getHeaders().get("foo")).as("Invalid foo property").isEqualTo("bar");
|
||||
}
|
||||
|
||||
protected TextMessage createTextMessage(MessageCreator creator) throws JMSException {
|
||||
Session mock = mock();
|
||||
given(mock.createTextMessage(any())).willAnswer(
|
||||
(Answer<TextMessage>) invocation ->
|
||||
new StubTextMessage((String) invocation.getArguments()[0]));
|
||||
jakarta.jms.Message message = creator.createMessage(mock);
|
||||
verify(mock).createTextMessage(any());
|
||||
return (TextMessage) message;
|
||||
}
|
||||
|
||||
}
|
||||
+141
-26
@@ -64,6 +64,7 @@ import static org.mockito.Mockito.verify;
|
||||
* Tests for {@link JmsMessagingTemplate}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class JmsMessagingTemplateTests {
|
||||
@@ -110,15 +111,13 @@ class JmsMessagingTemplateTests {
|
||||
void customConverterAlwaysTakesPrecedence() {
|
||||
MessageConverter customMessageConverter = mock();
|
||||
JmsMessagingTemplate messagingTemplate = new JmsMessagingTemplate();
|
||||
messagingTemplate.setJmsMessageConverter(
|
||||
new MessagingMessageConverter(customMessageConverter));
|
||||
messagingTemplate.setJmsMessageConverter(new MessagingMessageConverter(customMessageConverter));
|
||||
messagingTemplate.setJmsTemplate(this.jmsTemplate);
|
||||
messagingTemplate.afterPropertiesSet();
|
||||
assertPayloadConverter(messagingTemplate, customMessageConverter);
|
||||
}
|
||||
|
||||
private void assertPayloadConverter(JmsMessagingTemplate messagingTemplate,
|
||||
MessageConverter messageConverter) {
|
||||
private void assertPayloadConverter(JmsMessagingTemplate messagingTemplate, MessageConverter messageConverter) {
|
||||
MessageConverter jmsMessageConverter = messagingTemplate.getJmsMessageConverter();
|
||||
assertThat(jmsMessageConverter).isNotNull();
|
||||
assertThat(jmsMessageConverter.getClass()).isEqualTo(MessagingMessageConverter.class);
|
||||
@@ -170,19 +169,21 @@ class JmsMessagingTemplateTests {
|
||||
void sendNoDefaultSet() {
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
this.messagingTemplate.send(message));
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.messagingTemplate.send(message));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendPropertyInjection() {
|
||||
JmsMessagingTemplate t = new JmsMessagingTemplate();
|
||||
t.setJmsTemplate(this.jmsTemplate);
|
||||
t.setDefaultDestinationName("myQueue");
|
||||
t.afterPropertiesSet();
|
||||
MessageConverter messageConverter = new SimpleMessageConverter();
|
||||
given(this.jmsTemplate.getMessageConverter()).willReturn(messageConverter);
|
||||
|
||||
this.messagingTemplate = new JmsMessagingTemplate();
|
||||
this.messagingTemplate.setJmsTemplate(this.jmsTemplate);
|
||||
this.messagingTemplate.setDefaultDestinationName("myQueue");
|
||||
this.messagingTemplate.afterPropertiesSet();
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
t.send(message);
|
||||
this.messagingTemplate.send(message);
|
||||
verify(this.jmsTemplate).send(eq("myQueue"), this.messageCreator.capture());
|
||||
assertTextMessage(this.messageCreator.getValue());
|
||||
}
|
||||
@@ -236,8 +237,7 @@ class JmsMessagingTemplateTests {
|
||||
void convertAndSendCustomJmsMessageConverter() {
|
||||
this.messagingTemplate.setJmsMessageConverter(new SimpleMessageConverter() {
|
||||
@Override
|
||||
public jakarta.jms.Message toMessage(Object object, Session session)
|
||||
throws org.springframework.jms.support.converter.MessageConversionException {
|
||||
public jakarta.jms.Message toMessage(Object object, Session session) {
|
||||
throw new org.springframework.jms.support.converter.MessageConversionException("Test exception");
|
||||
}
|
||||
});
|
||||
@@ -245,9 +245,9 @@ class JmsMessagingTemplateTests {
|
||||
this.messagingTemplate.convertAndSend("myQueue", "msg to convert");
|
||||
verify(this.jmsTemplate).send(eq("myQueue"), this.messageCreator.capture());
|
||||
|
||||
assertThatExceptionOfType(org.springframework.messaging.converter.MessageConversionException.class).isThrownBy(() ->
|
||||
this.messageCreator.getValue().createMessage(mock()))
|
||||
.withMessageContaining("Test exception");
|
||||
assertThatExceptionOfType(org.springframework.messaging.converter.MessageConversionException.class)
|
||||
.isThrownBy(() -> this.messageCreator.getValue().createMessage(mock()))
|
||||
.withMessageContaining("Test exception");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -317,8 +317,56 @@ class JmsMessagingTemplateTests {
|
||||
|
||||
@Test
|
||||
void receiveNoDefaultSet() {
|
||||
assertThatIllegalStateException().isThrownBy(
|
||||
this.messagingTemplate::receive);
|
||||
assertThatIllegalStateException().isThrownBy(this.messagingTemplate::receive);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelected() {
|
||||
Destination destination = new Destination() {};
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.receiveSelected(destination, "selector")).willReturn(jmsMessage);
|
||||
|
||||
Message<?> message = this.messagingTemplate.receiveSelected(destination, "selector");
|
||||
verify(this.jmsTemplate).receiveSelected(destination, "selector");
|
||||
assertTextMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedName() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
Message<?> message = this.messagingTemplate.receiveSelected("myQueue", "selector");
|
||||
verify(this.jmsTemplate).receiveSelected("myQueue", "selector");
|
||||
assertTextMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedDefaultDestination() {
|
||||
Destination destination = new Destination() {};
|
||||
this.messagingTemplate.setDefaultDestination(destination);
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.receiveSelected(destination, "selector")).willReturn(jmsMessage);
|
||||
|
||||
Message<?> message = this.messagingTemplate.receiveSelected("selector");
|
||||
verify(this.jmsTemplate).receiveSelected(destination, "selector");
|
||||
assertTextMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedDefaultDestinationName() {
|
||||
this.messagingTemplate.setDefaultDestinationName("myQueue");
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage();
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
Message<?> message = this.messagingTemplate.receiveSelected("selector");
|
||||
verify(this.jmsTemplate).receiveSelected("myQueue", "selector");
|
||||
assertTextMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedNoDefaultSet() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.messagingTemplate.receiveSelected("selector"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -393,6 +441,78 @@ class JmsMessagingTemplateTests {
|
||||
assertThat(this.messagingTemplate.receiveAndConvert("myQueue", String.class)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvert() {
|
||||
Destination destination = new Destination() {};
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload");
|
||||
given(this.jmsTemplate.receiveSelected(destination, "selector")).willReturn(jmsMessage);
|
||||
|
||||
String payload = this.messagingTemplate.receiveSelectedAndConvert(destination, "selector", String.class);
|
||||
assertThat(payload).isEqualTo("my Payload");
|
||||
verify(this.jmsTemplate).receiveSelected(destination, "selector");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertName() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload");
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
String payload = this.messagingTemplate.receiveSelectedAndConvert("myQueue", "selector", String.class);
|
||||
assertThat(payload).isEqualTo("my Payload");
|
||||
verify(this.jmsTemplate).receiveSelected("myQueue", "selector");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertDefaultDestination() {
|
||||
Destination destination = new Destination() {};
|
||||
this.messagingTemplate.setDefaultDestination(destination);
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload");
|
||||
given(this.jmsTemplate.receiveSelected(destination, "selector")).willReturn(jmsMessage);
|
||||
|
||||
String payload = this.messagingTemplate.receiveSelectedAndConvert("selector", String.class);
|
||||
assertThat(payload).isEqualTo("my Payload");
|
||||
verify(this.jmsTemplate).receiveSelected(destination, "selector");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertDefaultDestinationName() {
|
||||
this.messagingTemplate.setDefaultDestinationName("myQueue");
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("my Payload");
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
String payload = this.messagingTemplate.receiveSelectedAndConvert("selector", String.class);
|
||||
assertThat(payload).isEqualTo("my Payload");
|
||||
verify(this.jmsTemplate).receiveSelected("myQueue", "selector");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertWithConversion() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("123");
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
this.messagingTemplate.setMessageConverter(new GenericMessageConverter());
|
||||
|
||||
Integer payload = this.messagingTemplate.receiveSelectedAndConvert("myQueue", "selector", Integer.class);
|
||||
assertThat(payload).isEqualTo(Integer.valueOf(123));
|
||||
verify(this.jmsTemplate).receiveSelected("myQueue", "selector");
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertNoConverter() {
|
||||
jakarta.jms.Message jmsMessage = createJmsTextMessage("Hello");
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(jmsMessage);
|
||||
|
||||
assertThatExceptionOfType(org.springframework.messaging.converter.MessageConversionException.class).isThrownBy(() ->
|
||||
this.messagingTemplate.receiveSelectedAndConvert("myQueue", "selector", Writer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void receiveSelectedAndConvertNoInput() {
|
||||
given(this.jmsTemplate.receiveSelected("myQueue", "selector")).willReturn(null);
|
||||
|
||||
assertThat(this.messagingTemplate.receiveSelectedAndConvert("myQueue", "selector", String.class)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendAndReceive() {
|
||||
Destination destination = new Destination() {};
|
||||
@@ -444,9 +564,7 @@ class JmsMessagingTemplateTests {
|
||||
@Test
|
||||
void sendAndReceiveNoDefaultSet() {
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
this.messagingTemplate.sendAndReceive(message));
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.messagingTemplate.sendAndReceive(message));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -592,6 +710,7 @@ class JmsMessagingTemplateTests {
|
||||
this.messagingTemplate.sendAndReceive(destination, createTextMessage()));
|
||||
}
|
||||
|
||||
|
||||
private void invokeMessageCreator() {
|
||||
willAnswer(invocation -> {
|
||||
MessageCreator messageCreator = (MessageCreator) invocation.getArguments()[1];
|
||||
@@ -600,10 +719,8 @@ class JmsMessagingTemplateTests {
|
||||
}).given(this.jmsTemplate).send(eq("myQueue"), any());
|
||||
}
|
||||
|
||||
|
||||
private Message<String> createTextMessage(String payload) {
|
||||
return MessageBuilder
|
||||
.withPayload(payload).setHeader("foo", "bar").build();
|
||||
return MessageBuilder.withPayload(payload).setHeader("foo", "bar").build();
|
||||
}
|
||||
|
||||
private Message<String> createTextMessage() {
|
||||
@@ -620,7 +737,6 @@ class JmsMessagingTemplateTests {
|
||||
return createJmsTextMessage("Hello");
|
||||
}
|
||||
|
||||
|
||||
private void assertTextMessage(MessageCreator messageCreator) {
|
||||
try {
|
||||
TextMessage jmsMessage = createTextMessage(messageCreator);
|
||||
@@ -638,7 +754,6 @@ class JmsMessagingTemplateTests {
|
||||
assertThat(message.getHeaders().get("foo")).as("Invalid foo property").isEqualTo("bar");
|
||||
}
|
||||
|
||||
|
||||
protected TextMessage createTextMessage(MessageCreator creator) throws JMSException {
|
||||
Session mock = mock();
|
||||
given(mock.createTextMessage(any())).willAnswer(
|
||||
|
||||
@@ -103,14 +103,14 @@ class JmsTemplateTests {
|
||||
|
||||
private JmsTemplate createTemplate() {
|
||||
JmsTemplate template = new JmsTemplate();
|
||||
JndiDestinationResolver destMan = new JndiDestinationResolver();
|
||||
destMan.setJndiTemplate(new JndiTemplate() {
|
||||
JndiDestinationResolver resolver = new JndiDestinationResolver();
|
||||
resolver.setJndiTemplate(new JndiTemplate() {
|
||||
@Override
|
||||
protected Context createInitialContext() {
|
||||
return JmsTemplateTests.this.jndiContext;
|
||||
}
|
||||
});
|
||||
template.setDestinationResolver(destMan);
|
||||
template.setDestinationResolver(resolver);
|
||||
template.setSessionTransacted(useTransactedTemplate());
|
||||
return template;
|
||||
}
|
||||
|
||||
+18
-5
@@ -37,6 +37,7 @@ import org.springframework.util.Assert;
|
||||
* @author Mark Fisher
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Stephane Nicoll
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0
|
||||
* @param <D> the destination type
|
||||
*/
|
||||
@@ -112,12 +113,17 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
|
||||
|
||||
@Override
|
||||
public void convertAndSend(Object payload) throws MessagingException {
|
||||
convertAndSend(payload, null);
|
||||
convertAndSend(payload, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(D destination, Object payload) throws MessagingException {
|
||||
convertAndSend(destination, payload, (Map<String, Object>) null);
|
||||
convertAndSend(destination, payload, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(Object payload, Map<String, Object> headers) throws MessagingException {
|
||||
convertAndSend(payload, headers, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,7 +137,7 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
|
||||
public void convertAndSend(Object payload, @Nullable MessagePostProcessor postProcessor)
|
||||
throws MessagingException {
|
||||
|
||||
convertAndSend(getRequiredDefaultDestination(), payload, postProcessor);
|
||||
convertAndSend(payload, null, postProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -141,6 +147,13 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
|
||||
convertAndSend(destination, payload, null, postProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(Object payload, @Nullable Map<String, Object> headers,
|
||||
@Nullable MessagePostProcessor postProcessor) throws MessagingException {
|
||||
|
||||
convertAndSend(getRequiredDefaultDestination(), payload, null, postProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(D destination, Object payload, @Nullable Map<String, Object> headers,
|
||||
@Nullable MessagePostProcessor postProcessor) throws MessagingException {
|
||||
@@ -152,10 +165,10 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link MessageConverter}, wrap it as a message with the given
|
||||
* headers and apply the given post processor.
|
||||
* headers and apply the given post-processor.
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers the headers for the message to send
|
||||
* @param postProcessor the post processor to apply to the message
|
||||
* @param postProcessor the post-processor to apply to the message
|
||||
* @return the converted message
|
||||
*/
|
||||
protected Message<?> doConvert(Object payload, @Nullable Map<String, Object> headers,
|
||||
|
||||
+32
-15
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
|
||||
/**
|
||||
* An extension of {@link AbstractMessageReceivingTemplate} that adds support for
|
||||
@@ -29,6 +30,7 @@ import org.springframework.messaging.Message;
|
||||
* @author Mark Fisher
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Stephane Nicoll
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0
|
||||
* @param <D> the destination type
|
||||
*/
|
||||
@@ -36,57 +38,72 @@ public abstract class AbstractMessagingTemplate<D> extends AbstractMessageReceiv
|
||||
implements MessageRequestReplyOperations<D> {
|
||||
|
||||
@Override
|
||||
public @Nullable Message<?> sendAndReceive(Message<?> requestMessage) {
|
||||
public @Nullable Message<?> sendAndReceive(Message<?> requestMessage) throws MessagingException {
|
||||
return sendAndReceive(getRequiredDefaultDestination(), requestMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Message<?> sendAndReceive(D destination, Message<?> requestMessage) {
|
||||
public @Nullable Message<?> sendAndReceive(D destination, Message<?> requestMessage) throws MessagingException {
|
||||
return doSendAndReceive(destination, requestMessage);
|
||||
}
|
||||
|
||||
protected abstract @Nullable Message<?> doSendAndReceive(D destination, Message<?> requestMessage);
|
||||
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(Object request, Class<T> targetClass) {
|
||||
return convertSendAndReceive(getRequiredDefaultDestination(), request, targetClass);
|
||||
public <T> @Nullable T convertSendAndReceive(Object request, Class<T> targetClass) throws MessagingException {
|
||||
return convertSendAndReceive(request, null, targetClass, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(D destination, Object request, Class<T> targetClass) {
|
||||
return convertSendAndReceive(destination, request, null, targetClass);
|
||||
public <T> @Nullable T convertSendAndReceive(D destination, Object request, Class<T> targetClass) throws MessagingException {
|
||||
return convertSendAndReceive(destination, request, null, targetClass, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(Object request, @Nullable Map<String, Object> headers, Class<T> targetClass) throws MessagingException {
|
||||
return convertSendAndReceive(request, headers, targetClass, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(
|
||||
D destination, Object request, @Nullable Map<String, Object> headers, Class<T> targetClass) {
|
||||
D destination, Object request, @Nullable Map<String, Object> headers, Class<T> targetClass)
|
||||
throws MessagingException {
|
||||
|
||||
return convertSendAndReceive(destination, request, headers, targetClass, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(
|
||||
Object request, Class<T> targetClass, @Nullable MessagePostProcessor postProcessor) {
|
||||
Object request, Class<T> targetClass, @Nullable MessagePostProcessor postProcessor)
|
||||
throws MessagingException {
|
||||
|
||||
return convertSendAndReceive(getRequiredDefaultDestination(), request, targetClass, postProcessor);
|
||||
return convertSendAndReceive(request, null, targetClass, postProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(D destination, Object request, Class<T> targetClass,
|
||||
@Nullable MessagePostProcessor postProcessor) {
|
||||
@Nullable MessagePostProcessor postProcessor) throws MessagingException {
|
||||
|
||||
return convertSendAndReceive(destination, request, null, targetClass, postProcessor);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(Object request, @Nullable Map<String, Object> headers,
|
||||
Class<T> targetClass, @Nullable MessagePostProcessor postProcessor) throws MessagingException {
|
||||
|
||||
return convertSendAndReceive(getRequiredDefaultDestination(), request, headers, targetClass, postProcessor);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> @Nullable T convertSendAndReceive(D destination, Object request, @Nullable Map<String, Object> headers,
|
||||
Class<T> targetClass, @Nullable MessagePostProcessor postProcessor) {
|
||||
Class<T> targetClass, @Nullable MessagePostProcessor postProcessor) throws MessagingException {
|
||||
|
||||
Message<?> requestMessage = doConvert(request, headers, postProcessor);
|
||||
Message<?> replyMessage = sendAndReceive(destination, requestMessage);
|
||||
Message<?> replyMessage = doSendAndReceive(destination, requestMessage);
|
||||
return (replyMessage != null ? (T) getMessageConverter().fromMessage(replyMessage, targetClass) : null);
|
||||
}
|
||||
|
||||
|
||||
protected abstract @Nullable Message<?> doSendAndReceive(D destination, Message<?> requestMessage);
|
||||
|
||||
}
|
||||
|
||||
+36
-3
@@ -28,6 +28,7 @@ import org.springframework.messaging.MessagingException;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0
|
||||
* @param <D> the type of destination
|
||||
* @see GenericMessagingTemplate
|
||||
@@ -76,6 +77,21 @@ public interface MessageRequestReplyOperations<D> {
|
||||
*/
|
||||
<T> @Nullable T convertSendAndReceive(D destination, Object request, Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter}, send
|
||||
* it as a {@link Message} with the given headers, to the specified destination,
|
||||
* receive the reply and convert its body of the specified target class.
|
||||
* @param request payload for the request message to send
|
||||
* @param headers the headers for the request message to send
|
||||
* @param targetClass the target type to convert the payload of the reply to
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
* @since 7.0
|
||||
*/
|
||||
<T> @Nullable T convertSendAndReceive(Object request, @Nullable Map<String, Object> headers, Class<T> targetClass)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter}, send
|
||||
@@ -95,7 +111,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* apply the given post processor and send the resulting {@link Message} to a
|
||||
* apply the given post-processor and send the resulting {@link Message} to a
|
||||
* default destination, receive the reply and convert its body of the given
|
||||
* target class.
|
||||
* @param request payload for the request message to send
|
||||
@@ -111,7 +127,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* apply the given post processor and send the resulting {@link Message} to the
|
||||
* apply the given post-processor and send the resulting {@link Message} to the
|
||||
* given destination, receive the reply and convert its body of the given
|
||||
* target class.
|
||||
* @param destination the target destination
|
||||
@@ -127,7 +143,24 @@ public interface MessageRequestReplyOperations<D> {
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message with the given headers, apply the given post processor
|
||||
* wrap it as a message with the given headers, apply the given post-processor
|
||||
* and send the resulting {@link Message} to the specified destination, receive
|
||||
* the reply and convert its body of the given target class.
|
||||
* @param request payload for the request message to send
|
||||
* @param targetClass the target type to convert the payload of the reply to
|
||||
* @param requestPostProcessor post process to apply to the request message
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
* @since 7.0
|
||||
*/
|
||||
<T> @Nullable T convertSendAndReceive(
|
||||
Object request, @Nullable Map<String, Object> headers, Class<T> targetClass,
|
||||
@Nullable MessagePostProcessor requestPostProcessor) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given request Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message with the given headers, apply the given post-processor
|
||||
* and send the resulting {@link Message} to the specified destination, receive
|
||||
* the reply and convert its body of the given target class.
|
||||
* @param destination the target destination
|
||||
|
||||
+31
-7
@@ -28,6 +28,7 @@ import org.springframework.messaging.MessagingException;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0
|
||||
* @param <D> the destination type
|
||||
*/
|
||||
@@ -63,6 +64,16 @@ public interface MessageSendingOperations<D> {
|
||||
*/
|
||||
void convertAndSend(D destination, Object payload) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message and send it to a default destination.
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers the headers for the message to send
|
||||
* @since 7.0
|
||||
*/
|
||||
void convertAndSend(Object payload, Map<String, Object> headers) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
@@ -77,33 +88,46 @@ public interface MessageSendingOperations<D> {
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message, apply the given post processor, and send
|
||||
* wrap it as a message, apply the given post-processor, and send
|
||||
* the resulting message to a default destination.
|
||||
* @param payload the Object to use as payload
|
||||
* @param postProcessor the post processor to apply to the message
|
||||
* @param postProcessor the post-processor to apply to the message
|
||||
*/
|
||||
void convertAndSend(Object payload, @Nullable MessagePostProcessor postProcessor) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message, apply the given post processor, and send
|
||||
* wrap it as a message, apply the given post-processor, and send
|
||||
* the resulting message to the given destination.
|
||||
* @param destination the target destination
|
||||
* @param payload the Object to use as payload
|
||||
* @param postProcessor the post processor to apply to the message
|
||||
* @param postProcessor the post-processor to apply to the message
|
||||
*/
|
||||
void convertAndSend(D destination, Object payload, MessagePostProcessor postProcessor) throws MessagingException;
|
||||
void convertAndSend(D destination, Object payload, @Nullable MessagePostProcessor postProcessor) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message with the given headers, apply the given post processor,
|
||||
* wrap it as a message with the given headers, apply the given post-processor,
|
||||
* and send the resulting message to the given destination.
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers the headers for the message to send
|
||||
* @param postProcessor the post-processor to apply to the message
|
||||
* @since 7.0
|
||||
*/
|
||||
void convertAndSend(Object payload, @Nullable Map<String, Object> headers,
|
||||
@Nullable MessagePostProcessor postProcessor) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message with the given headers, apply the given post-processor,
|
||||
* and send the resulting message to the given destination.
|
||||
* @param destination the target destination
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers the headers for the message to send
|
||||
* @param postProcessor the post processor to apply to the message
|
||||
* @param postProcessor the post-processor to apply to the message
|
||||
*/
|
||||
void convertAndSend(D destination, Object payload, @Nullable Map<String, Object> headers,
|
||||
@Nullable MessagePostProcessor postProcessor) throws MessagingException;
|
||||
|
||||
Reference in New Issue
Block a user