1   /***
2    *
3    * Copyright 2005 LogicBlaze, Inc.
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   *
17   **/
18  package org.logicblaze.lingo.jms;
19  
20  import org.activemq.ActiveMQConnectionFactory;
21  import org.activemq.message.ActiveMQQueue;
22  import org.logicblaze.lingo.LingoRemoteInvocationFactory;
23  import org.logicblaze.lingo.MetadataStrategy;
24  import org.logicblaze.lingo.SimpleMetadataStrategy;
25  import org.logicblaze.lingo.beans.ITestBean;
26  import org.logicblaze.lingo.beans.TestBean;
27  import org.aopalliance.intercept.MethodInvocation;
28  import org.springframework.remoting.RemoteAccessException;
29  import org.springframework.remoting.support.DefaultRemoteInvocationExecutor;
30  import org.springframework.remoting.support.RemoteInvocation;
31  
32  import javax.jms.JMSException;
33  import javax.jms.MessageConsumer;
34  import javax.jms.Queue;
35  import javax.jms.Session;
36  import java.lang.reflect.InvocationTargetException;
37  
38  /***
39   * Uses the single threaded requestor
40   *
41   * @version $Revision: 1.1 $
42   */
43  public class JmsRemotingTest extends JmsTestSupport {
44      private MetadataStrategy strategy;
45  
46      protected JmsServiceExporter exporter;
47      protected JmsProxyFactoryBean pfb;
48  
49  
50      public void testJmsProxyFactoryBeanAndServiceExporter() throws Throwable {
51          TestBean target = new TestBean("myname", 99);
52          exporter = new JmsServiceExporter();
53          exporter.setServiceInterface(ITestBean.class);
54          exporter.setService(target);
55          exporter.setProducer(createJmsProducer());
56          configure(exporter);
57          subscribeToQueue(exporter, getDestinationName());
58  
59          pfb = new JmsProxyFactoryBean();
60          pfb.setServiceInterface(ITestBean.class);
61          pfb.setServiceUrl("http://myurl");
62          pfb.setRequestor(createRequestor(getDestinationName()));
63          configure(pfb);
64  
65  
66          ITestBean proxy = (ITestBean) pfb.getObject();
67          assertEquals("myname", proxy.getName());
68          assertEquals(99, proxy.getAge());
69          proxy.setAge(50);
70  
71          System.out.println("getting name: " + proxy.getName());
72          int age = proxy.getAge();
73          System.out.println("got age: " + age);
74  
75          assertEquals("myname", proxy.getName());
76          assertEquals(50, proxy.getAge());
77  
78          try {
79              proxy.exceptional(new IllegalStateException());
80              fail("Should have thrown IllegalStateException");
81          }
82          catch (IllegalStateException ex) {
83              // expected
84          }
85          try {
86              proxy.exceptional(new IllegalAccessException());
87              fail("Should have thrown IllegalAccessException");
88          }
89          catch (IllegalAccessException ex) {
90              // expected
91          }
92      }
93  
94      public void testJmsProxyFactoryBeanAndServiceExporterUsingSimpleConfiguration() throws Throwable {
95          TestBean target = new TestBean("myname", 99);
96          exporter = new JmsServiceExporter();
97          exporter.setServiceInterface(ITestBean.class);
98          exporter.setService(target);
99          exporter.setConnectionFactory(connectionFactory);
100         configure(exporter);
101         subscribeToQueue(exporter, getDestinationName());
102 
103         pfb = new JmsProxyFactoryBean();
104         pfb.setServiceInterface(ITestBean.class);
105         pfb.setConnectionFactory(connectionFactory);
106         pfb.setDestination(new ActiveMQQueue(getDestinationName()));
107         configure(pfb);
108 
109         ITestBean proxy = (ITestBean) pfb.getObject();
110         assertEquals("myname", proxy.getName());
111         assertEquals(99, proxy.getAge());
112         proxy.setAge(50);
113 
114         System.out.println("getting name: " + proxy.getName());
115         int age = proxy.getAge();
116         System.out.println("got age: " + age);
117 
118         assertEquals("myname", proxy.getName());
119         assertEquals(50, proxy.getAge());
120     }
121 
122     public void testJmsProxyFactoryBeanAndServiceExporterWithOneWays() throws Throwable {
123         TestBean target = new TestBean("myname", 99);
124         exporter = new JmsServiceExporter();
125         exporter.setServiceInterface(ITestBean.class);
126         exporter.setService(target);
127         exporter.setProducer(createJmsProducer());
128         configure(exporter);
129         subscribeToQueue(exporter, getDestinationName());
130 
131         pfb = new JmsProxyFactoryBean();
132         pfb.setServiceInterface(ITestBean.class);
133         pfb.setServiceUrl("http://myurl");
134         pfb.setRequestor(createRequestor(getDestinationName()));
135         pfb.setRemoteInvocationFactory(new LingoRemoteInvocationFactory(new SimpleMetadataStrategy(true)));
136         configure(pfb);
137 
138         ITestBean proxy = (ITestBean) pfb.getObject();
139         assertEquals("myname", proxy.getName());
140         assertEquals(99, proxy.getAge());
141         proxy.setAge(50);
142 
143         System.out.println("getting name: " + proxy.getName());
144         int age = proxy.getAge();
145         System.out.println("got age: " + age);
146 
147         assertEquals("myname", proxy.getName());
148         assertEquals(50, proxy.getAge());
149 
150         try {
151             proxy.exceptional(new IllegalStateException());
152             fail("Should have thrown IllegalStateException");
153         }
154         catch (IllegalStateException ex) {
155             // expected
156         }
157         try {
158             proxy.exceptional(new IllegalAccessException());
159             fail("Should have thrown IllegalAccessException");
160         }
161         catch (IllegalAccessException ex) {
162             // expected
163         }
164     }
165 
166     public void testJmsProxyFactoryBeanAndServiceExporterWithJMSException() throws Exception {
167         TestBean target = new TestBean("myname", 99);
168         final JmsServiceExporter exporter = new JmsServiceExporter();
169         exporter.setServiceInterface(ITestBean.class);
170         exporter.setService(target);
171         exporter.setProducer(createJmsProducer());
172         configure(exporter);
173         subscribeToQueue(exporter, getDestinationName());
174 
175         JmsProxyFactoryBean pfb = new JmsProxyFactoryBean();
176         pfb.setServiceInterface(ITestBean.class);
177         pfb.setServiceUrl("http://myurl");
178 
179         pfb.setRequestor(createRequestor(getDestinationName()));
180         configure(pfb);
181         ITestBean proxy = (ITestBean) pfb.getObject();
182 
183         // lets force an exception by closing the session
184         closeSession(pfb);
185         try {
186             proxy.setAge(50);
187             fail("Should have thrown RemoteAccessException");
188         }
189         catch (RemoteAccessException ex) {
190             // expected
191             assertTrue(ex.getCause() instanceof JMSException);
192         }
193     }
194 
195     public void testJmsProxyFactoryBeanAndServiceExporterWithInvocationAttributes() throws Exception {
196         TestBean target = new TestBean("myname", 99);
197         final JmsServiceExporter exporter = new JmsServiceExporter();
198         exporter.setServiceInterface(ITestBean.class);
199         exporter.setService(target);
200         exporter.setProducer(createJmsProducer());
201         exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() {
202             public Object invoke(RemoteInvocation invocation, Object targetObject)
203                     throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
204                 assertNotNull(invocation.getAttributes());
205                 assertEquals(1, invocation.getAttributes().size());
206                 assertEquals("myValue", invocation.getAttributes().get("myKey"));
207                 assertEquals("myValue", invocation.getAttribute("myKey"));
208                 return super.invoke(invocation, targetObject);
209             }
210         });
211         configure(exporter);
212         subscribeToQueue(exporter, getDestinationName());
213 
214         JmsProxyFactoryBean pfb = new JmsProxyFactoryBean();
215         pfb.setServiceInterface(ITestBean.class);
216         pfb.setServiceUrl("http://myurl");
217         pfb.setRequestor(createRequestor(getDestinationName()));
218         pfb.setRemoteInvocationFactory(new LingoRemoteInvocationFactory(strategy) {
219             public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
220                 RemoteInvocation invocation = super.createRemoteInvocation(methodInvocation);
221                 invocation.addAttribute("myKey", "myValue");
222                 try {
223                     invocation.addAttribute("myKey", "myValue");
224                     fail("Should have thrown IllegalStateException");
225                 }
226                 catch (IllegalStateException ex) {
227                     // expected: already defined
228                 }
229                 assertNotNull(invocation.getAttributes());
230                 assertEquals(1, invocation.getAttributes().size());
231                 assertEquals("myValue", invocation.getAttributes().get("myKey"));
232                 assertEquals("myValue", invocation.getAttribute("myKey"));
233                 return invocation;
234             }
235         });
236         configure(pfb);
237 
238         ITestBean proxy = (ITestBean) pfb.getObject();
239         assertEquals("myname", proxy.getName());
240         assertEquals(99, proxy.getAge());
241     }
242 
243     public void testJmsProxyFactoryBeanAndServiceExporterWithCustomInvocationObject() throws Exception {
244         TestBean target = new TestBean("myname", 99);
245         final JmsServiceExporter exporter = new JmsServiceExporter();
246         exporter.setServiceInterface(ITestBean.class);
247         exporter.setService(target);
248         exporter.setProducer(createJmsProducer());
249         exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() {
250             public Object invoke(RemoteInvocation invocation, Object targetObject)
251                     throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
252                 assertNull(invocation.getAttributes());
253                 assertNull(invocation.getAttribute("myKey"));
254                 return super.invoke(invocation, targetObject);
255             }
256         });
257         configure(exporter);
258         subscribeToQueue(exporter, getDestinationName());
259 
260         JmsProxyFactoryBean pfb = new JmsProxyFactoryBean();
261         pfb.setServiceInterface(ITestBean.class);
262         pfb.setServiceUrl("http://myurl");
263         pfb.setRequestor(createRequestor(getDestinationName()));
264         pfb.setRemoteInvocationFactory(new LingoRemoteInvocationFactory(strategy) {
265             public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
266                 RemoteInvocation invocation = super.createRemoteInvocation(methodInvocation);
267                 assertNull(invocation.getAttributes());
268                 assertNull(invocation.getAttribute("myKey"));
269                 return invocation;
270             }
271         });
272         configure(pfb);
273 
274         ITestBean proxy = (ITestBean) pfb.getObject();
275         assertEquals("myname", proxy.getName());
276         assertEquals(99, proxy.getAge());
277     }
278 
279     public void testJmsInvokerWithSpecialLocalMethods() throws Exception {
280         String serviceUrl = "http://myurl";
281         JmsProxyFactoryBean pfb = new JmsProxyFactoryBean();
282         pfb.setServiceInterface(ITestBean.class);
283         pfb.setServiceUrl(serviceUrl);
284         pfb.setRequestor(createRequestor(getDestinationName()));
285         configure(pfb);
286 
287         ITestBean proxy = (ITestBean) pfb.getObject();
288 
289         // shouldn't go through to remote service
290         assertTrue(proxy.toString().indexOf("JMS invoker") != -1);
291         assertTrue(proxy.toString().indexOf(serviceUrl) != -1);
292         assertEquals(proxy.hashCode(), proxy.hashCode());
293         assertTrue(proxy.equals(proxy));
294 
295         // lets force an exception by closing the session
296         closeSession(pfb);
297         try {
298             proxy.setAge(50);
299             fail("Should have thrown RemoteAccessException");
300         }
301         catch (RemoteAccessException ex) {
302             // expected
303             assertTrue(ex.getCause() instanceof JMSException);
304         }
305     }
306 
307     protected void setUp() throws Exception {
308         super.setUp();
309         strategy = createMetadataStrategy();
310     }
311 
312     protected void tearDown() throws Exception {
313         if (connection != null) {
314             connection.close();
315         }
316         if (connectionFactory instanceof ActiveMQConnectionFactory) {
317             ActiveMQConnectionFactory amqConnectionFactory = (ActiveMQConnectionFactory) connectionFactory;
318             amqConnectionFactory.stop();
319         }
320         super.tearDown();
321     }
322 
323 
324     protected void configure(JmsServiceExporter exporter) throws Exception {
325         exporter.afterPropertiesSet();
326     }
327 
328     protected void configure(JmsProxyFactoryBean pfb) throws JMSException {
329         pfb.afterPropertiesSet();
330     }
331 
332     protected MetadataStrategy createMetadataStrategy() {
333         return new SimpleMetadataStrategy(false);
334     }
335 
336 
337     protected void subscribeToQueue(JmsServiceExporter exporter, String queueName) throws JMSException {
338         Session serverSession = createSession();
339         Queue queue = serverSession.createQueue(queueName);
340         MessageConsumer consumer = serverSession.createConsumer(queue);
341         consumer.setMessageListener(exporter);
342     }
343 
344 }