KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > proxool > admin > jmx > ConnectionPoolMBean


1 /*
2  * This software is released under a licence similar to the Apache Software Licence.
3  * See org.logicalcobwebs.proxool.package.html for details.
4  * The latest version is available at http://proxool.sourceforge.net
5  */

6 package org.logicalcobwebs.proxool.admin.jmx;
7
8 import org.logicalcobwebs.proxool.resources.ResourceNamesIF;
9 import org.logicalcobwebs.proxool.ProxoolConstants;
10 import org.logicalcobwebs.proxool.ConnectionPoolDefinitionIF;
11 import org.logicalcobwebs.proxool.ProxoolFacade;
12 import org.logicalcobwebs.proxool.ProxoolException;
13 import org.logicalcobwebs.proxool.ProxoolListenerIF;
14 import org.logicalcobwebs.proxool.ConfigurationListenerIF;
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17
18 import javax.management.MBeanInfo JavaDoc;
19 import javax.management.MBeanOperationInfo JavaDoc;
20 import javax.management.MBeanConstructorInfo JavaDoc;
21 import javax.management.MBeanAttributeInfo JavaDoc;
22 import javax.management.MBeanNotificationInfo JavaDoc;
23 import javax.management.DynamicMBean JavaDoc;
24 import javax.management.AttributeNotFoundException JavaDoc;
25 import javax.management.MBeanException JavaDoc;
26 import javax.management.ReflectionException JavaDoc;
27 import javax.management.RuntimeOperationsException JavaDoc;
28 import javax.management.Attribute JavaDoc;
29 import javax.management.InvalidAttributeValueException JavaDoc;
30 import javax.management.AttributeList JavaDoc;
31 import javax.management.MBeanParameterInfo JavaDoc;
32 import javax.management.NotificationBroadcaster JavaDoc;
33 import javax.management.NotificationBroadcasterSupport JavaDoc;
34 import javax.management.NotificationListener JavaDoc;
35 import javax.management.NotificationFilter JavaDoc;
36 import javax.management.ListenerNotFoundException JavaDoc;
37 import javax.management.Notification JavaDoc;
38 import javax.management.MBeanRegistration JavaDoc;
39 import javax.management.ObjectName JavaDoc;
40 import javax.management.MBeanServer JavaDoc;
41
42 import java.util.Iterator JavaDoc;
43 import java.util.ResourceBundle JavaDoc;
44 import java.util.Properties JavaDoc;
45 import java.util.StringTokenizer JavaDoc;
46 import java.text.MessageFormat JavaDoc;
47
48 /**
49  * JMX DynamicMBean adapter for a Proxool connection pool.<br>
50  * See the configuration documentation to learn
51  * how to activate a pool for JMX. No programming is necessary to do this.
52  * <p>
53  * <b>Attributes</b>
54  * <ul>
55  * <li>alias</li>
56  * <li>driverClass</li>
57  * <li>driverUrl</li>
58  * <li>driverProperties</li>
59  * <li>fatalSqlException</li>
60  * <li>houseKeepingSleeptime</li>
61  * <li>houseKeepingTestSql</li>
62  * <li>maximumActiveTime</li>
63  * <li>maximumConnectionCount</li>
64  * <li>maximumConnectionLifetime</li>
65  * <li>minimumConnectionCount</li>
66  * <li>maximumNewConnections</li>
67  * <li>overloadWithoutRefusalLifetime</li>
68  * <li>recentlyStartedThreshold</li>
69  * <li>prototypeCount</li>
70  * <li>trace</li>
71  * <li>verbose</li>
72  * </ul>
73  * </p>
74  * <p>
75  * <b>Operations</b>
76  * <ul>
77  * <li>shutdown</li>
78  * </ul>
79  * </p>
80  * <p>
81  * <b>Notifications</b>
82  * <ul>
83  * <li>{@link #NOTIFICATION_TYPE_DEFINITION_UPDATED}</li>
84  * </ul>
85  * </p>
86  * @version $Revision: 1.15 $, $Date: 2006/01/18 14:39:55 $
87  * @author Christian Nedregaard (christian_nedregaard@email.com)
88  * @author $Author: billhorsman $ (current maintainer)
89  * @since Proxool 0.8
90  */

