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: JDBCDataSource.java 7970 2006-02-02 15:06:42Z danesa $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas.dbm;
025:
026: // JOnAS imports
027: import java.sql.SQLException;
028:
029: import org.objectweb.jonas.management.ReconfiguredProp;
030: import org.objectweb.jonas.management.j2eemanagement.J2EEManagedObject;
031:
032: /**
033: * MBean class for JDBCDataSource Management
034: * This MBean manages a connection manager and its associated pool. This couple
035: * represents the JOnAS data source implementation
036: *
037: * @author Eric Hardesty JSR 77 (J2EE Management Standard)
038: * @author Adriana Danes add support for persistent reconfiguration
039: */
040: public class JDBCDataSource extends J2EEManagedObject {
041:
042: /**
043: * OBJECT_NAME of the associated JDBCDriver MBean
044: */
045: private String jdbcDriver = null;
046:
047: /**
048: * Associated connection manager
049: */
050: private ConnectionManager cm = null;
051:
052: /**
053: * Pool associated to the connection manager
054: */
055: private Pool pool = null;
056:
057: /**
058: * The current data source name
059: */
060: private String datasourceName = null;
061:
062: /**
063: * Value used as sequence number by reconfiguration notifications
064: */
065: private long sequenceNumber = 0;
066:
067: /**
068: * @param objectName This MBean's OBJECT_NAME
069: * @param cm Associated ConnectionManager reference
070: */
071: public JDBCDataSource(String objectName, ConnectionManager cm) {
072: super (objectName);
073: this .cm = cm;
074: this .pool = cm.getPool();
075: this .datasourceName = cm.getDatasourceName();
076: }
077:
078: // JDBC DataSource Configuration
079:
080: /**
081: * @return The OBJECT_NAME of the associated JDBCDriver MBean
082: */
083: public String getJdbcDriver() {
084: return jdbcDriver;
085: }
086:
087: /**
088: * @param jdbcDriverObjectName OBJECT_NAME of the associated JDBCDriver MBean
089: */
090: public void setJdbcDriver(String jdbcDriverObjectName) {
091: jdbcDriver = jdbcDriverObjectName;
092: }
093:
094: /**
095: * Return the current data source name. Returns the local attribute value (optimize
096: * call) - this value can't be changed, moreover, its used by private methods.
097: * @return The current data source name
098: */
099: public String getName() {
100: return datasourceName;
101: }
102:
103: /**
104: * @return The JNDI name
105: */
106: public String getJndiName() {
107: return cm.getDSName();
108: }
109:
110: /**
111: * @return Description of this data source
112: */
113: public String getDescription() {
114: return cm.getDataSourceDescription();
115: }
116:
117: /**
118: * @return The JDBC URL for the database
119: */
120: public String getUrl() {
121: return cm.getUrl();
122: }
123:
124: /**
125: * @return The user name for connection to the database
126: */
127: public String getUserName() {
128: return cm.getUserName();
129: }
130:
131: /**
132: * @return The password for connection to the database
133: */
134: public String getUserPassword() {
135: return cm.getPassword();
136: }
137:
138: /**
139: * @return The mapper JORM for the database
140: */
141: public String getMapperName() {
142: return cm.getMapperName();
143: }
144:
145: // JDBC Connection Pool Configuration
146:
147: /**
148: * @return JDBC connection checking level
149: */
150: public Integer getJdbcConnCheckLevel() {
151: return new Integer(pool.getCheckLevel());
152: }
153:
154: /**
155: * Sets the JDBC connection checking level
156: * @param level connection level
157: */
158: public void setJdbcConnCheckLevel(Integer level) {
159: pool.setCheckLevel(level.intValue());
160: String propName = DataBaseServiceImpl.CONNCHECKLEVEL;
161: ReconfiguredProp prop = new ReconfiguredProp(propName, level
162: .toString());
163: // Send a reconfiguration notification to the listener MBean
164: sendReconfigNotification(getSequenceNumber(), datasourceName,
165: prop);
166: }
167:
168: /**
169: * @return JDBC connections maximum age
170: */
171: public Integer getJdbcConnMaxAge() {
172: return new Integer(pool.getMaxAge());
173: }
174:
175: /**
176: * @param mn JDBC connections maximum age
177: */
178: public void setJdbcConnMaxAge(Integer mn) {
179: pool.setMaxAge(mn.intValue());
180: String propName = DataBaseServiceImpl.CONNMAXAGE;
181: ReconfiguredProp prop = new ReconfiguredProp(propName, mn
182: .toString());
183: // Send a reconfiguration notification to the listener MBean
184: sendReconfigNotification(getSequenceNumber(), datasourceName,
185: prop);
186: }
187:
188: /**
189: * @return max maximum size of JDBC connection pool
190: */
191: public Integer getJdbcMaxConnPool() {
192: return new Integer(pool.getPoolMax());
193: }
194:
195: /**
196: * @param max maximum size of JDBC connection pool
197: */
198: public void setJdbcMaxConnPool(Integer max) {
199: pool.setPoolMax(max.intValue());
200: // Update the configuration file
201: String propName = DataBaseServiceImpl.MAXCONPOOL;
202: ReconfiguredProp prop = new ReconfiguredProp(propName, max
203: .toString());
204: // Send a reconfiguration notification to the listener MBean
205: sendReconfigNotification(getSequenceNumber(), datasourceName,
206: prop);
207: }
208:
209: /**
210: * @return maximum opening time of JDBC connections
211: */
212: public Integer getJdbcMaxOpenTime() {
213: return new Integer(pool.getMaxOpenTime());
214: }
215:
216: /**
217: * @param mn maximum opening time in minutes for JDBC connections
218: */
219: public void setJdbcMaxOpenTime(Integer mn) {
220: pool.setMaxOpenTime(mn.intValue());
221: String propName = DataBaseServiceImpl.MAXOPENTIME;
222: ReconfiguredProp prop = new ReconfiguredProp(propName, mn
223: .toString());
224: // Send a reconfiguration notification to the listener MBean
225: sendReconfigNotification(getSequenceNumber(), datasourceName,
226: prop);
227: }
228:
229: /**
230: * @return maximum nb of waiters allowed
231: */
232: public Integer getJdbcMaxWaiters() {
233: return new Integer(pool.getMaxWaiters());
234: }
235:
236: /**
237: * @param max maximum nb of waiters allowed
238: */
239: public void setJdbcMaxWaiters(Integer max) {
240: pool.setMaxWaiters(max.intValue());
241: // Update the configuration file
242: String propName = DataBaseServiceImpl.MAXWAITERS;
243: ReconfiguredProp prop = new ReconfiguredProp(propName, max
244: .toString());
245: // Send a reconfiguration notification to the listener MBean
246: sendReconfigNotification(getSequenceNumber(), datasourceName,
247: prop);
248: }
249:
250: /**
251: * @return maximum time to wait for a connection, in seconds
252: */
253: public Integer getJdbcMaxWaitTime() {
254: return new Integer(pool.getMaxWaitTime());
255: }
256:
257: /**
258: * @param max maximum time to wait for a connection, in seconds
259: */
260: public void setJdbcMaxWaitTime(Integer max) {
261: pool.setMaxWaitTime(max.intValue());
262: // Update the configuration file
263: String propName = DataBaseServiceImpl.MAXWAITTIME;
264: ReconfiguredProp prop = new ReconfiguredProp(propName, max
265: .toString());
266: // Send a reconfiguration notification to the listener MBean
267: sendReconfigNotification(getSequenceNumber(), datasourceName,
268: prop);
269: }
270:
271: /**
272: * @return PreparedStatement cache size
273: */
274: public Integer getJdbcPstmtMax() {
275: return new Integer(cm.getPstmtMax());
276: }
277:
278: /**
279: * @param max PreparedStatement cache size
280: */
281: public void setJdbcPstmtMax(Integer max) {
282: cm.setPstmtMax(max.intValue());
283: // Update the configuration file
284: String propName = DataBaseServiceImpl.PSTMTMAX;
285: ReconfiguredProp prop = new ReconfiguredProp(propName, max
286: .toString());
287: // Send a reconfiguration notification to the listener MBean
288: sendReconfigNotification(getSequenceNumber(), datasourceName,
289: prop);
290: }
291:
292: /**
293: * @return minimum size of connection pool
294: */
295: public Integer getJdbcMinConnPool() {
296: return new Integer(pool.getPoolMin());
297: }
298:
299: /**
300: * MBean method allowing to set the minimum size of connection pool
301: * @param min minimum size of connection pool
302: */
303: public void setJdbcMinConnPool(Integer min) {
304: pool.setPoolMin(min.intValue());
305: // Update the configuration file
306: String propName = DataBaseServiceImpl.MINCONPOOL;
307: ReconfiguredProp prop = new ReconfiguredProp(propName, min
308: .toString());
309: // Send a reconfiguration notification to the listener MBean
310: sendReconfigNotification(getSequenceNumber(), datasourceName,
311: prop);
312: }
313:
314: /**
315: * @return sampling period for refresching pool statistics
316: */
317: public Integer getJdbcSamplingPeriod() {
318: return new Integer(pool.getSamplingPeriod());
319: }
320:
321: /**
322: * @param i sampling period for refresching pool statistics
323: */
324: public void setJdbcSamplingPeriod(Integer i) {
325: pool.setSamplingPeriod(i.intValue());
326: // Update the configuration file
327: String propName = DataBaseServiceImpl.SAMPLINGPERIOD;
328: ReconfiguredProp prop = new ReconfiguredProp(propName, i
329: .toString());
330: // Send a reconfiguration notification to the listener MBean
331: sendReconfigNotification(getSequenceNumber(), datasourceName,
332: prop);
333: }
334:
335: /**
336: * @return SQL query for JDBC connections test
337: */
338: public String getJdbcTestStatement() {
339: return pool.getTestStatement();
340: }
341:
342: /**
343: * @param test SQL query for JDBC connection test
344: * @return the test statement if the test succeeded, an error message otherwise
345: */
346: public String setJdbcTestStatement(String test) {
347: String result;
348: try {
349: result = pool.checkConnection(test);
350: if (result.equals(test)) {
351: // Test succeeded
352: pool.setTestStatement(test);
353: result = test;
354: }
355: } catch (SQLException e) {
356: result = e.toString();
357: }
358: String propName = DataBaseServiceImpl.CONNTESTSTMT;
359: ReconfiguredProp prop = new ReconfiguredProp(propName, test);
360: // Send a reconfiguration notification to the listener MBean
361: sendReconfigNotification(getSequenceNumber(), datasourceName,
362: prop);
363: return result;
364: }
365:
366: // JDBC Connection Pool Statistics
367:
368: /**
369: * @return number of connection failures
370: */
371: public Integer getConnectionFailures() {
372: return new Integer(pool.getConnectionFailures());
373: }
374:
375: /**
376: * @return number of connection leaks
377: */
378: public Integer getConnectionLeaks() {
379: return new Integer(pool.getConnectionLeaks());
380: }
381:
382: /**
383: * @return number of busy connections
384: */
385: public Integer getCurrentBusy() {
386: return new Integer(pool.getCurrentBusy());
387: }
388:
389: /**
390: * @return number of busy connections
391: */
392: public Integer getBusyMax() {
393: return new Integer(pool.getBusyMaxRecent());
394: }
395:
396: /**
397: * @return number of busy connections
398: */
399: public Integer getBusyMin() {
400: return new Integer(pool.getBusyMinRecent());
401: }
402:
403: /**
404: * @return number of connections used in transactions
405: */
406: public Integer getCurrentInTx() {
407: return new Integer(pool.getCurrentInTx());
408: }
409:
410: /**
411: * @return number of opened connections
412: */
413: public Integer getCurrentOpened() {
414: return new Integer(pool.getCurrentOpened());
415: }
416:
417: /**
418: * @return current number of connection waiters
419: */
420: public Integer getCurrentWaiters() {
421: return new Integer(pool.getCurrentWaiters());
422: }
423:
424: /**
425: * @return number of opened physical JDBC connections
426: */
427: public Integer getOpenedCount() {
428: return new Integer(pool.getOpenedCount());
429: }
430:
431: /**
432: * @return number of open calls that were rejected because too many waiters
433: */
434: public Integer getRejectedFull() {
435: return new Integer(pool.getRejectedFull());
436: }
437:
438: /**
439: * @return total number of open calls that were rejected
440: */
441: public Integer getRejectedOpen() {
442: return new Integer(pool.getRejectedOpen());
443: }
444:
445: /**
446: * @return number of open calls that were rejected by an unknown reason
447: */
448: public Integer getRejectedOther() {
449: return new Integer(pool.getRejectedOther());
450: }
451:
452: /**
453: * @return number of open calls that were rejected by timeout
454: */
455: public Integer getRejectedTimeout() {
456: return new Integer(pool.getRejectedTimeout());
457: }
458:
459: /**
460: * @return number of xa connection served
461: */
462: public Integer getServedOpen() {
463: return new Integer(pool.getServedOpen());
464: }
465:
466: /**
467: * @return total number of waiters since datasource creation.
468: */
469: public Integer getWaiterCount() {
470: return new Integer(pool.getWaiterCount());
471: }
472:
473: /**
474: * @return Maximum number of waiters since datasource creation.
475: */
476: public Integer getWaitersHigh() {
477: return new Integer(pool.getWaitersHigh());
478: }
479:
480: /**
481: * @return Maximum nb of waiters in last sampling period
482: */
483: public Integer getWaitersHighRecent() {
484: return new Integer(pool.getWaitersHighRecent());
485: }
486:
487: /**
488: * @return Maximum waiting time (millisec) since datasource creation.
489: */
490: public Long getWaitingHigh() {
491: return new Long(pool.getWaitingHigh());
492: }
493:
494: /**
495: * @return Maximum waiting time (millisec) in last sampling period
496: */
497: public Long getWaitingHighRecent() {
498: return new Long(pool.getWaitingHighRecent());
499: }
500:
501: /**
502: * @return Total waiting time (millisec) since datasource creation.
503: */
504: public Long getWaitingTime() {
505: return new Long(pool.getWaitingTime());
506: }
507:
508: /**
509: * Gets the sequence number for reconfiguration opeartions
510: * @return the sequence number for reconfiguration operations
511: */
512: protected long getSequenceNumber() {
513: return ++sequenceNumber;
514: }
515:
516: /**
517: * save updated configuration
518: */
519: public void saveConfig() {
520: sendSaveNotification(getSequenceNumber(), datasourceName);
521: }
522: }
|