/*
 * ScanDirClient.java
 *
 * Created on July 24, 2006, 16:00 PM
 *
 * %W% %E%
 *
 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * -Redistribution of source code must retain the above copyright notice, this
 *  list of conditions and the following disclaimer.
 *
 * -Redistribution in binary form must reproduce the above copyright notice,
 *  this list of conditions and the following disclaimer in the documentation
 *  and/or other materials provided with the distribution.
 *
 * Neither the name of Oracle or the names of contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that this software is not designed, licensed or intended
 * for use in the design, construction, operation or maintenance of any
 * nuclear facility.
 */

package com.sun.jmx.examples.scandir;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.rmi.ssl.SslRMIClientSocketFactory;

/**
 * The ScanDirClient class is a very simple programmatic client example
 * which is able to connect to a secured JMX <i>scandir</i> application.
 * <p>The program initialize the connection environment map with the 
 * appropriate properties and credentials, and then connects to the
 * secure JMX <i>scandir</i> daemon.</p>
 * <p>It gets the application's current configuration and prints it on
 * its <code>System.out</code>.</p>
 * <p>The {@link #main main} method takes two arguments: the host on which
 * the server is running (localhost), and the port number
 * that was configured to start the server RMI Connector (4545). 
 * </p>
 * @author Sun Microsystems, 2006 - All rights reserved.
 **/
public class ScanDirClient {
    
    // This class has only a main.
    private ScanDirClient() { }
    
    /**
     * The usage string for the ScanDirClient.
     */
    public static final String USAGE = ScanDirClient.class.getSimpleName() +
            " <server-host> <rmi-port-number>";
    
    /**
     * Connects to a secured JMX <i>scandir</i> application.
     * @param args The {@code main} method takes two parameters: 
     *        <ul>
     *        <li>args[0] must be the server's host</li>
     *        <li>args[1] must be the rmi port number at which the
     *        JMX <i>scandir</i> daemon is listening for connections
     *        - that is, the port number of its JMX RMI Connector which
     *        was configured in {@code management.properties}
     *        </li>
     *        <ul>
     **/
    public static void main(String[] args) {
        try {
            // Check args
            //
            if (args==null || args.length!=2) {
                System.err.println("Bad number of arguments: usage is: \n\t" +
                        USAGE);
                System.exit(1);
            }
            try {
                InetAddress.getByName(args[0]);
            } catch (UnknownHostException x) {
                System.err.println("No such host: " + args[0]+
                            "\n usage is: \n\t" + USAGE);
                System.exit(2);
            } catch (Exception x) {
                System.err.println("Bad address: " + args[0]+
                            "\n usage is: \n\t" + USAGE);                
                System.exit(2);
            }
            try {
                if (Integer.parseInt(args[1]) <= 0) {
                    System.err.println("Bad port value: " + args[1]+
                            "\n usage is: \n\t" + USAGE);
                    System.exit(2);
                }
            } catch (Exception x) {
                System.err.println("Bad argument: " + args[1]+
                        "\n usage is: \n\t" + USAGE);
                System.exit(2);
            }
            
            // Create an environment map to hold connection properties
            // like credentials etc... We will later pass this map
            // to the JMX Connector.
            //
            System.out.println("\nInitialize the environment map");
            final Map<String,Object> env = new HashMap<String,Object>();
            
            // Provide the credentials required by the server
            // to successfully perform user authentication
            //
            final String[] credentials = new String[] { "guest" , "guestpasswd" };
            env.put("jmx.remote.credentials", credentials);
            
            // Provide the SSL/TLS-based RMI Client Socket Factory required
            // by the JNDI/RMI Registry Service Provider to communicate with
            // the SSL/TLS-protected RMI Registry
            //
            env.put("com.sun.jndi.rmi.factory.socket",
                    new SslRMIClientSocketFactory());
            
            // Create the RMI connector client and
            // connect it to the RMI connector server
            // args[0] is the server's host - localhost
            // args[1] is the secure server port - 4545
            //
            System.out.println("\nCreate the RMI connector client and " +
                    "connect it to the RMI connector server");
            final JMXServiceURL url = new JMXServiceURL(
                    "service:jmx:rmi:///jndi/rmi://"+args[0]+":"+args[1] + 
                    "/jmxrmi");
            
            System.out.println("Connecting to: "+url);
            final JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
            
            // Get an MBeanServerConnection
            //
            System.out.println("\nGet the MBeanServerConnection");
            final MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
            
            // Create a proxy for the ScanManager MXBean
            //
            final ScanManagerMXBean proxy = 
                    ScanManager.newSingletonProxy(mbsc);
            
            // Get the ScanDirConfig MXBean from the scan manager
            //
            System.out.println(
                    "\nGet ScanDirConfigMXBean from ScanManagerMXBean");
            final ScanDirConfigMXBean configMBean = 
                    proxy.getConfigurationMBean();
            
            // Print the scan dir configuration
            //
            System.out.println(
                    "\nGet 'Configuration' attribute on ScanDirConfigMXBean");
            System.out.println("\nConfiguration:\n" +
                    configMBean.getConfiguration());
            
            // Try to invoke the "close" method on the ScanManager MXBean.
            //
            // Should get a SecurityException as the user "guest" doesn't
            // have readwrite access.
            //
            System.out.println("\nInvoke 'close' on ScanManagerMXBean");
            try {
                proxy.close();
            } catch (SecurityException e) {
                System.out.println("\nGot expected security exception: " + e);
            }
            
            // Close MBeanServer connection
            //
            System.out.println("\nClose the connection to the server");
            jmxc.close();
            System.out.println("\nBye! Bye!");
        } catch (Exception e) {
            System.out.println("\nGot unexpected exception: " + e);
            e.printStackTrace();
            System.exit(3);
        }
    }
}
