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.apache.activemq.command.ActiveMQQueue;
21  import org.aopalliance.intercept.MethodInvocation;
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.springframework.remoting.RemoteAccessException;
28  import org.springframework.remoting.support.DefaultRemoteInvocationExecutor;
29  import org.springframework.remoting.support.RemoteInvocation;
30  
31  import javax.jms.JMSException;
32  import javax.jms.MessageConsumer;
33  import javax.jms.Queue;
34  import javax.jms.Session;
35  
36  import java.lang.reflect.InvocationTargetException;
37  
38  /***
39   * Uses the single threaded requestor
40   *
41   * @version $Revision: 1.7 $
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          configure(exporter);
56          subscribeToQueue(exporter, getDestinationName());
57  
58          pfb = new JmsProxyFactoryBean();
59          pfb.setServiceInterface(ITestBean.class);
60          pfb.setServiceUrl("http://myurl");
61          pfb.setRequestor(createRequestor(getDestinationName()));
62          configure(pfb);
63  
64  
65          ITestBean proxy = (ITestBean) pfb.getObject();
66          assertEquals("myname", proxy.getName());
67          assertEquals(99, proxy.getAge());
68          proxy.setAge(50);
69  
70          System.out.println("getting name: " + proxy.getName());
71          int age = proxy.getAge();
72          System.out.println("got age: " + age);
73  
74          assertEquals("myname", proxy.getName());
75          assertEquals(50, proxy.getAge());
76  
77          try {
78              proxy.exceptional(new IllegalStateException());
79              fail("Should have thrown IllegalStateException");
80          }
81          catch (IllegalStateException ex) {
82              // expected
83          }
84          try {
85              proxy.exceptional(new IllegalAccessException());
86              fail("Should have thrown IllegalAccessException");
87          }
88          catch (IllegalAccessException ex) {
89              // expected
90          }
91      }
92  
93      public void testJmsProxyFactoryBeanAndServiceExporterUsingSimpleConfiguration() throws Throwable {
94          TestBean target = new TestBean("myname", 99);
95          exporter = new JmsServiceExporter();
96          exporter.setServiceInterface(ITestBean.class);
97          exporter.setService(target);
98          exporter.setConnectionFactory(connectionFactory);
99          configure(exporter);
100         subscribeToQueue(exporter, getDestinationName());
101 
102         pfb = new JmsProxyFactoryBean();
103         pfb.setServiceInterface(ITestBean.class);
104         pfb.setConnectionFactory(connectionFactory);
105         pfb.setDestination(new ActiveMQQueue(getDestinationName()));
106         configure(pfb);
107 
108         ITestBean proxy = (ITestBean) pfb.getObject();
109         assertEquals("myname", proxy.getName());
110         assertEquals(99, proxy.getAge());
111         proxy.setAge(50);
112 
113         System.out.println("getting name: " + proxy.getName());
114         int age = proxy.getAge();
115         System.out.println("got age: " + age);
116 
117         assertEquals("myname", proxy.getName());
118         assertEquals(50, proxy.getAge());
119     }
120 
121     public void testJmsProxyFactoryBeanAndServiceExporterWithOneWays() throws Throwable {
122         TestBean target = new TestBean("myname", 99);
123         exporter = new JmsServiceExporter();
124         exporter.setServiceInterface(ITestBean.class);
125         exporter.setService(target);
126         configure(exporter);
127         subscribeToQueue(exporter, getDestinationName());
128 
129         pfb = new JmsProxyFactoryBean();
130         pfb.setServiceInterface(ITestBean.class);
131         pfb.setServiceUrl("http://myurl");
132         pfb.setRequestor(createRequestor(getDestinationName()));
133         pfb.setRemoteInvocationFactory(new LingoRemoteInvocationFactory(new SimpleMetadataStrategy(true)));
134         configure(pfb);
135 
136         ITestBean proxy = (ITestBean) pfb.getObject();
137         assertEquals("myname", proxy.getName());
138         assertEquals(99, proxy.getAge());
139         proxy.setAge(50);
140 
141         System.out.println("getting name: " + proxy.getName());
142         int age = proxy.getAge();
143         System.out.println("got age: " + age);
144 
145         assertEquals("myname", proxy.getName());
146         assertEquals(50, proxy.getAge());
147 
148         try {
149             proxy.exceptional(new IllegalStateException());
150             fail("Should have thrown IllegalStateException");
151         }
152         catch (IllegalStateException ex) {
153             // expected
154         }
155         try {
156             proxy.exceptional(new IllegalAccessException());
157             fail("Should have thrown IllegalAccessException");
158         }
159         catch (IllegalAccessException ex) {
160             // expected
161         }
162     }
163 
164     public void testJmsProxyFactoryBeanAndServiceExporterWithJMSException() throws Exception {
165         TestBean target = new TestBean("myname", 99);
166         final JmsServiceExporter exporter = new JmsServiceExporter();
167         exporter.setServiceInterface(ITestBean.class);
168         exporter.setService(target);
169         configure(exporter);
170         subscribeToQueue(exporter, getDestinationName());
171 
172         JmsProxyFactoryBean pfb = new JmsProxyFactoryBean();
173         pfb.setServiceInterface(ITestBean.class);
174         pfb.setServiceUrl("http://myurl");
175 
176         pfb.setRequestor(createRequestor(getDestinationName()));
177         configure(pfb);
178         ITestBean proxy = (ITestBean) pfb.getObject();
179 
180         // lets force an exception by closing the session
181         closeSession(pfb);
182         try {
183             proxy.setAge(50);
184             fail("Should have thrown RemoteAccessException");
185         }
186         catch (RemoteAccessException ex) {
187             // expected
188             assertTrue(ex.getCause() instanceof JMSException);
189         }
190     }
191 
192     public void testJmsProxyFactoryBeanAndServiceExporterWithInvocationAttributes() throws Exception {
193         TestBean target = new TestBean("myname", 99);
194         final JmsServiceExporter exporter = new JmsServiceExporter();
195         exporter.setServiceInterface(ITestBean.class);
196         exporter.setService(target);
197         exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() {
198             public Object invoke(RemoteInvocation invocation, Object targetObject)
199                     throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
200                 assertNotNull(invocation.getAttributes());
201                 assertEquals(1, invocation.getAttributes().size());
202                 assertEquals("myValue", invocation.getAttributes().get("myKey"));
203                 assertEquals("myValue", invocation.getAttribute("myKey"));
204                 return super.invoke(invocation, targetObject);
205             }
206         });
207         configure(exporter);
208         subscribeToQueue(exporter, getDestinationName());
209 
210         JmsProxyFactoryBean pfb = new JmsProxyFactoryBean();
211         pfb.setServiceInterface(ITestBean.class);
212         pfb.setServiceUrl("http://myurl");
213         pfb.setRequestor(createRequestor(getDestinationName()));
214         pfb.setRemoteInvocationFactory(new LingoRemoteInvocationFactory(strategy) {
215             public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
216                 RemoteInvocation invocation = super.createRemoteInvocation(methodInvocation);
217                 invocation.addAttribute("myKey", "myValue");
218                 try {
219                     invocation.addAttribute("myKey", "myValue");
220                     fail("Should have thrown IllegalStateException");
221                 }
222                 catch (IllegalStateException ex) {
223                     // expected: already defined
224                 }
225                 assertNotNull(invocation.getAttributes());
226                 assertEquals(1, invocation.getAttributes().size());
227                 assertEquals("myValue", invocation.getAttributes().get("myKey"));
228                 assertEquals("myValue", invocation.getAttribute("myKey"));
229                 return invocation;
230             }
231         });
232         configure(pfb);
233 
234         ITestBean proxy = (ITestBean) pfb.getObject();
235         assertEquals("myname", proxy.getName());
236         assertEquals(99, proxy.getAge());
237     }
238 
239     public void testJmsProxyFactoryBeanAndServiceExporterWithCustomInvocationObject() throws Exception {
240         TestBean target = new TestBean("myname", 99);
241         final JmsServiceExporter exporter = new JmsServiceExporter();
242         exporter.setServiceInterface(ITestBean.class);
243         exporter.setService(target);
244         exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() {
245             public Object invoke(RemoteInvocation invocation, Object targetObject)
246                     throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
247                 assertNull(invocation.getAttributes());
248                 assertNull(invocation.getAttribute("myKey"));
249                 return super.invoke(invocation, targetObject);
250             }
251         });
252         configure(exporter);
253         subscribeToQueue(exporter, getDestinationName());
254 
255         JmsProxyFactoryBean pfb = new JmsProxyFactoryBean();
256         pfb.setServiceInterface(ITestBean.class);
257         pfb.setServiceUrl("http://myurl");
258         pfb.setRequestor(createRequestor(getDestinationName()));
259         pfb.setRemoteInvocationFactory(new LingoRemoteInvocationFactory(strategy) {
260             public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
261                 RemoteInvocation invocation = super.createRemoteInvocation(methodInvocation);
262                 assertNull(invocation.getAttributes());
263                 assertNull(invocation.getAttribute("myKey"));
264                 return invocation;
265             }
266         });
267         configure(pfb);
268 
269         ITestBean proxy = (ITestBean) pfb.getObject();
270         assertEquals("myname", proxy.getName());
271         assertEquals(99, proxy.getAge());
272     }
273 
274     public void testJmsInvokerWithSpecialLocalMethods() throws Exception {
275         String serviceUrl = "http://myurl";
276         JmsProxyFactoryBean pfb = new JmsProxyFactoryBean();
277         pfb.setServiceInterface(ITestBean.class);
278         pfb.setServiceUrl(serviceUrl);
279         pfb.setRequestor(createRequestor(getDestinationName()));
280         configure(pfb);
281 
282         ITestBean proxy = (ITestBean) pfb.getObject();
283 
284         // shouldn't go through to remote service
285         assertTrue(proxy.toString().indexOf("JMS invoker") != -1);
286         assertTrue(proxy.toString().indexOf(serviceUrl) != -1);
287         assertEquals(proxy.hashCode(), proxy.hashCode());
288         assertTrue(proxy.equals(proxy));
289 
290         // lets force an exception by closing the session
291         closeSession(pfb);
292         try {
293             proxy.setAge(50);
294             fail("Should have thrown RemoteAccessException");
295         }
296         catch (RemoteAccessException ex) {
297             // expected
298             assertTrue(ex.getCause() instanceof JMSException);
299         }
300     }
301 
302     protected void setUp() throws Exception {
303         super.setUp();
304         strategy = createMetadataStrategy();
305     }
306 
307     protected void tearDown() throws Exception {
308         if (connection != null) {
309             connection.close();
310         }
311         super.tearDown();
312     }
313 
314 
315     protected void configure(JmsServiceExporter exporter) throws Exception {
316         exporter.setConnectionFactory(connectionFactory);
317         exporter.afterPropertiesSet();
318     }
319 
320     protected void configure(JmsProxyFactoryBean pfb) throws JMSException {
321         pfb.setConnectionFactory(connectionFactory);
322         pfb.afterPropertiesSet();
323     }
324 
325     protected MetadataStrategy createMetadataStrategy() {
326         return new SimpleMetadataStrategy(false);
327     }
328 
329 
330     protected void subscribeToQueue(JmsServiceExporter exporter, String queueName) throws JMSException {
331         Session serverSession = createSession();
332         Queue queue = serverSession.createQueue(queueName);
333         MessageConsumer consumer = serverSession.createConsumer(queue);
334         consumer.setMessageListener(exporter);
335     }
336 
337 }