1   /***
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Exoffice Technologies.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Exoffice Technologies. Exolab is a registered
23   *    trademark of Exoffice Technologies.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: ExportTestCase.java,v 1.2 2005/05/27 13:52:23 tanderson Exp $
44   */
45  package org.exolab.jms.net.invoke;
46  
47  import java.rmi.server.ExportException;
48  import java.rmi.NoSuchObjectException;
49  import java.util.Map;
50  
51  import org.exolab.jms.common.security.BasicPrincipal;
52  import org.exolab.jms.net.EchoService;
53  import org.exolab.jms.net.EchoServiceImpl;
54  import org.exolab.jms.net.Callback;
55  import org.exolab.jms.net.CallbackService;
56  import org.exolab.jms.net.CallbackServiceImpl;
57  import org.exolab.jms.net.connector.Authenticator;
58  import org.exolab.jms.net.connector.TestAuthenticator;
59  import org.exolab.jms.net.orb.ORB;
60  import org.exolab.jms.net.proxy.Proxy;
61  import org.exolab.jms.net.proxy.RemoteInvocationException;
62  import org.exolab.jms.net.registry.Registry;
63  
64  
65  /***
66   * Tests the ORB.exportObject() and ORB.exportObjectTo() methods.
67   *
68   * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
69   * @version $Revision: 1.2 $ $Date: 2005/05/27 13:52:23 $
70   */
71  public abstract class ExportTestCase extends ORBTestCase {
72  
73      /***
74       * Construct a new <code>ExportTestCase</code>.
75       *
76       * @param name the name of the test to run
77       * @param uri  the server export URI
78       */
79      public ExportTestCase(String name, String uri) {
80          super(name, uri);
81      }
82  
83      /***
84       * Construct a new <code>ExportTestCase</code>.
85       *
86       * @param name the name of the test to run
87       * @param uri  the server export URI
88       * @param properties connection properties. May be <code>null</code>
89       */
90      public ExportTestCase(String name, String uri, Map properties) {
91          super(name, uri, properties);
92      }
93  
94      /***
95       * Construct a new <code>ExportTestCase</code>.
96       *
97       * @param name     the name of test case
98       * @param uri      the server export URI
99       * @param routeURI the route URI
100      */
101     public ExportTestCase(String name, String uri, String routeURI) {
102         super(name, uri, routeURI);
103     }
104 
105     /***
106      * Construct a new <code>ExportTestCase</code>.
107      *
108      * @param name            the name of test case
109      * @param uri             the export URI
110      * @param routeURI        the route URI
111      * @param connectionProps connection properties. May be <code>null</code>
112      * @param acceptorProps   acceptor properites. May be <code>null</code>
113      */
114     public ExportTestCase(String name, String uri, String routeURI,
115                             Map connectionProps, Map acceptorProps) {
116         super(name, uri, routeURI, connectionProps, acceptorProps);
117     }
118 
119     /***
120      * Verifies that methods can be invoked on an object exported via {@link
121      * ORB#exportObject(Object)}.
122      *
123      * @throws Exception for any error
124      */
125     public void testExportObject() throws Exception {
126         checkExportObject(null);
127     }
128 
129     /***
130      * Verifies that methods can be invoked by an authenticated user, on an
131      * object exported via {@link ORB#exportObject(Object)}.
132      *
133      * @throws Exception for any error
134      */
135     public void testExportObjectWithAuth() throws Exception {
136         BasicPrincipal principal = new BasicPrincipal("first", "secret");
137         checkExportObject(principal);
138     }
139 
140     /***
141      * Verifies that methods can be invoked on an object exported via {@link
142      * ORB#exportObject(Object, String)}.
143      *
144      * @throws Exception for any error
145      */
146     public void testExportObjectURI() throws Exception {
147         checkExportObjectURI(null);
148     }
149 
150     /***
151      * Verifies that methods can be invoked by an authenticated user, on an
152      * object exported via {@link ORB#exportObject(Object, String)}.
153      *
154      * @throws Exception for any error
155      */
156     public void testExportObjectURIWithAuth() throws Exception {
157         BasicPrincipal principal = new BasicPrincipal("second", "secret");
158         checkExportObjectURI(principal);
159     }
160 
161     /***
162      * Verifies that {@link ORB#exportObjectTo(Object)} throws
163      * <code>ExportException</code> when there is no current caller.
164      *
165      * @throws Exception for any error
166      */
167     public void testExportObjectToNoCaller() throws Exception {
168         ORB orb = getORB();
169         EchoServiceImpl impl = new EchoServiceImpl();
170         try {
171             orb.exportObjectTo(impl);
172             fail("Expected exportObjectTo() to fail with ExportException");
173         } catch (ExportException expected) {
174             // expected behaviour
175         }
176     }
177 
178     /***
179      * Verifies that an object can be exported via {@link
180      * ORB#exportObjectTo(Object)}.
181      *
182      * @throws Exception for any error
183      */
184     public void testExportObjectTo() throws Exception {
185         checkExportObjectTo(null);
186     }
187 
188     /***
189      * Verifies that methods can be invoked by an authenticated user, on an
190      * object exported via {@link ORB#exportObjectTo(Object)}.
191      *
192      * @throws Exception for any error
193      */
194     public void testExportObjectToWithAuth() throws Exception {
195         BasicPrincipal principal = new BasicPrincipal("third", "secret");
196         checkExportObjectTo(principal);
197     }
198 
199     /***
200      * Verifies that an object can be exported via {@link
201      * ORB#exportObjectTo(Object, String)}.
202      *
203      * @throws Exception for any error
204      */
205     public void testExportObjectToURI() throws Exception {
206         checkExportObjectToURI(null);
207     }
208 
209     /***
210      * Verifies that an object can be invoked by an authenticated user. on an
211      * object exported via {@link ORB#exportObjectTo(Object, String)}.
212      *
213      * @throws Exception for any error
214      */
215     public void testExportObjectToURIWithAuth() throws Exception {
216         BasicPrincipal principal = new BasicPrincipal("fourth", "secret");
217         checkExportObjectToURI(principal);
218     }
219 
220     /***
221      * Verifies that methods can be invoked an object exported via {@link
222      * ORB#exportObject(Object)}.
223      *
224      * @param principal the security principal. If <code>null</code>, indicates
225      *                  to not use authentication.
226      * @throws Exception for any error
227      */
228     private void checkExportObject(BasicPrincipal principal)
229             throws Exception {
230         Authenticator authenticator = new TestAuthenticator(principal);
231         ORB orb = createORB(authenticator);
232         EchoServiceImpl impl = new EchoServiceImpl();
233         Proxy proxy = orb.exportObject(impl);
234         orb.getRegistry().bind("service", proxy);
235 
236         Registry registry = getRegistry(principal);
237         EchoService service = (EchoService) registry.lookup("service");
238 
239         assertTrue(service.echoBoolean(true));
240 
241         checkUnexportObject(orb, impl, service);
242     }
243 
244     /***
245      * Verifies that methods can be invoked an object exported via {@link
246      * ORB#exportObject(Object, String)}.
247      *
248      * @param principal the security principal. If <code>null</code>, indicates
249      *                  to not use authentication.
250      * @throws Exception for any error
251      */
252     private void checkExportObjectURI(BasicPrincipal principal)
253             throws Exception {
254         Authenticator authenticator = new TestAuthenticator(principal);
255         ORB orb = createORB(authenticator);
256         EchoServiceImpl impl = new EchoServiceImpl();
257         Proxy proxy = orb.exportObject(impl, getExportURI());
258         orb.getRegistry().bind("service", proxy);
259 
260         Registry registry = getRegistry(principal);
261         EchoService service = (EchoService) registry.lookup("service");
262 
263         assertTrue(service.echoBoolean(true));
264 
265         checkUnexportObject(orb, impl, service);
266     }
267 
268     /***
269      * Verifies that methods can be invoked an object exported via {@link
270      * ORB#exportObjectTo(Object)}.
271      *
272      * @param principal the security principal. If <code>null</code>, indicates
273      *                  to not use authentication.
274      * @throws Exception for any error
275      */
276     private void checkExportObjectTo(BasicPrincipal principal)
277             throws Exception {
278         Authenticator authenticator = new TestAuthenticator(principal);
279         ORB orb = createORB(authenticator);
280         EchoServiceImpl echoImpl = new EchoServiceImpl();
281 
282         ExportServiceImpl exporterImpl = new ExportServiceImpl(echoImpl, orb);
283         Proxy proxy = orb.exportObject(exporterImpl);
284         orb.getRegistry().bind("service", proxy);
285 
286         Registry registry = getRegistry(principal);
287         ExportService exporter = (ExportService) registry.lookup("service");
288         EchoService echoer = (EchoService) exporter.exportObjectTo();
289 
290         assertTrue(echoer.echoBoolean(true));
291 
292         checkUnexportObject(orb, echoImpl, echoer);
293     }
294 
295     /***
296      * Verifies that methods can be invoked an object exported via {@link
297      * ORB#exportObjectTo(Object, String)}.
298      *
299      * @param principal the security principal. If <code>null</code>, indicates
300      *                  to not use authentication.
301      * @throws Exception for any error
302      */
303     private void checkExportObjectToURI(BasicPrincipal principal)
304             throws Exception {
305         final int count = 10;
306         String user = null;
307         String password = null;
308 
309         if (principal != null) {
310             user = principal.getName();
311             password = principal.getPassword();
312         }
313 
314         Authenticator authenticator = new TestAuthenticator(principal);
315         ORB orb = createORB(authenticator);
316 
317         CallbackService serviceImpl = new CallbackServiceImpl();
318         Proxy proxy = orb.exportObject(serviceImpl);
319         orb.getRegistry().bind("service", proxy);
320 
321         ORB client = getClientORB();
322         Registry registry = getRegistry(principal);
323         CallbackService service = (CallbackService) registry.lookup("service");
324 
325         LoggingCallback callback = new LoggingCallback();
326         Callback callbackProxy = (Callback) client.exportObjectTo(
327                 callback, getServerURI(), user, password);
328         service.addCallback(callbackProxy);
329 
330         for (int i = 0; i < count; ++i) {
331             service.invoke(new Integer(i));
332         }
333 
334         Integer[] objects = (Integer[]) callback.getObjects().toArray(
335                 new Integer[0]);
336         assertEquals(count, objects.length);
337         for (int i = 0; i < count; ++i) {
338             assertEquals(i, objects[i].intValue());
339         }
340 
341         client.unexportObject(callback);
342         try {
343             service.invoke(new Integer(0));
344         } catch (RemoteInvocationException expected) {
345             // expected behaviour
346             assertTrue(expected.getTargetException()
347                        instanceof NoSuchObjectException);
348         }
349 
350         try {
351             orb.unexportObject(client);
352             fail("Expected NoSuchObjectException to be thrown");
353         } catch (NoSuchObjectException expected) {
354             // expected behaviour
355         }        
356     }
357 
358     /***
359      * Verifies that an exported service can be unexported, and that
360      * subsequent invocations on its proxy fail with a
361      * <code>NoSuchObjectException</code>
362      *
363      * @param orb the orb to unexport the service with
364      * @param service the object to unexport
365      * @param proxy
366      * @throws Exception for any error
367      */
368     private void checkUnexportObject(ORB orb, EchoServiceImpl service,
369                                      EchoService proxy) throws Exception {
370         orb.unexportObject(service);
371 
372         try {
373             proxy.echoBoolean(true);
374             fail("Managed to invoke method on unexported object");
375         } catch (RemoteInvocationException expected) {
376             // expected behaviour
377             assertTrue(expected.getTargetException()
378                        instanceof NoSuchObjectException);
379         }
380 
381         try {
382             orb.unexportObject(service);
383             fail("Expected NoSuchObjectException to be thrown");
384         } catch (NoSuchObjectException expected) {
385             // expected behaviour
386         }
387     }
388 
389 }