1 22 23 package org.continuent.sequoia.console.jmx; 24 25 import java.io.IOException ; 26 import java.util.HashMap ; 27 import java.util.HashSet ; 28 import java.util.Map ; 29 import java.util.Set ; 30 31 import javax.management.Attribute ; 32 import javax.management.InstanceNotFoundException ; 33 import javax.management.MBeanInfo ; 34 import javax.management.MBeanServerConnection ; 35 import javax.management.MBeanServerInvocationHandler ; 36 import javax.management.MalformedObjectNameException ; 37 import javax.management.NotificationListener ; 38 import javax.management.ObjectName ; 39 import javax.management.monitor.StringMonitor ; 40 import javax.management.remote.JMXConnector ; 41 import javax.management.remote.JMXConnectorFactory ; 42 import javax.management.remote.JMXServiceURL ; 43 import javax.naming.Context ; 44 import javax.security.auth.Subject ; 45 46 import org.continuent.sequoia.common.authentication.PasswordAuthenticator; 47 import org.continuent.sequoia.common.exceptions.VirtualDatabaseException; 48 import org.continuent.sequoia.common.i18n.ConsoleTranslate; 49 import org.continuent.sequoia.common.jmx.JMXPrincipalWithPassword; 50 import org.continuent.sequoia.common.jmx.JmxConstants; 51 import org.continuent.sequoia.common.jmx.mbeans.AbstractSchedulerControlMBean; 52 import org.continuent.sequoia.common.jmx.mbeans.BackendTaskQueuesControlMBean; 53 import org.continuent.sequoia.common.jmx.mbeans.ControllerMBean; 54 import org.continuent.sequoia.common.jmx.mbeans.DataCollectorMBean; 55 import org.continuent.sequoia.common.jmx.mbeans.DatabaseBackendMBean; 56 import org.continuent.sequoia.common.jmx.mbeans.ParsingCacheMBean; 57 import org.continuent.sequoia.common.jmx.mbeans.RecoveryLogControlMBean; 58 import org.continuent.sequoia.common.jmx.mbeans.RequestManagerMBean; 59 import org.continuent.sequoia.common.jmx.mbeans.VirtualDatabaseMBean; 60 import org.continuent.sequoia.common.log.Trace; 61 62 69 public class RmiJmxClient 70 { 71 private JMXConnector connector; 72 private Object credentials; 73 private String remoteHostAddress; 74 private String remoteHostPort; 75 76 private NotificationListener notificationListener; 77 78 private ControllerMBean controllerMBean; 80 private DatabaseBackendMBean backendMBean; 81 private DataCollectorMBean dataMBean; 82 83 private Trace logger = Trace 84 .getLogger("org.continuent.sequoia.console.jmx"); 85 86 91 public NotificationListener getNotificationListener() 92 { 93 return notificationListener; 94 } 95 96 101 public void setNotificationListener(NotificationListener notificationListener) 102 { 103 this.notificationListener = notificationListener; 104 } 105 106 111 public Object getCredentials() 112 { 113 return credentials; 114 } 115 116 125 public RmiJmxClient(String port, String host, String jmxUser, 126 String jmxPassword) throws IOException 127 { 128 this(port, host, PasswordAuthenticator.createCredentials(jmxUser, 129 jmxPassword)); 130 } 131 132 139 public RmiJmxClient(String url, Object credentials) throws IOException 140 { 141 int index = url.indexOf(":"); 142 String ip = url.substring(0, index); 143 String port = url.substring(index + 1); 144 connect(port, ip, credentials); 145 } 146 147 155 public RmiJmxClient(String port, String host, Object credentials) 156 throws IOException 157 { 158 connect(port, host, credentials); 159 } 160 161 169 public void connect(String port, String host, Object credentials) 170 throws IOException 171 { 172 JMXServiceURL address = new JMXServiceURL ("rmi", host, 0, "/jndi/jrmp"); 173 174 Map environment = new HashMap (); 175 environment.put(Context.INITIAL_CONTEXT_FACTORY, 176 "com.sun.jndi.rmi.registry.RegistryContextFactory"); 177 environment.put(Context.PROVIDER_URL, "rmi://" + host + ":" + port); 178 179 if (credentials != null) 183 { 184 environment.put(JMXConnector.CREDENTIALS, credentials); 186 } 187 188 this.credentials = credentials; 189 190 connector = JMXConnectorFactory.connect(address, environment); 191 remoteHostAddress = host; 192 remoteHostPort = port; 193 invalidateMBeans(); 194 } 195 196 201 private void invalidateMBeans() 202 { 203 controllerMBean = null; 204 dataMBean = null; 205 backendMBean = null; 206 } 207 208 214 public Set listSequoiaMBeans() throws Exception 215 { 216 Set set = connector.getMBeanServerConnection().queryMBeans( 217 new ObjectName ("sequoia:*"), null); 218 return set; 219 } 220 221 228 public MBeanInfo getMBeanInfo(ObjectName mbean) throws Exception 229 { 230 return connector.getMBeanServerConnection().getMBeanInfo(mbean); 231 } 232 233 242 public Object getAttributeValue(ObjectName mbean, String attribute) 243 throws Exception 244 { 245 return connector.getMBeanServerConnection().getAttribute(mbean, attribute); 246 } 247 248 256 public void setAttributeValue(ObjectName mbean, String attribute, Object value) 257 throws Exception 258 { 259 Attribute att = new Attribute (attribute, value); 260 connector.getMBeanServerConnection().setAttribute(mbean, att); 261 } 262 263 269 private Subject getSubject(String user, String password) 270 { 271 Set principals = new HashSet (); 272 principals.add(new JMXPrincipalWithPassword(user, password)); 273 return new Subject (true, principals, new HashSet (), new HashSet ()); 274 } 275 276 287 public VirtualDatabaseMBean getVirtualDatabaseProxy(String database, 288 String user, String password) throws InstanceNotFoundException , 289 IOException , VirtualDatabaseException 290 { 291 if (!isValidConnection()) 292 { 293 try 294 { 295 reconnect(); 296 } 297 catch (Exception e) 298 { 299 throw new IOException (ConsoleTranslate 300 .get("jmx.server.connection.lost")); } 302 } 303 ObjectName db; 304 try 305 { 306 db = JmxConstants.getVirtualDataBaseObjectName(database); 307 } 308 catch (MalformedObjectNameException e) 309 { 310 throw new VirtualDatabaseException(e); 311 } 312 MBeanServerConnection delegateConnection = connector 315 .getMBeanServerConnection(getSubject(user, password)); 316 317 if (!delegateConnection.isRegistered(db)) 318 { 319 throw new VirtualDatabaseException(ConsoleTranslate 320 .get("virtualdatabase.mbean.not.accessible")); } 322 323 VirtualDatabaseMBean local = (VirtualDatabaseMBean) MBeanServerInvocationHandler 325 .newProxyInstance(delegateConnection, db, VirtualDatabaseMBean.class, 326 false); 327 checkAccessible(local); 328 boolean authenticated = false; 330 try 331 { 332 authenticated = local.checkAdminAuthentication(user, password); 333 } 334 catch (Exception e) 335 { 336 logger.warn( 337 "Exception while checking virtual database admin authentication", e); 338 throw new VirtualDatabaseException( 339 "Could not check authentication. MBean is not accessible."); 340 } 341 if (!authenticated) 342 throw new VirtualDatabaseException("Authentication Failed"); 343 344 if (notificationListener != null) 346 { 347 delegateConnection.addNotificationListener(db, notificationListener, 348 null, null); 349 350 } 358 359 return local; 360 } 361 362 370 private void checkAccessible(VirtualDatabaseMBean virtualDbMBean) 371 throws VirtualDatabaseException 372 { 373 if (virtualDbMBean == null) 374 { 375 return; 376 } 377 try 380 { 381 virtualDbMBean.getVirtualDatabaseName(); 382 } 383 catch (Exception e) 384 { 385 throw new VirtualDatabaseException(ConsoleTranslate 386 .get("virtualdatabase.mbean.not.accessible")); } 388 } 389 390 396 public ControllerMBean getControllerProxy() throws IOException 397 { 398 399 if (controllerMBean != null && isValidConnection()) 400 { 401 return controllerMBean; 402 } 403 else 404 { 405 if (!isValidConnection()) 406 { 407 try 408 { 409 reconnect(); 410 } 411 catch (Exception e) 412 { 413 throw new IOException (ConsoleTranslate 414 .get("jmx.server.connection.lost")); } 416 } 417 ObjectName db; 418 try 419 { 420 db = JmxConstants.getControllerObjectName(); 421 } 422 catch (MalformedObjectNameException e) 423 { 424 throw new IOException (e.getMessage()); 425 } 426 427 controllerMBean = (ControllerMBean) MBeanServerInvocationHandler 429 .newProxyInstance(connector.getMBeanServerConnection(), db, 430 ControllerMBean.class, false); 431 432 if (notificationListener != null) 434 { 435 try 436 { 437 connector.getMBeanServerConnection().addNotificationListener(db, 438 notificationListener, null, null); 439 } 440 catch (Exception e) 441 { 442 throw new IOException ("Could not register listener on the mbean"); 443 } 444 } 445 446 return controllerMBean; 447 } 448 } 449 450 456 public DataCollectorMBean getDataCollectorProxy() throws IOException 457 { 458 459 if (dataMBean != null && isValidConnection()) 460 { 461 return dataMBean; 462 } 463 else 464 { 465 if (!isValidConnection()) 466 reconnect(); 467 ObjectName db = JmxConstants.getDataCollectorObjectName(); 468 469 dataMBean = (DataCollectorMBean) MBeanServerInvocationHandler 471 .newProxyInstance(connector.getMBeanServerConnection(), db, 472 DataCollectorMBean.class, false); 473 return dataMBean; 474 } 475 } 476 477 488 public DatabaseBackendMBean getDatabaseBackendProxy(String vdb, 489 String backend, String user, String password) 490 throws InstanceNotFoundException , IOException 491 { 492 if (backendMBean != null && isValidConnection()) 493 { 494 try 495 { 496 if (backendMBean.getName().equals(backend)) 497 return backendMBean; 498 } 499 catch (Exception e) 500 { 501 } 503 } 504 505 if (!isValidConnection()) 506 reconnect(); 507 508 ObjectName backendObjectName; 509 try 510 { 511 backendObjectName = JmxConstants.getDatabaseBackendObjectName(vdb, 512 backend); 513 } 514 catch (MalformedObjectNameException e) 515 { 516 throw new IOException (e.getMessage()); 517 } 518 519 MBeanServerConnection delegateConnection = connector 520 .getMBeanServerConnection(getSubject(user, password)); 521 522 if (notificationListener != null) 523 { 524 delegateConnection.addNotificationListener(backendObjectName, 525 notificationListener, null, null); 526 StringMonitor sm = new StringMonitor (); 527 sm.setObservedObject(backendObjectName); 528 sm.setObservedAttribute("LastKnownCheckpoint"); 529 sm.setStringToCompare("hello"); 530 sm.setGranularityPeriod(100); 531 sm.setNotifyDiffer(true); 532 sm.addNotificationListener(notificationListener, null, null); 533 sm.start(); 534 } 535 536 backendMBean = (DatabaseBackendMBean) MBeanServerInvocationHandler 538 .newProxyInstance(delegateConnection, backendObjectName, 539 DatabaseBackendMBean.class, false); 540 return backendMBean; 541 } 542 543 553 public BackendTaskQueuesControlMBean getBackendTaskQueues(String vdb, 554 String backend, String user, String password) throws IOException 555 { 556 if (!isValidConnection()) 557 reconnect(); 558 559 ObjectName taskQueuesObjectName; 560 try 561 { 562 taskQueuesObjectName = JmxConstants.getBackendTaskQueuesObjectName(vdb, 563 backend); 564 } 565 catch (MalformedObjectNameException e) 566 { 567 throw new IOException (e.getMessage()); 568 } 569 570 MBeanServerConnection delegateConnection = connector 571 .getMBeanServerConnection(getSubject(user, password)); 572 573 return (BackendTaskQueuesControlMBean) MBeanServerInvocationHandler 575 .newProxyInstance(delegateConnection, taskQueuesObjectName, 576 BackendTaskQueuesControlMBean.class, false); 577 } 578 579 588 public RecoveryLogControlMBean getRecoveryLog(String vdb, String user, 589 String password) throws IOException 590 { 591 if (!isValidConnection()) 592 reconnect(); 593 594 ObjectName recoveryLogObjectName; 595 try 596 { 597 recoveryLogObjectName = JmxConstants.getRecoveryLogObjectName(vdb); 598 } 599 catch (MalformedObjectNameException e) 600 { 601 throw new IOException (e.getMessage()); 602 } 603 604 MBeanServerConnection delegateConnection = connector 605 .getMBeanServerConnection(getSubject(user, password)); 606 607 return (RecoveryLogControlMBean) MBeanServerInvocationHandler 609 .newProxyInstance(delegateConnection, recoveryLogObjectName, 610 RecoveryLogControlMBean.class, false); 611 } 612 613 622 public AbstractSchedulerControlMBean getAbstractScheduler(String vdb, 623 String user, String password) throws IOException 624 { 625 if (!isValidConnection()) 626 reconnect(); 627 628 ObjectName recoveryLogObjectName; 629 try 630 { 631 recoveryLogObjectName = JmxConstants.getAbstractSchedulerObjectName(vdb); 632 } 633 catch (MalformedObjectNameException e) 634 { 635 throw new IOException (e.getMessage()); 636 } 637 638 MBeanServerConnection delegateConnection = connector 639 .getMBeanServerConnection(getSubject(user, password)); 640 641 return (AbstractSchedulerControlMBean) MBeanServerInvocationHandler 643 .newProxyInstance(delegateConnection, recoveryLogObjectName, 644 AbstractSchedulerControlMBean.class, false); 645 } 646 647 656 public ParsingCacheMBean getParsingCache(String vdb, String user, 657 String password) throws IOException 658 { 659 if (!isValidConnection()) 660 reconnect(); 661 662 ObjectName parsingCacheObjectName; 663 try 664 { 665 parsingCacheObjectName = JmxConstants.getParsingCacheObjectName(vdb); 666 } 667 catch (MalformedObjectNameException e) 668 { 669 throw new IOException (e.getMessage()); 670 } 671 672 MBeanServerConnection delegateConnection = connector 673 .getMBeanServerConnection(getSubject(user, password)); 674 675 return (ParsingCacheMBean) MBeanServerInvocationHandler.newProxyInstance( 677 delegateConnection, parsingCacheObjectName, ParsingCacheMBean.class, 678 false); 679 } 680 681 690 public RequestManagerMBean getRequestManager(String vdb, String user, 691 String password) throws IOException 692 { 693 if (!isValidConnection()) 694 reconnect(); 695 696 ObjectName requestManagerObjectName; 697 try 698 { 699 requestManagerObjectName = JmxConstants.getRequestManagerObjectName(vdb); 700 } 701 catch (MalformedObjectNameException e) 702 { 703 throw new IOException (e.getMessage()); 704 } 705 706 MBeanServerConnection delegateConnection = connector 707 .getMBeanServerConnection(getSubject(user, password)); 708 709 return (RequestManagerMBean) MBeanServerInvocationHandler.newProxyInstance( 711 delegateConnection, requestManagerObjectName, 712 RequestManagerMBean.class, false); 713 } 714 715 721 public String getRemoteName() 722 { 723 return remoteHostAddress + ":" + remoteHostPort; 724 } 725 726 731 public String getRemoteHostAddress() 732 { 733 return remoteHostAddress; 734 } 735 736 741 public String getRemoteHostPort() 742 { 743 return remoteHostPort; 744 } 745 746 751 public void reconnect() throws IOException 752 { 753 connect(remoteHostPort, remoteHostAddress, credentials); 754 } 755 756 761 public boolean isValidConnection() 762 { 763 try 764 { 765 connector.getMBeanServerConnection().getMBeanCount(); 766 return true; 767 } 768 catch (Exception e) 769 { 770 controllerMBean = null; 771 backendMBean = null; 772 dataMBean = null; 773 return false; 774 } 775 } 776 } | Popular Tags |