KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > testbeancluster > test > RetryInterceptorUnitTestCase


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22
23 package org.jboss.test.testbeancluster.test;
24
25 import java.util.Properties JavaDoc;
26 import java.util.Random JavaDoc;
27
28 import javax.naming.Context JavaDoc;
29 import javax.naming.InitialContext JavaDoc;
30
31 import junit.framework.AssertionFailedError;
32 import junit.framework.Test;
33 import junit.framework.TestSuite;
34
35 import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
36 import org.jboss.logging.Logger;
37 import org.jboss.proxy.ejb.RetryInterceptor;
38 import org.jboss.test.JBossClusteredTestCase;
39 import org.jboss.test.testbean.interfaces.AComplexPK;
40 import org.jboss.test.testbean.interfaces.EntityPK;
41 import org.jboss.test.testbean.interfaces.EntityPKHome;
42 import org.jboss.test.testbean.interfaces.StatefulSessionHome;
43 import org.jboss.test.testbeancluster.interfaces.NodeAnswer;
44 import org.jboss.test.testbeancluster.interfaces.StatefulSession;
45 import org.jboss.test.testbeancluster.interfaces.StatelessSession;
46 import org.jboss.test.testbeancluster.interfaces.StatelessSessionHome;
47
48 /**
49  * Tests the RetryInterceptor.
50  *
51  * @author <a HREF="mailto://brian.stansberry@jboss.com">Brian Stansberry</a>
52  * @version $Revision $
53  */

