package org.opensource.clearpool.console; import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.ServerSocket; import java.util.HashMap; import java.util.Map; import javax.management.MBeanServer; import javax.management.ObjectName; import org.opensource.clearpool.configuration.console.Console; import org.opensource.clearpool.console.hook.HtmlAdaptorHook; import org.opensource.clearpool.core.ConnectionPoolManager; import org.opensource.clearpool.exception.ConnectionPoolMBeanException; import org.opensource.clearpool.logging.PoolLogger; import org.opensource.clearpool.logging.PoolLoggerFactory; import com.sun.jdmk.comm.CommunicatorServer; /** * This class is used to control MBean. * * @author xionghui * @date 26.07.2014 * @version 1.0 */ class CommunicatorServerHandler { private static final PoolLogger LOGGER = PoolLoggerFactory.getLogger(CommunicatorServerHandler.class); private static MBeanServer server = ManagementFactory.getPlatformMBeanServer(); // this map is used to unregister ObjectName while remove the pool private static Map<String, ObjectNameCarry> objectNameMap = new HashMap<String, ObjectNameCarry>(); private static CommunicatorServer communicatorServer; /** * Register a MBean */ public static void registerMBean(ConnectionPoolManager pool, String mbeanName, String poolName) { ConnectionPoolMBean bean = new ConnectionPool(pool); try { ObjectName objectName = new ObjectName(mbeanName); server.registerMBean(bean, objectName); ObjectNameCarry carry = new ObjectNameCarry(objectName, mbeanName); objectNameMap.put(poolName, carry); } catch (Exception e) { LOGGER.error("registerMBean error: ", e); throw new ConnectionPoolMBeanException(e); } LOGGER.info("register " + poolName + "'s MBean:" + mbeanName); } /** * Unregister a MBean */ public static void unregisterMBean(String poolName) { ObjectNameCarry carry = objectNameMap.get(poolName); if (carry == null) { return; } ObjectName objectName = carry.objectName; String mbeanName = carry.mbeanName; try { server.unregisterMBean(objectName); } catch (Exception e) { // If we use Unregister button to stop it,we will get this exception // and log it. LOGGER.error("unregisterMBean error: ", e); } LOGGER.info("unregister " + poolName + "'s MBean:" + mbeanName); } /** * Start communicatorServer */ public static void start() { if (communicatorServer != null) { return; } checkPort(MBeanFacade.console.getPort()); // start it. communicatorServer = HtmlAdaptorHook.startHook(server); } /** * check if port is valid. */ private static void checkPort(int port) { try { ServerSocket server = new ServerSocket(port); server.close(); } catch (IOException e) { LOGGER.error("checkPort error: ", e); throw new ConnectionPoolMBeanException(Console.PORT + " is used"); } } /** * Stop HtmlAdaptorServer,note:never stop the thread,instead of we should set stopRequested true * and close sockListen.Want to know the reason,please to see the source of CommunicatorServer and * HtmlAdaptorServer. */ public static void stop() { if (communicatorServer != null) { // stop it HtmlAdaptorHook.stop(communicatorServer); // help gc communicatorServer = null; objectNameMap = new HashMap<String, ObjectNameCarry>(); } } /** * This class used to carry mbeanName of the ObjectName,we can't log mbeanName with it while we * unregister the MBean. * * @author xionghui * @date 26.07.2014 * @version 1.0 */ private static class ObjectNameCarry { ObjectName objectName; String mbeanName; ObjectNameCarry(ObjectName objectName, String mbeanName) { this.objectName = objectName; this.mbeanName = mbeanName; } } }