package com.sptci.util

import javax.management.remote.JMXConnectorServer
import javax.management.remote.JMXServiceURL
import static java.lang.Integer.parseInt
import static java.lang.management.ManagementFactory.getPlatformMBeanServer
import static java.net.InetAddress.getLocalHost
import static java.rmi.registry.LocateRegistry.createRegistry
import static java.util.logging.Level.INFO
import static java.util.logging.Level.SEVERE
import static javax.management.remote.JMXConnectorServerFactory.newJMXConnectorServer
import javax.servlet.http.HttpServlet
import java.util.logging.Logger

/**
 * A servlet that sets up a RMI registry on a specified port and starts up a
 * JMX connector server on a predefined port.  This is necessary to work around
 * the default Sun JMX Remote server implementation that uses dynamic ports
 * for the connector server.
 *
 * <p>Copyright 2010 <a href='http://sptci.com/' target='_new'>Sans Pareil Technologies, Inc.</a></p>
 * @author Rakesh Vidyadharan 2010-09-29
 * @version $Id: JMXServer.groovy 953 2011-09-29 16:33:38Z rakesh $
 */
class JMXServer extends HttpServlet
{
  private static final long serialVersionUID = 1L
  protected static final Logger logger = Logger.getLogger( 'com.sptci.jmxserver' )

  JMXConnectorServer connectorServer

  @Override
  void init()
  {
    int registry = parseInt( System.getProperty( 'jmx.registry.port', '8099' ) )
    int connector = parseInt( System.getProperty( 'jmx.connector.port', '8098' ) )
    def host = getLocalHost()
    def url = "service:jmx:rmi://${host.hostName}:${connector}/jndi/rmi://${host.hostName}:${registry}/server"

    try
    {

      createRegistry registry
      def mbeanServer = getPlatformMBeanServer()
      def serviceUrl = new JMXServiceURL( url )
      connectorServer = newJMXConnectorServer( serviceUrl, new HashMap(), mbeanServer )
      connectorServer.start()

      logger.logp INFO, getClass().name, 'init', "Started JMX Connector Server on url: ${url}"
    }
    catch ( Throwable t )
    {
      logger.logp SEVERE, getClass().name, 'destroy',
          "Error starting JMX Connector Server on url: ${url}", t
    }

    super.init()
  }

  @Override
  void destroy()
  {
    if ( connectorServer )
    {
      logger.logp INFO, getClass().name, 'destroy', 'Stopping JMX Connector Server'
      connectorServer.stop()
    }

    super.destroy()
  }
}

