KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > jtm > TransactionServiceImpl


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999-2005 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: TransactionServiceImpl.java,v 1.40 2005/07/13 06:28:35 durieuxp Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.jonas.jtm;
27
28 import java.rmi.RemoteException JavaDoc;
29
30 import javax.management.MBeanServer JavaDoc;
31 import javax.management.ObjectName JavaDoc;
32 import javax.management.modelmbean.ModelMBean JavaDoc;
33 import javax.naming.Context JavaDoc;
34 import javax.naming.InitialContext JavaDoc;
35 import javax.naming.NamingException JavaDoc;
36 import javax.transaction.UserTransaction JavaDoc;
37 import javax.transaction.xa.Xid JavaDoc;
38
39 import org.apache.commons.modeler.ManagedBean;
40 import org.apache.commons.modeler.Registry;
41
42 import org.objectweb.jotm.Current;
43 import org.objectweb.jotm.TransactionFactory;
44 import org.objectweb.jotm.TransactionFactoryImpl;
45 import org.objectweb.transaction.jta.TransactionManager;
46
47 import org.objectweb.jonas.common.Log;
48 import org.objectweb.jonas.jmx.J2eeObjectName;
49 import org.objectweb.jonas.jmx.JmxService;
50 import org.objectweb.jonas.jmx.JonasObjectName;
51 import org.objectweb.jonas.management.JonasMBeanTools;
52 import org.objectweb.jonas.naming.NamingManager;
53 import org.objectweb.jonas.service.AbsServiceImpl;
54 import org.objectweb.jonas.service.ServiceException;
55 import org.objectweb.jonas.service.ServiceManager;
56
57 import org.objectweb.util.monolog.api.BasicLevel;
58 import org.objectweb.util.monolog.api.Logger;
59
60 /**
61  * Transaction Service implementation.
62  * This singleton class must exist in each jonas server.
63  * This class manages a unique Current object that implements both
64  * TransactionManager and UserTransaction interfaces.
65  * @author Philippe Durieux
66  * Contributor(s): Adriana Danes
67  */