91 public class ConnectionPoolMBean implements DynamicMBean JavaDoc, MBeanRegistration JavaDoc, NotificationBroadcaster JavaDoc,
92         ProxoolListenerIF, ConfigurationListenerIF {
93     /**
94      * Notification type emitted when the pool definition is updated.
95      */

96     public static final String JavaDoc NOTIFICATION_TYPE_DEFINITION_UPDATED = "proxool.definitionUpdated";
97
98
99     private static final Log LOG = LogFactory.getLog(ConnectionPoolMBean.class);
100     private static final String JavaDoc CLASS_NAME = ConnectionPoolMBean.class.getName();
101
102     private static final String JavaDoc RECOURCE_NAME_MBEAN_POOL_DESCRIPTION = "mbean.pool.description";
103     private static final String JavaDoc RECOURCE_NAME_MBEAN_NOTIFICATION_DESCRIPTION = "mbean.notification.description";
104     private static final String JavaDoc RECOURCE_NAME_MBEAN_NOTIFICATION_DEF_UPDATED = "mbean.notification.defUpdated";
105
106     private static final String JavaDoc OPERATION_NAME_SHUTDOWN = "shutdown";
107
108     private static final ResourceBundle JavaDoc ATTRIBUTE_DESCRIPTIONS_RESOURCE = createAttributeDescriptionsResource();
109     private static final ResourceBundle JavaDoc JMX_RESOURCE = createJMXResource();
110
111     private static final MBeanNotificationInfo JavaDoc[] NOTIFICATION_INFOS = getNotificationInfos();
112
113     private MBeanInfo JavaDoc mBeanInfo;
114     private ConnectionPoolDefinitionIF poolDefinition;
115     private Properties JavaDoc poolProperties;
116     private long definitionUpdatedSequence;
117     private NotificationBroadcasterSupport JavaDoc notificationHelper = new NotificationBroadcasterSupport JavaDoc();
118     private boolean active;
119
120     public ConnectionPoolMBean(String JavaDoc alias, Properties JavaDoc poolProperties)
121             throws ProxoolException {
122         this.poolDefinition = ProxoolFacade
123                 .getConnectionPoolDefinition(alias);
124         this.poolProperties = poolProperties;
125         this.mBeanInfo = getDynamicMBeanInfo(this.poolDefinition.getAlias());
126         ProxoolFacade.addProxoolListener(this);
127         ProxoolFacade.addConfigurationListener(alias, this);
128     }
129
130     /**
131      * @see javax.management.DynamicMBean#getAttribute(java.lang.String)
132      */

133     public Object JavaDoc getAttribute(String JavaDoc attributeName) throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc, ReflectionException JavaDoc {
134         if (attributeName == null) {
135             final String JavaDoc message = "Cannot invoke a getter of " + CLASS_NAME + " with null attribute name";
136             LOG.error(message);
137             throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("Attribute name cannot be null"),
138                     message);
139         }
140         if (LOG.isDebugEnabled()) {
141             LOG.debug("Getting attribute " + attributeName + ".");
142         }
143         return ((Attribute JavaDoc) getAttributes(new String JavaDoc[]{attributeName}).get(0)).getValue();
144     }
145
146     /**
147      * @see javax.management.DynamicMBean#setAttribute(javax.management.Attribute)
148      */

149     public void setAttribute(Attribute JavaDoc attribute) throws AttributeNotFoundException JavaDoc, InvalidAttributeValueException JavaDoc,
150             MBeanException JavaDoc, ReflectionException JavaDoc {
151         if (attribute == null) {
152             final String JavaDoc message = "Cannot invoke a setter of " + CLASS_NAME + " with null attribute";
153             LOG.error(message);
154             throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("Attribute cannot be null"),
155                     message);
156         }
157         if (LOG.isDebugEnabled()) {
158             LOG.debug("Setting attribute " + attribute.getName() + ".");
159         }
160         final AttributeList JavaDoc attributeList = new AttributeList JavaDoc();
161         attributeList.add(attribute);
162         setAttributes(attributeList);
163     }
164
165     /**
166      * @see javax.management.DynamicMBean#getAttributes(java.lang.String[])
167      */

