content: /* 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 2008-2009 Sun Microsystems Inc. All Rights Reserved
   */
  package com.sun.faban.harness.tools;
  
  import com.sun.faban.common.Command;
  import com.sun.faban.common.CommandHandle;
  import com.sun.faban.common.FileTransfer;
  import com.sun.faban.harness.agent.CmdAgent;
  import com.sun.faban.harness.agent.CmdAgentImpl;
  import com.sun.faban.harness.agent.FileAgent;
  import com.sun.faban.harness.common.Config;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.*;
  import java.util.concurrent.CountDownLatch;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  
  /**
   *
   * MysqlStats is a class for mysql stats collection.
   * It simply collects "show global status" at the start and end of a
   * run and diffs them.
   * The tool needs to be specified as follows: 
   * mysqlstats <MYSQL_HOME> <mysql_user> <mysql_password>
   * where MYSQL_HOME is the home directory of mysql,
   * mysql_user is the username to connect to mysql,
   * mysql_password is the password for username to connect to mysql.
   * E.g: mysqlstats /opt/coolstack/mysql_32bit web20 web20
   * @author Shanti Subramanyam
   * @see GenericTool
   * @deprecated
   */
  @Deprecated public class Mysqlstats implements Tool {
  
      static final int NOT_STARTED = 0;
      static final int STARTED = 1;
      static final int STOPPED = 2;
  	Logger logger;
  
      String cmd;
      Command mysql;
      CommandHandle tool;
  	int toolStatus = NOT_STARTED;
      CountDownLatch latch;
      boolean countedDown = false;
      String logfile, logfile1, logfile2, outfile; // Name of logfiles
      String toolName;
      String path = null; // The path to the tool.
      int priority;
      int delay;
      int duration;
      CmdAgent cmdAgent;
  
      /** The timer to be used by this tool. */
      protected Timer timer;
  
      // Thread toolThread = null;
  	// private Mysqlstats toolObj;
  
      /**
       * Constructs the Mysqlstats.
       */
      public Mysqlstats() {
  		logger = Logger.getLogger(this.getClass().getName());
  	}
  
      /**
       * Configures Mysqlstats.
       * @param tool name of the tool (Executable)
       * @param argList list containing arguments to tool
       * @param path The path to run mysqlstats
       * @param outDir The output directory
       * @param host name of machine the tool is running on
       * @param masterhost name of master machine
       * @param cmdAgent agent The command agent used for executing tools
       * @param latch The latch the tool uses to identify it's completion.
       */
      public void configure(String tool, List<String> argList, String path,
                            String outDir, String host, String masterhost,
                            CmdAgentImpl cmdAgent, CountDownLatch latch) {
          toolName = tool;
          this.cmdAgent = cmdAgent;
          timer = cmdAgent.getTimer();
          this.latch = latch;
  
          outfile = getOutputFile(outDir, host);
          logfile = getLogFile();
  		// We need two intermediate files for the begin/end snapshots
  		logfile1 = logfile + "_1";
  		logfile2 = logfile + "_2";
  
          if (argList.size() < 3)
              throw new IllegalArgumentException(
                      "MYSQL_HOME, USER, PASSWD not passed as argument");
  
          String mysqlHome = argList.get(0);
          String mysqlUser = argList.get(1);
          String mysqlPass = argList.get(2);
  
          if (mysqlHome.endsWith(File.separator))
              mysqlHome = mysqlHome.substring(0, mysqlHome.length() -
                                                File.separator.length());
  
          // Prepare the input
          // String stdin = "show global status\n" + "quit\n";
          // Prepare the command
          ArrayList<String> c = new ArrayList<String>();
          String cmd = "mysql";
          if (mysqlHome != null)
              cmd = mysqlHome + File.separator + "bin" + File.separator + cmd;
          c.add(cmd);
  		if (mysqlUser != null)
              c.add("-u" + mysqlUser);
          if (mysqlPass != null)
              c.add("-p" + mysqlPass);
          c.add("-B");
          c.add("-e");
          c.add("show global status;");
          logger.log(Level.FINE, "Setting up mysql command: " + c);
          mysql = new Command(c);
  		/***
          mysql.setEnvironment(env);
          mysql.setInput(stdin.getBytes());
          ***/
      }
  
      /**
       * Obtains the temporary log file name.
       * @return The log file name
       */
      protected String getLogFile() {
          return Config.TMP_DIR + toolName + ".out." + this.hashCode();
  
          // TODO: Take out hashcode, replace with other value.
      }
  
      /**
       * Obtains the final output file name.
       * @param outDir The output or run directory
       * @param host The host name running the tool
       * @return The output file name
       */
      protected String getOutputFile(String outDir, String host) {
          return outDir + toolName + ".log." + host;
      }
  
      /**
       * This method is required by the Tool API.
       * It is called to abort the currently running tool if any.
       */
      public void kill() {
          // For most tools, we try to collect the output no matter what.
          stop(false);
          finish();
      }
  
      /**
       * This method is responsible for starting up the tool and stopping it
       * after the duration specified. It uses a thread to sleep for the
       * delay + duration and then calls the stop().
       * @param delay int delay (sec) after which start should be called
       * @param duration int duration for which the tool needs to be run
       * @return true if mysqlstats scheduled successfully
       */
      public boolean start(int delay, int duration) {
          this.duration = duration;
  
          if(this.start(delay)) {
              TimerTask stopTask = new TimerTask() {
                  public void run() {
                      stop();
                  }
              };
              timer.schedule(stopTask, (delay + duration) * 1000);
              return true;
          } else {
              return false;
          }
      }
  
      /**
       * This method is responsible for starting up the tool utility.
       * @param delay int delay (sec) after which start should be called
       * @return true if mysqlstats scheduled successfully
       */
      public boolean start(int delay) {
          TimerTask startTask = new TimerTask() {
              public void run() {
                  start();
              }
          };
          timer.schedule(startTask, delay * 1000);
          return true;
      }
  
      /**
       * Starts the mysqlstat tool.
       */
      protected void start() {
          try {            
  		    mysql.setOutputFile(Command.STDOUT, logfile1);
              tool = cmdAgent.execute(mysql, null);
              logger.log(Level.FINE, "Calling mysql show status at start");
              toolStatus = STARTED;
          } catch (IOException e) {
              logger.log(Level.SEVERE, "Error executing mysql show status", e);
          } catch (InterruptedException e) {
              logger.log(Level.SEVERE, "Interrupted executing mysql show status", e);
          }
      }
  
      /**
       * This method is responsible for stopping the tool.
       */
      public void stop() {
          stop(true);
          finish();
      }
  
  
      /**
       * This method is responsible for stopping the tool utility.
       * @param warn Whether to warn if tool is not running.
       */
      protected void stop(boolean warn) {
  
          if (toolStatus == STARTED)
              try {
  		        mysql.setOutputFile(Command.STDOUT, logfile2);
                  logger.log(Level.FINE, "Calling mysql show status at end of run");
                  tool = cmdAgent.execute(mysql, null);
                  toolStatus = STOPPED;
  
                  // Get the report from both snapshots
                  getReport(logfile1, logfile2, logfile);
                  // xfer log file to master machine, log any errors
                  xferLog();
                  logger.fine(toolName + " Stopped ");
              } catch (IOException e) {
                  logger.log(Level.SEVERE, "Error executing mysql show status", e);
              } catch (InterruptedException e) {
                  logger.log(Level.SEVERE, "Interrupted executing mysql show status", e);
              }
          else if (warn && toolStatus == NOT_STARTED)
              logger.warning("Tool not started but stop called for " + toolName);
      }
  
      /**
       * Get final report by diffing the two logfiles.
       * @param log1 The first logfile
       * @param log2 The second logfile
       * @param outFile The output file
       */
      protected void getReport(String log1, String log2,
                                                 String outFile) {
  		String c = "mysql_diff_status.sh " + log1 + " " + log2 + " " + outFile;
          logger.log(Level.FINE, "Calling " + c);
  	    Command diffCommand = new Command(c);
  	    try {
  	        cmdAgent.execute(diffCommand, null);
          } catch (IOException e) {
              logger.log(Level.SEVERE, "Error executing mysql_diff_status.sh", e);
          } catch (InterruptedException e) {
              logger.log(Level.SEVERE, "Interrupted executing mysql_diff_status.sh", e);
          }
      }
  
      /**
       * Transfers the log files to the output file in the results directory.
       */
      protected void xferLog() {
          if (!new File(logfile).exists()) {
              logger.log(Level.SEVERE,
                      "Transfer file " + logfile + " not found.");
              return;
          }
          try {
              FileTransfer transfer = new FileTransfer(logfile, outfile);
              logger.finer("Transferring log from " + logfile + " to " + outfile);
              // Use FileAgent on master machine to copy log
              String s = Config.FILE_AGENT;
              FileAgent fa = (FileAgent)CmdAgentImpl.getRegistry().getService(s);
              if (fa.push(transfer) != transfer.getSize())
                  logger.log(Level.SEVERE, "Invalid transfer size");
  
          } catch (IOException e) {
              logger.log(Level.SEVERE, "Error transferring " + logfile, e);
          }
      }
  
      /**
       * Finishes up mysqlstats.
       */
      protected void finish() {
          if (!countedDown)
              latch.countDown();
          countedDown = true;
      }
  }
  
  