/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive_grid_cloud_portal.cli; import static org.ow2.proactive_grid_cloud_portal.cli.CLIException.REASON_INVALID_ARGUMENTS; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.CA_CERTS; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.CA_CERTS_PASSWORD; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.COMMON_HELP; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.CREDENTIALS; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.DEBUG; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.INFRASTRUCTURE; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.INSECURE; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.LOGIN; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.OUTPUT; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.PASSWORD; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.POLICY; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.RM_HELP; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.SCHEDULER_HELP; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.SESSION_ID; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.SESSION_ID_FILE; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.SILENT; import static org.ow2.proactive_grid_cloud_portal.cli.CommandSet.URL; import static org.ow2.proactive_grid_cloud_portal.cli.RestConstants.DEFAULT_CREDENTIALS_PATH; import static org.ow2.proactive_grid_cloud_portal.cli.RestConstants.DFLT_SESSION_DIR; import java.io.File; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.ow2.proactive.utils.ClasspathUtils; import org.ow2.proactive_grid_cloud_portal.cli.cmd.Command; import org.ow2.proactive_grid_cloud_portal.cli.cmd.ImodeCommand; import org.ow2.proactive_grid_cloud_portal.cli.cmd.LoginWithCredentialsCommand; import org.ow2.proactive_grid_cloud_portal.cli.utils.HierarchicalMap; /** * {@link CommandFactory} builds an ordered {@link Command} list for a given * user argument set. */ public abstract class CommandFactory { public static enum Type { SCHEDULER, RM, ALL; } private static final Map<String, CommandSet.Entry> commonCmdMap; static { commonCmdMap = new HashMap<>(); for (CommandSet.Entry entry : CommandSet.COMMON_COMMANDS) { commonCmdMap.put(opt(entry), entry); } } protected final Map<String, CommandSet.Entry> cmdMap = new HierarchicalMap<>(CommandFactory.supportedCommandMap()); public static CommandFactory getCommandFactory(Type type) { switch (type) { case SCHEDULER: return new SchedulerCommandFactory(); case RM: return new RmCommandFactory(); case ALL: return new CommonCommandFactory(); default: throw new CLIException(REASON_INVALID_ARGUMENTS, String.format("Unknown AbstractCommandFactory type['%s']", type)); } } static void put(CommandSet.Entry entry, Map<String, CommandSet.Entry> map) { map.put(opt(entry), entry); } static Map<String, CommandSet.Entry> supportedCommandMap() { return commonCmdMap; } static String opt(CommandSet.Entry entry) { return entry.opt(); } public Options supportedOptions() { return createOptions(cmdMap.values()); } public List<Command> getCommandList(CommandLine cli, ApplicationContext currentContext) { throw new UnsupportedOperationException(); } public void addCommandEntry(CommandSet.Entry entry) { cmdMap.put(opt(entry), entry); } public Command commandForOption(Option option) { return getCommandForOption(option, cmdMap); } public CommandSet.Entry[] supportedCommandEntries() { Collection<CommandSet.Entry> entries = cmdMap.values(); return entries.toArray(new CommandSet.Entry[entries.size()]); } /** * Returns an ordered {@link Command} list for specified user arguments. * * @param cli the command-line arguments * @return an ordered {@link Command} list. */ protected List<Command> getCommandList(CommandLine cli, Map<String, Command> map, ApplicationContext currentContext) { LinkedList<Command> list = new LinkedList<>(); if (map.containsKey(opt(COMMON_HELP))) { list.add(map.remove(opt(COMMON_HELP))); return list; } if (map.containsKey(opt(RM_HELP))) { list.add(map.remove(opt(RM_HELP))); return list; } if (map.containsKey(opt(SCHEDULER_HELP))) { list.add(map.remove(opt(SCHEDULER_HELP))); return list; } if (map.containsKey(opt(SILENT))) { list.add(map.remove(opt(SILENT))); } if (map.containsKey(opt(DEBUG))) { list.add(map.remove(opt(DEBUG))); } if (map.containsKey(opt(URL))) { list.addFirst(map.remove(opt(URL))); } if (map.containsKey(opt(INSECURE))) { list.add(map.remove(opt(INSECURE))); } else if (map.containsKey(opt(CA_CERTS))) { list.add(map.remove(opt(CA_CERTS))); if (map.containsKey(opt(CA_CERTS_PASSWORD))) { list.add(map.remove(opt(CA_CERTS_PASSWORD))); } } if (map.containsKey(opt(SESSION_ID))) { list.add(map.remove(opt(SESSION_ID))); } else if (map.containsKey(opt(SESSION_ID_FILE))) { list.add(map.remove(opt(SESSION_ID_FILE))); } if (map.containsKey(opt(PASSWORD))) { list.add(map.remove(opt(PASSWORD))); } if (map.containsKey(opt(LOGIN))) { list.add(map.remove(opt(LOGIN))); } else if (map.containsKey(opt(CREDENTIALS))) { list.add(map.remove(opt(CREDENTIALS))); } else { // auto login String resourceType = currentContext.getResourceType(); String filename = resourceType + ".cc"; File credFile = new File(DFLT_SESSION_DIR, filename); if (credFile.exists()) { list.add(new LoginWithCredentialsCommand(credFile.getAbsolutePath(), true)); } else { String schedulerHome = ClasspathUtils.findSchedulerHome(); File defaultCredentials = new File(schedulerHome, DEFAULT_CREDENTIALS_PATH); if (defaultCredentials.exists()) { list.add(new LoginWithCredentialsCommand(defaultCredentials.getAbsolutePath(), true)); } } } if (map.containsKey(opt(INFRASTRUCTURE))) { list.add(map.remove(opt(INFRASTRUCTURE))); } if (map.containsKey(opt(POLICY))) { list.add(map.remove(opt(POLICY))); } if (map.isEmpty()) { list.add(new ImodeCommand()); } else { Command output = map.remove(opt(OUTPUT)); list.addAll(map.values()); if (output != null) { list.add(output); } } return list; } protected Map<String, Command> commandMapInstance(CommandLine cli, final Map<String, CommandSet.Entry> supportedCommandEntryMap) { Map<String, Command> cliCommands = new HashMap<>(); for (Option o : cli.getOptions()) { cliCommands.put(o.getOpt(), getCommandForOption(o, supportedCommandEntryMap)); } return cliCommands; } protected Command getCommandForOption(Option opt, final Map<String, CommandSet.Entry> commandMap) { return commandMap.get(opt.getOpt()).commandObject(opt); } protected Options createOptions(Collection<CommandSet.Entry> entries) { Options options = new Options(); for (CommandSet.Entry entry : entries) { Option option = new Option(entry.opt(), entry.longOpt(), entry.hasArgs(), entry.description()); option.setArgName(entry.argNames()); option.setArgs(entry.numOfArgs()); option.setOptionalArg(entry.hasOptionalArg()); options.addOption(option); } return options; } }