168     public AttributeList JavaDoc getAttributes(String JavaDoc[] attributeNames) {
169         if (attributeNames == null) {
170             final String JavaDoc message = "Cannot invoke a null getter of " + CLASS_NAME;
171             LOG.error(message);
172             throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("attributeNames[] cannot be null"),
173                     message);
174         }
175         AttributeList JavaDoc resultList = new AttributeList JavaDoc();
176
177         // if attributeNames is empty, return an empty result list
178
if (attributeNames.length == 0) {
179             return resultList;
180         }
181
182         // build the result attribute list
183
for (int i = 0; i < attributeNames.length; i++) {
184             try {
185                 if (equalsProperty(attributeNames[i], ProxoolConstants.ALIAS)) {
186                     resultList.add(new Attribute JavaDoc(attributeNames[i],
187                             this.poolDefinition.getAlias()));
188                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.DRIVER_PROPERTIES)) {
189                     resultList.add(new Attribute JavaDoc(attributeNames[i],
190                             getDelegatePropertiesAsString(this.poolProperties)));
191                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.DRIVER_URL)) {
192                     resultList.add(new Attribute JavaDoc(attributeNames[i],
193                             this.poolDefinition.getUrl()));
194                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.FATAL_SQL_EXCEPTION)) {
195                     resultList.add(new Attribute JavaDoc(attributeNames[i],
196                             getValueOrEmpty(this.poolProperties.getProperty(ProxoolConstants.FATAL_SQL_EXCEPTION_PROPERTY))));
197                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.HOUSE_KEEPING_SLEEP_TIME)) {
198                     resultList.add(new Attribute JavaDoc(attributeNames[i],
199                             new Integer JavaDoc(this.poolDefinition.getHouseKeepingSleepTime())));
200                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.HOUSE_KEEPING_TEST_SQL)) {
201                     resultList.add(new Attribute JavaDoc(attributeNames[i],
202                             getValueOrEmpty(poolDefinition.getHouseKeepingTestSql())));
203                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.TEST_BEFORE_USE)) {
204                     resultList.add(new Attribute JavaDoc(attributeNames[i],
205                             new Boolean JavaDoc(this.poolDefinition.isTestBeforeUse())));
206                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.TEST_AFTER_USE)) {
207                     resultList.add(new Attribute JavaDoc(attributeNames[i],
208                             new Boolean JavaDoc(this.poolDefinition.isTestAfterUse())));
209                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MAXIMUM_ACTIVE_TIME)) {
210                     resultList.add(new Attribute JavaDoc(attributeNames[i],
211                             new Integer JavaDoc(this.poolDefinition.getMaximumActiveTime())));
212                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MAXIMUM_CONNECTION_COUNT)) {
213                     resultList.add(new Attribute JavaDoc(attributeNames[i],
214                             new Integer JavaDoc(this.poolDefinition.getMaximumConnectionCount())));
215                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MAXIMUM_CONNECTION_LIFETIME)) {
216                     resultList.add(new Attribute JavaDoc(attributeNames[i],
217                             new Integer JavaDoc(this.poolDefinition.getMaximumConnectionLifetime())));
218                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MAXIMUM_NEW_CONNECTIONS)) {
219                     resultList.add(new Attribute JavaDoc(attributeNames[i],
220                             new Integer JavaDoc(this.poolDefinition.getMaximumNewConnections())));
221                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.SIMULTANEOUS_BUILD_THROTTLE)) {
222                     resultList.add(new Attribute JavaDoc(attributeNames[i],
223                             new Integer JavaDoc(this.poolDefinition.getSimultaneousBuildThrottle())));
224                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MINIMUM_CONNECTION_COUNT)) {
225                     resultList.add(new Attribute JavaDoc(attributeNames[i],
226                             new Integer JavaDoc(this.poolDefinition.getMinimumConnectionCount())));
227                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.OVERLOAD_WITHOUT_REFUSAL_LIFETIME)) {
228                     resultList.add(new Attribute JavaDoc(attributeNames[i],
229                             new Integer JavaDoc(this.poolDefinition.getOverloadWithoutRefusalLifetime())));
230                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.PROTOTYPE_COUNT)) {
231                     resultList.add(new Attribute JavaDoc(attributeNames[i],
232                             new Integer JavaDoc(this.poolDefinition.getPrototypeCount())));
233                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.RECENTLY_STARTED_THRESHOLD)) {
234                     resultList.add(new Attribute JavaDoc(attributeNames[i],
235                             new Integer JavaDoc(this.poolDefinition.getRecentlyStartedThreshold())));
236                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.STATISTICS)) {
237                     resultList.add(new Attribute JavaDoc(attributeNames[i],
238                             getValueOrEmpty(this.poolDefinition.getStatistics())));
239                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.STATISTICS_LOG_LEVEL)) {
240                     resultList.add(new Attribute JavaDoc(attributeNames[i],
241                             getValueOrEmpty(this.poolDefinition.getStatisticsLogLevel())));
242                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.TRACE)) {
243                     resultList.add(new Attribute JavaDoc(attributeNames[i],
244                             new Boolean JavaDoc(this.poolDefinition.isTrace())));
245                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.VERBOSE)) {
246                     resultList.add(new Attribute JavaDoc(attributeNames[i],
247                             new Boolean JavaDoc(this.poolDefinition.isVerbose())));
248                 } else if (equalsProperty(attributeNames[i], ProxoolConstants.FATAL_SQL_EXCEPTION_WRAPPER_CLASS)) {
249                     resultList.add(new Attribute JavaDoc(attributeNames[i],
250                             getValueOrEmpty(this.poolDefinition.getFatalSqlExceptionWrapper())));
251                 } else {
252                     final String JavaDoc message = "Unknown attribute: " + attributeNames[i];
253                     LOG.error(message);
254                     throw new AttributeNotFoundException JavaDoc(message);
255                 }
256             } catch (AttributeNotFoundException JavaDoc e) {
257                 throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc(e.getMessage()));
258             }
259         }
260         return resultList;
261     }
262
263     /**
264      * @see javax.management.DynamicMBean#setAttributes(javax.management.AttributeList)
265      */

