All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.stratosphere.client.CliFrontend Maven / Gradle / Ivy

There is a newer version: 0.5.2-hadoop2
Show newest version
/***********************************************************************************************************************
 * Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
 *
 * 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 eu.stratosphere.client;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.MissingOptionException;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.cli.UnrecognizedOptionException;
import org.apache.commons.io.FileUtils;

import eu.stratosphere.api.common.JobExecutionResult;
import eu.stratosphere.api.common.accumulators.AccumulatorHelper;
import eu.stratosphere.client.program.Client;
import eu.stratosphere.client.program.PackagedProgram;
import eu.stratosphere.client.program.ProgramInvocationException;
import eu.stratosphere.configuration.ConfigConstants;
import eu.stratosphere.configuration.Configuration;
import eu.stratosphere.configuration.GlobalConfiguration;
import eu.stratosphere.nephele.event.job.RecentJobEvent;
import eu.stratosphere.nephele.ipc.RPC;
import eu.stratosphere.nephele.jobgraph.JobID;
import eu.stratosphere.nephele.jobgraph.JobStatus;
import eu.stratosphere.nephele.net.NetUtils;
import eu.stratosphere.nephele.protocols.ExtendedManagementProtocol;
import eu.stratosphere.util.StringUtils;

/**
 * Implementation of a simple command line fronted for executing programs.
 */
public class CliFrontend {

	//actions
	private static final String ACTION_RUN = "run";
	private static final String ACTION_INFO = "info";
	private static final String ACTION_LIST = "list";
	private static final String ACTION_CANCEL = "cancel";
	
	// general options
	private static final Option HELP_OPTION = new Option("h", "help", false, "Show the help for the CLI Frontend.");
	private static final Option VERBOSE_OPTION = new Option("v", "verbose", false, "Print more detailed error messages.");
	
	// program (jar file) specific options
	private static final Option JAR_OPTION = new Option("j", "jarfile", true, "Stratosphere program JAR file.");
	private static final Option CLASS_OPTION = new Option("c", "class", true, "Class with the program entry point (\"main\" method or \"getPlan()\" method. Only needed if the JAR file does not specify the class in its manifest.");
	private static final Option PARALLELISM_OPTION = new Option("p", "parallelism", true, "The parallelism with which to run the program. Optional flag to override the default value specified in the configuration.");
	private static final Option ARGS_OPTION = new Option("a", "arguments", true, "Program arguments. Arguments can also be added without -a, simply as trailing parameters.");
	
	private static final Option ADDRESS_OPTION = new Option("m", "jobmanager", true, "Address of the JobManager (master) to which to connect. Use this flag to connect to a different JobManager than the one specified in the configuration.");
	
	// info specific options
	private static final Option DESCR_OPTION = new Option("d", "description", false, "Show description of expected program arguments");
	private static final Option PLAN_OPTION = new Option("e", "executionplan", false, "Show optimized execution plan of the program (JSON)");
	
	// list specific options
	private static final Option RUNNING_OPTION = new Option("r", "running", false, "Show running programs and their JobIDs");
	private static final Option SCHEDULED_OPTION = new Option("s", "scheduled", false, "Show scheduled prorgrams and their JobIDs");
	
	// canceling
	private static final Option ID_OPTION = new Option("i", "jobid", true, "JobID of program to cancel");
	
	static {
		initOptions();
	}
	
	// general options
	private static final Options GENRAL_OPTIONS = createGeneralOptions();
	
	// action options all include the general options
	private static final Options RUN_OPTIONS = getRunOptions(createGeneralOptions());
	private static final Options INFO_OPTIONS = getInfoOptions(createGeneralOptions());
	private static final Options LIST_OPTIONS = getListOptions(createGeneralOptions());
	private static final Options CANCEL_OPTIONS = getCancelOptions(createGeneralOptions());
	
	// config dir parameters
	private static final String ENV_CONFIG_DIRECTORY = "STRATOSPHERE_CONF_DIR";
	private static final String CONFIG_DIRECTORY_FALLBACK_1 = "../conf";
	private static final String CONFIG_DIRECTORY_FALLBACK_2 = "conf";
	