54 public class RetryInterceptorUnitTestCase extends JBossClusteredTestCase
55 {
56    // NOTE: these variables must be static as apparently a separate instance
57
// of this class is created for each test.
58
private static boolean deployed0 = false;
59    private static boolean deployed1 = false;
60    
61    static abstract class RetryCaller extends Thread JavaDoc
62    {
63       Properties JavaDoc env;
64       Throwable JavaDoc failure;
65       
66       RetryCaller(Properties JavaDoc env)
67       {
68          this.env = env;
69       }
70       
71       public void run()
72       {
73          try
74          {
75             // Establish an initial context on this thread with the
76
// given properties -- needed for JBoss NamingContextFactory
77
// to work properly. Meaningless otherwise
78
new InitialContext JavaDoc(env);
79             
80             executeTest();
81          }
82          catch (Throwable JavaDoc t)
83          {
84             failure = t;
85          }
86       }
87       
88       protected abstract void executeTest() throws Throwable JavaDoc;
89       
90    }
91    
92    static class MultiRetryCaller extends RetryCaller
93    {
94       StatelessSessionHome slsbh;
95       StatelessSession slsb;
96       StatefulSessionHome sfsbh;
97       StatefulSession sfsb;
98       NodeAnswer node1;
99       EntityPKHome epkh;
100       EntityPK epk;
101       int other;
102       AComplexPK pk;
103       Logger log;
104       Throwable JavaDoc failure;
105       
106       MultiRetryCaller(Properties JavaDoc env,
107                   StatelessSessionHome slsbh, StatelessSession slsb,
108                       StatefulSessionHome sfsbh, StatefulSession sfsb,
109                       NodeAnswer node1,
110                       EntityPKHome epkh, EntityPK epk,
111                       int other, AComplexPK pk,
112                       Logger log)
113       {
114          super(env);
115          this.slsbh = slsbh;
116          this.slsb = slsb;
117          this.sfsbh = sfsbh;
118          this.sfsb = sfsb;
119          this.node1 = node1;
120          this.epkh = epkh;
121          this.epk = epk;
122          this.other = other;
123          this.pk = pk;
124          this.log = log;
125       }
126       
127       protected void executeTest() throws Throwable JavaDoc
128       {
129          // Test that the SFSB still works
130

131          System.setProperty ("JBossCluster-DoFail", "once");
132          NodeAnswer node2 = sfsb.getNodeState ();
133          log.debug (node2);
134          
135          assertTrue ("StatefulSession: Failover has occured",
136                      !node1.nodeId.equals(node2.nodeId));
137          
138          assertTrue ("StatefulSession: Value is identical on replicated node",
139                      "Bupple-Dupple".equals (node1.answer) &&
140                      node1.answer.equals(node2.answer) );
141          
142          log.debug("StatefulSession: Retry successful");
143          
144          // Test that the SFSB Home still works
145
System.setProperty ("JBossCluster-DoFail", "once");
146          sfsb = (StatefulSession)sfsbh.create("Hippie-Dippie");
147          
148          node2 = sfsb.getNodeState ();
149          log.debug (node2);
150          
151          assertTrue ("StatefulSessionHome: Failover has occured",
152                      !node1.nodeId.equals (node2.nodeId));
153          
154          log.debug("StatefulSessionHome: Retry successful");
155          
156          // Test that the SLSB still works
157
System.setProperty ("JBossCluster-DoFail", "once");
158          log.debug("StatelessSession: Now making 1 call on server1 ");
159          assertTrue("StatelessSession: Server1 has no calls", 0 == slsb.getCallCount());
160          
161          log.debug("StatelessSession: Retry successful");
162          
163          // Test that the SLSB Home still works
164
System.setProperty ("JBossCluster-DoFail", "once");
165          log.debug("Calling create on StatelessSessionHome...");
166          slsb = slsbh.create();
167          
168          log.debug("StatelessSessionHome: Retry successful");
169          
170          // Test that the entity bean still works
171
System.setProperty ("JBossCluster-DoFail", "once");
172          log.debug("Retrieving other field again, should be " + other + "...");
173          int newValue = epk.getOtherField();
174          assertEquals("pkBean.getOtherField() correct:", other, newValue);
175          
176          log.debug("EntityBean: Retry successful");
177          
178          // Test the entity home still works
179
System.setProperty ("JBossCluster-DoFail", "once");
180          epk = epkh.findByPrimaryKey(pk);
181
182          assertTrue("pkBean != null", epk != null);
183
184          log.debug("EntityBeanHome: Retry successful");
185       }
186    }
187    
188    static class SFSBRetryCaller extends RetryCaller
189    {
190       StatefulSessionHome sfsbh;
191       StatefulSession sfsb;
192       Throwable JavaDoc failure;
193       Logger log;
194       
195       SFSBRetryCaller(Properties JavaDoc env, StatefulSession sfsb, Logger log)
196       {
197          super(env);
198          this.sfsb = sfsb;
199          this.log = log;
200       }
201       
202       protected void executeTest() throws Throwable JavaDoc
203       {
204          // Test that the SFSB still works
205
System.setProperty ("JBossCluster-DoFail", "once");
206          NodeAnswer node2 = sfsb.getNodeState ();
207          log.debug (node2);
208          
209          assertTrue ("StatefulSession: Failover has occured", node2 != null);
210          
211          log.debug("StatefulSession: Retry successful");
212          
213       }
214    }
215    static class DeferredRecoveryCaller extends RetryCaller
216    {
217       StatelessSession slsb;
218       Object JavaDoc result;
219    
220       DeferredRecoveryCaller(Properties JavaDoc env, StatelessSession slsb)
221       {
222          super(env);
223          this.slsb = slsb;
224       }
225       
226       public void executeTest() throws Throwable JavaDoc
227       {
228          // Test that the SLSB still works
229
System.setProperty ("JBossCluster-DoFail", "once");
230          result = new Long JavaDoc(slsb.getCallCount());
231       }
232    }
233    
234    /**
235     * Create a new RetryInterceptorUnitTestCase.
236     *
237     * @param name
238     */

239    public RetryInterceptorUnitTestCase(String JavaDoc name)
240    {
241       super(name);
242    }
243
244    public static Test suite() throws Exception JavaDoc
245    {
246       TestSuite suite = new TestSuite();
247       suite.addTest(new TestSuite(RetryInterceptorUnitTestCase.class));
248
249       // Create an initializer for the test suite
250
DBSetup wrapper = new DBSetup(suite);
251       return wrapper;
252    }
253    
254    /**
255     * Tests that calls to bean and home calls to SLSB, SFSB, Entity beans
256     * will still succeed after a cluster topology change that makes
257     * the target list in FamilyClusterInfo completely invalid.
258     *
259     * @throws Exception
260     */

261    public void testRetryInterceptor() throws Exception JavaDoc
262    {
263       getLog().debug("+++ Enter testRetryInterceptor");
264       
265       configureCluster();
266       
267       // Connect to the server0 HA-JNDI
268

269       Properties JavaDoc env = getNamingProperties("org.jboss.naming.NamingContextFactory",
270                                            false);
271       InitialContext JavaDoc ctx = new InitialContext JavaDoc(env);
272       
273       getLog().debug("Looking up the home nextgen.StatefulSession" + getJndiSuffix()+"...");
274       StatefulSessionHome sfsbHome =
275          (StatefulSessionHome) ctx.lookup("nextgen_StatefulSession" + getJndiSuffix());
276       if (sfsbHome!= null ) getLog().debug("ok");
277          getLog().debug("Calling create on StatefulSessionHome" + getJndiSuffix()+"...");
278       StatefulSession sfsb = (StatefulSession)sfsbHome.create("Bupple-Dupple");
279       assertTrue("statefulSessionHome.create() != null", sfsb != null);
280       getLog().debug("ok");
281       
282       NodeAnswer node1 = sfsb.getNodeState ();
283       getLog ().debug (node1);
284       
285       getLog().debug("Looking up the home nextgen.StatelessSession" + getJndiSuffix()+"...");
286       StatelessSessionHome slsbHome =
287       (StatelessSessionHome) ctx.lookup("nextgen_StatelessSession" + getJndiSuffix());
288       if (slsbHome!= null ) getLog().debug("ok");
289       getLog().debug("Calling create on StatelessSessionHome" + getJndiSuffix()+"...");
290       StatelessSession slsb = slsbHome.create();
291
292       getLog().debug("StatelessSession: Now making 1 call on server0 ");
293       assertEquals("StatelessSession: Server0 has no calls", 0, slsb.getCallCount());
294       
295       getLog().debug("Looking up home for nextgen_EntityPK" + getJndiSuffix()+"...");
296       EntityPKHome pkHome = (EntityPKHome) ctx.lookup("nextgen_EntityPK" + getJndiSuffix());
297       assertTrue("pkHome != null", pkHome != null);
298       getLog().debug("ok");
299
300       getLog().debug("Calling find on the home...");
301       EntityPK pkBean = null;
302
303       Random JavaDoc rnd = new Random JavaDoc(System.currentTimeMillis());
304       int anInt = rnd.nextInt(10);
305       int other = rnd.nextInt(10000);
306       AComplexPK pk = new AComplexPK(true, anInt, 100, 1000.0, "Marc");
307       // Let's try to find the instance
308
try
309       {
310          pkBean = pkHome.findByPrimaryKey(pk);
311       }
312       catch (Exception JavaDoc e)
313       {
314          getLog().debug("Did not find the instance will create it...");
315          pkBean = pkHome.create(true, anInt, 100, 1000.0, "Marc");
316       }
317
318
319       assertTrue("pkBean != null", pkBean != null);
320       getLog().debug("ok");
321
322       getLog().debug("Setting otherField to " + other + "...");
323       pkBean.setOtherField(other);
324       getLog().debug("ok");
325       
326       
327       // Reconfigure the cluster so the existing targets are invalid
328
reconfigureCluster();
329       
330       // Make calls on the beans in another thread so we can terminate
331
// after a reasonable period of time if the RetryInterceptor is looping
332
MultiRetryCaller caller = new MultiRetryCaller(env, slsbHome,
333             slsb, sfsbHome, sfsb, node1, pkHome, pkBean, other,
334             pk, getLog());
335       executeRetryTest(caller);
336
337       getLog().debug("+++ Exit testRetryInterceptor");
338    }
339
340    protected void executeRetryTest(RetryCaller caller)
341       throws InterruptedException JavaDoc, AssertionFailedError
342    {
343       caller.start();
344       
345       // Give the caller 15 secs to do its work
346
caller.join(15000);
347       
348       boolean alive = caller.isAlive();
349       if (alive)
350          caller.interrupt();
351       
352       assertFalse("Retry calls completed", alive);
353       
354       if (caller.failure instanceof AssertionFailedError)
355       {
356          throw (AssertionFailedError) caller.failure;
357       }
358       else if (caller.failure != null)
359       {
360          fail(caller.failure.getMessage());
361       }
362    }
363    
364    public void testDeferredRecovery() throws Exception JavaDoc
365    {
366       deferredRecoveryTest(true);
367    }
368    
369    protected void deferredRecoveryTest(boolean expectSuccess) throws Exception JavaDoc
370    {
371       getLog().debug("+++ Enter testDeferredRecovery");
372       
373       configureCluster();
374       
375       Properties JavaDoc env = getNamingProperties("org.jboss.naming.NamingContextFactory",
376                                            false);
377       InitialContext JavaDoc ctx = new InitialContext JavaDoc(env);
378       
379       getLog().debug("Looking up the home nextgen.StatelessSession" + getJndiSuffix()+"...");
380       StatelessSessionHome home =
381             (StatelessSessionHome) ctx.lookup("nextgen_StatelessSession" + getJndiSuffix());
382       if (home!= null ) getLog().debug("ok");
383       getLog().debug("Calling create on StatelessSessionHome" + getJndiSuffix()+"...");
384       StatelessSession slsb = home.create();
385
386       getLog().debug("StatelessSession: Now making 1 call on server0 ");
387       assertEquals("StatelessSession: Server0 has no calls", 0, slsb.getCallCount());
388       
389       // Undeploy the ear
390
RMIAdaptor[] adaptors = getAdaptors();
391       undeploy(adaptors[0], "test-retry.ear");
392       setDeployed0(false);
393       
394       sleep(1000);
395       
396       DeferredRecoveryCaller caller = new DeferredRecoveryCaller(env, slsb);
397       caller.start();
398       
399       sleep(1000);
400       
401       if (caller.isAlive()) // don't bother deploying otherwise
402
{
403          deploy(adaptors[1], "test-retry.ear");
404          setDeployed1(true);
405       }
406       
407       // Give the caller 3 secs to complete (extremely generous)
408
caller.join(3000);
409       
410       if (caller.isAlive())
411          fail("Caller did not complete");
412       
413       if (expectSuccess)
414       {
415          assertTrue("Caller retrieved a long", (caller.result instanceof Long JavaDoc));
416          getLog().debug("StatefulSession: Retry successful");
417       }
418       else
419       {
420          assertTrue("Caller failed as expected", caller.failure != null);
421          getLog().debug("StatefulSession: Retry failed as expected");
422       }
423       
424       getLog().debug("+++ Exit testDeferredRecovery");
425    }
426    
427    /**
428     * Tests that the retry interceptor works properly if the naming context
429     * is established via RetryInterceptor.setRetryEnv()
430     * and auto-discovery is disabled.
431     *
432     * @throws Exception
433     */

434    public void testSetRetryEnv() throws Exception JavaDoc
435    {
436       getLog().debug("+++ Enter testSetRetryEnv");
437       
438       Properties JavaDoc env = getNamingProperties("org.jnp.interfaces.NamingContextFactory", false);
439       try
440       {
441          RetryInterceptor.setRetryEnv(env);
442          InitialContext JavaDoc ctx = new InitialContext JavaDoc(env);
443          
444          sfsbTest(ctx, env);
445          
446       }
447       finally
448       {
449          RetryInterceptor.setRetryEnv(null);
450       }
451       
452       getLog().debug("+++ Exit testSetRetryEnv");
453    }
454    
455    /**
456     * Tests that the retry interceptor works properly if the naming context
457     * is established by using org.jnp.interfaces.NamingContextFactory
458     * and auto-discovery is enabled.
459     *
460     * @throws Exception
461     */

462    public void testRetryWithJnpAndAutoDiscovery() throws Exception JavaDoc
463    {
464       getLog().debug("+++ Enter testRetryWithJnpAndAutoDiscovery()");
465       Properties JavaDoc env = getNamingProperties("org.jnp.interfaces.NamingContextFactory", true);
466       
467       InitialContext JavaDoc ctx = new InitialContext JavaDoc(env);
468       
469       sfsbTest(ctx, env);
470    }
471    
472    /**
473     * Tests that the retry interceptor works properly for an SFSB given
474     * a particular JNDI client configuration.
475     *
476     * @param ctx
477     * @throws Exception
478     */

479    protected void sfsbTest(Context JavaDoc ctx, Properties JavaDoc env) throws Exception JavaDoc
480    {
481       configureCluster();
482       
483       getLog().debug("Looking up the home nextgen.StatefulSession" + getJndiSuffix()+"...");
484       StatefulSessionHome statefulSessionHome =
485          (StatefulSessionHome) ctx.lookup("nextgen_StatefulSession" + getJndiSuffix());
486       if (statefulSessionHome!= null ) getLog().debug("ok");
487          getLog().debug("Calling create on StatefulSessionHome" + getJndiSuffix()+"...");
488       StatefulSession statefulSession =
489          (StatefulSession)statefulSessionHome.create("Bupple-Dupple");
490       assertTrue("statefulSessionHome.create() != null", statefulSession != null);
491       getLog().debug("ok");
492       
493       NodeAnswer node1 = statefulSession.getNodeState ();
494       getLog ().debug (node1);
495       
496       // Reconfigure the cluster so the existing targets are invalid
497
// BES -- don't bother; we test that functionality in testRetryInterceptor
498
// just confirm that reestablishing the targets works
499
// reconfigureCluster();
500

501       // Make calls on the bean in another thread so we can terminate
502
// after a reasonable period of time if the RetryInterceptor is looping
503
SFSBRetryCaller caller = new SFSBRetryCaller(env, statefulSession, getLog());
504       executeRetryTest(caller);
505       
506       getLog().debug("StatefulSession: Retry successful");
507    }
508    
509    protected Properties JavaDoc getNamingProperties(String JavaDoc namingFactoryClass, boolean autoDiscovery)
510       throws Exception JavaDoc
511    {
512       String JavaDoc[] urls = getHANamingURLs();
513       Properties JavaDoc env = new Properties JavaDoc();
514       env.setProperty(Context.INITIAL_CONTEXT_FACTORY, namingFactoryClass);
515       env.setProperty(Context.PROVIDER_URL, urls[0]);
516       if (!autoDiscovery)
517          env.setProperty("jnp.disableDiscovery", "true");
518       return env;
519    }
520    
521    protected String JavaDoc getJndiSuffix()
522    {
523       return "_Retry";
524    }
525    
526    protected void configureCluster() throws Exception JavaDoc
527    {
528       RMIAdaptor[] adaptors = getAdaptors();
529    
530       if (!isDeployed0())
531    {
532          deploy(adaptors[0], "test-retry.ear");
533          getLog().debug("Deployed test-retry.ear on server0");
534          setDeployed0(true);
535    }
536       if (isDeployed1())
537       {
538          undeploy(adaptors[1], "test-retry.ear");
539          getLog().debug("Undeployed test-retry.ear on server1");
540          setDeployed1(false);
541       }
542    
543       sleep(2000);
544    }
545    
546    protected void reconfigureCluster() throws Exception JavaDoc
547    {
548       RMIAdaptor[] adaptors = getAdaptors();
549       deploy(adaptors[1], "test-retry.ear");
550       setDeployed1(true);
551       
552       sleep(2000);
553       
554       undeploy(adaptors[0], "test-retry.ear");
555       setDeployed0(false);
556       
557       sleep(2000);
558    }
559
560
561    protected void tearDown() throws Exception JavaDoc
562    {
563       super.tearDown();
564       
565       if (System.getProperty("JBossCluster-DoFail") != null)
566          System.setProperty("JBossCluster-DoFail", "false");
567       
568       RMIAdaptor[] adaptors = getAdaptors();
569       if (isDeployed0())
570       {
571          undeploy(adaptors[0], "test-retry.ear");
572          getLog().debug("Undeployed test-retry.ear on server0");
573          setDeployed0(false);
574 }
575       if (isDeployed1())
576       {
577          undeploy(adaptors[1], "test-retry.ear");
578          getLog().debug("Undeployed test-retry.ear on server1");
579          setDeployed1(false);
580       }
581    }
582
583    protected boolean isDeployed0()
584    {
585       return deployed0;
586    }
587
588    protected void setDeployed0(boolean deployed)
589    {
590       deployed0 = deployed;
591    }
592
593    protected boolean isDeployed1()
594    {
595       return deployed1;
596    }
597
598    protected void setDeployed1(boolean deployed)
599    {
600       deployed1 = deployed;
601    }
602
603 }
604
Popular Tags