Java tutorial
/* * Copyright 1999-2010 University of Chicago * * 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.globus.workspace.remoting.admin.client; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.globus.workspace.remoting.admin.VMTranslation; import org.nimbustools.api.services.admin.RemoteAdminToolsManagement; import java.io.*; import java.rmi.RemoteException; import java.util.*; /** * This class runs the nimbus-admin tool and connects to the main service over rmi binding * RMI setup and config is handled by parent class RMIConfig */ public class RemoteAdminToolsMain extends RMIConfig { private static final String PROP_RMI_BINDING_ADMINTOOLS_DIR = "rmi.binding.admintools"; private static final String FIELD_ID = "id"; private static final String FIELD_NODE = "node"; private static final String FIELD_GROUP_ID = "group_id"; private static final String FIELD_GROUP_NAME = "group_name"; private static final String FIELD_CREATOR = "creator"; private static final String FIELD_STATE = "state"; private static final String FIELD_START = "start time"; private static final String FIELD_END = "end time"; private static final String FIELD_MEMORY = "memory"; private static final String FIELD_CPU_COUNT = "cpu count"; private static final String FIELD_URI = "uri"; final static String[] ADMIN_FIELDS = new String[] { FIELD_ID, FIELD_NODE, FIELD_GROUP_ID, FIELD_GROUP_NAME, FIELD_CREATOR, FIELD_STATE, FIELD_START, FIELD_END, FIELD_MEMORY, FIELD_CPU_COUNT, FIELD_URI }; final static String[] NODE_LIST_FIELDS = new String[] { FIELD_NODE, FIELD_ID }; private ToolAction action; private RemoteAdminToolsManagement remoteAdminToolsManagement; private String user; private String userDN; private String groupId; private String groupName; private String hostname; private String seconds; private String state; private List<String> vmIDs; private List<String> userList; private List<String> DNList; private List<String> gidList; private List<String> gnameList; private List<String> hostList; private boolean allVMs = false; private int numOpts = 0; private boolean force = false; public static void main(String args[]) { Throwable anyError = null; ParameterProblem paramError = null; ExecutionProblem execError = null; int ret = EXIT_OK; try { final RemoteAdminToolsMain ratm = new RemoteAdminToolsMain(); ratm.setupDebug(args); ratm.run(args); } catch (ParameterProblem e) { paramError = e; anyError = e; ret = EXIT_PARAMETER_PROBLEM; } catch (ExecutionProblem e) { execError = e; anyError = e; ret = EXIT_EXECUTION_PROBLEM; } catch (Throwable t) { anyError = t; ret = EXIT_UNKNOWN_PROBLEM; } if (anyError == null) { System.exit(ret); } else { logger.debug("Got error", anyError); } if (paramError != null) { System.err.println("Parameter Problem:\n\n" + paramError.getMessage()); System.err.println("See --help"); } else if (execError != null) { System.err.println(execError.getMessage()); } else { System.err.println("An unexpected error was encountered. Please report this!"); System.err.println(anyError.getMessage()); System.err.println(); System.err.println("Stack trace:"); anyError.printStackTrace(System.err); } System.exit(ret); } public void run(String[] args) throws ExecutionProblem, ParameterProblem { this.loadArgs(args); if (this.action == ToolAction.Help) { InputStream is = RemoteAdminToolsMain.class.getResourceAsStream("adminHelp.txt"); System.out.println(super.getHelpText(is)); return; } super.loadConfig(PROP_RMI_BINDING_ADMINTOOLS_DIR); this.remoteAdminToolsManagement = (RemoteAdminToolsManagement) super.setupRemoting(); switch (this.action) { case CleanupVMs: cleanupVMs(); break; case ListVMs: listVMs(); break; case ListNodes: listNodes(); break; case ShutdownVMs: shutdownVM(); break; } } private void loadArgs(String[] args) throws ParameterProblem { logger.debug("Parsing command line arguments"); final CommandLineParser parser = new PosixParser(); final Opts opts = new Opts(); final CommandLine line; try { line = parser.parse(opts.getOptions(), args); } catch (ParseException e) { throw new ParameterProblem(e.getMessage(), e); } // figure action first ToolAction tAction = null; for (ToolAction t : ToolAction.values()) { if (line.hasOption(t.option())) { if (tAction == null) { tAction = t; } else { throw new ParameterProblem("You may only specify a single action"); } } } if (tAction == null) { throw new ParameterProblem("You must specify an action"); } this.action = tAction; logger.debug("Action: " + tAction); // short circuit for --help arg if (tAction == ToolAction.Help) { return; } //numOpts just makes sure you don't have non-compatible options running at the same time if (this.action == ToolAction.ListVMs) { if (line.hasOption(Opts.USER)) { final String user = line.getOptionValue(Opts.USER); if (user == null || user.trim().length() == 0) { throw new ParameterProblem("User value is empty"); } this.user = user; numOpts++; } if (line.hasOption(Opts.DN)) { final String dn = line.getOptionValue(Opts.DN); if (dn == null || dn.trim().length() == 0) { throw new ParameterProblem("User DN value is empty"); } this.userDN = dn; numOpts++; } if (line.hasOption(Opts.GROUP_ID)) { final String gid = line.getOptionValue(Opts.GROUP_ID); if (gid == null || gid.trim().length() == 0) { throw new ParameterProblem("Group id value is empty"); } this.groupId = gid; numOpts++; } if (line.hasOption(Opts.GROUP_NAME)) { final String gname = line.getOptionValue(Opts.GROUP_NAME); if (gname == null || gname.trim().length() == 0) { throw new ParameterProblem("Group name value is empty"); } this.groupName = gname; numOpts++; } if (line.hasOption(Opts.HOST)) { final String hostname = line.getOptionValue(Opts.HOST); if (hostname == null || hostname.trim().length() == 0) { throw new ParameterProblem("Host value is empty"); } this.hostname = hostname; numOpts++; } if (line.hasOption(Opts.STATE)) { final String state = line.getOptionValue(Opts.STATE); if (state == null || state.trim().length() == 0) { throw new ParameterProblem("State value is empty"); } this.state = state; numOpts++; } } else if (this.action == ToolAction.ShutdownVMs || this.action == ToolAction.CleanupVMs) { if (line.hasOption(Opts.ALL_VMS)) { allVMs = true; numOpts++; } if (line.hasOption(Opts.ID)) { final String id = line.getOptionValue(Opts.ID); if (id == null || id.trim().length() == 0) { throw new ParameterProblem("VM ID value is empty"); } this.vmIDs = parseValues(id); numOpts++; } if (line.hasOption(Opts.USER)) { final String user = line.getOptionValue(Opts.USER); if (user == null || user.trim().length() == 0) { throw new ParameterProblem("User value is empty"); } this.userList = parseValues(user); numOpts++; } if (line.hasOption(Opts.DN)) { final String dn = line.getOptionValue(Opts.DN); if (dn == null || dn.trim().length() == 0) { throw new ParameterProblem("DN value is empty"); } this.DNList = parseValues(dn); numOpts++; } if (line.hasOption(Opts.GROUP_ID)) { final String gid = line.getOptionValue(Opts.GROUP_ID); if (gid == null || gid.trim().length() == 0) { throw new ParameterProblem("Group id value is empty"); } this.gidList = parseValues(gid); numOpts++; } if (line.hasOption(Opts.GROUP_NAME)) { final String gname = line.getOptionValue(Opts.GROUP_NAME); if (gname == null || gname.trim().length() == 0) { throw new ParameterProblem("Group name value is empty"); } this.gnameList = parseValues(gname); numOpts++; } if (line.hasOption(Opts.HOST)) { final String hostname = line.getOptionValue(Opts.HOST); if (hostname == null || hostname.trim().length() == 0) { throw new ParameterProblem("Hostname value is empty"); } this.hostList = parseValues(hostname); numOpts++; } if (line.hasOption(Opts.SECONDS)) { final String seconds = line.getOptionValue(Opts.SECONDS); if (seconds == null || seconds.trim().length() == 0) { throw new ParameterProblem("Seconds value is empty"); } this.seconds = seconds; } } //finally everything else if (!line.hasOption(Opts.CONFIG)) { throw new ParameterProblem(Opts.CONFIG_LONG + " option is required"); } String config = line.getOptionValue(Opts.CONFIG); if (config == null || config.trim().length() == 0) { throw new ParameterProblem("Config file path is invalid"); } super.configPath = config.trim(); final boolean batchMode = line.hasOption(Opts.BATCH); final boolean json = line.hasOption(Opts.JSON); force = line.hasOption(Opts.FORCE); final Reporter.OutputMode mode; if (batchMode && json) { throw new ParameterProblem("You cannot specify both " + Opts.BATCH_LONG + " and " + Opts.JSON_LONG); } else if (batchMode) { mode = Reporter.OutputMode.Batch; } else if (json) { mode = Reporter.OutputMode.Json; } else { mode = Reporter.OutputMode.Friendly; } final String[] fields; if (line.hasOption(Opts.REPORT)) { fields = parseFields(line.getOptionValue(Opts.REPORT), tAction); } else { fields = tAction.fields(); } String delimiter = null; if (line.hasOption(Opts.DELIMITER)) { delimiter = line.getOptionValue(Opts.DELIMITER); } if (fields != null) this.reporter = new Reporter(mode, fields, delimiter); if (line.hasOption(Opts.OUTPUT)) { final String filename = line.getOptionValue(Opts.OUTPUT); final File f = new File(filename); try { this.outStream = new FileOutputStream(f); } catch (FileNotFoundException e) { throw new ParameterProblem( "Specified output file could not be opened for writing: " + f.getAbsolutePath(), e); } } else { this.outStream = System.out; } final List leftovers = line.getArgList(); if (leftovers != null && !leftovers.isEmpty()) { throw new ParameterProblem("There are unrecognized arguments, check -h to make " + "sure you are doing the intended thing: " + leftovers.toString()); } } private void listVMs() throws ExecutionProblem { try { VMTranslation[] vms; if (numOpts > 1) { System.err.println("You may select only one of --user, --dn, --gid, --gname, or --host"); return; } if (this.user != null) { final String vmsJson = this.remoteAdminToolsManagement.getVMsByUser(user); if (vmsJson == null) { System.err.println("No vms with user " + user + " found"); return; } vms = gson.fromJson(vmsJson, VMTranslation[].class); } else if (this.userDN != null) { final String vmsJson = this.remoteAdminToolsManagement.getVMsByDN(userDN); if (vmsJson == null) { System.err.println("No vms with DN " + userDN + " found"); return; } vms = gson.fromJson(vmsJson, VMTranslation[].class); } else if (this.groupId != null) { final String vmsJson = this.remoteAdminToolsManagement.getAllVMsByGroupId(groupId); if (vmsJson == null) { System.err.println("No vms with group id " + groupId + " found"); return; } vms = gson.fromJson(vmsJson, VMTranslation[].class); } else if (this.groupName != null) { final String vmsJson = this.remoteAdminToolsManagement.getAllVMsByGroupName(groupName); if (vmsJson == null) { System.err.println("No vms with group name " + groupName + " found"); return; } vms = gson.fromJson(vmsJson, VMTranslation[].class); } else if (this.hostname != null) { final String vmsJson = this.remoteAdminToolsManagement.getAllVMsByHost(hostname); if (vmsJson == null) { System.err.println("No vms with host " + hostname + " found"); return; } vms = gson.fromJson(vmsJson, VMTranslation[].class); } else if (this.state != null) { final String vmsJson = this.remoteAdminToolsManagement.getVMsByState(state); if (vmsJson == null) { System.err.println("No vms with state " + state + " found"); return; } vms = gson.fromJson(vmsJson, VMTranslation[].class); } else { final String vmsJson = this.remoteAdminToolsManagement.getAllRunningVMs(); vms = gson.fromJson(vmsJson, VMTranslation[].class); } if (vms == null) { System.err.println("No Running vms found"); return; } reporter.report(vmsToMaps(vms), this.outStream); } catch (RemoteException e) { super.handleRemoteException(e); } catch (IOException e) { throw new ExecutionProblem("Problem writing output: " + e.getMessage(), e); } } private void listNodes() throws ExecutionProblem { try { Hashtable ht = this.remoteAdminToolsManagement.showVMsForAllHosts(); if (ht == null) System.err.println("No nodes with running VMs found"); else reporter.report(nodesToMaps(ht), this.outStream); } catch (RemoteException e) { System.err.println(e.getMessage()); } catch (IOException e) { throw new ExecutionProblem("Problem writing output: " + e.getMessage(), e); } } private void shutdownVM() { try { String result = ""; String feedback; if (numOpts > 1) { result = "You must select only one of --all, --id, --user, --dn, --gid, --gname, or --host"; System.err.println(result); return; } if (allVMs) { result = this.remoteAdminToolsManagement.shutdown(RemoteAdminToolsManagement.SHUTDOWN_ALL, null, seconds, force); } else if (vmIDs != null) { for (int i = 0; i < vmIDs.size(); i++) { feedback = this.remoteAdminToolsManagement.shutdown(RemoteAdminToolsManagement.SHUTDOWN_ID, vmIDs.get(i), seconds, force); if (feedback != null) result += feedback + "\n"; } } else if (userList != null) { for (int i = 0; i < userList.size(); i++) { feedback = this.remoteAdminToolsManagement.shutdown(RemoteAdminToolsManagement.SHUTDOWN_UNAME, userList.get(i), seconds, force); if (feedback != null) result += feedback + "\n"; } } else if (DNList != null) { for (int i = 0; i < DNList.size(); i++) { feedback = this.remoteAdminToolsManagement.shutdown(RemoteAdminToolsManagement.SHUTDOWN_DN, DNList.get(i), seconds, force); if (feedback != null) result += feedback + "\n"; } } else if (gidList != null) { for (int i = 0; i < gidList.size(); i++) { feedback = this.remoteAdminToolsManagement.shutdown(RemoteAdminToolsManagement.SHUTDOWN_GID, gidList.get(i), seconds, force); if (feedback != null) result += feedback + "\n"; } } else if (gnameList != null) { for (int i = 0; i < gnameList.size(); i++) { feedback = this.remoteAdminToolsManagement.shutdown(RemoteAdminToolsManagement.SHUTDOWN_GNAME, gnameList.get(i), seconds, force); if (feedback != null) result += feedback + "\n"; } } else if (hostList != null) { for (int i = 0; i < hostList.size(); i++) { feedback = this.remoteAdminToolsManagement.shutdown(RemoteAdminToolsManagement.SHUTDOWN_HOST, hostList.get(i), seconds, force); if (feedback != null) result += feedback + "\n"; } } else { result = "Shutdown requires either --all, --id, --user, --dn, --gid, --gname, or --host option"; } if (result != null && !result.isEmpty()) System.err.println(result); } catch (RemoteException e) { System.err.println(e.getMessage()); } } private void cleanupVMs() { try { String result = ""; String feedback; if (numOpts > 1) { result = "You must select only one of --all, --id, --user, --dn, --gid, --gname, or --host"; System.err.println(result); return; } if (allVMs) { result = this.remoteAdminToolsManagement.cleanup(RemoteAdminToolsManagement.CLEANUP_ALL, null); } else if (vmIDs != null) { for (int i = 0; i < vmIDs.size(); i++) { feedback = this.remoteAdminToolsManagement.cleanup(RemoteAdminToolsManagement.CLEANUP_ID, vmIDs.get(i)); if (feedback != null) result += feedback + "\n"; } } else if (userList != null) { for (int i = 0; i < userList.size(); i++) { feedback = this.remoteAdminToolsManagement.cleanup(RemoteAdminToolsManagement.CLEANUP_UNAME, userList.get(i)); if (feedback != null) result += feedback + "\n"; } } else if (DNList != null) { for (int i = 0; i < DNList.size(); i++) { feedback = this.remoteAdminToolsManagement.cleanup(RemoteAdminToolsManagement.CLEANUP_DN, DNList.get(i)); if (feedback != null) result += feedback + "\n"; } } else if (gidList != null) { for (int i = 0; i < gidList.size(); i++) { feedback = this.remoteAdminToolsManagement.cleanup(RemoteAdminToolsManagement.CLEANUP_GID, gidList.get(i)); if (feedback != null) result += feedback + "\n"; } } else if (gnameList != null) { for (int i = 0; i < gnameList.size(); i++) { feedback = this.remoteAdminToolsManagement.cleanup(RemoteAdminToolsManagement.CLEANUP_GNAME, gnameList.get(i)); if (feedback != null) result += feedback + "\n"; } } else if (hostList != null) { for (int i = 0; i < hostList.size(); i++) { feedback = this.remoteAdminToolsManagement.cleanup(RemoteAdminToolsManagement.CLEANUP_HOST, hostList.get(i)); if (feedback != null) result += feedback + "\n"; } } else { result = "Cleanup requires either --all, --id, --user, --dn, --gid, --gname, or --host option"; } if (result != null && !result.isEmpty()) System.err.println(result); } catch (RemoteException e) { System.err.println(e.getMessage()); } } private static List<Map<String, String>> vmsToMaps(VMTranslation[] vmts) { List<Map<String, String>> maps = new ArrayList<Map<String, String>>(vmts.length); for (VMTranslation vmt : vmts) { maps.add(vmToMap(vmt)); } return maps; } private static Map<String, String> vmToMap(VMTranslation vmt) { final HashMap<String, String> map = new HashMap(11); map.put(FIELD_ID, vmt.getId()); map.put(FIELD_NODE, vmt.getNode()); map.put(FIELD_GROUP_ID, vmt.getGroupId()); map.put(FIELD_GROUP_NAME, vmt.getGroupName()); map.put(FIELD_CREATOR, vmt.getCallerIdentity()); map.put(FIELD_STATE, vmt.getState()); map.put(FIELD_START, vmt.getStartTime()); map.put(FIELD_END, vmt.getEndTime()); map.put(FIELD_MEMORY, vmt.getMemory()); map.put(FIELD_CPU_COUNT, vmt.getCpuCount()); map.put(FIELD_URI, vmt.getUri()); return map; } private static List<Map<String, String>> nodesToMaps(Hashtable<String, String[]> ht) { List<Map<String, String>> maps = new ArrayList<Map<String, String>>(ht.size()); Enumeration<String> hosts = ht.keys(); while (hosts.hasMoreElements()) { String host = hosts.nextElement(); String[] ids = ht.get(host); String idList = ""; for (int i = 0; i < ids.length; i++) { if (i + 1 != ids.length) idList += ids[i] + ", "; else idList += ids[i]; } final HashMap<String, String> map = new HashMap(2); map.put(FIELD_NODE, host); map.put(FIELD_ID, idList); maps.add(map); } return maps; } private static List<String> parseValues(String valueString) throws ParameterProblem { if (valueString == null) { throw new ParameterProblem("list is invalid"); } final String[] valueArray = valueString.trim().split("\\s*,\\s*"); if (valueArray.length == 0) { throw new ParameterProblem("list is empty"); } final List<String> values = new ArrayList<String>(valueArray.length); for (final String value : valueArray) { values.add(value); } return values; } } enum ToolAction implements AdminEnum { CleanupVMs(Opts.CLEANUP_VMS, null), ListVMs(Opts.LIST_VMS, RemoteAdminToolsMain.ADMIN_FIELDS), ListNodes( Opts.NODE_LIST, RemoteAdminToolsMain.NODE_LIST_FIELDS), ShutdownVMs(Opts.SHUTDOWN_VMS, null), Help(Opts.HELP, null); private final String option; private final String[] fields; ToolAction(String option, String[] fields) { this.option = option; this.fields = fields; } public String option() { return option; } public String[] fields() { return fields; } }