	public static final String JOBMANAGER_ADDRESS_FILE = ".yarn-jobmanager";
	

	private CommandLineParser parser;
	
	private boolean verbose;
	private boolean printHelp;
	
	private boolean globalConfigurationLoaded;

	/**
	 * Initializes the class
	 */
	public CliFrontend() {
		parser = new PosixParser();
	}
	
	// --------------------------------------------------------------------------------------------
	//  Setup of options
	// --------------------------------------------------------------------------------------------

	private static void initOptions() {
		HELP_OPTION.setRequired(false);
		VERBOSE_OPTION.setRequired(false);
		
		JAR_OPTION.setRequired(false);
		JAR_OPTION.setArgName("jarfile");
		
		CLASS_OPTION.setRequired(false);
		CLASS_OPTION.setArgName("classname");
		
		ADDRESS_OPTION.setRequired(false);
		ADDRESS_OPTION.setArgName("host:port");
		
		PARALLELISM_OPTION.setRequired(false);
		PARALLELISM_OPTION.setArgName("parallelism");
		
		ARGS_OPTION.setRequired(false);
		ARGS_OPTION.setArgName("programArgs");
		ARGS_OPTION.setArgs(Option.UNLIMITED_VALUES);
		
		PLAN_OPTION.setRequired(false);
		DESCR_OPTION.setRequired(false);
		
		RUNNING_OPTION.setRequired(false);
		SCHEDULED_OPTION.setRequired(false);
		
		ID_OPTION.setRequired(false);
		ID_OPTION.setArgName("jobID");
	}
	
	static Options createGeneralOptions() {
		Options options = new Options();
		options.addOption(HELP_OPTION);
		options.addOption(VERBOSE_OPTION);

		return options;
	}
	
	// gets the program options with the old flags for jar file and arguments
	static Options getProgramSpecificOptions(Options options) {
		options.addOption(JAR_OPTION);
		options.addOption(CLASS_OPTION);
		options.addOption(PARALLELISM_OPTION);
		options.addOption(ARGS_OPTION);
		return options;
	}
	
	// gets the program options without the old flags for jar file and arguments
	static Options getProgramSpecificOptionsWithoutDeprecatedOptions(Options options) {
		options.addOption(CLASS_OPTION);
		options.addOption(PARALLELISM_OPTION);
		return options;
	}
	
	/**
	 * Builds command line options for the run action.
	 * 
	 * @return Command line options for the run action.
	 */
	static Options getRunOptions(Options options) {
		Options o = getProgramSpecificOptions(options);
		return getJobManagerAddressOption(o);
	}
	
	static Options getRunOptionsWithoutDeprecatedOptions(Options options) {
		Options o = getProgramSpecificOptionsWithoutDeprecatedOptions(options);
		return getJobManagerAddressOption(o);
	}
	
	static Options getJobManagerAddressOption(Options options) {
		options.addOption(ADDRESS_OPTION);
		return options;
	}
	
	/**
	 * Builds command line options for the info action.
	 * 
	 * @return Command line options for the info action.
	 */
	static Options getInfoOptions(Options options) {
		options = getProgramSpecificOptions(options);
		options = getJobManagerAddressOption(options);
		options.addOption(DESCR_OPTION);
		options.addOption(PLAN_OPTION);
		return options;
	}
	
	static Options getInfoOptionsWithoutDeprecatedOptions(Options options) {
		options = getProgramSpecificOptionsWithoutDeprecatedOptions(options);
		options = getJobManagerAddressOption(options);
		options.addOption(DESCR_OPTION);
		options.addOption(PLAN_OPTION);
		return options;
	}
	
	/**
	 * Builds command line options for the list action.
	 * 
	 * @return Command line options for the list action.
	 */
	static Options getListOptions(Options options) {
		options.addOption(RUNNING_OPTION);
		options.addOption(SCHEDULED_OPTION);
		options = getJobManagerAddressOption(options);
		return options;
	}
	
	/**
	 * Builds command line options for the cancel action.
	 * 
	 * @return Command line options for the cancel action.
	 */
	static Options getCancelOptions(Options options) {
		options.addOption(ID_OPTION);
		options = getJobManagerAddressOption(options);
		return options;
	}
	
