Package com.sun.faban.harness

Source Code of com.sun.faban.harness.DefaultFabanBenchmark

/* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.sun.com/cddl/cddl.html or
* install_dir/legal/LICENSE
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at install_dir/legal/LICENSE.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id$
*
* Copyright 2005-2009 Sun Microsystems Inc. All Rights Reserved
*/
package com.sun.faban.harness;

import static com.sun.faban.harness.RunContext.*;

import com.sun.faban.common.Command;
import com.sun.faban.common.CommandHandle;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.w3c.dom.Element;

/**
* The default benchmark class for use with benchmarks implemented with the
* Faban Driver Framework. This class is designed to be extended if additional
* features are desired. Do not use the DefaultFabanBenchmark if the actual
* driver is not implemented using the Faban Driver Framework. Implement the
* Benchmark interface directly in such cases.
*
* @author Akara Sucharitakul
* @deprecated Replaced by DefaultFabanBenchmark2, this class is provided for
*             backward compatibility and is to be removed in the future.
*/
@Deprecated public class DefaultFabanBenchmark implements Benchmark {

    private Logger logger = Logger.getLogger(getClass().getName());;

    /** The param repository. */
    protected ParamRepository params;

    /** The agent list. */
    protected List<String> agents;

    /** The agent hosts. */
    protected String[] agentHosts;

    /** The map from host to agents. */
    protected Map<String, List<String>> hostAgents;

    /** Environment to pass to agents when starting. */
    protected Map<String, List<String>> agentEnv;

    /** Command handle to the master. */
    protected CommandHandle masterHandle;

    /**
     * Allows benchmark to validate the configuration file. Note that no
     * execution facility is available during validation.
     *
     * @throws Exception if any error occurred.
     * @see RunContext#exec(com.sun.faban.common.Command)
     */
    public void validate() throws Exception {
        params = getParamRepository();

        // Check and match the hosts and agents
        // First, list the drivers in the config file.
        agents = params.getAttributeValues(
                                    "fa:runConfig/fd:driverConfig", "name");

        // Second, obtain the systems to run the drivers.
        agentHosts = params.getTokenizedValue(
                                        "fa:runConfig/fa:hostConfig/fa:host");

        hostAgents = new HashMap<String, List<String>>(agentHosts.length + 5);

        agentEnv = new HashMap<String, List<String>>();

        HashMap<String, Integer> anyHostAgents = new HashMap<String, Integer>();
        for (String agentName : agents) {

            String qb = "fa:runConfig/fd:driverConfig[@name=\"" + agentName +
                         "\"]/";
           
            // Obtain the environment needed for the agent type...
            List<String> env = params.getParameters(qb + "fd:environment");
            if (env != null && env.size() > 0) {
                agentEnv.put(agentName, env);
                if (logger.isLoggable(Level.FINER)) {
                    StringBuilder b = new StringBuilder();
                    b.append("Env for ").append(agentName).append("Agents: ");
                    for (String envEntry : env) {
                        b.append('[').append(envEntry).append(']');
                    }
                    logger.finer(b.toString());
                }
            }

            // Prepare the agent distribution...
            String[] agentSpecs = params.getTokenizedValue(qb + "fd:agents");

            switch (agentSpecs.length) {
                case 0: // Default to 1 agent
                    String[] defaultAgentSpecs = { "1" };
                    agentSpecs = defaultAgentSpecs; // fall thru to case 1.
                case 1: // Single value field, could be just count or host:count
                    if (agentSpecs[0].indexOf(':') < 0) { //Just count
                        int agentCnt = 0;
                        try {
                            agentCnt = Integer.parseInt(agentSpecs[0]);
                        } catch (NumberFormatException e) {
                            String msg = "Invalid agents spec " + agentSpecs[0];
                            ConfigurationException ce =
                                    new ConfigurationException(msg);
                            logger.log(Level.SEVERE, msg, ce);
                            throw ce;
                        }
                        // Record the count for this agent.
                        anyHostAgents.put(agentName, agentCnt);
                        break;
                    }
                default: // One or more host:count
                    for (String agentSpec : agentSpecs) {
                        int colIdx = agentSpec.indexOf(':');

                        // Check the spec for anything odd.
                        if (colIdx < 1) {
                            String msg = "Invalid agents spec " + agentSpec;
                            ConfigurationException ce =
                                    new ConfigurationException(msg);
                            logger.log(Level.SEVERE, msg, ce);
                            throw ce;
                        }
                        String hostName = agentSpec.substring(0, colIdx);
                        int agentCnt;
                        try {
                            agentCnt = Integer.parseInt(
                                            agentSpec.substring(colIdx + 1));
                        } catch (NumberFormatException e) {
                            String msg = "Invalid agents spec " + agentSpec;
                            ConfigurationException ce =
                                    new ConfigurationException(msg);
                            logger.log(Level.SEVERE, msg, ce);
                            throw ce;
                        }
                        // Add one entry to the list for each agent.
                        List<String> agentList = null;
                        for (int i = 0; i < agentCnt; i++) {
                            if (agentList == null)
                                agentList = hostAgents.get(hostName);
                            if (agentList == null) {
                                agentList = new ArrayList<String>();
                                hostAgents.put(hostName, agentList);
                            }
                            agentList.add(agentName);
                        }
                    }

            }
        }

        // After we got the host specifics done, we'll need to take care of
        // distributing the anyhost agents fairly.
        if (anyHostAgents.size() > 0) {

            // Ensure all hosts are in hostAgents.
            for (String hostName : agentHosts)
                if (hostAgents.get(hostName) == null)
                    hostAgents.put(hostName, new ArrayList<String>());

            String previousHost = null;
            for (Map.Entry<String, Integer> anyHostEntry :
                                                    anyHostAgents.entrySet()) {
                String agentName = anyHostEntry.getKey();
                int cnt = anyHostEntry.getValue();
                Set<Map.Entry<String, List<String>>> hostAgentsSet =
                                                        hostAgents.entrySet();

                // Find the host with minimum agent for each anyHostAgent
                for (int i = 0; i < cnt; i++) {
                    String leastBusyHost = null;
                    int minAgents = Integer.MAX_VALUE;
                    // Scan the hostAgents to find the least busy.
                    for (Map.Entry<String, List<String>> hostAgentsEntry :
                                                               hostAgentsSet) {
                        int agents = hostAgentsEntry.getValue().size();
                        if (agents < minAgents) {
                            leastBusyHost = hostAgentsEntry.getKey();
                            minAgents = agents;
                        } else if (agents == minAgents) {
                            // If there is more than one least busy, pick
                            // the first one that was not previously assigned.
                            if (leastBusyHost.equals(previousHost))
                                leastBusyHost = hostAgentsEntry.getKey();
                        }
                    }
                    hostAgents.get(leastBusyHost).add(agentName);
                    previousHost = leastBusyHost;
                }
            }
        }

        // In any case, there is a chance that some hosts are not used.
        // we just remove those hosts from hostAgents.
        Set<Map.Entry<String, List<String>>> hostAgentsSet =
                                                hostAgents.entrySet();
        for (Map.Entry<String, List<String>> hostAgentsEntry : hostAgentsSet)
            if (hostAgentsEntry.getValue().size() == 0)
                hostAgents.remove(hostAgentsEntry);

        // Then we need to make sure our agentHosts strings are accurate.

        // We want to keep the order the hosts were entered. So we use
        // a LinkedHashSet and insert every host in here.
        LinkedHashSet<String> agentHostSet = new LinkedHashSet<String>();
        for (String agentHost : agentHosts)
            agentHostSet.add(agentHost);

        Set<String> hostAgentsKeySet = hostAgents.keySet();

        // Now we remove all the hosts that are not used...
        agentHostSet.retainAll(hostAgentsKeySet);

        // and add what is used and not listed, if any.
        agentHostSet.addAll(hostAgentsKeySet);

        // Put it back into the array for later use.
        agentHosts = agentHostSet.toArray(new String[agentHostSet.size()]);

        // Recreate the string from the array.
        StringBuilder agentHostsBldr = new StringBuilder();
        for (int i = 0; i < agentHosts.length; i++) {
            if (i > 0)
                agentHostsBldr.append(' ');
            agentHostsBldr.append(agentHosts[i]);
        }

        try {
            // Save the new host back the list.
            params.setParameter("fa:runConfig/fa:hostConfig/fa:host",
                                                agentHostsBldr.toString());

            // Update the output directory to the one assigned by the harness.
            Element outputDirNode = (Element)
                    params.getNode("fa:runConfig/fd:outputDir");

            if (outputDirNode == null)
                outputDirNode = params.addParameter("fa:runConfig",
                        "http://faban.sunsource.net/ns/fabandriver", null,
                        "outputDir");

            params.setParameter(outputDirNode, getOutDir());
            params.save();
        } catch(Exception e) {
            logger.log(Level.SEVERE, "Exception updating " + getParamFile(), e);
            throw e;
        }
    }

    /**
     * This method is called to configure the specific benchmark run
     * Tasks done in this method include reading user parameters,
     * logging them and initializing various local variables.
     *
     * @throws Exception if any error occurred.
     */
    public void configure() throws Exception {
        // No configuration needed.
    }

    /**
     * This method is responsible for starting the benchmark run.
     *
     * @throws Exception if any error occurred.
     */
    public void start() throws Exception {

        // Spread the drivers to the systems.
        // Start Agents. Other JVM Options like security policy and logging
        // properties are added by CmdAgent when starting the java command.
        Command c = null;

        HashMap<String, Integer> agentIds =
                                new HashMap<String, Integer>(agents.size());

        // Iterate through all the hosts before coming back for the next set
        // of agents for the first host. Once we're though all agent sets
        // for all hosts, the agentStarted flag will be false and we'll exit
        // the loop.
        boolean agentStarted = true;
        for (int i = 0; agentStarted; i++) {
            agentStarted = false;
            for (String hostName : agentHosts) {
                List<String> agentList = hostAgents.get(hostName);
                if (i >= agentList.size())
                    continue;
                String agentType = agentList.get(i);
                Integer oldAgentId = agentIds.get(agentType);
                int agentId;
                if (oldAgentId == null) {
                    agentIds.put(agentType, 0);
                    agentId = 0;
                } else {
                    agentId = oldAgentId.intValue() + 1;
                    agentIds.put(agentType, agentId);
                }
                logger.info("Starting " + agentType + "Agent[" + agentId +
                        "] on host " + hostName + '.');
               
                String masterIP = getMasterIP(hostName);
                if (masterIP == null) {
                    masterIP = getMasterIP();
                }

                Command agent = new Command("com.sun.faban.driver.engine." +
                        "AgentImpl", agentType, String.valueOf(agentId),
                        masterIP);

                List<String> env = agentEnv.get(agentType);
                if (env != null) {
                    String[] e = new String[env.size()];
                    e = env.toArray(e);
                    agent.setEnvironment(e);
                }

                agent.setSynchronous(false);
                java(hostName, agent);
                agentStarted = true;
                //Wait for the Agents to register
                try {
                    Thread.sleep(500);
                } catch(InterruptedException e) {
                    logger.severe("Exception Sleeping : " + e);
                    logger.log(Level.FINE, "Exception", e);
                }
            }
        }

        //Wait for all the Agents to register
        try {
            Thread.sleep(5000);
        } catch(InterruptedException e) {
            logger.severe("Exception Sleeping : " + e);
            logger.log(Level.FINE, "Exception", e);
        }

        // Start the master
        c = new Command("-Dbenchmark.config=" + getParamFile(),
                "-Dfaban.outputdir.unique=true",
                "com.sun.faban.driver.engine.MasterImpl");
        c.setSynchronous(false);

        masterHandle = java(c);

        // Wait until the master gets to rampup before we give back control.
        // This will ensure the tools start at correct times.
        java(new Command("com.sun.faban.driver.engine.PingMaster", "RAMPUP"));
        logger.info("Ramp up started");
    }

    /**
     * This method is responsible for waiting for all commands started and
     * run all postprocessing needed.
     *
     * @throws Exception if any error occurred.
     */
    public void end() throws Exception {

        // Wait for the master to complete the run.
        masterHandle.waitFor();
        int exitValue = masterHandle.exitValue();
        if (exitValue != 0) {
            logger.severe("Master terminated with exit value " + exitValue);
            throw new Exception("Driver failed to complete benchmark run");
        }
    }

    /**
     * This method aborts the current benchmark run and is
     * called when a user asks for a run to be killed.
     *
     * @throws Exception if any error occurred.
     */
    public void kill() throws Exception {
        // We don't need to kill off anything here. All processes managed
        // by the run context are automatically terminated.
    }
}
TOP

Related Classes of com.sun.faban.harness.DefaultFabanBenchmark

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.