68 public class TransactionServiceImpl extends AbsServiceImpl implements TransactionService, TransactionServiceImplMBean {
69
70     private static Logger logger = null;
71
72     /**
73      * Service name as used to label configuration properties
74      */

75     public static final String JavaDoc SERVICE_NAME = "jtm";
76     // Transaction Service configuration properties
77
/**
78      * name of the 'timeout' configuration parameter
79      */

80     static final String JavaDoc TIMEOUT = "jonas.service.jtm.timeout";
81     /**
82      * name of the 'remote' configuration parameter
83      */

84     static final String JavaDoc REMOTE = "jonas.service.jtm.remote";
85     /**
86      * name of the 'class' configuration parameter
87      */

88     static final String JavaDoc CLASS = "jonas.service.jtm.class";
89
90     /**
91     /* TM factory may be local or remote.
92     /* The TM factory is used by the JTA implementation when transactions
93     /* are distributed among several JVM (JOnAS Server or applet client)
94      */

95     private TransactionFactory tm = null;
96
97     /**
98      * Unique Current object implementing the standard TransactionManager
99     /* set to null while service is not started.
100      */

101     private Current current = null;
102
103     private Xid JavaDoc[] myXid = null;
104
105     // Configuration information used to start the Transaction service
106
private int timeout;
107     private boolean jtmlocal;
108     private InitialContext JavaDoc ictx;
109
110     /**
111      * Registry object containing the information declared in mbean-descriptors configuration files
112      */

113     private Registry oRegistry = null;
114     /**
115      * Reference of the current MBean server needed to register MBeans
116      */

117     private MBeanServer JavaDoc mbeanServer = null;
118     // -------------------------------------------------------------------
119
// JOnAS Service Implementation
120
// -------------------------------------------------------------------
121

122     /**
123      * Init the Service.
124      * Configuration information is passed thru a Context object.
125      * @param ctx naming context containing configuration parameters
126      * @throws ServiceException if service initialization failes
127      */

128     public void doInit(Context JavaDoc ctx) throws ServiceException {
129
130         // get logger for this service
131
logger = Log.getLogger(Log.JONAS_SERVER_PREFIX);
132         super.initLogger(Log.getLogger(Log.JONAS_MANAGEMENT_PREFIX));
133
134         // Gets the configuration
135
String JavaDoc remote = "false";
136         try {
137             remote = (String JavaDoc) ctx.lookup(REMOTE);
138         } catch (NamingException JavaDoc e) {
139             // No problem if there is no value --> default value
140
}
141         if ((remote != null) && (!remote.equals(""))) {
142             jtmlocal = !remote.equalsIgnoreCase("true");
143         } else {
144             jtmlocal = false;
145         }
146
147         String JavaDoc tstr = "60";
148         try {
149             tstr = (String JavaDoc) ctx.lookup(TIMEOUT);
150         } catch (NamingException JavaDoc e) {
151             // No problem if there is no value --> default value
152
}
153         if ((tstr != null) && (!tstr.equals(""))) {
154             timeout = (new Integer JavaDoc(tstr)).intValue();
155         } else {
156             timeout = 60;
157         }
158
159         // Get the JMX Server via JMX Service
160
try {
161             mbeanServer =
162                 ((JmxService) ServiceManager.getInstance().getJmxService()).getJmxServer();
163         } catch (Exception JavaDoc e) {
164             // the JMX service may not be started
165
mbeanServer = null;
166         }
167         // Use Jakarta Common Modeler API
168
oRegistry = JonasMBeanTools.getRegistry();
169
170         if (logger.isLoggable(BasicLevel.DEBUG)) {
171             logger.log(BasicLevel.DEBUG, "TransactionService initialized. Timeout = " + timeout);
172         }
173     }
174
175     /**
176      * Start the Service
177      * Initialization of the service is already done.
178      * @throws ServiceException if service start fails
179      */

180     public void doStart() throws ServiceException {
181         try {
182             ictx = NamingManager.getInstance().getInitialContext();
183         } catch (NamingException JavaDoc e) {
184             logger.log(BasicLevel.ERROR, "TransactionService: Cannot get InitialContext:\n" + e);
185             throw new ServiceException("TransactionService: Cannot get InitialContext", e);
186         }
187
188         // Gets the Distributed Transaction Manager (JTM)
189
if (jtmlocal) {
190             // Creates a JTM locally in this server
191
if (logger.isLoggable(BasicLevel.DEBUG)) {
192                 logger.log(BasicLevel.DEBUG, "working with a colocated Transaction Manager ");
193             }
194
195             // TODO: Recovery of the JTM
196

197             // Creates the ControlFactory and register it in JNDI.
198
try {
199                 if (logger.isLoggable(BasicLevel.DEBUG)) {
200                     logger.log(BasicLevel.DEBUG, "Create and register TM factory");
201                 }
202                 tm = new TransactionFactoryImpl();
203                 ictx.rebind("TMFactory", tm);
204             } catch (RemoteException JavaDoc e) {
205                 logger.log(BasicLevel.ERROR, "TransactionService: Cannot create TransactionFactory:\n" + e);
206                 throw new ServiceException("TransactionService: Cannot create TransactionFactory",
207                                            e);
208             } catch (NamingException JavaDoc e) {
209                 logger.log(BasicLevel.ERROR, "TransactionService: Cannot rebind TM:\n" + e);
210                 throw new ServiceException("TransactionService: Cannot rebind TM", e);
211             }
212         } else {
213             // JTM is remote, finds it by JNDI
214
if (logger.isLoggable(BasicLevel.DEBUG)) {
215                 logger.log(BasicLevel.DEBUG, "working with a remote Transaction Manager ");
216             }
217             final int maxloops = 5;
218             for (int i = 0; i <= maxloops; i++) {
219                 try {
220                     tm = (TransactionFactory) ictx.lookup("TMFactory");
221                     break;
222                 } catch (NamingException JavaDoc e) {
223                     if (i < maxloops) {
224                         logger.log(BasicLevel.WARN, "Cannot get TM factory - retrying...");
225                         try {
226                             Thread.sleep(2000 * (i + 1));
227                         } catch (InterruptedException JavaDoc e2) {
228                             throw new ServiceException("Cannot get TM factory", e2);
229                         }
230                     } else {
231                         logger.log(BasicLevel.ERROR, "TransactionService: Cannot get TM factory:\n" + e);
232                         throw new ServiceException("TransactionService: Cannot get TM factory", e);
233                     }
234                 }
235             }
236         }
237
238         // Create and init the unique Current object.
239
// Current is the local TransactionManager. It must be present in every
240
// jonas server and implements the JTA TransactionManager interface.
241
//
242
// In case of a JTM standalone:
243
// We must create the current only to export it via JNDI for clients
244
// that want to get UserTransaction.
245
current = new Current(tm);
246         setTimeout(timeout);
247
248        try {
249             if (mbeanServer != null) {
250                 // Register TransactionService MBean : only used by jo,nasAdmin's tree builder
251
mbeanServer.registerMBean(this, JonasObjectName.transactionService());
252
253                 // JTAResource implemented by this Service
254
// ------------------------------------------------
255
try {
256                     String JavaDoc sJTAResourceName = "JTAResource";
257                     ObjectName JavaDoc onJTAResource =
258                         J2eeObjectName.JTAResource(getDomainName(),
259                                                    getJonasServerName(),
260                                                    sJTAResourceName);
261                     JTAResource jtaResourceMBean = new JTAResource(onJTAResource.toString(), this,
262                             new Integer JavaDoc(timeout),
263                             new Boolean JavaDoc(jtmlocal),
264                             new Integer JavaDoc(tm.getPortNumber()),
265                             tm.getHostName());
266                     ManagedBean oManaged = oRegistry.findManagedBean("JTAResource");
267                     ModelMBean JavaDoc oMBean = oManaged.createMBean(jtaResourceMBean);
268                     if (logger.isLoggable(BasicLevel.DEBUG)) {
269                         logger.log(BasicLevel.DEBUG, "JTAResource J2EEResource created");
270                     }
271                     mbeanServer.registerMBean(oMBean, onJTAResource);
272                 } catch (Exception JavaDoc e) {
273                     e.printStackTrace();
274                     logger.log(BasicLevel.ERROR, "JOnAS: Cannot register JTAResource mBean" + e);
275                 }
276             }
277         } catch (ServiceException se) {
278             // Jmx Service not available, do nothing
279
} catch (Exception JavaDoc e) {
280             logger.log(BasicLevel.ERROR, "TransactionService: Cannot start the Transaction service:\n" + e);
281             throw new ServiceException("TransactionService: Cannot start the Transaction service", e);
282         }
283
284         if (logger.isLoggable(BasicLevel.DEBUG)) {
285             logger.log(BasicLevel.DEBUG, "TransactionService started, default timeout= " + timeout);
286         }
287
288
289         // Start recovery
290
try {
291             Current.getTransactionRecovery().startResourceManagerRecovery();
292         } catch (Exception JavaDoc ex) {
293             if (logger.isLoggable(BasicLevel.DEBUG)) {
294                 logger.log(BasicLevel.DEBUG, "JOTM startResourceManagerRecovery failed: ", ex);
295             }
296             throw new ServiceException("Cannot start resource manager recovery", ex);
297         }
298     }
299
300     /**
301      * Stop the transaction service
302      * Not already implementated
303      * @throws ServiceException if the service stop fails
304      */

305     public void doStop() throws ServiceException {
306         if (logger.isLoggable(BasicLevel.DEBUG)) {
307             logger.log(BasicLevel.DEBUG, "Stop of TransactionService not already implemented");
308         }
309     }
310
311     // -------------------------------------------------------------------
312
// TransactionService Implementation
313
// -------------------------------------------------------------------
314

315     /**
316      * Gets the Current object instance
317      * @return the current object
318      */

319     public Current getCurrent() {
320         return current;
321     }
322
323     /**
324      * Gets the TransactionManager object instance
325      * @return the transaction manager
326      */

327     public TransactionManager getTransactionManager() {
328         return (TransactionManager) current;
329     }
330
331     /**
332      * Gets the UserTransaction object instance
333      * @return the user transaction object
334      */

335     public UserTransaction JavaDoc getUserTransaction() {
336         return (UserTransaction JavaDoc) current;
337     }
338
339     /**
340      * Gets the TransactionFactory object (JTM factory)
341      * @return the transaction factory (JTM object)
342      */

343     public TransactionFactory getTransactionFactory() {
344         return tm;
345     }
346
347     public int getTimeout() {
348         return current.getDefaultTimeout();
349     }
350     
351     /**
352      * Sets the default transaction timeout and register Current in JNDI
353      * @param t new value for time-out
354      */

355     public void setTimeout(int t) {
356
357         if (logger.isLoggable(BasicLevel.DEBUG)) {
358             logger.log(BasicLevel.DEBUG, "" + t);
359         }
360         current.setDefaultTimeout(t);
361
362         // Register a UserTransactionFactory in JNDI.
363
// Only if we are inside the JTM
364
if (jtmlocal) {
365             try {
366                 if (logger.isLoggable(BasicLevel.DEBUG)) {
367                     logger.log(BasicLevel.DEBUG, "Register UserTransactionFactory");
368                 }
369                 NamingManager.getInstance().getInitialContext().rebind("javax.transaction.UserTransaction", current);
370             } catch (NamingException JavaDoc e) {
371                 logger.log(BasicLevel.ERROR, "Cannot rebind UserTransaction:" + e);
372             }
373         }
374
375     }
376
377     /**
378      * Get begun transactions number
379      * @return total number of begun transactions
380      */

381     protected int getTotalBegunTransactions() {
382         return current.getTotalBegunTransactions();
383     }
384
385     /**
386      * Get committed transactions number
387      * @return total number of committed transactions
388      */

389     protected int getTotalCommittedTransactions() {
390         return current.getTotalCommittedTransactions();
391     }
392
393     /**
394      * Get current transactions number
395      * @return total number of current transactions
396      */

397     protected int getTotalCurrentTransactions() {
398         return current.getTotalCurrentTransactions();
399     }
400
401     /**
402      * Get expired transactions number
403      * @return total number of expired transactions
404      */

405     protected int getTotalExpiredTransactions() {
406         return current.getTotalExpiredTransactions();
407     }
408
409     /**
410      * Get rollebacked transactions number
411      * @return total number of rollbacked transactions
412      */

413     protected int getTotalRolledbackTransactions() {
414         return current.getTotalRolledbackTransactions();
415     }
416
417    /**
418     * Reset all transaction counters
419     */

420     protected void resetAllTxTotalCounters() {
421         current.resetAllTxTotalCounters();
422     }
423
424     /**
425      * Get all currently executing Xids
426      * @return total number of executing Xids
427      */

428     protected Xid JavaDoc [] getAllActiveXids() {
429         return (current.getAllXid());
430     }
431
432     /**
433      * Get all currently executing transactions
434      * @return total number of executing transaction
435      */

436     protected String JavaDoc [] getAllActiveTx() {
437         String JavaDoc [] mysArray;
438
439         mysArray = current.getAllTx();
440         return mysArray;
441     }
442
443     /**
444      * Get all transactions that require administrator recovery action
445      * @return Transactions that require administrator recovery action
446      */

447     protected String JavaDoc [] getAllRecoveryTx() {
448         String JavaDoc [] mysArray;
449
450         mysArray = current.getAllRcTx();
451         return mysArray;
452     }
453
454     /**
455      * Get all XAResoures of a transaction that require administrator recovery action
456      * @return XAResources that require administrator recovery action
457      */

458     protected String JavaDoc [] getAllXAResource(String JavaDoc xtx) {
459         String JavaDoc [] mysArray;
460
461         mysArray = current.getAllXaTx(xtx);
462         return mysArray;
463     }
464
465     /**
466      * @return Returns all XAResources that require administrator recovery action.
467      */

468     protected int commitXAResource(String JavaDoc xatx) {
469         int commiterror;
470         commiterror = current.actionXAResource("commit", xatx);
471         return commiterror;
472     }
473
474     /**
475      * @return Returns all XAResources that require administrator recovery action.
476      */

477     protected int rollbackXAResource(String JavaDoc xatx) {
478         int rollbackerror;
479         rollbackerror = current.actionXAResource("rollback", xatx);
480         return rollbackerror;
481     }
482
483     /**
484      * @return Returns all XAResources that require administrator recovery action.
485      */

486     protected int forgetXAResource(String JavaDoc xatx) {
487         int forgeterror;
488         forgeterror = current.actionXAResource("forget", xatx);
489         return forgeterror;
490     }
491 }
492
493
Popular Tags