You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@falcon.apache.org by pe...@apache.org on 2016/04/13 17:39:58 UTC
[1/2] falcon git commit: FALCON-1895 Refactoring of FalconCLI and
FalconClient
Repository: falcon
Updated Branches:
refs/heads/master 3e22a77fe -> 6655e90a7
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/client/src/main/java/org/apache/falcon/cli/FalconCLI.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/falcon/cli/FalconCLI.java b/client/src/main/java/org/apache/falcon/cli/FalconCLI.java
deleted file mode 100644
index 7d0f2f6..0000000
--- a/client/src/main/java/org/apache/falcon/cli/FalconCLI.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/**
- * 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 com.sun.jersey.api.client.ClientHandlerException;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.falcon.client.FalconCLIException;
-import org.apache.falcon.client.FalconClient;
-import org.apache.falcon.entity.v0.EntityType;
-import org.apache.falcon.resource.EntityList;
-import org.apache.falcon.resource.InstancesResult;
-import org.apache.falcon.resource.InstancesSummaryResult;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.Arrays;
-import java.util.Properties;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Falcon Command Line Interface - wraps the RESTful API.
- */
-public class FalconCLI {
-
- public static final AtomicReference<PrintStream> ERR = new AtomicReference<PrintStream>(System.err);
- public static final AtomicReference<PrintStream> OUT = new AtomicReference<PrintStream>(System.out);
-
- public static final String ENV_FALCON_DEBUG = "FALCON_DEBUG";
- public static final String DEBUG_OPTION = "debug";
- public static final String URL_OPTION = "url";
- private static final String FALCON_URL = "FALCON_URL";
-
- public static final String ADMIN_CMD = "admin";
- public static final String HELP_CMD = "help";
- public static final String METADATA_CMD = "metadata";
- public static final String ENTITY_CMD = "entity";
- public static final String INSTANCE_CMD = "instance";
-
- public static final String TYPE_OPT = "type";
- public static final String COLO_OPT = "colo";
- public static final String CLUSTER_OPT = "cluster";
- public static final String FEED_OPT = "feed";
- public static final String PROCESS_OPT = "process";
- public static final String ENTITY_NAME_OPT = "name";
- public static final String FILE_PATH_OPT = "file";
- public static final String VERSION_OPT = "version";
- public static final String SCHEDULE_OPT = "schedule";
- public static final String SUSPEND_OPT = "suspend";
- public static final String RESUME_OPT = "resume";
- public static final String STATUS_OPT = "status";
- public static final String SUMMARY_OPT = "summary";
- public static final String DEPENDENCY_OPT = "dependency";
- public static final String LIST_OPT = "list";
- public static final String SKIPDRYRUN_OPT = "skipDryRun";
- public static final String FILTER_BY_OPT = "filterBy";
- public static final String ORDER_BY_OPT = "orderBy";
- public static final String SORT_ORDER_OPT = "sortOrder";
- public static final String OFFSET_OPT = "offset";
- public static final String NUM_RESULTS_OPT = "numResults";
- public static final String START_OPT = "start";
- public static final String END_OPT = "end";
- public static final String CURRENT_COLO = "current.colo";
- public static final String CLIENT_PROPERTIES = "/client.properties";
- public static final String DO_AS_OPT = "doAs";
-
- private final Properties clientProperties;
-
- public FalconCLI() throws Exception {
- clientProperties = getClientProperties();
- }
-
- /**
- * Entry point for the Falcon CLI when invoked from the command line. Upon
- * completion this method exits the JVM with '0' (success) or '-1'
- * (failure).
- *
- * @param args options and arguments for the Falcon CLI.
- */
- public static void main(final String[] args) throws Exception {
- System.exit(new FalconCLI().run(args));
- }
-
- // TODO help and headers
- private static final String[] FALCON_HELP = { "the env variable '" + FALCON_URL
- + "' is used as default value for the '-" + URL_OPTION
- + "' option",
- "custom headers for Falcon web services can be specified using '-D"
- + FalconClient.WS_HEADER_PREFIX + "NAME=VALUE'", };
- /**
- * Run a CLI programmatically.
- * <p/>
- * It does not exit the JVM.
- * <p/>
- * A CLI instance can be used only once.
- *
- * @param args options and arguments for the Oozie CLI.
- * @return '0' (success), '-1' (failure).
- */
- public synchronized int run(final String[] args) throws Exception {
-
- CLIParser parser = new CLIParser("falcon", FALCON_HELP);
-
- FalconAdminCLI adminCLI = new FalconAdminCLI();
- FalconEntityCLI entityCLI = new FalconEntityCLI();
- FalconInstanceCLI instanceCLI = new FalconInstanceCLI();
- FalconMetadataCLI metadataCLI = new FalconMetadataCLI();
-
- parser.addCommand(ADMIN_CMD, "", "admin operations", adminCLI.createAdminOptions(), true);
- parser.addCommand(HELP_CMD, "", "display usage", new Options(), false);
- parser.addCommand(ENTITY_CMD, "",
- "Entity operations like submit, suspend, resume, delete, status, definition, submitAndSchedule",
- entityCLI.createEntityOptions(), false);
- parser.addCommand(INSTANCE_CMD, "",
- "Process instances operations like running, status, kill, suspend, resume, rerun, logs",
- instanceCLI.createInstanceOptions(), false);
- parser.addCommand(METADATA_CMD, "", "Metadata operations like list, relations",
- metadataCLI.createMetadataOptions(), true);
- parser.addCommand(VERSION_OPT, "", "show client version", new Options(), false);
-
- try {
- CLIParser.Command command = parser.parse(args);
- int exitValue = 0;
- if (command.getName().equals(HELP_CMD)) {
- parser.showHelp();
- } else {
- CommandLine commandLine = command.getCommandLine();
- String falconUrl = getFalconEndpoint(commandLine);
- FalconClient client = new FalconClient(falconUrl, clientProperties);
-
- setDebugMode(client, commandLine.hasOption(DEBUG_OPTION));
- if (command.getName().equals(ADMIN_CMD)) {
- exitValue = adminCLI.adminCommand(commandLine, client, falconUrl);
- } else if (command.getName().equals(ENTITY_CMD)) {
- entityCLI.entityCommand(commandLine, client);
- } else if (command.getName().equals(INSTANCE_CMD)) {
- instanceCLI.instanceCommand(commandLine, client);
- } else if (command.getName().equals(METADATA_CMD)) {
- metadataCLI.metadataCommand(commandLine, client);
- }
- }
- return exitValue;
- } catch (ParseException ex) {
- ERR.get().println("Invalid sub-command: " + ex.getMessage());
- ERR.get().println();
- ERR.get().println(parser.shortHelp());
- ERR.get().println("Stacktrace:");
- ex.printStackTrace();
- return -1;
- } catch (ClientHandlerException ex) {
- ERR.get().print("Unable to connect to Falcon server, "
- + "please check if the URL is correct and Falcon server is up and running\n");
- ERR.get().println("Stacktrace:");
- ex.printStackTrace();
- return -1;
- } catch (FalconCLIException e) {
- ERR.get().println("ERROR: " + e.getMessage());
- return -1;
- } catch (Exception ex) {
- ERR.get().println("Stacktrace:");
- ex.printStackTrace();
- return -1;
- }
- }
-
- protected Integer parseIntegerInput(String optionValue, Integer defaultVal, String optionName)
- throws FalconCLIException {
- Integer integer = defaultVal;
- if (optionValue != null) {
- try {
- return Integer.parseInt(optionValue);
- } catch (NumberFormatException e) {
- throw new FalconCLIException("Input value provided for queryParam \""+ optionName
- +"\" is not a valid Integer");
- }
- }
- return integer;
- }
-
- protected void validateEntityTypeForSummary(String type) throws FalconCLIException {
- EntityType entityType = EntityType.getEnum(type);
- if (!entityType.isSchedulable()) {
- throw new FalconCLIException("Invalid entity type " + entityType
- + " for EntitySummary API. Valid options are feed or process");
- }
- }
-
- protected void validateNotEmpty(String paramVal, String paramName) throws FalconCLIException {
- if (StringUtils.isBlank(paramVal)) {
- throw new FalconCLIException("Missing argument : " + paramName);
- }
- }
-
- protected void validateSortOrder(String sortOrder) throws FalconCLIException {
- if (!StringUtils.isBlank(sortOrder)) {
- if (!sortOrder.equalsIgnoreCase("asc") && !sortOrder.equalsIgnoreCase("desc")) {
- throw new FalconCLIException("Value for param sortOrder should be \"asc\" or \"desc\". It is : "
- + sortOrder);
- }
- }
- }
-
- protected String getColo(String colo) throws FalconCLIException, IOException {
- if (colo == null) {
- Properties prop = getClientProperties();
- colo = prop.getProperty(CURRENT_COLO, "*");
- }
- return colo;
- }
-
- protected void validateFilterBy(String filterBy, String filterType) throws FalconCLIException {
- if (StringUtils.isEmpty(filterBy)) {
- return;
- }
- String[] filterSplits = filterBy.split(",");
- for (String s : filterSplits) {
- String[] tempKeyVal = s.split(":", 2);
- try {
- if (filterType.equals("entity")) {
- EntityList.EntityFilterByFields.valueOf(tempKeyVal[0].toUpperCase());
- } else if (filterType.equals("instance")) {
- InstancesResult.InstanceFilterFields.valueOf(tempKeyVal[0].toUpperCase());
- }else if (filterType.equals("summary")) {
- InstancesSummaryResult.InstanceSummaryFilterFields.valueOf(tempKeyVal[0].toUpperCase());
- } else {
- throw new IllegalArgumentException("Invalid API call: filterType is not valid");
- }
- } catch (IllegalArgumentException ie) {
- throw new FalconCLIException("Invalid filterBy argument : " + tempKeyVal[0] + " in : " + s);
- }
- }
- }
-
- protected void validateOrderBy(String orderBy, String action) throws FalconCLIException {
- if (StringUtils.isBlank(orderBy)) {
- return;
- }
- if (action.equals("instance")) {
- if (Arrays.asList(new String[]{"status", "cluster", "starttime", "endtime"})
- .contains(orderBy.toLowerCase())) {
- return;
- }
- } else if (action.equals("entity")) {
- if (Arrays.asList(new String[] {"type", "name"}).contains(orderBy.toLowerCase())) {
- return;
- }
- } else if (action.equals("summary")) {
- if (Arrays.asList(new String[]{"cluster"})
- .contains(orderBy.toLowerCase())) {
- return;
- }
- }
- throw new FalconCLIException("Invalid orderBy argument : " + orderBy);
- }
-
- protected String getFalconEndpoint(CommandLine commandLine) throws FalconCLIException, IOException {
- String url = commandLine.getOptionValue(URL_OPTION);
- if (url == null) {
- url = System.getenv(FALCON_URL);
- }
- if (url == null) {
- if (clientProperties.containsKey("falcon.url")) {
- url = clientProperties.getProperty("falcon.url");
- }
- }
- if (url == null) {
- throw new FalconCLIException("Failed to get falcon url from cmdline, or environment or client properties");
- }
-
- return url;
- }
-
- private void setDebugMode(FalconClient client, boolean debugOpt) {
- String debug = System.getenv(ENV_FALCON_DEBUG);
- if (debugOpt) { // CLI argument "-debug" used
- client.setDebugMode(true);
- } else if (StringUtils.isNotBlank(debug)) {
- System.out.println(ENV_FALCON_DEBUG + ": " + debug);
- if (debug.trim().toLowerCase().equals("true")) {
- client.setDebugMode(true);
- }
- }
- }
-
- private Properties getClientProperties() throws IOException {
- InputStream inputStream = null;
- try {
- inputStream = FalconCLI.class.getResourceAsStream(CLIENT_PROPERTIES);
- Properties prop = new Properties();
- if (inputStream != null) {
- prop.load(inputStream);
- }
- return prop;
- } finally {
- IOUtils.closeQuietly(inputStream);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/client/src/main/java/org/apache/falcon/cli/FalconEntityCLI.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/falcon/cli/FalconEntityCLI.java b/client/src/main/java/org/apache/falcon/cli/FalconEntityCLI.java
deleted file mode 100644
index 6f9d620..0000000
--- a/client/src/main/java/org/apache/falcon/cli/FalconEntityCLI.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/**
- * 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.commons.lang3.StringUtils;
-import org.apache.falcon.ResponseHelper;
-import org.apache.falcon.client.FalconCLIException;
-import org.apache.falcon.client.FalconClient;
-import org.apache.falcon.entity.v0.EntityType;
-import org.apache.falcon.entity.v0.SchemaHelper;
-import org.apache.falcon.resource.EntityList;
-import org.apache.falcon.resource.FeedLookupResult;
-import org.apache.falcon.resource.SchedulableEntityInstanceResult;
-
-import java.io.IOException;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Entity extension to Falcon Command Line Interface - wraps the RESTful API for entities.
- */
-public class FalconEntityCLI extends FalconCLI {
-
- private static final String SUBMIT_OPT = "submit";
- private static final String UPDATE_OPT = "update";
- private static final String DELETE_OPT = "delete";
- private static final String SUBMIT_AND_SCHEDULE_OPT = "submitAndSchedule";
- private static final String VALIDATE_OPT = "validate";
- private static final String DEFINITION_OPT = "definition";
- public static final String SLA_MISS_ALERT_OPT = "slaAlert";
-
- private static final String LOOKUP_OPT = "lookup";
- private static final String PATH_OPT = "path";
- private static final String TOUCH_OPT = "touch";
- private static final String PROPS_OPT = "properties";
- private static final String FIELDS_OPT = "fields";
- private static final String TAGS_OPT = "tags";
- private static final String NUM_INSTANCES_OPT = "numInstances";
- private static final String NAMESEQ_OPT = "nameseq";
- private static final String TAGKEYS_OPT = "tagkeys";
- private static final String SHOWSCHEDULER_OPT = "showScheduler";
-
- public FalconEntityCLI() throws Exception {
- super();
- }
-
- public Options createEntityOptions() {
-
- Options entityOptions = new Options();
-
- Option submit = new Option(SUBMIT_OPT, false,
- "Submits an entity xml to Falcon");
- Option update = new Option(UPDATE_OPT, false,
- "Updates an existing entity xml");
- Option schedule = new Option(SCHEDULE_OPT, false,
- "Schedules a submited entity in Falcon");
- Option suspend = new Option(SUSPEND_OPT, false,
- "Suspends a running entity in Falcon");
- Option resume = new Option(RESUME_OPT, false,
- "Resumes a suspended entity in Falcon");
- Option delete = new Option(DELETE_OPT, false,
- "Deletes an entity in Falcon, and kills its instance from workflow engine");
- Option submitAndSchedule = new Option(SUBMIT_AND_SCHEDULE_OPT, false,
- "Submits and entity to Falcon and schedules it immediately");
- Option validate = new Option(VALIDATE_OPT, false,
- "Validates an entity based on the entity type");
- Option status = new Option(STATUS_OPT, false,
- "Gets the status of entity");
- Option definition = new Option(DEFINITION_OPT, false,
- "Gets the Definition of entity");
- Option dependency = new Option(DEPENDENCY_OPT, false,
- "Gets the dependencies of entity");
- Option list = new Option(LIST_OPT, false,
- "List entities registered for a type");
- Option lookup = new Option(LOOKUP_OPT, false, "Lookup a feed given its instance's path");
- Option slaAlert = new Option(SLA_MISS_ALERT_OPT, false, "Get missing feed instances which missed SLA");
- Option entitySummary = new Option(SUMMARY_OPT, false,
- "Get summary of instances for list of entities");
- Option touch = new Option(TOUCH_OPT, false,
- "Force update the entity in workflow engine(even without any changes to entity)");
-
- OptionGroup group = new OptionGroup();
- group.addOption(submit);
- group.addOption(update);
- group.addOption(schedule);
- group.addOption(suspend);
- group.addOption(resume);
- group.addOption(delete);
- group.addOption(submitAndSchedule);
- group.addOption(validate);
- group.addOption(status);
- group.addOption(definition);
- group.addOption(dependency);
- group.addOption(list);
- group.addOption(lookup);
- group.addOption(slaAlert);
- group.addOption(entitySummary);
- group.addOption(touch);
-
- Option url = new Option(URL_OPTION, true, "Falcon URL");
- Option entityType = new Option(TYPE_OPT, true,
- "Entity type, can be cluster, feed or process xml");
- Option filePath = new Option(FILE_PATH_OPT, true,
- "Path to entity xml file");
- Option entityName = new Option(ENTITY_NAME_OPT, true,
- "Entity type, can be cluster, feed or process xml");
- Option start = new Option(START_OPT, true, "Start time is optional for summary");
- Option end = new Option(END_OPT, true, "End time is optional for summary");
- Option colo = new Option(COLO_OPT, true, "Colo name");
- Option cluster = new Option(CLUSTER_OPT, true, "Cluster name");
- colo.setRequired(false);
- Option fields = new Option(FIELDS_OPT, true, "Entity fields to show for a request");
- Option filterBy = new Option(FILTER_BY_OPT, true,
- "Filter returned entities by the specified status");
- Option filterTags = new Option(TAGS_OPT, true, "Filter returned entities by the specified tags");
- Option nameSubsequence = new Option(NAMESEQ_OPT, true, "Subsequence of entity name");
- Option tagKeywords = new Option(TAGKEYS_OPT, true, "Keywords in tags");
- Option orderBy = new Option(ORDER_BY_OPT, true,
- "Order returned entities by this field");
- Option sortOrder = new Option(SORT_ORDER_OPT, true, "asc or desc order for results");
- Option offset = new Option(OFFSET_OPT, true,
- "Start returning entities from this offset");
- Option numResults = new Option(NUM_RESULTS_OPT, true,
- "Number of results to return per request");
- Option numInstances = new Option(NUM_INSTANCES_OPT, true,
- "Number of instances to return per entity summary request");
- Option path = new Option(PATH_OPT, true, "Path for a feed's instance");
- Option skipDryRun = new Option(SKIPDRYRUN_OPT, false, "skip dry run in workflow engine");
- Option doAs = new Option(DO_AS_OPT, true, "doAs user");
- Option userProps = new Option(PROPS_OPT, true, "User supplied comma separated key value properties");
- Option showScheduler = new Option(SHOWSCHEDULER_OPT, false, "To return the scheduler "
- + "on which the entity is scheduled.");
- Option debug = new Option(DEBUG_OPTION, false, "Use debug mode to see debugging statements on stdout");
-
- entityOptions.addOption(url);
- entityOptions.addOption(path);
- entityOptions.addOptionGroup(group);
- entityOptions.addOption(entityType);
- entityOptions.addOption(entityName);
- entityOptions.addOption(filePath);
- entityOptions.addOption(colo);
- entityOptions.addOption(cluster);
- entityOptions.addOption(start);
- entityOptions.addOption(end);
- entityOptions.addOption(fields);
- entityOptions.addOption(filterBy);
- entityOptions.addOption(filterTags);
- entityOptions.addOption(nameSubsequence);
- entityOptions.addOption(tagKeywords);
- entityOptions.addOption(orderBy);
- entityOptions.addOption(sortOrder);
- entityOptions.addOption(offset);
- entityOptions.addOption(numResults);
- entityOptions.addOption(numInstances);
- entityOptions.addOption(skipDryRun);
- entityOptions.addOption(doAs);
- entityOptions.addOption(userProps);
- entityOptions.addOption(debug);
- entityOptions.addOption(showScheduler);
-
- return entityOptions;
- }
-
- public void entityCommand(CommandLine commandLine, FalconClient client) throws FalconCLIException, IOException {
- Set<String> optionsList = new HashSet<String>();
- for (Option option : commandLine.getOptions()) {
- optionsList.add(option.getOpt());
- }
-
- String result = null;
- String entityType = commandLine.getOptionValue(TYPE_OPT);
- String entityName = commandLine.getOptionValue(ENTITY_NAME_OPT);
- String filePath = commandLine.getOptionValue(FILE_PATH_OPT);
- String colo = commandLine.getOptionValue(COLO_OPT);
- colo = getColo(colo);
- String cluster = commandLine.getOptionValue(CLUSTER_OPT);
- String start = commandLine.getOptionValue(START_OPT);
- String end = commandLine.getOptionValue(END_OPT);
- String orderBy = commandLine.getOptionValue(ORDER_BY_OPT);
- String sortOrder = commandLine.getOptionValue(SORT_ORDER_OPT);
- String filterBy = commandLine.getOptionValue(FILTER_BY_OPT);
- String filterTags = commandLine.getOptionValue(TAGS_OPT);
- String nameSubsequence = commandLine.getOptionValue(NAMESEQ_OPT);
- String tagKeywords = commandLine.getOptionValue(TAGKEYS_OPT);
- String fields = commandLine.getOptionValue(FIELDS_OPT);
- String feedInstancePath = commandLine.getOptionValue(PATH_OPT);
- Integer offset = parseIntegerInput(commandLine.getOptionValue(OFFSET_OPT), 0, "offset");
- Integer numResults = parseIntegerInput(commandLine.getOptionValue(NUM_RESULTS_OPT),
- null, "numResults");
- String doAsUser = commandLine.getOptionValue(DO_AS_OPT);
-
- Integer numInstances = parseIntegerInput(commandLine.getOptionValue(NUM_INSTANCES_OPT), 7, "numInstances");
- Boolean skipDryRun = null;
- if (optionsList.contains(SKIPDRYRUN_OPT)) {
- skipDryRun = true;
- }
-
- String userProps = commandLine.getOptionValue(PROPS_OPT);
- boolean showScheduler = false;
- if (optionsList.contains(SHOWSCHEDULER_OPT)) {
- showScheduler = true;
- }
-
- EntityType entityTypeEnum = null;
- if (optionsList.contains(LIST_OPT)) {
- if (entityType == null) {
- entityType = "";
- }
- if (StringUtils.isNotEmpty(entityType)) {
- String[] types = entityType.split(",");
- for (String type : types) {
- EntityType.getEnum(type);
- }
- }
- } else {
- validateNotEmpty(entityType, TYPE_OPT);
- entityTypeEnum = EntityType.getEnum(entityType);
- }
- validateSortOrder(sortOrder);
- String entityAction = "entity";
-
- if (optionsList.contains(SLA_MISS_ALERT_OPT)) {
- validateNotEmpty(entityType, TYPE_OPT);
- validateNotEmpty(start, START_OPT);
- parseDateString(start);
- parseDateString(end);
- SchedulableEntityInstanceResult response = client.getFeedSlaMissPendingAlerts(entityType,
- entityName, start, end, colo);
- result = ResponseHelper.getString(response);
- } else if (optionsList.contains(SUBMIT_OPT)) {
- validateNotEmpty(filePath, "file");
- validateColo(optionsList);
- result = client.submit(entityType, filePath, doAsUser).getMessage();
- } else if (optionsList.contains(LOOKUP_OPT)) {
- validateNotEmpty(feedInstancePath, PATH_OPT);
- FeedLookupResult resp = client.reverseLookUp(entityType, feedInstancePath, doAsUser);
- result = ResponseHelper.getString(resp);
- } else if (optionsList.contains(UPDATE_OPT)) {
- validateNotEmpty(filePath, "file");
- validateColo(optionsList);
- validateNotEmpty(entityName, ENTITY_NAME_OPT);
- result = client.update(entityType, entityName, filePath, skipDryRun, doAsUser).getMessage();
- } else if (optionsList.contains(SUBMIT_AND_SCHEDULE_OPT)) {
- validateNotEmpty(filePath, "file");
- validateColo(optionsList);
- result = client.submitAndSchedule(entityType, filePath, skipDryRun, doAsUser, userProps).getMessage();
- } else if (optionsList.contains(VALIDATE_OPT)) {
- validateNotEmpty(filePath, "file");
- validateColo(optionsList);
- result = client.validate(entityType, filePath, skipDryRun, doAsUser).getMessage();
- } else if (optionsList.contains(SCHEDULE_OPT)) {
- validateNotEmpty(entityName, ENTITY_NAME_OPT);
- colo = getColo(colo);
- result = client.schedule(entityTypeEnum, entityName, colo, skipDryRun, doAsUser, userProps).getMessage();
- } else if (optionsList.contains(SUSPEND_OPT)) {
- validateNotEmpty(entityName, ENTITY_NAME_OPT);
- colo = getColo(colo);
- result = client.suspend(entityTypeEnum, entityName, colo, doAsUser).getMessage();
- } else if (optionsList.contains(RESUME_OPT)) {
- validateNotEmpty(entityName, ENTITY_NAME_OPT);
- colo = getColo(colo);
- result = client.resume(entityTypeEnum, entityName, colo, doAsUser).getMessage();
- } else if (optionsList.contains(DELETE_OPT)) {
- validateColo(optionsList);
- validateNotEmpty(entityName, ENTITY_NAME_OPT);
- result = client.delete(entityTypeEnum, entityName, doAsUser).getMessage();
- } else if (optionsList.contains(STATUS_OPT)) {
- validateNotEmpty(entityName, ENTITY_NAME_OPT);
- colo = getColo(colo);
- result = client.getStatus(entityTypeEnum, entityName, colo, doAsUser, showScheduler).getMessage();
- } else if (optionsList.contains(DEFINITION_OPT)) {
- validateColo(optionsList);
- validateNotEmpty(entityName, ENTITY_NAME_OPT);
- result = client.getDefinition(entityType, entityName, doAsUser).toString();
- } else if (optionsList.contains(DEPENDENCY_OPT)) {
- validateColo(optionsList);
- validateNotEmpty(entityName, ENTITY_NAME_OPT);
- result = client.getDependency(entityType, entityName, doAsUser).toString();
- } else if (optionsList.contains(LIST_OPT)) {
- validateColo(optionsList);
- validateEntityFields(fields);
- validateOrderBy(orderBy, entityAction);
- validateFilterBy(filterBy, entityAction);
- EntityList entityList = client.getEntityList(entityType, fields, nameSubsequence, tagKeywords,
- filterBy, filterTags, orderBy, sortOrder, offset, numResults, doAsUser);
- result = entityList != null ? entityList.toString() : "No entity of type (" + entityType + ") found.";
- } else if (optionsList.contains(SUMMARY_OPT)) {
- validateEntityTypeForSummary(entityType);
- validateNotEmpty(cluster, CLUSTER_OPT);
- validateEntityFields(fields);
- validateFilterBy(filterBy, entityAction);
- validateOrderBy(orderBy, entityAction);
- result = ResponseHelper.getString(client.getEntitySummary(
- entityType, cluster, start, end, fields, filterBy, filterTags,
- orderBy, sortOrder, offset, numResults, numInstances, doAsUser));
- } else if (optionsList.contains(TOUCH_OPT)) {
- validateNotEmpty(entityName, ENTITY_NAME_OPT);
- colo = getColo(colo);
- result = client.touch(entityType, entityName, colo, skipDryRun, doAsUser).getMessage();
- } else if (optionsList.contains(HELP_CMD)) {
- OUT.get().println("Falcon Help");
- } else {
- throw new FalconCLIException("Invalid command");
- }
- OUT.get().println(result);
- }
-
- private void validateColo(Set<String> optionsList) throws FalconCLIException {
- if (optionsList.contains(COLO_OPT)) {
- throw new FalconCLIException("Invalid argument : " + COLO_OPT);
- }
- }
-
- private void validateEntityFields(String fields) throws FalconCLIException {
- if (StringUtils.isEmpty(fields)) {
- return;
- }
- String[] fieldsList = fields.split(",");
- for (String s : fieldsList) {
- try {
- EntityList.EntityFieldList.valueOf(s.toUpperCase());
- } catch (IllegalArgumentException ie) {
- throw new FalconCLIException("Invalid fields argument : " + FIELDS_OPT);
- }
- }
- }
-
- private Date parseDateString(String time) throws FalconCLIException {
- if (time != null && !time.isEmpty()) {
- try {
- return SchemaHelper.parseDateUTC(time);
- } catch(Exception e) {
- throw new FalconCLIException("Time " + time + " is not valid", e);
- }
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/client/src/main/java/org/apache/falcon/cli/FalconInstanceCLI.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/falcon/cli/FalconInstanceCLI.java b/client/src/main/java/org/apache/falcon/cli/FalconInstanceCLI.java
deleted file mode 100644
index 544bda8..0000000
--- a/client/src/main/java/org/apache/falcon/cli/FalconInstanceCLI.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/**
- * 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.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.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Instance extension to Falcon Command Line Interface - wraps the RESTful API for instances.
- */
-public class FalconInstanceCLI extends FalconCLI {
-
- private static final String FORCE_RERUN_FLAG = "force";
- private static final String INSTANCE_TIME_OPT = "instanceTime";
- private static final String RUNNING_OPT = "running";
- private static final String KILL_OPT = "kill";
- private static final String RERUN_OPT = "rerun";
- private static final String LOG_OPT = "logs";
- private static final String ALL_ATTEMPTS = "allAttempts";
- private static final String RUNID_OPT = "runid";
- private static final String CLUSTERS_OPT = "clusters";
- private static final String SOURCECLUSTER_OPT = "sourceClusters";
- private static final String LIFECYCLE_OPT = "lifecycle";
- private static final String PARARMS_OPT = "params";
- private static final String LISTING_OPT = "listing";
- private static final String TRIAGE_OPT = "triage";
-
- public FalconInstanceCLI() throws Exception {
- super();
- }
-
- public Options createInstanceOptions() {
-
- Options instanceOptions = new Options();
-
- Option running = new Option(RUNNING_OPT, false,
- "Gets running process instances for a given process");
- Option list = new Option(LIST_OPT, false,
- "Gets all instances for a given process in the range start time and optional end time");
- Option status = new Option(STATUS_OPT, false,
- "Gets status of process instances for a given process in the range start time and optional end time");
- Option summary = new Option(SUMMARY_OPT, false,
- "Gets summary of instances for a given process in the range start time and optional end time");
- Option kill = new Option(KILL_OPT, false,
- "Kills active process instances for a given process in the range start time and optional end time");
- Option suspend = new Option(SUSPEND_OPT, false,
- "Suspends active process instances for a given process in the range start time and optional end time");
- Option resume = new Option(RESUME_OPT, false,
- "Resumes suspended process instances for a given process "
- + "in the range start time and optional end time");
- Option rerun = new Option(RERUN_OPT, false,
- "Reruns process instances for a given process in the range start time and "
- + "optional end time and overrides properties present in job.properties file");
- Option logs = new Option(LOG_OPT, false,
- "Logs print the logs for process instances for a given process in "
- + "the range start time and optional end time");
- Option params = new Option(PARARMS_OPT, false,
- "Displays the workflow parameters for a given instance of specified nominal time"
- + "start time represents nominal time and end time is not considered");
- Option listing = new Option(LISTING_OPT, false,
- "Displays feed listing and their status between a start and end time range.");
- Option dependency = new Option(DEPENDENCY_OPT, false,
- "Displays dependent instances for a specified instance.");
- Option triage = new Option(TRIAGE_OPT, false,
- "Triage a feed or process instance and find the failures in it's lineage.");
-
- 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);
-
- Option url = new Option(URL_OPTION, true, "Falcon URL");
- Option start = new Option(START_OPT, true,
- "Start time is required for commands, status, kill, suspend, resume and re-run"
- + "and it is nominal time while displaying workflow params");
- Option end = new Option(END_OPT, true,
- "End time is optional for commands, status, kill, suspend, resume and re-run; "
- + "if not specified then current time is considered as end time");
- Option runid = new Option(RUNID_OPT, true,
- "Instance runid is optional and user can specify the runid, defaults to 0");
- Option clusters = new Option(CLUSTERS_OPT, true,
- "clusters is optional for commands kill, suspend and resume, "
- + "should not be specified for other commands");
- Option sourceClusters = new Option(SOURCECLUSTER_OPT, true,
- " source cluster is optional for commands kill, suspend and resume, "
- + "should not be specified for other commands (required for only feed)");
- Option filePath = new Option(FILE_PATH_OPT, true,
- "Path to job.properties file is required for rerun command, "
- + "it should contain name=value pair for properties to override for rerun");
- Option entityType = new Option(TYPE_OPT, true,
- "Entity type, can be feed or process xml");
- Option entityName = new Option(ENTITY_NAME_OPT, true,
- "Entity name, can be feed or process name");
- Option colo = new Option(COLO_OPT, true,
- "Colo on which the cmd has to be executed");
- Option lifecycle = new Option(LIFECYCLE_OPT, true,
- "describes life cycle of entity , for feed it can be replication/retention "
- + "and for process it can be execution");
- Option filterBy = new Option(FILTER_BY_OPT, true,
- "Filter returned instances by the specified fields");
- Option orderBy = new Option(ORDER_BY_OPT, true,
- "Order returned instances by this field");
- Option sortOrder = new Option(SORT_ORDER_OPT, true, "asc or desc order for results");
- Option offset = new Option(OFFSET_OPT, true,
- "Start returning instances from this offset");
- Option numResults = new Option(NUM_RESULTS_OPT, true,
- "Number of results to return per request");
- Option forceRerun = new Option(FORCE_RERUN_FLAG, false,
- "Flag to forcefully rerun entire workflow of an instance");
- Option doAs = new Option(DO_AS_OPT, true, "doAs user");
- Option debug = new Option(DEBUG_OPTION, false, "Use debug mode to see debugging statements on stdout");
-
- Option instanceTime = new Option(INSTANCE_TIME_OPT, true, "Time for an instance");
-
- Option allAttempts = new Option(ALL_ATTEMPTS, false, "To get all attempts of corresponding instances");
-
- 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(allAttempts);
-
- return instanceOptions;
- }
-
- public void instanceCommand(CommandLine commandLine, FalconClient client) throws FalconCLIException, IOException {
- Set<String> optionsList = new HashSet<String>();
- for (Option option : commandLine.getOptions()) {
- optionsList.add(option.getOpt());
- }
-
- String result;
- String type = commandLine.getOptionValue(TYPE_OPT);
- String entity = commandLine.getOptionValue(ENTITY_NAME_OPT);
- String instanceTime = commandLine.getOptionValue(INSTANCE_TIME_OPT);
- String start = commandLine.getOptionValue(START_OPT);
- String end = commandLine.getOptionValue(END_OPT);
- String filePath = commandLine.getOptionValue(FILE_PATH_OPT);
- String runId = commandLine.getOptionValue(RUNID_OPT);
- String colo = commandLine.getOptionValue(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(FILTER_BY_OPT);
- String orderBy = commandLine.getOptionValue(ORDER_BY_OPT);
- String sortOrder = commandLine.getOptionValue(SORT_ORDER_OPT);
- String doAsUser = commandLine.getOptionValue(DO_AS_OPT);
- Integer offset = parseIntegerInput(commandLine.getOptionValue(OFFSET_OPT), 0, "offset");
- Integer numResults = parseIntegerInput(commandLine.getOptionValue(NUM_RESULTS_OPT), null, "numResults");
-
- colo = getColo(colo);
- String instanceAction = "instance";
- validateSortOrder(sortOrder);
- validateInstanceCommands(optionsList, entity, type, colo);
-
- if (optionsList.contains(TRIAGE_OPT)) {
- validateNotEmpty(colo, COLO_OPT);
- validateNotEmpty(start, START_OPT);
- validateNotEmpty(type, TYPE_OPT);
- validateEntityTypeForSummary(type);
- validateNotEmpty(entity, ENTITY_NAME_OPT);
- result = client.triage(type, entity, start, colo).toString();
- } else if (optionsList.contains(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)) {
- validateOrderBy(orderBy, instanceAction);
- validateFilterBy(filterBy, instanceAction);
- result = ResponseHelper.getString(client.getRunningInstances(type,
- entity, colo, lifeCycles, filterBy, orderBy, sortOrder, offset, numResults, doAsUser));
- } else if (optionsList.contains(STATUS_OPT) || optionsList.contains(LIST_OPT)) {
- boolean allAttempts = false;
- if (optionsList.contains(ALL_ATTEMPTS)) {
- allAttempts = true;
- }
- validateOrderBy(orderBy, instanceAction);
- 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(SUMMARY_OPT)) {
- validateOrderBy(orderBy, "summary");
- 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, START_OPT);
- validateNotEmpty(end, END_OPT);
- result = ResponseHelper.getString(client.killInstances(type, entity, start, end, colo, clusters,
- sourceClusters, lifeCycles, doAsUser));
- } else if (optionsList.contains(SUSPEND_OPT)) {
- validateNotEmpty(start, START_OPT);
- validateNotEmpty(end, END_OPT);
- result = ResponseHelper.getString(client.suspendInstances(type, entity, start, end, colo, clusters,
- sourceClusters, lifeCycles, doAsUser));
- } else if (optionsList.contains(RESUME_OPT)) {
- validateNotEmpty(start, START_OPT);
- validateNotEmpty(end, END_OPT);
- result = ResponseHelper.getString(client.resumeInstances(type, entity, start, end, colo, clusters,
- sourceClusters, lifeCycles, doAsUser));
- } else if (optionsList.contains(RERUN_OPT)) {
- validateNotEmpty(start, START_OPT);
- validateNotEmpty(end, 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)) {
- validateOrderBy(orderBy, instanceAction);
- 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 {
- throw new FalconCLIException("Invalid command");
- }
-
- OUT.get().println(result);
- }
-
- private void validateInstanceCommands(Set<String> optionsList,
- String entity, String type,
- String colo) throws FalconCLIException {
-
- validateNotEmpty(entity, ENTITY_NAME_OPT);
- validateNotEmpty(type, TYPE_OPT);
- validateNotEmpty(colo, COLO_OPT);
-
- if (optionsList.contains(CLUSTERS_OPT)) {
- if (optionsList.contains(RUNNING_OPT)
- || optionsList.contains(LOG_OPT)
- || optionsList.contains(STATUS_OPT)
- || optionsList.contains(SUMMARY_OPT)) {
- throw new FalconCLIException("Invalid argument: clusters");
- }
- }
-
- if (optionsList.contains(SOURCECLUSTER_OPT)) {
- if (optionsList.contains(RUNNING_OPT)
- || optionsList.contains(LOG_OPT)
- || optionsList.contains(STATUS_OPT)
- || optionsList.contains(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");
- }
- }
- }
-
- private List<LifeCycle> getLifeCycle(String lifeCycleValue) throws FalconCLIException {
-
- if (lifeCycleValue != null) {
- String[] lifeCycleValues = lifeCycleValue.split(",");
- List<LifeCycle> lifeCycles = new ArrayList<LifeCycle>();
- try {
- for (String lifeCycle : lifeCycleValues) {
- lifeCycles.add(LifeCycle.valueOf(lifeCycle.toUpperCase().trim()));
- }
- } catch (IllegalArgumentException e) {
- throw new FalconCLIException("Invalid life cycle values: " + lifeCycles, e);
- }
- return lifeCycles;
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/client/src/main/java/org/apache/falcon/cli/FalconMetadataCLI.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/falcon/cli/FalconMetadataCLI.java b/client/src/main/java/org/apache/falcon/cli/FalconMetadataCLI.java
deleted file mode 100644
index 6487d41..0000000
--- a/client/src/main/java/org/apache/falcon/cli/FalconMetadataCLI.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/**
- * 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.commons.lang3.StringUtils;
-import org.apache.falcon.client.FalconCLIException;
-import org.apache.falcon.client.FalconClient;
-import org.apache.falcon.entity.v0.EntityType;
-import org.apache.falcon.metadata.RelationshipType;
-
-import java.io.PrintStream;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Metadata extension to Falcon Command Line Interface - wraps the RESTful API for Metadata.
- */
-public class FalconMetadataCLI extends FalconCLI {
-
- public static final AtomicReference<PrintStream> OUT = new AtomicReference<PrintStream>(System.out);
-
- // Discovery Commands
- public static final String DISCOVERY_OPT = "discovery";
- public static final String LIST_OPT = "list";
- public static final String RELATIONS_OPT = "relations";
- public static final String URL_OPTION = "url";
- public static final String NAME_OPT = "name";
-
- // Lineage Commands
- public static final String LINEAGE_OPT = "lineage";
- public static final String VERTEX_CMD = "vertex";
- public static final String VERTICES_CMD = "vertices";
- public static final String VERTEX_EDGES_CMD = "edges";
- public static final String PIPELINE_OPT = "pipeline";
- public static final String EDGE_CMD = "edge";
- public static final String ID_OPT = "id";
- public static final String KEY_OPT = "key";
- public static final String VALUE_OPT = "value";
- public static final String DIRECTION_OPT = "direction";
-
- public FalconMetadataCLI() throws Exception {
- super();
- }
-
- public Options createMetadataOptions() {
- Options metadataOptions = new Options();
-
- OptionGroup group = new OptionGroup();
- Option discovery = new Option(DISCOVERY_OPT, false, "Discover falcon metadata relations");
- Option lineage = new Option(LINEAGE_OPT, false, "Get falcon metadata lineage information");
- group.addOption(discovery);
- group.addOption(lineage);
- Option pipeline = new Option(PIPELINE_OPT, true,
- "Get lineage graph for the entities in a pipeline");
- metadataOptions.addOptionGroup(group);
-
- // Add discovery options
-
- Option list = new Option(LIST_OPT, false, "List all dimensions");
- Option relations = new Option(RELATIONS_OPT, false, "List all relations for a dimension");
- metadataOptions.addOption(list);
- metadataOptions.addOption(relations);
-
- Option url = new Option(URL_OPTION, true, "Falcon URL");
- Option type = new Option(TYPE_OPT, true, "Dimension type");
- Option name = new Option(NAME_OPT, true, "Dimension name");
- Option cluster = new Option(CLUSTER_OPT, true, "Cluster name");
- Option feed = new Option(FEED_OPT, true, "Feed Entity name");
- Option process = new Option(PROCESS_OPT, true, "Process Entity name");
- Option numResults = new Option(NUM_RESULTS_OPT, true,
- "Number of results to return per request");
-
- // Add lineage options
- metadataOptions.addOption(pipeline);
-
- metadataOptions.addOption(url);
- metadataOptions.addOption(type);
- metadataOptions.addOption(cluster);
- metadataOptions.addOption(name);
- metadataOptions.addOption(feed);
- metadataOptions.addOption(process);
- metadataOptions.addOption(numResults);
-
- Option vertex = new Option(VERTEX_CMD, false, "show the vertices");
- Option vertices = new Option(VERTICES_CMD, false, "show the vertices");
- Option vertexEdges = new Option(VERTEX_EDGES_CMD, false, "show the edges for a given vertex");
- Option edges = new Option(EDGE_CMD, false, "show the edges");
- Option id = new Option(ID_OPT, true, "vertex or edge id");
- Option key = new Option(KEY_OPT, true, "key property");
- Option value = new Option(VALUE_OPT, true, "value property");
- Option direction = new Option(DIRECTION_OPT, true, "edge direction property");
- Option debug = new Option(DEBUG_OPTION, false, "Use debug mode to see debugging statements on stdout");
-
- metadataOptions.addOption(vertex);
- metadataOptions.addOption(vertices);
- metadataOptions.addOption(vertexEdges);
- metadataOptions.addOption(edges);
- metadataOptions.addOption(id);
- metadataOptions.addOption(key);
- metadataOptions.addOption(value);
- metadataOptions.addOption(direction);
- metadataOptions.addOption(debug);
-
- Option doAs = new Option(FalconCLI.DO_AS_OPT, true, "doAs user");
- metadataOptions.addOption(doAs);
-
- return metadataOptions;
- }
-
- public void metadataCommand(CommandLine commandLine, FalconClient client) throws FalconCLIException {
- Set<String> optionsList = new HashSet<String>();
- for (Option option : commandLine.getOptions()) {
- optionsList.add(option.getOpt());
- }
-
- String result;
- String dimensionType = commandLine.getOptionValue(TYPE_OPT);
- String cluster = commandLine.getOptionValue(CLUSTER_OPT);
- String feed = commandLine.getOptionValue(FEED_OPT);
- String process = commandLine.getOptionValue(PROCESS_OPT);
- String dimensionName = commandLine.getOptionValue(NAME_OPT);
- String id = commandLine.getOptionValue(ID_OPT);
- String key = commandLine.getOptionValue(KEY_OPT);
- String value = commandLine.getOptionValue(VALUE_OPT);
- String direction = commandLine.getOptionValue(DIRECTION_OPT);
- String pipeline = commandLine.getOptionValue(PIPELINE_OPT);
- String doAsUser = commandLine.getOptionValue(FalconCLI.DO_AS_OPT);
- Integer numResults = parseIntegerInput(commandLine.getOptionValue(NUM_RESULTS_OPT), null, "numResults");
-
- if (optionsList.contains(LINEAGE_OPT)) {
- validatePipelineName(pipeline);
- result = client.getEntityLineageGraph(pipeline, doAsUser).getDotNotation();
- } else if (optionsList.contains(LIST_OPT)) {
- validateDimensionType(dimensionType.toUpperCase());
- if (!(dimensionType.toUpperCase())
- .equals(RelationshipType.REPLICATION_METRICS.name())) {
- result = client.getDimensionList(dimensionType, cluster, doAsUser);
- } else {
- String schedEntityType = null;
- String schedEntityName = null;
- if (StringUtils.isNotEmpty(feed)) {
- schedEntityType = EntityType.getEnum(FEED_OPT).name();
- schedEntityName = feed;
- } else if (StringUtils.isNotEmpty(process)) {
- schedEntityType = EntityType.getEnum(PROCESS_OPT).name();
- schedEntityName = process;
- }
- validateScheduleEntity(schedEntityType, schedEntityName);
-
- result = client.getReplicationMetricsDimensionList(schedEntityType, schedEntityName,
- numResults, doAsUser);
- }
- } else if (optionsList.contains(RELATIONS_OPT)) {
- validateDimensionType(dimensionType.toUpperCase());
- validateDimensionName(dimensionName, RELATIONS_OPT);
- result = client.getDimensionRelations(dimensionType, dimensionName, doAsUser);
- } else if (optionsList.contains(VERTEX_CMD)) {
- validateId(id);
- result = client.getVertex(id, doAsUser);
- } else if (optionsList.contains(VERTICES_CMD)) {
- validateVerticesCommand(key, value);
- result = client.getVertices(key, value, doAsUser);
- } else if (optionsList.contains(VERTEX_EDGES_CMD)) {
- validateVertexEdgesCommand(id, direction);
- result = client.getVertexEdges(id, direction, doAsUser);
- } else if (optionsList.contains(EDGE_CMD)) {
- validateId(id);
- result = client.getEdge(id, doAsUser);
- } else {
- throw new FalconCLIException("Invalid metadata command");
- }
-
- OUT.get().println(result);
- }
-
- private void validatePipelineName(String pipeline) throws FalconCLIException {
- if (StringUtils.isEmpty(pipeline)) {
- throw new FalconCLIException("Invalid value for pipeline");
- }
- }
-
- private void validateDimensionType(String dimensionType) throws FalconCLIException {
- if (StringUtils.isEmpty(dimensionType)
- || dimensionType.contains("INSTANCE")) {
- throw new FalconCLIException("Invalid value provided for queryParam \"type\" " + dimensionType);
- }
- try {
- RelationshipType.valueOf(dimensionType);
- } catch (IllegalArgumentException iae) {
- throw new FalconCLIException("Invalid value provided for queryParam \"type\" " + dimensionType);
- }
- }
-
- private void validateDimensionName(String dimensionName, String action) throws FalconCLIException {
- if (StringUtils.isEmpty(dimensionName)) {
- throw new FalconCLIException("Dimension ID cannot be empty or null for action " + action);
- }
- }
-
- private void validateScheduleEntity(String schedEntityType, String schedEntityName) throws FalconCLIException {
- if (StringUtils.isBlank(schedEntityType)) {
- throw new FalconCLIException("Entity must be schedulable type : -feed/process");
- }
-
- if (StringUtils.isBlank(schedEntityName)) {
- throw new FalconCLIException("Entity name is missing");
- }
- }
-
- private void validateId(String id) throws FalconCLIException {
- if (id == null || id.length() == 0) {
- throw new FalconCLIException("Missing argument: id");
- }
- }
-
- private void validateVerticesCommand(String key, String value) throws FalconCLIException {
- if (key == null || key.length() == 0) {
- throw new FalconCLIException("Missing argument: key");
- }
-
- if (value == null || value.length() == 0) {
- throw new FalconCLIException("Missing argument: value");
- }
- }
-
- private void validateVertexEdgesCommand(String id, String direction) throws FalconCLIException {
- if (id == null || id.length() == 0) {
- throw new FalconCLIException("Missing argument: id");
- }
-
- if (direction == null || direction.length() == 0) {
- throw new FalconCLIException("Missing argument: direction");
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/client/src/main/java/org/apache/falcon/client/FalconClient.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/falcon/client/FalconClient.java b/client/src/main/java/org/apache/falcon/client/FalconClient.java
index 10243f0..0aaf0ec 100644
--- a/client/src/main/java/org/apache/falcon/client/FalconClient.java
+++ b/client/src/main/java/org/apache/falcon/client/FalconClient.java
@@ -45,9 +45,8 @@ import javax.ws.rs.core.UriBuilder;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.util.TrustManagerUtils;
+import org.apache.falcon.FalconCLIConstants;
import org.apache.falcon.LifeCycle;
-import org.apache.falcon.cli.FalconCLI;
-import org.apache.falcon.cli.FalconMetadataCLI;
import org.apache.falcon.entity.v0.DateValidator;
import org.apache.falcon.entity.v0.Entity;
import org.apache.falcon.entity.v0.EntityType;
@@ -667,7 +666,7 @@ public class FalconClient extends AbstractFalconClient {
public LineageGraphResult getEntityLineageGraph(String pipelineName, String doAsUser) throws FalconCLIException {
MetadataOperations operation = MetadataOperations.LINEAGE;
ClientResponse clientResponse = new ResourceBuilder().path(operation.path).addQueryParam(DO_AS_OPT, doAsUser)
- .addQueryParam(FalconMetadataCLI.PIPELINE_OPT, pipelineName).call(operation);
+ .addQueryParam(FalconCLIConstants.PIPELINE_OPT, pipelineName).call(operation);
printClientResponse(clientResponse);
checkIfSuccessful(clientResponse);
return clientResponse.getEntity(LineageGraphResult.class);
@@ -861,18 +860,18 @@ public class FalconClient extends AbstractFalconClient {
WebResource resource = service.path(operation.path)
.path(schedEntityName)
.path(RelationshipType.REPLICATION_METRICS.getName())
- .path(FalconMetadataCLI.LIST_OPT);
+ .path(FalconCLIConstants.LIST_OPT);
if (StringUtils.isNotEmpty(schedEntityName)) {
- resource = resource.queryParam(FalconCLI.TYPE_OPT, schedEntityType);
+ resource = resource.queryParam(FalconCLIConstants.TYPE_OPT, schedEntityType);
}
if (numResults != null) {
- resource = resource.queryParam(FalconCLI.NUM_RESULTS_OPT, numResults.toString());
+ resource = resource.queryParam(FalconCLIConstants.NUM_RESULTS_OPT, numResults.toString());
}
if (StringUtils.isNotEmpty(doAsUser)) {
- resource = resource.queryParam(FalconCLI.DO_AS_OPT, doAsUser);
+ resource = resource.queryParam(FalconCLIConstants.DO_AS_OPT, doAsUser);
}
ClientResponse clientResponse = resource
@@ -897,14 +896,14 @@ public class FalconClient extends AbstractFalconClient {
case LIST:
resource = service.path(operation.path)
.path(dimensionType)
- .path(FalconMetadataCLI.LIST_OPT);
+ .path(FalconCLIConstants.LIST_OPT);
break;
case RELATIONS:
resource = service.path(operation.path)
.path(dimensionType)
.path(dimensionName)
- .path(FalconMetadataCLI.RELATIONS_OPT);
+ .path(FalconCLIConstants.RELATIONS_OPT);
break;
default:
@@ -912,11 +911,11 @@ public class FalconClient extends AbstractFalconClient {
}
if (!StringUtils.isEmpty(cluster)) {
- resource = resource.queryParam(FalconMetadataCLI.CLUSTER_OPT, cluster);
+ resource = resource.queryParam(FalconCLIConstants.CLUSTER_OPT, cluster);
}
if (StringUtils.isNotEmpty(doAsUser)) {
- resource = resource.queryParam(FalconCLI.DO_AS_OPT, doAsUser);
+ resource = resource.queryParam(FalconCLIConstants.DO_AS_OPT, doAsUser);
}
ClientResponse clientResponse = resource
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/client/src/test/java/org/apache/falcon/cli/TestCLIParser.java
----------------------------------------------------------------------
diff --git a/client/src/test/java/org/apache/falcon/cli/TestCLIParser.java b/client/src/test/java/org/apache/falcon/cli/TestCLIParser.java
deleted file mode 100644
index 6ac3e9f..0000000
--- a/client/src/test/java/org/apache/falcon/cli/TestCLIParser.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * 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.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-/**
- * Command parser for CLI.
- */
-public class TestCLIParser {
-
- @Test
- public void testEmptyParser() throws Exception {
- try {
- CLIParser parser = new CLIParser("falcon", new String[]{});
- CLIParser.Command c = parser.parse(new String[]{"a"});
- Assert.fail();
- } catch (ParseException ex) {
- // nop
- }
- }
-
- @Test
- public void testCommandParser() throws Exception {
- try {
- CLIParser parser = new CLIParser("oozie", new String[]{});
- parser.addCommand("a", "<A>", "AAAAA", new Options(), false);
- CLIParser.Command c = parser.parse(new String[]{"a", "b"});
- Assert.assertEquals("a", c.getName());
- Assert.assertEquals("b", c.getCommandLine().getArgs()[0]);
- } catch (ParseException ex) {
- Assert.fail();
- }
- }
-
- @Test
- public void testCommandParserX() throws Exception {
- Option opt = new Option("o", false, "O");
- Options opts = new Options();
- opts.addOption(opt);
- CLIParser parser = new CLIParser("test", new String[]{});
- parser.addCommand("c", "-X ",
- "(everything after '-X' are pass-through parameters)", opts,
- true);
- CLIParser.Command c = parser.parse("c -o -X -o c".split(" "));
- Assert.assertEquals("-X", c.getCommandLine().getArgList().get(0));
- Assert.assertEquals(3, c.getCommandLine().getArgList().size());
- }
-}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/common/src/main/java/org/apache/falcon/cliParser/CLIParser.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/falcon/cliParser/CLIParser.java b/common/src/main/java/org/apache/falcon/cliParser/CLIParser.java
new file mode 100644
index 0000000..9bff723
--- /dev/null
+++ b/common/src/main/java/org/apache/falcon/cliParser/CLIParser.java
@@ -0,0 +1,155 @@
+/**
+ * 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.cliParser;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.HelpFormatter;
+
+import java.io.PrintWriter;
+import java.text.MessageFormat;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+/**
+ * Cannibalized from Oozie CLIParser into Falcon
+ * Command line parser based on Apache common-cli 1.x that supports subcommands.
+ */
+public class CLIParser {
+ private static final String LEFT_PADDING = " ";
+
+ private String cliName;
+ private String[] cliHelp;
+ private Map<String, Options> commands = new LinkedHashMap<String, Options>();
+ private Map<String, Boolean> commandWithArgs = new LinkedHashMap<String, Boolean>();
+ private Map<String, String> commandsHelp = new LinkedHashMap<String, String>();
+
+ /**
+ * Create a parser.
+ *
+ * @param aCliName name of the parser, for help purposes.
+ * @param aCliHelp help for the CLI.
+ */
+ public CLIParser(String aCliName, String[] aCliHelp) {
+ this.cliName = aCliName;
+ this.cliHelp = aCliHelp.clone();
+ }
+
+ /**
+ * Add a command to the parser.
+ *
+ * @param command comand name.
+ * @param argsHelp command arguments help.
+ * @param commandHelp command description.
+ * @param commandOptions command options.
+ * @param hasArguments has args
+ */
+ public void addCommand(String command, String argsHelp, String commandHelp, Options commandOptions,
+ boolean hasArguments) {
+ String helpMsg = argsHelp + ((hasArguments) ? "<ARGS> " : "") + ": " + commandHelp;
+ commandsHelp.put(command, helpMsg);
+ commands.put(command, commandOptions);
+ commandWithArgs.put(command, hasArguments);
+ }
+
+ /**
+ * Bean that represents a parsed command.
+ */
+ public static final class Command {
+ private String name;
+ private CommandLine commandLine;
+
+ private Command(String name, CommandLine commandLine) {
+ this.name = name;
+ this.commandLine = commandLine;
+ }
+
+ /**
+ * Return the command name.
+ *
+ * @return the command name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Return the command line.
+ *
+ * @return the command line.
+ */
+ public CommandLine getCommandLine() {
+ return commandLine;
+ }
+ }
+
+ /**
+ * Parse a array of arguments into a command.
+ *
+ * @param args array of arguments.
+ * @return the parsed Command.
+ * @throws ParseException thrown if the arguments could not be parsed.
+ */
+ public Command parse(String[] args) throws ParseException {
+ if (args.length == 0) {
+ throw new ParseException("missing sub-command");
+ } else {
+ if (commands.containsKey(args[0])) {
+ GnuParser parser = new GnuParser();
+ String[] minusCommand = new String[args.length - 1];
+ System.arraycopy(args, 1, minusCommand, 0, minusCommand.length);
+ return new Command(args[0], parser.parse(commands.get(args[0]), minusCommand,
+ commandWithArgs.get(args[0])));
+ } else {
+ throw new ParseException(MessageFormat.format("invalid sub-command [{0}]", args[0]));
+ }
+ }
+ }
+
+ public String shortHelp() {
+ return "use 'help' sub-command for help details";
+ }
+
+ /**
+ * Print the help for the parser to standard output.
+ */
+ public void showHelp() {
+ PrintWriter pw = new PrintWriter(System.out);
+ pw.println("usage: ");
+ for (String s : cliHelp) {
+ pw.println(LEFT_PADDING + s);
+ }
+ pw.println();
+ HelpFormatter formatter = new HelpFormatter();
+ for (Map.Entry<String, Options> entry : commands.entrySet()) {
+ String s = LEFT_PADDING + cliName + " " + entry.getKey() + " ";
+ if (entry.getValue().getOptions().size() > 0) {
+ pw.println(s + "<OPTIONS> " + commandsHelp.get(entry.getKey()));
+ formatter.printOptions(pw, 100, entry.getValue(), s.length(), 3);
+ } else {
+ pw.println(s + commandsHelp.get(entry.getKey()));
+ }
+ pw.println();
+ }
+ pw.flush();
+ }
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/common/src/main/java/org/apache/falcon/tools/FalconStateStoreDBCLI.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/falcon/tools/FalconStateStoreDBCLI.java b/common/src/main/java/org/apache/falcon/tools/FalconStateStoreDBCLI.java
index df8194c..d56087a 100644
--- a/common/src/main/java/org/apache/falcon/tools/FalconStateStoreDBCLI.java
+++ b/common/src/main/java/org/apache/falcon/tools/FalconStateStoreDBCLI.java
@@ -21,7 +21,7 @@ import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
-import org.apache.falcon.cli.CLIParser;
+import org.apache.falcon.cliParser.CLIParser;
import org.apache.falcon.service.FalconJPAService;
import org.apache.falcon.util.BuildProperties;
import org.apache.falcon.util.StateStoreProperties;
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/common/src/test/java/cli/TestCLIParser.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/cli/TestCLIParser.java b/common/src/test/java/cli/TestCLIParser.java
new file mode 100644
index 0000000..164f531
--- /dev/null
+++ b/common/src/test/java/cli/TestCLIParser.java
@@ -0,0 +1,70 @@
+/**
+ * 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 cli;
+
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.falcon.cliParser.CLIParser;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Command parser for CLI.
+ */
+public class TestCLIParser {
+
+ @Test
+ public void testEmptyParser() throws Exception {
+ try {
+ CLIParser parser = new CLIParser("falcon", new String[]{});
+ CLIParser.Command c = parser.parse(new String[]{"a"});
+ Assert.fail();
+ } catch (ParseException ex) {
+ // nop
+ }
+ }
+
+ @Test
+ public void testCommandParser() throws Exception {
+ try {
+ CLIParser parser = new CLIParser("oozie", new String[]{});
+ parser.addCommand("a", "<A>", "AAAAA", new Options(), false);
+ CLIParser.Command c = parser.parse(new String[]{"a", "b"});
+ Assert.assertEquals("a", c.getName());
+ Assert.assertEquals("b", c.getCommandLine().getArgs()[0]);
+ } catch (ParseException ex) {
+ Assert.fail();
+ }
+ }
+
+ @Test
+ public void testCommandParserX() throws Exception {
+ Option opt = new Option("o", false, "O");
+ Options opts = new Options();
+ opts.addOption(opt);
+ CLIParser parser = new CLIParser("test", new String[]{});
+ parser.addCommand("c", "-X ",
+ "(everything after '-X' are pass-through parameters)", opts,
+ true);
+ CLIParser.Command c = parser.parse("c -o -X -o c".split(" "));
+ Assert.assertEquals("-X", c.getCommandLine().getArgList().get(0));
+ Assert.assertEquals(3, c.getCommandLine().getArgList().size());
+ }
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/webapp/pom.xml
----------------------------------------------------------------------
diff --git a/webapp/pom.xml b/webapp/pom.xml
index 06aa897..dad0581 100644
--- a/webapp/pom.xml
+++ b/webapp/pom.xml
@@ -274,6 +274,12 @@
<type>war</type>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.falcon</groupId>
+ <artifactId>falcon-cli</artifactId>
+ <version>0.10-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java b/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java
index 4805597..5ce8893 100644
--- a/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java
+++ b/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java
@@ -18,6 +18,7 @@
package org.apache.falcon.cli;
+import org.apache.falcon.FalconCLIConstants;
import org.apache.falcon.entity.v0.SchemaHelper;
import org.apache.falcon.metadata.RelationshipType;
import org.apache.falcon.resource.TestContext;
@@ -713,22 +714,21 @@ public class FalconCLIIT {
String feedName = overlay.get("outputFeedName");
String clusterName = overlay.get("cluster");
- Assert.assertEquals(executeWithURL(FalconCLI.ENTITY_CMD + " -" + FalconCLI.SCHEDULE_OPT + " -"
- + FalconCLI.TYPE_OPT + " process -" + FalconCLI.ENTITY_NAME_OPT + " " + processName),
- 0);
+ Assert.assertEquals(executeWithURL(FalconCLIConstants.ENTITY_CMD + " -" + FalconCLIConstants.SCHEDULE_OPT + " -"
+ + FalconCLIConstants.TYPE_OPT + " process -"
+ + FalconCLIConstants.ENTITY_NAME_OPT + " " + processName), 0);
- Assert.assertEquals(executeWithURL(FalconCLI.ENTITY_CMD + " -" + FalconCLI.SCHEDULE_OPT + " -"
- + FalconCLI.TYPE_OPT + " feed -" + FalconCLI.ENTITY_NAME_OPT + " " + feedName), 0);
+ Assert.assertEquals(executeWithURL(FalconCLIConstants.ENTITY_CMD + " -" + FalconCLIConstants.SCHEDULE_OPT + " -"
+ + FalconCLIConstants.TYPE_OPT + " feed -" + FalconCLIConstants.ENTITY_NAME_OPT + " " + feedName), 0);
OozieTestUtils.waitForProcessWFtoStart(context);
- String metadataListCommand = FalconCLI.METADATA_CMD + " -" + FalconMetadataCLI.LIST_OPT + " -"
- + FalconMetadataCLI.TYPE_OPT + " ";
- String metadataListCommandWithDoAs = FalconCLI.METADATA_CMD + " -doAs " + FalconTestUtil.TEST_USER_2 + " -"
- + FalconMetadataCLI.LIST_OPT + " -"
- + FalconMetadataCLI.TYPE_OPT + " ";
+ String metadataListCommand = FalconCLIConstants.METADATA_CMD + " -" + FalconCLIConstants.LIST_OPT + " -"
+ + FalconCLIConstants.TYPE_OPT + " ";
+ String metadataListCommandWithDoAs = FalconCLIConstants.METADATA_CMD + " -doAs " + FalconTestUtil.TEST_USER_2
+ + " -" + FalconCLIConstants.LIST_OPT + " -" + FalconCLIConstants.TYPE_OPT + " ";
- String clusterString = " -" + FalconMetadataCLI.CLUSTER_OPT + " " + clusterName;
+ String clusterString = " -" + FalconCLIConstants.CLUSTER_OPT + " " + clusterName;
Assert.assertEquals(executeWithURL(metadataListCommand + RelationshipType.CLUSTER_ENTITY.name()), 0);
Assert.assertEquals(executeWithURL(metadataListCommand + RelationshipType.PROCESS_ENTITY.name()), 0);
@@ -757,36 +757,36 @@ public class FalconCLIIT {
String feedName = overlay.get("outputFeedName");
String clusterName = overlay.get("cluster");
- Assert.assertEquals(executeWithURL(FalconCLI.ENTITY_CMD + " -" + FalconCLI.SCHEDULE_OPT + " -"
- + FalconCLI.TYPE_OPT + " process -" + FalconCLI.ENTITY_NAME_OPT + " " + processName),
- 0);
+ Assert.assertEquals(executeWithURL(FalconCLIConstants.ENTITY_CMD + " -" + FalconCLIConstants.SCHEDULE_OPT + " -"
+ + FalconCLIConstants.TYPE_OPT + " process -"
+ + FalconCLIConstants.ENTITY_NAME_OPT + " " + processName), 0);
- Assert.assertEquals(executeWithURL(FalconCLI.ENTITY_CMD + " -" + FalconCLI.SCHEDULE_OPT + " -"
- + FalconCLI.TYPE_OPT + " feed -" + FalconCLI.ENTITY_NAME_OPT + " " + feedName), 0);
+ Assert.assertEquals(executeWithURL(FalconCLIConstants.ENTITY_CMD + " -" + FalconCLIConstants.SCHEDULE_OPT + " -"
+ + FalconCLIConstants.TYPE_OPT + " feed -" + FalconCLIConstants.ENTITY_NAME_OPT + " " + feedName), 0);
OozieTestUtils.waitForProcessWFtoStart(context);
- String metadataRelationsCommand = FalconCLI.METADATA_CMD + " -" + FalconMetadataCLI.RELATIONS_OPT + " -"
- + FalconMetadataCLI.TYPE_OPT + " ";
+ String metadataRelationsCommand = FalconCLIConstants.METADATA_CMD + " -"
+ + FalconCLIConstants.RELATIONS_OPT + " -" + FalconCLIConstants.TYPE_OPT + " ";
- String metadataRelationsCommandWithDoAs = FalconCLI.METADATA_CMD + " -doAs " + FalconTestUtil.TEST_USER_2
- + " -" + FalconMetadataCLI.RELATIONS_OPT + " -"
- + FalconMetadataCLI.TYPE_OPT + " ";
+ String metadataRelationsCommandWithDoAs = FalconCLIConstants.METADATA_CMD
+ + " -doAs " + FalconTestUtil.TEST_USER_2 + " -" + FalconCLIConstants.RELATIONS_OPT + " -"
+ + FalconCLIConstants.TYPE_OPT + " ";
Assert.assertEquals(executeWithURL(metadataRelationsCommand + RelationshipType.CLUSTER_ENTITY.name()
- + " -" + FalconMetadataCLI.NAME_OPT + " " + clusterName), 0);
+ + " -" + FalconCLIConstants.NAME_OPT + " " + clusterName), 0);
Assert.assertEquals(executeWithURL(metadataRelationsCommand + RelationshipType.PROCESS_ENTITY.name()
- + " -" + FalconMetadataCLI.NAME_OPT + " " + processName), 0);
+ + " -" + FalconCLIConstants.NAME_OPT + " " + processName), 0);
// with doAs
Assert.assertEquals(executeWithURL(metadataRelationsCommandWithDoAs + RelationshipType.PROCESS_ENTITY.name()
- + " -" + FalconMetadataCLI.NAME_OPT + " " + processName), 0);
+ + " -" + FalconCLIConstants.NAME_OPT + " " + processName), 0);
Assert.assertEquals(executeWithURL(metadataRelationsCommand + "feed -"
- + FalconMetadataCLI.NAME_OPT + " " + clusterName), -1);
+ + FalconCLIConstants.NAME_OPT + " " + clusterName), -1);
Assert.assertEquals(executeWithURL(metadataRelationsCommand + "invalid -"
- + FalconMetadataCLI.NAME_OPT + " " + clusterName), -1);
+ + FalconCLIConstants.NAME_OPT + " " + clusterName), -1);
Assert.assertEquals(executeWithURL(metadataRelationsCommand + RelationshipType.CLUSTER_ENTITY.name()), -1);
}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/webapp/src/test/java/org/apache/falcon/resource/TestContext.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/resource/TestContext.java b/webapp/src/test/java/org/apache/falcon/resource/TestContext.java
index e3fe8bb..f84559f 100644
--- a/webapp/src/test/java/org/apache/falcon/resource/TestContext.java
+++ b/webapp/src/test/java/org/apache/falcon/resource/TestContext.java
@@ -27,6 +27,7 @@ import com.sun.jersey.client.urlconnection.HTTPSProperties;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.util.TrustManagerUtils;
+import org.apache.falcon.FalconCLIConstants;
import org.apache.falcon.FalconException;
import org.apache.falcon.FalconRuntimException;
import org.apache.falcon.catalog.HiveCatalogService;
@@ -304,7 +305,7 @@ public class TestContext extends AbstractTestContext {
}
if (StringUtils.isNotEmpty(doAsUser)) {
- resource = resource.queryParam(FalconCLI.DO_AS_OPT, doAsUser);
+ resource = resource.queryParam(FalconCLIConstants.DO_AS_OPT, doAsUser);
}
if (StringUtils.isNotEmpty(properties)) {
@@ -408,7 +409,7 @@ public class TestContext extends AbstractTestContext {
WebResource resource = this.service.path("api/entities/submit/" + entityType.name().toLowerCase());
if (StringUtils.isNotEmpty(doAsUser)) {
- resource = resource.queryParam(FalconCLI.DO_AS_OPT, doAsUser);
+ resource = resource.queryParam(FalconCLIConstants.DO_AS_OPT, doAsUser);
}
return resource.header("Cookie", getAuthenticationToken())
[2/2] falcon git commit: FALCON-1895 Refactoring of FalconCLI and
FalconClient
Posted by pe...@apache.org.
FALCON-1895 Refactoring of FalconCLI and FalconClient
Author: Praveen Adlakha <ad...@gmail.com>
Reviewers: Peeyush Bishnoi<pe...@apache.org>, Balu<bv...@hortonworks.com>, Sowmya<sr...@hortonworks.com>
Closes #94 from PraveenAdlakha/1895 and squashes the following commits:
00a65a2 [Praveen Adlakha] merge conflicts resolved
d069466 [Praveen Adlakha] sync from upstream
4e79efc [Praveen Adlakha] extra space removed
d8bc106 [Praveen Adlakha] FALCON-1895 Refactoring of FalconCLI and FalconClient
Project: http://git-wip-us.apache.org/repos/asf/falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/falcon/commit/6655e90a
Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/6655e90a
Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/6655e90a
Branch: refs/heads/master
Commit: 6655e90a7b3990cbe8dffd2e20d3657c249b123e
Parents: 3e22a77
Author: Praveen Adlakha <ad...@gmail.com>
Authored: Wed Apr 13 21:09:37 2016 +0530
Committer: peeyush b <pb...@hortonworks.com>
Committed: Wed Apr 13 21:09:37 2016 +0530
----------------------------------------------------------------------
cli/pom.xml | 15 +-
.../org/apache/falcon/cli/FalconAdminCLI.java | 111 ++++++
.../java/org/apache/falcon/cli/FalconCLI.java | 283 +++++++++++++++
.../org/apache/falcon/cli/FalconEntityCLI.java | 362 +++++++++++++++++++
.../apache/falcon/cli/FalconInstanceCLI.java | 340 +++++++++++++++++
.../apache/falcon/cli/FalconMetadataCLI.java | 256 +++++++++++++
.../org/apache/falcon/FalconCLIConstants.java | 76 ++++
.../java/org/apache/falcon/cli/CLIParser.java | 155 --------
.../org/apache/falcon/cli/FalconAdminCLI.java | 109 ------
.../java/org/apache/falcon/cli/FalconCLI.java | 318 ----------------
.../org/apache/falcon/cli/FalconEntityCLI.java | 360 ------------------
.../apache/falcon/cli/FalconInstanceCLI.java | 336 -----------------
.../apache/falcon/cli/FalconMetadataCLI.java | 256 -------------
.../org/apache/falcon/client/FalconClient.java | 21 +-
.../org/apache/falcon/cli/TestCLIParser.java | 69 ----
.../org/apache/falcon/cliParser/CLIParser.java | 155 ++++++++
.../falcon/tools/FalconStateStoreDBCLI.java | 2 +-
common/src/test/java/cli/TestCLIParser.java | 70 ++++
webapp/pom.xml | 6 +
.../java/org/apache/falcon/cli/FalconCLIIT.java | 52 +--
.../org/apache/falcon/resource/TestContext.java | 5 +-
21 files changed, 1710 insertions(+), 1647 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/cli/pom.xml
----------------------------------------------------------------------
diff --git a/cli/pom.xml b/cli/pom.xml
index 408c6ee..ff4a16b 100644
--- a/cli/pom.xml
+++ b/cli/pom.xml
@@ -53,10 +53,7 @@
</profiles>
<dependencies>
- <dependency>
- <groupId>org.apache.falcon</groupId>
- <artifactId>falcon-client</artifactId>
- </dependency>
+
<dependency>
<groupId>commons-net</groupId>
@@ -142,6 +139,16 @@
<artifactId>spring-beans</artifactId>
<version>4.0.3.RELEASE</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.falcon</groupId>
+ <artifactId>falcon-client</artifactId>
+ <version>0.10-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.falcon</groupId>
+ <artifactId>falcon-common</artifactId>
+ <version>0.10-SNAPSHOT</version>
+ </dependency>
</dependencies>
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/cli/src/main/java/org/apache/falcon/cli/FalconAdminCLI.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/falcon/cli/FalconAdminCLI.java b/cli/src/main/java/org/apache/falcon/cli/FalconAdminCLI.java
new file mode 100644
index 0000000..56cc5b9
--- /dev/null
+++ b/cli/src/main/java/org/apache/falcon/cli/FalconAdminCLI.java
@@ -0,0 +1,111 @@
+/**
+ * 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.FalconCLIConstants;
+import org.apache.falcon.client.FalconCLIException;
+import org.apache.falcon.client.FalconClient;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Admin extension to Falcon Command Line Interface - wraps the RESTful API for admin commands.
+ */
+public class FalconAdminCLI extends FalconCLI {
+
+ private static final String STACK_OPTION = "stack";
+
+ public FalconAdminCLI() throws Exception {
+ super();
+ }
+
+ public Options createAdminOptions() {
+ Options adminOptions = new Options();
+ Option url = new Option(FalconCLIConstants.URL_OPTION, true, "Falcon URL");
+ adminOptions.addOption(url);
+
+ OptionGroup group = new OptionGroup();
+ Option status = new Option(FalconCLIConstants.STATUS_OPT, false,
+ "show the current system status");
+ Option version = new Option(FalconCLIConstants.VERSION_OPT, false,
+ "show Falcon server build version");
+ Option stack = new Option(STACK_OPTION, false,
+ "show the thread stack dump");
+ Option doAs = new Option(FalconCLIConstants.DO_AS_OPT, true,
+ "doAs user");
+ Option help = new Option("help", false, "show Falcon help");
+ Option debug = new Option(FalconCLIConstants.DEBUG_OPTION, false,
+ "Use debug mode to see debugging statements on stdout");
+ group.addOption(status);
+ group.addOption(version);
+ group.addOption(stack);
+ group.addOption(help);
+
+ adminOptions.addOptionGroup(group);
+ adminOptions.addOption(doAs);
+ adminOptions.addOption(debug);
+ return adminOptions;
+ }
+
+ public int adminCommand(CommandLine commandLine, FalconClient client,
+ String falconUrl) throws FalconCLIException, IOException {
+ String result;
+ Set<String> optionsList = new HashSet<String>();
+ for (Option option : commandLine.getOptions()) {
+ optionsList.add(option.getOpt());
+ }
+
+ String doAsUser = commandLine.getOptionValue(FalconCLIConstants.DO_AS_OPT);
+
+ if (optionsList.contains(STACK_OPTION)) {
+ result = client.getThreadDump(doAsUser);
+ OUT.get().println(result);
+ }
+
+ int exitValue = 0;
+ if (optionsList.contains(FalconCLIConstants.STATUS_OPT)) {
+ try {
+ int status = client.getStatus(doAsUser);
+ if (status != 200) {
+ ERR.get().println("Falcon server is not fully operational (on " + falconUrl + "). "
+ + "Please check log files.");
+ exitValue = status;
+ } else {
+ OUT.get().println("Falcon server is running (on " + falconUrl + ")");
+ }
+ } catch (Exception e) {
+ ERR.get().println("Falcon server doesn't seem to be running on " + falconUrl);
+ exitValue = -1;
+ }
+ } else if (optionsList.contains(FalconCLIConstants.VERSION_OPT)) {
+ result = client.getVersion(doAsUser);
+ OUT.get().println("Falcon server build version: " + result);
+ } else if (optionsList.contains(FalconCLIConstants.HELP_CMD)) {
+ OUT.get().println("Falcon Help");
+ }
+ return exitValue;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/cli/src/main/java/org/apache/falcon/cli/FalconCLI.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/falcon/cli/FalconCLI.java b/cli/src/main/java/org/apache/falcon/cli/FalconCLI.java
new file mode 100644
index 0000000..a414c94
--- /dev/null
+++ b/cli/src/main/java/org/apache/falcon/cli/FalconCLI.java
@@ -0,0 +1,283 @@
+/**
+ * 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 com.sun.jersey.api.client.ClientHandlerException;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.falcon.FalconCLIConstants;
+import org.apache.falcon.cliParser.CLIParser;
+import org.apache.falcon.client.FalconCLIException;
+import org.apache.falcon.client.FalconClient;
+import org.apache.falcon.entity.v0.EntityType;
+import org.apache.falcon.resource.EntityList;
+import org.apache.falcon.resource.InstancesResult;
+import org.apache.falcon.resource.InstancesSummaryResult;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Falcon Command Line Interface - wraps the RESTful API.
+ */
+public class FalconCLI {
+
+ public static final AtomicReference<PrintStream> ERR = new AtomicReference<PrintStream>(System.err);
+ public static final AtomicReference<PrintStream> OUT = new AtomicReference<PrintStream>(System.out);
+
+ private static final String FALCON_URL = "FALCON_URL";
+ private final Properties clientProperties;
+
+ public FalconCLI() throws Exception {
+ clientProperties = getClientProperties();
+ }
+
+ /**
+ * Entry point for the Falcon CLI when invoked from the command line. Upon
+ * completion this method exits the JVM with '0' (success) or '-1'
+ * (failure).
+ *
+ * @param args options and arguments for the Falcon CLI.
+ */
+ public static void main(final String[] args) throws Exception {
+ System.exit(new FalconCLI().run(args));
+ }
+
+ // TODO help and headers
+ private static final String[] FALCON_HELP = { "the env variable '" + FALCON_URL
+ + "' is used as default value for the '-"
+ + FalconCLIConstants.URL_OPTION + "' option",
+ "custom headers for Falcon web services can be specified using '-D"
+ + FalconClient.WS_HEADER_PREFIX + "NAME=VALUE'", };
+ /**
+ * Run a CLI programmatically.
+ * <p/>
+ * It does not exit the JVM.
+ * <p/>
+ * A CLI instance can be used only once.
+ *
+ * @param args options and arguments for the Oozie CLI.
+ * @return '0' (success), '-1' (failure).
+ */
+ public synchronized int run(final String[] args) throws Exception {
+
+ CLIParser parser = new CLIParser("falcon", FALCON_HELP);
+
+ FalconAdminCLI adminCLI = new FalconAdminCLI();
+ FalconEntityCLI entityCLI = new FalconEntityCLI();
+ FalconInstanceCLI instanceCLI = new FalconInstanceCLI();
+ FalconMetadataCLI metadataCLI = new FalconMetadataCLI();
+
+ parser.addCommand(FalconCLIConstants.ADMIN_CMD, "", "admin operations", adminCLI.createAdminOptions(), true);
+ parser.addCommand(FalconCLIConstants.HELP_CMD, "", "display usage", new Options(), false);
+ parser.addCommand(FalconCLIConstants.ENTITY_CMD, "",
+ "Entity operations like submit, suspend, resume, delete, status, definition, submitAndSchedule",
+ entityCLI.createEntityOptions(), false);
+ parser.addCommand(FalconCLIConstants.INSTANCE_CMD, "",
+ "Process instances operations like running, status, kill, suspend, resume, rerun, logs",
+ instanceCLI.createInstanceOptions(), false);
+ parser.addCommand(FalconCLIConstants.METADATA_CMD, "", "Metadata operations like list, relations",
+ metadataCLI.createMetadataOptions(), true);
+ parser.addCommand(FalconCLIConstants.VERSION_OPT, "", "show client version", new Options(), false);
+
+ try {
+ CLIParser.Command command = parser.parse(args);
+ int exitValue = 0;
+ if (command.getName().equals(FalconCLIConstants.HELP_CMD)) {
+ parser.showHelp();
+ } else {
+ CommandLine commandLine = command.getCommandLine();
+ String falconUrl = getFalconEndpoint(commandLine);
+ FalconClient client = new FalconClient(falconUrl, clientProperties);
+
+ setDebugMode(client, commandLine.hasOption(FalconCLIConstants.DEBUG_OPTION));
+ if (command.getName().equals(FalconCLIConstants.ADMIN_CMD)) {
+ exitValue = adminCLI.adminCommand(commandLine, client, falconUrl);
+ } else if (command.getName().equals(FalconCLIConstants.ENTITY_CMD)) {
+ entityCLI.entityCommand(commandLine, client);
+ } else if (command.getName().equals(FalconCLIConstants.INSTANCE_CMD)) {
+ instanceCLI.instanceCommand(commandLine, client);
+ } else if (command.getName().equals(FalconCLIConstants.METADATA_CMD)) {
+ metadataCLI.metadataCommand(commandLine, client);
+ }
+ }
+ return exitValue;
+ } catch (ParseException ex) {
+ ERR.get().println("Invalid sub-command: " + ex.getMessage());
+ ERR.get().println();
+ ERR.get().println(parser.shortHelp());
+ ERR.get().println("Stacktrace:");
+ ex.printStackTrace();
+ return -1;
+ } catch (ClientHandlerException ex) {
+ ERR.get().print("Unable to connect to Falcon server, "
+ + "please check if the URL is correct and Falcon server is up and running\n");
+ ERR.get().println("Stacktrace:");
+ ex.printStackTrace();
+ return -1;
+ } catch (FalconCLIException e) {
+ ERR.get().println("ERROR: " + e.getMessage());
+ return -1;
+ } catch (Exception ex) {
+ ERR.get().println("Stacktrace:");
+ ex.printStackTrace();
+ return -1;
+ }
+ }
+
+ protected Integer parseIntegerInput(String optionValue, Integer defaultVal, String optionName)
+ throws FalconCLIException {
+ Integer integer = defaultVal;
+ if (optionValue != null) {
+ try {
+ return Integer.parseInt(optionValue);
+ } catch (NumberFormatException e) {
+ throw new FalconCLIException("Input value provided for queryParam \""+ optionName
+ +"\" is not a valid Integer");
+ }
+ }
+ return integer;
+ }
+
+ protected void validateEntityTypeForSummary(String type) throws FalconCLIException {
+ EntityType entityType = EntityType.getEnum(type);
+ if (!entityType.isSchedulable()) {
+ throw new FalconCLIException("Invalid entity type " + entityType
+ + " for EntitySummary API. Valid options are feed or process");
+ }
+ }
+
+ protected void validateNotEmpty(String paramVal, String paramName) throws FalconCLIException {
+ if (StringUtils.isBlank(paramVal)) {
+ throw new FalconCLIException("Missing argument : " + paramName);
+ }
+ }
+
+ protected void validateSortOrder(String sortOrder) throws FalconCLIException {
+ if (!StringUtils.isBlank(sortOrder)) {
+ if (!sortOrder.equalsIgnoreCase("asc") && !sortOrder.equalsIgnoreCase("desc")) {
+ throw new FalconCLIException("Value for param sortOrder should be \"asc\" or \"desc\". It is : "
+ + sortOrder);
+ }
+ }
+ }
+
+ protected String getColo(String colo) throws FalconCLIException, IOException {
+ if (colo == null) {
+ Properties prop = getClientProperties();
+ colo = prop.getProperty(FalconCLIConstants.CURRENT_COLO, "*");
+ }
+ return colo;
+ }
+
+ protected void validateFilterBy(String filterBy, String filterType) throws FalconCLIException {
+ if (StringUtils.isEmpty(filterBy)) {
+ return;
+ }
+ String[] filterSplits = filterBy.split(",");
+ for (String s : filterSplits) {
+ String[] tempKeyVal = s.split(":", 2);
+ try {
+ if (filterType.equals("entity")) {
+ EntityList.EntityFilterByFields.valueOf(tempKeyVal[0].toUpperCase());
+ } else if (filterType.equals("instance")) {
+ InstancesResult.InstanceFilterFields.valueOf(tempKeyVal[0].toUpperCase());
+ }else if (filterType.equals("summary")) {
+ InstancesSummaryResult.InstanceSummaryFilterFields.valueOf(tempKeyVal[0].toUpperCase());
+ } else {
+ throw new IllegalArgumentException("Invalid API call: filterType is not valid");
+ }
+ } catch (IllegalArgumentException ie) {
+ throw new FalconCLIException("Invalid filterBy argument : " + tempKeyVal[0] + " in : " + s);
+ }
+ }
+ }
+
+ protected void validateOrderBy(String orderBy, String action) throws FalconCLIException {
+ if (StringUtils.isBlank(orderBy)) {
+ return;
+ }
+ if (action.equals("instance")) {
+ if (Arrays.asList(new String[]{"status", "cluster", "starttime", "endtime"})
+ .contains(orderBy.toLowerCase())) {
+ return;
+ }
+ } else if (action.equals("entity")) {
+ if (Arrays.asList(new String[] {"type", "name"}).contains(orderBy.toLowerCase())) {
+ return;
+ }
+ } else if (action.equals("summary")) {
+ if (Arrays.asList(new String[]{"cluster"})
+ .contains(orderBy.toLowerCase())) {
+ return;
+ }
+ }
+ throw new FalconCLIException("Invalid orderBy argument : " + orderBy);
+ }
+
+ protected String getFalconEndpoint(CommandLine commandLine) throws FalconCLIException, IOException {
+ String url = commandLine.getOptionValue(FalconCLIConstants.URL_OPTION);
+ if (url == null) {
+ url = System.getenv(FALCON_URL);
+ }
+ if (url == null) {
+ if (clientProperties.containsKey("falcon.url")) {
+ url = clientProperties.getProperty("falcon.url");
+ }
+ }
+ if (url == null) {
+ throw new FalconCLIException("Failed to get falcon url from cmdline, or environment or client properties");
+ }
+
+ return url;
+ }
+
+ private void setDebugMode(FalconClient client, boolean debugOpt) {
+ String debug = System.getenv(FalconCLIConstants.ENV_FALCON_DEBUG);
+ if (debugOpt) { // CLI argument "-debug" used
+ client.setDebugMode(true);
+ } else if (StringUtils.isNotBlank(debug)) {
+ System.out.println(FalconCLIConstants.ENV_FALCON_DEBUG + ": " + debug);
+ if (debug.trim().toLowerCase().equals("true")) {
+ client.setDebugMode(true);
+ }
+ }
+ }
+
+ private Properties getClientProperties() throws IOException {
+ InputStream inputStream = null;
+ try {
+ inputStream = FalconCLI.class.getResourceAsStream(FalconCLIConstants.CLIENT_PROPERTIES);
+ Properties prop = new Properties();
+ if (inputStream != null) {
+ prop.load(inputStream);
+ }
+ return prop;
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/cli/src/main/java/org/apache/falcon/cli/FalconEntityCLI.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/falcon/cli/FalconEntityCLI.java b/cli/src/main/java/org/apache/falcon/cli/FalconEntityCLI.java
new file mode 100644
index 0000000..fa71d67
--- /dev/null
+++ b/cli/src/main/java/org/apache/falcon/cli/FalconEntityCLI.java
@@ -0,0 +1,362 @@
+/**
+ * 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.commons.lang3.StringUtils;
+import org.apache.falcon.FalconCLIConstants;
+import org.apache.falcon.ResponseHelper;
+import org.apache.falcon.client.FalconCLIException;
+import org.apache.falcon.client.FalconClient;
+import org.apache.falcon.entity.v0.EntityType;
+import org.apache.falcon.entity.v0.SchemaHelper;
+import org.apache.falcon.resource.EntityList;
+import org.apache.falcon.resource.FeedLookupResult;
+import org.apache.falcon.resource.SchedulableEntityInstanceResult;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Entity extension to Falcon Command Line Interface - wraps the RESTful API for entities.
+ */
+public class FalconEntityCLI extends FalconCLI {
+
+ private static final String SUBMIT_OPT = "submit";
+ private static final String UPDATE_OPT = "update";
+ private static final String DELETE_OPT = "delete";
+ private static final String SUBMIT_AND_SCHEDULE_OPT = "submitAndSchedule";
+ private static final String VALIDATE_OPT = "validate";
+ private static final String DEFINITION_OPT = "definition";
+ public static final String SLA_MISS_ALERT_OPT = "slaAlert";
+
+ private static final String LOOKUP_OPT = "lookup";
+ private static final String PATH_OPT = "path";
+ private static final String TOUCH_OPT = "touch";
+ private static final String PROPS_OPT = "properties";
+ private static final String FIELDS_OPT = "fields";
+ private static final String TAGS_OPT = "tags";
+ private static final String NUM_INSTANCES_OPT = "numInstances";
+ private static final String NAMESEQ_OPT = "nameseq";
+ private static final String TAGKEYS_OPT = "tagkeys";
+ private static final String SHOWSCHEDULER_OPT = "showScheduler";
+
+ public FalconEntityCLI() throws Exception {
+ super();
+ }
+
+ public Options createEntityOptions() {
+
+ Options entityOptions = new Options();
+
+ Option submit = new Option(SUBMIT_OPT, false,
+ "Submits an entity xml to Falcon");
+ Option update = new Option(UPDATE_OPT, false,
+ "Updates an existing entity xml");
+ Option schedule = new Option(FalconCLIConstants.SCHEDULE_OPT, false,
+ "Schedules a submited entity in Falcon");
+ Option suspend = new Option(FalconCLIConstants.SUSPEND_OPT, false,
+ "Suspends a running entity in Falcon");
+ Option resume = new Option(FalconCLIConstants.RESUME_OPT, false,
+ "Resumes a suspended entity in Falcon");
+ Option delete = new Option(DELETE_OPT, false,
+ "Deletes an entity in Falcon, and kills its instance from workflow engine");
+ Option submitAndSchedule = new Option(SUBMIT_AND_SCHEDULE_OPT, false,
+ "Submits and entity to Falcon and schedules it immediately");
+ Option validate = new Option(VALIDATE_OPT, false,
+ "Validates an entity based on the entity type");
+ Option status = new Option(FalconCLIConstants.STATUS_OPT, false,
+ "Gets the status of entity");
+ Option definition = new Option(DEFINITION_OPT, false,
+ "Gets the Definition of entity");
+ Option dependency = new Option(FalconCLIConstants.DEPENDENCY_OPT, false,
+ "Gets the dependencies of entity");
+ Option list = new Option(FalconCLIConstants.LIST_OPT, false,
+ "List entities registered for a type");
+ Option lookup = new Option(LOOKUP_OPT, false, "Lookup a feed given its instance's path");
+ Option slaAlert = new Option(SLA_MISS_ALERT_OPT, false, "Get missing feed instances which missed SLA");
+ Option entitySummary = new Option(FalconCLIConstants.SUMMARY_OPT, false,
+ "Get summary of instances for list of entities");
+ Option touch = new Option(TOUCH_OPT, false,
+ "Force update the entity in workflow engine(even without any changes to entity)");
+
+ OptionGroup group = new OptionGroup();
+ group.addOption(submit);
+ group.addOption(update);
+ group.addOption(schedule);
+ group.addOption(suspend);
+ group.addOption(resume);
+ group.addOption(delete);
+ group.addOption(submitAndSchedule);
+ group.addOption(validate);
+ group.addOption(status);
+ group.addOption(definition);
+ group.addOption(dependency);
+ group.addOption(list);
+ group.addOption(lookup);
+ group.addOption(slaAlert);
+ group.addOption(entitySummary);
+ group.addOption(touch);
+
+ Option url = new Option(FalconCLIConstants.URL_OPTION, true, "Falcon URL");
+ Option entityType = new Option(FalconCLIConstants.TYPE_OPT, true,
+ "Entity type, can be cluster, feed or process xml");
+ Option filePath = new Option(FalconCLIConstants.FILE_PATH_OPT, true,
+ "Path to entity xml file");
+ Option entityName = new Option(FalconCLIConstants.ENTITY_NAME_OPT, true,
+ "Entity type, can be cluster, feed or process xml");
+ Option start = new Option(FalconCLIConstants.START_OPT, true, "Start time is optional for summary");
+ Option end = new Option(FalconCLIConstants.END_OPT, true, "End time is optional for summary");
+ Option colo = new Option(FalconCLIConstants.COLO_OPT, true, "Colo name");
+ Option cluster = new Option(FalconCLIConstants.CLUSTER_OPT, true, "Cluster name");
+ colo.setRequired(false);
+ Option fields = new Option(FIELDS_OPT, true, "Entity fields to show for a request");
+ Option filterBy = new Option(FalconCLIConstants.FILTER_BY_OPT, true,
+ "Filter returned entities by the specified status");
+ Option filterTags = new Option(TAGS_OPT, true, "Filter returned entities by the specified tags");
+ Option nameSubsequence = new Option(NAMESEQ_OPT, true, "Subsequence of entity name");
+ Option tagKeywords = new Option(TAGKEYS_OPT, true, "Keywords in tags");
+ Option orderBy = new Option(FalconCLIConstants.ORDER_BY_OPT, true,
+ "Order returned entities by this field");
+ Option sortOrder = new Option(FalconCLIConstants.SORT_ORDER_OPT, true, "asc or desc order for results");
+ Option offset = new Option(FalconCLIConstants.OFFSET_OPT, true,
+ "Start returning entities from this offset");
+ Option numResults = new Option(FalconCLIConstants.NUM_RESULTS_OPT, true,
+ "Number of results to return per request");
+ Option numInstances = new Option(NUM_INSTANCES_OPT, true,
+ "Number of instances to return per entity summary request");
+ Option path = new Option(PATH_OPT, true, "Path for a feed's instance");
+ Option skipDryRun = new Option(FalconCLIConstants.SKIPDRYRUN_OPT, false, "skip dry run in workflow engine");
+ Option doAs = new Option(FalconCLIConstants.DO_AS_OPT, true, "doAs user");
+ Option userProps = new Option(PROPS_OPT, true, "User supplied comma separated key value properties");
+ Option showScheduler = new Option(SHOWSCHEDULER_OPT, false, "To return the scheduler "
+ + "on which the entity is scheduled.");
+ Option debug = new Option(FalconCLIConstants.DEBUG_OPTION, false,
+ "Use debug mode to see debugging statements on stdout");
+
+ entityOptions.addOption(url);
+ entityOptions.addOption(path);
+ entityOptions.addOptionGroup(group);
+ entityOptions.addOption(entityType);
+ entityOptions.addOption(entityName);
+ entityOptions.addOption(filePath);
+ entityOptions.addOption(colo);
+ entityOptions.addOption(cluster);
+ entityOptions.addOption(start);
+ entityOptions.addOption(end);
+ entityOptions.addOption(fields);
+ entityOptions.addOption(filterBy);
+ entityOptions.addOption(filterTags);
+ entityOptions.addOption(nameSubsequence);
+ entityOptions.addOption(tagKeywords);
+ entityOptions.addOption(orderBy);
+ entityOptions.addOption(sortOrder);
+ entityOptions.addOption(offset);
+ entityOptions.addOption(numResults);
+ entityOptions.addOption(numInstances);
+ entityOptions.addOption(skipDryRun);
+ entityOptions.addOption(doAs);
+ entityOptions.addOption(userProps);
+ entityOptions.addOption(debug);
+ entityOptions.addOption(showScheduler);
+
+ return entityOptions;
+ }
+
+ public void entityCommand(CommandLine commandLine, FalconClient client) throws FalconCLIException, IOException {
+ Set<String> optionsList = new HashSet<String>();
+ for (Option option : commandLine.getOptions()) {
+ optionsList.add(option.getOpt());
+ }
+
+ String result = null;
+ String entityType = commandLine.getOptionValue(FalconCLIConstants.TYPE_OPT);
+ String entityName = commandLine.getOptionValue(FalconCLIConstants.ENTITY_NAME_OPT);
+ String filePath = commandLine.getOptionValue(FalconCLIConstants.FILE_PATH_OPT);
+ String colo = commandLine.getOptionValue(FalconCLIConstants.COLO_OPT);
+ colo = getColo(colo);
+ String cluster = commandLine.getOptionValue(FalconCLIConstants.CLUSTER_OPT);
+ String start = commandLine.getOptionValue(FalconCLIConstants.START_OPT);
+ String end = commandLine.getOptionValue(FalconCLIConstants.END_OPT);
+ String orderBy = commandLine.getOptionValue(FalconCLIConstants.ORDER_BY_OPT);
+ String sortOrder = commandLine.getOptionValue(FalconCLIConstants.SORT_ORDER_OPT);
+ String filterBy = commandLine.getOptionValue(FalconCLIConstants.FILTER_BY_OPT);
+ String filterTags = commandLine.getOptionValue(TAGS_OPT);
+ String nameSubsequence = commandLine.getOptionValue(NAMESEQ_OPT);
+ String tagKeywords = commandLine.getOptionValue(TAGKEYS_OPT);
+ String fields = commandLine.getOptionValue(FIELDS_OPT);
+ String feedInstancePath = commandLine.getOptionValue(PATH_OPT);
+ Integer offset = parseIntegerInput(commandLine.getOptionValue(FalconCLIConstants.OFFSET_OPT), 0, "offset");
+ Integer numResults = parseIntegerInput(commandLine.getOptionValue(FalconCLIConstants.NUM_RESULTS_OPT),
+ null, "numResults");
+ String doAsUser = commandLine.getOptionValue(FalconCLIConstants.DO_AS_OPT);
+
+ Integer numInstances = parseIntegerInput(commandLine.getOptionValue(NUM_INSTANCES_OPT), 7, "numInstances");
+ Boolean skipDryRun = null;
+ if (optionsList.contains(FalconCLIConstants.SKIPDRYRUN_OPT)) {
+ skipDryRun = true;
+ }
+
+ String userProps = commandLine.getOptionValue(PROPS_OPT);
+ boolean showScheduler = false;
+ if (optionsList.contains(SHOWSCHEDULER_OPT)) {
+ showScheduler = true;
+ }
+
+ EntityType entityTypeEnum = null;
+ if (optionsList.contains(FalconCLIConstants.LIST_OPT)) {
+ if (entityType == null) {
+ entityType = "";
+ }
+ if (StringUtils.isNotEmpty(entityType)) {
+ String[] types = entityType.split(",");
+ for (String type : types) {
+ EntityType.getEnum(type);
+ }
+ }
+ } else {
+ validateNotEmpty(entityType, FalconCLIConstants.TYPE_OPT);
+ entityTypeEnum = EntityType.getEnum(entityType);
+ }
+ validateSortOrder(sortOrder);
+ String entityAction = "entity";
+
+ if (optionsList.contains(SLA_MISS_ALERT_OPT)) {
+ validateNotEmpty(entityType, FalconCLIConstants.TYPE_OPT);
+ validateNotEmpty(start, FalconCLIConstants.START_OPT);
+ parseDateString(start);
+ parseDateString(end);
+ SchedulableEntityInstanceResult response = client.getFeedSlaMissPendingAlerts(entityType,
+ entityName, start, end, colo);
+ result = ResponseHelper.getString(response);
+ } else if (optionsList.contains(SUBMIT_OPT)) {
+ validateNotEmpty(filePath, "file");
+ validateColo(optionsList);
+ result = client.submit(entityType, filePath, doAsUser).getMessage();
+ } else if (optionsList.contains(LOOKUP_OPT)) {
+ validateNotEmpty(feedInstancePath, PATH_OPT);
+ FeedLookupResult resp = client.reverseLookUp(entityType, feedInstancePath, doAsUser);
+ result = ResponseHelper.getString(resp);
+ } else if (optionsList.contains(UPDATE_OPT)) {
+ validateNotEmpty(filePath, "file");
+ validateColo(optionsList);
+ validateNotEmpty(entityName, FalconCLIConstants.ENTITY_NAME_OPT);
+ result = client.update(entityType, entityName, filePath, skipDryRun, doAsUser).getMessage();
+ } else if (optionsList.contains(SUBMIT_AND_SCHEDULE_OPT)) {
+ validateNotEmpty(filePath, "file");
+ validateColo(optionsList);
+ result = client.submitAndSchedule(entityType, filePath, skipDryRun, doAsUser, userProps).getMessage();
+ } else if (optionsList.contains(VALIDATE_OPT)) {
+ validateNotEmpty(filePath, "file");
+ validateColo(optionsList);
+ result = client.validate(entityType, filePath, skipDryRun, doAsUser).getMessage();
+ } else if (optionsList.contains(FalconCLIConstants.SCHEDULE_OPT)) {
+ validateNotEmpty(entityName, FalconCLIConstants.ENTITY_NAME_OPT);
+ colo = getColo(colo);
+ result = client.schedule(entityTypeEnum, entityName, colo, skipDryRun, doAsUser, userProps).getMessage();
+ } else if (optionsList.contains(FalconCLIConstants.SUSPEND_OPT)) {
+ validateNotEmpty(entityName, FalconCLIConstants.ENTITY_NAME_OPT);
+ colo = getColo(colo);
+ result = client.suspend(entityTypeEnum, entityName, colo, doAsUser).getMessage();
+ } else if (optionsList.contains(FalconCLIConstants.RESUME_OPT)) {
+ validateNotEmpty(entityName, FalconCLIConstants.ENTITY_NAME_OPT);
+ colo = getColo(colo);
+ result = client.resume(entityTypeEnum, entityName, colo, doAsUser).getMessage();
+ } else if (optionsList.contains(DELETE_OPT)) {
+ validateColo(optionsList);
+ validateNotEmpty(entityName, FalconCLIConstants.ENTITY_NAME_OPT);
+ result = client.delete(entityTypeEnum, entityName, doAsUser).getMessage();
+ } else if (optionsList.contains(FalconCLIConstants.STATUS_OPT)) {
+ validateNotEmpty(entityName, FalconCLIConstants.ENTITY_NAME_OPT);
+ colo = getColo(colo);
+ result = client.getStatus(entityTypeEnum, entityName, colo, doAsUser, showScheduler).getMessage();
+ } else if (optionsList.contains(DEFINITION_OPT)) {
+ validateColo(optionsList);
+ validateNotEmpty(entityName, FalconCLIConstants.ENTITY_NAME_OPT);
+ result = client.getDefinition(entityType, entityName, doAsUser).toString();
+ } else if (optionsList.contains(FalconCLIConstants.DEPENDENCY_OPT)) {
+ validateColo(optionsList);
+ validateNotEmpty(entityName, FalconCLIConstants.ENTITY_NAME_OPT);
+ result = client.getDependency(entityType, entityName, doAsUser).toString();
+ } else if (optionsList.contains(FalconCLIConstants.LIST_OPT)) {
+ validateColo(optionsList);
+ validateEntityFields(fields);
+ validateOrderBy(orderBy, entityAction);
+ validateFilterBy(filterBy, entityAction);
+ EntityList entityList = client.getEntityList(entityType, fields, nameSubsequence, tagKeywords,
+ filterBy, filterTags, orderBy, sortOrder, offset, numResults, doAsUser);
+ result = entityList != null ? entityList.toString() : "No entity of type (" + entityType + ") found.";
+ } else if (optionsList.contains(FalconCLIConstants.SUMMARY_OPT)) {
+ validateEntityTypeForSummary(entityType);
+ validateNotEmpty(cluster, FalconCLIConstants.CLUSTER_OPT);
+ validateEntityFields(fields);
+ validateFilterBy(filterBy, entityAction);
+ validateOrderBy(orderBy, entityAction);
+ result = ResponseHelper.getString(client.getEntitySummary(
+ entityType, cluster, start, end, fields, filterBy, filterTags,
+ orderBy, sortOrder, offset, numResults, numInstances, doAsUser));
+ } else if (optionsList.contains(TOUCH_OPT)) {
+ validateNotEmpty(entityName, FalconCLIConstants.ENTITY_NAME_OPT);
+ colo = getColo(colo);
+ result = client.touch(entityType, entityName, colo, skipDryRun, doAsUser).getMessage();
+ } else if (optionsList.contains(FalconCLIConstants.HELP_CMD)) {
+ OUT.get().println("Falcon Help");
+ } else {
+ throw new FalconCLIException("Invalid command");
+ }
+ OUT.get().println(result);
+ }
+
+ private void validateColo(Set<String> optionsList) throws FalconCLIException {
+ if (optionsList.contains(FalconCLIConstants.COLO_OPT)) {
+ throw new FalconCLIException("Invalid argument : " + FalconCLIConstants.COLO_OPT);
+ }
+ }
+
+ private void validateEntityFields(String fields) throws FalconCLIException {
+ if (StringUtils.isEmpty(fields)) {
+ return;
+ }
+ String[] fieldsList = fields.split(",");
+ for (String s : fieldsList) {
+ try {
+ EntityList.EntityFieldList.valueOf(s.toUpperCase());
+ } catch (IllegalArgumentException ie) {
+ throw new FalconCLIException("Invalid fields argument : " + FIELDS_OPT);
+ }
+ }
+ }
+
+ private Date parseDateString(String time) throws FalconCLIException {
+ if (time != null && !time.isEmpty()) {
+ try {
+ return SchemaHelper.parseDateUTC(time);
+ } catch(Exception e) {
+ throw new FalconCLIException("Time " + time + " is not valid", e);
+ }
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/cli/src/main/java/org/apache/falcon/cli/FalconInstanceCLI.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/falcon/cli/FalconInstanceCLI.java b/cli/src/main/java/org/apache/falcon/cli/FalconInstanceCLI.java
new file mode 100644
index 0000000..afbba12
--- /dev/null
+++ b/cli/src/main/java/org/apache/falcon/cli/FalconInstanceCLI.java
@@ -0,0 +1,340 @@
+/**
+ * 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.FalconCLIConstants;
+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.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Instance extension to Falcon Command Line Interface - wraps the RESTful API for instances.
+ */
+public class FalconInstanceCLI extends FalconCLI {
+
+ private static final String FORCE_RERUN_FLAG = "force";
+ private static final String INSTANCE_TIME_OPT = "instanceTime";
+ private static final String RUNNING_OPT = "running";
+ private static final String KILL_OPT = "kill";
+ private static final String RERUN_OPT = "rerun";
+ private static final String LOG_OPT = "logs";
+ private static final String ALL_ATTEMPTS = "allAttempts";
+ private static final String RUNID_OPT = "runid";
+ private static final String CLUSTERS_OPT = "clusters";
+ private static final String SOURCECLUSTER_OPT = "sourceClusters";
+ private static final String LIFECYCLE_OPT = "lifecycle";
+ private static final String PARARMS_OPT = "params";
+ private static final String LISTING_OPT = "listing";
+ private static final String TRIAGE_OPT = "triage";
+
+ public FalconInstanceCLI() throws Exception {
+ super();
+ }
+
+ public Options createInstanceOptions() {
+
+ Options instanceOptions = new Options();
+
+ Option running = new Option(RUNNING_OPT, false,
+ "Gets running process instances for a given process");
+ Option list = new Option(FalconCLIConstants.LIST_OPT, false,
+ "Gets all instances for a given process in the range start time and optional end time");
+ Option status = new Option(FalconCLIConstants.STATUS_OPT, false,
+ "Gets status of process instances for a given process in the range start time and optional end time");
+ Option summary = new Option(FalconCLIConstants.SUMMARY_OPT, false,
+ "Gets summary of instances for a given process in the range start time and optional end time");
+ Option kill = new Option(KILL_OPT, false,
+ "Kills active process instances for a given process in the range start time and optional end time");
+ Option suspend = new Option(FalconCLIConstants.SUSPEND_OPT, false,
+ "Suspends active process instances for a given process in the range start time and optional end time");
+ Option resume = new Option(FalconCLIConstants.RESUME_OPT, false,
+ "Resumes suspended process instances for a given process "
+ + "in the range start time and optional end time");
+ Option rerun = new Option(RERUN_OPT, false,
+ "Reruns process instances for a given process in the range start time and "
+ + "optional end time and overrides properties present in job.properties file");
+ Option logs = new Option(LOG_OPT, false,
+ "Logs print the logs for process instances for a given process in "
+ + "the range start time and optional end time");
+ Option params = new Option(PARARMS_OPT, false,
+ "Displays the workflow parameters for a given instance of specified nominal time"
+ + "start time represents nominal time and end time is not considered");
+ Option listing = new Option(LISTING_OPT, false,
+ "Displays feed listing and their status between a start and end time range.");
+ Option dependency = new Option(FalconCLIConstants.DEPENDENCY_OPT, false,
+ "Displays dependent instances for a specified instance.");
+ Option triage = new Option(TRIAGE_OPT, false,
+ "Triage a feed or process instance and find the failures in it's lineage.");
+
+ 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);
+
+ Option url = new Option(FalconCLIConstants.URL_OPTION, true, "Falcon URL");
+ Option start = new Option(FalconCLIConstants.START_OPT, true,
+ "Start time is required for commands, status, kill, suspend, resume and re-run"
+ + "and it is nominal time while displaying workflow params");
+ Option end = new Option(FalconCLIConstants.END_OPT, true,
+ "End time is optional for commands, status, kill, suspend, resume and re-run; "
+ + "if not specified then current time is considered as end time");
+ Option runid = new Option(RUNID_OPT, true,
+ "Instance runid is optional and user can specify the runid, defaults to 0");
+ Option clusters = new Option(CLUSTERS_OPT, true,
+ "clusters is optional for commands kill, suspend and resume, "
+ + "should not be specified for other commands");
+ Option sourceClusters = new Option(SOURCECLUSTER_OPT, true,
+ " source cluster is optional for commands kill, suspend and resume, "
+ + "should not be specified for other commands (required for only feed)");
+ Option filePath = new Option(FalconCLIConstants.FILE_PATH_OPT, true,
+ "Path to job.properties file is required for rerun command, "
+ + "it should contain name=value pair for properties to override for rerun");
+ Option entityType = new Option(FalconCLIConstants.TYPE_OPT, true,
+ "Entity type, can be feed or process xml");
+ Option entityName = new Option(FalconCLIConstants.ENTITY_NAME_OPT, true,
+ "Entity name, can be feed or process name");
+ Option colo = new Option(FalconCLIConstants.COLO_OPT, true,
+ "Colo on which the cmd has to be executed");
+ Option lifecycle = new Option(LIFECYCLE_OPT, true,
+ "describes life cycle of entity , for feed it can be replication/retention "
+ + "and for process it can be execution");
+ Option filterBy = new Option(FalconCLIConstants.FILTER_BY_OPT, true,
+ "Filter returned instances by the specified fields");
+ Option orderBy = new Option(FalconCLIConstants.ORDER_BY_OPT, true,
+ "Order returned instances by this field");
+ Option sortOrder = new Option(FalconCLIConstants.SORT_ORDER_OPT, true, "asc or desc order for results");
+ Option offset = new Option(FalconCLIConstants.OFFSET_OPT, true,
+ "Start returning instances from this offset");
+ Option numResults = new Option(FalconCLIConstants.NUM_RESULTS_OPT, true,
+ "Number of results to return per request");
+ Option forceRerun = new Option(FORCE_RERUN_FLAG, false,
+ "Flag to forcefully rerun entire workflow of an instance");
+ Option doAs = new Option(FalconCLIConstants.DO_AS_OPT, true, "doAs user");
+ Option debug = new Option(FalconCLIConstants.DEBUG_OPTION, false, "Use debug mode to see"
+ + " debugging statements on stdout");
+
+ Option instanceTime = new Option(INSTANCE_TIME_OPT, true, "Time for an instance");
+
+ Option allAttempts = new Option(ALL_ATTEMPTS, false, "To get all attempts of corresponding instances");
+
+ 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(allAttempts);
+
+ return instanceOptions;
+ }
+
+ public void instanceCommand(CommandLine commandLine, FalconClient client) throws FalconCLIException, 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 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);
+ 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);
+ 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)) {
+ validateOrderBy(orderBy, instanceAction);
+ 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;
+ }
+ validateOrderBy(orderBy, instanceAction);
+ 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)) {
+ validateOrderBy(orderBy, "summary");
+ 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)) {
+ validateOrderBy(orderBy, instanceAction);
+ 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 {
+ throw new FalconCLIException("Invalid command");
+ }
+
+ OUT.get().println(result);
+ }
+
+ private void validateInstanceCommands(Set<String> optionsList,
+ String entity, String type,
+ String colo) throws FalconCLIException {
+
+ 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");
+ }
+ }
+ }
+
+ private List<LifeCycle> getLifeCycle(String lifeCycleValue) throws FalconCLIException {
+
+ if (lifeCycleValue != null) {
+ String[] lifeCycleValues = lifeCycleValue.split(",");
+ List<LifeCycle> lifeCycles = new ArrayList<LifeCycle>();
+ try {
+ for (String lifeCycle : lifeCycleValues) {
+ lifeCycles.add(LifeCycle.valueOf(lifeCycle.toUpperCase().trim()));
+ }
+ } catch (IllegalArgumentException e) {
+ throw new FalconCLIException("Invalid life cycle values: " + lifeCycles, e);
+ }
+ return lifeCycles;
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/cli/src/main/java/org/apache/falcon/cli/FalconMetadataCLI.java
----------------------------------------------------------------------
diff --git a/cli/src/main/java/org/apache/falcon/cli/FalconMetadataCLI.java b/cli/src/main/java/org/apache/falcon/cli/FalconMetadataCLI.java
new file mode 100644
index 0000000..b3e138f
--- /dev/null
+++ b/cli/src/main/java/org/apache/falcon/cli/FalconMetadataCLI.java
@@ -0,0 +1,256 @@
+/**
+ * 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.commons.lang3.StringUtils;
+import org.apache.falcon.FalconCLIConstants;
+import org.apache.falcon.client.FalconCLIException;
+import org.apache.falcon.client.FalconClient;
+import org.apache.falcon.entity.v0.EntityType;
+import org.apache.falcon.metadata.RelationshipType;
+
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Metadata extension to Falcon Command Line Interface - wraps the RESTful API for Metadata.
+ */
+public class FalconMetadataCLI extends FalconCLI {
+
+ public static final AtomicReference<PrintStream> OUT = new AtomicReference<PrintStream>(System.out);
+
+ // Discovery Commands
+ public static final String DISCOVERY_OPT = "discovery";
+ public static final String LIST_OPT = "list";
+ public static final String URL_OPTION = "url";
+
+ // Lineage Commands
+ public static final String LINEAGE_OPT = "lineage";
+ public static final String VERTEX_CMD = "vertex";
+ public static final String VERTICES_CMD = "vertices";
+ public static final String VERTEX_EDGES_CMD = "edges";
+ public static final String EDGE_CMD = "edge";
+ public static final String ID_OPT = "id";
+ public static final String KEY_OPT = "key";
+ public static final String VALUE_OPT = "value";
+ public static final String DIRECTION_OPT = "direction";
+
+ public FalconMetadataCLI() throws Exception {
+ super();
+ }
+
+ public Options createMetadataOptions() {
+ Options metadataOptions = new Options();
+
+ OptionGroup group = new OptionGroup();
+ Option discovery = new Option(DISCOVERY_OPT, false, "Discover falcon metadata relations");
+ Option lineage = new Option(LINEAGE_OPT, false, "Get falcon metadata lineage information");
+ group.addOption(discovery);
+ group.addOption(lineage);
+ Option pipeline = new Option(FalconCLIConstants.PIPELINE_OPT, true,
+ "Get lineage graph for the entities in a pipeline");
+ metadataOptions.addOptionGroup(group);
+
+ // Add discovery options
+
+ Option list = new Option(LIST_OPT, false, "List all dimensions");
+ Option relations = new Option(FalconCLIConstants.RELATIONS_OPT, false, "List all relations for a dimension");
+ metadataOptions.addOption(list);
+ metadataOptions.addOption(relations);
+
+ Option url = new Option(URL_OPTION, true, "Falcon URL");
+ Option type = new Option(FalconCLIConstants.TYPE_OPT, true, "Dimension type");
+ Option name = new Option(FalconCLIConstants.NAME_OPT, true, "Dimension name");
+ Option cluster = new Option(FalconCLIConstants.CLUSTER_OPT, true, "Cluster name");
+ Option feed = new Option(FalconCLIConstants.FEED_OPT, true, "Feed Entity name");
+ Option process = new Option(FalconCLIConstants.PROCESS_OPT, true, "Process Entity name");
+ Option numResults = new Option(FalconCLIConstants.NUM_RESULTS_OPT, true,
+ "Number of results to return per request");
+
+ // Add lineage options
+ metadataOptions.addOption(pipeline);
+
+ metadataOptions.addOption(url);
+ metadataOptions.addOption(type);
+ metadataOptions.addOption(cluster);
+ metadataOptions.addOption(name);
+ metadataOptions.addOption(feed);
+ metadataOptions.addOption(process);
+ metadataOptions.addOption(numResults);
+
+ Option vertex = new Option(VERTEX_CMD, false, "show the vertices");
+ Option vertices = new Option(VERTICES_CMD, false, "show the vertices");
+ Option vertexEdges = new Option(VERTEX_EDGES_CMD, false, "show the edges for a given vertex");
+ Option edges = new Option(EDGE_CMD, false, "show the edges");
+ Option id = new Option(ID_OPT, true, "vertex or edge id");
+ Option key = new Option(KEY_OPT, true, "key property");
+ Option value = new Option(VALUE_OPT, true, "value property");
+ Option direction = new Option(DIRECTION_OPT, true, "edge direction property");
+ Option debug = new Option(FalconCLIConstants.DEBUG_OPTION, false,
+ "Use debug mode to see debugging statements on stdout");
+
+ metadataOptions.addOption(vertex);
+ metadataOptions.addOption(vertices);
+ metadataOptions.addOption(vertexEdges);
+ metadataOptions.addOption(edges);
+ metadataOptions.addOption(id);
+ metadataOptions.addOption(key);
+ metadataOptions.addOption(value);
+ metadataOptions.addOption(direction);
+ metadataOptions.addOption(debug);
+
+ Option doAs = new Option(FalconCLIConstants.DO_AS_OPT, true, "doAs user");
+ metadataOptions.addOption(doAs);
+
+ return metadataOptions;
+ }
+
+ public void metadataCommand(CommandLine commandLine, FalconClient client) throws FalconCLIException {
+ Set<String> optionsList = new HashSet<String>();
+ for (Option option : commandLine.getOptions()) {
+ optionsList.add(option.getOpt());
+ }
+
+ String result;
+ String dimensionType = commandLine.getOptionValue(FalconCLIConstants.TYPE_OPT);
+ String cluster = commandLine.getOptionValue(FalconCLIConstants.CLUSTER_OPT);
+ String feed = commandLine.getOptionValue(FalconCLIConstants.FEED_OPT);
+ String process = commandLine.getOptionValue(FalconCLIConstants.PROCESS_OPT);
+ String dimensionName = commandLine.getOptionValue(FalconCLIConstants.NAME_OPT);
+ String id = commandLine.getOptionValue(ID_OPT);
+ String key = commandLine.getOptionValue(KEY_OPT);
+ String value = commandLine.getOptionValue(VALUE_OPT);
+ String direction = commandLine.getOptionValue(DIRECTION_OPT);
+ String pipeline = commandLine.getOptionValue(FalconCLIConstants.PIPELINE_OPT);
+ String doAsUser = commandLine.getOptionValue(FalconCLIConstants.DO_AS_OPT);
+ Integer numResults = parseIntegerInput(commandLine.getOptionValue(FalconCLIConstants.NUM_RESULTS_OPT),
+ null, "numResults");
+
+ if (optionsList.contains(LINEAGE_OPT)) {
+ validatePipelineName(pipeline);
+ result = client.getEntityLineageGraph(pipeline, doAsUser).getDotNotation();
+ } else if (optionsList.contains(LIST_OPT)) {
+ validateDimensionType(dimensionType.toUpperCase());
+ if (!(dimensionType.toUpperCase())
+ .equals(RelationshipType.REPLICATION_METRICS.name())) {
+ result = client.getDimensionList(dimensionType, cluster, doAsUser);
+ } else {
+ String schedEntityType = null;
+ String schedEntityName = null;
+ if (StringUtils.isNotEmpty(feed)) {
+ schedEntityType = EntityType.getEnum(FalconCLIConstants.FEED_OPT).name();
+ schedEntityName = feed;
+ } else if (StringUtils.isNotEmpty(process)) {
+ schedEntityType = EntityType.getEnum(FalconCLIConstants.PROCESS_OPT).name();
+ schedEntityName = process;
+ }
+ validateScheduleEntity(schedEntityType, schedEntityName);
+
+ result = client.getReplicationMetricsDimensionList(schedEntityType, schedEntityName,
+ numResults, doAsUser);
+ }
+ } else if (optionsList.contains(FalconCLIConstants.RELATIONS_OPT)) {
+ validateDimensionType(dimensionType.toUpperCase());
+ validateDimensionName(dimensionName, FalconCLIConstants.RELATIONS_OPT);
+ result = client.getDimensionRelations(dimensionType, dimensionName, doAsUser);
+ } else if (optionsList.contains(VERTEX_CMD)) {
+ validateId(id);
+ result = client.getVertex(id, doAsUser);
+ } else if (optionsList.contains(VERTICES_CMD)) {
+ validateVerticesCommand(key, value);
+ result = client.getVertices(key, value, doAsUser);
+ } else if (optionsList.contains(VERTEX_EDGES_CMD)) {
+ validateVertexEdgesCommand(id, direction);
+ result = client.getVertexEdges(id, direction, doAsUser);
+ } else if (optionsList.contains(EDGE_CMD)) {
+ validateId(id);
+ result = client.getEdge(id, doAsUser);
+ } else {
+ throw new FalconCLIException("Invalid metadata command");
+ }
+
+ OUT.get().println(result);
+ }
+
+ private void validatePipelineName(String pipeline) throws FalconCLIException {
+ if (StringUtils.isEmpty(pipeline)) {
+ throw new FalconCLIException("Invalid value for pipeline");
+ }
+ }
+
+ private void validateDimensionType(String dimensionType) throws FalconCLIException {
+ if (StringUtils.isEmpty(dimensionType)
+ || dimensionType.contains("INSTANCE")) {
+ throw new FalconCLIException("Invalid value provided for queryParam \"type\" " + dimensionType);
+ }
+ try {
+ RelationshipType.valueOf(dimensionType);
+ } catch (IllegalArgumentException iae) {
+ throw new FalconCLIException("Invalid value provided for queryParam \"type\" " + dimensionType);
+ }
+ }
+
+ private void validateDimensionName(String dimensionName, String action) throws FalconCLIException {
+ if (StringUtils.isEmpty(dimensionName)) {
+ throw new FalconCLIException("Dimension ID cannot be empty or null for action " + action);
+ }
+ }
+
+ private void validateScheduleEntity(String schedEntityType, String schedEntityName) throws FalconCLIException {
+ if (StringUtils.isBlank(schedEntityType)) {
+ throw new FalconCLIException("Entity must be schedulable type : -feed/process");
+ }
+
+ if (StringUtils.isBlank(schedEntityName)) {
+ throw new FalconCLIException("Entity name is missing");
+ }
+ }
+
+ private void validateId(String id) throws FalconCLIException {
+ if (id == null || id.length() == 0) {
+ throw new FalconCLIException("Missing argument: id");
+ }
+ }
+
+ private void validateVerticesCommand(String key, String value) throws FalconCLIException {
+ if (key == null || key.length() == 0) {
+ throw new FalconCLIException("Missing argument: key");
+ }
+
+ if (value == null || value.length() == 0) {
+ throw new FalconCLIException("Missing argument: value");
+ }
+ }
+
+ private void validateVertexEdgesCommand(String id, String direction) throws FalconCLIException {
+ if (id == null || id.length() == 0) {
+ throw new FalconCLIException("Missing argument: id");
+ }
+
+ if (direction == null || direction.length() == 0) {
+ throw new FalconCLIException("Missing argument: direction");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/client/src/main/java/org/apache/falcon/FalconCLIConstants.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/falcon/FalconCLIConstants.java b/client/src/main/java/org/apache/falcon/FalconCLIConstants.java
new file mode 100644
index 0000000..eb4cf3f
--- /dev/null
+++ b/client/src/main/java/org/apache/falcon/FalconCLIConstants.java
@@ -0,0 +1,76 @@
+/**
+ * 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;
+
+/**
+* FalconCLI Constants.
+*/
+public final class FalconCLIConstants {
+ private FalconCLIConstants(){
+
+ }
+ public static final String ENV_FALCON_DEBUG = "FALCON_DEBUG";
+ public static final String DEBUG_OPTION = "debug";
+ public static final String URL_OPTION = "url";
+
+ public static final String ADMIN_CMD = "admin";
+ public static final String HELP_CMD = "help";
+ public static final String METADATA_CMD = "metadata";
+ public static final String ENTITY_CMD = "entity";
+ public static final String INSTANCE_CMD = "instance";
+ public static final String RECIPE_CMD = "recipe";
+
+ public static final String TYPE_OPT = "type";
+ public static final String COLO_OPT = "colo";
+ public static final String CLUSTER_OPT = "cluster";
+ public static final String FEED_OPT = "feed";
+ public static final String PROCESS_OPT = "process";
+ public static final String ENTITY_NAME_OPT = "name";
+ public static final String FILE_PATH_OPT = "file";
+ public static final String VERSION_OPT = "version";
+ public static final String SCHEDULE_OPT = "schedule";
+ public static final String SUSPEND_OPT = "suspend";
+ public static final String RESUME_OPT = "resume";
+ public static final String STATUS_OPT = "status";
+ public static final String SUMMARY_OPT = "summary";
+ public static final String DEPENDENCY_OPT = "dependency";
+ public static final String LIST_OPT = "list";
+ public static final String SKIPDRYRUN_OPT = "skipDryRun";
+ public static final String FILTER_BY_OPT = "filterBy";
+ public static final String ORDER_BY_OPT = "orderBy";
+ public static final String SORT_ORDER_OPT = "sortOrder";
+ public static final String OFFSET_OPT = "offset";
+ public static final String NUM_RESULTS_OPT = "numResults";
+ public static final String START_OPT = "start";
+ public static final String END_OPT = "end";
+ public static final String CURRENT_COLO = "current.colo";
+ public static final String CLIENT_PROPERTIES = "/client.properties";
+ public static final String DO_AS_OPT = "doAs";
+ public static final String RELATIONS_OPT = "relations";
+ public static final String PIPELINE_OPT = "pipeline";
+ public static final String NAME_OPT = "name";
+
+ /**
+ * Recipe operation enum.
+ */
+ public enum RecipeOperation {
+ HDFS_REPLICATION,
+ HIVE_DISASTER_RECOVERY
+ }
+}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/client/src/main/java/org/apache/falcon/cli/CLIParser.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/falcon/cli/CLIParser.java b/client/src/main/java/org/apache/falcon/cli/CLIParser.java
deleted file mode 100644
index 9d8554f..0000000
--- a/client/src/main/java/org/apache/falcon/cli/CLIParser.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * 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.GnuParser;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.HelpFormatter;
-
-import java.io.PrintWriter;
-import java.text.MessageFormat;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-
-/**
- * Cannibalized from Oozie CLIParser into Falcon
- * Command line parser based on Apache common-cli 1.x that supports subcommands.
- */
-public class CLIParser {
- private static final String LEFT_PADDING = " ";
-
- private String cliName;
- private String[] cliHelp;
- private Map<String, Options> commands = new LinkedHashMap<String, Options>();
- private Map<String, Boolean> commandWithArgs = new LinkedHashMap<String, Boolean>();
- private Map<String, String> commandsHelp = new LinkedHashMap<String, String>();
-
- /**
- * Create a parser.
- *
- * @param aCliName name of the parser, for help purposes.
- * @param aCliHelp help for the CLI.
- */
- public CLIParser(String aCliName, String[] aCliHelp) {
- this.cliName = aCliName;
- this.cliHelp = aCliHelp.clone();
- }
-
- /**
- * Add a command to the parser.
- *
- * @param command comand name.
- * @param argsHelp command arguments help.
- * @param commandHelp command description.
- * @param commandOptions command options.
- * @param hasArguments has args
- */
- public void addCommand(String command, String argsHelp, String commandHelp, Options commandOptions,
- boolean hasArguments) {
- String helpMsg = argsHelp + ((hasArguments) ? "<ARGS> " : "") + ": " + commandHelp;
- commandsHelp.put(command, helpMsg);
- commands.put(command, commandOptions);
- commandWithArgs.put(command, hasArguments);
- }
-
- /**
- * Bean that represents a parsed command.
- */
- public static final class Command {
- private String name;
- private CommandLine commandLine;
-
- private Command(String name, CommandLine commandLine) {
- this.name = name;
- this.commandLine = commandLine;
- }
-
- /**
- * Return the command name.
- *
- * @return the command name.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Return the command line.
- *
- * @return the command line.
- */
- public CommandLine getCommandLine() {
- return commandLine;
- }
- }
-
- /**
- * Parse a array of arguments into a command.
- *
- * @param args array of arguments.
- * @return the parsed Command.
- * @throws ParseException thrown if the arguments could not be parsed.
- */
- public Command parse(String[] args) throws ParseException {
- if (args.length == 0) {
- throw new ParseException("missing sub-command");
- } else {
- if (commands.containsKey(args[0])) {
- GnuParser parser = new GnuParser();
- String[] minusCommand = new String[args.length - 1];
- System.arraycopy(args, 1, minusCommand, 0, minusCommand.length);
- return new Command(args[0], parser.parse(commands.get(args[0]), minusCommand,
- commandWithArgs.get(args[0])));
- } else {
- throw new ParseException(MessageFormat.format("invalid sub-command [{0}]", args[0]));
- }
- }
- }
-
- public String shortHelp() {
- return "use 'help' sub-command for help details";
- }
-
- /**
- * Print the help for the parser to standard output.
- */
- public void showHelp() {
- PrintWriter pw = new PrintWriter(System.out);
- pw.println("usage: ");
- for (String s : cliHelp) {
- pw.println(LEFT_PADDING + s);
- }
- pw.println();
- HelpFormatter formatter = new HelpFormatter();
- for (Map.Entry<String, Options> entry : commands.entrySet()) {
- String s = LEFT_PADDING + cliName + " " + entry.getKey() + " ";
- if (entry.getValue().getOptions().size() > 0) {
- pw.println(s + "<OPTIONS> " + commandsHelp.get(entry.getKey()));
- formatter.printOptions(pw, 100, entry.getValue(), s.length(), 3);
- } else {
- pw.println(s + commandsHelp.get(entry.getKey()));
- }
- pw.println();
- }
- pw.flush();
- }
-}
http://git-wip-us.apache.org/repos/asf/falcon/blob/6655e90a/client/src/main/java/org/apache/falcon/cli/FalconAdminCLI.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/falcon/cli/FalconAdminCLI.java b/client/src/main/java/org/apache/falcon/cli/FalconAdminCLI.java
deleted file mode 100644
index 6360743..0000000
--- a/client/src/main/java/org/apache/falcon/cli/FalconAdminCLI.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * 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.FalconCLIException;
-import org.apache.falcon.client.FalconClient;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Admin extension to Falcon Command Line Interface - wraps the RESTful API for admin commands.
- */
-public class FalconAdminCLI extends FalconCLI {
-
- private static final String STACK_OPTION = "stack";
-
- public FalconAdminCLI() throws Exception {
- super();
- }
-
- public Options createAdminOptions() {
- Options adminOptions = new Options();
- Option url = new Option(URL_OPTION, true, "Falcon URL");
- adminOptions.addOption(url);
-
- OptionGroup group = new OptionGroup();
- Option status = new Option(STATUS_OPT, false,
- "show the current system status");
- Option version = new Option(VERSION_OPT, false,
- "show Falcon server build version");
- Option stack = new Option(STACK_OPTION, false,
- "show the thread stack dump");
- Option doAs = new Option(DO_AS_OPT, true,
- "doAs user");
- Option help = new Option("help", false, "show Falcon help");
- Option debug = new Option(DEBUG_OPTION, false, "Use debug mode to see debugging statements on stdout");
- group.addOption(status);
- group.addOption(version);
- group.addOption(stack);
- group.addOption(help);
-
- adminOptions.addOptionGroup(group);
- adminOptions.addOption(doAs);
- adminOptions.addOption(debug);
- return adminOptions;
- }
-
- public int adminCommand(CommandLine commandLine, FalconClient client,
- String falconUrl) throws FalconCLIException, IOException {
- String result;
- Set<String> optionsList = new HashSet<String>();
- for (Option option : commandLine.getOptions()) {
- optionsList.add(option.getOpt());
- }
-
- String doAsUser = commandLine.getOptionValue(DO_AS_OPT);
-
- if (optionsList.contains(STACK_OPTION)) {
- result = client.getThreadDump(doAsUser);
- OUT.get().println(result);
- }
-
- int exitValue = 0;
- if (optionsList.contains(STATUS_OPT)) {
- try {
- int status = client.getStatus(doAsUser);
- if (status != 200) {
- ERR.get().println("Falcon server is not fully operational (on " + falconUrl + "). "
- + "Please check log files.");
- exitValue = status;
- } else {
- OUT.get().println("Falcon server is running (on " + falconUrl + ")");
- }
- } catch (Exception e) {
- ERR.get().println("Falcon server doesn't seem to be running on " + falconUrl);
- exitValue = -1;
- }
- } else if (optionsList.contains(VERSION_OPT)) {
- result = client.getVersion(doAsUser);
- OUT.get().println("Falcon server build version: " + result);
- } else if (optionsList.contains(HELP_CMD)) {
- OUT.get().println("Falcon Help");
- }
- return exitValue;
- }
-
-}