1 8 9 package com.sleepycat.je.jmx; 10 11 import java.io.File ; 12 import java.util.ArrayList ; 13 import java.util.List ; 14 15 import javax.management.Attribute ; 16 import javax.management.AttributeNotFoundException ; 17 import javax.management.InvalidAttributeValueException ; 18 import javax.management.MBeanAttributeInfo ; 19 import javax.management.MBeanException ; 20 import javax.management.MBeanNotificationInfo ; 21 import javax.management.MBeanOperationInfo ; 22 import javax.management.MBeanParameterInfo ; 23 24 import com.sleepycat.je.CheckpointConfig; 25 import com.sleepycat.je.Database; 26 import com.sleepycat.je.DatabaseConfig; 27 import com.sleepycat.je.DatabaseException; 28 import com.sleepycat.je.DatabaseStats; 29 import com.sleepycat.je.DbInternal; 30 import com.sleepycat.je.Environment; 31 import com.sleepycat.je.EnvironmentConfig; 32 import com.sleepycat.je.EnvironmentMutableConfig; 33 import com.sleepycat.je.StatsConfig; 34 35 46 47 public class JEMBeanHelper { 48 49 58 59 60 61 62 public static final String ATT_ENV_HOME = "environmentHome"; 63 public static final String ATT_OPEN = "isOpen"; 64 public static final String ATT_IS_READ_ONLY = "isReadOnly"; 65 public static final String ATT_IS_TRANSACTIONAL = "isTransactional"; 66 public static final String ATT_CACHE_SIZE = "cacheSize"; 67 public static final String ATT_CACHE_PERCENT = "cachePercent"; 68 public static final String ATT_LOCK_TIMEOUT = "lockTimeout"; 69 public static final String ATT_IS_SERIALIZABLE = "isSerializableIsolation"; 70 public static final String ATT_TXN_TIMEOUT = "transactionTimeout"; 71 public static final String ATT_SET_READ_ONLY = "openReadOnly"; 72 public static final String ATT_SET_TRANSACTIONAL = "openTransactional"; 73 public static final String ATT_SET_SERIALIZABLE = 74 "openSerializableIsolation"; 75 76 77 private static final MBeanAttributeInfo [] COMMON_ATTR = { 78 79 new MBeanAttributeInfo (ATT_ENV_HOME, 80 "java.lang.String", 81 "Environment home directory.", 82 true, false, false), new MBeanAttributeInfo (ATT_OPEN, 86 "java.lang.Boolean", 87 "True if this environment is open.", 88 true, false, true) }; 92 93 94 private static final MBeanAttributeInfo [] OPEN_ATTR = { 95 96 new MBeanAttributeInfo (ATT_IS_READ_ONLY, 97 "java.lang.Boolean", 98 "True if this environment is read only.", 99 true, false, true), new MBeanAttributeInfo (ATT_IS_TRANSACTIONAL, 103 "java.lang.Boolean", 104 "True if this environment supports transactions.", 105 true, false, true), new MBeanAttributeInfo (ATT_CACHE_SIZE, 109 "java.lang.Long", 110 "Cache size, in bytes.", 111 true, true, false), new MBeanAttributeInfo (ATT_CACHE_PERCENT, 115 "java.lang.Integer", 116 "By default, cache size is (cachePercent * " + 117 "JVM maximum memory. To change the cache size "+ 118 "using a percentage of the heap size, set " + 119 "the cache size to 0 and cachePercent to the "+ 120 "desired percentage value.", 121 true, true, false), new MBeanAttributeInfo (ATT_LOCK_TIMEOUT, 125 "java.lang.Long", 126 "Lock timeout, in microseconds.", 127 true, false, false), }; 131 132 136 private static final MBeanAttributeInfo [] TRANSACTIONAL_ATTR = { 137 138 new MBeanAttributeInfo (ATT_IS_SERIALIZABLE, 139 "java.lang.Boolean", 140 "True if this environment provides " + 141 "Serializable (degree 3) isolation. The " + 142 "default is RepeatableRead isolation.", 143 true, false, true), new MBeanAttributeInfo (ATT_TXN_TIMEOUT, 147 "java.lang.Long", 148 "Transaction timeout, in seconds. A value " + 149 "of 0 means there is no timeout.", 150 true, false, false) }; 154 155 160 private static final MBeanAttributeInfo [] CREATE_ATTR = { 161 162 new MBeanAttributeInfo (ATT_SET_READ_ONLY, 163 "java.lang.Boolean", 164 "True if this environment should be opened " + 165 "in readonly mode.", 166 true, true, false), new MBeanAttributeInfo (ATT_SET_TRANSACTIONAL, 170 "java.lang.Boolean", 171 "True if this environment should be opened " + 172 "in transactional mode.", 173 true, true, false), new MBeanAttributeInfo (ATT_SET_SERIALIZABLE, 177 "java.lang.Boolean", 178 "True if this environment should be opened " + 179 "with serializableIsolation. The default is "+ 180 "false.", 181 true, true, false), }; 185 186 187 188 189 static final String OP_CLEAN = "cleanLog"; 190 static final String OP_EVICT = "evictMemory"; 191 static final String OP_CHECKPOINT = "checkpoint"; 192 static final String OP_SYNC = "sync"; 193 static final String OP_ENV_STAT = "getEnvironmentStats"; 194 static final String OP_LOCK_STAT = "getLockStats"; 195 static final String OP_TXN_STAT = "getTxnStats"; 196 static final String OP_DB_NAMES = "getDatabaseNames"; 197 static final String OP_DB_STAT = "getDatabaseStats"; 198 199 private static final MBeanOperationInfo OP_CLEAN_INFO = 200 new MBeanOperationInfo (OP_CLEAN, 201 "Remove obsolete environment log files. " + 202 "Zero or more log files will be cleaned as " + 203 "necessary to bring the disk space " + 204 "utilization of the environment above the " + 205 "configured minimum utilization threshold " + 206 "as determined by the setting " + 207 "je.cleaner.minUtilization. Returns the " + 208 "number of files cleaned, that will be " + 209 "deleted at the next qualifying checkpoint.", 210 new MBeanParameterInfo [0], "java.lang.Integer", 212 MBeanOperationInfo.UNKNOWN); 213 214 private static final MBeanOperationInfo OP_EVICT_INFO = 215 new MBeanOperationInfo (OP_EVICT, 216 "Reduce cache usage to the threshold " + 217 "determined by the setting " + 218 "je.evictor.useMemoryFloor. ", 219 new MBeanParameterInfo [0], "void", 221 MBeanOperationInfo.UNKNOWN); 222 223 224 private static final MBeanParameterInfo [] checkpointParams = { 225 new MBeanParameterInfo ("force", "java.lang.Boolean", 226 "If true, force a checkpoint even if " + 227 "there has been no activity since the last " + 228 "checkpoint. Returns true if a checkpoint " + 229 "executed.") 230 }; 231 232 private static final MBeanOperationInfo OP_CHECKPOINT_INFO = 233 new MBeanOperationInfo (OP_CHECKPOINT, 234 "Checkpoint the environment.", 235 checkpointParams, 236 "void", 237 MBeanOperationInfo.UNKNOWN); 238 239 private static final MBeanOperationInfo OP_SYNC_INFO = 240 new MBeanOperationInfo (OP_SYNC, 241 "Flush the environment to stable storage.", 242 new MBeanParameterInfo [0], "void", 244 MBeanOperationInfo.UNKNOWN); 245 246 private static final MBeanParameterInfo [] statParams = { 247 new MBeanParameterInfo ("clear", "java.lang.Boolean", 248 "If true, reset statistics after reading."), 249 new MBeanParameterInfo ("fast", "java.lang.Boolean", 250 "If true, only return statistics which do " + 251 "not require expensive computation.") 252 253 }; 254 255 private static final MBeanOperationInfo OP_ENV_STAT_INFO = 256 new MBeanOperationInfo (OP_ENV_STAT, 257 "Get environment statistics.", 258 statParams, 259 "com.sleepycat.je.EnvironmentStats", 260 MBeanOperationInfo.INFO); 261 262 private static final MBeanOperationInfo OP_LOCK_STAT_INFO = 263 new MBeanOperationInfo (OP_LOCK_STAT, 264 "Get locking statistics.", 265 statParams, 266 "com.sleepycat.je.LockStats", 267 MBeanOperationInfo.INFO); 268 269 private static final MBeanOperationInfo OP_TXN_STAT_INFO = 270 new MBeanOperationInfo (OP_TXN_STAT, 271 "Get transactional statistics.", 272 statParams, 273 "com.sleepycat.je.TransactionStats", 274 MBeanOperationInfo.INFO); 275 276 private static final MBeanOperationInfo OP_DB_NAMES_INFO = 277 new MBeanOperationInfo (OP_DB_NAMES, 278 "Get the names of databases in the environment.", 279 new MBeanParameterInfo [0], "java.util.ArrayList", 281 MBeanOperationInfo.INFO); 282 283 private static final MBeanParameterInfo [] dbStatParams = { 284 new MBeanParameterInfo ("clear", "java.lang.Boolean", 285 "If true, reset statistics after reading."), 286 new MBeanParameterInfo ("fast", "java.lang.Boolean", 287 "If true, only return statistics which do " + 288 "not require expensive computation. " + 289 "Currently all database stats are not fast."), 290 new MBeanParameterInfo ("databaseName", "java.lang.String", 291 "database name") 292 293 }; 294 295 private static final MBeanOperationInfo OP_DB_STAT_INFO = 296 new MBeanOperationInfo (OP_DB_STAT, 297 "Get database statistics.", 298 dbStatParams, 299 "com.sleepycat.je.DatabaseStats", 300 MBeanOperationInfo.INFO); 301 302 303 304 private File environmentHome; 305 306 311 private boolean canConfigure; 312 private EnvironmentConfig openConfig; 313 314 315 private boolean needReset; 316 317 321 private boolean envWasOpen; 322 323 330 public JEMBeanHelper(File environmentHome, boolean canConfigure) { 331 332 if (environmentHome == null) { 333 throw new IllegalArgumentException ( 334 "Environment home cannot be null"); 335 } 336 this.environmentHome = environmentHome; 337 this.canConfigure = canConfigure; 338 if (canConfigure) { 339 openConfig = new EnvironmentConfig(); 340 } 341 } 342 343 347 public File getEnvironmentHome() { 348 return environmentHome; 349 } 350 351 359 public EnvironmentConfig getEnvironmentOpenConfig() { 360 return openConfig; 361 } 362 363 369 public Environment getEnvironmentIfOpen() { 370 if (environmentHome == null) { 371 return null; 372 } 373 374 return DbInternal.getEnvironmentShell(environmentHome); 375 } 376 377 382 public synchronized boolean getNeedReset() { 383 return needReset; 384 } 385 386 387 388 389 390 397 public List getAttributeList(Environment targetEnv) { 398 399 400 setNeedReset(false); 401 402 ArrayList attrList = new ArrayList (); 403 404 405 for (int i = 0; i < COMMON_ATTR.length; i++) { 406 attrList.add(COMMON_ATTR[i]); 407 } 408 409 if (targetEnv == null) { 410 if (canConfigure) { 411 412 for (int i = 0; i < CREATE_ATTR.length; i++) { 413 attrList.add(CREATE_ATTR[i]); 414 } 415 } 416 } else { 417 418 for (int i = 0; i < OPEN_ATTR.length; i++) { 419 attrList.add(OPEN_ATTR[i]); 420 } 421 422 423 try { 424 EnvironmentConfig config = targetEnv.getConfig(); 425 if (config.getTransactional()) { 426 for (int i = 0; i < TRANSACTIONAL_ATTR.length; i++) { 427 attrList.add(TRANSACTIONAL_ATTR[i]); 428 } 429 } 430 } catch (DatabaseException ignore) { 431 432 } 433 } 434 435 return attrList; 436 } 437 438 449 public Object getAttribute(Environment targetEnv, 450 String attributeName) 451 throws AttributeNotFoundException , 452 MBeanException { 453 454 455 if (attributeName == null) { 456 throw new AttributeNotFoundException ( 457 "Attribute name cannot be null"); 458 } 459 460 461 try { 462 if (attributeName.equals(ATT_ENV_HOME)) { 463 return environmentHome.getCanonicalPath(); 464 } else if (attributeName.equals(ATT_OPEN)) { 465 boolean envIsOpen = (targetEnv != null); 466 resetIfOpenStateChanged(envIsOpen); 467 return new Boolean (envIsOpen); 468 } else if (attributeName.equals(ATT_SET_READ_ONLY)) { 469 return new Boolean (openConfig.getReadOnly()); 470 } else if (attributeName.equals(ATT_SET_TRANSACTIONAL)) { 471 return new Boolean (openConfig.getTransactional()); 472 } else if (attributeName.equals(ATT_SET_SERIALIZABLE)) { 473 return new Boolean (openConfig.getTxnSerializableIsolation()); 474 } else { 475 476 if (targetEnv != null) { 477 478 EnvironmentConfig config = targetEnv.getConfig(); 479 480 if (attributeName.equals(ATT_IS_READ_ONLY)) { 481 return new Boolean (config.getReadOnly()); 482 } else if (attributeName.equals(ATT_IS_TRANSACTIONAL)) { 483 return new Boolean (config.getTransactional()); 484 } else if (attributeName.equals(ATT_CACHE_SIZE)) { 485 return new Long (config.getCacheSize()); 486 } else if (attributeName.equals(ATT_CACHE_PERCENT)) { 487 return new Integer (config.getCachePercent()); 488 } else if (attributeName.equals(ATT_LOCK_TIMEOUT)) { 489 return new Long (config.getLockTimeout()); 490 } else if (attributeName.equals(ATT_IS_SERIALIZABLE)) { 491 return new 492 Boolean (config.getTxnSerializableIsolation()); 493 } else if (attributeName.equals(ATT_TXN_TIMEOUT)) { 494 return new Long (config.getTxnTimeout()); 495 } else { 496 throw new AttributeNotFoundException ("attribute " + 497 attributeName + 498 " is not valid."); 499 } 500 } 501 return null; 502 } 503 } catch (Exception e) { 504 509 throw new MBeanException (e, e.getMessage()); 510 } 511 } 512 513 520 public void setAttribute(Environment targetEnv, 521 Attribute attribute) 522 throws AttributeNotFoundException , 523 InvalidAttributeValueException { 524 525 if (attribute == null) { 526 throw new AttributeNotFoundException ("Attribute cannot be null"); 527 } 528 529 530 String name = attribute.getName(); 531 Object value = attribute.getValue(); 532 533 if (name == null) { 534 throw new AttributeNotFoundException ( 535 "Attribute name cannot be null"); 536 } 537 538 if (value == null) { 539 throw new InvalidAttributeValueException ( 540 "Attribute value for attribute " + 541 name + " cannot be null"); 542 } 543 544 try { 545 if (name.equals(ATT_SET_READ_ONLY)) { 546 openConfig.setReadOnly(((Boolean ) value).booleanValue()); 547 } else if (name.equals(ATT_SET_TRANSACTIONAL)) { 548 openConfig.setTransactional(((Boolean ) value).booleanValue()); 549 } else if (name.equals(ATT_SET_SERIALIZABLE)) { 550 openConfig.setTxnSerializableIsolation( 551 ((Boolean ) value).booleanValue()); 552 } else { 553 554 if (targetEnv != null) { 555 556 EnvironmentMutableConfig config = 557 targetEnv.getMutableConfig(); 558 559 if (name.equals(ATT_CACHE_SIZE)) { 560 config.setCacheSize(((Long ) value).longValue()); 561 targetEnv.setMutableConfig(config); 562 } else if (name.equals(ATT_CACHE_PERCENT)) { 563 config.setCachePercent(((Integer ) value).intValue()); 564 targetEnv.setMutableConfig(config); 565 } else { 566 throw new AttributeNotFoundException ("attribute " + 567 name + 568 " is not valid."); 569 } 570 } else { 571 throw new AttributeNotFoundException ("attribute " + 572 name + 573 " is not valid."); 574 } 575 } 576 } catch (NumberFormatException e) { 577 throw new InvalidAttributeValueException ("attribute name=" + name); 578 } catch (DatabaseException e) { 579 throw new InvalidAttributeValueException ("attribute name=" + name + 580 e.getMessage()); 581 } 582 } 583 584 585 586 587 588 595 public List getOperationList(Environment targetEnv) { 596 setNeedReset(false); 597 598 List operationList = new ArrayList (); 599 600 if (targetEnv != null) { 601 605 operationList.add(OP_CLEAN_INFO); 606 operationList.add(OP_EVICT_INFO); 607 operationList.add(OP_ENV_STAT_INFO); 608 operationList.add(OP_LOCK_STAT_INFO); 609 operationList.add(OP_DB_NAMES_INFO); 610 operationList.add(OP_DB_STAT_INFO); 611 612 613 boolean isTransactional = false; 614 try { 615 EnvironmentConfig config = targetEnv.getConfig(); 616 isTransactional = config.getTransactional(); 617 } catch (DatabaseException e) { 618 619 return new ArrayList (); 620 } 621 622 if (isTransactional) { 623 operationList.add(OP_CHECKPOINT_INFO); 624 operationList.add(OP_TXN_STAT_INFO); 625 } else { 626 operationList.add(OP_SYNC_INFO); 627 } 628 } 629 630 return operationList; 631 } 632 633 643 public Object invoke(Environment targetEnv, 644 String actionName, 645 Object [] params, 646 String [] signature) 647 throws MBeanException { 648 649 650 if (actionName == null) { 651 throw new IllegalArgumentException ("actionName cannot be null"); 652 } 653 654 try { 655 if (targetEnv != null) { 656 if (actionName.equals(OP_CLEAN)) { 657 int numFiles = targetEnv.cleanLog(); 658 return new Integer (numFiles); 659 } else if (actionName.equals(OP_EVICT)) { 660 targetEnv.evictMemory(); 661 return null; 662 } else if (actionName.equals(OP_CHECKPOINT)) { 663 CheckpointConfig config = new CheckpointConfig(); 664 if ((params != null) && (params.length > 0)) { 665 Boolean force = (Boolean ) params[0]; 666 config.setForce(force.booleanValue()); 667 } 668 targetEnv.checkpoint(config); 669 return null; 670 } else if (actionName.equals(OP_SYNC)) { 671 targetEnv.sync(); 672 return null; 673 } else if (actionName.equals(OP_ENV_STAT)) { 674 return targetEnv.getStats(getStatsConfig(params)); 675 } else if (actionName.equals(OP_LOCK_STAT)) { 676 return targetEnv.getLockStats(getStatsConfig(params)); 677 } else if (actionName.equals(OP_TXN_STAT)) { 678 return targetEnv.getTransactionStats( 679 getStatsConfig(params)); 680 } else if (actionName.equals(OP_DB_NAMES)) { 681 return targetEnv.getDatabaseNames(); 682 } else if (actionName.equals(OP_DB_STAT)) { 683 return getDatabaseStats(targetEnv, params); 684 } 685 } 686 687 return new IllegalArgumentException ("actionName: " + 688 actionName + 689 " is not valid"); 690 } catch (DatabaseException e) { 691 696 throw new MBeanException (e, e.getMessage()); 697 } 698 } 699 700 704 private StatsConfig getStatsConfig(Object [] params) { 705 StatsConfig statsConfig = new StatsConfig(); 706 if ((params != null) && (params.length > 0) && (params[0] != null)) { 707 Boolean clear = (Boolean ) params[0]; 708 statsConfig.setClear(clear.booleanValue()); 709 } 710 if ((params != null) && (params.length > 1) && (params[1] != null)) { 711 Boolean fast = (Boolean ) params[1]; 712 statsConfig.setFast(fast.booleanValue()); 713 } 714 return statsConfig; 715 } 716 717 722 private DatabaseStats getDatabaseStats(Environment targetEnv, 723 Object [] params) 724 throws IllegalArgumentException , 725 DatabaseException { 726 727 if ((params == null) || (params.length < 3)) { 728 return null; 729 } 730 String dbName = (String )params[2]; 731 732 Database db = null; 733 try { 734 DatabaseConfig dbConfig = new DatabaseConfig(); 735 dbConfig.setReadOnly(true); 736 DbInternal.setUseExistingConfig(dbConfig, true); 737 db = targetEnv.openDatabase(null, dbName, dbConfig); 738 return db.getStats(getStatsConfig(params)); 739 } finally { 740 if (db != null) { 741 db.close(); 742 } 743 } 744 } 745 746 747 749 750 754 public MBeanNotificationInfo [] 755 getNotificationInfo(Environment targetEnv) { 756 return null; 757 } 758 759 760 762 763 private synchronized void setNeedReset(boolean reset) { 764 needReset = reset; 765 } 766 767 private synchronized void resetIfOpenStateChanged(boolean isOpen) { 768 if (isOpen != envWasOpen) { 769 setNeedReset(true); 770 envWasOpen = isOpen; 771 } 772 } 773 } 774 775 | Popular Tags |