	// --------------------------------------------------------------------------------------------
	//  Execute Actions
	// --------------------------------------------------------------------------------------------
	
	/**
	 * Executions the run action.
	 * 
	 * @param args Command line arguments for the run action.
	 */
	protected int run(String[] args) {
		// Parse command line options
		CommandLine line;
		try {
			line = parser.parse(RUN_OPTIONS, args, false);
			evaluateGeneralOptions(line);
		}
		catch (MissingOptionException e) {
			System.out.println(e.getMessage());
			printHelpForRun();
			return 1;
		}
		catch (UnrecognizedOptionException e) {
			System.out.println(e.getMessage());
			printHelpForRun();
			return 2;
		}
		catch (Exception e) {
			return handleError(e);
		}
		
		// ------------ check for help first --------------
		
		if (printHelp) {
			printHelpForRun();
			return 0;
		}
		
		try {
			PackagedProgram program = buildProgram(line);
			if (program == null) {
				printHelpForRun();
				return 1;
			}
			
			Client client = getClient(line);
			if (client == null) {
				printHelpForRun();
				return 1;
			}
		
			int parallelism = -1;
			if (line.hasOption(PARALLELISM_OPTION.getOpt())) {
				String parString = line.getOptionValue(PARALLELISM_OPTION.getOpt());
				try {
					parallelism = Integer.parseInt(parString);
				} catch (NumberFormatException e) {
					System.out.println("The value " + parString + " is invalid for the degree of parallelism.");
					printHelpForRun();
					return 1;
				}
				
				if (parallelism <= 0) {
					System.out.println("Invalid value for the degree-of-parallelism. Parallelism must be greater than zero.");
					printHelpForRun();
					return 1;
				}
			}
		
			return executeProgram(program, client, parallelism);
		}
		catch (Throwable t) {
			return handleError(t);
		}
	}
	
	// --------------------------------------------------------------------------------------------
	
	protected int executeProgram(PackagedProgram program, Client client, int parallelism) {
		JobExecutionResult execResult;
		try {
			client.setPrintStatusDuringExecution(true);
			execResult = client.run(program, parallelism, true);
		}
		catch (ProgramInvocationException e) {
			return handleError(e);
		}
		finally {
			program.deleteExtractedLibraries();
		}
		
		// we come here after the job has finished
		if (execResult != null) {
			System.out.println("Job Runtime: " + execResult.getNetRuntime());
			Map accumulatorsResult = execResult.getAllAccumulatorResults();
			if (accumulatorsResult.size() > 0) {
				System.out.println("Accumulator Results: ");
				System.out.println(AccumulatorHelper.getResultsFormated(accumulatorsResult));
			}
		}
		return 0;
	}
	
	// --------------------------------------------------------------------------------------------
	
	/**
	 * Executes the info action.
	 * 
	 * @param args Command line arguments for the info action. 
	 */
	protected int info(String[] args) {
		// Parse command line options
		CommandLine line;
		try {
			line = parser.parse(INFO_OPTIONS, args, false);
			evaluateGeneralOptions(line);
		}
		catch (MissingOptionException e) {
			System.out.println(e.getMessage());
			printHelpForInfo();
			return 1;
		}
		catch (UnrecognizedOptionException e) {
			System.out.println(e.getMessage());
			printHelpForInfo();
			return 2;
		}
		catch (Exception e) {
			return handleError(e);
		}

		if (printHelp) {
			printHelpForInfo();
			return 0;
		}
		
		boolean description = line.hasOption(DESCR_OPTION.getOpt());
		boolean plan = line.hasOption(PLAN_OPTION.getOpt());
		
		if (!description && !plan) {
			System.out.println("ERROR: Specify the information to display.");
			printHelpForInfo();
			return 1;
		}

		// -------- build the packaged program -------------
		
		PackagedProgram program;
		try {
			program = buildProgram(line);
		} catch (Throwable t) {
			return handleError(t);
		}
		
		if (program == null) {
			printHelpForInfo();
			return 1;
		}
		
		int parallelism = -1;
		if (line.hasOption(PARALLELISM_OPTION.getOpt())) {
			String parString = line.getOptionValue(PARALLELISM_OPTION.getOpt());
			try {
				parallelism = Integer.parseInt(parString);
			} catch (NumberFormatException e) {
				System.out.println("The value " + parString + " is invalid for the degree of parallelism.");
				printHelpForRun();
				return 1;
			}
			
			if (parallelism <= 0) {
				System.out.println("Invalid value for the degree-of-parallelism. Parallelism must be greater than zero.");
				printHelpForRun();
				return 1;
			}
		}
		
		try {
			// check for description request
			if (description) {
				String descr = program.getDescription();
				
				if (descr != null) {
					System.out.println("-------------------- Program Description ---------------------");
					System.out.println(descr);
					System.out.println("--------------------------------------------------------------");
				} else {
					System.out.println("No description available for this program.");
				}
			}
			
			// check for json plan request
			if (plan) {
				Client client = getClient(line);
				String jsonPlan = client.getOptimizedPlanAsJson(program, parallelism);
				
				if (jsonPlan != null) {
					System.out.println("----------------------- Execution Plan -----------------------");
					System.out.println(jsonPlan);
					System.out.println("--------------------------------------------------------------");
				} else {
					System.out.println("JSON plan could not be compiled.");
				}
			}
			
			return 0;
		}
		catch (Throwable t) {
			return handleError(t);
		}
		finally {
			program.deleteExtractedLibraries();
		}
	}

