

package gov.va.med.cds.client.functional.mbean;


import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import gov.va.med.cds.client.functional.AbstractFunctionalTest;
import gov.va.med.cds.junit.runners.AfterTestsOnce;
import gov.va.med.cds.junit.runners.BeforeTestsOnce;
import gov.va.med.cds.junit.runners.SuiteAwareSpringRunner;
import gov.va.med.cds.junit.runners.Suite;

import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * ResponseValidatorMBeanTest: verifyies the read results validation flag that has been exposed through MBean
 */
@RunWith( SuiteAwareSpringRunner.class )
public class ResponseValidatorMBeanTest
    extends
        AbstractFunctionalTest
{
    private static Log logger = null;
    private static final String NL = System.getProperty( "line.separator" );
    private static final String MBEAN_SERVER_IP = "localhost";
    private static final String MBEAN_SERVER_PORT = "5555";
    private static final String ADMIN_USER_ENV_PROPERTY_NAME = "USER";
    private static final String ADMIN_PASSWORD_ENV_PROPERTY_NAME = "PASSWORD";
    private static final String FILTER_MANAGER_MBEAN_DOMAIN = "gov.va.med.cds.request";
    private static final String FILTER_MANAGER_MBEAN_NAME = ":name=cds-read-response-validator";

    private JMXConnector jmxc;
    private ObjectName stdMBeanName;
    private MBeanServerConnection mbsc;


    public static final void usage( )
    {
        if ( logger.isErrorEnabled() )
        {
            logger.error( "The FilterManager JMX client:" + NL + "Options:" + NL + " -ip - IP Address to FilterManager." + NL
                            + " -port - Listening port." + NL + " -user - (optional) Specify the username for authentication." + NL
                            + " -password - (optional) Specify the password for authentication." + NL );

            System.exit( 1 );
        }
    }


    @Ignore
    @Test
    @Suite(groups = "prototypetest" )
    // FIX ME .R.S.
    public void testVerifyValidationXml( )
        throws Exception
    {
        // set the flag as 'true'
        mbsc.invoke( stdMBeanName, "setValidateReadResponseXML", new Object[] { true }, new String[] { "boolean" } );
        String validateReadResponseXML = mbsc.invoke( stdMBeanName, "isValidateReadResponseXML", null, null ).toString();
        assertTrue( new java.lang.Boolean( validateReadResponseXML ).booleanValue() );

        // set the flag as 'false'
        mbsc.invoke( stdMBeanName, "setValidateReadResponseXML", new Object[] { false }, new String[] { "boolean" } );
        validateReadResponseXML = mbsc.invoke( stdMBeanName, "isValidateReadResponseXML", null, null ).toString();
        assertFalse( new java.lang.Boolean( validateReadResponseXML ).booleanValue() );
    }


        @BeforeClass
        static public void beforeResponseValidatorMBeanTestClassSetUp( )
            throws Exception
        {
            logger = LogFactory.getLog(ResponseValidatorMBeanTest.class);
    
        }

        @Ignore
        @BeforeTestsOnce
        @Suite(groups = "prototypetest" )
        public void beforeResponseValidatorMBeanTestsSetUp() {
            // instantiate response validator MBean
            getResponseValidatorMBean( new String[] { "-ip", MBEAN_SERVER_IP, "-port", MBEAN_SERVER_PORT } );
            
        }
        
        @Ignore
        @AfterTestsOnce
        @Suite(groups = "prototypetest" )
        public void afterResponseValidatorMBeanTestsTearDown( )
            throws Exception
        {
    
            // Close MBeanServer connection
            jmxc.close();
        }

    private void getResponseValidatorMBean( String[] args )
    {
        try
        {
            GetArgs opts = new GetArgs( ResponseValidatorMBeanTest.class, args, "ip:port:user:password:shutdownNow", "ip:port", false );

            String ip = opts.getArg( "ip" );
            String user = opts.getArg( "user" );
            String port = opts.getArg( "port" );
            String password = opts.getArg( "password" );

            // Create an RMI connector client and connect it to the RMI connector server
            JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://" + ip + ":" + port + "/jmxrmi" );

            // Need to test password against remote server
            Map<String, String> env = new HashMap<String, String>();
            String pkgs = "com.sun.enterprise.admin.jmx.remote.protocol";
            env.put( JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, pkgs );
            env.put( ADMIN_USER_ENV_PROPERTY_NAME, user );
            env.put( ADMIN_PASSWORD_ENV_PROPERTY_NAME, password );

            // Creates a connector client for the connector server at the given address. The resultant client is not
            // connected until its connect method is called.
            jmxc = JMXConnectorFactory.newJMXConnector( url, env );
            jmxc.connect();

            // Get an MBeanServerConnection
            mbsc = jmxc.getMBeanServerConnection();

            // Create FitlerManager MBean
            stdMBeanName = new ObjectName( FILTER_MANAGER_MBEAN_DOMAIN + FILTER_MANAGER_MBEAN_NAME );
            mbsc.getObjectInstance( stdMBeanName );
        }
        catch ( Exception e )
        {
            if ( e.getMessage().startsWith( "Failed to retrieve RMIServer stub" ) )
            {
                if ( logger.isErrorEnabled() )
                {
                    logger.error( "\nFailed to retrieve RMIServer stub. Response Validator not running at the specified location." );
                }
            }
            else
            {
                e.printStackTrace();
            }
        }
    }
}
