/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.falcon.cli; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionGroup; import org.apache.commons.cli.Options; import org.apache.falcon.client.FalconCLIConstants; import org.apache.falcon.ValidationUtil; import org.apache.falcon.LifeCycle; import org.apache.falcon.ResponseHelper; import org.apache.falcon.client.FalconCLIException; import org.apache.falcon.client.FalconClient; import org.apache.falcon.resource.InstanceDependencyResult; import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.apache.falcon.client.FalconCLIConstants.RUNNING_OPT; import static org.apache.falcon.client.FalconCLIConstants.RUNNING_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.LIST_OPT; import static org.apache.falcon.client.FalconCLIConstants.LIST_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.STATUS_OPT; import static org.apache.falcon.client.FalconCLIConstants.STATUS_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.SUMMARY_OPT; import static org.apache.falcon.client.FalconCLIConstants.SUMMARY_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.KILL_OPT; import static org.apache.falcon.client.FalconCLIConstants.KILL_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.SUSPEND_OPT; import static org.apache.falcon.client.FalconCLIConstants.SUSPEND_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.RESUME_OPT; import static org.apache.falcon.client.FalconCLIConstants.RESUME_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.RERUN_OPT; import static org.apache.falcon.client.FalconCLIConstants.LOG_OPT; import static org.apache.falcon.client.FalconCLIConstants.LOG_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.PARARMS_OPT; import static org.apache.falcon.client.FalconCLIConstants.PARARMS_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.LISTING_OPT; import static org.apache.falcon.client.FalconCLIConstants.LISTING_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.DEPENDENCY_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.DEPENDENCY_OPT; import static org.apache.falcon.client.FalconCLIConstants.TRIAGE_OPT; import static org.apache.falcon.client.FalconCLIConstants.TRIAGE_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.SEARCH_OPT; import static org.apache.falcon.client.FalconCLIConstants.URL_OPTION; import static org.apache.falcon.client.FalconCLIConstants.START_OPT; import static org.apache.falcon.client.FalconCLIConstants.START_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.END_OPT; import static org.apache.falcon.client.FalconCLIConstants.END_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.RUNID_OPT; import static org.apache.falcon.client.FalconCLIConstants.CLUSTERS_OPT; import static org.apache.falcon.client.FalconCLIConstants.CLUSTERS_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.SOURCECLUSTER_OPT; import static org.apache.falcon.client.FalconCLIConstants.SOURCECLUSTER_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.FILE_PATH_OPT; import static org.apache.falcon.client.FalconCLIConstants.FILE_PATH_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.TYPE_OPT; import static org.apache.falcon.client.FalconCLIConstants.TYPE_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.ENTITY_NAME_OPT; import static org.apache.falcon.client.FalconCLIConstants.ENTITY_NAME_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.COLO_OPT; import static org.apache.falcon.client.FalconCLIConstants.COLO_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.RERUN_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.URL_OPTION_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.RUNID_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.LIFECYCLE_OPT; import static org.apache.falcon.client.FalconCLIConstants.LIFECYCLE_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.FILTER_BY_OPT; import static org.apache.falcon.client.FalconCLIConstants.FILTER_BY_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.ORDER_BY_OPT; import static org.apache.falcon.client.FalconCLIConstants.ORDER_BY_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.SORT_ORDER_OPT; import static org.apache.falcon.client.FalconCLIConstants.SORT_ORDER_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.OFFSET_OPT; import static org.apache.falcon.client.FalconCLIConstants.OFFSET_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.NUM_RESULTS_OPT; import static org.apache.falcon.client.FalconCLIConstants.NUM_RESULTS_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.FORCE_RERUN_FLAG; import static org.apache.falcon.client.FalconCLIConstants.FORCE_RERUN_FLAG_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.DO_AS_OPT; import static org.apache.falcon.client.FalconCLIConstants.DO_AS_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.DEBUG_OPTION; import static org.apache.falcon.client.FalconCLIConstants.DEBUG_OPTION_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.INSTANCE_TIME_OPT; import static org.apache.falcon.client.FalconCLIConstants.INSTANCE_TIME_OPT_DESCRIPTION; import static org.apache.falcon.client.FalconCLIConstants.ALL_ATTEMPTS; import static org.apache.falcon.client.FalconCLIConstants.ALL_ATTEMPTS_DESCRIPTION; import static org.apache.falcon.ValidationUtil.getLifeCycle; import static org.apache.falcon.ValidationUtil.validateSortOrder; import static org.apache.falcon.ValidationUtil.validateNotEmpty; /** * Instance extension to Falcon Command Line Interface - wraps the RESTful API for instances. */ public class FalconInstanceCLI extends FalconCLI { public FalconInstanceCLI() throws Exception { super(); } public Options createInstanceOptions() { Options instanceOptions = new Options(); Option running = new Option(RUNNING_OPT, false, RUNNING_OPT_DESCRIPTION); Option list = new Option(LIST_OPT, false, LIST_OPT_DESCRIPTION); Option status = new Option(STATUS_OPT, false, STATUS_OPT_DESCRIPTION); Option summary = new Option(SUMMARY_OPT, false, SUMMARY_OPT_DESCRIPTION); Option kill = new Option(KILL_OPT, false, KILL_OPT_DESCRIPTION); Option suspend = new Option(SUSPEND_OPT, false, SUSPEND_OPT_DESCRIPTION); Option resume = new Option(RESUME_OPT, false, RESUME_OPT_DESCRIPTION); Option rerun = new Option(RERUN_OPT, false, RERUN_OPT_DESCRIPTION); Option logs = new Option(LOG_OPT, false, LOG_OPT_DESCRIPTION); Option params = new Option(PARARMS_OPT, false, PARARMS_OPT_DESCRIPTION); Option listing = new Option(LISTING_OPT, false, LISTING_OPT_DESCRIPTION); Option dependency = new Option(DEPENDENCY_OPT, false, DEPENDENCY_OPT_DESCRIPTION); Option triage = new Option(TRIAGE_OPT, false, TRIAGE_OPT_DESCRIPTION); Option search = new Option(SEARCH_OPT, false, "Search instances with filtering criteria on the entity, instance time and status."); OptionGroup group = new OptionGroup(); group.addOption(running); group.addOption(list); group.addOption(status); group.addOption(summary); group.addOption(kill); group.addOption(resume); group.addOption(suspend); group.addOption(resume); group.addOption(rerun); group.addOption(logs); group.addOption(params); group.addOption(listing); group.addOption(dependency); group.addOption(triage); group.addOption(search); Option url = new Option(URL_OPTION, true, URL_OPTION_DESCRIPTION); Option start = new Option(START_OPT, true, START_OPT_DESCRIPTION); Option end = new Option(END_OPT, true, END_OPT_DESCRIPTION); Option runid = new Option(RUNID_OPT, true, RUNID_OPT_DESCRIPTION); Option clusters = new Option(CLUSTERS_OPT, true, CLUSTERS_OPT_DESCRIPTION); Option sourceClusters = new Option(SOURCECLUSTER_OPT, true, SOURCECLUSTER_OPT_DESCRIPTION); Option filePath = new Option(FILE_PATH_OPT, true, FILE_PATH_OPT_DESCRIPTION); Option entityType = new Option(TYPE_OPT, true, TYPE_OPT_DESCRIPTION); Option entityName = new Option(ENTITY_NAME_OPT, true, ENTITY_NAME_OPT_DESCRIPTION); Option colo = new Option(COLO_OPT, true, COLO_OPT_DESCRIPTION); Option lifecycle = new Option(LIFECYCLE_OPT, true, LIFECYCLE_OPT_DESCRIPTION); Option filterBy = new Option(FILTER_BY_OPT, true, FILTER_BY_OPT_DESCRIPTION); Option orderBy = new Option(ORDER_BY_OPT, true, ORDER_BY_OPT_DESCRIPTION); Option sortOrder = new Option(SORT_ORDER_OPT, true, SORT_ORDER_OPT_DESCRIPTION); Option offset = new Option(OFFSET_OPT, true, OFFSET_OPT_DESCRIPTION); Option numResults = new Option(NUM_RESULTS_OPT, true, NUM_RESULTS_OPT_DESCRIPTION); Option forceRerun = new Option(FORCE_RERUN_FLAG, false, FORCE_RERUN_FLAG_DESCRIPTION); Option doAs = new Option(DO_AS_OPT, true, DO_AS_OPT_DESCRIPTION); Option debug = new Option(DEBUG_OPTION, false, DEBUG_OPTION_DESCRIPTION); Option instanceTime = new Option(INSTANCE_TIME_OPT, true, INSTANCE_TIME_OPT_DESCRIPTION); Option allAttempts = new Option(ALL_ATTEMPTS, false, ALL_ATTEMPTS_DESCRIPTION); Option instanceStatus = new Option(FalconCLIConstants.INSTANCE_STATUS_OPT, true, "Instance status"); Option nameSubsequence = new Option(FalconCLIConstants.NAMESEQ_OPT, true, "Subsequence of entity name"); Option tagKeywords = new Option(FalconCLIConstants.TAGKEYS_OPT, true, "Keywords in tags"); instanceOptions.addOption(url); instanceOptions.addOptionGroup(group); instanceOptions.addOption(start); instanceOptions.addOption(end); instanceOptions.addOption(filePath); instanceOptions.addOption(entityType); instanceOptions.addOption(entityName); instanceOptions.addOption(runid); instanceOptions.addOption(clusters); instanceOptions.addOption(sourceClusters); instanceOptions.addOption(colo); instanceOptions.addOption(lifecycle); instanceOptions.addOption(filterBy); instanceOptions.addOption(offset); instanceOptions.addOption(orderBy); instanceOptions.addOption(sortOrder); instanceOptions.addOption(numResults); instanceOptions.addOption(forceRerun); instanceOptions.addOption(doAs); instanceOptions.addOption(debug); instanceOptions.addOption(instanceTime); instanceOptions.addOption(instanceStatus); instanceOptions.addOption(nameSubsequence); instanceOptions.addOption(tagKeywords); instanceOptions.addOption(allAttempts); return instanceOptions; } public void instanceCommand(CommandLine commandLine, FalconClient client) throws IOException { Set<String> optionsList = new HashSet<String>(); for (Option option : commandLine.getOptions()) { optionsList.add(option.getOpt()); } String result; String type = commandLine.getOptionValue(FalconCLIConstants.TYPE_OPT); String entity = commandLine.getOptionValue(FalconCLIConstants.ENTITY_NAME_OPT); String instanceTime = commandLine.getOptionValue(INSTANCE_TIME_OPT); String start = commandLine.getOptionValue(FalconCLIConstants.START_OPT); String end = commandLine.getOptionValue(FalconCLIConstants.END_OPT); String status = commandLine.getOptionValue(FalconCLIConstants.INSTANCE_STATUS_OPT); String nameSubsequence = commandLine.getOptionValue(FalconCLIConstants.NAMESEQ_OPT); String tagKeywords = commandLine.getOptionValue(FalconCLIConstants.TAGKEYS_OPT); String filePath = commandLine.getOptionValue(FalconCLIConstants.FILE_PATH_OPT); String runId = commandLine.getOptionValue(RUNID_OPT); String colo = commandLine.getOptionValue(FalconCLIConstants.COLO_OPT); String clusters = commandLine.getOptionValue(CLUSTERS_OPT); String sourceClusters = commandLine.getOptionValue(SOURCECLUSTER_OPT); List<LifeCycle> lifeCycles = getLifeCycle(commandLine.getOptionValue(LIFECYCLE_OPT)); String filterBy = commandLine.getOptionValue(FalconCLIConstants.FILTER_BY_OPT); String orderBy = commandLine.getOptionValue(FalconCLIConstants.ORDER_BY_OPT); String sortOrder = commandLine.getOptionValue(FalconCLIConstants.SORT_ORDER_OPT); String doAsUser = commandLine.getOptionValue(FalconCLIConstants.DO_AS_OPT); Integer offset = parseIntegerInput(commandLine.getOptionValue(FalconCLIConstants.OFFSET_OPT), 0, "offset"); Integer numResults = parseIntegerInput(commandLine.getOptionValue(FalconCLIConstants.NUM_RESULTS_OPT), null, "numResults"); colo = getColo(colo); String instanceAction = "instance"; validateSortOrder(sortOrder); if (!optionsList.contains(SEARCH_OPT)) { validateInstanceCommands(optionsList, entity, type, colo); } if (optionsList.contains(TRIAGE_OPT)) { validateNotEmpty(colo, FalconCLIConstants.COLO_OPT); validateNotEmpty(start, FalconCLIConstants.START_OPT); validateNotEmpty(type, FalconCLIConstants.TYPE_OPT); ValidationUtil.validateEntityTypeForSummary(type); validateNotEmpty(entity, FalconCLIConstants.ENTITY_NAME_OPT); result = client.triage(type, entity, start, colo).toString(); } else if (optionsList.contains(FalconCLIConstants.DEPENDENCY_OPT)) { validateNotEmpty(instanceTime, INSTANCE_TIME_OPT); InstanceDependencyResult response = client.getInstanceDependencies(type, entity, instanceTime, colo); result = ResponseHelper.getString(response); } else if (optionsList.contains(RUNNING_OPT)) { ValidationUtil.validateOrderBy(orderBy, instanceAction); ValidationUtil.validateFilterBy(filterBy, instanceAction); result = ResponseHelper.getString(client.getRunningInstances(type, entity, colo, lifeCycles, filterBy, orderBy, sortOrder, offset, numResults, doAsUser)); } else if (optionsList.contains(FalconCLIConstants.STATUS_OPT) || optionsList.contains(FalconCLIConstants.LIST_OPT)) { boolean allAttempts = false; if (optionsList.contains(ALL_ATTEMPTS)) { allAttempts = true; } ValidationUtil.validateOrderBy(orderBy, instanceAction); ValidationUtil.validateFilterBy(filterBy, instanceAction); result = ResponseHelper.getString(client.getStatusOfInstances(type, entity, start, end, colo, lifeCycles, filterBy, orderBy, sortOrder, offset, numResults, doAsUser, allAttempts)); } else if (optionsList.contains(FalconCLIConstants.SUMMARY_OPT)) { ValidationUtil.validateOrderBy(orderBy, "summary"); ValidationUtil.validateFilterBy(filterBy, "summary"); result = ResponseHelper.getString(client.getSummaryOfInstances(type, entity, start, end, colo, lifeCycles, filterBy, orderBy, sortOrder, doAsUser)); } else if (optionsList.contains(KILL_OPT)) { validateNotEmpty(start, FalconCLIConstants.START_OPT); validateNotEmpty(end, FalconCLIConstants.END_OPT); result = ResponseHelper.getString(client.killInstances(type, entity, start, end, colo, clusters, sourceClusters, lifeCycles, doAsUser)); } else if (optionsList.contains(FalconCLIConstants.SUSPEND_OPT)) { validateNotEmpty(start, FalconCLIConstants.START_OPT); validateNotEmpty(end, FalconCLIConstants.END_OPT); result = ResponseHelper.getString(client.suspendInstances(type, entity, start, end, colo, clusters, sourceClusters, lifeCycles, doAsUser)); } else if (optionsList.contains(FalconCLIConstants.RESUME_OPT)) { validateNotEmpty(start, FalconCLIConstants.START_OPT); validateNotEmpty(end, FalconCLIConstants.END_OPT); result = ResponseHelper.getString(client.resumeInstances(type, entity, start, end, colo, clusters, sourceClusters, lifeCycles, doAsUser)); } else if (optionsList.contains(RERUN_OPT)) { validateNotEmpty(start, FalconCLIConstants.START_OPT); validateNotEmpty(end, FalconCLIConstants.END_OPT); boolean isForced = false; if (optionsList.contains(FORCE_RERUN_FLAG)) { isForced = true; } result = ResponseHelper.getString(client.rerunInstances(type, entity, start, end, filePath, colo, clusters, sourceClusters, lifeCycles, isForced, doAsUser)); } else if (optionsList.contains(LOG_OPT)) { ValidationUtil.validateOrderBy(orderBy, instanceAction); ValidationUtil.validateFilterBy(filterBy, instanceAction); result = ResponseHelper.getString(client.getLogsOfInstances(type, entity, start, end, colo, runId, lifeCycles, filterBy, orderBy, sortOrder, offset, numResults, doAsUser), runId); } else if (optionsList.contains(PARARMS_OPT)) { // start time is the nominal time of instance result = ResponseHelper.getString(client.getParamsOfInstance(type, entity, start, colo, lifeCycles, doAsUser)); } else if (optionsList.contains(LISTING_OPT)) { result = ResponseHelper.getString(client.getFeedInstanceListing(type, entity, start, end, colo, doAsUser)); } else if (optionsList.contains(SEARCH_OPT)) { result = ResponseHelper.getString(client.searchInstances( type, nameSubsequence, tagKeywords, start, end, status, orderBy, offset, numResults)); } else { throw new FalconCLIException("Invalid/missing instance command. Supported commands include " + "running, status, kill, suspend, resume, rerun, logs, search. " + "Please refer to Falcon CLI twiki for more details."); } OUT.get().println(result); } private void validateInstanceCommands(Set<String> optionsList, String entity, String type, String colo) { validateNotEmpty(entity, FalconCLIConstants.ENTITY_NAME_OPT); validateNotEmpty(type, FalconCLIConstants.TYPE_OPT); validateNotEmpty(colo, FalconCLIConstants.COLO_OPT); if (optionsList.contains(CLUSTERS_OPT)) { if (optionsList.contains(RUNNING_OPT) || optionsList.contains(LOG_OPT) || optionsList.contains(FalconCLIConstants.STATUS_OPT) || optionsList.contains(FalconCLIConstants.SUMMARY_OPT)) { throw new FalconCLIException("Invalid argument: clusters"); } } if (optionsList.contains(SOURCECLUSTER_OPT)) { if (optionsList.contains(RUNNING_OPT) || optionsList.contains(LOG_OPT) || optionsList.contains(FalconCLIConstants.STATUS_OPT) || optionsList.contains(FalconCLIConstants.SUMMARY_OPT) || !type.equals("feed")) { throw new FalconCLIException("Invalid argument: sourceClusters"); } } if (optionsList.contains(FORCE_RERUN_FLAG)) { if (!optionsList.contains(RERUN_OPT)) { throw new FalconCLIException("Force option can be used only with instance rerun"); } } } }