	/**
	 * Executes the list action.
	 * 
	 * @param args Command line arguments for the list action.
	 */
	protected int list(String[] args) {
		// Parse command line options
		CommandLine line;
		try {
			line = parser.parse(LIST_OPTIONS, args, false);
		}
		catch (MissingOptionException e) {
			System.out.println(e.getMessage());
			printHelpForList();
			return 1;
		}
		catch (UnrecognizedOptionException e) {
			System.out.println(e.getMessage());
			printHelpForList();
			return 2;
		}
		catch (Exception e) {
			return handleError(e);
		}
		
		if (printHelp) {
			printHelpForList();
			return 0;
		}
		
		// get list options
		boolean running = line.hasOption(RUNNING_OPTION.getOpt());
		boolean scheduled = line.hasOption(SCHEDULED_OPTION.getOpt());
		
		if (!running && !scheduled) {
			System.out.println("Error: Specify the status of the jobs to list.");
			printHelpForList();
			return 1;
		}
		
		ExtendedManagementProtocol jmConn = null;
		try {
			jmConn = getJobManagerConnection(line);
			if (jmConn == null) {
				printHelpForList();
				return 1;
			}
			
			List recentJobs = jmConn.getRecentJobs();
			
			ArrayList runningJobs = null;
			ArrayList scheduledJobs = null;
			if (running) {
				runningJobs = new ArrayList();
			}
			if (scheduled) {
				scheduledJobs = new ArrayList();
			}
			
			for (RecentJobEvent rje : recentJobs) {
				
				if (running && rje.getJobStatus().equals(JobStatus.RUNNING)) {
					runningJobs.add(rje);
				}
				if (scheduled && rje.getJobStatus().equals(JobStatus.SCHEDULED)) {
					scheduledJobs.add(rje);
				}
			}
			
			SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
			Comparator njec = new Comparator(){
				
				@Override
				public int compare(RecentJobEvent o1, RecentJobEvent o2) {
					return (int)(o1.getTimestamp()-o2.getTimestamp());
				}
			};
			
			if (running) {
				if(runningJobs.size() == 0) {
					System.out.println("No running jobs.");
				} else {
					Collections.sort(runningJobs, njec);
					
					System.out.println("------------------------ Running Jobs ------------------------");
					for(RecentJobEvent je : runningJobs) {
						System.out.println(df.format(new Date(je.getTimestamp()))+" : "+je.getJobID().toString()+" : "+je.getJobName());
					}
					System.out.println("--------------------------------------------------------------");
				}
			}
			if (scheduled) {
				if(scheduledJobs.size() == 0) {
					System.out.println("No scheduled jobs.");
				} else {
					Collections.sort(scheduledJobs, njec);
					
					System.out.println("----------------------- Scheduled Jobs -----------------------");
					for(RecentJobEvent je : scheduledJobs) {
						System.out.println(df.format(new Date(je.getTimestamp()))+" : "+je.getJobID().toString()+" : "+je.getJobName());
					}
					System.out.println("--------------------------------------------------------------");
				}
			}
			return 0;
		}
		catch (Throwable t) {
			return handleError(t);
		}
		finally {
			if (jmConn != null) {
				try {
					RPC.stopProxy(jmConn);
				} catch (Throwable t) {
					System.out.println("Could not cleanly shut down connection from compiler to job manager");
				}
			}
			jmConn = null;
		}
		
	}
	