266     public AttributeList JavaDoc setAttributes(AttributeList JavaDoc attributes) {
267
268         if (attributes == null) {
269             final String JavaDoc message = "AttributeList attributes cannot be null";
270             LOG.error(message);
271             throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc(message),
272                     "Cannot invoke a setter of " + CLASS_NAME);
273         }
274         AttributeList JavaDoc resultList = new AttributeList JavaDoc();
275
276         if (attributes.isEmpty()) {
277             return resultList;
278         }
279
280         String JavaDoc name = null;
281         Object JavaDoc value = null;
282         final Properties JavaDoc newProperties = new Properties JavaDoc();
283         Attribute JavaDoc attribute = null;
284         for (Iterator JavaDoc i = attributes.iterator(); i.hasNext();) {
285             attribute = (Attribute JavaDoc) i.next();
286             try {
287                 name = attribute.getName();
288                 value = attribute.getValue();
289
290                 if (equalsProperty(name, ProxoolConstants.DRIVER_PROPERTIES)) {
291                     if (!isEqualProperties(value.toString(), getDelegatePropertiesAsString(this.poolProperties))) {
292                         checkAssignable(name, String JavaDoc.class, value);
293                         setDelegateProperties(newProperties, value.toString());
294                         resultList.add(new Attribute JavaDoc(name, value));
295                     }
296                 } else if (equalsProperty(name, ProxoolConstants.DRIVER_URL)) {
297                     checkAssignable(name, String JavaDoc.class, value);
298                     if (notEmpty(value)) {
299                         newProperties.setProperty(ProxoolConstants.DRIVER_URL_PROPERTY, value.toString());
300                     } else {
301                         newProperties.setProperty(ProxoolConstants.DRIVER_URL_PROPERTY, "");
302                     }
303                     resultList.add(new Attribute JavaDoc(name, value));
304                 } else if (equalsProperty(name, ProxoolConstants.FATAL_SQL_EXCEPTION)) {
305                     if (!isEqualProperties(value.toString(),
306                             this.poolProperties.getProperty(ProxoolConstants.FATAL_SQL_EXCEPTION_PROPERTY))) {
307                         checkAssignable(name, String JavaDoc.class, value);
308                         if (notEmpty(value)) {
309                             newProperties.setProperty(ProxoolConstants.FATAL_SQL_EXCEPTION_PROPERTY, value.toString());
310                         } else {
311                             newProperties.setProperty(ProxoolConstants.FATAL_SQL_EXCEPTION_PROPERTY, "");
312                         }
313                         resultList.add(new Attribute JavaDoc(name, value));
314                     }
315                 } else if (equalsProperty(name, ProxoolConstants.HOUSE_KEEPING_SLEEP_TIME)) {
316                     setIntegerAttribute(name, ProxoolConstants.HOUSE_KEEPING_SLEEP_TIME_PROPERTY, value,
317                             ConnectionPoolDefinitionIF.DEFAULT_HOUSE_KEEPING_SLEEP_TIME, newProperties, resultList);
318                 } else if (equalsProperty(name, ProxoolConstants.HOUSE_KEEPING_TEST_SQL)) {
319                     checkAssignable(name, String JavaDoc.class, value);
320                     if (notEmpty(value)) {
321                         newProperties.setProperty(ProxoolConstants.HOUSE_KEEPING_TEST_SQL_PROPERTY, value.toString());
322                     } else {
323                         newProperties.setProperty(ProxoolConstants.HOUSE_KEEPING_TEST_SQL_PROPERTY, "");
324                     }
325                     resultList.add(new Attribute JavaDoc(name, value));
326                 } else if (equalsProperty(name, ProxoolConstants.TEST_BEFORE_USE)) {
327                     checkAssignable(name, Boolean JavaDoc.class, value);
328                     newProperties.setProperty(ProxoolConstants.TEST_BEFORE_USE_PROPERTY, value.toString());
329                     resultList.add(new Attribute JavaDoc(name, value));
330                 } else if (equalsProperty(name, ProxoolConstants.TEST_AFTER_USE)) {
331                     checkAssignable(name, Boolean JavaDoc.class, value);
332                     newProperties.setProperty(ProxoolConstants.TEST_AFTER_USE_PROPERTY, value.toString());
333                     resultList.add(new Attribute JavaDoc(name, value));
334                 } else if (equalsProperty(name, ProxoolConstants.MAXIMUM_ACTIVE_TIME)) {
335                     setIntegerAttribute(name, ProxoolConstants.MAXIMUM_ACTIVE_TIME_PROPERTY, value,
336                             ConnectionPoolDefinitionIF.DEFAULT_MAXIMUM_ACTIVE_TIME, newProperties, resultList);
337                 } else if (equalsProperty(name, ProxoolConstants.MAXIMUM_CONNECTION_COUNT)) {
338                     setIntegerAttribute(name, ProxoolConstants.MAXIMUM_CONNECTION_COUNT_PROPERTY, value,
339                             ConnectionPoolDefinitionIF.DEFAULT_MAXIMUM_CONNECTION_COUNT, newProperties, resultList);
340                 } else if (equalsProperty(name, ProxoolConstants.MAXIMUM_CONNECTION_LIFETIME)) {
341                     setIntegerAttribute(name, ProxoolConstants.MAXIMUM_CONNECTION_LIFETIME_PROPERTY, value,
342                             ConnectionPoolDefinitionIF.DEFAULT_MAXIMUM_CONNECTION_LIFETIME, newProperties, resultList);
343                 } else if (equalsProperty(name, ProxoolConstants.MAXIMUM_NEW_CONNECTIONS)) {
344                     setIntegerAttribute(name, ProxoolConstants.MAXIMUM_NEW_CONNECTIONS_PROPERTY, value,
345                             ConnectionPoolDefinitionIF.DEFAULT_MAXIMUM_NEW_CONNECTIONS, newProperties, resultList);
346                 } else if (equalsProperty(name, ProxoolConstants.SIMULTANEOUS_BUILD_THROTTLE)) {
347                     setIntegerAttribute(name, ProxoolConstants.SIMULTANEOUS_BUILD_THROTTLE_PROPERTY, value,
348                             ConnectionPoolDefinitionIF.DEFAULT_SIMULTANEOUS_BUILD_THROTTLE, newProperties, resultList);
349                 } else if (equalsProperty(name, ProxoolConstants.MINIMUM_CONNECTION_COUNT)) {
350                     checkAssignable(name, Integer JavaDoc.class, value);
351                     newProperties.setProperty(ProxoolConstants.MINIMUM_CONNECTION_COUNT_PROPERTY, value.toString());
352                     resultList.add(new Attribute JavaDoc(name, value));
353                 } else if (equalsProperty(name, ProxoolConstants.OVERLOAD_WITHOUT_REFUSAL_LIFETIME)) {
354                     setIntegerAttribute(name, ProxoolConstants.OVERLOAD_WITHOUT_REFUSAL_LIFETIME_PROPERTY, value,
355                             ConnectionPoolDefinitionIF.DEFAULT_OVERLOAD_WITHOUT_REFUSAL_THRESHOLD, newProperties, resultList);
356                 } else if (equalsProperty(name, ProxoolConstants.PROTOTYPE_COUNT)) {
357                     checkAssignable(name, Integer JavaDoc.class, value);
358                     newProperties.setProperty(ProxoolConstants.PROTOTYPE_COUNT_PROPERTY, value.toString());
359                     resultList.add(new Attribute JavaDoc(name, value));
360                 } else if (equalsProperty(name, ProxoolConstants.RECENTLY_STARTED_THRESHOLD)) {
361                     setIntegerAttribute(name, ProxoolConstants.RECENTLY_STARTED_THRESHOLD_PROPERTY, value,
362                             ConnectionPoolDefinitionIF.DEFAULT_RECENTLY_STARTED_THRESHOLD, newProperties, resultList);
363                 } else if (equalsProperty(name, ProxoolConstants.STATISTICS)) {
364                     checkAssignable(name, String JavaDoc.class, value);
365                     if (notEmpty(value)) {
366                         newProperties.setProperty(ProxoolConstants.STATISTICS_PROPERTY, value.toString());
367                     } else {
368                         newProperties.setProperty(ProxoolConstants.STATISTICS_PROPERTY, "");
369                     }
370                     resultList.add(new Attribute JavaDoc(name, value));
371                 } else if (equalsProperty(name, ProxoolConstants.STATISTICS_LOG_LEVEL)) {
372                     checkAssignable(name, String JavaDoc.class, value);
373                     if (notEmpty(value)) {
374                         newProperties.setProperty(ProxoolConstants.STATISTICS_LOG_LEVEL_PROPERTY, value.toString());
375                     } else {
376                         newProperties.setProperty(ProxoolConstants.STATISTICS_LOG_LEVEL_PROPERTY, "");
377                     }
378                     resultList.add(new Attribute JavaDoc(name, value));
379                 } else if (equalsProperty(name, ProxoolConstants.TRACE)) {
380                     checkAssignable(name, Boolean JavaDoc.class, value);
381                     newProperties.setProperty(ProxoolConstants.TRACE_PROPERTY, value.toString());
382                     resultList.add(new Attribute JavaDoc(name, value));
383                 } else if (equalsProperty(name, ProxoolConstants.VERBOSE)) {
384                     checkAssignable(name, Boolean JavaDoc.class, value);
385                     newProperties.setProperty(ProxoolConstants.VERBOSE_PROPERTY, value.toString());
386                     resultList.add(new Attribute JavaDoc(name, value));
387                 } else if (equalsProperty(name, ProxoolConstants.FATAL_SQL_EXCEPTION_WRAPPER_CLASS)) {
388                     checkAssignable(name, Boolean JavaDoc.class, value);
389                     newProperties.setProperty(ProxoolConstants.FATAL_SQL_EXCEPTION_WRAPPER_CLASS_PROPERTY, value.toString());
390                     resultList.add(new Attribute JavaDoc(name, value));
391                 } else {
392                     final String JavaDoc message = "Unknown attribute: " + name;
393                     LOG.error(message);
394                     throw new AttributeNotFoundException JavaDoc(message);
395                 }
396             } catch (InvalidAttributeValueException JavaDoc e) {
397                 final String JavaDoc message = "Attribute value was illegal: " + e.getMessage();
398                 LOG.error(message);
399                 throw new RuntimeOperationsException JavaDoc(new RuntimeException JavaDoc(message));
400             } catch (AttributeNotFoundException JavaDoc e) {
401                 throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc(e.getMessage()));
402             }
403         }
404         try {
405             ProxoolFacade.updateConnectionPool(ProxoolConstants.PROPERTY_PREFIX + this.poolDefinition.getAlias(), newProperties);
406         } catch (ProxoolException e) {
407             LOG.error("Update of Proxool pool failed: ", e);
408             throw new RuntimeOperationsException JavaDoc(new RuntimeException JavaDoc(e.getMessage()));
409         }
410         return resultList;
411     }
412
413     /**
414      * @see javax.management.DynamicMBean#invoke(java.lang.String, java.lang.Object[], java.lang.String[])
415      */

