
import javax.management.MBeanServer;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnectorServer;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.util.HashMap;

/**
 * setup JSR-160 JMXConnector
 */
public class SSLJMXConnector
{

    /* start of configurable settings */
    private static int rmiRegistryPort = 1090; // create a RMI registry at this port

    private static int rmiServerPort = 1091; // rmi server will listen on this port

    private static String hostname = "localhost";

    private static MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();

    private static Registry registry;

   
    private static RMIClientSocketFactory clientSocketFactory = new SslRMIClientSocketFactory();

    /** An optional custom server socket factory */
    private static RMIServerSocketFactory serverSocketFactory = new SslRMIServerSocketFactory(null, null, true);


    public static void main(String[] args)
    {
        try
        {
          
             System.out.println("starting JMXConnector on host " + hostname + ":" + rmiRegistryPort);
             System.out.println("starting RMIServer on host " + hostname + ":" + rmiServerPort);
            
            
            registry = LocateRegistry.createRegistry(rmiRegistryPort, new SslRMIClientSocketFactory(),
            		serverSocketFactory);
            JMXServiceURL url = buildJMXServiceURL();
            HashMap<String, Object> env = new HashMap<String, Object>();
            env.put("com.sun.jndi.rmi.factory.socket", clientSocketFactory);
            env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, clientSocketFactory);
			env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverSocketFactory);
            JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbeanServer);
			cs.start();
           
        }
        catch (IOException e)	
        {
        	System.out.println("Could not start JMXConnector");
        	e.printStackTrace();
        }
    }

    /**
     * build URL and handle IPV6 literal address case. TODO: share IPV6 logic like this via a shared
     * library.
     */
    private static JMXServiceURL buildJMXServiceURL() throws MalformedURLException
    {
        String host = hostname;
        if (host.indexOf(':') != -1)
        { // is this a IPV6 literal address? if yes, surround with square brackets
          // as per rfc2732.
          // IPV6 literal addresses have one or more colons
          // IPV4 addresses/hostnames have no colons
            host = "[" + host + "]";
        }
        //JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://" + host);
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://" + hostname
				+ ":" + rmiServerPort + "/jndi/rmi://" + hostname + ":"
				+ rmiRegistryPort + "/jmxrmi");
        return url;
        
        
    }

    
    
}