提交 0f0c93a5 编写于 作者: J Juergen Hoeller

Removed JMS 1.0.2 support

上级 36942f60
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
......@@ -18,6 +18,10 @@ package org.springframework.jms.config;
import javax.jms.Session;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
......@@ -26,9 +30,6 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Abstract parser for JMS listener container elements, providing support for
......@@ -156,10 +157,7 @@ abstract class AbstractListenerContainerParser implements BeanDefinitionParser {
}
}
// Remain JMS 1.0.2 compatible for the adapter if the container class indicates this.
boolean jms102 = indicatesJms102(containerDef);
listenerDef.setBeanClassName(
"org.springframework.jms.listener.adapter.MessageListenerAdapter" + (jms102 ? "102" : ""));
listenerDef.setBeanClassName("org.springframework.jms.listener.adapter.MessageListenerAdapter");
containerDef.getPropertyValues().add("messageListener", listenerDef);
......@@ -180,10 +178,6 @@ abstract class AbstractListenerContainerParser implements BeanDefinitionParser {
return false;
}
protected boolean indicatesJms102(BeanDefinition containerDef) {
return false;
}
protected void parseListenerConfiguration(Element ele, ParserContext parserContext, BeanDefinition configDef) {
String destination = ele.getAttribute(DESTINATION_ATTRIBUTE);
if (!StringUtils.hasText(destination)) {
......
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
......@@ -62,21 +62,15 @@ class JmsListenerContainerParser extends AbstractListenerContainerParser {
if (!"".equals(containerClass)) {
containerDef.setBeanClassName(containerClass);
}
else if ("".equals(containerType) || "default".equals(containerType)) {
else if ("".equals(containerType) || containerType.startsWith("default")) {
containerDef.setBeanClassName("org.springframework.jms.listener.DefaultMessageListenerContainer");
}
else if ("default102".equals(containerType)) {
containerDef.setBeanClassName("org.springframework.jms.listener.DefaultMessageListenerContainer102");
}
else if ("simple".equals(containerType)) {
else if (containerType.startsWith("simple")) {
containerDef.setBeanClassName("org.springframework.jms.listener.SimpleMessageListenerContainer");
}
else if ("simple102".equals(containerType)) {
containerDef.setBeanClassName("org.springframework.jms.listener.SimpleMessageListenerContainer102");
}
else {
parserContext.getReaderContext().error(
"Invalid 'container-type' attribute: only \"default(102)\" and \"simple(102)\" supported.", containerEle);
"Invalid 'container-type' attribute: only \"default\" and \"simple\" supported.", containerEle);
}
String connectionFactoryBeanName = "connectionFactory";
......@@ -178,9 +172,4 @@ class JmsListenerContainerParser extends AbstractListenerContainerParser {
return indicatesPubSubConfig(containerDef);
}
@Override
protected boolean indicatesJms102(BeanDefinition containerDef) {
return containerDef.getBeanClassName().endsWith("102");
}
}
/*
* Copyright 2002-2012 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
*
* http://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.connection;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
/**
* A subclass of {@link JmsTransactionManager} for the JMS 1.0.2 specification,
* not relying on JMS 1.1 methods like JmsTransactionManager itself.
* This class can be used for JMS 1.0.2 providers, offering the same API as
* JmsTransactionManager does for JMS 1.1 providers.
*
* <p>You need to set the {@link #setPubSubDomain "pubSubDomain" property},
* since this class will always explicitly differentiate between a
* {@link javax.jms.QueueConnection} and a {@link javax.jms.TopicConnection}.
*
* @author Juergen Hoeller
* @since 1.1
* @see #setConnectionFactory
* @see #setPubSubDomain
* @deprecated as of Spring 3.0, in favor of the JMS 1.1 based {@link JmsTransactionManager}
*/
@Deprecated
@SuppressWarnings("serial")
public class JmsTransactionManager102 extends JmsTransactionManager {
private boolean pubSubDomain = false;
/**
* Create a new JmsTransactionManager102 for bean-style usage.
* <p>Note: The ConnectionFactory has to be set before using the instance.
* This constructor can be used to prepare a JmsTemplate via a BeanFactory,
* typically setting the ConnectionFactory via setConnectionFactory.
* @see #setConnectionFactory
*/
public JmsTransactionManager102() {
super();
}
/**
* Create a new JmsTransactionManager102, given a ConnectionFactory.
* @param connectionFactory the ConnectionFactory to manage transactions for
* @param pubSubDomain whether the Publish/Subscribe domain (Topics) or
* Point-to-Point domain (Queues) should be used
* @see #setPubSubDomain
*/
public JmsTransactionManager102(ConnectionFactory connectionFactory, boolean pubSubDomain) {
setConnectionFactory(connectionFactory);
this.pubSubDomain = pubSubDomain;
afterPropertiesSet();
}
/**
* Configure the transaction manager with knowledge of the JMS domain used.
* This tells the JMS 1.0.2 provider which class hierarchy to use for creating
* Connections and Sessions.
* <p>Default is Point-to-Point (Queues).
* @param pubSubDomain {@code true} for Publish/Subscribe domain (Topics),
* {@code false} for Point-to-Point domain (Queues)
*/
public void setPubSubDomain(boolean pubSubDomain) {
this.pubSubDomain = pubSubDomain;
}
/**
* Return whether the Publish/Subscribe domain (Topics) is used.
* Otherwise, the Point-to-Point domain (Queues) is used.
*/
public boolean isPubSubDomain() {
return this.pubSubDomain;
}
/**
* In addition to checking if the connection factory is set, make sure
* that the supplied connection factory is of the appropriate type for
* the specified destination type: QueueConnectionFactory for queues,
* and TopicConnectionFactory for topics.
*/
public void afterPropertiesSet() {
super.afterPropertiesSet();
// Make sure that the ConnectionFactory passed is consistent.
// Some provider implementations of the ConnectionFactory interface
// implement both domain interfaces under the cover, so just check if
// the selected domain is consistent with the type of connection factory.
if (isPubSubDomain()) {
if (!(getConnectionFactory() instanceof TopicConnectionFactory)) {
throw new IllegalArgumentException(
"Specified a Spring JMS 1.0.2 transaction manager for topics " +
"but did not supply an instance of TopicConnectionFactory");
}
}
else {
if (!(getConnectionFactory() instanceof QueueConnectionFactory)) {
throw new IllegalArgumentException(
"Specified a Spring JMS 1.0.2 transaction manager for queues " +
"but did not supply an instance of QueueConnectionFactory");
}
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected Connection createConnection() throws JMSException {
if (isPubSubDomain()) {
return ((TopicConnectionFactory) getConnectionFactory()).createTopicConnection();
}
else {
return ((QueueConnectionFactory) getConnectionFactory()).createQueueConnection();
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected Session createSession(Connection con) throws JMSException {
if (isPubSubDomain()) {
return ((TopicConnection) con).createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
}
else {
return ((QueueConnection) con).createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
}
}
}
/*
* Copyright 2002-2012 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
*
* http://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.connection;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.QueueConnectionFactory;
import javax.jms.TopicConnectionFactory;
/**
* A subclass of {@link SingleConnectionFactory} for the JMS 1.0.2 specification,
* not relying on JMS 1.1 methods like SingleConnectionFactory itself.
* This class can be used for JMS 1.0.2 providers, offering the same API as
* SingleConnectionFactory does for JMS 1.1 providers.
*
* <p>You need to set the {@link #setPubSubDomain "pubSubDomain" property},
* since this class will always explicitly differentiate between a
* {@link javax.jms.QueueConnection} and a {@link javax.jms.TopicConnection}.
*
* @author Juergen Hoeller
* @since 1.1
* @see #setTargetConnectionFactory
* @see #setPubSubDomain
* @deprecated as of Spring 3.0, in favor of the JMS 1.1 based {@link SingleConnectionFactory}
*/
@Deprecated
public class SingleConnectionFactory102 extends SingleConnectionFactory {
private boolean pubSubDomain = false;
/**
* Create a new SingleConnectionFactory102 for bean-style usage.
*/
public SingleConnectionFactory102() {
super();
}
/**
* Create a new SingleConnectionFactory102 that always returns a single
* Connection that it will lazily create via the given target
* ConnectionFactory.
* @param connectionFactory the target ConnectionFactory
* @param pubSubDomain whether the Publish/Subscribe domain (Topics) or
* Point-to-Point domain (Queues) should be used
*/
public SingleConnectionFactory102(ConnectionFactory connectionFactory, boolean pubSubDomain) {
setTargetConnectionFactory(connectionFactory);
this.pubSubDomain = pubSubDomain;
afterPropertiesSet();
}
/**
* Configure the factory with knowledge of the JMS domain used.
* This tells the JMS 1.0.2 provider which class hierarchy to use for creating
* Connections and Sessions.
* <p>Default is Point-to-Point (Queues).
* @param pubSubDomain {@code true} for Publish/Subscribe domain (Topics),
* {@code false} for Point-to-Point domain (Queues)
*/
public void setPubSubDomain(boolean pubSubDomain) {
this.pubSubDomain = pubSubDomain;
}
/**
* Return whether the Publish/Subscribe domain (Topics) is used.
* Otherwise, the Point-to-Point domain (Queues) is used.
*/
public boolean isPubSubDomain() {
return this.pubSubDomain;
}
/**
* In addition to checking whether the target ConnectionFactory is set,
* make sure that the supplied factory is of the appropriate type for
* the specified destination type: QueueConnectionFactory for queues,
* TopicConnectionFactory for topics.
*/
public void afterPropertiesSet() {
super.afterPropertiesSet();
// Make sure that the ConnectionFactory passed is consistent.
// Some provider implementations of the ConnectionFactory interface
// implement both domain interfaces under the cover, so just check if
// the selected domain is consistent with the type of connection factory.
if (isPubSubDomain()) {
if (!(getTargetConnectionFactory() instanceof TopicConnectionFactory)) {
throw new IllegalArgumentException(
"Specified a Spring JMS 1.0.2 SingleConnectionFactory for topics " +
"but did not supply an instance of TopicConnectionFactory");
}
}
else {
if (!(getTargetConnectionFactory() instanceof QueueConnectionFactory)) {
throw new IllegalArgumentException(
"Specified a Spring JMS 1.0.2 SingleConnectionFactory for queues " +
"but did not supply an instance of QueueConnectionFactory");
}
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected Connection doCreateConnection() throws JMSException {
if (isPubSubDomain()) {
return ((TopicConnectionFactory) getTargetConnectionFactory()).createTopicConnection();
}
else {
return ((QueueConnectionFactory) getTargetConnectionFactory()).createQueueConnection();
}
}
}
/*
* Copyright 2002-2012 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
*
* http://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 javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import org.springframework.jms.connection.JmsResourceHolder;
import org.springframework.jms.support.converter.SimpleMessageConverter102;
/**
* A subclass of {@link JmsTemplate} for the JMS 1.0.2 specification, not relying
* on JMS 1.1 methods like JmsTemplate itself. This class can be used for JMS
* 1.0.2 providers, offering the same API as JmsTemplate does for JMS 1.1 providers.
*
* <p>You must specify the domain (or style) of messaging to be either
* Point-to-Point (Queues) or Publish/Subscribe (Topics), using the
* {@link #setPubSubDomain "pubSubDomain" property}.
* Point-to-Point (Queues) is the default domain.
*
* <p>The "pubSubDomain" property is an important setting due to the use of similar
* but separate class hierarchies in the JMS 1.0.2 API. JMS 1.1 provides a new
* domain-independent API that allows for easy mix-and-match use of Point-to-Point
* and Publish/Subscribe styles.
*
* <p>This template uses a
* {@link org.springframework.jms.support.destination.DynamicDestinationResolver}
* and a {@link org.springframework.jms.support.converter.SimpleMessageConverter102}
* as default strategies for resolving a destination name and converting a message,
* respectively.
*
* @author Mark Pollack
* @author Juergen Hoeller
* @since 1.1
* @see #setConnectionFactory
* @see #setPubSubDomain
* @see javax.jms.Queue
* @see javax.jms.Topic
* @see javax.jms.QueueSession
* @see javax.jms.TopicSession
* @see javax.jms.QueueSender
* @see javax.jms.TopicPublisher
* @see javax.jms.QueueReceiver
* @see javax.jms.TopicSubscriber
* @deprecated as of Spring 3.0, in favor of the JMS 1.1 based {@link JmsTemplate}
*/
@Deprecated
public class JmsTemplate102 extends JmsTemplate {
/**
* Create a new JmsTemplate102 for bean-style usage.
* <p>Note: The ConnectionFactory has to be set before using the instance.
* This constructor can be used to prepare a JmsTemplate via a BeanFactory,
* typically setting the ConnectionFactory via setConnectionFactory.
* @see #setConnectionFactory
*/
public JmsTemplate102() {
super();
}
/**
* Create a new JmsTemplate102, given a ConnectionFactory.
* @param connectionFactory the ConnectionFactory to obtain Connections from
* @param pubSubDomain whether the Publish/Subscribe domain (Topics) or
* Point-to-Point domain (Queues) should be used
* @see #setPubSubDomain
*/
public JmsTemplate102(ConnectionFactory connectionFactory, boolean pubSubDomain) {
this();
setConnectionFactory(connectionFactory);
setPubSubDomain(pubSubDomain);
afterPropertiesSet();
}
/**
* Initialize the default implementations for the template's strategies:
* DynamicDestinationResolver and SimpleMessageConverter102.
* @see #setDestinationResolver
* @see #setMessageConverter
* @see org.springframework.jms.support.destination.DynamicDestinationResolver
* @see org.springframework.jms.support.converter.SimpleMessageConverter102
*/
protected void initDefaultStrategies() {
setMessageConverter(new SimpleMessageConverter102());
}
/**
* In addition to checking if the connection factory is set, make sure
* that the supplied connection factory is of the appropriate type for
* the specified destination type: QueueConnectionFactory for queues,
* and TopicConnectionFactory for topics.
*/
public void afterPropertiesSet() {
super.afterPropertiesSet();
// Make sure that the ConnectionFactory passed is consistent.
// Some provider implementations of the ConnectionFactory interface
// implement both domain interfaces under the cover, so just check if
// the selected domain is consistent with the type of connection factory.
if (isPubSubDomain()) {
if (!(getConnectionFactory() instanceof TopicConnectionFactory)) {
throw new IllegalArgumentException(
"Specified a Spring JMS 1.0.2 template for topics " +
"but did not supply an instance of TopicConnectionFactory");
}
}
else {
if (!(getConnectionFactory() instanceof QueueConnectionFactory)) {
throw new IllegalArgumentException(
"Specified a Spring JMS 1.0.2 template for queues " +
"but did not supply an instance of QueueConnectionFactory");
}
}
}
/**
* This implementation overrides the superclass method to accept either
* a QueueConnection or a TopicConnection, depending on the domain.
*/
protected Connection getConnection(JmsResourceHolder holder) {
return holder.getConnection(isPubSubDomain() ? (Class) TopicConnection.class : QueueConnection.class);
}
/**
* This implementation overrides the superclass method to accept either
* a QueueSession or a TopicSession, depending on the domain.
*/
protected Session getSession(JmsResourceHolder holder) {
return holder.getSession(isPubSubDomain() ? (Class) TopicSession.class : QueueSession.class);
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected Connection createConnection() throws JMSException {
if (isPubSubDomain()) {
return ((TopicConnectionFactory) getConnectionFactory()).createTopicConnection();
}
else {
return ((QueueConnectionFactory) getConnectionFactory()).createQueueConnection();
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected Session createSession(Connection con) throws JMSException {
if (isPubSubDomain()) {
return ((TopicConnection) con).createTopicSession(isSessionTransacted(), getSessionAcknowledgeMode());
}
else {
return ((QueueConnection) con).createQueueSession(isSessionTransacted(), getSessionAcknowledgeMode());
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected MessageProducer doCreateProducer(Session session, Destination destination) throws JMSException {
if (isPubSubDomain()) {
return ((TopicSession) session).createPublisher((Topic) destination);
}
else {
return ((QueueSession) session).createSender((Queue) destination);
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected MessageConsumer createConsumer(Session session, Destination destination, String messageSelector)
throws JMSException {
if (isPubSubDomain()) {
return ((TopicSession) session).createSubscriber((Topic) destination, messageSelector, isPubSubNoLocal());
}
else {
return ((QueueSession) session).createReceiver((Queue) destination, messageSelector);
}
}
protected QueueBrowser createBrowser(Session session, Queue queue, String messageSelector)
throws JMSException {
if (isPubSubDomain()) {
throw new javax.jms.IllegalStateException("Cannot create QueueBrowser for a TopicSession");
}
else {
return ((QueueSession) session).createBrowser(queue, messageSelector);
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected void doSend(MessageProducer producer, Message message) throws JMSException {
if (isPubSubDomain()) {
if (isExplicitQosEnabled()) {
((TopicPublisher) producer).publish(message, getDeliveryMode(), getPriority(), getTimeToLive());
}
else {
((TopicPublisher) producer).publish(message);
}
}
else {
if (isExplicitQosEnabled()) {
((QueueSender) producer).send(message, getDeliveryMode(), getPriority(), getTimeToLive());
}
else {
((QueueSender) producer).send(message);
}
}
}
/**
* This implementation overrides the superclass method to avoid using
* JMS 1.1's Session {@code getAcknowledgeMode()} method.
* The best we can do here is to check the setting on the template.
* @see #getSessionAcknowledgeMode()
*/
protected boolean isClientAcknowledge(Session session) throws JMSException {
return (getSessionAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE);
}
}
/*
* Copyright 2002-2012 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
*
* http://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.listener;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import org.springframework.jms.connection.JmsResourceHolder;
/**
* A subclass of {@link DefaultMessageListenerContainer} for the JMS 1.0.2 specification,
* not relying on JMS 1.1 methods like SimpleMessageListenerContainer itself.
*
* <p>This class can be used for JMS 1.0.2 providers, offering the same facility as
* DefaultMessageListenerContainer does for JMS 1.1 providers.
*
* @author Juergen Hoeller
* @since 2.0
* @deprecated as of Spring 3.0, in favor of the JMS 1.1 based {@link DefaultMessageListenerContainer}
*/
@Deprecated
public class DefaultMessageListenerContainer102 extends DefaultMessageListenerContainer {
/**
* This implementation overrides the superclass method to accept either
* a QueueConnection or a TopicConnection, depending on the domain.
*/
protected Connection getConnection(JmsResourceHolder holder) {
return holder.getConnection(isPubSubDomain() ? TopicConnection.class : QueueConnection.class);
}
/**
* This implementation overrides the superclass method to accept either
* a QueueSession or a TopicSession, depending on the domain.
*/
protected Session getSession(JmsResourceHolder holder) {
return holder.getSession(isPubSubDomain() ? TopicSession.class : QueueSession.class);
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected Connection createConnection() throws JMSException {
if (isPubSubDomain()) {
return ((TopicConnectionFactory) getConnectionFactory()).createTopicConnection();
}
else {
return ((QueueConnectionFactory) getConnectionFactory()).createQueueConnection();
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected Session createSession(Connection con) throws JMSException {
if (isPubSubDomain()) {
return ((TopicConnection) con).createTopicSession(isSessionTransacted(), getSessionAcknowledgeMode());
}
else {
return ((QueueConnection) con).createQueueSession(isSessionTransacted(), getSessionAcknowledgeMode());
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected MessageConsumer createConsumer(Session session, Destination destination) throws JMSException {
if (isPubSubDomain()) {
if (isSubscriptionDurable()) {
return ((TopicSession) session).createDurableSubscriber(
(Topic) destination, getDurableSubscriptionName(), getMessageSelector(), isPubSubNoLocal());
}
else {
return ((TopicSession) session).createSubscriber(
(Topic) destination, getMessageSelector(), isPubSubNoLocal());
}
}
else {
return ((QueueSession) session).createReceiver((Queue) destination, getMessageSelector());
}
}
/**
* This implementation overrides the superclass method to avoid using
* JMS 1.1's Session {@code getAcknowledgeMode()} method.
* The best we can do here is to check the setting on the listener container.
*/
protected boolean isClientAcknowledge(Session session) throws JMSException {
return (getSessionAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE);
}
}
/*
* Copyright 2002-2012 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
*
* http://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.listener;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
/**
* A subclass of {@link SimpleMessageListenerContainer} for the JMS 1.0.2 specification,
* not relying on JMS 1.1 methods like SimpleMessageListenerContainer itself.
*
* <p>This class can be used for JMS 1.0.2 providers, offering the same facility as
* SimpleMessageListenerContainer does for JMS 1.1 providers.
*
* @author Juergen Hoeller
* @since 2.0
* @deprecated as of Spring 3.0, in favor of the JMS 1.1 based {@link SimpleMessageListenerContainer}
*/
@Deprecated
public class SimpleMessageListenerContainer102 extends SimpleMessageListenerContainer {
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected Connection createConnection() throws JMSException {
if (isPubSubDomain()) {
return ((TopicConnectionFactory) getConnectionFactory()).createTopicConnection();
}
else {
return ((QueueConnectionFactory) getConnectionFactory()).createQueueConnection();
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected Session createSession(Connection con) throws JMSException {
if (isPubSubDomain()) {
return ((TopicConnection) con).createTopicSession(isSessionTransacted(), getSessionAcknowledgeMode());
}
else {
return ((QueueConnection) con).createQueueSession(isSessionTransacted(), getSessionAcknowledgeMode());
}
}
/**
* This implementation overrides the superclass method to use JMS 1.0.2 API.
*/
protected MessageConsumer createConsumer(Session session, Destination destination) throws JMSException {
if (isPubSubDomain()) {
if (isSubscriptionDurable()) {
return ((TopicSession) session).createDurableSubscriber(
(Topic) destination, getDurableSubscriptionName(), getMessageSelector(), isPubSubNoLocal());
}
else {
return ((TopicSession) session).createSubscriber(
(Topic) destination, getMessageSelector(), isPubSubNoLocal());
}
}
else {
return ((QueueSession) session).createReceiver((Queue) destination, getMessageSelector());
}
}
/**
* This implementation overrides the superclass method to avoid using
* JMS 1.1's Session {@code getAcknowledgeMode()} method.
* The best we can do here is to check the setting on the listener container.
*/
protected boolean isClientAcknowledge(Session session) throws JMSException {
return (getSessionAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE);
}
}
/*
* Copyright 2002-2012 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
*
* http://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.listener.adapter;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import org.springframework.jms.support.JmsUtils;
import org.springframework.jms.support.converter.SimpleMessageConverter102;
/**
* A {@link MessageListenerAdapter} subclass for the JMS 1.0.2 specification,
* not relying on JMS 1.1 methods like MessageListenerAdapter itself.
*
* <p>This class can be used for JMS 1.0.2 providers, offering the same facility
* as MessageListenerAdapter does for JMS 1.1 providers.
*
* @author Juergen Hoeller
* @author Rick Evans
* @since 2.0
* @deprecated as of Spring 3.0, in favor of the JMS 1.1 based {@link MessageListenerAdapter}
*/
@Deprecated
public class MessageListenerAdapter102 extends MessageListenerAdapter {
/**
* Create a new instance of the MessageListenerAdapter102 class
* with the default settings.
*/
public MessageListenerAdapter102() {
}
/**
* Create a new instance of the MessageListenerAdapter102 class
* for the given delegate.
* @param delegate the target object to delegate message listening to
*/
public MessageListenerAdapter102(Object delegate) {
super(delegate);
}
/**
* Initialize the default implementations for the adapter's strategies:
* SimpleMessageConverter102.
* @see #setMessageConverter
* @see org.springframework.jms.support.converter.SimpleMessageConverter102
*/
protected void initDefaultStrategies() {
setMessageConverter(new SimpleMessageConverter102());
}
/**
* Overrides the superclass method to use the JMS 1.0.2 API to send a response.
* <p>Uses the JMS pub-sub API if the given destination is a topic,
* else uses the JMS queue API.
*/
protected void sendResponse(Session session, Destination destination, Message response) throws JMSException {
MessageProducer producer = null;
try {
if (destination instanceof Topic) {
producer = ((TopicSession) session).createPublisher((Topic) destination);
postProcessProducer(producer, response);
((TopicPublisher) producer).publish(response);
}
else {
producer = ((QueueSession) session).createSender((Queue) destination);
postProcessProducer(producer, response);
((QueueSender) producer).send(response);
}
}
finally {
JmsUtils.closeMessageProducer(producer);
}
}
}
/*
* Copyright 2002-2012 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
*
* http://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.support.converter;
import java.io.ByteArrayOutputStream;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
/**
* A subclass of {@link SimpleMessageConverter} for the JMS 1.0.2 specification,
* not relying on JMS 1.1 methods like SimpleMessageConverter itself.
* This class can be used for JMS 1.0.2 providers, offering the same functionality
* as SimpleMessageConverter does for JMS 1.1 providers.
*
* <p>The only difference to the default SimpleMessageConverter is that BytesMessage
* is handled differently: namely, without using the {@code getBodyLength()}
* method which has been introduced in JMS 1.1 and is therefore not available on a
* JMS 1.0.2 provider.
*
* @author Juergen Hoeller
* @since 1.1.1
* @see javax.jms.BytesMessage#getBodyLength()
* @deprecated as of Spring 3.0, in favor of the JMS 1.1 based {@link SimpleMessageConverter}
*/
@Deprecated
public class SimpleMessageConverter102 extends SimpleMessageConverter {
public static final int BUFFER_SIZE = 4096;
/**
* Overrides superclass method to copy bytes from the message into a
* ByteArrayOutputStream, using a buffer, to avoid using the
* {@code getBodyLength()} method which has been introduced in
* JMS 1.1 and is therefore not available on a JMS 1.0.2 provider.
* @see javax.jms.BytesMessage#getBodyLength()
*/
protected byte[] extractByteArrayFromMessage(BytesMessage message) throws JMSException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFFER_SIZE);
byte[] buffer = new byte[BUFFER_SIZE];
int bufferCount = -1;
while ((bufferCount = message.readBytes(buffer)) >= 0) {
baos.write(buffer, 0, bufferCount);
if (bufferCount < BUFFER_SIZE) {
break;
}
}
return baos.toByteArray();
}
}
......@@ -52,7 +52,7 @@
<bean id="testDestinationResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver"/>
<bean id="testMessageConverter" class="org.springframework.jms.support.converter.SimpleMessageConverter102"/>
<bean id="testMessageConverter" class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
<bean id="testTransactionManager" class="org.springframework.tests.transaction.CallCountingTransactionManager"/>
......
......@@ -22,19 +22,13 @@ import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import org.junit.After;
import org.junit.Test;
import org.springframework.jms.StubQueue;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.JmsTemplate102;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.SessionCallback;
import org.springframework.transaction.TransactionDefinition;
......@@ -331,57 +325,4 @@ public class JmsTransactionManagerTests {
verify(con).close();
}
@Test
@Deprecated
public void testTransactionCommit102WithQueue() throws JMSException {
QueueConnectionFactory cf = mock(QueueConnectionFactory.class);
QueueConnection con = mock(QueueConnection.class);
final QueueSession session = mock(QueueSession.class);
given(cf.createQueueConnection()).willReturn(con);
given(con.createQueueSession(true, Session.AUTO_ACKNOWLEDGE)).willReturn(session);
JmsTransactionManager tm = new JmsTransactionManager102(cf, false);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
JmsTemplate jt = new JmsTemplate102(cf, false);
jt.execute(new SessionCallback() {
@Override
public Object doInJms(Session sess) {
assertTrue(sess == session);
return null;
}
});
tm.commit(ts);
verify(session).commit();
verify(session).close();
verify(con).close();
}
@Test
@Deprecated
public void testTransactionCommit102WithTopic() throws JMSException {
TopicConnectionFactory cf = mock(TopicConnectionFactory.class);
TopicConnection con = mock(TopicConnection.class);
final TopicSession session = mock(TopicSession.class);
given(cf.createTopicConnection()).willReturn(con);
given(con.createTopicSession(true, Session.AUTO_ACKNOWLEDGE)).willReturn(session);
JmsTransactionManager tm = new JmsTransactionManager102(cf, true);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
JmsTemplate jt = new JmsTemplate102(cf, true);
jt.execute(new SessionCallback() {
@Override
public Object doInJms(Session sess) {
assertTrue(sess == session);
return null;
}
});
tm.commit(ts);
verify(session).commit();
verify(session).close();
verify(con).close();
}
}
......@@ -309,50 +309,6 @@ public class SingleConnectionFactoryTests {
assertEquals(1, listener.getCount());
}
@Test
public void testConnectionFactory102WithQueue() throws JMSException {
QueueConnectionFactory cf = mock(QueueConnectionFactory.class);
QueueConnection con = mock(QueueConnection.class);
given(cf.createQueueConnection()).willReturn(con);
SingleConnectionFactory scf = new SingleConnectionFactory102(cf, false);
QueueConnection con1 = scf.createQueueConnection();
con1.start();
con1.close(); // should be ignored
QueueConnection con2 = scf.createQueueConnection();
con2.start();
con2.close(); // should be ignored
scf.destroy(); // should trigger actual close
verify(con).start();
verify(con).stop();
verify(con).close();
verifyNoMoreInteractions(con);
}
@Test
public void testConnectionFactory102WithTopic() throws JMSException {
TopicConnectionFactory cf = mock(TopicConnectionFactory.class);
TopicConnection con = mock(TopicConnection.class);
given(cf.createTopicConnection()).willReturn(con);
SingleConnectionFactory scf = new SingleConnectionFactory102(cf, true);
TopicConnection con1 = scf.createTopicConnection();
con1.start();
con1.close(); // should be ignored
TopicConnection con2 = scf.createTopicConnection();
con2.start();
con2.close(); // should be ignored
scf.destroy(); // should trigger actual close
verify(con).start();
verify(con).stop();
verify(con).close();
verifyNoMoreInteractions(con);
}
@Test
public void testCachingConnectionFactory() throws JMSException {
ConnectionFactory cf = mock(ConnectionFactory.class);
......
/*
* Copyright 2002-2012 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
*
* http://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;
/**
* @author Juergen Hoeller
* @since 06.01.2005
*/
public class JmsTemplate102JtaTests extends JmsTemplate102Tests {
@Override
protected boolean useTransactedSession() {
return true;
}
@Override
protected boolean useTransactedTemplate() {
return false;
}
}
/*
* Copyright 2002-2012 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
*
* http://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;
/**
* @author Juergen Hoeller
* @since 06.01.2005
*/
public class JmsTemplate102TransactedTests extends JmsTemplate102Tests {
@Override
protected boolean useTransactedSession() {
return true;
}
@Override
protected boolean useTransactedTemplate() {
return true;
}
}
/*
* Copyright 2002-2013 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
*
* http://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.listener.adapter;
import java.io.ByteArrayInputStream;
import javax.jms.BytesMessage;
import javax.jms.InvalidDestinationException;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.jms.support.converter.SimpleMessageConverter102;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
/**
* Unit tests for the {@link MessageListenerAdapter102} class.
*
* @author Rick Evans
* @author Chris Beams
*/
@Deprecated
public final class MessageListenerAdapter102Tests {
private static final String TEXT = "The Runaways";
private static final String CORRELATION_ID = "100";
private static final String RESPONSE_TEXT = "Old Lace";
@Test
public void testWithMessageContentsDelegateForBytesMessage() throws Exception {
BytesMessage bytesMessage = mock(BytesMessage.class);
// BytesMessage contents must be unwrapped...
given(bytesMessage.readBytes(any(byte[].class))).willAnswer(new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocation) throws Throwable {
byte[] bytes = (byte[]) invocation.getArguments()[0];
ByteArrayInputStream inputStream = new ByteArrayInputStream(TEXT.getBytes());
return inputStream.read(bytes);
}
});
MessageContentsDelegate delegate = mock(MessageContentsDelegate.class);
MessageListenerAdapter102 adapter = new MessageListenerAdapter102(delegate);
adapter.onMessage(bytesMessage);
verify(delegate).handleMessage(TEXT.getBytes());
}
@Test
public void testWithMessageDelegate() throws Exception {
TextMessage textMessage = mock(TextMessage.class);
MessageDelegate delegate = mock(MessageDelegate.class);
MessageListenerAdapter102 adapter = new MessageListenerAdapter102(delegate);
// we DON'T want the default SimpleMessageConversion happening...
adapter.setMessageConverter(null);
adapter.onMessage(textMessage);
verify(delegate).handleMessage(textMessage);
}
@Test
public void testThatTheDefaultMessageConverterisIndeedTheSimpleMessageConverter102() throws Exception {
MessageListenerAdapter102 adapter = new MessageListenerAdapter102();
assertNotNull("The default [MessageConverter] must never be null.", adapter.getMessageConverter());
assertTrue("The default [MessageConverter] must be of the type [SimpleMessageConverter102]; if you've just changed it, then change this test to reflect your change.", adapter.getMessageConverter() instanceof SimpleMessageConverter102);
}
@Test
public void testWithResponsiveMessageDelegate_DoesNotSendReturnTextMessageIfNoSessionSupplied() throws Exception {
TextMessage textMessage = mock(TextMessage.class);
ResponsiveMessageDelegate delegate = mock(ResponsiveMessageDelegate.class);
given(delegate.handleMessage(textMessage)).willReturn(TEXT);
MessageListenerAdapter102 adapter = new MessageListenerAdapter102(delegate);
// we DON'T want the default SimpleMessageConversion happening...
adapter.setMessageConverter(null);
adapter.onMessage(textMessage);
verify(delegate).handleMessage(textMessage);
}
@Test
public void testWithResponsiveMessageDelegateWithDefaultDestination_SendsReturnTextMessageWhenSessionSuppliedForQueue() throws Exception {
Queue destination = mock(Queue.class);
TextMessage sentTextMessage = mock(TextMessage.class);
// correlation ID is queried when response is being created...
given(sentTextMessage.getJMSCorrelationID()).willReturn(CORRELATION_ID);
// Reply-To is queried when response is being created...
given(sentTextMessage.getJMSReplyTo()).willReturn(null);
TextMessage responseTextMessage = mock(TextMessage.class);
QueueSender queueSender = mock(QueueSender.class);
QueueSession session = mock(QueueSession.class);
given(session.createTextMessage(RESPONSE_TEXT)).willReturn(responseTextMessage);
given(session.createSender(destination)).willReturn(queueSender);
ResponsiveMessageDelegate delegate = mock(ResponsiveMessageDelegate.class);
given(delegate.handleMessage(sentTextMessage)).willReturn(RESPONSE_TEXT);
MessageListenerAdapter102 adapter = new MessageListenerAdapter102(delegate) {
@Override
protected Object extractMessage(Message message) {
return message;
}
};
adapter.setDefaultResponseDestination(destination);
adapter.onMessage(sentTextMessage, session);
verify(responseTextMessage).setJMSCorrelationID(CORRELATION_ID);
verify(queueSender).send(responseTextMessage);
verify(queueSender).close();
verify(delegate).handleMessage(sentTextMessage);
}
@Test
public void testWithResponsiveMessageDelegateWithDefaultDestination_SendsReturnTextMessageWhenSessionSuppliedForTopic() throws Exception {
Topic destination = mock(Topic.class);
TextMessage sentTextMessage = mock(TextMessage.class);
// correlation ID is queried when response is being created...
given(sentTextMessage.getJMSCorrelationID()).willReturn(CORRELATION_ID);
// Reply-To is queried when response is being created...
given(sentTextMessage.getJMSReplyTo()).willReturn(null); // we want to fall back to the default...
TextMessage responseTextMessage = mock(TextMessage.class);
TopicPublisher topicPublisher = mock(TopicPublisher.class);
TopicSession session = mock(TopicSession.class);
given(session.createTextMessage(RESPONSE_TEXT)).willReturn(responseTextMessage);
given(session.createPublisher(destination)).willReturn(topicPublisher);
ResponsiveMessageDelegate delegate = mock(ResponsiveMessageDelegate.class);
given(delegate.handleMessage(sentTextMessage)).willReturn(RESPONSE_TEXT);
MessageListenerAdapter102 adapter = new MessageListenerAdapter102(delegate) {
@Override
protected Object extractMessage(Message message) {
return message;
}
};
adapter.setDefaultResponseDestination(destination);
adapter.onMessage(sentTextMessage, session);
verify(responseTextMessage).setJMSCorrelationID(CORRELATION_ID);
verify(topicPublisher).publish(responseTextMessage);
verify(topicPublisher).close();
verify(delegate).handleMessage(sentTextMessage);
}
@Test
public void testWithResponsiveMessageDelegateNoDefaultDestination_SendsReturnTextMessageWhenSessionSupplied() throws Exception {
Queue destination = mock(Queue.class);
TextMessage sentTextMessage = mock(TextMessage.class);
// correlation ID is queried when response is being created...
given(sentTextMessage.getJMSCorrelationID()).willReturn(CORRELATION_ID);
// Reply-To is queried when response is being created...
given(sentTextMessage.getJMSReplyTo()).willReturn(destination);
TextMessage responseTextMessage = mock(TextMessage.class);
QueueSender queueSender = mock(QueueSender.class);
QueueSession session = mock(QueueSession.class);
given(session.createTextMessage(RESPONSE_TEXT)).willReturn(responseTextMessage);
given(session.createSender(destination)).willReturn(queueSender);
ResponsiveMessageDelegate delegate = mock(ResponsiveMessageDelegate.class);
given(delegate.handleMessage(sentTextMessage)).willReturn(RESPONSE_TEXT);
MessageListenerAdapter102 adapter = new MessageListenerAdapter102(delegate) {
@Override
protected Object extractMessage(Message message) {
return message;
}
};
adapter.onMessage(sentTextMessage, session);
verify(responseTextMessage).setJMSCorrelationID(CORRELATION_ID);
verify(queueSender).send(responseTextMessage);
verify(queueSender).close();
verify(delegate).handleMessage(sentTextMessage);
}
@Test
public void testWithResponsiveMessageDelegateNoDefaultDestinationAndNoReplyToDestination_SendsReturnTextMessageWhenSessionSupplied() throws Exception {
final TextMessage sentTextMessage = mock(TextMessage.class);
// correlation ID is queried when response is being created...
given(sentTextMessage.getJMSCorrelationID()).willReturn(CORRELATION_ID);
// Reply-To is queried when response is being created...
given(sentTextMessage.getJMSReplyTo()).willReturn(null);
TextMessage responseTextMessage = mock(TextMessage.class);
final QueueSession session = mock(QueueSession.class);
given(session.createTextMessage(RESPONSE_TEXT)).willReturn(responseTextMessage);
ResponsiveMessageDelegate delegate = mock(ResponsiveMessageDelegate.class);
given(delegate.handleMessage(sentTextMessage)).willReturn(RESPONSE_TEXT);
final MessageListenerAdapter102 adapter = new MessageListenerAdapter102(delegate) {
@Override
protected Object extractMessage(Message message) {
return message;
}
};
try {
adapter.onMessage(sentTextMessage, session);
fail("expected InvalidDestinationException");
} catch (InvalidDestinationException ex) { /* expected */ }
verify(responseTextMessage).setJMSCorrelationID(CORRELATION_ID);
verify(delegate).handleMessage(sentTextMessage);
}
@Test
public void testWithResponsiveMessageDelegateNoDefaultDestination_SendsReturnTextMessageWhenSessionSupplied_AndSendingThrowsJMSException() throws Exception {
Queue destination = mock(Queue.class);
final TextMessage sentTextMessage = mock(TextMessage.class);
// correlation ID is queried when response is being created...
given(sentTextMessage.getJMSCorrelationID()).willReturn(CORRELATION_ID);
// Reply-To is queried when response is being created...
given(sentTextMessage.getJMSReplyTo()).willReturn(destination);
TextMessage responseTextMessage = mock(TextMessage.class);
QueueSender queueSender = mock(QueueSender.class);
willThrow(new JMSException("Doe!")).given(queueSender).send(responseTextMessage);
// ensure that regardless of a JMSException the producer is closed...
final QueueSession session = mock(QueueSession.class);
given(session.createTextMessage(RESPONSE_TEXT)).willReturn(responseTextMessage);
given(session.createSender(destination)).willReturn(queueSender);
ResponsiveMessageDelegate delegate = mock(ResponsiveMessageDelegate.class);
given(delegate.handleMessage(sentTextMessage)).willReturn(RESPONSE_TEXT);
final MessageListenerAdapter102 adapter = new MessageListenerAdapter102(delegate) {
@Override
protected Object extractMessage(Message message) {
return message;
}
};
try {
adapter.onMessage(sentTextMessage, session);
fail("expected JMSException");
} catch (JMSException ex) { /* expected */ }
verify(responseTextMessage).setJMSCorrelationID(CORRELATION_ID);
verify(queueSender).close();
verify(delegate).handleMessage(sentTextMessage);
}
@Test
public void testWithResponsiveMessageDelegateDoesNotSendReturnTextMessageWhenSessionSupplied_AndListenerMethodThrowsException() throws Exception {
final TextMessage sentTextMessage = mock(TextMessage.class);
final QueueSession session = mock(QueueSession.class);
ResponsiveMessageDelegate delegate = mock(ResponsiveMessageDelegate.class);
willThrow(new IllegalArgumentException("Doe!")).given(delegate).handleMessage(sentTextMessage);
final MessageListenerAdapter102 adapter = new MessageListenerAdapter102(delegate) {
@Override
protected Object extractMessage(Message message) {
return message;
}
};
try {
adapter.onMessage(sentTextMessage, session);
fail("expected ListenerExecutionFailedException");
} catch (ListenerExecutionFailedException ex) { /* expected */ }
}
}
/*
* Copyright 2002-2012 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
*
* http://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.listener.adapter;
/**
* Stub extension of the {@link MessageListenerAdapter102} class for use in testing.
*
* @author Rick Evans
*/
public class StubMessageListenerAdapter102 extends MessageListenerAdapter102 {
private boolean wasCalled;
public boolean wasCalled() {
return this.wasCalled;
}
public void handleMessage(String message) {
this.wasCalled = true;
}
@Override
protected void handleListenerException(Throwable ex) {
System.out.println(ex);
}
}
/*
* Copyright 2002-2013 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
*
* http://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.support;
import java.io.ByteArrayInputStream;
import java.util.Random;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.jms.support.converter.SimpleMessageConverter102;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
/**
* Unit tests for the {@link SimpleMessageConverter102} class.
*
* @author Juergen Hoeller
* @author Rick Evans
*/
public final class SimpleMessageConverter102Tests {
@Test
public void testByteArrayConversion102() throws JMSException {
Session session = mock(Session.class);
BytesMessage message = mock(BytesMessage.class);
byte[] content = new byte[5000];
new Random().nextBytes(content);
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content);
given(session.createBytesMessage()).willReturn(message);
given(message.readBytes((byte[]) anyObject())).willAnswer(new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocation) throws Throwable {
return byteArrayInputStream.read((byte[])invocation.getArguments()[0]);
}
});
SimpleMessageConverter102 converter = new SimpleMessageConverter102();
Message msg = converter.toMessage(content, session);
assertThat((byte[])converter.fromMessage(msg), equalTo(content));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册