416     public Object JavaDoc invoke(String JavaDoc operationName, Object JavaDoc params[], String JavaDoc signature[]) throws MBeanException JavaDoc, ReflectionException JavaDoc {
417         if (operationName == null) {
418             throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("Operation name cannot be null"), "Cannot invoke a null operation in " + CLASS_NAME);
419         } else if (operationName.equals(OPERATION_NAME_SHUTDOWN)) {
420             try {
421                 ProxoolFacade.removeConnectionPool(this.poolDefinition.getAlias());
422             } catch (ProxoolException e) {
423                 LOG.error("Shutdown of pool " + this.poolDefinition.getAlias() + " failed.", e);
424             }
425             return null;
426         } else {
427             throw new ReflectionException JavaDoc(new NoSuchMethodException JavaDoc(operationName),
428                     "Cannot find the operation " + operationName + ".");
429         }
430     }
431
432     /**
433      * @see javax.management.DynamicMBean#getMBeanInfo()
434      */

435     public MBeanInfo JavaDoc getMBeanInfo() {
436         return mBeanInfo;
437     }
438
439     private MBeanInfo JavaDoc getDynamicMBeanInfo(String JavaDoc alias) {
440         final MBeanAttributeInfo JavaDoc[] attributeInfos = new MBeanAttributeInfo JavaDoc[]{
441             createProxoolAttribute(ProxoolConstants.ALIAS, String JavaDoc.class, false),
442             createProxoolAttribute(ProxoolConstants.DRIVER_PROPERTIES, String JavaDoc.class),
443             createProxoolAttribute(ProxoolConstants.DRIVER_URL, String JavaDoc.class),
444             createProxoolAttribute(ProxoolConstants.FATAL_SQL_EXCEPTION, String JavaDoc.class),
445             createProxoolAttribute(ProxoolConstants.HOUSE_KEEPING_SLEEP_TIME, Integer JavaDoc.class),
446             createProxoolAttribute(ProxoolConstants.HOUSE_KEEPING_TEST_SQL, String JavaDoc.class),
447             createProxoolAttribute(ProxoolConstants.TEST_BEFORE_USE, Boolean JavaDoc.class),
448             createProxoolAttribute(ProxoolConstants.TEST_AFTER_USE, Boolean JavaDoc.class),
449             createProxoolAttribute(ProxoolConstants.MAXIMUM_ACTIVE_TIME, Integer JavaDoc.class),
450             createProxoolAttribute(ProxoolConstants.MAXIMUM_CONNECTION_COUNT, Integer JavaDoc.class),
451             createProxoolAttribute(ProxoolConstants.MAXIMUM_CONNECTION_LIFETIME, Integer JavaDoc.class),
452             createProxoolAttribute(ProxoolConstants.SIMULTANEOUS_BUILD_THROTTLE, Integer JavaDoc.class),
453             createProxoolAttribute(ProxoolConstants.MINIMUM_CONNECTION_COUNT, Integer JavaDoc.class),
454             createProxoolAttribute(ProxoolConstants.OVERLOAD_WITHOUT_REFUSAL_LIFETIME, Integer JavaDoc.class),
455             createProxoolAttribute(ProxoolConstants.PROTOTYPE_COUNT, Integer JavaDoc.class),
456             createProxoolAttribute(ProxoolConstants.RECENTLY_STARTED_THRESHOLD, Integer JavaDoc.class),
457             createProxoolAttribute(ProxoolConstants.STATISTICS, String JavaDoc.class),
458             createProxoolAttribute(ProxoolConstants.STATISTICS_LOG_LEVEL, String JavaDoc.class),
459             createProxoolAttribute(ProxoolConstants.TRACE, Boolean JavaDoc.class),
460             createProxoolAttribute(ProxoolConstants.VERBOSE, Boolean JavaDoc.class),
461             createProxoolAttribute(ProxoolConstants.FATAL_SQL_EXCEPTION_WRAPPER_CLASS, String JavaDoc.class),
462         };
463
464         final MBeanConstructorInfo JavaDoc[] constructorInfos = new MBeanConstructorInfo JavaDoc[]{
465             new MBeanConstructorInfo JavaDoc("ConnectionPoolMBean(): Construct a ConnectionPoolMBean object.", ConnectionPoolMBean.class.getConstructors()[0])
466         };
467
468         final MBeanOperationInfo JavaDoc[] operationInfos = new MBeanOperationInfo JavaDoc[]{
469             new MBeanOperationInfo JavaDoc(OPERATION_NAME_SHUTDOWN, "Stop and dispose this connection pool.",
470                     new MBeanParameterInfo JavaDoc[]{}, "void", MBeanOperationInfo.ACTION)
471         };
472
473         return new MBeanInfo JavaDoc(CLASS_NAME, MessageFormat.format(getJMXText(RECOURCE_NAME_MBEAN_POOL_DESCRIPTION),
474                 new Object JavaDoc[]{alias}), attributeInfos, constructorInfos, operationInfos, new MBeanNotificationInfo JavaDoc[0]);
475     }
476
477     private static String JavaDoc getAttributeDescription(String JavaDoc attributeName) {
478         String JavaDoc description = "";
479         if (ATTRIBUTE_DESCRIPTIONS_RESOURCE != null) {
480             try {
481                 description = ATTRIBUTE_DESCRIPTIONS_RESOURCE.getString(attributeName);
482             } catch (Exception JavaDoc e) {
483                 LOG.warn("Could not get description for attribute '" + attributeName + "' from resource " + ResourceNamesIF.ATTRIBUTE_DESCRIPTIONS + ".");
484             }
485         }
486         return description;
487     }
488
489     private static String JavaDoc getJMXText(String JavaDoc key) {
490         String JavaDoc value = "";
491         if (JMX_RESOURCE != null) {
492             try {
493                 value = JMX_RESOURCE.getString(key);
494             } catch (Exception JavaDoc e) {
495                 LOG.warn("Could not get value for attribute '" + key + "' from resource " + ResourceNamesIF.JMX + ".");
496             }
497         }
498         return value;
499     }
500
501     private static ResourceBundle JavaDoc createAttributeDescriptionsResource() {
502         try {
503             return ResourceBundle.getBundle(ResourceNamesIF.ATTRIBUTE_DESCRIPTIONS);
504         } catch (Exception JavaDoc e) {
505             LOG.error("Could not find resource " + ResourceNamesIF.ATTRIBUTE_DESCRIPTIONS, e);
506         }
507         return null;
508     }
509
510     private static ResourceBundle JavaDoc createJMXResource() {
511         try {
512             return ResourceBundle.getBundle(ResourceNamesIF.JMX);
513         } catch (Exception JavaDoc e) {
514             LOG.error("Could not find resource " + ResourceNamesIF.JMX, e);
515         }
516         return null;
517     }
518
519     private static MBeanAttributeInfo JavaDoc createProxoolAttribute(String JavaDoc attributeName, Class JavaDoc type) {
520         return createProxoolAttribute(attributeName, type, true);
521     }
522
523     private static MBeanAttributeInfo JavaDoc createProxoolAttribute(String JavaDoc attributeName, Class JavaDoc type, boolean writable) {
524         return new MBeanAttributeInfo JavaDoc(ProxoolJMXHelper.getValidIdentifier(attributeName), type.getName(),
525                 getAttributeDescription(attributeName), true, writable, false);
526     }
527
528     private void checkAssignable(String JavaDoc name, Class JavaDoc clazz, Object JavaDoc value) throws InvalidAttributeValueException JavaDoc {
529         if (value == null) {
530             if (!String JavaDoc.class.equals(clazz)) {
531                 throw(new InvalidAttributeValueException JavaDoc("Cannot set attribute " + name + " to null "
532                         + " an instance of " + clazz.getName() + " expected."));
533             }
534         } else {
535             Class JavaDoc valueClass = value.getClass();
536             if (!clazz.isAssignableFrom(valueClass)) {
537                 throw(new InvalidAttributeValueException JavaDoc("Cannot set attribute " + name + " to a " + valueClass.getName()
538                         + " instance, " + clazz.getName() + " expected."));
539             }
540         }
541     }
542
543     private boolean equalsProperty(String JavaDoc beanAttribute, String JavaDoc proxoolProperty) {
544         return beanAttribute.equals(ProxoolJMXHelper.getValidIdentifier(proxoolProperty));
545     }
546
547     private void setDelegateProperties(Properties JavaDoc properties, String JavaDoc propertyString)
548             throws InvalidAttributeValueException JavaDoc {
549         if (propertyString == null || propertyString.trim().length() == 0) {
550             return;
551         }
552         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(propertyString, ",");
553         String JavaDoc keyValuePair = null;
554         int equalsIndex = -1;
555         while (tokenizer.hasMoreElements()) {
556             keyValuePair = tokenizer.nextToken().trim();
557             equalsIndex = keyValuePair.indexOf("=");
558             if (equalsIndex != -1) {
559                 properties.put(keyValuePair.substring(0, equalsIndex).trim(),
560                         keyValuePair.substring(equalsIndex + 1).trim());
561             } else {
562                 throw new InvalidAttributeValueException JavaDoc("Could not find key/value delimiter '=' in property definition: '"
563                         + keyValuePair + "'.");
564             }
565         }
566     }
567
568     private String JavaDoc getDelegatePropertiesAsString(Properties JavaDoc properties) {
569         final StringBuffer JavaDoc result = new StringBuffer JavaDoc();
570         Iterator JavaDoc keyIterator = properties.keySet().iterator();
571         String JavaDoc key = null;
572         boolean first = true;
573         while (keyIterator.hasNext()) {
574             key = (String JavaDoc) keyIterator.next();
575             if (!key.startsWith(ProxoolConstants.PROPERTY_PREFIX)) {
576                 if (!first) {
577                     result.append(", ");
578                 } else {
579                     first = false;
580                 }
581                 result.append(key).append("=").append(properties.getProperty(key));
582             }
583         }
584         return result.toString();
585     }
586
587     private boolean notEmpty(Object JavaDoc object) {
588         return object != null && object.toString().trim().length() > 0;
589     }
590
591     private boolean notEmptyOrZero(Integer JavaDoc integer) {
592         return integer != null && integer.intValue() > 0;
593     }
594
595     private String JavaDoc getValueOrEmpty(String JavaDoc property) {
596         return property == null ? "" : property;
597     }
598
599     private void setIntegerAttribute(String JavaDoc attributeName, String JavaDoc propertyName, Object JavaDoc value, int defaultValue, Properties JavaDoc properties,
600                                      AttributeList JavaDoc resultList) throws InvalidAttributeValueException JavaDoc {
601         checkAssignable(attributeName, Integer JavaDoc.class, value);
602         if (notEmptyOrZero((Integer JavaDoc) value)) {
603             properties.setProperty(propertyName, value.toString());
604             resultList.add(new Attribute JavaDoc(attributeName, value));
605         } else {
606             resultList.add(new Attribute JavaDoc(attributeName,
607                     new Integer JavaDoc(defaultValue)));
608         }
609     }
610
611     private boolean isEqualProperties(String JavaDoc property1, String JavaDoc property2) {
612         if (property1 == null) {
613             return property2 == null;
614         } else if (property2 == null) {
615             return property1 == null;
616         } else {
617             return property1.equals(property2);
618         }
619     }
620
621     private static MBeanNotificationInfo JavaDoc[] getNotificationInfos() {
622         return new MBeanNotificationInfo JavaDoc[]{
623             new MBeanNotificationInfo JavaDoc(
624                     new String JavaDoc[]{NOTIFICATION_TYPE_DEFINITION_UPDATED}, Notification JavaDoc.class.getName(), getJMXText(RECOURCE_NAME_MBEAN_NOTIFICATION_DESCRIPTION))
625         };
626     }
627
628     // Listener methods
629

