KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > jca > mbean > MTOperation


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 package org.jboss.test.jca.mbean;
23
24 import java.io.Serializable JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Set JavaDoc;
30
31 import javax.naming.InitialContext JavaDoc;
32 import javax.resource.cci.Connection JavaDoc;
33 import javax.resource.cci.ConnectionFactory JavaDoc;
34 import javax.sql.DataSource JavaDoc;
35 import javax.transaction.Synchronization JavaDoc;
36 import javax.transaction.Transaction JavaDoc;
37 import javax.transaction.TransactionManager JavaDoc;
38
39 import org.jboss.logging.Logger;
40 import org.jboss.tm.TxUtils;
41
42 /**
43  * MultiThreaded Operations that can be executed concurrently.
44  *
45  * Based on Operation class.
46  *
47  * @author <a HREF="dimitris@jboss.org">Dimitris Andreadis</a>
48  * @version $Revision: 37406 $
49  */

50 public class MTOperation implements Serializable JavaDoc
51 {
52    // Static Data ---------------------------------------------------
53

54    /** The serialVersionUID */
55    private static final long serialVersionUID = 1L;
56    
57    /** Available Operations */
58    public static final int TM_GET_STATUS = 0;
59    public static final int TM_BEGIN = 1;
60    public static final int TM_SUSPEND = 2;
61    public static final int TM_RESUME = 3;
62    public static final int TM_COMMIT = 4;
63    public static final int TX_COMMIT = 5;
64    public static final int TX_REGISTER_SYNC = 6;
65    
66    public static final int CF_LOOKUP = 10;
67    public static final int CF_BY_TX_LOOKUP = 11;
68    public static final int CF_GET_CONN = 12;
69    public static final int CN_CLOSE_CONN = 13;
70    
71    public static final int DS_TEST_LOOKUP = 15;
72    public static final int DS_DEFAULT_LOOKUP = 16;
73    public static final int DS_GET_CONN = 17;
74    public static final int DS_CLOSE_CONN = 18;
75    
76    public static final int XX_SLEEP_200 = 20;
77    public static final int XX_SLEEP_RANDOM = 21;
78    public static final int XX_POST_SIGNAL = 22;
79    public static final int XX_WAIT_FOR_SIGNAL = 23;
80    public static final int XX_WAIT_FOR_TX = 24;
81    public static final int XX_WAIT_FOR_CONN = 25;
82    
83    /** The Logger */
84    protected static Logger log;
85
86    /** TM instance */
87    protected static TransactionManager JavaDoc tm = null;
88    
89    /** Shared connections */
90    protected static Map JavaDoc connections = Collections.synchronizedMap(new HashMap JavaDoc());
91    
92    /** Active Transactions */
93    protected static Map JavaDoc transactions = Collections.synchronizedMap(new HashMap JavaDoc());
94    
95    /** Used for signaling between threads */
96    protected static Set JavaDoc signals = Collections.synchronizedSet(new HashSet JavaDoc());
97    
98    /** Shared reference to a connection factory */
99    protected static ConnectionFactory JavaDoc cf = null;
100    
101    /**Shared reference to a DataSource */
102    protected static DataSource JavaDoc ds = null;
103    
104    /** Set when the first unexpected throwable is encounter in any thread */
105    protected static boolean testMarkedForExit;
106    
107    // Protected Data ------------------------------------------------
108

109    /** An id for this transaction */
110    protected Integer JavaDoc id;
111    
112    /** The operation to execute */
113    protected int op;
114    
115    /** Set when an exception is expected */
116    protected Throwable JavaDoc throwable;
117    
118    // Static Methods ------------------------------------------------
119

120    /**
121     * Setup static objects for the test
122     */

123    public static void init(Logger log) throws Exception JavaDoc
124    {
125       MTOperation.log = log;
126       
127       if (getTM().getTransaction() != null)
128       {
129          throw new IllegalStateException JavaDoc("Invalid thread association " + getTM().getTransaction());
130       }
131       connections.clear();
132       transactions.clear();
133       signals.clear();
134       
135       // clear the exit flag
136
setTestMarkedForExit(false);
137    }
138
139    /**
140     * Lazy TransactionManager lookup
141     */

142    public static TransactionManager JavaDoc getTM() throws Exception JavaDoc
143    {
144       if (tm == null)
145       {
146          tm = (TransactionManager JavaDoc) new InitialContext JavaDoc().lookup("java:/TransactionManager");
147       }
148       return tm;
149    }
150    
151    /**
152     * Cleanup
153     */

154    public static void destroy()
155    {
156       connections.clear();
157       transactions.clear();
158       signals.clear();
159    }
160    
161    /**
162     * Returns true if the test is marked for exit
163     */

164    public static boolean isTestMarkedForExit()
165    {
166       return testMarkedForExit;
167    }
168    
169    /**
170     * Tell the threads to exit
171     */

172    public static void setTestMarkedForExit(boolean testMarkedForExit)
173    {
174       MTOperation.testMarkedForExit = testMarkedForExit;
175    }
176    
177    /**
178     * Used by waiting threads to stop execution
179     *
180     * @throws Exception if the test if marked to exit
181     */

182    public static void checkTestMarkedForExit() throws Exception JavaDoc
183    {
184       if (testMarkedForExit)
185       {
186          throw new MarkedForExitException();
187       }
188    }
189    
190    /**
191     * Exception used for early existing
192     */

193    private static class MarkedForExitException extends Exception JavaDoc
194    {
195       // empty
196
}
197    
198    // Constructors --------------------------------------------------
199

200    public MTOperation(int op)
201    {
202       this(op, 0);
203    }
204    
205    public MTOperation(int op, int id)
206    {
207       this.id = new Integer JavaDoc(id);
208       this.op = op;
209    }
210
211    public MTOperation(int op, int id, Throwable JavaDoc throwable)
212    {
213       this.id = new Integer JavaDoc(id);
214       this.op = op;
215       this.throwable = throwable;
216    }
217    
218    // Public Methods ------------------------------------------------
219

220    public void perform() throws Exception JavaDoc
221    {
222       Throwable JavaDoc caught = null;
223       try
224       {
225          switch (op)
226          {
227             case TM_GET_STATUS:
228                tmGetStatus();
229                break;
230             
231             case TM_BEGIN:
232                tmBegin();
233                break;
234                
235             case TM_SUSPEND:
236                tmSuspend();
237                break;
238                
239             case TM_RESUME:
240                tmResume();
241                break;
242                
243             case TM_COMMIT:
244                tmCommit();
245                break;
246                
247             case TX_COMMIT:
248                txCommit();
249                break;
250                
251             case TX_REGISTER_SYNC:
252                txRegisterSync();
253                break;
254                
255             case XX_SLEEP_200:
256                xxSleep200();
257                break;
258                
259             case XX_SLEEP_RANDOM:
260                xxSleepRandom();
261                break;
262                
263             case XX_POST_SIGNAL:
264                xxPostSignal();
265                break;
266                
267             case XX_WAIT_FOR_SIGNAL:
268                xxWaitForSignal();
269                break;
270                
271             case XX_WAIT_FOR_TX:
272                xxWaitForTx();
273                break;
274                
275             case XX_WAIT_FOR_CONN:
276                xxWaitForConn();
277                break;
278                
279             case CF_LOOKUP:
280                cfLookup();
281                break;
282                
283             case CF_BY_TX_LOOKUP:
284                cfByTxLookup();
285                break;
286                
287             case DS_TEST_LOOKUP:
288                dsTestLookup();
289                break;
290                
291             case DS_DEFAULT_LOOKUP:
292                dsDefaultLookup();
293                break;
294                
295             case DS_GET_CONN:
296                dsGetConn();
297                break;
298                
299             case DS_CLOSE_CONN:
300                dsCloseConn();
301                break;
302                
303             case CF_GET_CONN:
304                cfGetConn();
305                break;
306                
307             case CN_CLOSE_CONN:
308                cnCloseConn();
309                break;
310                
311             default:
312                throw new IllegalArgumentException JavaDoc("Invalid operation " + op);
313          }
314       }
315       catch (MarkedForExitException e)
316       {
317          log.info(tid() + "Early exit");
318          return;
319       }
320       catch (Throwable JavaDoc t)
321       {
322          caught = t;
323       }
324
325       // expected an exception but caught none
326
if (throwable != null && caught == null)
327       {
328          setTestMarkedForExit(true);
329          throw new Exception JavaDoc("Expected throwable ", throwable);
330       }
331       
332       // expected an exception but caught the wrong one
333
if (throwable != null && (throwable.getClass().isAssignableFrom(caught.getClass())) == false)
334       {
335          log.warn("Caught wrong throwable", caught);
336          setTestMarkedForExit(true);
337          throw new Exception JavaDoc("Expected throwable " + throwable + " caught ", caught);
338       }
339       
340       // did not expect an exception bug caught one
341
if (throwable == null && caught != null)
342       {
343          log.warn("Caught unexpected throwable", caught);
344          setTestMarkedForExit(true);
345          throw new Exception JavaDoc("Unexpected throwable ", caught);
346       }
347    }
348
349    public void cfLookup() throws Exception JavaDoc
350    {
351       log.info(tid() + " CF_LOOKUP");
352       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
353       cf = (ConnectionFactory JavaDoc)ctx.lookup("java:JBossTestCF");
354    }
355    
356    public void cfByTxLookup() throws Exception JavaDoc
357    {
358       log.info(tid() + " CF_BY_TX_LOOKUP");
359       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
360       cf = (ConnectionFactory JavaDoc)ctx.lookup("java:JBossTestCFByTx");
361    }
362     
363    public void cfGetConn() throws Exception JavaDoc
364    {
365       log.info(tid() + " CF_GET_CONN (" + id + ")");
366       Connection JavaDoc conn = cf.getConnection();
367       connections.put(id, conn);
368    }
369    
370    public void cnCloseConn() throws Exception JavaDoc
371    {
372       log.info(tid() + " CN_CLOSE_CONN (" + id + ")");
373       Connection JavaDoc conn = (Connection JavaDoc)connections.get(id);
374       conn.close();
375    }
376    
377    public void dsTestLookup() throws Exception JavaDoc
378    {
379       log.info(tid() + " DS_TEST_LOOKUP");
380       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
381       ds = (DataSource JavaDoc)ctx.lookup("java:StatementTestsConnectionDS");
382       
383    }
384    
385    public void dsDefaultLookup() throws Exception JavaDoc
386    {
387       log.info(tid() + " DS_DEFAULT_LOOKUP");
388       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
389       ds = (DataSource JavaDoc)ctx.lookup("java:DefaultDS");
390    }
391    
392    public void dsGetConn() throws Exception JavaDoc
393    {
394       log.info(tid() + " DS_GET_CONN (" + id + ")");
395       java.sql.Connection JavaDoc conn = ds.getConnection();
396       connections.put(id, conn);
397    }
398    
399    public void dsCloseConn() throws Exception JavaDoc
400    {
401       log.info(tid() + " DS_CLOSE_CONN (" + id + ")");
402       java.sql.Connection JavaDoc conn = (java.sql.Connection JavaDoc)connections.get(id);
403       conn.close();
404    }
405    
406    public void tmGetStatus() throws Exception JavaDoc
407    {
408       log.info(tid() + " " + TxUtils.getStatusAsString(getTM().getStatus()));
409    }
410
411    public void tmBegin() throws Exception JavaDoc
412    {
413       log.info(tid() + " TM_BEGIN (" + id + ")");
414       getTM().begin();
415       Transaction JavaDoc tx = getTM().getTransaction();
416       synchronized (transactions)
417       {
418          transactions.put(id, tx);
419          transactions.notifyAll();
420       }
421    }
422    
423    public void tmSuspend() throws Exception JavaDoc
424    {
425       log.info(tid() + " TM_SUSPEND (" + id + ")");
426       Transaction JavaDoc tx = getTM().suspend();
427       transactions.put(id, tx);
428    }
429    
430    public void tmResume() throws Exception JavaDoc
431    {
432       log.info(tid() + " TM_RESUME (" + id + ")");
433       Transaction JavaDoc tx = (Transaction JavaDoc)transactions.get(id);
434       if (tx == null)
435       {
436          throw new IllegalStateException JavaDoc("Tx not found:" + id);
437       }
438       else
439       {
440          getTM().resume(tx);
441       }
442    }
443    
444    public void tmCommit() throws Exception JavaDoc
445    {
446       log.info(tid() + " TM_COMMIT");
447       getTM().commit();
448    }
449    
450    public void txCommit() throws Exception JavaDoc
451    {
452       log.info(tid() + " TX_COMMIT (" + id + ")");
453       Transaction JavaDoc tx = (Transaction JavaDoc)transactions.get(id);
454       if (tx == null)
455       {
456          throw new IllegalStateException JavaDoc("Tx not found: " + id);
457       }
458       else
459       {
460          tx.commit();
461       }
462    }
463    
464    public void txRegisterSync() throws Exception JavaDoc
465    {
466       log.info(tid() + " TX_REGISTER_SYNC (" + id + ")");
467       Transaction JavaDoc tx = (Transaction JavaDoc)transactions.get(id);
468       if (tx == null)
469       {
470          throw new IllegalStateException JavaDoc("Tx not found: " + id);
471       }
472       Synchronization JavaDoc sync = new Synchronization JavaDoc()
473       {
474          public void beforeCompletion()
475          {
476             log.info(tid() + " beforeCompletion() called");
477          }
478          
479          public void afterCompletion(int status)
480          {
481             log.info (tid() + " afterCompletion(" + TxUtils.getStatusAsString(status) + ") called");
482          }
483       };
484       tx.registerSynchronization(sync);
485    }
486    
487    public void xxWaitForTx() throws Exception JavaDoc
488    {
489       log.info(tid() + " XX_WAIT_FOR_TX (" + id + ")");
490       
491       Transaction JavaDoc tx = (Transaction JavaDoc)transactions.get(id);
492       while (tx == null)
493       {
494          checkTestMarkedForExit();
495          
496          log.info(tid() + " Sleeping for 100 msecs");
497          
498          synchronized (transactions)
499          {
500             try
501             {
502                transactions.wait(100);
503             }
504             catch (InterruptedException JavaDoc ignore) {}
505          }
506          tx = (Transaction JavaDoc)transactions.get(id);
507       }
508       log.info(tid() + " Got it");
509    }
510    
511    public void xxWaitForConn() throws Exception JavaDoc
512    {
513       log.info(tid() + " XX_WAIT_FOR_CONN (" + id + ")");
514       
515       boolean contained = connections.containsKey(id);
516       while (contained == false)
517       {
518          checkTestMarkedForExit();
519          
520          log.info(tid() + " Sleeping for 100 msecs");
521          
522          synchronized (connections)
523          {
524             try
525             {
526                connections.wait(100);
527             }
528             catch (InterruptedException JavaDoc ignore) {}
529          }
530          contained = connections.containsKey(id);
531       }
532       log.info(tid() + " Got it");
533    }
534    
535    public void xxSleep200() throws Exception JavaDoc
536    {
537       log.info(tid() + " XX_SLEEP_200");
538       Thread.sleep(200);
539    }
540    
541    public void xxSleepRandom() throws Exception JavaDoc
542    {
543       long random = Math.round((Math.random() * 100));
544       log.info(tid() + " XX_SLEEP_RANDOM (" + random + ")");
545       Thread.sleep(random);
546    }
547    
548    public void xxPostSignal() throws Exception JavaDoc
549    {
550       log.info(tid() + " XX_POST_SIGNAL (" + id + ")");
551       synchronized (signals)
552       {
553          signals.add(id);
554          signals.notifyAll();
555       }
556    }
557    
558    public void xxWaitForSignal() throws Exception JavaDoc
559    {
560       log.info(tid() + " XX_WAIT_FOR_SIGNAL (" + id + ")");
561       
562       boolean posted = signals.contains(id);
563       while (posted == false)
564       {
565          checkTestMarkedForExit();
566          
567          log.info(tid() + " Signal not posted, waiting...");
568          
569          synchronized (signals)
570          {
571             try
572             {
573                signals.wait(100);
574             }
575             catch (InterruptedException JavaDoc ignore) {}
576          }
577          posted = signals.contains(id);
578       }
579       log.info(tid() + " Got it!");
580    }
581    
582    private String JavaDoc tid()
583    {
584       return Thread.currentThread().getName();
585    }
586    
587 }
588
Popular Tags