1 24 25 package org.objectweb.cjdbc.console.jmx; 26 27 import java.io.IOException ; 28 import java.util.HashMap ; 29 import java.util.HashSet ; 30 import java.util.Map ; 31 import java.util.Set ; 32 33 import javax.management.Attribute ; 34 import javax.management.InstanceNotFoundException ; 35 import javax.management.MBeanInfo ; 36 import javax.management.MBeanOperationInfo ; 37 import javax.management.MBeanParameterInfo ; 38 import javax.management.MBeanServerConnection ; 39 import javax.management.MBeanServerInvocationHandler ; 40 import javax.management.NotificationListener ; 41 import javax.management.ObjectName ; 42 import javax.management.monitor.StringMonitor ; 43 import javax.management.remote.JMXConnector ; 44 import javax.management.remote.JMXConnectorFactory ; 45 import javax.management.remote.JMXServiceURL ; 46 import javax.naming.Context ; 47 import javax.security.auth.Subject ; 48 49 import org.objectweb.cjdbc.common.exceptions.VirtualDatabaseException; 50 import org.objectweb.cjdbc.common.jmx.JmxConstants; 51 import org.objectweb.cjdbc.common.jmx.mbeans.ControllerMBean; 52 import org.objectweb.cjdbc.common.jmx.mbeans.DataCollectorMBean; 53 import org.objectweb.cjdbc.common.jmx.mbeans.DatabaseBackendMBean; 54 import org.objectweb.cjdbc.common.jmx.mbeans.VirtualDatabaseMBean; 55 import org.objectweb.cjdbc.common.users.AdminUser; 56 import org.objectweb.cjdbc.controller.authentication.PasswordAuthenticator; 57 58 65 public class RmiJmxClient 66 { 67 private JMXConnector connector; 68 private Object credentials; 69 private String remoteHostAddress; 70 private String remoteHostPort; 71 72 private NotificationListener notificationListener; 73 74 private ControllerMBean controllerMBean; 76 private VirtualDatabaseMBean virtualDbMBean; 77 private DatabaseBackendMBean backendMBean; 78 private DataCollectorMBean dataMBean; 79 80 85 public NotificationListener getNotificationListener() 86 { 87 return notificationListener; 88 } 89 90 95 public void setNotificationListener(NotificationListener notificationListener) 96 { 97 this.notificationListener = notificationListener; 98 } 99 100 105 public Object getCredentials() 106 { 107 return credentials; 108 } 109 110 119 public RmiJmxClient(String port, String host, String jmxUser, 120 String jmxPassword) throws IOException 121 { 122 this(port, host, PasswordAuthenticator.createCredentials(jmxUser, 123 jmxPassword)); 124 } 125 126 133 public RmiJmxClient(String url, Object credentials) throws IOException 134 { 135 int index = url.indexOf(":"); 136 String ip = url.substring(0, index); 137 String port = url.substring(index + 1); 138 connect(port, ip, credentials); 139 } 140 141 149 public RmiJmxClient(String port, String host, Object credentials) 150 throws IOException 151 { 152 connect(port, host, credentials); 153 } 154 155 163 public void connect(String port, String host, Object credentials) 164 throws IOException 165 { 166 JMXServiceURL address = new JMXServiceURL ("rmi", host, 0, "/jndi/jrmp"); 167 168 Map environment = new HashMap (); 169 environment.put(Context.INITIAL_CONTEXT_FACTORY, 170 "com.sun.jndi.rmi.registry.RegistryContextFactory"); 171 environment.put(Context.PROVIDER_URL, "rmi://" + host + ":" + port); 172 173 if (credentials != null) 177 { 178 environment.put(JMXConnector.CREDENTIALS, credentials); 180 } 181 182 this.credentials = credentials; 183 184 connector = JMXConnectorFactory.connect(address, environment); 185 remoteHostAddress = host; 186 remoteHostPort = port; 187 invalidateMBeans(); 188 } 189 190 198 private void invalidateMBeans() 199 { 200 controllerMBean = null; 201 virtualDbMBean = null; 202 dataMBean = null; 203 backendMBean = null; 204 } 205 206 212 public Set listCJDBCMBeans() throws Exception 213 { 214 Set set = connector.getMBeanServerConnection().queryMBeans( 215 new ObjectName ("c-jdbc:*"), null); 216 return set; 217 } 218 219 226 public MBeanInfo getMBeanInfo(ObjectName mbean) throws Exception 227 { 228 return connector.getMBeanServerConnection().getMBeanInfo(mbean); 229 } 230 231 240 public Object getAttributeValue(ObjectName mbean, String attribute) 241 throws Exception 242 { 243 return connector.getMBeanServerConnection().getAttribute(mbean, attribute); 244 } 245 246 254 public void setAttributeValue(ObjectName mbean, String attribute, Object value) 255 throws Exception 256 { 257 Attribute att = new Attribute (attribute, value); 258 connector.getMBeanServerConnection().setAttribute(mbean, att); 259 } 260 261 267 public void setCurrentSubject(String user, String password) 268 { 269 if (user != null && password != null) 270 { 271 AdminUser dbUser = new AdminUser(user, password); 273 Set principals = new HashSet (); 274 principals.add(dbUser); 275 subject = new Subject (true, principals, new HashSet (), new HashSet ()); 276 } 277 } 278 279 Subject subject; 280 281 286 public boolean isSubjectSet() 287 { 288 return subject != null; 289 } 290 291 300 public Object invokeOperation(ObjectName name, MBeanOperationInfo operation, 301 Object [] args) throws Exception 302 { 303 if (JmxConstants.mbeanNeedAuthentication(name)) 304 { 305 if (!isSubjectSet()) 306 throw new Exception ( 307 "Subject has not been set for this jmx client, and authentication is required"); 308 return connector.getMBeanServerConnection(subject).invoke(name, 309 operation.getName(), args, getSignature(operation)); 310 } 311 else 312 { 313 return connector.getMBeanServerConnection().invoke(name, 314 operation.getName(), args, getSignature(operation)); 315 } 316 } 317 318 private String [] getSignature(MBeanOperationInfo operation) 319 { 320 MBeanParameterInfo [] info = operation.getSignature(); 321 String [] signature = new String [info.length]; 322 for (int i = 0; i < info.length; i++) 323 signature[i] = info[i].getType(); 324 return signature; 325 } 326 327 338 public VirtualDatabaseMBean getVirtualDatabaseProxy(String database, 339 String user, String password) throws InstanceNotFoundException , 340 IOException , VirtualDatabaseException 341 { 342 if (virtualDbMBean != null && isValidConnection() 343 && virtualDbMBean.getVirtualDatabaseName().equals(database)) 344 { 345 return virtualDbMBean; 346 } 347 else 348 { 349 ObjectName db = JmxConstants.getVirtualDbObjectName(database); 350 351 AdminUser dbUser = new AdminUser(user, password); 353 Set principals = new HashSet (); 354 principals.add(dbUser); 355 Subject subj = new Subject (true, principals, new HashSet (), new HashSet ()); 356 357 MBeanServerConnection delegateConnection = connector 360 .getMBeanServerConnection(subj); 361 362 VirtualDatabaseMBean local = (VirtualDatabaseMBean) MBeanServerInvocationHandler 364 .newProxyInstance(delegateConnection, db, VirtualDatabaseMBean.class, 365 false); 366 367 boolean authenticated = false; 369 try 370 { 371 authenticated = local.checkAdminAuthentication(user, password); 372 } 373 catch (Exception e) 374 { 375 throw new VirtualDatabaseException( 376 "Could not check authentication. MBean is not accessible."); 377 } 378 if (!authenticated) 379 throw new VirtualDatabaseException("Authentication Failed"); 380 381 if (notificationListener != null) 383 { 384 delegateConnection.addNotificationListener(db, notificationListener, 385 null, null); 386 387 } 395 396 this.virtualDbMBean = local; 397 398 return virtualDbMBean; 399 } 400 } 401 402 408 public ControllerMBean getControllerProxy() throws IOException 409 { 410 411 if (controllerMBean != null && isValidConnection()) 412 { 413 return controllerMBean; 414 } 415 else 416 { 417 if (!isValidConnection()) 418 reconnect(); 419 420 ObjectName db = JmxConstants.getControllerObjectName(); 421 422 controllerMBean = (ControllerMBean) MBeanServerInvocationHandler 424 .newProxyInstance(connector.getMBeanServerConnection(), db, 425 ControllerMBean.class, false); 426 427 if (notificationListener != null) 429 { 430 try 431 { 432 connector.getMBeanServerConnection().addNotificationListener(db, 433 notificationListener, null, null); 434 } 435 catch (Exception e) 436 { 437 throw new IOException ("Could not register listener on the mbean"); 438 } 439 } 440 441 return controllerMBean; 442 } 443 } 444 445 451 public DataCollectorMBean getDataCollectorProxy() throws IOException 452 { 453 454 if (dataMBean != null && isValidConnection()) 455 { 456 return dataMBean; 457 } 458 else 459 { 460 if (!isValidConnection()) 461 reconnect(); 462 ObjectName db = JmxConstants.getDataCollectorObjectName(); 463 464 dataMBean = (DataCollectorMBean) MBeanServerInvocationHandler 466 .newProxyInstance(connector.getMBeanServerConnection(), db, 467 DataCollectorMBean.class, false); 468 return dataMBean; 469 } 470 } 471 472 483 public DatabaseBackendMBean getDatabaseBackendProxy(String vdb, 484 String backend, String user, String password) 485 throws InstanceNotFoundException , IOException 486 { 487 if (backendMBean != null && isValidConnection()) 488 { 489 try 490 { 491 if (backendMBean.getName().equals(backend)) 492 return backendMBean; 493 } 494 catch (Exception e) 495 { 496 } 498 } 499 500 if (!isValidConnection()) 501 reconnect(); 502 503 AdminUser dbUser = new AdminUser(user, password); 505 Set principals = new HashSet (); 506 principals.add(dbUser); 507 Subject subj = new Subject (true, principals, new HashSet (), new HashSet ()); 508 509 ObjectName db = JmxConstants.getDatabaseBackendObjectName(vdb, backend); 510 MBeanServerConnection delegateConnection = connector 511 .getMBeanServerConnection(subj); 512 513 if (notificationListener != null) 514 { 515 delegateConnection.addNotificationListener(db, notificationListener, 516 null, null); 517 StringMonitor sm = new StringMonitor (); 518 sm.setObservedObject(db); 519 sm.setObservedAttribute("LastKnownCheckpoint"); 520 sm.setStringToCompare("hello"); 521 sm.setGranularityPeriod(100); 522 sm.setNotifyDiffer(true); 523 sm.addNotificationListener(notificationListener, null, null); 524 sm.start(); 525 } 526 527 backendMBean = (DatabaseBackendMBean) MBeanServerInvocationHandler 529 .newProxyInstance(delegateConnection, db, DatabaseBackendMBean.class, 530 false); 531 return backendMBean; 532 } 533 534 540 public String getRemoteName() 541 { 542 return remoteHostAddress + ":" + remoteHostPort; 543 } 544 545 550 public String getRemoteHostAddress() 551 { 552 return remoteHostAddress; 553 } 554 555 560 public String getRemoteHostPort() 561 { 562 return remoteHostPort; 563 } 564 565 570 public void reconnect() throws IOException 571 { 572 connect(remoteHostPort, remoteHostAddress, credentials); 573 } 574 575 580 public boolean isValidConnection() 581 { 582 try 583 { 584 connector.getMBeanServerConnection().getMBeanCount(); 585 return true; 586 } 587 catch (Exception e) 588 { 589 controllerMBean = null; 590 backendMBean = null; 591 virtualDbMBean = null; 592 dataMBean = null; 593 return false; 594 } 595 } 596 } | Popular Tags |