630     /**
631      * Not used.
632      * @see org.logicalcobwebs.proxool.ProxoolListenerIF#onRegistration(org.logicalcobwebs.proxool.ConnectionPoolDefinitionIF, java.util.Properties)
633      */

634     public void onRegistration(ConnectionPoolDefinitionIF connectionPoolDefinition, Properties JavaDoc completeInfo) {
635         // Not used.
636
}
637
638     /**
639      * If the given alias equals this pools alias: Unregister this JMX bean.
640      * @see org.logicalcobwebs.proxool.ProxoolListenerIF#onShutdown(java.lang.String)
641      */

642     public void onShutdown(String JavaDoc alias) {
643         if (alias.equals(this.poolDefinition.getAlias())) {
644             if (this.active) {
645                 this.active = false;
646                 ProxoolJMXHelper.unregisterPool(this.poolDefinition.getAlias(), this.poolProperties);
647                 LOG.info(this.poolDefinition.getAlias() + " MBean unregistered.");
648             }
649         }
650     }
651
652     /**
653      * Update the attributes of this MBean and emit a {@link #NOTIFICATION_TYPE_DEFINITION_UPDATED} event.
654      * @see org.logicalcobwebs.proxool.ConfigurationListenerIF#definitionUpdated(org.logicalcobwebs.proxool.ConnectionPoolDefinitionIF, java.util.Properties, java.util.Properties)
655      */