	/**
	 * Executes the cancel action.
	 * 
	 * @param args Command line arguments for the cancel action.
	 */
	protected int cancel(String[] args) {
		// Parse command line options
		CommandLine line;
		try {
			line = parser.parse(CANCEL_OPTIONS, args, false);
		}
		catch (MissingOptionException e) {
			System.out.println(e.getMessage());
			printHelpForCancel();
			return 1;
		}
		catch (UnrecognizedOptionException e) {
			System.out.println(e.getMessage());
			printHelpForCancel();
			return 2;
		}
		catch (Exception e) {
			return handleError(e);
		}
		
		if (printHelp) {
			printHelpForCancel();
			return 0;
		}
		
		JobID jobId;
		
		if (line.hasOption(ID_OPTION.getOpt())) {
			String jobIdString = line.getOptionValue(ID_OPTION.getOpt());
			try {
				jobId = new JobID(StringUtils.hexStringToByte(jobIdString));
			} catch (Exception e) {
				System.out.println("Error: The value for the Job ID is not a valid ID.");
				printHelpForCancel();
				return 1;
			}
		} else {
			System.out.println("Error: Specify a Job ID to cancel a job.");
			printHelpForCancel();
			return 1;
		}
		
		ExtendedManagementProtocol jmConn = null;
		try {
			jmConn = getJobManagerConnection(line);
			if (jmConn == null) {
				printHelpForCancel();
				return 1;
			}
			
			jmConn.cancelJob(jobId);
			return 0;
		}
		catch (Throwable t) {
			return handleError(t);
		}
		finally {
			if (jmConn != null) {
				try {
					RPC.stopProxy(jmConn);
				} catch (Throwable t) {
					System.out.println("Warning: Could not cleanly shut down connection to the JobManager.");
				}
			}
			jmConn = null;
		}
	}

	/**
	 * @param line
	 * 
	 * @return Either a PackagedProgram (upon success), or null;
	 */
	protected PackagedProgram buildProgram(CommandLine line) {
		String[] programArgs = line.hasOption(ARGS_OPTION.getOpt()) ?
				line.getOptionValues(ARGS_OPTION.getOpt()) :
				line.getArgs();
	
		// take the jar file from the option, or as the first trailing parameter (if available)
		String jarFilePath = null;
		if (line.hasOption(JAR_OPTION.getOpt())) {
			jarFilePath = line.getOptionValue(JAR_OPTION.getOpt());
		}
		else if (programArgs.length > 0) {
			jarFilePath = programArgs[0];
			programArgs = Arrays.copyOfRange(programArgs, 1, programArgs.length);
		}
		else {
			System.out.println("Error: Jar file is not set.");
			return null;
		}
		
		File jarFile = new File(jarFilePath);
		
		// Check if JAR file exists
		if (!jarFile.exists()) {
			System.out.println("Error: Jar file does not exist.");
			return null;
		}
		else if (!jarFile.isFile()) {
			System.out.println("Error: Jar file is not a file.");
			return null;
		}
		
		// Get assembler class
		String entryPointClass = line.hasOption(CLASS_OPTION.getOpt()) ?
				line.getOptionValue(CLASS_OPTION.getOpt()) :
				null;
				
		try {
			return entryPointClass == null ? 
					new PackagedProgram(jarFile, programArgs) :
					new PackagedProgram(jarFile, entryPointClass, programArgs);
		} catch (ProgramInvocationException e) {
			handleError(e);
			return null;
		}
	}
	
