/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * This software is the proprietary information of Sun Microsystems, Inc.
 * Use is subject to license terms.
 * 
 * Copyright 2004 Sun Microsystems, Inc.  Tous droits r?serv?s.
 * Ce logiciel est propri?t? de Sun Microsystems, Inc.
 * Distribu? par des licences qui en restreignent l'utilisation.
 *
 * ident        "@(#)Transaction1.java 1.12     04/06/30 SMI"
 *
 */

package com.sun.mfwk.examples.instrum;

// java imports
//

import java.util.*;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.logging.Level;

// JDMK import
import com.sun.jdmk.comm.*;
import com.sun.jdmk.*;

// JMX RI imports
import javax.management.*;
import javax.management.remote.*;
import javax.management.remote.jmxmp.*;
import javax.management.remote.rmi.*;

// JESMA APIs
import com.sun.mfwk.trans.*;
import com.sun.mfwk.util.instrum.*;
import com.sun.mfwk.util.log.MfLogService;

/*
 *
 * Example of MfTransaction API usage using the Option 1 (MfTransaction start/stop)
 *
 */

public class Transaction1 { 

    public static void main(String[] args) {

	Transaction1 myTransaction1 = new Transaction1();

	if (args.length == 1) {
	    myTransaction1.nbLoop = new Integer(args[0]).intValue();
	} else {
	    System.out.println("Usage: java Transaction1 nbLoop");
	    System.exit(1);
	}


	// Initialization: traces, connectors
	myTransaction1.init();

	// MfTransaction example
	myTransaction1.manageTransactions();
    }


    public void init() {

        // Parse system properties to check if LEVEL_TRACE and/or
	// LEVEL_DEBUG are set and enable the TRACE level accordingly
        try {
            TraceManager.parseTraceProperties();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

	
	/*
        ** Create the MBean server
	*/
	mbs = MBeanServerFactory.createMBeanServer();

	/*
        ** Create JDMK HTML adaptor for debug 
	*/
	HtmlAdaptorServer htmlAdaptor = new HtmlAdaptorServer(8083);
        try {
            ObjectName oName =
                new ObjectName("jmx", "type", "htmlAdaptor");
            mbs.registerMBean(htmlAdaptor, oName);
	    htmlAdaptor.start();
        } catch(Exception e) {
            e.printStackTrace();
        }
	// waiting to leave starting state...
        while (htmlAdaptor.getState() == CommunicatorServer.STARTING) {
	    System.out.println("sleeping on htmlAdaptor");
            sleep(500);
        }
        System.out.println("\nHTML protocol adaptor started on port "+ htmlAdaptor.getPort());

	/*
        ** Create JSR 160 JMXMP connector 
	*/
	JMXConnectorServer cs = null;
	try {
	    JMXServiceURL url = new JMXServiceURL("jmxmp", null, 0);
	    cs = new JMXMPConnectorServer(url, null);
	    ObjectName csName =
		new ObjectName("jmx:type=cserver,name=jmxmpConnectorServer"); 
	    mbs.registerMBean(cs, csName);
	    cs.start();
	} catch (Exception e) {
	    e.printStackTrace();
	    System.exit(1);
	}
	System.out.println("\nJMXMP connector started.");

	/*
        ** Create JSR 160 RMI connector 
	*/
	RMIConnectorServer rmiConnect = null;
	try {
	    String urlPath = "/jndi/rmi://" + "localhost" + ":" + "1099" + "/jmxrmi";
	    JMXServiceURL url = new JMXServiceURL("rmi", "", 0, urlPath);
	    Map env = new HashMap();
	    env.put(RMIConnectorServer.JNDI_REBIND_ATTRIBUTE, "true");
	    rmiConnect = new RMIConnectorServer(url, env, mbs);
	    ObjectName oName =
  	    	    new ObjectName("jmx:type=cserver,name=RmiConnectorServer"); 
	    mbs.registerMBean(rmiConnect, oName);
	    rmiConnect.start();
	} catch (Exception e) {
	    e.printStackTrace();
	    System.exit(1);
	}
	System.out.println("\nRMI connector started.");

	// logging init
        MfLogService l = new MfLogService("sdk_transaction1");
    }


    void manageTransactions() {
	// Instanciate transaction factory
	MfTransactionFactory tranFactory = new MfTransactionFactoryImpl();

	// Instanciate the MfInstrumManagement MBean
	MfInstrumManagement instrumManagement = new MfInstrumManagement();
	// Register it in the MBeanServer
	try {
	    ObjectName oName = MfObjectNameFactory.getInstrumManagementName();
	    mbs.registerMBean(instrumManagement, oName);
	} catch (Exception e) {
	    e.printStackTrace();
	}

	// Set logging level to ALL
	try {
	    mbs.setAttribute(MfObjectNameFactory.getInstrumManagementName(),
	    		     new Attribute("LoggingLevel", Level.ALL));
	} catch (Exception e) {
	    e.printStackTrace();
	}

	// Instanciate the Metrics MBean
	MfTransactionMetrics transMetrics = new MfTransactionMetrics();
	// Register it in the MBeanServer
	try {
	    ObjectName oName = MfObjectNameFactory.getTransactionMetricsName("uri_name");
	    mbs.registerMBean(transMetrics, oName);
	} catch (Exception e) {
	    e.printStackTrace();
	}

	// Define the MfTransaction type
	MfTransactionDefinition tranDef =
	    tranFactory.newTransactionDefinition("MfTransaction type 1", "hello:/xx.xx", transMetrics);

	// Define the MfTransaction instance (start/stop mode)
	MfTransaction tran = tranFactory.newTransaction(tranDef, null);

	for (int ii=0; ii < nbLoop; ii++, sleep(500)) {

	    // Start the transaction
	    tran.start();

	    // MfTransaction processing
	    System.out.println("Hello world1!");

	    math_proc(); 

	    sleep(4000);

	    // Suspend transaction time
	    tran.block();

	    // External service processing
	    sleep(1000);

	    math_proc(); 

	    // Resume transaction time
	    tran.unblock();


	    // Stop the transaction
	    tran.stop(MfConstants.STATUS_GOOD);
	}

    }

    private static void math_proc() {
	    double sum = 0;
	    for (int i = 0; i < 50000; i++) {
		double r = 0.543;
		double x = Math.pow(30, r);
		sum += x - r;
	    }	  
    } 

    private static void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            return;
        }
    }

    private MBeanServer mbs = null;
    private int nbLoop = 0;

}
