/*
* Copyright 2002-2016 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.remoting;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Enumeration;
import javax.jms.CompletionListener;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.SimpleMessageConverter;
import org.springframework.remoting.RemoteTimeoutException;
import org.springframework.tests.sample.beans.ITestBean;
import org.springframework.tests.sample.beans.TestBean;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
/**
* @author Juergen Hoeller
* @author Stephane Nicoll
*/
public class JmsInvokerTests {
@Rule
public final ExpectedException thrown = ExpectedException.none();
private QueueConnectionFactory mockConnectionFactory;
private QueueConnection mockConnection;
private QueueSession mockSession;
private Queue mockQueue;
@Before
public void setUpMocks() throws Exception {
mockConnectionFactory = mock(QueueConnectionFactory.class);
mockConnection = mock(QueueConnection.class);
mockSession = mock(QueueSession.class);
mockQueue = mock(Queue.class);
given(mockConnectionFactory.createConnection()).willReturn(mockConnection);
given(mockConnection.createSession(false, Session.AUTO_ACKNOWLEDGE)).willReturn(mockSession);
}
@Test
public void testJmsInvokerProxyFactoryBeanAndServiceExporter() throws Throwable {
doTestJmsInvokerProxyFactoryBeanAndServiceExporter(false);
}
@Test
public void testJmsInvokerProxyFactoryBeanAndServiceExporterWithDynamicQueue() throws Throwable {
given(mockSession.createQueue("myQueue")).willReturn(mockQueue);
doTestJmsInvokerProxyFactoryBeanAndServiceExporter(true);
}
@Test
public void receiveTimeoutExpired() {
JmsInvokerProxyFactoryBean pfb = new JmsInvokerProxyFactoryBean() {
@Override
protected Message doExecuteRequest(Session session, Queue queue, Message requestMessage) throws JMSException {
return null; // faking no message received
}
};
pfb.setServiceInterface(ITestBean.class);
pfb.setConnectionFactory(this.mockConnectionFactory);
pfb.setQueue(this.mockQueue);
pfb.setReceiveTimeout(1500);
pfb.afterPropertiesSet();
ITestBean proxy = (ITestBean) pfb.getObject();
thrown.expect(RemoteTimeoutException.class);
thrown.expectMessage("1500 ms");
thrown.expectMessage("getAge");
proxy.getAge();
}
private void doTestJmsInvokerProxyFactoryBeanAndServiceExporter(boolean dynamicQueue) throws Throwable {
TestBean target = new TestBean("myname", 99);
final JmsInvokerServiceExporter exporter = new JmsInvokerServiceExporter();
exporter.setServiceInterface(ITestBean.class);
exporter.setService(target);
exporter.setMessageConverter(new MockSimpleMessageConverter());
exporter.afterPropertiesSet();
JmsInvokerProxyFactoryBean pfb = new JmsInvokerProxyFactoryBean() {
@Override
protected Message doExecuteRequest(Session session, Queue queue, Message requestMessage) throws JMSException {
Session mockExporterSession = mock(Session.class);
ResponseStoringProducer mockProducer = new ResponseStoringProducer();
given(mockExporterSession.createProducer(requestMessage.getJMSReplyTo())).willReturn(mockProducer);
exporter.onMessage(requestMessage, mockExporterSession);
assertTrue(mockProducer.closed);
return mockProducer.response;
}
};
pfb.setServiceInterface(ITestBean.class);
pfb.setConnectionFactory(this.mockConnectionFactory);
if (dynamicQueue) {
pfb.setQueueName("myQueue");
}
else {
pfb.setQueue(this.mockQueue);
}
pfb.setMessageConverter(new MockSimpleMessageConverter());
pfb.afterPropertiesSet();
ITestBean proxy = (ITestBean) pfb.getObject();
assertEquals("myname", proxy.getName());
assertEquals(99, proxy.getAge());
proxy.setAge(50);
assertEquals(50, proxy.getAge());
proxy.setStringArray(new String[] {"str1", "str2"});
assertTrue(Arrays.equals(new String[] {"str1", "str2"}, proxy.getStringArray()));
try {
proxy.exceptional(new IllegalStateException());
fail("Should have thrown IllegalStateException");
}
catch (IllegalStateException ex) {
// expected
}
try {
proxy.exceptional(new IllegalAccessException());
fail("Should have thrown IllegalAccessException");
}
catch (IllegalAccessException ex) {
// expected
}
}
private static class ResponseStoringProducer implements MessageProducer {
public Message response;
public boolean closed = false;
@Override
public void setDisableMessageID(boolean b) throws JMSException {
}
@Override
public boolean getDisableMessageID() throws JMSException {
return false;
}
@Override
public void setDisableMessageTimestamp(boolean b) throws JMSException {
}
@Override
public boolean getDisableMessageTimestamp() throws JMSException {
return false;
}
@Override
public void setDeliveryMode(int i) throws JMSException {
}
@Override
public int getDeliveryMode() throws JMSException {
return 0;
}
@Override
public void setPriority(int i) throws JMSException {
}
@Override
public int getPriority() throws JMSException {
return 0;
}
@Override
public void setTimeToLive(long l) throws JMSException {
}
@Override
public long getTimeToLive() throws JMSException {
return 0;
}
@Override
public void setDeliveryDelay(long deliveryDelay) throws JMSException {
}
@Override
public long getDeliveryDelay() throws JMSException {
return 0;
}
@Override
public Destination getDestination() throws JMSException {
return null;
}
@Override
public void close() throws JMSException {
this.closed = true;
}
@Override
public void send(Message message) throws JMSException {
this.response = message;
}
@Override
public void send(Message message, int i, int i1, long l) throws JMSException {
}
@Override
public void send(Destination destination, Message message) throws JMSException {
}
@Override
public void send(Destination destination, Message message, int i, int i1, long l) throws JMSException {
}
@Override
public void send(Message message, CompletionListener completionListener) throws JMSException {
}
@Override
public void send(Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener) throws JMSException {
}
@Override
public void send(Destination destination, Message message, CompletionListener completionListener) throws JMSException {
}
@Override
public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener) throws JMSException {
}
}
private static class MockObjectMessage implements ObjectMessage {
private Serializable serializable;
private Destination replyTo;
public MockObjectMessage(Serializable serializable) {
this.serializable = serializable;
}
@Override
public void setObject(Serializable serializable) throws JMSException {
this.serializable = serializable;
}
@Override
public Serializable getObject() throws JMSException {
return serializable;
}
@Override
public String getJMSMessageID() throws JMSException {
return null;
}
@Override
public void setJMSMessageID(String string) throws JMSException {
}
@Override
public long getJMSTimestamp() throws JMSException {
return 0;
}
@Override
public void setJMSTimestamp(long l) throws JMSException {
}
@Override
public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
return new byte[0];
}
@Override
public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException {
}
@Override
public void setJMSCorrelationID(String string) throws JMSException {
}
@Override
public String getJMSCorrelationID() throws JMSException {
return null;
}
@Override
public Destination getJMSReplyTo() throws JMSException {
return replyTo;
}
@Override
public void setJMSReplyTo(Destination destination) throws JMSException {
this.replyTo = destination;
}
@Override
public Destination getJMSDestination() throws JMSException {
return null;
}
@Override
public void setJMSDestination(Destination destination) throws JMSException {
}
@Override
public int getJMSDeliveryMode() throws JMSException {
return 0;
}
@Override
public void setJMSDeliveryMode(int i) throws JMSException {
}
@Override
public boolean getJMSRedelivered() throws JMSException {
return false;
}
@Override
public void setJMSRedelivered(boolean b) throws JMSException {
}
@Override
public String getJMSType() throws JMSException {
return null;
}
@Override
public void setJMSType(String string) throws JMSException {
}
@Override
public long getJMSExpiration() throws JMSException {
return 0;
}
@Override
public void setJMSExpiration(long l) throws JMSException {
}
@Override
public int getJMSPriority() throws JMSException {
return 0;
}
@Override
public void setJMSPriority(int i) throws JMSException {
}
@Override
public long getJMSDeliveryTime() throws JMSException {
return 0;
}
@Override
public void setJMSDeliveryTime(long deliveryTime) throws JMSException {
}
@Override
public <T> T getBody(Class<T> c) throws JMSException {
return null;
}
@Override
public boolean isBodyAssignableTo(Class c) throws JMSException {
return false;
}
@Override
public void clearProperties() throws JMSException {
}
@Override
public boolean propertyExists(String string) throws JMSException {
return false;
}
@Override
public boolean getBooleanProperty(String string) throws JMSException {
return false;
}
@Override
public byte getByteProperty(String string) throws JMSException {
return 0;
}
@Override
public short getShortProperty(String string) throws JMSException {
return 0;
}
@Override
public int getIntProperty(String string) throws JMSException {
return 0;
}
@Override
public long getLongProperty(String string) throws JMSException {
return 0;
}
@Override
public float getFloatProperty(String string) throws JMSException {
return 0;
}
@Override
public double getDoubleProperty(String string) throws JMSException {
return 0;
}
@Override
public String getStringProperty(String string) throws JMSException {
return null;
}
@Override
public Object getObjectProperty(String string) throws JMSException {
return null;
}
@Override
public Enumeration getPropertyNames() throws JMSException {
return null;
}
@Override
public void setBooleanProperty(String string, boolean b) throws JMSException {
}
@Override
public void setByteProperty(String string, byte b) throws JMSException {
}
@Override
public void setShortProperty(String string, short i) throws JMSException {
}
@Override
public void setIntProperty(String string, int i) throws JMSException {
}
@Override
public void setLongProperty(String string, long l) throws JMSException {
}
@Override
public void setFloatProperty(String string, float v) throws JMSException {
}
@Override
public void setDoubleProperty(String string, double v) throws JMSException {
}
@Override
public void setStringProperty(String string, String string1) throws JMSException {
}
@Override
public void setObjectProperty(String string, Object object) throws JMSException {
}
@Override
public void acknowledge() throws JMSException {
}
@Override
public void clearBody() throws JMSException {
}
}
private static class MockSimpleMessageConverter extends SimpleMessageConverter {
@Override
public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
return new MockObjectMessage((Serializable) object);
}
}
}