package org.commons.jconfig.internal.jmx; import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; import javax.management.JMX; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import org.apache.log4j.Logger; import org.commons.jconfig.config.ConfigRuntimeException; import com.sun.tools.attach.VirtualMachineDescriptor; /** * Exposes @MBeanServerConnection for a VirtualMachine with a registered ConfigManagerMXBean.<BR> * * <B>Usage:</B><BR> * * //Attach to a VM with a registered ConfigManagerMXBean with the objectName attribute of "myApplication"<BR> * ConfigManagerVM vm = new ConfigManagerVM("myApplicatoin");<BR> * try {<BR> * vm.Attach();<BR> * } catch ( VirtualMachineException e ) {<BR> * //do something<BR> * }<BR> * MBeanServerConnection mbsc = vm.getMBeanServerConnection();<BR><BR> * * //execute operations using the server connection<BR> * mbsc.doSomething();<BR><BR> * * //Detach<BR> * vm.Detach();<BR> * * <BR><B>Note</B> ConfigLoader application identified by com.yahoo.configldr:type=configLoader MBean * * @author aabed */ public class ConfigManagerJvm extends VirtualMachine { /** * MBean Name identifying VirtualMachine with a registered @ConfigManagerMXBean */ public static final String CONFIG_MGR_MBEAN_NAME = "com.yahoo.configmgr:type=ConfigManager,appName="; public static final String CONFIG_MGR_MBEAN_SEARCH_PATTERN = "com.yahoo.configmgr:type=ConfigManager,appName=*"; public static final String APPNAME_KEY = "appName"; private final ObjectName objectName; private String vmId = "-1"; /** * Our Logger */ private static final Logger logger = Logger.getLogger(ConfigLoaderJvm.class); public ConfigManagerJvm(final ObjectName bname) { if (bname == null) { throw new IllegalArgumentException("Config manager ObjectName cannot be null."); } if (!bname.getCanonicalName().contains(APPNAME_KEY)) { throw new IllegalArgumentException("Config manager ObjectName should contain appname key."); } this.objectName = bname; } /** * Attach to the VM with a registered @ConfigManagerMXBean who's name attribute matches * objectName. * @throws @VirtualMachineException */ @Override public void attach() throws VirtualMachineException { // Iterate through the running vms ... List<VirtualMachineDescriptor> vms = com.sun.tools.attach.VirtualMachine.list(); for (VirtualMachineDescriptor vmd : vms) { JMXConnector jmxc = null; try { jmxc = connect(vmd); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); // Look for one that has the ConfigLoader MBean registered if (!mbsc.isRegistered(objectName)) { jmxc.close(); continue; } else { // // now does it match the objectName we are looking for // ConfigManagerJmxMXBean managerBean = JMX.newMBeanProxy(mbsc, objectName, ConfigManagerJmxMXBean.class, true); if (managerBean.getVMName().equals(objectName.getKeyProperty(APPNAME_KEY))) { vmId = vmd.id(); // Set the JMXConnector and the MBeanServerConnection setJMXConnector(jmxc); return; } } } catch (IOException e) { if (jmxc != null) { try { jmxc.close(); } catch (IOException e1) { } } // ignore exception to allow gc to collect the object ad // continue to loop to find the correct jvm } } throw new VirtualMachineException("Unable to find config manager jvm with appname: " + objectName); } /** * @return Set of {@link ConfigManagerJvm} all in attached state */ public static Set<ConfigManagerJvm> find() { Set<ConfigManagerJvm> jvms = new HashSet<ConfigManagerJvm>(); JMXConnector jmxc = null; List<VirtualMachineDescriptor> vms = com.sun.tools.attach.VirtualMachine.list(); ObjectName mbeanName; try { mbeanName = new ObjectName(CONFIG_MGR_MBEAN_SEARCH_PATTERN); } catch (MalformedObjectNameException e) { throw new ConfigRuntimeException("Fail to instantiate config manager object bean ", e); } // Iterate through the running vms ... for (VirtualMachineDescriptor vmd : vms) { try { jmxc = connect(vmd); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); Set<ObjectName> registeredConfigManagers = new TreeSet<ObjectName>(mbsc.queryNames(mbeanName, null)); if (registeredConfigManagers.isEmpty()) { jmxc.close(); continue; } else { jmxc.close(); for (ObjectName bname : registeredConfigManagers) { ConfigManagerJvm vm = new ConfigManagerJvm(bname); vm.setJMXConnector(connect(vmd)); vm.setVmId(vmd.id()); jvms.add(vm); } } } catch (VirtualMachineException e) { logger.debug("Fail fetching config manager vms ", e); } catch (IOException e) { logger.debug("Fail fetching config manager vms ", e); } } return jvms; } public String getVmId() { return vmId; } public void setVmId(final String id) { vmId = id; } public ObjectName getObjectName() { return objectName; } @Override public String toString() { return "[" + vmId + ", " + objectName + "]"; } }