1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved. 5 * 6 */ 7 8 package com.sleepycat.je.jmx; 9 10 import java.io.File; 11 import java.util.ArrayList; 12 import java.util.List; 13 14 import javax.management.Attribute; 15 import javax.management.AttributeNotFoundException; 16 import javax.management.InvalidAttributeValueException; 17 import javax.management.MBeanAttributeInfo; 18 import javax.management.MBeanException; 19 import javax.management.MBeanNotificationInfo; 20 import javax.management.MBeanOperationInfo; 21 import javax.management.MBeanParameterInfo; 22 23 import com.sleepycat.je.CheckpointConfig; 24 import com.sleepycat.je.Database; 25 import com.sleepycat.je.DatabaseConfig; 26 import com.sleepycat.je.DatabaseException; 27 import com.sleepycat.je.DatabaseExistsException; 28 import com.sleepycat.je.DatabaseNotFoundException; 29 import com.sleepycat.je.DatabaseStats; 30 import com.sleepycat.je.DbInternal; 31 import com.sleepycat.je.Environment; 32 import com.sleepycat.je.EnvironmentConfig; 33 import com.sleepycat.je.EnvironmentFailureException; 34 import com.sleepycat.je.EnvironmentMutableConfig; 35 import com.sleepycat.je.StatsConfig; 36 37 /** 38 * @deprecated As of JE 4, JEMBeanHelper is deprecated in favor of the concrete 39 * MBeans available by default with a JE environment. These MBeans can be 40 * registered and enabled by the environment by setting the following JVM 41 * property: 42 * JEMonitor: 43 * This MBean provides general stats monitoring and access to basic 44 * environment level operations. 45 * 46 * JEMBeanHelper is a utility class for the MBean implementation which wants to 47 * add management of a JE environment to its capabilities. MBean 48 * implementations can contain a JEMBeanHelper instance to get MBean metadata 49 * for JE and to set attributes, get attributes, and invoke operations. 50 * <p> 51 * com.sleepycat.je.jmx.JEMonitor and the example program 52 * jmx.JEApplicationMBean are two MBean implementations which provide support 53 * different application use cases. See those classes for examples of how to 54 * use JEMBeanHelper. 55 */ 56 public class JEMBeanHelper { 57 58 /* 59 * A note to JE developers: all available JE attributes and operations are 60 * described in the following static info arrays. New management 61 * functionality can be added to the helper by adding to the appropriate 62 * set of static definitions. For example, if we want to add a new JE 63 * attribute called "foo", which is available for open environments, we 64 * need to define a new MBeanAttributeInfo in the OPEN_ATTR array. The 65 * helper then needs to provide an implementation in set/getAttribute. 66 */ 67 68 /* Attribute names. */ 69 public static final String ATT_ENV_HOME = "environmentHome"; 70 public static final String ATT_OPEN = "isOpen"; 71 public static final String ATT_IS_READ_ONLY = "isReadOnly"; 72 public static final String ATT_IS_TRANSACTIONAL = "isTransactional"; 73 public static final String ATT_CACHE_SIZE = "cacheSize"; 74 public static final String ATT_CACHE_PERCENT = "cachePercent"; 75 public static final String ATT_LOCK_TIMEOUT = "lockTimeout"; 76 public static final String ATT_IS_SERIALIZABLE = "isSerializableIsolation"; 77 public static final String ATT_TXN_TIMEOUT = "transactionTimeout"; 78 public static final String ATT_SET_READ_ONLY = "openReadOnly"; 79 public static final String ATT_SET_TRANSACTIONAL = "openTransactional"; 80 public static final String ATT_SET_SERIALIZABLE = 81 "openSerializableIsolation"; 82 83 /* COMMON_ATTR attributes are available for any environment. */ 84 private static final MBeanAttributeInfo[] COMMON_ATTR = { 85 86 new MBeanAttributeInfo(ATT_ENV_HOME, 87 "java.lang.String", 88 "Environment home directory.", 89 true, // readable 90 false, // writable 91 false), // isIs 92 new MBeanAttributeInfo(ATT_OPEN, 93 "java.lang.Boolean", 94 "True if this environment is open.", 95 true, // readable 96 false, // writable 97 true) // isIs 98 }; 99 100 /* OPEN_ATTR attributes are available for all open environments. */ 101 private static final MBeanAttributeInfo[] OPEN_ATTR = { 102 103 new MBeanAttributeInfo(ATT_IS_READ_ONLY, 104 "java.lang.Boolean", 105 "True if this environment is read only.", 106 true, // readable 107 false, // writable 108 true), // isIs 109 new MBeanAttributeInfo(ATT_IS_TRANSACTIONAL, 110 "java.lang.Boolean", 111 "True if this environment supports transactions.", 112 true, // readable 113 false, // writable 114 true), // isIs 115 new MBeanAttributeInfo(ATT_CACHE_SIZE, 116 "java.lang.Long", 117 "Cache size, in bytes.", 118 true, // readable 119 true, // writable 120 false), // isIs 121 new MBeanAttributeInfo(ATT_CACHE_PERCENT, 122 "java.lang.Integer", 123 "By default, cache size is (cachePercent * " + 124 "JVM maximum memory. To change the cache size "+ 125 "using a percentage of the heap size, set " + 126 "the cache size to 0 and cachePercent to the "+ 127 "desired percentage value.", 128 true, // readable 129 true, // writable 130 false), // isIs 131 new MBeanAttributeInfo(ATT_LOCK_TIMEOUT, 132 "java.lang.Long", 133 "Lock timeout, in microseconds.", 134 true, // readable 135 false, // writable 136 false), // isIs 137 }; 138 139 /* 140 * TRANSACTIONAL_ATTR attributes are available only for open, transactional 141 * environments. 142 */ 143 private static final MBeanAttributeInfo[] TRANSACTIONAL_ATTR = { 144 145 new MBeanAttributeInfo(ATT_IS_SERIALIZABLE, 146 "java.lang.Boolean", 147 "True if this environment provides " + 148 "Serializable (degree 3) isolation. The " + 149 "default is RepeatableRead isolation.", 150 true, // readable 151 false, // writable 152 true), // isIs 153 new MBeanAttributeInfo(ATT_TXN_TIMEOUT, 154 "java.lang.Long", 155 "Transaction timeout, in seconds. A value " + 156 "of 0 means there is no timeout.", 157 true, // readable 158 false, // writable 159 false) // isIs 160 }; 161 162 /* 163 * CREATE_ATTR attributes are available when the mbean is configured to 164 * support configuration and opening by the mbean. They express the 165 * configuration settings. 166 */ 167 private static final MBeanAttributeInfo[] CREATE_ATTR = { 168 169 new MBeanAttributeInfo(ATT_SET_READ_ONLY, 170 "java.lang.Boolean", 171 "True if this environment should be opened " + 172 "in readonly mode.", 173 true, // readable 174 true, // writable 175 false), // isIs 176 new MBeanAttributeInfo(ATT_SET_TRANSACTIONAL, 177 "java.lang.Boolean", 178 "True if this environment should be opened " + 179 "in transactional mode.", 180 true, // readable 181 true, // writable 182 false), // isIs 183 new MBeanAttributeInfo(ATT_SET_SERIALIZABLE, 184 "java.lang.Boolean", 185 "True if this environment should be opened " + 186 "with serializableIsolation. The default is "+ 187 "false.", 188 true, // readable 189 true, // writable 190 false), // isIs 191 }; 192 193 /* Operation names */ 194 static final String OP_CLEAN = "cleanLog"; 195 static final String OP_EVICT = "evictMemory"; 196 static final String OP_CHECKPOINT = "checkpoint"; 197 static final String OP_SYNC = "sync"; 198 static final String OP_ENV_STAT = "getEnvironmentStats"; 199 static final String OP_TXN_STAT = "getTxnStats"; 200 static final String OP_DB_NAMES = "getDatabaseNames"; 201 static final String OP_DB_STAT = "getDatabaseStats"; 202 203 private static final MBeanOperationInfo OP_CLEAN_INFO = 204 new MBeanOperationInfo(OP_CLEAN, 205 "Remove obsolete environment log files. " + 206 "Zero or more log files will be cleaned as " + 207 "necessary to bring the disk space " + 208 "utilization of the environment above the " + 209 "configured minimum utilization threshold " + 210 "as determined by the setting " + 211 "je.cleaner.minUtilization. Returns the " + 212 "number of files cleaned, that will be " + 213 "deleted at the next qualifying checkpoint.", 214 new MBeanParameterInfo[0], // no params 215 "java.lang.Integer", 216 MBeanOperationInfo.UNKNOWN); 217 218 private static final MBeanOperationInfo OP_EVICT_INFO = 219 new MBeanOperationInfo(OP_EVICT, 220 "Reduce cache usage to the threshold " + 221 "determined by the setting " + 222 "je.evictor.useMemoryFloor. ", 223 new MBeanParameterInfo[0], // no params 224 "void", 225 MBeanOperationInfo.UNKNOWN); 226 227 /* parameter for checkpoint operation. */ 228 private static final MBeanParameterInfo[] checkpointParams = { 229 new MBeanParameterInfo("force", "java.lang.Boolean", 230 "If true, force a checkpoint even if " + 231 "there has been no activity since the last " + 232 "checkpoint. Returns true if a checkpoint " + 233 "executed.") 234 }; 235 236 private static final MBeanOperationInfo OP_CHECKPOINT_INFO = 237 new MBeanOperationInfo(OP_CHECKPOINT, 238 "Checkpoint the environment.", 239 checkpointParams, 240 "void", 241 MBeanOperationInfo.UNKNOWN); 242 243 private static final MBeanOperationInfo OP_SYNC_INFO = 244 new MBeanOperationInfo(OP_SYNC, 245 "Flush the environment to stable storage.", 246 new MBeanParameterInfo[0], // no params 247 "void", 248 MBeanOperationInfo.UNKNOWN); 249 250 private static final MBeanParameterInfo[] statParams = { 251 new MBeanParameterInfo("clear", "java.lang.Boolean", 252 "If true, reset statistics after reading."), 253 new MBeanParameterInfo("fast", "java.lang.Boolean", 254 "If true, only return statistics which do " + 255 "not require expensive computation.") 256 }; 257 258 private static final MBeanOperationInfo OP_ENV_STAT_INFO = 259 new MBeanOperationInfo(OP_ENV_STAT, 260 "Get environment statistics.", 261 statParams, 262 "java.lang.String", 263 MBeanOperationInfo.INFO); 264 265 private static final MBeanOperationInfo OP_TXN_STAT_INFO = 266 new MBeanOperationInfo(OP_TXN_STAT, 267 "Get transactional statistics.", 268 statParams, 269 "java.lang.String", 270 MBeanOperationInfo.INFO); 271 272 private static final MBeanOperationInfo OP_DB_NAMES_INFO = 273 new MBeanOperationInfo(OP_DB_NAMES, 274 "Get the names of databases in the environment.", 275 new MBeanParameterInfo[0], // no params 276 "java.util.ArrayList", 277 MBeanOperationInfo.INFO); 278 279 private static final MBeanParameterInfo[] dbStatParams = { 280 new MBeanParameterInfo("clear", "java.lang.Boolean", 281 "If true, reset statistics after reading."), 282 new MBeanParameterInfo("fast", "java.lang.Boolean", 283 "If true, only return statistics which do " + 284 "not require expensive computation. " + 285 "Currently all database stats are not fast."), 286 new MBeanParameterInfo("databaseName", "java.lang.String", 287 "database name") 288 }; 289 290 private static final MBeanOperationInfo OP_DB_STAT_INFO = 291 new MBeanOperationInfo(OP_DB_STAT, 292 "Get database statistics.", 293 dbStatParams, 294 "java.lang.String", 295 MBeanOperationInfo.INFO); 296 297 /* target JE environment home directory. */ 298 private File environmentHome; 299 300 /* 301 * If canConfigure is true, this helper will make environment configuration 302 * attributes available in the mbean metadata. Configuration attributes 303 * will be saved in the openConfig instance. 304 */ 305 private boolean canConfigure; 306 private EnvironmentConfig openConfig; 307 308 /* true if the mbean metadata needs to be refreshed. */ 309 private boolean needReset; 310 311 /* 312 * Save whether the environment was open the last time we fetched mbean 313 * attributes. Use to detect a change in environment status. 314 */ 315 private boolean envWasOpen; 316 317 /** 318 * Instantiate a helper, specifying environment home and open capabilities. 319 * 320 * @param environmentHome home directory of the target JE environment. 321 * @param canConfigure If true, the helper will show environment 322 * configuration attributes. 323 */ JEMBeanHelper(File environmentHome, boolean canConfigure)324 public JEMBeanHelper(File environmentHome, boolean canConfigure) { 325 326 if (environmentHome == null) { 327 throw new IllegalArgumentException 328 ("Environment home cannot be null"); 329 } 330 this.environmentHome = environmentHome; 331 this.canConfigure = canConfigure; 332 if (canConfigure) { 333 openConfig = new EnvironmentConfig(); 334 } 335 } 336 337 /** 338 * Return the target environment directory. 339 * 340 * @return the environment directory. 341 */ getEnvironmentHome()342 public File getEnvironmentHome() { 343 return environmentHome; 344 } 345 346 /** 347 * If the helper was instantiated with canConfigure==true, it shows 348 * environment configuration attributes. Those attributes are returned 349 * within this EnvironmentConfig object for use in opening environments. 350 * 351 * @return EnvironmentConfig object which saves configuration attributes 352 * recorded through MBean attributes. 353 */ getEnvironmentOpenConfig()354 public EnvironmentConfig getEnvironmentOpenConfig() { 355 return openConfig; 356 } 357 358 /** 359 * Return an Environment only if the environment has already been opened 360 * in this process. A helper method for MBeans which want to only access 361 * open environments. 362 * 363 * @return Environment if already open, null if not open. 364 */ getEnvironmentIfOpen()365 public Environment getEnvironmentIfOpen() { 366 if (environmentHome == null) { 367 return null; 368 } 369 370 return DbInternal.getEnvironmentShell(environmentHome); 371 } 372 373 /** 374 * Tell the MBean if the available set of functionality has changed. 375 * 376 * @return true if the MBean should regenerate its JE metadata. 377 */ getNeedReset()378 public synchronized boolean getNeedReset() { 379 return needReset; 380 } 381 382 /** 383 * Get MBean attribute metadata for this environment. 384 * @param targetEnv The target JE environment. May be null if the 385 * environment is not open. 386 * @return list of MBeanAttributeInfo objects describing the available 387 * attributes. 388 */ getAttributeList(Environment targetEnv)389 public List<MBeanAttributeInfo> getAttributeList(Environment targetEnv) { 390 391 /* Turn off reset because the mbean metadata is being refreshed. */ 392 setNeedReset(false); 393 394 ArrayList<MBeanAttributeInfo> attrList = 395 new ArrayList<MBeanAttributeInfo>(); 396 397 /* Add attributes for all JE environments. */ 398 for (int i = 0; i < COMMON_ATTR.length; i++) { 399 attrList.add(COMMON_ATTR[i]); 400 } 401 402 if (targetEnv == null) { 403 if (canConfigure) { 404 /* Add attributes for configuring an environment. */ 405 for (int i = 0; i < CREATE_ATTR.length; i++) { 406 attrList.add(CREATE_ATTR[i]); 407 } 408 } 409 } else { 410 /* Add attributes for an open environment. */ 411 for (int i = 0; i < OPEN_ATTR.length; i++) { 412 attrList.add(OPEN_ATTR[i]); 413 } 414 415 /* Add attributes for an open, transactional environment. */ 416 try { 417 EnvironmentConfig config = targetEnv.getConfig(); 418 if (config.getTransactional()) { 419 for (int i = 0; i < TRANSACTIONAL_ATTR.length; i++) { 420 attrList.add(TRANSACTIONAL_ATTR[i]); 421 } 422 } 423 } catch (DatabaseException ignore) { 424 /* ignore */ 425 } 426 } 427 428 return attrList; 429 } 430 431 /** 432 * Get an attribute value for the given environment. Check 433 * JEMBeanHelper.getNeedReset() after this call because the helper may 434 * detect that the environment has changed and that the MBean metadata 435 * should be reset. 436 * 437 * @param targetEnv The target JE environment. May be null if the 438 * environment is not open. 439 * @param attributeName attribute name. 440 * @return attribute value. 441 */ getAttribute(Environment targetEnv, String attributeName)442 public Object getAttribute(Environment targetEnv, String attributeName) 443 throws AttributeNotFoundException, 444 MBeanException { 445 446 /* Sanity check. */ 447 if (attributeName == null) { 448 throw new AttributeNotFoundException 449 ("Attribute name cannot be null"); 450 } 451 452 /* These attributes are available regardless of environment state. */ 453 try { 454 if (attributeName.equals(ATT_ENV_HOME)) { 455 return environmentHome.getCanonicalPath(); 456 } else if (attributeName.equals(ATT_OPEN)) { 457 boolean envIsOpen = (targetEnv != null); 458 resetIfOpenStateChanged(envIsOpen); 459 return new Boolean(envIsOpen); 460 } else if (attributeName.equals(ATT_SET_READ_ONLY)) { 461 return new Boolean(openConfig.getReadOnly()); 462 } else if (attributeName.equals(ATT_SET_TRANSACTIONAL)) { 463 return new Boolean(openConfig.getTransactional()); 464 } else if (attributeName.equals(ATT_SET_SERIALIZABLE)) { 465 return new Boolean(openConfig.getTxnSerializableIsolation()); 466 } else { 467 /* The rest are JE environment attributes. */ 468 if (targetEnv != null) { 469 470 EnvironmentConfig config = targetEnv.getConfig(); 471 472 if (attributeName.equals(ATT_IS_READ_ONLY)) { 473 return new Boolean(config.getReadOnly()); 474 } else if (attributeName.equals(ATT_IS_TRANSACTIONAL)) { 475 return new Boolean(config.getTransactional()); 476 } else if (attributeName.equals(ATT_CACHE_SIZE)) { 477 return new Long(config.getCacheSize()); 478 } else if (attributeName.equals(ATT_CACHE_PERCENT)) { 479 return new Integer(config.getCachePercent()); 480 } else if (attributeName.equals(ATT_LOCK_TIMEOUT)) { 481 return new Long(config.getLockTimeout()); 482 } else if (attributeName.equals(ATT_IS_SERIALIZABLE)) { 483 return new 484 Boolean(config.getTxnSerializableIsolation()); 485 } else if (attributeName.equals(ATT_TXN_TIMEOUT)) { 486 return new Long(config.getTxnTimeout()); 487 } else { 488 throw new AttributeNotFoundException 489 ("attribute " + attributeName + " is not valid."); 490 } 491 } 492 return null; 493 } 494 } catch (Exception e) { 495 496 /* 497 * Add both the message and the exception for easiest deciphering 498 * of the problem. Sometimes the original exception stacktrace gets 499 * hidden in server logs. 500 */ 501 throw new MBeanException(e, e.getMessage()); 502 } 503 } 504 505 /** 506 * Set an attribute value for the given environment. 507 * 508 * @param targetEnv The target JE environment. May be null if the 509 * environment is not open. 510 * @param attribute name/value pair 511 */ setAttribute(Environment targetEnv, Attribute attribute)512 public void setAttribute(Environment targetEnv, Attribute attribute) 513 throws AttributeNotFoundException, 514 InvalidAttributeValueException { 515 516 if (attribute == null) { 517 throw new AttributeNotFoundException("Attribute cannot be null"); 518 } 519 520 /* Sanity check parameters. */ 521 String name = attribute.getName(); 522 Object value = attribute.getValue(); 523 524 if (name == null) { 525 throw new AttributeNotFoundException 526 ("Attribute name cannot be null"); 527 } 528 529 if (value == null) { 530 throw new InvalidAttributeValueException 531 ("Attribute value for attribute " + name + " cannot be null"); 532 } 533 534 try { 535 if (name.equals(ATT_SET_READ_ONLY)) { 536 openConfig.setReadOnly(((Boolean) value).booleanValue()); 537 } else if (name.equals(ATT_SET_TRANSACTIONAL)) { 538 openConfig.setTransactional(((Boolean) value).booleanValue()); 539 } else if (name.equals(ATT_SET_SERIALIZABLE)) { 540 openConfig.setTxnSerializableIsolation 541 (((Boolean) value).booleanValue()); 542 } else { 543 /* Set the specified attribute if the environment is open. */ 544 if (targetEnv != null) { 545 546 EnvironmentMutableConfig config = 547 targetEnv.getMutableConfig(); 548 549 if (name.equals(ATT_CACHE_SIZE)) { 550 config.setCacheSize(((Long) value).longValue()); 551 targetEnv.setMutableConfig(config); 552 } else if (name.equals(ATT_CACHE_PERCENT)) { 553 config.setCachePercent(((Integer) value).intValue()); 554 targetEnv.setMutableConfig(config); 555 } else { 556 throw new AttributeNotFoundException 557 ("attribute " + name + " is not valid."); 558 } 559 } else { 560 throw new AttributeNotFoundException 561 ("attribute " + name + " is not valid."); 562 } 563 } 564 } catch (NumberFormatException e) { 565 throw new InvalidAttributeValueException("attribute name=" + name); 566 } catch (DatabaseException e) { 567 throw new InvalidAttributeValueException 568 ("attribute name=" + name + e.getMessage()); 569 } 570 } 571 572 /********************************************************************/ 573 /* JE Operations */ 574 /********************************************************************/ 575 576 /** 577 * Get mbean operation metadata for this environment. 578 * 579 * @param targetEnv The target JE environment. May be null if the 580 * environment is not open. 581 * @return List of MBeanOperationInfo describing available operations. 582 */ getOperationList(Environment targetEnv)583 public List<MBeanOperationInfo> getOperationList(Environment targetEnv) { 584 setNeedReset(false); 585 586 List<MBeanOperationInfo> operationList = 587 new ArrayList<MBeanOperationInfo>(); 588 589 if (targetEnv != null) { 590 591 /* 592 * These operations are only available if the environment is open. 593 */ 594 operationList.add(OP_CLEAN_INFO); 595 operationList.add(OP_EVICT_INFO); 596 operationList.add(OP_ENV_STAT_INFO); 597 operationList.add(OP_DB_NAMES_INFO); 598 operationList.add(OP_DB_STAT_INFO); 599 600 /* Add checkpoint only for transactional environments. */ 601 boolean isTransactional = false; 602 try { 603 EnvironmentConfig config = targetEnv.getConfig(); 604 isTransactional = config.getTransactional(); 605 } catch (DatabaseException e) { 606 /* Don't make any operations available. */ 607 return new ArrayList<MBeanOperationInfo>(); 608 } 609 610 if (isTransactional) { 611 operationList.add(OP_CHECKPOINT_INFO); 612 operationList.add(OP_TXN_STAT_INFO); 613 } else { 614 operationList.add(OP_SYNC_INFO); 615 } 616 } 617 618 return operationList; 619 } 620 621 /** 622 * Invoke an operation for the given environment. 623 * 624 * @param targetEnv The target JE environment. May be null if the 625 * environment is not open. 626 * @param actionName operation name. 627 * @param params operation parameters. May be null. 628 * @param signature operation signature. May be null. 629 * @return the operation result 630 */ invoke(Environment targetEnv, String actionName, Object[] params, String[] signature)631 public Object invoke(Environment targetEnv, 632 String actionName, 633 Object[] params, 634 String[] signature) 635 throws MBeanException { 636 637 /* Sanity checking. */ 638 if (actionName == null) { 639 throw new IllegalArgumentException("actionName cannot be null"); 640 } 641 642 try { 643 if (targetEnv != null) { 644 if (actionName.equals(OP_CLEAN)) { 645 int numFiles = targetEnv.cleanLog(); 646 return new Integer(numFiles); 647 } else if (actionName.equals(OP_EVICT)) { 648 targetEnv.evictMemory(); 649 return null; 650 } else if (actionName.equals(OP_CHECKPOINT)) { 651 CheckpointConfig config = new CheckpointConfig(); 652 if ((params != null) && (params.length > 0)) { 653 Boolean force = (Boolean) params[0]; 654 config.setForce(force.booleanValue()); 655 } 656 targetEnv.checkpoint(config); 657 return null; 658 } else if (actionName.equals(OP_SYNC)) { 659 targetEnv.sync(); 660 return null; 661 } else if (actionName.equals(OP_ENV_STAT)) { 662 return targetEnv.getStats 663 (getStatsConfig(params)).toString(); 664 } else if (actionName.equals(OP_TXN_STAT)) { 665 return targetEnv.getTransactionStats 666 (getStatsConfig(params)).toString(); 667 } else if (actionName.equals(OP_DB_NAMES)) { 668 return targetEnv.getDatabaseNames(); 669 } else if (actionName.equals(OP_DB_STAT)) { 670 DatabaseStats stats = getDatabaseStats(targetEnv, params); 671 return stats != null ? stats.toString() : null; 672 } 673 } 674 675 return new IllegalArgumentException 676 ("actionName: " + actionName + " is not valid"); 677 } catch (Exception e) { 678 679 /* 680 * Add both the message and the exception for easiest deciphering 681 * of the problem. Sometimes the original exception stacktrace gets 682 * hidden in server logs. 683 */ 684 throw new MBeanException(e, e.getMessage()); 685 } 686 } 687 688 /** 689 * Helper for creating a StatsConfig object to use as an operation 690 * parameter. 691 */ getStatsConfig(Object[] params)692 private StatsConfig getStatsConfig(Object[] params) { 693 StatsConfig statsConfig = new StatsConfig(); 694 if ((params != null) && (params.length > 0) && (params[0] != null)) { 695 Boolean clear = (Boolean) params[0]; 696 statsConfig.setClear(clear.booleanValue()); 697 } 698 if ((params != null) && (params.length > 1) && (params[1] != null)) { 699 Boolean fast = (Boolean) params[1]; 700 statsConfig.setFast(fast.booleanValue()); 701 } 702 return statsConfig; 703 } 704 705 /** 706 * Helper to get statistics for a given database. 707 * @param params operation parameters 708 * @return DatabaseStats object 709 */ getDatabaseStats(Environment targetEnv, Object[] params)710 private DatabaseStats getDatabaseStats(Environment targetEnv, 711 Object[] params) 712 throws IllegalArgumentException, 713 DatabaseNotFoundException, 714 DatabaseException { 715 716 if ((params == null) || (params.length < 3)) { 717 return null; 718 } 719 String dbName = (String)params[2]; 720 721 Database db = null; 722 try { 723 DatabaseConfig dbConfig = new DatabaseConfig(); 724 dbConfig.setReadOnly(true); 725 DbInternal.setUseExistingConfig(dbConfig, true); 726 try { 727 db = targetEnv.openDatabase(null, dbName, dbConfig); 728 } catch (DatabaseExistsException e) { 729 /* Should never happen, ExlcusiveCreate is false. */ 730 throw EnvironmentFailureException.unexpectedException(e); 731 } 732 return db.getStats(getStatsConfig(params)); 733 } finally { 734 if (db != null) { 735 db.close(); 736 } 737 } 738 } 739 740 /** 741 * No notifications are supported. 742 * @return List of MBeanNotificationInfo for available notifications. 743 */ 744 public MBeanNotificationInfo[] getNotificationInfo(Environment targetEnv)745 getNotificationInfo(Environment targetEnv) { 746 return null; 747 } 748 setNeedReset(boolean reset)749 private synchronized void setNeedReset(boolean reset) { 750 needReset = reset; 751 } 752 resetIfOpenStateChanged(boolean isOpen)753 private synchronized void resetIfOpenStateChanged(boolean isOpen) { 754 if (isOpen != envWasOpen) { 755 setNeedReset(true); 756 envWasOpen = isOpen; 757 } 758 } 759 } 760