	protected InetSocketAddress getJobManagerAddress(CommandLine line) throws IOException {
		Configuration configuration = getGlobalConfiguration();
		
		// first, check if the address comes from the command line option
		if (line.hasOption(ADDRESS_OPTION.getOpt())) {
			try {
				String address = line.getOptionValue(ADDRESS_OPTION.getOpt());
				return RemoteExecutor.getInetFromHostport(address);
			}
			catch (Exception e) {
				System.out.println("Error: The JobManager address has an invalid format. " + e.getMessage());
				return null;
			}
		}
		else {
			// second, search for a .yarn-jobmanager file
			String loc = getConfigurationDirectory();
			File jmAddressFile = new File(loc + '/' + JOBMANAGER_ADDRESS_FILE);
			
			if (jmAddressFile.exists()) {
				try {
					String address = FileUtils.readFileToString(jmAddressFile).trim();
					System.out.println("Found a " + JOBMANAGER_ADDRESS_FILE + " file, using \""+address+"\" to connect to the JobManager");
					
					return RemoteExecutor.getInetFromHostport(address);
				}
				catch (Exception e) {
					System.out.println("Found a " + JOBMANAGER_ADDRESS_FILE + " file, but could not read the JobManager address from the file. " 
								+ e.getMessage());
					return null;
				}
			}
			else {
				// regular config file gives the address
				String jobManagerAddress = configuration.getString(ConfigConstants.JOB_MANAGER_IPC_ADDRESS_KEY, null);
				
				// verify that there is a jobmanager address and port in the configuration
				if (jobManagerAddress == null) {
					System.out.println("Error: Found no configuration in the config directory '" + 
							getConfigurationDirectory() + "' that specifies the JobManager address.");
					return null;
				}
				
				int jobManagerPort;
				try {
					jobManagerPort = configuration.getInteger(ConfigConstants.JOB_MANAGER_IPC_PORT_KEY, -1);
				} catch (NumberFormatException e) {
					System.out.println("Invalid value for the JobManager IPC port (" + ConfigConstants.JOB_MANAGER_IPC_PORT_KEY +
							") in the configuration.");
					return null;
				}
				
				if (jobManagerPort == -1) {
					System.out.println("Error: Found no configuration in the config directory '" + 
							getConfigurationDirectory() + "' that specifies the JobManager port.");
					return null;
				}
				
				return new InetSocketAddress(jobManagerAddress, jobManagerPort);
			}
		}
	}
	
	protected ExtendedManagementProtocol getJobManagerConnection(CommandLine line) throws IOException {
		InetSocketAddress jobManagerAddress = getJobManagerAddress(line);
		if (jobManagerAddress == null) {
			return null;
		}
		
		String address = jobManagerAddress.getAddress().getHostAddress();
		int port = jobManagerAddress.getPort();
		
		return RPC.getProxy(ExtendedManagementProtocol.class, 
				new InetSocketAddress(address, port), NetUtils.getSocketFactory());
	}
	
	
	protected String getConfigurationDirectory() {
		String location = null;
		if (System.getenv(ENV_CONFIG_DIRECTORY) != null) {
			location = System.getenv(ENV_CONFIG_DIRECTORY);
		} else if (new File(CONFIG_DIRECTORY_FALLBACK_1).exists()) {
			location = CONFIG_DIRECTORY_FALLBACK_1;
		} else if (new File(CONFIG_DIRECTORY_FALLBACK_2).exists()) {
			location = CONFIG_DIRECTORY_FALLBACK_2;
		} else {
			throw new RuntimeException("The configuration directory was not found. Please configure the '" + 
					ENV_CONFIG_DIRECTORY + "' environment variable properly.");
		}
		return location;
	}
	/**
	 * Reads configuration settings. The default path can be overridden
	 * by setting the ENV variable "STRATOSPHERE_CONF_DIR".
	 * 
	 * @return Stratosphere's global configuration
	 */
	protected Configuration getGlobalConfiguration() {
		if (!globalConfigurationLoaded) {
			String location = getConfigurationDirectory();
			GlobalConfiguration.loadConfiguration(location);
			globalConfigurationLoaded = true;
		}
		return GlobalConfiguration.getConfiguration();
	}
	
	protected Client getClient(CommandLine line) throws IOException {
		return new Client(getJobManagerAddress(line), getGlobalConfiguration());
	}

