You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ji...@apache.org on 2017/09/12 00:36:12 UTC
[70/84] [abbrv] hadoop git commit: YARN-7091. Rename application to
service in yarn-native-services. Contributed by Jian He
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java
new file mode 100644
index 0000000..c3a2752
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java
@@ -0,0 +1,892 @@
+/**
+ * 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.hadoop.yarn.service.client;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.RetryNTimes;
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.permission.FsPermission;
+import org.apache.hadoop.net.NetUtils;
+import org.apache.hadoop.registry.client.api.RegistryConstants;
+import org.apache.hadoop.registry.client.api.RegistryOperations;
+import org.apache.hadoop.registry.client.api.RegistryOperationsFactory;
+import org.apache.hadoop.registry.client.binding.RegistryUtils;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.util.VersionInfo;
+import org.apache.hadoop.yarn.api.ApplicationConstants;
+import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest;
+import org.apache.hadoop.yarn.api.protocolrecords.UpdateApplicationTimeoutsRequest;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.ApplicationReport;
+import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
+import org.apache.hadoop.yarn.api.records.ApplicationTimeout;
+import org.apache.hadoop.yarn.api.records.ApplicationTimeoutType;
+import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
+import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
+import org.apache.hadoop.yarn.api.records.LocalResource;
+import org.apache.hadoop.yarn.api.records.LocalResourceType;
+import org.apache.hadoop.yarn.api.records.Resource;
+import org.apache.hadoop.yarn.api.records.YarnApplicationState;
+import org.apache.hadoop.yarn.client.api.YarnClient;
+import org.apache.hadoop.yarn.client.api.YarnClientApplication;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.hadoop.yarn.ipc.YarnRPC;
+import org.apache.hadoop.yarn.proto.ClientAMProtocol.ComponentCountProto;
+import org.apache.hadoop.yarn.proto.ClientAMProtocol.FlexComponentsRequestProto;
+import org.apache.hadoop.yarn.proto.ClientAMProtocol.GetStatusRequestProto;
+import org.apache.hadoop.yarn.proto.ClientAMProtocol.GetStatusResponseProto;
+import org.apache.hadoop.yarn.proto.ClientAMProtocol.StopRequestProto;
+import org.apache.hadoop.yarn.service.ClientAMProtocol;
+import org.apache.hadoop.yarn.service.ServiceMaster;
+import org.apache.hadoop.yarn.service.api.records.Service;
+import org.apache.hadoop.yarn.service.api.records.Component;
+import org.apache.hadoop.yarn.service.api.records.ServiceState;
+import org.apache.hadoop.yarn.service.client.params.AbstractClusterBuildingActionArgs;
+import org.apache.hadoop.yarn.service.client.params.ActionDependencyArgs;
+import org.apache.hadoop.yarn.service.client.params.ActionFlexArgs;
+import org.apache.hadoop.yarn.service.client.params.Arguments;
+import org.apache.hadoop.yarn.service.client.params.ClientArgs;
+import org.apache.hadoop.yarn.service.client.params.CommonArgs;
+import org.apache.hadoop.yarn.service.conf.SliderExitCodes;
+import org.apache.hadoop.yarn.service.conf.YarnServiceConstants;
+import org.apache.hadoop.yarn.service.conf.YarnServiceConf;
+import org.apache.hadoop.yarn.service.provider.AbstractClientProvider;
+import org.apache.hadoop.yarn.service.provider.ProviderUtils;
+import org.apache.hadoop.yarn.service.utils.ServiceApiUtil;
+import org.apache.hadoop.yarn.service.utils.ServiceRegistryUtils;
+import org.apache.hadoop.yarn.service.utils.SliderFileSystem;
+import org.apache.hadoop.yarn.service.utils.SliderUtils;
+import org.apache.hadoop.yarn.util.Records;
+import org.apache.hadoop.yarn.util.Times;
+import org.apache.hadoop.yarn.service.exceptions.BadClusterStateException;
+import org.apache.hadoop.yarn.service.exceptions.BadConfigException;
+import org.apache.hadoop.yarn.service.exceptions.SliderException;
+import org.apache.hadoop.yarn.service.exceptions.UsageException;
+import org.apache.hadoop.yarn.service.containerlaunch.ClasspathConstructor;
+import org.apache.hadoop.yarn.service.containerlaunch.JavaCommandLineBuilder;
+import org.apache.hadoop.yarn.service.utils.ZookeeperUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.apache.hadoop.yarn.api.records.YarnApplicationState.*;
+import static org.apache.hadoop.yarn.service.client.params.SliderActions.ACTION_CREATE;
+import static org.apache.hadoop.yarn.service.client.params.SliderActions.ACTION_FLEX;
+import static org.apache.hadoop.yarn.service.conf.YarnServiceConf.YARN_QUEUE;
+import static org.apache.hadoop.yarn.service.utils.ServiceApiUtil.jsonSerDeser;
+import static org.apache.hadoop.yarn.service.utils.SliderUtils.*;
+
+@InterfaceAudience.Public
+@InterfaceStability.Unstable
+public class ServiceClient extends CompositeService
+ implements SliderExitCodes, YarnServiceConstants {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(ServiceClient.class);
+ private SliderFileSystem fs;
+ //TODO disable retry so that client / rest API doesn't block?
+ protected YarnClient yarnClient;
+ // Avoid looking up applicationId from fs all the time.
+ private Map<String, ApplicationId> cachedAppIds = new ConcurrentHashMap<>();
+
+ private RegistryOperations registryClient;
+ private CuratorFramework curatorClient;
+ private YarnRPC rpc;
+
+ private static EnumSet<YarnApplicationState> terminatedStates =
+ EnumSet.of(FINISHED, FAILED, KILLED);
+ private static EnumSet<YarnApplicationState> liveStates =
+ EnumSet.of(NEW, NEW_SAVING, SUBMITTED, ACCEPTED, RUNNING);
+ private static EnumSet<YarnApplicationState> preRunningStates =
+ EnumSet.of(NEW, NEW_SAVING, SUBMITTED, ACCEPTED);
+
+ public ServiceClient() {
+ super(ServiceClient.class.getName());
+ }
+
+ @Override protected void serviceInit(Configuration configuration)
+ throws Exception {
+ fs = new SliderFileSystem(configuration);
+ yarnClient = YarnClient.createYarnClient();
+ rpc = YarnRPC.create(configuration);
+ addService(yarnClient);
+ super.serviceInit(configuration);
+ }
+
+ @Override
+ protected void serviceStop() throws Exception {
+ if (registryClient != null) {
+ registryClient.stop();
+ }
+ super.serviceStop();
+ }
+
+ private Service loadAppJsonFromLocalFS(
+ AbstractClusterBuildingActionArgs args) throws IOException {
+ File file = args.getAppDef();
+ Path filePath = new Path(file.getAbsolutePath());
+ LOG.info("Loading app json from: " + filePath);
+ Service service = jsonSerDeser
+ .load(FileSystem.getLocal(getConfig()), filePath);
+ if (args.lifetime > 0) {
+ service.setLifetime(args.lifetime);
+ }
+ service.setName(args.getClusterName());
+ return service;
+ }
+
+ public int actionBuild(AbstractClusterBuildingActionArgs args)
+ throws IOException, YarnException {
+ return actionBuild(loadAppJsonFromLocalFS(args));
+ }
+
+ public int actionBuild(Service service)
+ throws YarnException, IOException {
+ Path appDir = checkAppNotExistOnHdfs(service);
+ ServiceApiUtil.validateAndResolveService(service, fs, getConfig());
+ createDirAndPersistApp(appDir, service);
+ return EXIT_SUCCESS;
+ }
+
+ public int actionCreate(AbstractClusterBuildingActionArgs args)
+ throws IOException, YarnException {
+ actionCreate(loadAppJsonFromLocalFS(args));
+ return EXIT_SUCCESS;
+ }
+
+ public ApplicationId actionCreate(Service service)
+ throws IOException, YarnException {
+ String serviceName = service.getName();
+ ServiceApiUtil.validateNameFormat(serviceName, getConfig());
+ ServiceApiUtil.validateAndResolveService(service, fs, getConfig());
+ verifyNoLiveAppInRM(serviceName, "create");
+ Path appDir = checkAppNotExistOnHdfs(service);
+
+ // Write the definition first and then submit - AM will read the definition
+ createDirAndPersistApp(appDir, service);
+ ApplicationId appId = submitApp(service);
+ cachedAppIds.put(serviceName, appId);
+ service.setId(appId.toString());
+ // update app definition with appId
+ persistAppDef(appDir, service);
+ return appId;
+ }
+
+ // Called by ServiceCLI
+ protected int actionFlexByCLI(ClientArgs args)
+ throws YarnException, IOException {
+ ActionFlexArgs flexArgs = args.getActionFlexArgs();
+ Map<String, Long> componentCounts =
+ new HashMap<>(flexArgs.getComponentMap().size());
+ Service persistedService =
+ ServiceApiUtil.loadService(fs, flexArgs.getClusterName());
+ if (!StringUtils.isEmpty(persistedService.getId())) {
+ cachedAppIds.put(persistedService.getName(),
+ ApplicationId.fromString(persistedService.getId()));
+ } else {
+ throw new YarnException(persistedService.getName()
+ + " appId is null, may be not submitted to YARN yet");
+ }
+
+ for (Map.Entry<String, String> entry : flexArgs.getComponentMap()
+ .entrySet()) {
+ String compName = entry.getKey();
+ ServiceApiUtil.validateNameFormat(compName, getConfig());
+ Component component = persistedService.getComponent(compName);
+ if (component == null) {
+ throw new IllegalArgumentException(entry.getKey() + " does not exist !");
+ }
+ long numberOfContainers =
+ parseNumberOfContainers(component, entry.getValue());
+ componentCounts.put(compName, numberOfContainers);
+ }
+ // throw usage exception if no changes proposed
+ if (componentCounts.size() == 0) {
+ actionHelp(ACTION_FLEX, args);
+ }
+ flexComponents(args.getClusterName(), componentCounts, persistedService);
+ return EXIT_SUCCESS;
+ }
+
+ // Parse the number of containers requested by user, e.g.
+ // +5 means add 5 additional containers
+ // -5 means reduce 5 containers, if it goes to negative, sets it to 0
+ // 5 means sets it to 5 containers.
+ private long parseNumberOfContainers(Component component, String newNumber) {
+
+ long orig = component.getNumberOfContainers();
+ if (newNumber.startsWith("+")) {
+ return orig + Long.parseLong(newNumber.substring(1));
+ } else if (newNumber.startsWith("-")) {
+ long ret = orig - Long.parseLong(newNumber.substring(1));
+ if (ret < 0) {
+ LOG.warn(MessageFormat.format(
+ "[COMPONENT {}]: component count goes to negative ({}{} = {}), reset it to 0.",
+ component.getName(), orig, newNumber, ret));
+ ret = 0;
+ }
+ return ret;
+ } else {
+ return Long.parseLong(newNumber);
+ }
+ }
+
+ // Called by Rest Service
+ public Map<String, Long> flexByRestService(String serviceName,
+ Map<String, Long> componentCounts) throws YarnException, IOException {
+ // load app definition
+ Service persistedService = ServiceApiUtil.loadService(fs, serviceName);
+ if (StringUtils.isEmpty(persistedService.getId())) {
+ throw new YarnException(
+ serviceName + " appId is null, may be not submitted to YARN yet");
+ }
+ cachedAppIds.put(persistedService.getName(),
+ ApplicationId.fromString(persistedService.getId()));
+ return flexComponents(serviceName, componentCounts, persistedService);
+ }
+
+ private Map<String, Long> flexComponents(String serviceName,
+ Map<String, Long> componentCounts, Service persistedService)
+ throws YarnException, IOException {
+ ServiceApiUtil.validateNameFormat(serviceName, getConfig());
+
+ Map<String, Long> original = new HashMap<>(componentCounts.size());
+
+ ComponentCountProto.Builder countBuilder = ComponentCountProto.newBuilder();
+ FlexComponentsRequestProto.Builder requestBuilder =
+ FlexComponentsRequestProto.newBuilder();
+
+ for (Component persistedComp : persistedService.getComponents()) {
+ String name = persistedComp.getName();
+ if (componentCounts.containsKey(persistedComp.getName())) {
+ original.put(name, persistedComp.getNumberOfContainers());
+ persistedComp.setNumberOfContainers(componentCounts.get(name));
+
+ // build the request
+ countBuilder.setName(persistedComp.getName())
+ .setNumberOfContainers(persistedComp.getNumberOfContainers());
+ requestBuilder.addComponents(countBuilder.build());
+ }
+ }
+ if (original.size() < componentCounts.size()) {
+ componentCounts.keySet().removeAll(original.keySet());
+ throw new YarnException("Components " + componentCounts.keySet()
+ + " do not exist in app definition.");
+ }
+ jsonSerDeser
+ .save(fs.getFileSystem(), ServiceApiUtil.getServiceJsonPath(fs, serviceName),
+ persistedService, true);
+
+ ApplicationReport appReport =
+ yarnClient.getApplicationReport(getAppId(serviceName));
+ if (appReport.getYarnApplicationState() != RUNNING) {
+ String message =
+ serviceName + " is at " + appReport.getYarnApplicationState()
+ + " state, flex can only be invoked when service is running";
+ LOG.error(message);
+ throw new YarnException(message);
+ }
+ if (StringUtils.isEmpty(appReport.getHost())) {
+ throw new YarnException(serviceName + " AM hostname is empty");
+ }
+ ClientAMProtocol proxy =
+ createAMProxy(appReport.getHost(), appReport.getRpcPort());
+ proxy.flexComponents(requestBuilder.build());
+ for (Map.Entry<String, Long> entry : original.entrySet()) {
+ LOG.info("[COMPONENT {}]: number of containers changed from {} to {}",
+ entry.getKey(), entry.getValue(),
+ componentCounts.get(entry.getKey()));
+ }
+ return original;
+ }
+
+ public int actionStop(String serviceName, boolean waitForAppStopped)
+ throws YarnException, IOException {
+ ServiceApiUtil.validateNameFormat(serviceName, getConfig());
+ ApplicationId currentAppId = getAppId(serviceName);
+ ApplicationReport report = yarnClient.getApplicationReport(currentAppId);
+ if (terminatedStates.contains(report.getYarnApplicationState())) {
+ LOG.info("Service {} is already in a terminated state {}", serviceName,
+ report.getYarnApplicationState());
+ return EXIT_SUCCESS;
+ }
+ if (preRunningStates.contains(report.getYarnApplicationState())) {
+ String msg = serviceName + " is at " + report.getYarnApplicationState()
+ + ", forcefully killed by user!";
+ yarnClient.killApplication(currentAppId, msg);
+ LOG.info(msg);
+ return EXIT_SUCCESS;
+ }
+ if (StringUtils.isEmpty(report.getHost())) {
+ throw new YarnException(serviceName + " AM hostname is empty");
+ }
+ LOG.info("Stopping service {}, with appId = {}", serviceName, currentAppId);
+ try {
+ ClientAMProtocol proxy =
+ createAMProxy(report.getHost(), report.getRpcPort());
+ cachedAppIds.remove(serviceName);
+ if (proxy != null) {
+ // try to stop the app gracefully.
+ StopRequestProto request = StopRequestProto.newBuilder().build();
+ proxy.stop(request);
+ LOG.info("Service " + serviceName + " is being gracefully stopped...");
+ } else {
+ yarnClient.killApplication(currentAppId,
+ serviceName + " is forcefully killed by user!");
+ LOG.info("Forcefully kill the service: " + serviceName);
+ return EXIT_SUCCESS;
+ }
+
+ if (!waitForAppStopped) {
+ return EXIT_SUCCESS;
+ }
+ // Wait until the app is killed.
+ long startTime = System.currentTimeMillis();
+ int pollCount = 0;
+ while (true) {
+ Thread.sleep(2000);
+ report = yarnClient.getApplicationReport(currentAppId);
+ if (terminatedStates.contains(report.getYarnApplicationState())) {
+ LOG.info("Service " + serviceName + " is stopped.");
+ break;
+ }
+ // Forcefully kill after 10 seconds.
+ if ((System.currentTimeMillis() - startTime) > 10000) {
+ LOG.info("Stop operation timeout stopping, forcefully kill the app "
+ + serviceName);
+ yarnClient.killApplication(currentAppId,
+ "Forcefully kill the app by user");
+ break;
+ }
+ if (++pollCount % 10 == 0) {
+ LOG.info("Waiting for service " + serviceName + " to be stopped.");
+ }
+ }
+ } catch (IOException | YarnException | InterruptedException e) {
+ LOG.info("Failed to stop " + serviceName
+ + " gracefully, forcefully kill the app.");
+ yarnClient.killApplication(currentAppId, "Forcefully kill the app");
+ }
+ return EXIT_SUCCESS;
+ }
+
+ public int actionDestroy(String serviceName) throws Exception {
+ ServiceApiUtil.validateNameFormat(serviceName, getConfig());
+ verifyNoLiveAppInRM(serviceName, "Destroy");
+ Path appDir = fs.buildClusterDirPath(serviceName);
+ FileSystem fileSystem = fs.getFileSystem();
+ // remove from the appId cache
+ cachedAppIds.remove(serviceName);
+ if (fileSystem.exists(appDir)) {
+ if (fileSystem.delete(appDir, true)) {
+ LOG.info("Successfully deleted service dir for " + serviceName + ": "
+ + appDir);
+ } else {
+ String message =
+ "Failed to delete service + " + serviceName + " at: " + appDir;
+ LOG.info(message);
+ throw new YarnException(message);
+ }
+ }
+ deleteZKNode(serviceName);
+ String registryPath = ServiceRegistryUtils.registryPathForInstance(serviceName);
+ try {
+ getRegistryClient().delete(registryPath, true);
+ } catch (IOException e) {
+ LOG.warn("Error deleting registry entry {}", registryPath, e);
+ }
+ LOG.info("Destroyed cluster {}", serviceName);
+ return EXIT_SUCCESS;
+ }
+
+ private synchronized RegistryOperations getRegistryClient()
+ throws SliderException, IOException {
+
+ if (registryClient == null) {
+ registryClient =
+ RegistryOperationsFactory.createInstance("ServiceClient", getConfig());
+ registryClient.init(getConfig());
+ registryClient.start();
+ }
+ return registryClient;
+ }
+
+ private void deleteZKNode(String clusterName) throws Exception {
+ CuratorFramework curatorFramework = getCuratorClient();
+ String user = RegistryUtils.currentUser();
+ String zkPath = ServiceRegistryUtils.mkClusterPath(user, clusterName);
+ if (curatorFramework.checkExists().forPath(zkPath) != null) {
+ curatorFramework.delete().deletingChildrenIfNeeded().forPath(zkPath);
+ LOG.info("Deleted zookeeper path: " + zkPath);
+ }
+ }
+
+ private synchronized CuratorFramework getCuratorClient()
+ throws BadConfigException {
+ String registryQuorum =
+ getConfig().get(RegistryConstants.KEY_REGISTRY_ZK_QUORUM);
+
+ // though if neither is set: trouble
+ if (SliderUtils.isUnset(registryQuorum)) {
+ throw new BadConfigException(
+ "No Zookeeper quorum provided in the" + " configuration property "
+ + RegistryConstants.KEY_REGISTRY_ZK_QUORUM);
+ }
+ ZookeeperUtils.splitToHostsAndPortsStrictly(registryQuorum);
+
+ if (curatorClient == null) {
+ curatorClient =
+ CuratorFrameworkFactory.builder().connectString(registryQuorum)
+ .sessionTimeoutMs(10000).retryPolicy(new RetryNTimes(5, 2000))
+ .build();
+ curatorClient.start();
+ }
+ return curatorClient;
+ }
+
+ private int actionHelp(String actionName, CommonArgs args)
+ throws YarnException, IOException {
+ throw new UsageException(CommonArgs.usage(args, actionName));
+ }
+
+ private void verifyNoLiveAppInRM(String serviceName, String action)
+ throws IOException, YarnException {
+ Set<String> types = new HashSet<>(1);
+ types.add(YarnServiceConstants.APP_TYPE);
+ Set<String> tags = null;
+ if (serviceName != null) {
+ tags = Collections.singleton(SliderUtils.createNameTag(serviceName));
+ }
+ GetApplicationsRequest request = GetApplicationsRequest.newInstance();
+ request.setApplicationTypes(types);
+ request.setApplicationTags(tags);
+ request.setApplicationStates(liveStates);
+ List<ApplicationReport> reports = yarnClient.getApplications(request);
+ if (!reports.isEmpty()) {
+ throw new YarnException(
+ "Failed to " + action + " service, as " + serviceName
+ + " already exists.");
+ }
+ }
+
+ private ApplicationId submitApp(Service app)
+ throws IOException, YarnException {
+ String serviceName = app.getName();
+ Configuration conf = getConfig();
+ Path appRootDir = fs.buildClusterDirPath(app.getName());
+
+ YarnClientApplication yarnApp = yarnClient.createApplication();
+ ApplicationSubmissionContext submissionContext =
+ yarnApp.getApplicationSubmissionContext();
+ ServiceApiUtil.validateCompResourceSize(
+ yarnApp.getNewApplicationResponse().getMaximumResourceCapability(),
+ app);
+
+ submissionContext.setKeepContainersAcrossApplicationAttempts(true);
+ if (app.getLifetime() > 0) {
+ Map<ApplicationTimeoutType, Long> appTimeout = new HashMap<>();
+ appTimeout.put(ApplicationTimeoutType.LIFETIME, app.getLifetime());
+ submissionContext.setApplicationTimeouts(appTimeout);
+ }
+ submissionContext.setMaxAppAttempts(conf.getInt(
+ YarnServiceConf.AM_RESTART_MAX, 2));
+
+ Map<String, LocalResource> localResources = new HashMap<>();
+
+ // copy local slideram-log4j.properties to hdfs and add to localResources
+ boolean hasAMLog4j =
+ addAMLog4jResource(serviceName, conf, localResources);
+ // copy jars to hdfs and add to localResources
+ addJarResource(serviceName, localResources);
+ // add keytab if in secure env
+ addKeytabResourceIfSecure(fs, localResources, conf, serviceName);
+ if (LOG.isDebugEnabled()) {
+ printLocalResources(localResources);
+ }
+ Map<String, String> env = addAMEnv(conf);
+
+ // create AM CLI
+ String cmdStr =
+ buildCommandLine(serviceName, conf, appRootDir, hasAMLog4j);
+ submissionContext.setResource(Resource.newInstance(YarnServiceConf
+ .getLong(YarnServiceConf.AM_RESOURCE_MEM, YarnServiceConf.DEFAULT_KEY_AM_RESOURCE_MEM,
+ app.getConfiguration(), conf), 1));
+ String queue = app.getQueue();
+ if (StringUtils.isEmpty(queue)) {
+ queue = conf.get(YARN_QUEUE, "default");
+ }
+ submissionContext.setQueue(queue);
+ submissionContext.setApplicationName(serviceName);
+ submissionContext.setApplicationType(YarnServiceConstants.APP_TYPE);
+ Set<String> appTags =
+ AbstractClientProvider.createApplicationTags(serviceName, null, null);
+ if (!appTags.isEmpty()) {
+ submissionContext.setApplicationTags(appTags);
+ }
+ ContainerLaunchContext amLaunchContext =
+ Records.newRecord(ContainerLaunchContext.class);
+ amLaunchContext.setCommands(Collections.singletonList(cmdStr));
+ amLaunchContext.setEnvironment(env);
+ amLaunchContext.setLocalResources(localResources);
+ submissionContext.setAMContainerSpec(amLaunchContext);
+ yarnClient.submitApplication(submissionContext);
+ return submissionContext.getApplicationId();
+ }
+
+ private void printLocalResources(Map<String, LocalResource> map) {
+ LOG.debug("Added LocalResource for localization: ");
+ StringBuilder builder = new StringBuilder();
+ for (Map.Entry<String, LocalResource> entry : map.entrySet()) {
+ builder.append(entry.getKey()).append(" -> ")
+ .append(entry.getValue().getResource().getFile())
+ .append(System.lineSeparator());
+ }
+ LOG.debug(builder.toString());
+ }
+
+ private String buildCommandLine(String serviceName, Configuration conf,
+ Path appRootDir, boolean hasSliderAMLog4j) throws BadConfigException {
+ JavaCommandLineBuilder CLI = new JavaCommandLineBuilder();
+ CLI.forceIPv4().headless();
+ //TODO CLI.setJVMHeap
+ //TODO CLI.addJVMOPTS
+ if (hasSliderAMLog4j) {
+ CLI.sysprop(SYSPROP_LOG4J_CONFIGURATION, YARN_SERVICE_LOG4J_FILENAME);
+ CLI.sysprop(SYSPROP_LOG_DIR, ApplicationConstants.LOG_DIR_EXPANSION_VAR);
+ }
+ CLI.add(ServiceMaster.class.getCanonicalName());
+ CLI.add(ACTION_CREATE, serviceName);
+ //TODO debugAM CLI.add(Arguments.ARG_DEBUG)
+ CLI.add(Arguments.ARG_CLUSTER_URI, new Path(appRootDir, serviceName + ".json"));
+ // pass the registry binding
+ CLI.addConfOptionToCLI(conf, RegistryConstants.KEY_REGISTRY_ZK_ROOT,
+ RegistryConstants.DEFAULT_ZK_REGISTRY_ROOT);
+ CLI.addMandatoryConfOption(conf, RegistryConstants.KEY_REGISTRY_ZK_QUORUM);
+
+ // write out the path output
+ CLI.addOutAndErrFiles(STDOUT_AM, STDERR_AM);
+ String cmdStr = CLI.build();
+ LOG.info("AM launch command: {}", cmdStr);
+ return cmdStr;
+ }
+
+ private Map<String, String> addAMEnv(Configuration conf) throws IOException {
+ Map<String, String> env = new HashMap<>();
+ ClasspathConstructor classpath =
+ buildClasspath(YarnServiceConstants.SUBMITTED_CONF_DIR, "lib", fs, getConfig()
+ .getBoolean(YarnConfiguration.IS_MINI_YARN_CLUSTER, false));
+ env.put("CLASSPATH", classpath.buildClasspath());
+ env.put("LANG", "en_US.UTF-8");
+ env.put("LC_ALL", "en_US.UTF-8");
+ env.put("LANGUAGE", "en_US.UTF-8");
+ String jaas = System.getenv("HADOOP_JAAS_DEBUG");
+ if (jaas != null) {
+ env.put("HADOOP_JAAS_DEBUG", jaas);
+ }
+ if (!UserGroupInformation.isSecurityEnabled()) {
+ String userName = UserGroupInformation.getCurrentUser().getUserName();
+ LOG.info("Run as user " + userName);
+ // HADOOP_USER_NAME env is used by UserGroupInformation when log in
+ // This env makes AM run as this user
+ env.put("HADOOP_USER_NAME", userName);
+ }
+ LOG.info("AM env: \n{}", stringifyMap(env));
+ return env;
+ }
+
+ protected Path addJarResource(String serviceName,
+ Map<String, LocalResource> localResources)
+ throws IOException, SliderException {
+ Path libPath = fs.buildClusterDirPath(serviceName);
+ ProviderUtils
+ .addProviderJar(localResources, ServiceMaster.class, SERVICE_CORE_JAR, fs,
+ libPath, "lib", false);
+ Path dependencyLibTarGzip = fs.getDependencyTarGzip();
+ if (fs.isFile(dependencyLibTarGzip)) {
+ LOG.info("Loading lib tar from " + fs.getFileSystem().getScheme() + ":/"
+ + dependencyLibTarGzip);
+ SliderUtils.putAmTarGzipAndUpdate(localResources, fs);
+ } else {
+ String[] libs = SliderUtils.getLibDirs();
+ for (String libDirProp : libs) {
+ ProviderUtils.addAllDependencyJars(localResources, fs, libPath, "lib",
+ libDirProp);
+ }
+ }
+ return libPath;
+ }
+
+ private boolean addAMLog4jResource(String serviceName, Configuration conf,
+ Map<String, LocalResource> localResources)
+ throws IOException, BadClusterStateException {
+ boolean hasAMLog4j = false;
+ String hadoopConfDir =
+ System.getenv(ApplicationConstants.Environment.HADOOP_CONF_DIR.name());
+ if (hadoopConfDir != null) {
+ File localFile =
+ new File(hadoopConfDir, YarnServiceConstants.YARN_SERVICE_LOG4J_FILENAME);
+ if (localFile.exists()) {
+ Path localFilePath = createLocalPath(localFile);
+ Path appDirPath = fs.buildClusterDirPath(serviceName);
+ Path remoteConfPath =
+ new Path(appDirPath, YarnServiceConstants.SUBMITTED_CONF_DIR);
+ Path remoteFilePath =
+ new Path(remoteConfPath, YarnServiceConstants.YARN_SERVICE_LOG4J_FILENAME);
+ copy(conf, localFilePath, remoteFilePath);
+ LocalResource localResource =
+ fs.createAmResource(remoteConfPath, LocalResourceType.FILE);
+ localResources.put(localFilePath.getName(), localResource);
+ hasAMLog4j = true;
+ } else {
+ LOG.warn("AM log4j property file doesn't exist: " + localFile);
+ }
+ }
+ return hasAMLog4j;
+ }
+
+ public int actionStart(String serviceName) throws YarnException, IOException {
+ ServiceApiUtil.validateNameFormat(serviceName, getConfig());
+ Path appDir = checkAppExistOnHdfs(serviceName);
+ Service service = ServiceApiUtil.loadService(fs, serviceName);
+ ServiceApiUtil.validateAndResolveService(service, fs, getConfig());
+ // see if it is actually running and bail out;
+ verifyNoLiveAppInRM(serviceName, "thaw");
+ ApplicationId appId = submitApp(service);
+ service.setId(appId.toString());
+ // write app definition on to hdfs
+ createDirAndPersistApp(appDir, service);
+ return 0;
+ }
+
+ private Path checkAppNotExistOnHdfs(Service service)
+ throws IOException, SliderException {
+ Path appDir = fs.buildClusterDirPath(service.getName());
+ fs.verifyDirectoryNonexistent(
+ new Path(appDir, service.getName() + ".json"));
+ return appDir;
+ }
+
+ private Path checkAppExistOnHdfs(String serviceName)
+ throws IOException, SliderException {
+ Path appDir = fs.buildClusterDirPath(serviceName);
+ fs.verifyPathExists(new Path(appDir, serviceName + ".json"));
+ return appDir;
+ }
+
+ private void createDirAndPersistApp(Path appDir, Service service)
+ throws IOException, SliderException {
+ FsPermission appDirPermission = new FsPermission("750");
+ fs.createWithPermissions(appDir, appDirPermission);
+ persistAppDef(appDir, service);
+ }
+
+ private void persistAppDef(Path appDir, Service service)
+ throws IOException {
+ Path appJson = new Path(appDir, service.getName() + ".json");
+ jsonSerDeser
+ .save(fs.getFileSystem(), appJson, service, true);
+ LOG.info(
+ "Persisted service " + service.getName() + " at " + appJson);
+ }
+
+ private void addKeytabResourceIfSecure(SliderFileSystem fileSystem,
+ Map<String, LocalResource> localResource, Configuration conf,
+ String serviceName) throws IOException, BadConfigException {
+ if (!UserGroupInformation.isSecurityEnabled()) {
+ return;
+ }
+ String keytabPreInstalledOnHost =
+ conf.get(YarnServiceConf.KEY_AM_KEYTAB_LOCAL_PATH);
+ if (StringUtils.isEmpty(keytabPreInstalledOnHost)) {
+ String amKeytabName =
+ conf.get(YarnServiceConf.KEY_AM_LOGIN_KEYTAB_NAME);
+ String keytabDir = conf.get(YarnServiceConf.KEY_HDFS_KEYTAB_DIR);
+ Path keytabPath =
+ fileSystem.buildKeytabPath(keytabDir, amKeytabName, serviceName);
+ if (fileSystem.getFileSystem().exists(keytabPath)) {
+ LocalResource keytabRes =
+ fileSystem.createAmResource(keytabPath, LocalResourceType.FILE);
+ localResource
+ .put(YarnServiceConstants.KEYTAB_DIR + "/" + amKeytabName, keytabRes);
+ LOG.info("Adding AM keytab on hdfs: " + keytabPath);
+ } else {
+ LOG.warn("No keytab file was found at {}.", keytabPath);
+ if (conf.getBoolean(YarnServiceConf.KEY_AM_LOGIN_KEYTAB_REQUIRED, false)) {
+ throw new BadConfigException("No keytab file was found at %s.",
+ keytabPath);
+ } else {
+ LOG.warn("The AM will be "
+ + "started without a kerberos authenticated identity. "
+ + "The service is therefore not guaranteed to remain "
+ + "operational beyond 24 hours.");
+ }
+ }
+ }
+ }
+
+ public String updateLifetime(String serviceName, long lifetime)
+ throws YarnException, IOException {
+ ApplicationId currentAppId = getAppId(serviceName);
+ ApplicationReport report = yarnClient.getApplicationReport(currentAppId);
+ if (report == null) {
+ throw new YarnException("Service not found for " + serviceName);
+ }
+ ApplicationId appId = report.getApplicationId();
+ LOG.info("Updating lifetime of an service: serviceName = " + serviceName
+ + ", appId = " + appId + ", lifetime = " + lifetime);
+ Map<ApplicationTimeoutType, String> map = new HashMap<>();
+ String newTimeout =
+ Times.formatISO8601(System.currentTimeMillis() + lifetime * 1000);
+ map.put(ApplicationTimeoutType.LIFETIME, newTimeout);
+ UpdateApplicationTimeoutsRequest request =
+ UpdateApplicationTimeoutsRequest.newInstance(appId, map);
+ yarnClient.updateApplicationTimeouts(request);
+ LOG.info(
+ "Successfully updated lifetime for an service: serviceName = " + serviceName
+ + ", appId = " + appId + ". New expiry time in ISO8601 format is "
+ + newTimeout);
+ return newTimeout;
+ }
+
+ public ServiceState convertState(FinalApplicationStatus status) {
+ switch (status) {
+ case UNDEFINED:
+ return ServiceState.ACCEPTED;
+ case FAILED:
+ case KILLED:
+ return ServiceState.FAILED;
+ case ENDED:
+ case SUCCEEDED:
+ return ServiceState.STOPPED;
+ }
+ return ServiceState.ACCEPTED;
+ }
+
+ public Service getStatus(String serviceName)
+ throws IOException, YarnException {
+ ServiceApiUtil.validateNameFormat(serviceName, getConfig());
+ ApplicationId currentAppId = getAppId(serviceName);
+ ApplicationReport appReport = yarnClient.getApplicationReport(currentAppId);
+ Service appSpec = new Service();
+ appSpec.setName(serviceName);
+ appSpec.setState(convertState(appReport.getFinalApplicationStatus()));
+ ApplicationTimeout lifetime =
+ appReport.getApplicationTimeouts().get(ApplicationTimeoutType.LIFETIME);
+ if (lifetime != null) {
+ appSpec.setLifetime(lifetime.getRemainingTime());
+ }
+
+ if (appReport.getYarnApplicationState() != RUNNING) {
+ LOG.info("Service {} is at {} state", serviceName,
+ appReport.getYarnApplicationState());
+ return appSpec;
+ }
+ if (StringUtils.isEmpty(appReport.getHost())) {
+ LOG.warn(serviceName + " AM hostname is empty");
+ return appSpec;
+ }
+ ClientAMProtocol amProxy =
+ createAMProxy(appReport.getHost(), appReport.getRpcPort());
+ GetStatusResponseProto response =
+ amProxy.getStatus(GetStatusRequestProto.newBuilder().build());
+ appSpec = jsonSerDeser.fromJson(response.getStatus());
+
+ return appSpec;
+ }
+
+ public YarnClient getYarnClient() {
+ return this.yarnClient;
+ }
+
+ public int actionDependency(ActionDependencyArgs args)
+ throws IOException, YarnException {
+ String currentUser = RegistryUtils.currentUser();
+ LOG.info("Running command as user {}", currentUser);
+
+ Path dependencyLibTarGzip = fs.getDependencyTarGzip();
+
+ // Check if dependency has already been uploaded, in which case log
+ // appropriately and exit success (unless overwrite has been requested)
+ if (fs.isFile(dependencyLibTarGzip) && !args.overwrite) {
+ System.out.println(String.format(
+ "Dependency libs are already uploaded to %s. Use %s "
+ + "if you want to re-upload", dependencyLibTarGzip.toUri(),
+ Arguments.ARG_OVERWRITE));
+ return EXIT_SUCCESS;
+ }
+
+ String[] libDirs = SliderUtils.getLibDirs();
+ if (libDirs.length > 0) {
+ File tempLibTarGzipFile = File.createTempFile(
+ YarnServiceConstants.DEPENDENCY_TAR_GZ_FILE_NAME + "_",
+ YarnServiceConstants.DEPENDENCY_TAR_GZ_FILE_EXT);
+ // copy all jars
+ tarGzipFolder(libDirs, tempLibTarGzipFile, createJarFilter());
+
+ LOG.info("Version Info: " + VersionInfo.getBuildVersion());
+ fs.copyLocalFileToHdfs(tempLibTarGzipFile, dependencyLibTarGzip,
+ new FsPermission(YarnServiceConstants.DEPENDENCY_DIR_PERMISSIONS));
+ return EXIT_SUCCESS;
+ } else {
+ return EXIT_FALSE;
+ }
+ }
+
+ protected ClientAMProtocol createAMProxy(String host, int port)
+ throws IOException {
+ InetSocketAddress address =
+ NetUtils.createSocketAddrForHost(host, port);
+ return ClientAMProxy.createProxy(getConfig(), ClientAMProtocol.class,
+ UserGroupInformation.getCurrentUser(), rpc, address);
+ }
+
+ private synchronized ApplicationId getAppId(String serviceName)
+ throws IOException, YarnException {
+ if (cachedAppIds.containsKey(serviceName)) {
+ return cachedAppIds.get(serviceName);
+ }
+ Service persistedService = ServiceApiUtil.loadService(fs, serviceName);
+ if (persistedService == null) {
+ throw new YarnException("Service " + serviceName
+ + " doesn't exist on hdfs. Please check if the app exists in RM");
+ }
+ ApplicationId currentAppId = ApplicationId.fromString(persistedService.getId());
+ cachedAppIds.put(serviceName, currentAppId);
+ return currentAppId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractActionArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractActionArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractActionArgs.java
new file mode 100644
index 0000000..ea3bb0a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractActionArgs.java
@@ -0,0 +1,158 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameter;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException;
+import org.apache.hadoop.yarn.service.exceptions.ErrorStrings;
+import org.apache.hadoop.yarn.service.exceptions.UsageException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Base args for all actions
+ */
+public abstract class AbstractActionArgs extends ArgOps implements Arguments {
+ protected static final Logger log =
+ LoggerFactory.getLogger(AbstractActionArgs.class);
+
+
+ protected AbstractActionArgs() {
+ }
+
+ /**
+ * URI/binding to the filesystem
+ */
+ @Parameter(names = {ARG_FILESYSTEM, ARG_FILESYSTEM_LONG},
+ description = "Filesystem Binding")
+ public String filesystemBinding;
+
+ @Parameter(names = {ARG_BASE_PATH},
+ description = "Service base path on the filesystem",
+ converter = PathArgumentConverter.class)
+ public Path basePath;
+
+ /**
+ * This is the default parameter
+ */
+ @Parameter
+ public final List<String> parameters = new ArrayList<>();
+
+ /**
+ * get the name: relies on arg 1 being the cluster name in all operations
+ * @return the name argument, null if there is none
+ */
+ public String getClusterName() {
+ return (parameters.isEmpty()) ? null : parameters.get(0);
+ }
+
+ /**
+ -D name=value
+
+ Define an configuration option which overrides any options in
+ the configuration XML files of the image or in the image configuration
+ directory. The values will be persisted.
+ Configuration options are only passed to the cluster when creating or reconfiguring a cluster.
+
+ */
+
+ @Parameter(names = ARG_DEFINE, arity = 1, description = "Definitions")
+ public final List<String> definitions = new ArrayList<>();
+
+ /**
+ * System properties
+ */
+ @Parameter(names = {ARG_SYSPROP}, arity = 1,
+ description = "system properties in the form name value" +
+ " These are set after the JVM is started.")
+ public final List<String> sysprops = new ArrayList<>(0);
+
+
+ @Parameter(names = {ARG_MANAGER_SHORT, ARG_MANAGER},
+ description = "Binding (usually hostname:port) of the YARN resource manager")
+ public String manager;
+
+
+ @Parameter(names = ARG_DEBUG, description = "Debug mode")
+ public boolean debug = false;
+
+ @Parameter(names = {ARG_HELP}, description = "Help", help = true)
+ public boolean help = false;
+
+ /**
+ * Get the min #of params expected
+ * @return the min number of params in the {@link #parameters} field
+ */
+ public int getMinParams() {
+ return 1;
+ }
+
+ /**
+ * Get the name of the action
+ * @return the action name
+ */
+ public abstract String getActionName() ;
+
+ /**
+ * Get the max #of params expected
+ * @return the number of params in the {@link #parameters} field;
+ */
+ public int getMaxParams() {
+ return getMinParams();
+ }
+
+ public void validate() throws BadCommandArgumentsException, UsageException {
+
+ int minArgs = getMinParams();
+ int actionArgSize = parameters.size();
+ if (minArgs > actionArgSize) {
+ throw new BadCommandArgumentsException(
+ ErrorStrings.ERROR_NOT_ENOUGH_ARGUMENTS + getActionName() +
+ ", Expected minimum " + minArgs + " but got " + actionArgSize);
+ }
+ int maxArgs = getMaxParams();
+ if (maxArgs == -1) {
+ maxArgs = minArgs;
+ }
+ if (actionArgSize > maxArgs) {
+ String message = String.format("%s for action %s: limit is %d but saw %d: ",
+ ErrorStrings.ERROR_TOO_MANY_ARGUMENTS,
+ getActionName(), maxArgs,
+ actionArgSize);
+
+ log.error(message);
+ int index = 1;
+ StringBuilder buf = new StringBuilder(message);
+ for (String actionArg : parameters) {
+ log.error("[{}] \"{}\"", index++, actionArg);
+ buf.append(" \"").append(actionArg).append("\" ");
+ }
+ throw new BadCommandArgumentsException(buf.toString());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + ": " + getActionName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractArgsDelegate.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractArgsDelegate.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractArgsDelegate.java
new file mode 100644
index 0000000..457e357
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractArgsDelegate.java
@@ -0,0 +1,28 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import org.apache.hadoop.yarn.service.client.params.ArgOps;
+import org.apache.hadoop.yarn.service.client.params.Arguments;
+
+/**
+ * Base class for all the delegates
+ */
+public class AbstractArgsDelegate extends ArgOps implements Arguments {
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractClusterBuildingActionArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractClusterBuildingActionArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractClusterBuildingActionArgs.java
new file mode 100644
index 0000000..3a3a19a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractClusterBuildingActionArgs.java
@@ -0,0 +1,58 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParametersDelegate;
+import com.google.common.annotations.VisibleForTesting;
+import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstract Action to build things; shares args across build and
+ * list
+ */
+public abstract class AbstractClusterBuildingActionArgs
+ extends AbstractActionArgs {
+ @Parameter(names = {ARG_APPDEF},
+ description = "Template service definition file in JSON format.")
+ public File appDef;
+
+ public File getAppDef() {
+ return appDef;
+ }
+
+ @Parameter(names = {
+ ARG_QUEUE }, description = "Queue to submit the service")
+ public String queue;
+
+ @Parameter(names = {
+ ARG_LIFETIME }, description = "Lifetime of the service from the time of request")
+ public long lifetime;
+
+ @ParametersDelegate
+ public ComponentArgsDelegate componentDelegate = new ComponentArgsDelegate();
+
+ @ParametersDelegate
+ public OptionArgsDelegate optionsDelegate =
+ new OptionArgsDelegate();
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionBuildArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionBuildArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionBuildArgs.java
new file mode 100644
index 0000000..c2ff545
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionBuildArgs.java
@@ -0,0 +1,31 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameters;
+
+@Parameters(commandNames = { SliderActions.ACTION_BUILD},
+ commandDescription = SliderActions.DESCRIBE_ACTION_BUILD)
+
+public class ActionBuildArgs extends AbstractClusterBuildingActionArgs {
+
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_BUILD;
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionClientArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionClientArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionClientArgs.java
new file mode 100644
index 0000000..c43d61a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionClientArgs.java
@@ -0,0 +1,71 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs;
+import org.apache.hadoop.yarn.service.client.params.SliderActions;
+
+import java.io.File;
+
+@Parameters(commandNames = { SliderActions.ACTION_CLIENT},
+ commandDescription = SliderActions.DESCRIBE_ACTION_CLIENT)
+
+public class ActionClientArgs extends AbstractActionArgs {
+
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_CLIENT;
+ }
+
+ @Parameter(names = {ARG_INSTALL},
+ description = "Install client")
+ public boolean install;
+
+ @Parameter(names = {ARG_NAME},
+ description = "The name of the service")
+ public String name;
+
+ @Parameter(names = {ARG_PACKAGE},
+ description = "Path to app package")
+ public String packageURI;
+
+ @Parameter(names = {ARG_DEST},
+ description = "The location where to install the client")
+ public File installLocation;
+
+ @Parameter(names = {ARG_CONFIG},
+ description = "Client configuration")
+ public File clientConfig;
+
+ /**
+ * Get the min #of params expected
+ *
+ * @return the min number of params in the {@link #parameters} field
+ */
+ public int getMinParams() {
+ return 0;
+ }
+
+ @Override
+ public int getMaxParams() {
+ return 1;
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionCreateArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionCreateArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionCreateArgs.java
new file mode 100644
index 0000000..eecffb6
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionCreateArgs.java
@@ -0,0 +1,33 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameters;
+
+@Parameters(commandNames = { SliderActions.ACTION_CREATE},
+ commandDescription = SliderActions.DESCRIBE_ACTION_CREATE)
+
+public class ActionCreateArgs extends AbstractClusterBuildingActionArgs {
+
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_CREATE;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDependencyArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDependencyArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDependencyArgs.java
new file mode 100644
index 0000000..51e07c9
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDependencyArgs.java
@@ -0,0 +1,65 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException;
+import org.apache.hadoop.yarn.service.exceptions.UsageException;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+
+@Parameters(commandNames = { SliderActions.ACTION_DEPENDENCY },
+ commandDescription = SliderActions.DESCRIBE_ACTION_DEPENDENCY)
+public class ActionDependencyArgs extends AbstractActionArgs {
+
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_DEPENDENCY;
+ }
+
+ @Parameter(names = { ARG_UPLOAD },
+ description = "Upload AM and agent libraries to HDFS for this client")
+ public boolean upload;
+
+ @Parameter(names = { ARG_OVERWRITE },
+ description = "Overwrite current uploaded dependency libs")
+ public boolean overwrite = false;
+
+ /**
+ * Get the min #of params expected
+ *
+ * @return the min number of params in the {@link #parameters} field
+ */
+ public int getMinParams() {
+ return 0;
+ }
+
+ @Override
+ public int getMaxParams() {
+ return 1;
+ }
+
+ @Override
+ public void validate() throws BadCommandArgumentsException, UsageException {
+ super.validate();
+
+ if (!upload) {
+ throw new UsageException("Option " + ARG_UPLOAD + " is mandatory");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDestroyArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDestroyArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDestroyArgs.java
new file mode 100644
index 0000000..8c41c04
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDestroyArgs.java
@@ -0,0 +1,37 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+
+@Parameters(commandNames = { SliderActions.ACTION_DESTROY},
+ commandDescription = SliderActions.DESCRIBE_ACTION_DESTROY)
+
+public class ActionDestroyArgs extends AbstractActionArgs {
+
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_DESTROY;
+ }
+
+ @Parameter(names = {ARG_FORCE},
+ description = "force the operation")
+ public boolean force;
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionExistsArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionExistsArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionExistsArgs.java
new file mode 100644
index 0000000..088ad47
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionExistsArgs.java
@@ -0,0 +1,49 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs;
+import org.apache.hadoop.yarn.service.client.params.SliderActions;
+
+import java.io.File;
+
+@Parameters(commandNames = { SliderActions.ACTION_EXISTS},
+ commandDescription = SliderActions.DESCRIBE_ACTION_EXISTS)
+
+public class ActionExistsArgs extends AbstractActionArgs {
+
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_EXISTS;
+ }
+
+ @Parameter(names = {ARG_LIVE},
+ description = "verify that the service is running")
+ public boolean live;
+
+ @Parameter(names = {ARG_STATE},
+ description = "verify that the service is in the specific YARN state")
+ public String state = "";
+
+ @Parameter(names = {ARG_OUTPUT, ARG_OUTPUT_SHORT},
+ description = "output file for any service report")
+ public File out;
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFlexArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFlexArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFlexArgs.java
new file mode 100644
index 0000000..b7acf58
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFlexArgs.java
@@ -0,0 +1,50 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameters;
+import com.beust.jcommander.ParametersDelegate;
+import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException;
+
+import java.util.List;
+import java.util.Map;
+
+@Parameters(commandNames = { SliderActions.ACTION_FLEX},
+ commandDescription = SliderActions.DESCRIBE_ACTION_FLEX)
+
+public class ActionFlexArgs extends AbstractActionArgs {
+
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_FLEX;
+ }
+
+ @ParametersDelegate
+ public ComponentArgsDelegate componentDelegate = new ComponentArgsDelegate();
+
+ /**
+ * Get the component mapping (may be empty, but never null)
+ * @return mapping
+ * @throws BadCommandArgumentsException parse problem
+ */
+ public Map<String, String> getComponentMap() throws
+ BadCommandArgumentsException {
+ return componentDelegate.getComponentMap();
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFreezeArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFreezeArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFreezeArgs.java
new file mode 100644
index 0000000..aecf0eb
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFreezeArgs.java
@@ -0,0 +1,56 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import com.beust.jcommander.ParametersDelegate;
+
+@Parameters(commandNames = { SliderActions.ACTION_STOP },
+ commandDescription = SliderActions.DESCRIBE_ACTION_FREEZE)
+
+public class ActionFreezeArgs extends AbstractActionArgs implements
+ WaitTimeAccessor {
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_STOP;
+ }
+
+ public static final String FREEZE_COMMAND_ISSUED = "stop command issued";
+ @ParametersDelegate
+ public WaitArgsDelegate waitDelegate = new WaitArgsDelegate();
+
+ @Override
+ public int getWaittime() {
+ return waitDelegate.getWaittime();
+ }
+
+ @Override
+ public void setWaittime(int waittime) {
+ waitDelegate.setWaittime(waittime);
+ }
+
+ @Parameter(names={ARG_MESSAGE},
+ description = "reason for the operation")
+ public String message = FREEZE_COMMAND_ISSUED;
+
+ @Parameter(names = {ARG_FORCE},
+ description = "force the operation")
+ public boolean force;
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionHelpArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionHelpArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionHelpArgs.java
new file mode 100644
index 0000000..51aa88a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionHelpArgs.java
@@ -0,0 +1,44 @@
+/*
+ * 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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameters;
+import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs;
+import org.apache.hadoop.yarn.service.client.params.SliderActions;
+
+/**
+ * The Help command
+ */
+@Parameters(commandNames = { SliderActions.ACTION_HELP},
+ commandDescription = SliderActions.DESCRIBE_ACTION_HELP)
+public class ActionHelpArgs extends AbstractActionArgs {
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_HELP;
+ }
+
+ /**
+ * Get the min #of params expected
+ * @return the min number of params in the {@link #parameters} field
+ */
+ @Override
+ public int getMinParams() {
+ return 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKDiagArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKDiagArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKDiagArgs.java
new file mode 100644
index 0000000..061121e
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKDiagArgs.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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.hadoop.yarn.service.utils.SliderUtils;
+import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException;
+import org.apache.hadoop.yarn.service.exceptions.UsageException;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+@Parameters(commandNames = { SliderActions.ACTION_KDIAG},
+ commandDescription = SliderActions.DESCRIBE_ACTION_KDIAG)
+
+public class ActionKDiagArgs extends AbstractActionArgs {
+
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_KDIAG;
+ }
+
+ @Parameter(names = {ARG_SERVICES}, variableArity = true,
+ description =" list of services to check")
+ public List<String> services = new ArrayList<>();
+
+ @Parameter(names = {ARG_OUTPUT, ARG_OUTPUT_SHORT},
+ description = "output file for report")
+ public File out;
+
+ @Parameter(names = {ARG_KEYTAB}, description = "keytab to use")
+ public File keytab;
+
+ @Parameter(names = {ARG_KEYLEN}, description = "minimum key length")
+ public int keylen = 256;
+
+ @Parameter(names = {ARG_PRINCIPAL}, description = "principal to log in from a keytab")
+ public String principal;
+
+ @Parameter(names = {ARG_SECURE}, description = "Is security required")
+ public boolean secure = false;
+
+ @Override
+ public int getMinParams() {
+ return 0;
+ }
+
+ @Override
+ public void validate() throws BadCommandArgumentsException, UsageException {
+ super.validate();
+ if (keytab != null && SliderUtils.isUnset(principal)) {
+ throw new UsageException("Missing argument " + ARG_PRINCIPAL);
+ }
+ if (keytab == null && SliderUtils.isSet(principal)) {
+ throw new UsageException("Missing argument " + ARG_KEYTAB);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKeytabArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKeytabArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKeytabArgs.java
new file mode 100644
index 0000000..7e51457
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKeytabArgs.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.hadoop.yarn.service.client.params;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs;
+import org.apache.hadoop.yarn.service.client.params.SliderActions;
+
+@Parameters(commandNames = { SliderActions.ACTION_KEYTAB},
+ commandDescription = SliderActions.DESCRIBE_ACTION_KEYTAB)
+
+public class ActionKeytabArgs extends AbstractActionArgs {
+
+ public ActionKeytabArgs() {
+ super();
+ }
+
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_INSTALL_KEYTAB;
+ }
+
+ @Parameter(names = {ARG_KEYTABINSTALL},
+ description = "Install the keytab")
+ public boolean install;
+
+ @Parameter(names = {ARG_KEYTABDELETE},
+ description = "Delete the keytab")
+ public boolean delete;
+
+ @Parameter(names = {ARG_KEYTABLIST},
+ description = "List of installed keytabs")
+ public boolean list;
+
+ @Parameter(names = {ARG_KEYTAB},
+ description = "Path or name of the keytab")
+ public String keytab;
+
+ @Parameter(names = {ARG_FOLDER},
+ description = "The name of the folder in which to store the keytab")
+ public String folder;
+
+ @Parameter(names = {ARG_OVERWRITE}, description = "Overwrite existing keytab")
+ public boolean overwrite = false;
+
+ /**
+ * Get the min #of params expected
+ * @return the min number of params in the {@link #parameters} field
+ */
+ public int getMinParams() {
+ return 0;
+ }
+
+ @Override
+ public int getMaxParams() {
+ return 3;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ea399dfd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionListArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionListArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionListArgs.java
new file mode 100644
index 0000000..c05e602
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionListArgs.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.hadoop.yarn.service.client.params;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs;
+import org.apache.hadoop.yarn.service.client.params.SliderActions;
+
+@Parameters(commandNames = { SliderActions.ACTION_LIST},
+ commandDescription = SliderActions.DESCRIBE_ACTION_LIST)
+
+public class ActionListArgs extends AbstractActionArgs {
+ @Override
+ public String getActionName() {
+ return SliderActions.ACTION_LIST;
+ }
+
+ @Parameter(names = {ARG_LIVE},
+ description = "List only live service instances")
+ public boolean live;
+
+ @Parameter(names = {ARG_STATE},
+ description = "list only applications in the specific YARN state")
+ public String state = "";
+
+ @Parameter(names = {ARG_VERBOSE},
+ description = "print out information in details")
+ public boolean verbose = false;
+
+ @Parameter(names = {ARG_CONTAINERS},
+ description = "List containers of a service instance")
+ public boolean containers;
+
+ @Parameter(names = {ARG_VERSION},
+ description = "Filter containers by app version (used with " +
+ ARG_CONTAINERS + ")")
+ public String version;
+
+ @Parameter(names = {ARG_COMPONENTS}, variableArity = true,
+ description = "Filter containers by component names (used with " +
+ ARG_CONTAINERS + ")")
+ public Set<String> components = new HashSet<>(0);
+
+ /**
+ * Get the min #of params expected
+ * @return the min number of params in the {@link #parameters} field
+ */
+ public int getMinParams() {
+ return 0;
+ }
+
+ @Override
+ public int getMaxParams() {
+ return 1;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org