656     public void definitionUpdated(ConnectionPoolDefinitionIF connectionPoolDefinition, Properties JavaDoc completeInfo,
657                                   Properties JavaDoc changedInfo) {
658         this.poolDefinition = connectionPoolDefinition;
659         this.poolProperties = completeInfo;
660         this.notificationHelper.sendNotification(new Notification JavaDoc(NOTIFICATION_TYPE_DEFINITION_UPDATED, this,
661                 definitionUpdatedSequence++, System.currentTimeMillis(),
662                 getJMXText(RECOURCE_NAME_MBEAN_NOTIFICATION_DEF_UPDATED)));
663     }
664
665     /**
666      * @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
667      */

668     public void addNotificationListener(NotificationListener JavaDoc notificationListener, NotificationFilter JavaDoc notificationFilter,
669                                         Object JavaDoc handBack) throws IllegalArgumentException JavaDoc {
670         this.notificationHelper.addNotificationListener(notificationListener, notificationFilter, handBack);
671     }
672
673     /**
674      * @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener)
675      */

676     public void removeNotificationListener(NotificationListener JavaDoc notificationListener) throws ListenerNotFoundException JavaDoc {
677         this.notificationHelper.removeNotificationListener(notificationListener);
678     }
679
680     /**
681      * @see javax.management.NotificationBroadcaster#getNotificationInfo()
682      */