	/**
	 * Prints the help for the client.
	 * 
	 * @param options A map with options for actions. 
	 */
	private void printHelp() {
		System.out.println("./stratosphere  [GENERAL_OPTIONS] [ARGUMENTS]");
		
		HelpFormatter formatter = new HelpFormatter();
		formatter.setWidth(80);
		formatter.setLeftPadding(5);
		formatter.setSyntaxPrefix("  general options:");
		formatter.printHelp(" ", GENRAL_OPTIONS);
		
		printHelpForRun();
		printHelpForInfo();
		printHelpForList();
		printHelpForCancel();
	}
	
	private void printHelpForRun() {
		HelpFormatter formatter = new HelpFormatter();
		formatter.setLeftPadding(5);
		formatter.setWidth(80);
		
		System.out.println("\nAction \"run\" compiles and runs a program.");
		System.out.println("\n  Syntax: run [OPTIONS]  ");
		formatter.setSyntaxPrefix("  \"run\" action arguments:");
		formatter.printHelp(" ", getRunOptionsWithoutDeprecatedOptions(new Options()));
	}
	
	private void printHelpForInfo() {
		HelpFormatter formatter = new HelpFormatter();
		formatter.setLeftPadding(5);
		formatter.setWidth(80);
		
		System.out.println("\nAction \"info\" displays information about a program.");
		formatter.setSyntaxPrefix("  \"info\" action arguments:");
		formatter.printHelp(" ", getInfoOptionsWithoutDeprecatedOptions(new Options()));
	}
	
	private void printHelpForList() {
		HelpFormatter formatter = new HelpFormatter();
		formatter.setLeftPadding(5);
		formatter.setWidth(80);
		
		System.out.println("\nAction \"list\" lists running and finished programs.");
		formatter.setSyntaxPrefix("  \"list\" action arguments:");
		formatter.printHelp(" ", getListOptions(new Options()));
	}
	
	private void printHelpForCancel() {
		HelpFormatter formatter = new HelpFormatter();
		formatter.setLeftPadding(5);
		formatter.setWidth(80);
		
		System.out.println("\nAction \"cancel\" cancels a running program.");
		formatter.setSyntaxPrefix("  \"cancel\" action arguments:");
		formatter.printHelp(" ", getCancelOptions(new Options()));
	}
	
	
	/**
	 * Displays exceptions.
	 * 
	 * @param e the exception to display.
	 */
	private int handleError(Throwable t) {
		System.out.println("Error: " + t.getMessage());
		if (this.verbose) {
			t.printStackTrace();
		} else {
			System.out.println("For a more detailed error message use the vebose output option '-v'.");
		}
		return 1;
	}


	

	private void evaluateGeneralOptions(CommandLine line) {
		// check help flag
		this.printHelp = line.hasOption(HELP_OPTION.getOpt());
		
		// check verbosity flag
		this.verbose = line.hasOption(VERBOSE_OPTION.getOpt());
	}
	
	/**
	 * Parses the command line arguments and starts the requested action.
	 * 
	 * @param args command line arguments of the client.
	 * @return The return code of the program
	 */
	public int parseParameters(String[] args) {
		
		// check for action
		if (args.length < 1) {
			System.out.println("Please specify an action.");
			printHelp();
			return 1;
		}
		
		// get action
		String action = args[0];
		
		// remove action from parameters
		String[] params = Arrays.copyOfRange(args, 1, args.length);
		
		// do action
		if (action.equals(ACTION_RUN)) {
			return run(params);
		} else if (action.equals(ACTION_LIST)) {
			return list(params);
		} else if (action.equals(ACTION_INFO)) {
			return info(params);
		} else if (action.equals(ACTION_CANCEL)) {
			return cancel(params);
		} else if (action.equals("-h") || action.equals("--help")) {
			printHelp();
			return 0;
		} else {
			System.out.println("Invalid action!");
			printHelp();
			return 1;
		}
	}

	

	/**
	 * Submits the job based on the arguments
	 */
	public static void main(String[] args) throws ParseException {
		CliFrontend cli = new CliFrontend();
		int retCode = cli.parseParameters(args);
		System.exit(retCode);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy