Package org.ngrinder

Source Code of org.ngrinder.NGrinderAgentStarter

/*
* Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ngrinder;

import com.beust.jcommander.JCommander;
import net.grinder.AgentControllerDaemon;
import net.grinder.util.VersionNumber;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.hyperic.sigar.ProcState;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.ngrinder.common.constants.AgentConstants;
import org.ngrinder.common.constants.CommonConstants;
import org.ngrinder.infra.AgentConfig;
import org.ngrinder.infra.ArchLoaderInit;
import org.ngrinder.monitor.agent.MonitorServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

import static net.grinder.util.NetworkUtils.getIP;
import static org.ngrinder.common.constants.InternalConstants.PROP_INTERNAL_NGRINDER_VERSION;
import static org.ngrinder.common.util.NoOp.noOp;

/**
* Main class to start agent or monitor.
*
* @author Mavlarn
* @author JunHo Yoon
* @since 3.0
*/
public class NGrinderAgentStarter implements AgentConstants, CommonConstants {

  private static final Logger LOG = LoggerFactory.getLogger("starter");

  private AgentConfig agentConfig;

  private AgentControllerDaemon agentController;


  /**
   * Constructor.
   */
  public NGrinderAgentStarter() {
  }

  public void init() {
    // Check agent start mode
    this.agentConfig = createAgentConfig();
    try {
      new ArchLoaderInit().init(agentConfig.getHome().getNativeDirectory());
    } catch (Exception e) {
      LOG.error("Error while expanding native lib", e);
    }
  }

  protected AgentConfig createAgentConfig() {
    AgentConfig agentConfig = new AgentConfig();
    agentConfig.init();
    return agentConfig;
  }

  /*
   * Get the start mode, "agent" or "monitor". If it is not set in configuration, it will return "agent".
   */
  public String getStartMode() {
    return agentConfig.getCommonProperties().getProperty(PROP_COMMON_START_MODE);
  }

  /**
   * Get agent version.
   *
   * @return version string
   */
  public String getVersion() {
    return agentConfig.getInternalProperties().getProperty(PROP_INTERNAL_NGRINDER_VERSION);
  }

  /**
   * Start the performance monitor.
   */
  public void startMonitor() {
    printLog("***************************************************");
    printLog("* Start nGrinder Monitor... ");
    printLog("***************************************************");
    try {
      MonitorServer.getInstance().init(agentConfig);
      MonitorServer.getInstance().start();
    } catch (Exception e) {
      LOG.error("ERROR: {}", e.getMessage());
      printHelpAndExit("Error while starting Monitor", e);
    }
  }

  /**
   * Stop monitors.
   * Only for unit-test.
   */
  void stopMonitor() {
    MonitorServer.getInstance().stop();
  }

  /**
   * Start ngrinder agent.
   */
  public void startAgent() {
    printLog("***************************************************");
    printLog("   Start nGrinder Agent ...");
    printLog("***************************************************");

    if (StringUtils.isEmpty(System.getenv("JAVA_HOME"))) {
      printLog("Hey!! JAVA_HOME env var was not provided. "
          + "Please provide JAVA_HOME env var before running agent."
          + "Otherwise you can not execute the agent in the security mode.");
    }


    boolean serverMode = agentConfig.isServerMode();
    if (!serverMode) {
      printLog("JVM server mode is disabled.");
    }

    String controllerIP = getIP(agentConfig.getControllerIP());
    int controllerPort = agentConfig.getControllerPort();
    agentConfig.setControllerHost(controllerIP);
    LOG.info("connecting to controller {}:{}", controllerIP, controllerPort);

    try {
      agentController = new AgentControllerDaemon(agentConfig);
      agentController.run();
    } catch (Exception e) {
      LOG.error("Error while connecting to : {}:{}", controllerIP, controllerPort);
      printHelpAndExit("Error while starting Agent", e);
    }

  }

  private void printLog(String s, Object... args) {
    if (!agentConfig.isSilentMode()) {
      LOG.info(s, args);
    }
  }

  /**
   * Stop the ngrinder agent.
   * Only for unit-test.
   */
  void stopAgent() {
    LOG.info("Stop nGrinder agent!");
    agentController.shutdown();
  }


  public static NGrinderAgentStarterParam.NGrinderModeParam modeParam;

  /**
   * Agent starter.
   *
   * @param args arguments
   */
  public static void main(String[] args) {
    NGrinderAgentStarter starter = new NGrinderAgentStarter();
    final NGrinderAgentStarterParam param = new NGrinderAgentStarterParam();
    checkJavaVersion();
    JCommander commander = new JCommander(param);
    commander.setProgramName("ngrinder-agent");
    commander.setAcceptUnknownOptions(true);
    try {
      commander.parse(args);
    } catch (Exception e) {
      LOG.error(e.getMessage());
      return;
    }
    final List<String> unknownOptions = commander.getUnknownOptions();
    modeParam = param.getModeParam();
    modeParam.parse(unknownOptions.toArray(new String[unknownOptions.size()]));

    if (modeParam.version != null) {
      System.out.println("nGrinder v" + getStaticVersion());
      return;
    }

    if (modeParam.help != null) {
      modeParam.usage();
      return;
    }

    System.getProperties().putAll(modeParam.params);
    starter.init();

    final String startMode = modeParam.name();
    if ("stop".equalsIgnoreCase(param.command)) {
      starter.stopProcess(startMode);
      System.out.println("Stop the " + startMode);
      return;
    }
    starter.checkDuplicatedRun(startMode);
    if (startMode.equalsIgnoreCase("agent")) {
      starter.startAgent();
    } else if (startMode.equalsIgnoreCase("monitor")) {
      starter.startMonitor();
    } else {
      staticPrintHelpAndExit("Invalid agent.conf, '--mode' must be set as 'monitor' or 'agent'.");
    }
  }

  private static String getStaticVersion() {
    InputStream inputStream = null;
    Properties properties = new Properties();
    try {
      inputStream = NGrinderAgentStarter.class.getResourceAsStream("/internal.properties");
      properties.load(inputStream);
    } catch (IOException e) {
      // Do nothing.
    } finally {
      IOUtils.closeQuietly(inputStream);
    }
    return properties.getProperty("ngrinder.version", "UNKNOWN");
  }

  static void checkJavaVersion() {
    String curJavaVersion = System.getProperty("java.version", "1.6");
    checkJavaVersion(curJavaVersion);
  }

  static void checkJavaVersion(String curJavaVersion) {
    if (new VersionNumber(curJavaVersion).compareTo(new VersionNumber("1.6")) < 0) {
      LOG.info("- Current java version {} is less than 1.6. nGrinder Agent might not work well", curJavaVersion);
    }
  }

  /**
   * Stop process.
   *
   * @param mode agent or monitor.
   */
  protected void stopProcess(String mode) {
    String pid = agentConfig.getAgentPidProperties(mode);
    try {
      if (StringUtils.isNotBlank(pid)) {
        new Sigar().kill(pid, 15);
      }
      agentConfig.updateAgentPidProperties(mode);
    } catch (SigarException e) {
      printHelpAndExit(String.format("Error occurred while terminating %s process.\n"
          + "It can be already stopped or you may not have the permission.\n"
          + "If everything is OK. Please stop it manually.", mode), e);
    }
  }

  /**
   * Check if the process is already running in this env.
   *
   * @param startMode monitor or agent
   */
  public void checkDuplicatedRun(String startMode) {
    Sigar sigar = new Sigar();
    String existingPid = this.agentConfig.getAgentPidProperties(startMode);
    if (StringUtils.isNotEmpty(existingPid)) {
      try {
        ProcState procState = sigar.getProcState(existingPid);
        if (procState.getState() == ProcState.RUN || procState.getState() == ProcState.IDLE
            || procState.getState() == ProcState.SLEEP) {
          printHelpAndExit("Currently " + startMode + " is running with pid " + existingPid
              + ". Please stop it before run");
        }
        agentConfig.updateAgentPidProperties(startMode);
      } catch (SigarException e) {
        noOp();
      }
    }
    this.agentConfig.saveAgentPidProperties(String.valueOf(sigar.getPid()), startMode);
  }


  /**
   * Print help and exit. This is provided for mocking.
   *
   * @param message message
   */
  protected void printHelpAndExit(String message) {
    staticPrintHelpAndExit(message);
  }

  /**
   * print help and exit. This is provided for mocking.
   *
   * @param message message
   * @param e       exception
   */
  protected void printHelpAndExit(String message, Exception e) {
    staticPrintHelpAndExit(message, e);
  }


  private static void staticPrintHelpAndExit(String message) {
    staticPrintHelpAndExit(message, null);
  }

  private static void staticPrintHelpAndExit(String message, Exception e) {
    if (e == null) {
      LOG.error(message);
    } else {
      LOG.error(message, e);
    }
    if (modeParam != null) {
      modeParam.usage();
    }
    System.exit(-1);
  }
}
TOP

Related Classes of org.ngrinder.NGrinderAgentStarter

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.