001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: DataBaseServiceImpl.java 10106 2007-03-28 09:19:07Z durieuxp $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas.dbm;
025:
026: import java.io.FileNotFoundException;
027: import java.util.Collection;
028: import java.util.Enumeration;
029: import java.util.Hashtable;
030: import java.util.List;
031: import java.util.Properties;
032: import java.util.StringTokenizer;
033: import java.util.Vector;
034:
035: import javax.management.InstanceNotFoundException;
036: import javax.management.MBeanRegistrationException;
037: import javax.management.MBeanServer;
038: import javax.management.MalformedObjectNameException;
039: import javax.management.ObjectName;
040: import javax.management.modelmbean.ModelMBean;
041: import javax.naming.Context;
042: import javax.naming.InitialContext;
043: import javax.naming.NamingException;
044:
045: import org.apache.commons.modeler.ManagedBean;
046: import org.apache.commons.modeler.Registry;
047: import org.objectweb.jonas.common.JModule;
048: import org.objectweb.jonas.common.JProp;
049: import org.objectweb.jonas.common.Log;
050: import org.objectweb.jonas.jmx.J2eeObjectName;
051: import org.objectweb.jonas.jmx.JmxService;
052: import org.objectweb.jonas.jmx.JonasObjectName;
053: import org.objectweb.jonas.jtm.TransactionService;
054: import org.objectweb.jonas.management.JonasMBeanTools;
055: import org.objectweb.jonas.service.AbsServiceImpl;
056: import org.objectweb.jonas.service.ServiceException;
057: import org.objectweb.jonas.service.ServiceManager;
058: import org.objectweb.util.monolog.api.BasicLevel;
059: import org.objectweb.util.monolog.api.Logger;
060:
061: /**
062: * DatabaseService acts as a factory for the DataSource objects.
063: * Its goal is to create such objects and to register them in JNDI
064: *
065: * @author Philippe Durieux
066: *
067: * Contributor(s):
068: *
069: * 00/18/04 Jun Inamori (j-office@osa.att.ne.jp)
070: * New implementation of unbindDataSources for closing correctly
071: * all connections at server shutdown.<p>
072: * 03/01/14 Adriana Danes <p>
073: * Highlight Configuration properties
074: * Change createDataSource() signature : take additional argument, the datasource name
075: * Manage binded datasources (mapping of jndi name to datasource name)
076: * Use datasource name for naming MBeans (instead of jndi name)
077: * Modify MBean methods to take into account the previous points.<p>
078: * 03/05/25 Introduce pool size configuration
079: * 04/09/20 Create JSR77 MBeans JDBCResource, JDBCDataSource JDBCDriver
080: */
081: public class DataBaseServiceImpl extends AbsServiceImpl implements
082: DataBaseService, DataBaseServiceImplMBean {
083:
084: static private Logger logger = null;
085:
086: // List of DataSource in use.
087: private Vector cmList = new Vector(); // ConnectionManager
088:
089: // Binded Datasource (jndi name -> datasource name)
090: private Hashtable bindedDatasources = new Hashtable();
091:
092: // Names of the DataSource to create when starting the DataBase service
093: private Vector dataSourceNames = new Vector();
094:
095: // Transaction Service reference
096: private TransactionService transactionService = null;
097:
098: // Initial Context for Naming
099: private Context ictx = null;
100:
101: // The DataBase service configuration parameters
102: static final String DATASOURCES = "jonas.service.dbm.datasources";
103: static final String CLASS = "jonas.service.dbm.class";
104:
105: // The Datasource configuration parameters
106: static final String NAME = "datasource.name"; // JNDI name of the datasource
107: static final String CLASSNAME = "datasource.classname";
108: static final String DEF_CLASSNAME = "no class name";
109: static final String URL = "datasource.url";
110: static final String DEF_URL = "no url";
111: static final String DESCRIPTION = "datasource.description";
112: static final String DEF_DESCRIPTION = "no desc";
113: static final String USERNAME = "datasource.username";
114: static final String DEF_USERNAME = "";
115: static final String PASSWORD = "datasource.password";
116: static final String DEF_PASSWORD = "";
117: static final String ISOLATIONLEVEL = "datasource.isolationlevel";
118: static final String DEF_ISOLATIONLEVEL = "";
119: static final String MAPPERNAME = "datasource.mapper";
120: static final String DEF_MAPPERNAME = "rdb";
121:
122: // The ConnectionManager configuration parameters
123: public static final String CONNCHECKLEVEL = "jdbc.connchecklevel";
124: static final String DEF_CONNCHECKLEVEL = "1";
125: public static final String CONNMAXAGE = "jdbc.connmaxage";
126: static final String DEF_CONNMAXAGE = "1440";
127: public static final String MAXOPENTIME = "jdbc.maxopentime";
128: static final String DEF_MAXOPENTIME = "1440";
129: public static final String CONNTESTSTMT = "jdbc.connteststmt";
130: static final String DEF_CONNTESTSTMT = "SELECT 1";
131: public static final String PSTMTMAX = "jdbc.pstmtmax";
132: static final String DEF_PSTMTMAX = "12";
133: static final String MINCONPOOL = "jdbc.minconpool";
134: static final String DEF_MINCONPOOL = "0";
135: static final String MAXCONPOOL = "jdbc.maxconpool";
136: static final String DEF_MAXCONPOOL = "-1";
137: static final String MAXWAITTIME = "jdbc.maxwaittime";
138: static final String DEF_MAXWAITTIME = "10";
139: static final String MAXWAITERS = "jdbc.maxwaiters";
140: static final String DEF_MAXWAITERS = "1000";
141: static final String SAMPLINGPERIOD = "jdbc.samplingperiod";
142: static final String DEF_SAMPLINGPERIOD = "60";
143:
144: // JSR 77 variables
145: // ----------------
146: /**
147: * Our naming convention for JDBCResource ObjectName (value of the 'name' key property)
148: */
149: public static final String JDBCResourceName = "JDBCResource";
150: /**
151: * Reference of the JDBCResource MBeans
152: */
153: private JDBCResource jdbcResourceMBean = null;
154: private Registry oRegistry = null;
155: private ManagedBean oManaged = null;
156: private ModelMBean oMBean = null;
157: private MBeanServer mbeanServer = null;
158: private String domainName = null;
159: private String serverName = null;
160:
161: // -------------------------------------------------------------------
162: // Service Implementation
163: // -------------------------------------------------------------------
164:
165: /**
166: * Initialization of the DataBase service.
167: * Configuration information is passed thru a Context object.
168: */
169: public void doInit(Context ctx) throws ServiceException {
170: logger = Log.getLogger(Log.JONAS_DBM_PREFIX);
171: // Avoid using NamingManager here: performance is not a goal here.
172: try {
173: ictx = new InitialContext();
174: } catch (NamingException e) {
175: logger
176: .log(BasicLevel.ERROR,
177: "Cannot create initial context when DataBase service initializing");
178: throw new ServiceException(
179: "Cannot create initial context when DataBase service initializing",
180: e);
181: }
182:
183: // Get the list of the datasource names
184: String ds = null;
185: try {
186: ds = (String) ctx.lookup(DATASOURCES);
187: } catch (NamingException e) {
188: // No problem if there is no value for 'datasources'
189: logger.log(BasicLevel.INFO, "No value set for Datasource:"
190: + e);
191: }
192: if (ds != null) {
193: StringTokenizer st = new StringTokenizer(ds, ",");
194: while (st.hasMoreTokens()) {
195: dataSourceNames.add(st.nextToken().trim());
196: }
197: }
198:
199: // Get un reference to the Transaction service
200: try {
201: transactionService = (TransactionService) ServiceManager
202: .getInstance().getTransactionService();
203: } catch (ServiceException se) {
204: logger.log(BasicLevel.ERROR,
205: "Cannot get the Transaction service: ");
206: throw se;
207: } catch (Exception e) {
208: logger.log(BasicLevel.ERROR,
209: "Cannot get the Transaction service");
210: throw new ServiceException(
211: "Cannot get the Transaction service: ", e);
212: }
213:
214: // Get the JMX Server via JMX Service
215: try {
216: mbeanServer = ((JmxService) ServiceManager.getInstance()
217: .getJmxService()).getJmxServer();
218: } catch (Exception e) {
219: // the JMX service may not be started
220: mbeanServer = null;
221: }
222: // Use Jakarta Common Modeler API
223: oRegistry = JonasMBeanTools.getRegistry();
224: if (logger.isLoggable(BasicLevel.DEBUG)) {
225: logger.log(BasicLevel.DEBUG, "DataBaseService initialized");
226: }
227: }
228:
229: /**
230: * Starting DataBase service
231: * Initialization of the service is already done.
232: */
233: public void doStart() throws ServiceException {
234: logger.log(BasicLevel.DEBUG, "Starting DataBase service");
235: /*
236: * Create JDBCResource MBean associated by the dbm service.
237: * This bean has to be created before the creation of the connection manager objects
238: * beacuse the creation of cms implies the creation of JDBCDataSource MBeans to
239: * be attached to the JDBCResource MBeans
240: */
241: domainName = getDomainName();
242: serverName = getJonasServerName();
243: if (mbeanServer != null) {
244: try {
245: ObjectName onJDBCResource = J2eeObjectName
246: .JDBCResource(domainName, serverName,
247: JDBCResourceName);
248: jdbcResourceMBean = new JDBCResource(onJDBCResource
249: .toString());
250: oManaged = oRegistry.findManagedBean("JDBCResource");
251: oMBean = oManaged.createMBean(jdbcResourceMBean);
252: if (logger.isLoggable(BasicLevel.DEBUG)) {
253: logger.log(BasicLevel.DEBUG,
254: "JDBResource J2EEResource created");
255: }
256: mbeanServer.registerMBean(oMBean, onJDBCResource);
257: } catch (Exception e) {
258: logger.log(BasicLevel.ERROR,
259: "JOnAS: Cannot register JDBCResource mBean", e);
260: }
261: }
262:
263: // Creates connection managers for each datasource
264: String dsName = null;
265: for (int i = 0; i < dataSourceNames.size(); i++) {
266: dsName = (String) dataSourceNames.elementAt(i);
267: try {
268: JProp prop = JProp.getInstance(dsName);
269: if (logger.isLoggable(BasicLevel.DEBUG)) {
270: logger.log(BasicLevel.DEBUG, "Creating Datasource "
271: + dsName);
272: }
273: createDataSource(dsName, prop.getConfigFileEnv());
274: } catch (Exception e) {
275: JProp.removeInstance(dsName);
276: logger.log(BasicLevel.ERROR,
277: "JOnAS: Cannot create datasource: '" + dsName
278: + "'", e);
279: logger.log(BasicLevel.ERROR, "Please check if "
280: + dsName + ".properties is available");
281: }
282: }
283:
284: // Register DataBaseService MBean
285: try {
286: mbeanServer.registerMBean(this , JonasObjectName
287: .databaseService());
288: } catch (ServiceException se) {
289: // Jmx Service not available, do nothing
290: } catch (Exception e) {
291: logger
292: .log(BasicLevel.ERROR,
293: "DataBaseService: Cannot start the DataBase service");
294: throw new ServiceException(
295: "DataBaseService: Cannot start the DataBase service",
296: e);
297: }
298: if (logger.isLoggable(BasicLevel.DEBUG)) {
299: logger.log(BasicLevel.DEBUG, "DataBaseService started");
300: }
301: }
302:
303: /**
304: * Stopping DataBase service
305: * Unbind Datasource
306: */
307: public void doStop() throws ServiceException {
308: try {
309: unbindDataSources();
310: } catch (NamingException e) {
311: logger.log(BasicLevel.ERROR, "Cannot unbind datasources");
312: throw new ServiceException("Cannot unbind datasources ", e);
313: }
314:
315: try {
316: if (mbeanServer != null) {
317: // unregister DatabaseService MBean
318: mbeanServer.unregisterMBean(JonasObjectName
319: .databaseService());
320: // unregister JDBCResource
321: ObjectName onJDBCResource = J2eeObjectName
322: .JDBCResource(domainName, serverName,
323: JDBCResourceName);
324: mbeanServer.unregisterMBean(onJDBCResource);
325: }
326: } catch (ServiceException se) {
327: // Jmx Service not available, do nothing
328: } catch (Exception e) {
329: logger.log(BasicLevel.ERROR,
330: "EJBService: Cannot stop the DataBase service");
331: throw new ServiceException(
332: "DataBaseService: Cannot stop the DataBase service",
333: e);
334: }
335: if (logger.isLoggable(BasicLevel.DEBUG)) {
336: logger.log(BasicLevel.DEBUG, "DataBaseService stopped");
337: }
338: }
339:
340: // -------------------------------------------------------------------
341: // DataBaseService Implementation
342: // -------------------------------------------------------------------
343:
344: /**
345: * Creates a ConnectionManager (implementation of sql.dataSource).
346: * @param datasourceName - datasource name
347: * @param dsd - a set of properties that describes a dataSource and the ConnectionPool
348: */
349: public void createDataSource(String datasourceName, Properties dsd)
350: throws Exception {
351: // Get properties common to all DataSource types
352: String dsName = dsd.getProperty(NAME); // JDNI name of the datasource
353: if (dsName != null) {
354: dsName = dsName.trim();
355: } else {
356: logger.log(BasicLevel.ERROR, "");
357: throw new ServiceException(
358: "Cannot create datasource as JNDI name not provided");
359: }
360: String className = dsd.getProperty(CLASSNAME, DEF_CLASSNAME)
361: .trim();
362: String url = dsd.getProperty(URL, DEF_URL).trim();
363: String description = dsd.getProperty(DESCRIPTION,
364: DEF_DESCRIPTION).trim();
365: String user = dsd.getProperty(USERNAME, DEF_USERNAME).trim();
366: String password = dsd.getProperty(PASSWORD, DEF_PASSWORD)
367: .trim();
368: String connCheckLevel = dsd.getProperty(CONNCHECKLEVEL,
369: DEF_CONNCHECKLEVEL).trim();
370: String connMaxAge = dsd.getProperty(CONNMAXAGE, DEF_CONNMAXAGE)
371: .trim();
372: String maxOpenTime = dsd.getProperty(MAXOPENTIME,
373: DEF_MAXOPENTIME).trim();
374: String minconpool = dsd.getProperty(MINCONPOOL, DEF_MINCONPOOL)
375: .trim();
376: String maxconpool = dsd.getProperty(MAXCONPOOL, DEF_MAXCONPOOL)
377: .trim();
378: String maxwaittime = dsd.getProperty(MAXWAITTIME,
379: DEF_MAXWAITTIME).trim();
380: String maxwaiters = dsd.getProperty(MAXWAITERS, DEF_MAXWAITERS)
381: .trim();
382: String samplingperiod = dsd.getProperty(SAMPLINGPERIOD,
383: DEF_SAMPLINGPERIOD).trim();
384: String defaultStatement = dsd.getProperty(CONNTESTSTMT,
385: DEF_CONNTESTSTMT).trim();
386: String pstmtmax = dsd.getProperty(PSTMTMAX, DEF_PSTMTMAX)
387: .trim();
388:
389: // Create ConnectionManager (JOnAS DataSource)
390: if (logger.isLoggable(BasicLevel.DEBUG)) {
391: logger.log(BasicLevel.DEBUG,
392: "create JOnAS ConnectionManager corresponding to data source "
393: + datasourceName + " with JNDI name "
394: + dsName);
395: }
396: ConnectionManager ds = new ConnectionManager();
397:
398: // Initialize ConnectionManager
399: ds.setDatasourceName(datasourceName); // set datasource name
400: ds.setDSName(dsName); // set jndi name
401: ds.setUrl(url);
402: ds.setClassName(className);
403: ds.setUserName(user);
404: ds.setPassword(password);
405: ds.setTransactionIsolation(dsd.getProperty(ISOLATIONLEVEL,
406: DEF_ISOLATIONLEVEL).trim());
407: ds.setMapperName(dsd.getProperty(MAPPERNAME, DEF_MAPPERNAME)
408: .trim());
409: ds.setDataSourceDescription(description);
410: ds.poolConfigure(connCheckLevel, connMaxAge, maxOpenTime,
411: defaultStatement, pstmtmax, minconpool, maxconpool,
412: maxwaittime, maxwaiters, samplingperiod);
413:
414: // Register ConnectionManager in JNDI and in internal data structures
415: cmList.addElement(ds);
416: ictx.rebind(dsName, ds);
417: // allows for getting the data source name from the jndi name
418: bindedDatasources.put(dsName, datasourceName);
419: logger.log(BasicLevel.INFO, "Mapping ConnectionManager " + url
420: + " on " + dsName);
421:
422: try {
423: // --------------------------
424: // Register MBeans cf. JSR 77
425: // --------------------------
426: if (mbeanServer != null) {
427: // Available DataSources and Drivers
428: // ------------------------------------------------------------
429: // DataSource MBean
430: // -----------------------
431: String jdbcDataSourceName = datasourceName;
432: ObjectName onJDBCDataSource = J2eeObjectName
433: .getJDBCDataSource(domainName, serverName,
434: jdbcDataSourceName);
435: JDBCDataSource jdbcDataSourceMBean = new JDBCDataSource(
436: onJDBCDataSource.toString(), ds);
437: oManaged = oRegistry.findManagedBean("JDBCDataSource");
438: oMBean = oManaged.createMBean(jdbcDataSourceMBean);
439: if (logger.isLoggable(BasicLevel.DEBUG)) {
440: logger.log(BasicLevel.DEBUG,
441: "JDBCDataSource created");
442: }
443: mbeanServer.registerMBean(oMBean, onJDBCDataSource);
444:
445: // Update the list of dataSources in the JDBCResource MBean with the JDBCDataSource
446: // MBean's OBJECT_NAME
447: jdbcResourceMBean.addJdbcDataSource(onJDBCDataSource
448: .toString());
449:
450: // JDBCDriver MBean
451: // ------------------------------
452: String jdbcDriverName = "aJDBCDriver-"
453: + jdbcDataSourceName; // TO BE IMPLEMENTED
454: ObjectName onJDBCDriver = J2eeObjectName.getJDBCDriver(
455: domainName, serverName, jdbcDriverName);
456: JDBCDriver jdbcDriverMBean = new JDBCDriver(
457: onJDBCDriver.toString());
458: jdbcDriverMBean.setDriverClassName(className);
459: oManaged = oRegistry.findManagedBean("JDBCDriver");
460: oMBean = oManaged.createMBean(jdbcDriverMBean);
461: if (logger.isLoggable(BasicLevel.DEBUG)) {
462: logger.log(BasicLevel.DEBUG, "JDBCDriver created");
463: }
464: mbeanServer.registerMBean(oMBean, onJDBCDriver);
465:
466: // Update the JDBC DataSource with the JDBC Driver
467: jdbcDataSourceMBean.setJdbcDriver(onJDBCDriver
468: .toString());
469: if (logger.isLoggable(BasicLevel.DEBUG)) {
470: logger.log(BasicLevel.DEBUG,
471: "JDBCDataSource updated");
472: }
473:
474: } // end JMX registration
475: } catch (ServiceException se) {
476: // Jmx Service not available, do nothing
477: }
478:
479: }
480:
481: /**
482: * Unbind dataSource names from the registry, unregister MBeans
483: */
484: public void unbindDataSources() throws NamingException {
485:
486: logger.log(BasicLevel.DEBUG, "");
487:
488: try {
489: if (cmList.size() > 0) {
490: String dsn = null;
491: for (Enumeration lk = cmList.elements(); lk
492: .hasMoreElements();) {
493: ConnectionManager cm = (ConnectionManager) lk
494: .nextElement();
495: cm.closeAllConnection();
496: dsn = cm.getDSName();
497: ictx.unbind(dsn);
498: bindedDatasources.remove(dsn);
499: }
500: }
501: } catch (NamingException e) {
502: logger
503: .log(BasicLevel.ERROR, "cannot unbind DataSources",
504: e);
505: throw e;
506: }
507:
508: // --------------------------
509: // unregister MBeans cf. JSR 77
510: // --------------------------
511: if (mbeanServer != null) {
512: try {
513: // Get JDBCDataSource OBJECT_NAMEs
514: String[] ons = jdbcResourceMBean.getJdbcDataSources();
515: ObjectName onJDBCDataSource = null;
516: ObjectName onJDBCDriver = null;
517: for (int i = 0; i < ons.length; i++) {
518: onJDBCDataSource = ObjectName.getInstance(ons[i]);
519: String jdbcDriverName = (String) mbeanServer
520: .getAttribute(onJDBCDataSource,
521: "jdbcDriver");
522: onJDBCDriver = new ObjectName(jdbcDriverName);
523: // Unregister JDBCDataSource MBean
524: mbeanServer.unregisterMBean(onJDBCDataSource);
525: // Unregister JDBCDriver MBean
526: mbeanServer.unregisterMBean(onJDBCDriver);
527: // Update the list of dataSources in the JDBCResource MBean
528: jdbcResourceMBean
529: .removeJdbcDataSource(onJDBCDataSource
530: .toString());
531: }
532: } catch (MalformedObjectNameException ma) {
533: logger.log(BasicLevel.ERROR,
534: "Cannot cleanly unregister DataSource", ma);
535: } catch (MBeanRegistrationException mr) {
536: logger.log(BasicLevel.ERROR,
537: "Cannot cleanly unregister DataSource", mr);
538: } catch (InstanceNotFoundException infe) {
539: logger.log(BasicLevel.ERROR,
540: "Cannot cleanly unregister DataSource", infe);
541: } catch (Exception e) {
542: logger.log(BasicLevel.ERROR,
543: "Cannot cleanly unregister DataSource", e);
544: }
545: }
546: }
547:
548: /**
549: * get ConnectionManager for the datasource having this JNDI name.
550: */
551: public ConnectionManager getConnectionManager(String dsname) {
552: ConnectionManager cm = null;
553: if (cmList.size() > 0) {
554: for (Enumeration lk = cmList.elements(); lk
555: .hasMoreElements();) {
556: cm = (ConnectionManager) lk.nextElement();
557: if (cm.getDSName().equals(dsname)) {
558: return cm;
559: }
560: }
561: }
562: return null;
563: }
564:
565: /**
566: * return the list of the datasources
567: * @return
568: */
569: public Collection getDSList() {
570: return cmList;
571: }
572:
573: //------------------------------------------------------------------------------------------
574:
575: /**
576: * MBean method:
577: * @return the list of properties files describing datasources found in JONAS_BASE/conf
578: */
579: public List getDataSourcePropertiesFiles() throws Exception {
580: return JModule.getDatasourcePropsInDir();
581: }
582:
583: /**
584: * MBean method:
585: * @return Integer Total Number of Datasource available in JOnAS
586: */
587: public Integer getCurrentNumberOfDataSource() {
588: return new Integer(cmList.size());
589: }
590:
591: /**
592: * MBean method:
593: * @return Integer Total Number of JDBC connection open
594: */
595: public Integer getTotalCurrentNumberOfJDBCConnectionOpen() {
596: int result = 0;
597: if (cmList.size() > 0) {
598: for (Enumeration lk = cmList.elements(); lk
599: .hasMoreElements();) {
600: ConnectionManager cm = (ConnectionManager) lk
601: .nextElement();
602: result += cm.getPool().getCurrentOpened();
603: }
604: }
605: return new Integer(result);
606: }
607:
608: /**
609: * MBean method:
610: * @return true if the datasource having thid jndi name is loadd
611: */
612: public boolean isLoadedDataSource(String dsName) {
613: boolean result = false;
614: if (cmList.size() > 0) {
615: for (Enumeration lk = cmList.elements(); lk
616: .hasMoreElements();) {
617: ConnectionManager cm = (ConnectionManager) lk
618: .nextElement();
619: if (cm.getDatasourceName().equals(dsName))
620: return true;
621: }
622: }
623: return result;
624: }
625:
626: /**
627: * MBean method:
628: * @param name of the data source to unload
629: */
630: public void unloadDataSource(String name) {
631: logger.log(BasicLevel.DEBUG, "");
632: try {
633: if (cmList.size() > 0) {
634: for (Enumeration lk = cmList.elements(); lk
635: .hasMoreElements();) {
636: ConnectionManager cm = (ConnectionManager) lk
637: .nextElement();
638: String dsName = cm.getDatasourceName();
639: String jndiName = cm.getDSName();
640: if (dsName.equals(name)) {
641: // unbind data source
642: cm.closeAllConnection();
643: ictx.unbind(jndiName);
644: // remove datasource
645: cmList.remove(cm);
646: // remove JProp instance corresponding to this datasource in order to
647: // allow re-create in case its re-loaded
648: JProp.removeInstance(dsName);
649: if (mbeanServer != null) {
650: ObjectName onJDBCDataSource = J2eeObjectName
651: .getJDBCDataSource(domainName,
652: serverName, dsName);
653: String jdbcDriverName = (String) mbeanServer
654: .getAttribute(onJDBCDataSource,
655: "jdbcDriver");
656: ObjectName onJDBCDriver = new ObjectName(
657: jdbcDriverName);
658: // Unregister JDBCDataSource MBean
659: mbeanServer
660: .unregisterMBean(onJDBCDataSource);
661: // Unregister JDBCDriver MBean
662: mbeanServer.unregisterMBean(onJDBCDriver);
663: // Update the list of dataSources in the JDBCResource MBean
664: jdbcResourceMBean
665: .removeJdbcDataSource(onJDBCDataSource
666: .toString());
667: }
668: return;
669: }
670: }
671: }
672: } catch (Exception e) {
673: logger
674: .log(BasicLevel.ERROR, "cannot unload DataSources",
675: e);
676: }
677: }
678:
679: /**
680: * MBean method:
681: * @return datasource properties from a local file
682: */
683: public Properties getDataSourcePropertiesFile(String dsFile)
684: throws Exception {
685: try {
686: return JProp.getInstance(dsFile).getConfigFileEnv();
687:
688: } catch (Exception e) {
689: if (e instanceof FileNotFoundException) {
690: logger
691: .log(
692: BasicLevel.ERROR,
693: "Please check if '"
694: + dsFile
695: + ".properties' is available in JONAS_BASE/conf/ directory");
696: } else {
697: logger.log(BasicLevel.ERROR,
698: "Error occured when reading file " + dsFile);
699: }
700: throw e;
701: }
702: }
703:
704: /**
705: * MBean method:
706: * load a new datasource
707: * @param name datasource name
708: * @param prop datasource properties
709: * @param loadFromFile if false the datasource creation was dynamicaly invoked by a management
710: * operation providing the properties in the prop object.
711: * @throws ServiceException datasource could not be created
712: */
713: public void loadDataSource(String name, Properties prop,
714: Boolean loadFromFile) throws ServiceException {
715: boolean fromFile = loadFromFile.booleanValue();
716:
717: if (fromFile) {
718: logger.log(BasicLevel.DEBUG, "Load data source named "
719: + name + " from file");
720: } else {
721: logger.log(BasicLevel.DEBUG, "Load data source named "
722: + name + " from form");
723: if (isLoadedDataSource(name)) {
724: logger.log(BasicLevel.DEBUG, "This data source, "
725: + name + " is already loaded ; Unload it !");
726: unloadDataSource(name);
727: }
728: try {
729: logger
730: .log(BasicLevel.DEBUG,
731: "Call getInstance on JProp in order to create the properties file");
732: JProp.getInstance(name, prop);
733: } catch (Exception e) {
734: logger.log(BasicLevel.ERROR,
735: "Cannot create datasource " + name
736: + " as cannot create properties file");
737: throw new ServiceException(
738: "DatabaseService: Cannot create datasource '"
739: + name + "'", e);
740: }
741: }
742:
743: try {
744: logger.log(BasicLevel.DEBUG,
745: "Call method to create a data source");
746: createDataSource(name, prop);
747: logger.log(BasicLevel.DEBUG, "New data source created");
748: } catch (Exception e) {
749: logger.log(BasicLevel.ERROR, "Cannot create datasource '"
750: + name + "'.");
751: if (fromFile) {
752: JProp.removeInstance(name);
753: } else {
754: JProp.deleteInstance(name);
755: }
756: throw new ServiceException(
757: "DatabaseService: Cannot create datasource: "
758: + name + "'", e);
759: }
760: }
761:
762: /**
763: * MBean method allowing to determine the datasource name from its jndi name
764: * @param jndiName The jndi name of a datasource
765: * @return The datasource name
766: */
767: public String getDatasourceName(String jndiName) {
768: return (String) bindedDatasources.get(jndiName);
769: }
770:
771: }
|