1 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 ; 19 import javax.management.MBeanOperationInfo ; 20 import javax.management.MBeanConstructorInfo ; 21 import javax.management.MBeanAttributeInfo ; 22 import javax.management.MBeanNotificationInfo ; 23 import javax.management.DynamicMBean ; 24 import javax.management.AttributeNotFoundException ; 25 import javax.management.MBeanException ; 26 import javax.management.ReflectionException ; 27 import javax.management.RuntimeOperationsException ; 28 import javax.management.Attribute ; 29 import javax.management.InvalidAttributeValueException ; 30 import javax.management.AttributeList ; 31 import javax.management.MBeanParameterInfo ; 32 import javax.management.NotificationBroadcaster ; 33 import javax.management.NotificationBroadcasterSupport ; 34 import javax.management.NotificationListener ; 35 import javax.management.NotificationFilter ; 36 import javax.management.ListenerNotFoundException ; 37 import javax.management.Notification ; 38 import javax.management.MBeanRegistration ; 39 import javax.management.ObjectName ; 40 import javax.management.MBeanServer ; 41 42 import java.util.Iterator ; 43 import java.util.ResourceBundle ; 44 import java.util.Properties ; 45 import java.util.StringTokenizer ; 46 import java.text.MessageFormat ; 47 48 91 public class ConnectionPoolMBean implements DynamicMBean , MBeanRegistration , NotificationBroadcaster , 92 ProxoolListenerIF, ConfigurationListenerIF { 93 96 public static final String NOTIFICATION_TYPE_DEFINITION_UPDATED = "proxool.definitionUpdated"; 97 98 99 private static final Log LOG = LogFactory.getLog(ConnectionPoolMBean.class); 100 private static final String CLASS_NAME = ConnectionPoolMBean.class.getName(); 101 102 private static final String RECOURCE_NAME_MBEAN_POOL_DESCRIPTION = "mbean.pool.description"; 103 private static final String RECOURCE_NAME_MBEAN_NOTIFICATION_DESCRIPTION = "mbean.notification.description"; 104 private static final String RECOURCE_NAME_MBEAN_NOTIFICATION_DEF_UPDATED = "mbean.notification.defUpdated"; 105 106 private static final String OPERATION_NAME_SHUTDOWN = "shutdown"; 107 108 private static final ResourceBundle ATTRIBUTE_DESCRIPTIONS_RESOURCE = createAttributeDescriptionsResource(); 109 private static final ResourceBundle JMX_RESOURCE = createJMXResource(); 110 111 private static final MBeanNotificationInfo [] NOTIFICATION_INFOS = getNotificationInfos(); 112 113 private MBeanInfo mBeanInfo; 114 private ConnectionPoolDefinitionIF poolDefinition; 115 private Properties poolProperties; 116 private long definitionUpdatedSequence; 117 private NotificationBroadcasterSupport notificationHelper = new NotificationBroadcasterSupport (); 118 private boolean active; 119 120 public ConnectionPoolMBean(String alias, Properties 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 133 public Object getAttribute(String attributeName) throws AttributeNotFoundException , MBeanException , ReflectionException { 134 if (attributeName == null) { 135 final String message = "Cannot invoke a getter of " + CLASS_NAME + " with null attribute name"; 136 LOG.error(message); 137 throw new RuntimeOperationsException (new IllegalArgumentException ("Attribute name cannot be null"), 138 message); 139 } 140 if (LOG.isDebugEnabled()) { 141 LOG.debug("Getting attribute " + attributeName + "."); 142 } 143 return ((Attribute ) getAttributes(new String []{attributeName}).get(0)).getValue(); 144 } 145 146 149 public void setAttribute(Attribute attribute) throws AttributeNotFoundException , InvalidAttributeValueException , 150 MBeanException , ReflectionException { 151 if (attribute == null) { 152 final String message = "Cannot invoke a setter of " + CLASS_NAME + " with null attribute"; 153 LOG.error(message); 154 throw new RuntimeOperationsException (new IllegalArgumentException ("Attribute cannot be null"), 155 message); 156 } 157 if (LOG.isDebugEnabled()) { 158 LOG.debug("Setting attribute " + attribute.getName() + "."); 159 } 160 final AttributeList attributeList = new AttributeList (); 161 attributeList.add(attribute); 162 setAttributes(attributeList); 163 } 164 165 168 public AttributeList getAttributes(String [] attributeNames) { 169 if (attributeNames == null) { 170 final String message = "Cannot invoke a null getter of " + CLASS_NAME; 171 LOG.error(message); 172 throw new RuntimeOperationsException (new IllegalArgumentException ("attributeNames[] cannot be null"), 173 message); 174 } 175 AttributeList resultList = new AttributeList (); 176 177 if (attributeNames.length == 0) { 179 return resultList; 180 } 181 182 for (int i = 0; i < attributeNames.length; i++) { 184 try { 185 if (equalsProperty(attributeNames[i], ProxoolConstants.ALIAS)) { 186 resultList.add(new Attribute (attributeNames[i], 187 this.poolDefinition.getAlias())); 188 } else if (equalsProperty(attributeNames[i], ProxoolConstants.DRIVER_PROPERTIES)) { 189 resultList.add(new Attribute (attributeNames[i], 190 getDelegatePropertiesAsString(this.poolProperties))); 191 } else if (equalsProperty(attributeNames[i], ProxoolConstants.DRIVER_URL)) { 192 resultList.add(new Attribute (attributeNames[i], 193 this.poolDefinition.getUrl())); 194 } else if (equalsProperty(attributeNames[i], ProxoolConstants.FATAL_SQL_EXCEPTION)) { 195 resultList.add(new Attribute (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 (attributeNames[i], 199 new Integer (this.poolDefinition.getHouseKeepingSleepTime()))); 200 } else if (equalsProperty(attributeNames[i], ProxoolConstants.HOUSE_KEEPING_TEST_SQL)) { 201 resultList.add(new Attribute (attributeNames[i], 202 getValueOrEmpty(poolDefinition.getHouseKeepingTestSql()))); 203 } else if (equalsProperty(attributeNames[i], ProxoolConstants.TEST_BEFORE_USE)) { 204 resultList.add(new Attribute (attributeNames[i], 205 new Boolean (this.poolDefinition.isTestBeforeUse()))); 206 } else if (equalsProperty(attributeNames[i], ProxoolConstants.TEST_AFTER_USE)) { 207 resultList.add(new Attribute (attributeNames[i], 208 new Boolean (this.poolDefinition.isTestAfterUse()))); 209 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MAXIMUM_ACTIVE_TIME)) { 210 resultList.add(new Attribute (attributeNames[i], 211 new Integer (this.poolDefinition.getMaximumActiveTime()))); 212 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MAXIMUM_CONNECTION_COUNT)) { 213 resultList.add(new Attribute (attributeNames[i], 214 new Integer (this.poolDefinition.getMaximumConnectionCount()))); 215 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MAXIMUM_CONNECTION_LIFETIME)) { 216 resultList.add(new Attribute (attributeNames[i], 217 new Integer (this.poolDefinition.getMaximumConnectionLifetime()))); 218 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MAXIMUM_NEW_CONNECTIONS)) { 219 resultList.add(new Attribute (attributeNames[i], 220 new Integer (this.poolDefinition.getMaximumNewConnections()))); 221 } else if (equalsProperty(attributeNames[i], ProxoolConstants.SIMULTANEOUS_BUILD_THROTTLE)) { 222 resultList.add(new Attribute (attributeNames[i], 223 new Integer (this.poolDefinition.getSimultaneousBuildThrottle()))); 224 } else if (equalsProperty(attributeNames[i], ProxoolConstants.MINIMUM_CONNECTION_COUNT)) { 225 resultList.add(new Attribute (attributeNames[i], 226 new Integer (this.poolDefinition.getMinimumConnectionCount()))); 227 } else if (equalsProperty(attributeNames[i], ProxoolConstants.OVERLOAD_WITHOUT_REFUSAL_LIFETIME)) { 228 resultList.add(new Attribute (attributeNames[i], 229 new Integer (this.poolDefinition.getOverloadWithoutRefusalLifetime()))); 230 } else if (equalsProperty(attributeNames[i], ProxoolConstants.PROTOTYPE_COUNT)) { 231 resultList.add(new Attribute (attributeNames[i], 232 new Integer (this.poolDefinition.getPrototypeCount()))); 233 } else if (equalsProperty(attributeNames[i], ProxoolConstants.RECENTLY_STARTED_THRESHOLD)) { 234 resultList.add(new Attribute (attributeNames[i], 235 new Integer (this.poolDefinition.getRecentlyStartedThreshold()))); 236 } else if (equalsProperty(attributeNames[i], ProxoolConstants.STATISTICS)) { 237 resultList.add(new Attribute (attributeNames[i], 238 getValueOrEmpty(this.poolDefinition.getStatistics()))); 239 } else if (equalsProperty(attributeNames[i], ProxoolConstants.STATISTICS_LOG_LEVEL)) { 240 resultList.add(new Attribute (attributeNames[i], 241 getValueOrEmpty(this.poolDefinition.getStatisticsLogLevel()))); 242 } else if (equalsProperty(attributeNames[i], ProxoolConstants.TRACE)) { 243 resultList.add(new Attribute (attributeNames[i], 244 new Boolean (this.poolDefinition.isTrace()))); 245 } else if (equalsProperty(attributeNames[i], ProxoolConstants.VERBOSE)) { 246 resultList.add(new Attribute (attributeNames[i], 247 new Boolean (this.poolDefinition.isVerbose()))); 248 } else if (equalsProperty(attributeNames[i], ProxoolConstants.FATAL_SQL_EXCEPTION_WRAPPER_CLASS)) { 249 resultList.add(new Attribute (attributeNames[i], 250 getValueOrEmpty(this.poolDefinition.getFatalSqlExceptionWrapper()))); 251 } else { 252 final String message = "Unknown attribute: " + attributeNames[i]; 253 LOG.error(message); 254 throw new AttributeNotFoundException (message); 255 } 256 } catch (AttributeNotFoundException e) { 257 throw new RuntimeOperationsException (new IllegalArgumentException (e.getMessage())); 258 } 259 } 260 return resultList; 261 } 262 263 266 public AttributeList setAttributes(AttributeList attributes) { 267 268 if (attributes == null) { 269 final String message = "AttributeList attributes cannot be null"; 270 LOG.error(message); 271 throw new RuntimeOperationsException (new IllegalArgumentException (message), 272 "Cannot invoke a setter of " + CLASS_NAME); 273 } 274 AttributeList resultList = new AttributeList (); 275 276 if (attributes.isEmpty()) { 277 return resultList; 278 } 279 280 String name = null; 281 Object value = null; 282 final Properties newProperties = new Properties (); 283 Attribute attribute = null; 284 for (Iterator i = attributes.iterator(); i.hasNext();) { 285 attribute = (Attribute ) 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 .class, value); 293 setDelegateProperties(newProperties, value.toString()); 294 resultList.add(new Attribute (name, value)); 295 } 296 } else if (equalsProperty(name, ProxoolConstants.DRIVER_URL)) { 297 checkAssignable(name, String .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 (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 .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 (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 .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 (name, value)); 326 } else if (equalsProperty(name, ProxoolConstants.TEST_BEFORE_USE)) { 327 checkAssignable(name, Boolean .class, value); 328 newProperties.setProperty(ProxoolConstants.TEST_BEFORE_USE_PROPERTY, value.toString()); 329 resultList.add(new Attribute (name, value)); 330 } else if (equalsProperty(name, ProxoolConstants.TEST_AFTER_USE)) { 331 checkAssignable(name, Boolean .class, value); 332 newProperties.setProperty(ProxoolConstants.TEST_AFTER_USE_PROPERTY, value.toString()); 333 resultList.add(new Attribute (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 .class, value); 351 newProperties.setProperty(ProxoolConstants.MINIMUM_CONNECTION_COUNT_PROPERTY, value.toString()); 352 resultList.add(new Attribute (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 .class, value); 358 newProperties.setProperty(ProxoolConstants.PROTOTYPE_COUNT_PROPERTY, value.toString()); 359 resultList.add(new Attribute (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 .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 (name, value)); 371 } else if (equalsProperty(name, ProxoolConstants.STATISTICS_LOG_LEVEL)) { 372 checkAssignable(name, String .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 (name, value)); 379 } else if (equalsProperty(name, ProxoolConstants.TRACE)) { 380 checkAssignable(name, Boolean .class, value); 381 newProperties.setProperty(ProxoolConstants.TRACE_PROPERTY, value.toString()); 382 resultList.add(new Attribute (name, value)); 383 } else if (equalsProperty(name, ProxoolConstants.VERBOSE)) { 384 checkAssignable(name, Boolean .class, value); 385 newProperties.setProperty(ProxoolConstants.VERBOSE_PROPERTY, value.toString()); 386 resultList.add(new Attribute (name, value)); 387 } else if (equalsProperty(name, ProxoolConstants.FATAL_SQL_EXCEPTION_WRAPPER_CLASS)) { 388 checkAssignable(name, Boolean .class, value); 389 newProperties.setProperty(ProxoolConstants.FATAL_SQL_EXCEPTION_WRAPPER_CLASS_PROPERTY, value.toString()); 390 resultList.add(new Attribute (name, value)); 391 } else { 392 final String message = "Unknown attribute: " + name; 393 LOG.error(message); 394 throw new AttributeNotFoundException (message); 395 } 396 } catch (InvalidAttributeValueException e) { 397 final String message = "Attribute value was illegal: " + e.getMessage(); 398 LOG.error(message); 399 throw new RuntimeOperationsException (new RuntimeException (message)); 400 } catch (AttributeNotFoundException e) { 401 throw new RuntimeOperationsException (new IllegalArgumentException (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 (new RuntimeException (e.getMessage())); 409 } 410 return resultList; 411 } 412 413 416 public Object invoke(String operationName, Object params[], String signature[]) throws MBeanException , ReflectionException { 417 if (operationName == null) { 418 throw new RuntimeOperationsException (new IllegalArgumentException ("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 (new NoSuchMethodException (operationName), 428 "Cannot find the operation " + operationName + "."); 429 } 430 } 431 432 435 public MBeanInfo getMBeanInfo() { 436 return mBeanInfo; 437 } 438 439 private MBeanInfo getDynamicMBeanInfo(String alias) { 440 final MBeanAttributeInfo [] attributeInfos = new MBeanAttributeInfo []{ 441 createProxoolAttribute(ProxoolConstants.ALIAS, String .class, false), 442 createProxoolAttribute(ProxoolConstants.DRIVER_PROPERTIES, String .class), 443 createProxoolAttribute(ProxoolConstants.DRIVER_URL, String .class), 444 createProxoolAttribute(ProxoolConstants.FATAL_SQL_EXCEPTION, String .class), 445 createProxoolAttribute(ProxoolConstants.HOUSE_KEEPING_SLEEP_TIME, Integer .class), 446 createProxoolAttribute(ProxoolConstants.HOUSE_KEEPING_TEST_SQL, String .class), 447 createProxoolAttribute(ProxoolConstants.TEST_BEFORE_USE, Boolean .class), 448 createProxoolAttribute(ProxoolConstants.TEST_AFTER_USE, Boolean .class), 449 createProxoolAttribute(ProxoolConstants.MAXIMUM_ACTIVE_TIME, Integer .class), 450 createProxoolAttribute(ProxoolConstants.MAXIMUM_CONNECTION_COUNT, Integer .class), 451 createProxoolAttribute(ProxoolConstants.MAXIMUM_CONNECTION_LIFETIME, Integer .class), 452 createProxoolAttribute(ProxoolConstants.SIMULTANEOUS_BUILD_THROTTLE, Integer .class), 453 createProxoolAttribute(ProxoolConstants.MINIMUM_CONNECTION_COUNT, Integer .class), 454 createProxoolAttribute(ProxoolConstants.OVERLOAD_WITHOUT_REFUSAL_LIFETIME, Integer .class), 455 createProxoolAttribute(ProxoolConstants.PROTOTYPE_COUNT, Integer .class), 456 createProxoolAttribute(ProxoolConstants.RECENTLY_STARTED_THRESHOLD, Integer .class), 457 createProxoolAttribute(ProxoolConstants.STATISTICS, String .class), 458 createProxoolAttribute(ProxoolConstants.STATISTICS_LOG_LEVEL, String .class), 459 createProxoolAttribute(ProxoolConstants.TRACE, Boolean .class), 460 createProxoolAttribute(ProxoolConstants.VERBOSE, Boolean .class), 461 createProxoolAttribute(ProxoolConstants.FATAL_SQL_EXCEPTION_WRAPPER_CLASS, String .class), 462 }; 463 464 final MBeanConstructorInfo [] constructorInfos = new MBeanConstructorInfo []{ 465 new MBeanConstructorInfo ("ConnectionPoolMBean(): Construct a ConnectionPoolMBean object.", ConnectionPoolMBean.class.getConstructors()[0]) 466 }; 467 468 final MBeanOperationInfo [] operationInfos = new MBeanOperationInfo []{ 469 new MBeanOperationInfo (OPERATION_NAME_SHUTDOWN, "Stop and dispose this connection pool.", 470 new MBeanParameterInfo []{}, "void", MBeanOperationInfo.ACTION) 471 }; 472 473 return new MBeanInfo (CLASS_NAME, MessageFormat.format(getJMXText(RECOURCE_NAME_MBEAN_POOL_DESCRIPTION), 474 new Object []{alias}), attributeInfos, constructorInfos, operationInfos, new MBeanNotificationInfo [0]); 475 } 476 477 private static String getAttributeDescription(String attributeName) { 478 String description = ""; 479 if (ATTRIBUTE_DESCRIPTIONS_RESOURCE != null) { 480 try { 481 description = ATTRIBUTE_DESCRIPTIONS_RESOURCE.getString(attributeName); 482 } catch (Exception 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 getJMXText(String key) { 490 String value = ""; 491 if (JMX_RESOURCE != null) { 492 try { 493 value = JMX_RESOURCE.getString(key); 494 } catch (Exception 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 createAttributeDescriptionsResource() { 502 try { 503 return ResourceBundle.getBundle(ResourceNamesIF.ATTRIBUTE_DESCRIPTIONS); 504 } catch (Exception e) { 505 LOG.error("Could not find resource " + ResourceNamesIF.ATTRIBUTE_DESCRIPTIONS, e); 506 } 507 return null; 508 } 509 510 private static ResourceBundle createJMXResource() { 511 try { 512 return ResourceBundle.getBundle(ResourceNamesIF.JMX); 513 } catch (Exception e) { 514 LOG.error("Could not find resource " + ResourceNamesIF.JMX, e); 515 } 516 return null; 517 } 518 519 private static MBeanAttributeInfo createProxoolAttribute(String attributeName, Class type) { 520 return createProxoolAttribute(attributeName, type, true); 521 } 522 523 private static MBeanAttributeInfo createProxoolAttribute(String attributeName, Class type, boolean writable) { 524 return new MBeanAttributeInfo (ProxoolJMXHelper.getValidIdentifier(attributeName), type.getName(), 525 getAttributeDescription(attributeName), true, writable, false); 526 } 527 528 private void checkAssignable(String name, Class clazz, Object value) throws InvalidAttributeValueException { 529 if (value == null) { 530 if (!String .class.equals(clazz)) { 531 throw(new InvalidAttributeValueException ("Cannot set attribute " + name + " to null " 532 + " an instance of " + clazz.getName() + " expected.")); 533 } 534 } else { 535 Class valueClass = value.getClass(); 536 if (!clazz.isAssignableFrom(valueClass)) { 537 throw(new InvalidAttributeValueException ("Cannot set attribute " + name + " to a " + valueClass.getName() 538 + " instance, " + clazz.getName() + " expected.")); 539 } 540 } 541 } 542 543 private boolean equalsProperty(String beanAttribute, String proxoolProperty) { 544 return beanAttribute.equals(ProxoolJMXHelper.getValidIdentifier(proxoolProperty)); 545 } 546 547 private void setDelegateProperties(Properties properties, String propertyString) 548 throws InvalidAttributeValueException { 549 if (propertyString == null || propertyString.trim().length() == 0) { 550 return; 551 } 552 StringTokenizer tokenizer = new StringTokenizer (propertyString, ","); 553 String 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 ("Could not find key/value delimiter '=' in property definition: '" 563 + keyValuePair + "'."); 564 } 565 } 566 } 567 568 private String getDelegatePropertiesAsString(Properties properties) { 569 final StringBuffer result = new StringBuffer (); 570 Iterator keyIterator = properties.keySet().iterator(); 571 String key = null; 572 boolean first = true; 573 while (keyIterator.hasNext()) { 574 key = (String ) 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 object) { 588 return object != null && object.toString().trim().length() > 0; 589 } 590 591 private boolean notEmptyOrZero(Integer integer) { 592 return integer != null && integer.intValue() > 0; 593 } 594 595 private String getValueOrEmpty(String property) { 596 return property == null ? "" : property; 597 } 598 599 private void setIntegerAttribute(String attributeName, String propertyName, Object value, int defaultValue, Properties properties, 600 AttributeList resultList) throws InvalidAttributeValueException { 601 checkAssignable(attributeName, Integer .class, value); 602 if (notEmptyOrZero((Integer ) value)) { 603 properties.setProperty(propertyName, value.toString()); 604 resultList.add(new Attribute (attributeName, value)); 605 } else { 606 resultList.add(new Attribute (attributeName, 607 new Integer (defaultValue))); 608 } 609 } 610 611 private boolean isEqualProperties(String property1, String 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 [] getNotificationInfos() { 622 return new MBeanNotificationInfo []{ 623 new MBeanNotificationInfo ( 624 new String []{NOTIFICATION_TYPE_DEFINITION_UPDATED}, Notification .class.getName(), getJMXText(RECOURCE_NAME_MBEAN_NOTIFICATION_DESCRIPTION)) 625 }; 626 } 627 628 630 634 public void onRegistration(ConnectionPoolDefinitionIF connectionPoolDefinition, Properties completeInfo) { 635 } 637 638 642 public void onShutdown(String 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 656 public void definitionUpdated(ConnectionPoolDefinitionIF connectionPoolDefinition, Properties completeInfo, 657 Properties changedInfo) { 658 this.poolDefinition = connectionPoolDefinition; 659 this.poolProperties = completeInfo; 660 this.notificationHelper.sendNotification(new Notification (NOTIFICATION_TYPE_DEFINITION_UPDATED, this, 661 definitionUpdatedSequence++, System.currentTimeMillis(), 662 getJMXText(RECOURCE_NAME_MBEAN_NOTIFICATION_DEF_UPDATED))); 663 } 664 665 668 public void addNotificationListener(NotificationListener notificationListener, NotificationFilter notificationFilter, 669 Object handBack) throws IllegalArgumentException { 670 this.notificationHelper.addNotificationListener(notificationListener, notificationFilter, handBack); 671 } 672 673 676 public void removeNotificationListener(NotificationListener notificationListener) throws ListenerNotFoundException { 677 this.notificationHelper.removeNotificationListener(notificationListener); 678 } 679 680 683 public MBeanNotificationInfo [] getNotificationInfo() { 684 return NOTIFICATION_INFOS; 685 } 686 687 690 public ObjectName preRegister(MBeanServer mBeanServer, ObjectName objectName) throws Exception { 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 701 public void postRegister(Boolean success) { 702 if (success.booleanValue() == true) { 703 this.active = true; 704 } 705 } 706 707 710 public void preDeregister() throws Exception { 711 this.active = false; 712 } 713 714 717 public void postDeregister() { 718 } 719 } 720 721 | Popular Tags |