683     public MBeanNotificationInfo JavaDoc[] getNotificationInfo() {
684         return NOTIFICATION_INFOS;
685     }
686
687     /**
688      * @see javax.management.MBeanRegistration#preRegister(javax.management.MBeanServer, javax.management.ObjectName)
689      */

690     public ObjectName JavaDoc preRegister(MBeanServer JavaDoc mBeanServer, ObjectName JavaDoc objectName) throws Exception JavaDoc {
691         if (objectName == null) {
692             throw new ProxoolException("objectName was null, but we can not construct an MBean instance without knowing"
693                     + " the pool alias.");
694         }
695         return objectName;
696     }
697
698     /**
699      * @see javax.management.MBeanRegistration#postRegister(java.lang.Boolean)
700      */

701     public void postRegister(Boolean JavaDoc success) {
702         if (success.booleanValue() == true) {
703             this.active = true;
704         }
705     }
706
707     /**
708      * @see javax.management.MBeanRegistration#preDeregister()
709      */

710     public void preDeregister() throws Exception JavaDoc {
711         this.active = false;
712     }
713
714     /**
715      * @see javax.management.MBeanRegistration#postDeregister()
716      */

717     public void postDeregister() {
718     }
719 }
720
721 /*
722  Revision history:
723  $Log: ConnectionPoolMBean.java,v $
724  Revision 1.15 2006/01/18 14:39:55 billhorsman
725  Unbundled Jakarta's Commons Logging.
726
727  Revision 1.14 2003/10/20 07:37:07 chr32
728  Bettered handling of empty values. Now not setting attributes that has not changed.
729
730  Revision 1.13 2003/09/30 18:38:27 billhorsman
731  New properties
732
733  Revision 1.12 2003/09/29 17:48:08 billhorsman
734  New fatal-sql-exception-wrapper-class allows you to define what exception is used as a wrapper. This means that you
735  can make it a RuntimeException if you need to.
736
737  Revision 1.11 2003/09/14 21:29:31 chr32
738  Added support for wrap-fatal-sql-exceptions,statistics and statistics-log-level properties.
739
740  Revision 1.10 2003/09/10 22:21:04 chr32
741  Removing > jdk 1.2 dependencies.
742
743  Revision 1.9 2003/05/06 23:15:55 chr32
744  Moving JMX classes back in from sandbox.
745
746  Revision 1.1 2003/03/07 16:35:17 billhorsman
747  moved jmx stuff into sandbox until it is tested
748
749  Revision 1.7 2003/03/05 23:28:56 billhorsman
750  deprecated maximum-new-connections property in favour of
751  more descriptive simultaneous-build-throttle
752
753  Revision 1.6 2003/03/03 11:11:59 billhorsman
754  fixed licence
755
756  Revision 1.5 2003/02/26 19:04:30 chr32
757  Added active/inactive state check.
758
759  Revision 1.4 2003/02/26 16:37:48 billhorsman
760  fixed spelling in ConfigurationListenerIF
761
762  Revision 1.3 2003/02/25 16:50:31 chr32
763  Added JMX notification and doc.
764
765  Revision 1.2 2003/02/24 18:01:57 chr32
766  1st working version.
767
768  Revision 1.1 2003/02/24 01:14:17 chr32
769  Init rev (unfinished).
770
771 */
Popular Tags