/* 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 com.sun.faban.common.Command;
import com.sun.faban.common.CommandHandle;
import com.sun.faban.harness.engine.CmdService;
import com.sun.faban.harness.engine.RunFacade;
import com.sun.faban.harness.common.Config;
import com.sun.faban.harness.util.Invoker;
import com.sun.faban.harness.agent.CmdAgentImpl;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.File;
import java.util.List;
/**
* The RunContext provides callbacks into the harness and the run environment.
* All methods are static and it is suitable for static imports making calls
* much shorter and easier. RunContext calls are available during a run on the
* master. With exception to two methods, calling RunContext methods from tools
* or inside RemoteCallable.call() will result in a NullPointerException.
* The two methods callable from the agent are the local versions of
* RunContext.exec() and RunContext.java(). These are the signatures without
* a host name.
*
* @author Akara Sucharitakul
*/
public class RunContext {
/**
* Obtains the benchmark deployment directory.
* @return The benchmark deployment directory
*/
public static String getBenchmarkDir() {
return RunFacade.getInstance().getBenchmarkDir();
}
/**
* Obtains the sequence part of the run id.
* @return The run sequence
*/
public static String getRunSeq() {
return RunFacade.getInstance().getRunSeq();
}
/**
* Obtains the full name of the run in the form benchmark.id.
* @return The run name
*/
public static String getRunId() {
return RunFacade.getInstance().getRunId();
}
/**
* Obtains the output directory for this run.
* @return The run output directory
*/
public static String getOutDir() {
return RunFacade.getInstance().getOutDir();
}
/**
* Obtains the tmp directory used by Faban on the target host.
* This may not be the same as the local one. Each OS is different
* and the tmpdir for the web container is also different.
* @param host The host to obtain the tmp dir, or null for local JVM
* @return The tmp directory
*/
public static String getTmpDir(String host) {
if (host == null)
return Config.TMP_DIR;
else
return CmdService.getHandle().getTmpDir(host);
}
/**
* Obtains the param repository for this run.
* @return The param repository
*/
public static ParamRepository getParamRepository() {
return RunFacade.getInstance().getParamRepository();
}
/**
* Obtains the parameter/config file path for this run.
* @return The parameter file path
*/
public static String getParamFile() {
return RunFacade.getInstance().getParamFile();
}
/**
* Returns the location of this command on the local system. This is
* one of the few methods callable from tools and RemoteCallable.call().
* Similar to the which shell command, 'which' returns the actual path
* to the given command. If it maps to a series of commands, they will
* be returned as a single string separated by spaces. Note that 'which'
* does not actually try to check the underlying system for commands
* in the search path. It only checks the Faban infrastructure for
* existence of such a command.
* @param c The command to search for
* @return The actual command to execute, or null if not found.
* @throws IOException If there is a communication error to the
* remote agent
*/
public static String which(String c) throws IOException {
CmdAgentImpl agent = CmdAgentImpl.getHandle();
if (agent != null) // Running on agent
return agent.which(c, Invoker.getContextLocation());
else // Running on master
return CmdService.getHandle().which(c,
Invoker.getContextLocation());
}
/**
* Returns the location of this command on the target system.
* Similar to the which shell command, 'which' returns the actual path
* to the given command. If it maps to a series of commands, they will
* be returned as a single string separated by spaces. Note that 'which'
* does not actually try to check the underlying system for commands
* in the search path. It only checks the Faban infrastructure for
* existence of such a command.
* @param host The host to search
* @param c The command to search for
* @return The actual command to execute, or null if not found.
* @throws IOException If there is a communication error to the
* remote agent
*/
public static String which(String host, String c) throws IOException {
return CmdService.getHandle().which(host, c,
Invoker.getContextLocation());
}
/**
* Returns the location of this command on the target systems.
* Similar to the which shell command, 'which' returns the actual path
* to the given command. If it maps to a series of commands, they will
* be returned as a single string separated by spaces. Note that 'which'
* does not actually try to check the underlying system for commands
* in the search path. It only checks the Faban infrastructure for
* existence of such a command.
* @param hosts The hosts to search
* @param c The command to search for
* @return The actual command paths to execute, or null elements if not found.
*/
public static String[] which(String[] hosts, String c) {
return CmdService.getHandle().which(hosts, c,
Invoker.getContextLocation());
}
/**
* Executes a command on the local system. This is one of the few
* methods callable from tools and RemoteCallable.call().
* @param c The command to be executed
* @return A handle to the command
* @throws IOException Error communicating with resulting process
* @throws InterruptedException Thread got interrupted waiting
*/
public static CommandHandle exec(Command c)
throws IOException, InterruptedException {
CmdAgentImpl agent = CmdAgentImpl.getHandle();
if (agent != null) // Running on agent
return agent.execute(c, Invoker.getContextLocation());
else // Running on master
return CmdService.getHandle().execute(c,
Invoker.getContextLocation());
}
/**
* Executes a command on a remote host.
* @param host The target machine to execute the command
* @param c The command to be executed
* @return A handle to the command
* @throws IOException Error communicating with resulting process
* @throws InterruptedException Thread got interrupted waiting
*/
public static CommandHandle exec(String host, Command c)
throws IOException, InterruptedException {
return CmdService.getHandle().execute(host, c,
Invoker.getContextLocation());
}
/**
* Executes a command on a set of remote hosts.
* @param hosts The target machines to execute the command
* @param c The command to be executed
* @return Handles to the command on each of the target machines
* @throws IOException Error communicating with resulting process
* @throws InterruptedException Thread got interrupted waiting
*/
public static CommandHandle[] exec(String[] hosts, Command c)
throws IOException, InterruptedException {
return CmdService.getHandle().execute(hosts, c,
Invoker.getContextLocation());
}
/**
* Executes a java command on the local system. This is one of the two
* methods callable from tools and RemoteCallable.call().
* @param java The command to be executed
* @return A handle to the command
* @throws java.io.IOException Error communicating with resulting process
* @throws InterruptedException Thread got interrupted waiting
*/
public static CommandHandle java(Command java)
throws IOException, InterruptedException {
CmdAgentImpl agent = CmdAgentImpl.getHandle();
if (agent != null) // Running on agent
return agent.java(java, Invoker.getContextLocation());
else // Running on master
return CmdService.getHandle().java(java,
Invoker.getContextLocation());
}
/**
* Executes a java command on a remote host.
*
* @param host The target machine to execute the command
* @param java The command to be executed
* @return A handle to the command
* @throws java.io.IOException Error communicating with resulting process
* @throws InterruptedException Thread got interrupted waiting
*/
public static CommandHandle java(String host, Command java)
throws IOException, InterruptedException {
return CmdService.getHandle().java(host, java,
Invoker.getContextLocation());
}
/**
* Executes a java command on a set of remote hosts.
*
* @param hosts The target machines to execute the command
* @param java The command to be executed
* @return Handles to the command on each of the target machines
* @throws java.io.IOException Error communicating with resulting process
* @throws InterruptedException Thread got interrupted waiting
*/
public static CommandHandle[] java(String[] hosts, Command java)
throws IOException, InterruptedException {
return CmdService.getHandle().java(hosts, java,
Invoker.getContextLocation());
}
/**
* Execute a code block defined as a RemoteCallable on a remote host.
* The only RunContext methods available to the code block are the local
* exec and java calls. All other calls to RunContext will result in a
* NullPointerException.
* @param host The remote host
* @param callable The callable defining the code block
* @return The result of the callable
* @throws Exception An error occurred making the call
*/
public static <V extends Serializable> V
exec(String host, RemoteCallable<V> callable)
throws Exception {
return CmdService.getHandle().execute(host, callable,
Invoker.getContextLocation());
}
/**
* Execute a code block defined as a RemoteCallable on a set of
* remote hosts. The only RunContext methods available to the code block
* are the local exec and java calls. All other calls to RunContext will
* result in a NullPointerException.
* @param hosts The remote hosts
* @param callable The callable defining the code block
* @return The result of the callable
* @throws Exception An error occurred making the call
*/
public static <V extends Serializable> List<V>
exec(String[] hosts, RemoteCallable<V> callable)
throws Exception {
return CmdService.getHandle().execute(hosts, callable,
Invoker.getContextLocation());
}
/**
* Obtains the name of the master machine.
*
* @return The name of the master machine
*/
public static String getMaster() {
return CmdService.getHandle().getMaster();
}
/**
* Returns the ip address of the master.
* @return The ip address of the master
*/
public static String getMasterIP() {
return CmdService.getHandle().getMasterIP();
}
/**
* Returns the ip address of the master's interface best used for
* communicating with the target host.
* @param agentHost The target host
* @return The ip address of the master
*/
public static String getMasterIP(String agentHost) {
return CmdService.getHandle().getMasterIP(agentHost);
}
/**
* Obtains the actual host name of a host. In most cases, the configuration
* refers to a host with the interface name. If the host has multiple
* interfaces, the interface name is not the same as the host name. This
* method tries to detect the true hostname given a host or interface name.
* @param host The known host name
* @return The true host name
*/
public static String getHostName(String host) {
return CmdService.getHandle().getHostRoles().getHostByAlias(host);
}
/**
* Pushes a local file on the Faban master to the remote host. If a
* relative path is given for the filename (local file), it is looked
* up in the run directory.
* @param fileName The source file name
* @param destHost The destination machine
* @param destFile The destination file name
* @return true if successful, false otherwise
*/
public static boolean pushFile(String fileName, String destHost,
String destFile) {
File src = new File(fileName);
if (!src.isAbsolute())
fileName = getOutDir() + fileName;
return CmdService.getHandle().push(fileName, destHost, destFile);
}
/**
* Deletes a file on a remote host.
* @param hostName The remote host name
* @param fileName The file name
* @return true if successful, false otherwise
*/
public static boolean deleteFile(String hostName, String fileName) {
return CmdService.getHandle().delete(hostName, fileName);
}
/**
* Deletes files on a target remote host.
* @param hostName The remote host name
* @param dir The file name
* @param filter The file name filter
* @return true if successful, false otherwise
*/
public static boolean deleteFiles(String hostName, String dir,
FileFilter filter) {
return CmdService.getHandle().delete(hostName, dir, filter);
}
/**
* Truncates a file on a remote host.
* @param hostName The remote host name
* @param fileName The file name
* @return true if successful, false otherwise
*/
public static boolean truncateFile(String hostName, String fileName) {
return CmdService.getHandle().truncate(hostName, fileName);
}
/**
* Gets/copies a file from a remote host. If a relative path is given for
* localFileName, the file will be placed in the current run output
* directory.
* @param hostName The remote host name
* @param fileName The file name on the remote host
* @param localFileName The target file name on the local host
* @return true if successful, false otherwise
*/
public static boolean getFile(String hostName, String fileName,
String localFileName) {
File dest = new File(localFileName);
if (!dest.isAbsolute())
localFileName = getOutDir() + localFileName;
return CmdService.getHandle().get(hostName, fileName, localFileName);
}
/**
* Checks whether the given remote file exists.
* @param hostName The host name to check.
* @param fileName The file name to test.
* @return true if exists, false otherwise.
*/
public static boolean exists(String hostName, String fileName) {
CmdService cs = CmdService.getHandle();
return cs.doesFileExist(hostName, fileName);
}
/**
* Checks whether the given remote file exists and is a normal file.
* @param hostName The host name to check.
* @param fileName The file name to test.
* @return true if file is a normal file, false otherwise.
*/
public static boolean isFile(String hostName, String fileName) {
CmdService cs = CmdService.getHandle();
return cs.isFile(hostName, fileName);
}
/**
* Checks whether the given remote file exists and is a directory.
* @param hostName The host name to check.
* @param fileName The file name to test.
* @return true if file is a directory, false otherwise.
*/
public static boolean isDirectory(String hostName, String fileName) {
CmdService cs = CmdService.getHandle();
return cs.isDirectory(hostName, fileName);
}
/**
* Reads a file from a remote host and writes the contents to a
* given output stream. This method is useful for filtering the content
* of a remote file through a filtering stream.
* @param hostName The remote host name
* @param fileName The file name on the remote host
* @param stream The stream to output the data to
* @return true if successful, false otherwise
*/
public static boolean writeFileToStream(String hostName, String fileName,
OutputStream stream) {
return CmdService.getHandle().copyToStream(hostName, fileName, stream);
}
}