This is an automated email from the ASF dual-hosted git repository.
sankarh pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/branch-3 by this push:
new 7be7e176014 HIVE-27842: Backport of HIVE-20752, HIVE-20807 and
HIVE-21866 to branch-3 (#4848)
7be7e176014 is described below
commit 7be7e1760146d9da63a9f83b11291c7bc53edff1
Author: Sruthi Mooriyathvariam <[email protected]>
AuthorDate: Sat Nov 25 20:35:06 2023 +0530
HIVE-27842: Backport of HIVE-20752, HIVE-20807 and HIVE-21866 to branch-3
(#4848)
* HIVE-20752: In case of LLAP start failure add info how to find YARN logs
(Miklos Gergely via Ashutosh Chauhan)
* HIVE-20807: Refactor LlapStatusServiceDriver (Miklos Gergely via Sergey
Shelukhin)
* HIVE-21866: LLAP status service driver may get stuck with wrong Yarn app
ID (Adam Szita, reviewed by Marta Kuczoram)
---------
Co-authored-by: Miklos Gergely <[email protected]>
Co-authored-by: Adam Szita <[email protected]>
---------
Signed-off-by: Sankar Hariappan <[email protected]>
Closes (#4848)
---
bin/ext/llapstatus.sh | 4 +-
.../hadoop/hive/llap/cli/LlapSliderUtils.java | 55 +-
.../hive/llap/cli/LlapStatusOptionsProcessor.java | 272 --------
.../apache/hadoop/hive/llap/cli/status/AmInfo.java | 93 +++
.../hive/llap/cli/status/AppStatusBuilder.java | 231 +++++++
.../hadoop/hive/llap/cli/status/ExitCode.java | 44 ++
.../hadoop/hive/llap/cli/status/LlapInstance.java | 134 ++++
.../llap/cli/status/LlapStatusCliException.java | 40 ++
.../hive/llap/cli/status/LlapStatusHelpers.java | 449 -------------
.../cli/status/LlapStatusServiceCommandLine.java | 302 +++++++++
.../cli/{ => status}/LlapStatusServiceDriver.java | 735 +++++++++------------
.../apache/hadoop/hive/llap/cli/status/State.java | 31 +
.../hadoop/hive/llap/cli/status/package-info.java | 24 +
.../status/TestLlapStatusServiceCommandLine.java | 91 +++
.../hadoop/hive/llap/cli/status/package-info.java | 23 +
.../src/java/org/apache/hive/http/LlapServlet.java | 11 +-
16 files changed, 1344 insertions(+), 1195 deletions(-)
diff --git a/bin/ext/llapstatus.sh b/bin/ext/llapstatus.sh
index 2d2c8f4c09c..23e6be6f10e 100644
--- a/bin/ext/llapstatus.sh
+++ b/bin/ext/llapstatus.sh
@@ -17,7 +17,7 @@ THISSERVICE=llapstatus
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "
llapstatus () {
- CLASS=org.apache.hadoop.hive.llap.cli.LlapStatusServiceDriver;
+ CLASS=org.apache.hadoop.hive.llap.cli.status.LlapStatusServiceDriver;
if [ ! -f ${HIVE_LIB}/hive-cli-*.jar ]; then
echo "Missing Hive CLI Jar"
exit 3;
@@ -36,7 +36,7 @@ llapstatus () {
}
llapstatus_help () {
- CLASS=org.apache.hadoop.hive.llap.cli.LlapStatusServiceDriver;
+ CLASS=org.apache.hadoop.hive.llap.cli.status.LlapStatusServiceDriver;
execHiveCmd $CLASS "--help"
}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapSliderUtils.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapSliderUtils.java
index af47b26e566..5ec9e1d91bc 100644
--- a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapSliderUtils.java
+++ b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapSliderUtils.java
@@ -24,69 +24,24 @@ import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.yarn.api.records.ApplicationId;
-import org.apache.hadoop.yarn.api.records.ApplicationReport;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.service.api.records.Service;
import org.apache.hadoop.yarn.service.client.ServiceClient;
import org.apache.hadoop.yarn.service.utils.CoreFileSystem;
-import org.apache.hadoop.yarn.util.Clock;
-import org.apache.hadoop.yarn.util.SystemClock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LlapSliderUtils {
- private static final Logger LOG = LoggerFactory
- .getLogger(LlapSliderUtils.class);
+ private static final Logger LOG =
LoggerFactory.getLogger(LlapSliderUtils.class);
private static final String LLAP_PACKAGE_DIR = ".yarn/package/LLAP/";
- public static ServiceClient createServiceClient(
- Configuration conf) throws Exception {
+ public static ServiceClient createServiceClient(Configuration conf) throws
Exception {
ServiceClient serviceClient = new ServiceClient();
serviceClient.init(conf);
serviceClient.start();
return serviceClient;
}
- public static ApplicationReport getAppReport(String appName, ServiceClient
serviceClient,
- long timeoutMs) throws
- LlapStatusServiceDriver.LlapStatusCliException {
- Clock clock = SystemClock.getInstance();
- long startTime = clock.getTime();
- long timeoutTime = timeoutMs < 0 ? Long.MAX_VALUE : (startTime +
timeoutMs);
- ApplicationReport appReport = null;
- ApplicationId appId;
- try {
- appId = serviceClient.getAppId(appName);
- } catch (YarnException | IOException e) {
- return null;
- }
-
- while (appReport == null) {
- try {
- appReport = serviceClient.getYarnClient().getApplicationReport(appId);
- if (timeoutMs == 0) {
- // break immediately if timeout is 0
- break;
- }
- // Otherwise sleep, and try again.
- if (appReport == null) {
- long remainingTime = Math.min(timeoutTime - clock.getTime(), 500l);
- if (remainingTime > 0) {
- Thread.sleep(remainingTime);
- } else {
- break;
- }
- }
- } catch (Exception e) { // No point separating IOException vs
YarnException vs others
- throw new LlapStatusServiceDriver.LlapStatusCliException(
- LlapStatusServiceDriver.ExitCode.YARN_ERROR,
- "Failed to get Yarn AppReport", e);
- }
- }
- return appReport;
- }
-
public static Service getService(Configuration conf, String name) {
LOG.info("Get service details for " + name);
ServiceClient sc;
@@ -112,10 +67,8 @@ public class LlapSliderUtils {
return service;
}
- public static void startCluster(Configuration conf, String name,
- String packageName, Path packageDir, String queue) {
- LOG.info("Starting cluster with " + name + ", "
- + packageName + ", " + queue + ", " + packageDir);
+ public static void startCluster(Configuration conf, String name, String
packageName, Path packageDir, String queue) {
+ LOG.info("Starting cluster with " + name + ", " + packageName + ", " +
queue + ", " + packageDir);
ServiceClient sc;
try {
sc = createServiceClient(conf);
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusOptionsProcessor.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusOptionsProcessor.java
deleted file mode 100644
index e88c819b2c2..00000000000
---
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusOptionsProcessor.java
+++ /dev/null
@@ -1,272 +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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.hive.llap.cli;
-
-import java.util.Arrays;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-
-import jline.TerminalFactory;
-import org.apache.commons.cli.GnuParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.OptionBuilder;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-public class LlapStatusOptionsProcessor {
-
- private static final String LLAPSTATUS_CONSTANT = "llapstatus";
-
- private static final long FIND_YARN_APP_TIMEOUT_MS = 20 * 1000l; //
20seconds to wait for app to be visible
-
- private static final long DEFAULT_STATUS_REFRESH_INTERVAL_MS = 1 * 1000l; //
1 seconds wait until subsequent status
- private static final long DEFAULT_WATCH_MODE_TIMEOUT_MS = 5 * 60 * 1000l; //
5 minutes timeout for watch mode
- private static final float DEFAULT_RUNNING_NODES_THRESHOLD = 1.0f;
-
- // TODO: why doesn't this use one of the existing options implementations?!
- enum OptionConstants {
-
- NAME("name", 'n', "LLAP cluster name", true),
- FIND_APP_TIMEOUT("findAppTimeout", 'f',
- "Amount of time(s) that the tool will sleep to wait for the YARN
application to start. negative values=wait forever, 0=Do not wait. default=" +
- TimeUnit.SECONDS.convert(FIND_YARN_APP_TIMEOUT_MS,
TimeUnit.MILLISECONDS) + "s", true),
- OUTPUT_FILE("outputFile", 'o', "File to which output should be written
(Default stdout)", true),
- WATCH_MODE("watch", 'w', "Watch mode waits until all LLAP daemons are
running or subset of the nodes are " +
- "running (threshold can be specified via -r option) (Default wait until
all nodes are running)", false),
- // This is a negative because we want the positive to be the default when
nothing is specified.
- NOT_LAUNCHED("notlaunched", 'l', "In watch mode, do not assume that the
application was "
- + "already launched if there's doubt (e.g. if the last application
instance has failed).",
- false),
- RUNNING_NODES_THRESHOLD("runningNodesThreshold", 'r', "When watch mode is
enabled (-w), wait until the " +
- "specified threshold of nodes are running (Default 1.0 which means 100%
nodes are running)", true),
- STATUS_REFRESH_INTERVAL("refreshInterval", 'i', "Amount of time in seconds
to wait until subsequent status checks" +
- " in watch mode. Valid only for watch mode. (Default " +
- TimeUnit.SECONDS.convert(DEFAULT_STATUS_REFRESH_INTERVAL_MS,
TimeUnit.MILLISECONDS) + "s)", true),
- WATCH_MODE_TIMEOUT("watchTimeout", 't', "Exit watch mode if the desired
state is not attained until the specified" +
- " timeout. (Default " +
TimeUnit.SECONDS.convert(DEFAULT_WATCH_MODE_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+"s)", true),
- HIVECONF("hiveconf", null, "Use value for given property. Overridden by
explicit parameters", "property=value", 2),
- HELP("help", 'H', "Print help information", false);
-
-
- private final String longOpt;
- private final Character shortOpt;
- private final String description;
- private final String argName;
- private final int numArgs;
-
- OptionConstants(String longOpt, char shortOpt, String description, boolean
hasArgs) {
- this(longOpt, shortOpt, description, longOpt, hasArgs ? 1 : 0);
- }
-
- OptionConstants(String longOpt, Character shortOpt, String description,
String argName, int numArgs) {
- this.longOpt = longOpt;
- this.shortOpt = shortOpt;
- this.description = description;
- this.argName = argName;
- this.numArgs = numArgs;
- }
-
- public String getLongOpt() {
- return longOpt;
- }
-
- public Character getShortOpt() {
- return shortOpt;
- }
-
- public String getDescription() {
- return description;
- }
-
- public String getArgName() {
- return argName;
- }
-
- public int getNumArgs() {
- return numArgs;
- }
- }
-
-
- public static class LlapStatusOptions {
- private final String name;
- private final Properties conf;
- private final long findAppTimeoutMs;
- private final String outputFile;
- private final long refreshIntervalMs;
- private final boolean watchMode;
- private final long watchTimeout;
- private final float runningNodesThreshold;
- private final boolean isLaunched;
-
- public LlapStatusOptions(final String name) {
- this(name, new Properties(), FIND_YARN_APP_TIMEOUT_MS, null,
DEFAULT_STATUS_REFRESH_INTERVAL_MS, false,
- DEFAULT_WATCH_MODE_TIMEOUT_MS, DEFAULT_RUNNING_NODES_THRESHOLD, true);
- }
-
- public LlapStatusOptions(String name, Properties hiveProperties, long
findAppTimeoutMs,
- String outputFile, long refreshIntervalMs,
- final boolean watchMode, final long
watchTimeoutMs,
- final float runningNodesThreshold, final boolean
isLaunched) {
- this.name = name;
- this.conf = hiveProperties;
- this.findAppTimeoutMs = findAppTimeoutMs;
- this.outputFile = outputFile;
- this.refreshIntervalMs = refreshIntervalMs;
- this.watchMode = watchMode;
- this.watchTimeout = watchTimeoutMs;
- this.runningNodesThreshold = runningNodesThreshold;
- this.isLaunched = isLaunched;
- }
-
- public String getName() {
- return name;
- }
-
- public Properties getConf() {
- return conf;
- }
-
- public long getFindAppTimeoutMs() {
- return findAppTimeoutMs;
- }
-
- public String getOutputFile() {
- return outputFile;
- }
-
- public long getRefreshIntervalMs() {
- return refreshIntervalMs;
- }
-
- public boolean isWatchMode() {
- return watchMode;
- }
-
- public boolean isLaunched() {
- return isLaunched;
- }
-
- public long getWatchTimeoutMs() {
- return watchTimeout;
- }
-
- public float getRunningNodesThreshold() {
- return runningNodesThreshold;
- }
- }
-
- private final Options options = new Options();
- private org.apache.commons.cli.CommandLine commandLine;
-
- public LlapStatusOptionsProcessor() {
-
- for (OptionConstants optionConstant : OptionConstants.values()) {
-
- OptionBuilder optionBuilder =
OptionBuilder.hasArgs(optionConstant.getNumArgs())
-
.withArgName(optionConstant.getArgName()).withLongOpt(optionConstant.getLongOpt())
- .withDescription(optionConstant.getDescription());
- if (optionConstant.getShortOpt() == null) {
- options.addOption(optionBuilder.create());
- } else {
- options.addOption(optionBuilder.create(optionConstant.getShortOpt()));
- }
- }
- }
-
- public LlapStatusOptions processOptions(String[] args) throws ParseException
{
- commandLine = new GnuParser().parse(options, args);
- if (commandLine.hasOption(OptionConstants.HELP.getShortOpt())) {
- printUsage();
- return null;
- }
-
- String name =
commandLine.getOptionValue(OptionConstants.NAME.getLongOpt());
-
- long findAppTimeoutMs = FIND_YARN_APP_TIMEOUT_MS;
- if (commandLine.hasOption(OptionConstants.FIND_APP_TIMEOUT.getLongOpt())) {
- findAppTimeoutMs = TimeUnit.MILLISECONDS.convert(Long.parseLong(
-
commandLine.getOptionValue(OptionConstants.FIND_APP_TIMEOUT.getLongOpt())),
- TimeUnit.SECONDS);
- }
-
- Properties hiveConf;
- if (commandLine.hasOption(OptionConstants.HIVECONF.getLongOpt())) {
- hiveConf =
commandLine.getOptionProperties(OptionConstants.HIVECONF.getLongOpt());
- } else {
- hiveConf = new Properties();
- }
-
- String outputFile = null;
- if (commandLine.hasOption(OptionConstants.OUTPUT_FILE.getLongOpt())) {
- outputFile =
commandLine.getOptionValue(OptionConstants.OUTPUT_FILE.getLongOpt());
- }
-
- long refreshIntervalMs = DEFAULT_STATUS_REFRESH_INTERVAL_MS;
- if
(commandLine.hasOption(OptionConstants.STATUS_REFRESH_INTERVAL.getLongOpt())) {
- long refreshIntervalSec =
Long.parseLong(commandLine.getOptionValue(OptionConstants.STATUS_REFRESH_INTERVAL
- .getLongOpt()));
- if (refreshIntervalSec <= 0) {
- throw new IllegalArgumentException("Refresh interval should be >0");
- }
- refreshIntervalMs = TimeUnit.MILLISECONDS.convert(refreshIntervalSec,
TimeUnit.SECONDS);
- }
-
- boolean watchMode =
commandLine.hasOption(OptionConstants.WATCH_MODE.getLongOpt());
- long watchTimeoutMs = DEFAULT_WATCH_MODE_TIMEOUT_MS;
- if
(commandLine.hasOption(OptionConstants.WATCH_MODE_TIMEOUT.getLongOpt())) {
- long watchTimeoutSec = Long.parseLong(commandLine.getOptionValue(
- OptionConstants.WATCH_MODE_TIMEOUT.getLongOpt()));
- if (watchTimeoutSec <= 0) {
- throw new IllegalArgumentException("Watch timeout should be >0");
- }
- watchTimeoutMs = TimeUnit.MILLISECONDS.convert(watchTimeoutSec,
TimeUnit.SECONDS);
- }
-
- boolean isLaunched =
!commandLine.hasOption(OptionConstants.NOT_LAUNCHED.getLongOpt());
-
- float runningNodesThreshold = DEFAULT_RUNNING_NODES_THRESHOLD;
- if
(commandLine.hasOption(OptionConstants.RUNNING_NODES_THRESHOLD.getLongOpt())) {
- runningNodesThreshold = Float.parseFloat(commandLine.getOptionValue(
- OptionConstants.RUNNING_NODES_THRESHOLD.getLongOpt()));
- if (runningNodesThreshold < 0.0f || runningNodesThreshold > 1.0f) {
- throw new IllegalArgumentException(
- "Running nodes threshold value should be between 0.0 and 1.0
(inclusive)");
- }
- }
- return new LlapStatusOptions(name, hiveConf, findAppTimeoutMs, outputFile,
refreshIntervalMs,
- watchMode, watchTimeoutMs, runningNodesThreshold, isLaunched);
- }
-
-
- public static void printUsage() {
- HelpFormatter hf = new HelpFormatter();
- try {
- int width = hf.getWidth();
- int jlineWidth = TerminalFactory.get().getWidth();
- width = Math.min(160, Math.max(jlineWidth, width)); // Ignore
potentially incorrect values
- hf.setWidth(width);
- } catch (Throwable t) { // Ignore
- }
-
- LlapStatusOptionsProcessor optionsProcessor = new
LlapStatusOptionsProcessor();
- hf.printHelp(LLAPSTATUS_CONSTANT, optionsProcessor.options);
- }
-
-}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/AmInfo.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/AmInfo.java
new file mode 100644
index 00000000000..ac2ff65789b
--- /dev/null
+++ b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/AmInfo.java
@@ -0,0 +1,93 @@
+/*
+ * 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.hive.llap.cli.status;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * Represents the state of the yarn application.
+ */
+class AmInfo {
+ private String appName;
+ private String appType;
+ private String appId;
+ private String containerId;
+ private String hostname;
+ private String amWebUrl;
+
+ AmInfo setAppName(String appName) {
+ this.appName = appName;
+ return this;
+ }
+
+ AmInfo setAppType(String appType) {
+ this.appType = appType;
+ return this;
+ }
+
+ AmInfo setAppId(String appId) {
+ this.appId = appId;
+ return this;
+ }
+
+ AmInfo setContainerId(String containerId) {
+ this.containerId = containerId;
+ return this;
+ }
+
+ AmInfo setHostname(String hostname) {
+ this.hostname = hostname;
+ return this;
+ }
+
+ AmInfo setAmWebUrl(String amWebUrl) {
+ this.amWebUrl = amWebUrl;
+ return this;
+ }
+
+ String getAppName() {
+ return appName;
+ }
+
+ String getAppType() {
+ return appType;
+ }
+
+ String getAppId() {
+ return appId;
+ }
+
+ String getContainerId() {
+ return containerId;
+ }
+
+ String getHostname() {
+ return hostname;
+ }
+
+ String getAmWebUrl() {
+ return amWebUrl;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this,
ToStringStyle.SHORT_PREFIX_STYLE);
+ }
+}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/AppStatusBuilder.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/AppStatusBuilder.java
new file mode 100644
index 00000000000..c2ba4dba0c5
--- /dev/null
+++
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/AppStatusBuilder.java
@@ -0,0 +1,231 @@
+/*
+ * 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.hive.llap.cli.status;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+/**
+ * Represents the status of the Llap application.
+ */
+class AppStatusBuilder {
+
+ private AmInfo amInfo;
+ private State state = State.UNKNOWN;
+ private String diagnostics;
+ private String originalConfigurationPath;
+ private String generatedConfigurationPath;
+
+ private Long appStartTime;
+ private Long appFinishTime;
+
+ private boolean runningThresholdAchieved = false;
+
+ private Integer desiredInstances = null;
+ private Integer liveInstances = null;
+ private Integer launchingInstances = null;
+
+ private final List<LlapInstance> runningInstances = new LinkedList<>();
+ private final List<LlapInstance> completedInstances = new LinkedList<>();
+
+ private final transient Map<String, LlapInstance>
containerToRunningInstanceMap = new HashMap<>();
+ private final transient Map<String, LlapInstance>
containerToCompletedInstanceMap = new HashMap<>();
+
+ void setAmInfo(AmInfo amInfo) {
+ this.amInfo = amInfo;
+ }
+
+ AppStatusBuilder setState(State state) {
+ this.state = state;
+ return this;
+ }
+
+ AppStatusBuilder setDiagnostics(String diagnostics) {
+ this.diagnostics = diagnostics;
+ return this;
+ }
+
+ AppStatusBuilder setOriginalConfigurationPath(String
originalConfigurationPath) {
+ this.originalConfigurationPath = originalConfigurationPath;
+ return this;
+ }
+
+ AppStatusBuilder setGeneratedConfigurationPath(String
generatedConfigurationPath) {
+ this.generatedConfigurationPath = generatedConfigurationPath;
+ return this;
+ }
+
+ AppStatusBuilder setAppStartTime(long appStartTime) {
+ this.appStartTime = appStartTime;
+ return this;
+ }
+
+ AppStatusBuilder setAppFinishTime(long finishTime) {
+ this.appFinishTime = finishTime;
+ return this;
+ }
+
+ void setRunningThresholdAchieved(boolean runningThresholdAchieved) {
+ this.runningThresholdAchieved = runningThresholdAchieved;
+ }
+
+ AppStatusBuilder setDesiredInstances(int desiredInstances) {
+ this.desiredInstances = desiredInstances;
+ return this;
+ }
+
+ AppStatusBuilder setLiveInstances(int liveInstances) {
+ this.liveInstances = liveInstances;
+ return this;
+ }
+
+ AppStatusBuilder setLaunchingInstances(int launchingInstances) {
+ this.launchingInstances = launchingInstances;
+ return this;
+ }
+
+ AppStatusBuilder addNewRunningLlapInstance(LlapInstance llapInstance) {
+ this.runningInstances.add(llapInstance);
+ this.containerToRunningInstanceMap
+ .put(llapInstance.getContainerId(), llapInstance);
+ return this;
+ }
+
+ LlapInstance removeAndGetRunningLlapInstanceForContainer(String
containerIdString) {
+ return containerToRunningInstanceMap.remove(containerIdString);
+ }
+
+ void clearRunningLlapInstances() {
+ this.runningInstances.clear();
+ this.containerToRunningInstanceMap.clear();
+ }
+
+ AppStatusBuilder
clearAndAddPreviouslyKnownRunningInstances(List<LlapInstance> llapInstances) {
+ clearRunningLlapInstances();
+ for (LlapInstance llapInstance : llapInstances) {
+ addNewRunningLlapInstance(llapInstance);
+ }
+ return this;
+ }
+
+ @JsonIgnore
+ List<LlapInstance> allRunningInstances() {
+ return this.runningInstances;
+ }
+
+ AppStatusBuilder addNewCompleteLlapInstance(LlapInstance llapInstance) {
+ this.completedInstances.add(llapInstance);
+ this.containerToCompletedInstanceMap
+ .put(llapInstance.getContainerId(), llapInstance);
+ return this;
+ }
+
+ LlapInstance removeAndGetCompletedLlapInstanceForContainer(String
containerIdString) {
+ return containerToCompletedInstanceMap.remove(containerIdString);
+ }
+
+ void clearCompletedLlapInstances() {
+ this.completedInstances.clear();
+ this.containerToCompletedInstanceMap.clear();
+ }
+
+ AppStatusBuilder
clearAndAddPreviouslyKnownCompletedInstances(List<LlapInstance> llapInstances) {
+ clearCompletedLlapInstances();
+ for (LlapInstance llapInstance : llapInstances) {
+ addNewCompleteLlapInstance(llapInstance);
+ }
+ return this;
+ }
+
+ @JsonIgnore
+ List<LlapInstance> allCompletedInstances() {
+ return this.completedInstances;
+ }
+
+ AmInfo getAmInfo() {
+ return amInfo;
+ }
+
+ State getState() {
+ return state;
+ }
+
+ String getDiagnostics() {
+ return diagnostics;
+ }
+
+ String getOriginalConfigurationPath() {
+ return originalConfigurationPath;
+ }
+
+ String getGeneratedConfigurationPath() {
+ return generatedConfigurationPath;
+ }
+
+ Long getAppStartTime() {
+ return appStartTime;
+ }
+
+ Long getAppFinishTime() {
+ return appFinishTime;
+ }
+
+ boolean isRunningThresholdAchieved() {
+ return runningThresholdAchieved;
+ }
+
+ Integer getDesiredInstances() {
+ return desiredInstances;
+ }
+
+ Integer getLiveInstances() {
+ return liveInstances;
+ }
+
+ Integer getLaunchingInstances() {
+ return launchingInstances;
+ }
+
+ List<LlapInstance> getRunningInstances() {
+ return runningInstances;
+ }
+
+ List<LlapInstance> getCompletedInstances() {
+ return completedInstances;
+ }
+
+ @JsonIgnore
+ AmInfo maybeCreateAndGetAmInfo() {
+ if (amInfo == null) {
+ amInfo = new AmInfo();
+ }
+ return amInfo;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this,
ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/ExitCode.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/ExitCode.java
new file mode 100644
index 00000000000..16c71d27ff3
--- /dev/null
+++ b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/ExitCode.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.hive.llap.cli.status;
+
+/**
+ * Enumeration of the potential outcomes of the Llap state checking.
+ */
+public enum ExitCode {
+ SUCCESS(0),
+ INCORRECT_USAGE(10),
+ YARN_ERROR(20),
+ SERVICE_CLIENT_ERROR_CREATE_FAILED(30),
+ SERVICE_CLIENT_ERROR_OTHER(31),
+ LLAP_REGISTRY_ERROR(40),
+ LLAP_JSON_GENERATION_ERROR(50),
+ // Error in the script itself - likely caused by an incompatible change, or
new functionality / states added.
+ INTERNAL_ERROR(100);
+
+ private final int code;
+
+ ExitCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapInstance.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapInstance.java
new file mode 100644
index 00000000000..5b979fd59b6
--- /dev/null
+++
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapInstance.java
@@ -0,0 +1,134 @@
+/*
+ * 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.hive.llap.cli.status;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * Representing the state of an Llap instance monitored.
+ */
+class LlapInstance {
+ private final String hostname;
+ private final String containerId;
+ private String logUrl;
+
+ // Only for live instances.
+ private String statusUrl;
+ private String webUrl;
+ private Integer rpcPort;
+ private Integer mgmtPort;
+ private Integer shufflePort;
+
+ // For completed instances
+ private String diagnostics;
+ private int yarnContainerExitStatus;
+
+ // TODO HIVE-13454 Add additional information such as #executors, container
size, etc
+
+ LlapInstance(String hostname, String containerId) {
+ this.hostname = hostname;
+ this.containerId = containerId;
+ }
+
+ LlapInstance setLogUrl(String logUrl) {
+ this.logUrl = logUrl;
+ return this;
+ }
+
+ LlapInstance setStatusUrl(String statusUrl) {
+ this.statusUrl = statusUrl;
+ return this;
+ }
+
+ LlapInstance setWebUrl(String webUrl) {
+ this.webUrl = webUrl;
+ return this;
+ }
+
+ LlapInstance setRpcPort(int rpcPort) {
+ this.rpcPort = rpcPort;
+ return this;
+ }
+
+ LlapInstance setMgmtPort(int mgmtPort) {
+ this.mgmtPort = mgmtPort;
+ return this;
+ }
+
+ LlapInstance setShufflePort(int shufflePort) {
+ this.shufflePort = shufflePort;
+ return this;
+ }
+
+ LlapInstance setDiagnostics(String diagnostics) {
+ this.diagnostics = diagnostics;
+ return this;
+ }
+
+ LlapInstance setYarnContainerExitStatus(int yarnContainerExitStatus) {
+ this.yarnContainerExitStatus = yarnContainerExitStatus;
+ return this;
+ }
+
+ String getHostname() {
+ return hostname;
+ }
+
+ String getContainerId() {
+ return containerId;
+ }
+
+ String getLogUrl() {
+ return logUrl;
+ }
+
+ String getStatusUrl() {
+ return statusUrl;
+ }
+
+ String getWebUrl() {
+ return webUrl;
+ }
+
+ Integer getRpcPort() {
+ return rpcPort;
+ }
+
+ Integer getMgmtPort() {
+ return mgmtPort;
+ }
+
+ Integer getShufflePort() {
+ return shufflePort;
+ }
+
+ String getDiagnostics() {
+ return diagnostics;
+ }
+
+ int getYarnContainerExitStatus() {
+ return yarnContainerExitStatus;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this,
ToStringStyle.SHORT_PREFIX_STYLE);
+ }
+}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusCliException.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusCliException.java
new file mode 100644
index 00000000000..7ebf404818f
--- /dev/null
+++
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusCliException.java
@@ -0,0 +1,40 @@
+/*
+ * 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.hive.llap.cli.status;
+
+/**
+ * Representing the exceptions that may occur during the Llap state chacking.
+ */
+class LlapStatusCliException extends Exception {
+ private final ExitCode exitCode;
+
+ LlapStatusCliException(ExitCode exitCode, String message) {
+ super(exitCode.getCode() +": " + message);
+ this.exitCode = exitCode;
+ }
+
+ LlapStatusCliException(ExitCode exitCode, String message, Throwable cause) {
+ super(exitCode.getCode() +": " + message, cause);
+ this.exitCode = exitCode;
+ }
+
+ ExitCode getExitCode() {
+ return exitCode;
+ }
+}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusHelpers.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusHelpers.java
deleted file mode 100644
index 5c8aeb07249..00000000000
---
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusHelpers.java
+++ /dev/null
@@ -1,449 +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.hadoop.hive.llap.cli.status;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.hadoop.hive.llap.cli.LlapStatusServiceDriver;
-import org.codehaus.jackson.annotate.JsonIgnore;
-
-public class LlapStatusHelpers {
- public enum State {
- APP_NOT_FOUND, LAUNCHING,
- RUNNING_PARTIAL,
- RUNNING_ALL, COMPLETE, UNKNOWN
- }
-
- public static class AmInfo {
- private String appName;
- private String appType;
- private String appId;
- private String containerId;
- private String hostname;
- private String amWebUrl;
-
- public AmInfo setAppName(String appName) {
- this.appName = appName;
- return this;
- }
-
- public AmInfo setAppType(String appType) {
- this.appType = appType;
- return this;
- }
-
- public AmInfo setAppId(String appId) {
- this.appId = appId;
- return this;
- }
-
- public AmInfo setContainerId(String containerId) {
- this.containerId = containerId;
- return this;
- }
-
- public AmInfo setHostname(String hostname) {
- this.hostname = hostname;
- return this;
- }
-
- public AmInfo setAmWebUrl(String amWebUrl) {
- this.amWebUrl = amWebUrl;
- return this;
- }
-
- public String getAppName() {
- return appName;
- }
-
- public String getAppType() {
- return appType;
- }
-
- public String getAppId() {
- return appId;
- }
-
- public String getContainerId() {
- return containerId;
- }
-
- public String getHostname() {
- return hostname;
- }
-
- public String getAmWebUrl() {
- return amWebUrl;
- }
-
- @Override
- public String toString() {
- return "AmInfo{" +
- "appName='" + appName + '\'' +
- ", appType='" + appType + '\'' +
- ", appId='" + appId + '\'' +
- ", containerId='" + containerId + '\'' +
- ", hostname='" + hostname + '\'' +
- ", amWebUrl='" + amWebUrl + '\'' +
- '}';
- }
- }
-
- public static class LlapInstance {
- private final String hostname;
- private final String containerId;
- private String logUrl;
-
- // Only for live instances.
- private String statusUrl;
- private String webUrl;
- private Integer rpcPort;
- private Integer mgmtPort;
- private Integer shufflePort;
-
- // For completed instances
- private String diagnostics;
- private int yarnContainerExitStatus;
-
- // TODO HIVE-13454 Add additional information such as #executors,
container size, etc
-
- public LlapInstance(String hostname, String containerId) {
- this.hostname = hostname;
- this.containerId = containerId;
- }
-
- public LlapInstance setLogUrl(String logUrl) {
- this.logUrl = logUrl;
- return this;
- }
-
- public LlapInstance setWebUrl(String webUrl) {
- this.webUrl = webUrl;
- return this;
- }
-
- public LlapInstance setStatusUrl(String statusUrl) {
- this.statusUrl = statusUrl;
- return this;
- }
-
- public LlapInstance setRpcPort(int rpcPort) {
- this.rpcPort = rpcPort;
- return this;
- }
-
- public LlapInstance setMgmtPort(int mgmtPort) {
- this.mgmtPort = mgmtPort;
- return this;
- }
-
- public LlapInstance setShufflePort(int shufflePort) {
- this.shufflePort = shufflePort;
- return this;
- }
-
- public LlapInstance setDiagnostics(String diagnostics) {
- this.diagnostics = diagnostics;
- return this;
- }
-
- public LlapInstance setYarnContainerExitStatus(int
yarnContainerExitStatus) {
- this.yarnContainerExitStatus = yarnContainerExitStatus;
- return this;
- }
-
- public String getHostname() {
- return hostname;
- }
-
- public String getLogUrl() {
- return logUrl;
- }
-
- public String getStatusUrl() {
- return statusUrl;
- }
-
- public String getContainerId() {
- return containerId;
- }
-
- public String getWebUrl() {
- return webUrl;
- }
-
- public Integer getRpcPort() {
- return rpcPort;
- }
-
- public Integer getMgmtPort() {
- return mgmtPort;
- }
-
- public Integer getShufflePort() {
- return shufflePort;
- }
-
- public String getDiagnostics() {
- return diagnostics;
- }
-
- public int getYarnContainerExitStatus() {
- return yarnContainerExitStatus;
- }
-
- @Override
- public String toString() {
- return "LlapInstance{" +
- "hostname='" + hostname + '\'' +
- "logUrl=" + logUrl + '\'' +
- ", containerId='" + containerId + '\'' +
- ", statusUrl='" + statusUrl + '\'' +
- ", webUrl='" + webUrl + '\'' +
- ", rpcPort=" + rpcPort +
- ", mgmtPort=" + mgmtPort +
- ", shufflePort=" + shufflePort +
- ", diagnostics=" + diagnostics +
- ", yarnContainerExitStatus=" + yarnContainerExitStatus +
- '}';
- }
- }
-
- public static final class AppStatusBuilder {
-
- private AmInfo amInfo;
- private State state = State.UNKNOWN;
- private String diagnostics;
- private String originalConfigurationPath;
- private String generatedConfigurationPath;
-
- private Integer desiredInstances = null;
- private Integer liveInstances = null;
- private Integer launchingInstances = null;
-
-
- private Long appStartTime;
- private Long appFinishTime;
-
- private boolean runningThresholdAchieved = false;
-
- private final List<LlapInstance> runningInstances = new LinkedList<>();
- private final List<LlapInstance> completedInstances = new LinkedList<>();
-
- private transient final Map<String, LlapInstance>
- containerToRunningInstanceMap = new HashMap<>();
- private transient final Map<String, LlapInstance>
- containerToCompletedInstanceMap = new HashMap<>();
-
- public void setAmInfo(AmInfo amInfo) {
- this.amInfo = amInfo;
- }
-
- public AppStatusBuilder setState(
- State state) {
- this.state = state;
- return this;
- }
-
- public AppStatusBuilder setDiagnostics(String diagnostics) {
- this.diagnostics = diagnostics;
- return this;
- }
-
- public AppStatusBuilder setOriginalConfigurationPath(String
originalConfigurationPath) {
- this.originalConfigurationPath = originalConfigurationPath;
- return this;
- }
-
- public AppStatusBuilder setGeneratedConfigurationPath(String
generatedConfigurationPath) {
- this.generatedConfigurationPath = generatedConfigurationPath;
- return this;
- }
-
- public AppStatusBuilder setAppStartTime(long appStartTime) {
- this.appStartTime = appStartTime;
- return this;
- }
-
- public AppStatusBuilder setAppFinishTime(long finishTime) {
- this.appFinishTime = finishTime;
- return this;
- }
-
- public void setRunningThresholdAchieved(boolean runningThresholdAchieved) {
- this.runningThresholdAchieved = runningThresholdAchieved;
- }
-
- public AppStatusBuilder setDesiredInstances(int desiredInstances) {
- this.desiredInstances = desiredInstances;
- return this;
- }
-
- public AppStatusBuilder setLiveInstances(int liveInstances) {
- this.liveInstances = liveInstances;
- return this;
- }
-
- public AppStatusBuilder setLaunchingInstances(int launchingInstances) {
- this.launchingInstances = launchingInstances;
- return this;
- }
-
- public AppStatusBuilder addNewRunningLlapInstance(LlapInstance
llapInstance) {
- this.runningInstances.add(llapInstance);
- this.containerToRunningInstanceMap
- .put(llapInstance.getContainerId(), llapInstance);
- return this;
- }
-
- public LlapInstance removeAndGetRunningLlapInstanceForContainer(String
containerIdString) {
- return containerToRunningInstanceMap.remove(containerIdString);
- }
-
- public void clearRunningLlapInstances() {
- this.runningInstances.clear();
- this.containerToRunningInstanceMap.clear();
- }
-
- public AppStatusBuilder
clearAndAddPreviouslyKnownRunningInstances(List<LlapInstance> llapInstances) {
- clearRunningLlapInstances();
- for (LlapInstance llapInstance : llapInstances) {
- addNewRunningLlapInstance(llapInstance);
- }
- return this;
- }
-
- @JsonIgnore
- public List<LlapInstance> allRunningInstances() {
- return this.runningInstances;
- }
-
- public AppStatusBuilder addNewCompleteLlapInstance(LlapInstance
llapInstance) {
- this.completedInstances.add(llapInstance);
- this.containerToCompletedInstanceMap
- .put(llapInstance.getContainerId(), llapInstance);
- return this;
- }
-
- public LlapInstance removeAndGetCompletedLlapInstanceForContainer(String
containerIdString) {
- return containerToCompletedInstanceMap.remove(containerIdString);
- }
-
- public void clearCompletedLlapInstances() {
- this.completedInstances.clear();
- this.containerToCompletedInstanceMap.clear();
- }
-
- public AppStatusBuilder
clearAndAddPreviouslyKnownCompletedInstances(List<LlapInstance> llapInstances) {
- clearCompletedLlapInstances();
- for (LlapInstance llapInstance : llapInstances) {
- addNewCompleteLlapInstance(llapInstance);
- }
- return this;
- }
-
- @JsonIgnore
- public List<LlapInstance> allCompletedInstances() {
- return this.completedInstances;
- }
-
- public AmInfo getAmInfo() {
- return amInfo;
- }
-
- public State getState() {
- return state;
- }
-
- public String getDiagnostics() {
- return diagnostics;
- }
-
- public String getOriginalConfigurationPath() {
- return originalConfigurationPath;
- }
-
- public String getGeneratedConfigurationPath() {
- return generatedConfigurationPath;
- }
-
- public Integer getDesiredInstances() {
- return desiredInstances;
- }
-
- public Integer getLiveInstances() {
- return liveInstances;
- }
-
- public Integer getLaunchingInstances() {
- return launchingInstances;
- }
-
- public Long getAppStartTime() {
- return appStartTime;
- }
-
- public Long getAppFinishTime() {
- return appFinishTime;
- }
-
- public boolean isRunningThresholdAchieved() {
- return runningThresholdAchieved;
- }
-
- public List<LlapInstance> getRunningInstances() {
- return runningInstances;
- }
-
- public List<LlapInstance> getCompletedInstances() {
- return completedInstances;
- }
-
- @JsonIgnore
- public AmInfo maybeCreateAndGetAmInfo() {
- if (amInfo == null) {
- amInfo = new AmInfo();
- }
- return amInfo;
- }
-
- @Override
- public String toString() {
- return "AppStatusBuilder{" +
- "amInfo=" + amInfo +
- ", state=" + state +
- ", diagnostics=" + diagnostics +
- ", originalConfigurationPath='" + originalConfigurationPath + '\'' +
- ", generatedConfigurationPath='" + generatedConfigurationPath + '\''
+
- ", desiredInstances=" + desiredInstances +
- ", liveInstances=" + liveInstances +
- ", launchingInstances=" + launchingInstances +
- ", appStartTime=" + appStartTime +
- ", appFinishTime=" + appFinishTime +
- ", runningThresholdAchieved=" + runningThresholdAchieved +
- ", runningInstances=" + runningInstances +
- ", completedInstances=" + completedInstances +
- ", containerToRunningInstanceMap=" + containerToRunningInstanceMap +
- '}';
- }
- }
-}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusServiceCommandLine.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusServiceCommandLine.java
new file mode 100644
index 00000000000..bee50791a3a
--- /dev/null
+++
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusServiceCommandLine.java
@@ -0,0 +1,302 @@
+/*
+ * 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.hive.llap.cli.status;
+
+import java.util.Arrays;
+import java.util.Properties;
+
+import jline.TerminalFactory;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Parses, verifies, prints and provides the command line arguments of the
Llap Status program.
+ */
+public class LlapStatusServiceCommandLine {
+ private static final Logger LOGGER =
LoggerFactory.getLogger("LlapStatusServiceDriverConsole");
+
+ @VisibleForTesting
+ static final long DEFAULT_FIND_YARN_APP_TIMEOUT_MS = 20 * 1000L;
+ @VisibleForTesting
+ static final long DEFAULT_STATUS_REFRESH_INTERVAL_MS = 1 * 1000L;
+ @VisibleForTesting
+ static final long DEFAULT_WATCH_MODE_TIMEOUT_MS = 5 * 60 * 1000L;
+ @VisibleForTesting
+ static final float DEFAULT_RUNNING_NODES_THRESHOLD = 1.0f;
+
+ @SuppressWarnings("static-access")
+ private static final Option NAME = OptionBuilder
+ .withLongOpt("name")
+ .withDescription("LLAP cluster name")
+ .withArgName("name")
+ .hasArg()
+ .create('n');
+
+ @SuppressWarnings("static-access")
+ private static final Option FIND_APP_TIMEOUT = OptionBuilder
+ .withLongOpt("findAppTimeout")
+ .withDescription("Amount of time(s) that the tool will sleep to wait for
the YARN application to start." +
+ "negative values=wait forever, 0=Do not wait. default=" +
(DEFAULT_FIND_YARN_APP_TIMEOUT_MS / 1000) + "s")
+ .withArgName("findAppTimeout")
+ .hasArg()
+ .create('f');
+
+ @SuppressWarnings("static-access")
+ private static final Option OUTPUT_FILE = OptionBuilder
+ .withLongOpt("outputFile")
+ .withDescription("File to which output should be written (Default
stdout)")
+ .withArgName("outputFile")
+ .hasArg()
+ .create('o');
+
+ @SuppressWarnings("static-access")
+ private static final Option WATCH_MODE = OptionBuilder
+ .withLongOpt("watch")
+ .withDescription("Watch mode waits until all LLAP daemons are running or
subset of the nodes are running " +
+ "(threshold can be specified via -r option) (Default wait until all
nodes are running)")
+ .withArgName("watch")
+ .create('w');
+
+ @SuppressWarnings("static-access")
+ private static final Option NOT_LAUNCHED = OptionBuilder
+ .withLongOpt("notLaunched")
+ .withDescription("In watch mode, do not assume that the application was
already launched if there's doubt " +
+ "(e.g. if the last application instance has failed).")
+ .withArgName("notLaunched")
+ .create('l');
+
+ @SuppressWarnings("static-access")
+ private static final Option RUNNING_NODES_THRESHOLD = OptionBuilder
+ .withLongOpt("runningNodesThreshold")
+ .withDescription("When watch mode is enabled (-w), wait until the
specified threshold of nodes are running " +
+ "(Default 1.0 which means 100% nodes are running)")
+ .withArgName("runningNodesThreshold")
+ .hasArg()
+ .create('r');
+
+ @SuppressWarnings("static-access")
+ private static final Option REFRESH_INTERVAL = OptionBuilder
+ .withLongOpt("refreshInterval")
+ .withDescription("Amount of time in seconds to wait until subsequent
status checks in watch mode. Valid only " +
+ "for watch mode. (Default " + (DEFAULT_STATUS_REFRESH_INTERVAL_MS /
1000) + "s)")
+ .withArgName("refreshInterval")
+ .hasArg()
+ .create('i');
+
+ @SuppressWarnings("static-access")
+ private static final Option WATCH_TIMEOUT = OptionBuilder
+ .withLongOpt("watchTimeout")
+ .withDescription("Exit watch mode if the desired state is not attained
until the specified timeout. (Default " +
+ (DEFAULT_WATCH_MODE_TIMEOUT_MS / 1000) + "s)")
+ .withArgName("watchTimeout")
+ .hasArg()
+ .create('t');
+
+ @SuppressWarnings("static-access")
+ private static final Option HIVECONF = OptionBuilder
+ .withLongOpt("hiveconf")
+ .withDescription("Use value for given property. Overridden by explicit
parameters")
+ .withArgName("property=value")
+ .hasArgs(2)
+ .create();
+
+ @SuppressWarnings("static-access")
+ private static final Option HELP = OptionBuilder
+ .withLongOpt("help")
+ .withDescription("Print help information")
+ .withArgName("help")
+ .create('h');
+
+ private static final Options OPTIONS = new Options();
+ static {
+ OPTIONS.addOption(NAME);
+ OPTIONS.addOption(FIND_APP_TIMEOUT);
+ OPTIONS.addOption(OUTPUT_FILE);
+ OPTIONS.addOption(WATCH_MODE);
+ OPTIONS.addOption(NOT_LAUNCHED);
+ OPTIONS.addOption(RUNNING_NODES_THRESHOLD);
+ OPTIONS.addOption(REFRESH_INTERVAL);
+ OPTIONS.addOption(WATCH_TIMEOUT);
+ OPTIONS.addOption(HIVECONF);
+ OPTIONS.addOption(HELP);
+ }
+
+ private String name;
+ private long findAppTimeoutMs;
+ private String outputFile;
+ private boolean watchMode;
+ private boolean isLaunched;
+ private float runningNodesThreshold;
+ private long refreshIntervalMs;
+ private long watchTimeoutMs;
+ private Properties hiveConf;
+ private boolean isHelp;
+
+ public static LlapStatusServiceCommandLine parseArguments(String[] args) {
+ LlapStatusServiceCommandLine cl = null;
+ try {
+ cl = new LlapStatusServiceCommandLine(args);
+ } catch (Exception e) {
+ LOGGER.error("Parsing the command line arguments failed", e);
+ printUsage();
+ System.exit(ExitCode.INCORRECT_USAGE.getCode());
+ }
+
+ if (cl.isHelp()) {
+ printUsage();
+ System.exit(0);
+ }
+
+ return cl;
+ }
+
+ LlapStatusServiceCommandLine(String[] args) throws ParseException {
+ LOGGER.info("LLAP status invoked with arguments = {}",
Arrays.toString(args));
+ parseCommandLine(args);
+ printArguments();
+ }
+
+ private void parseCommandLine(String[] args) throws ParseException {
+ CommandLine cl = new GnuParser().parse(OPTIONS, args);
+
+ name = cl.getOptionValue(NAME.getLongOpt());
+
+ findAppTimeoutMs = DEFAULT_FIND_YARN_APP_TIMEOUT_MS;
+ if (cl.hasOption(FIND_APP_TIMEOUT.getLongOpt())) {
+ findAppTimeoutMs =
Long.parseLong(cl.getOptionValue(FIND_APP_TIMEOUT.getLongOpt())) * 1000;
+ }
+
+ if (cl.hasOption(OUTPUT_FILE.getLongOpt())) {
+ outputFile = cl.getOptionValue(OUTPUT_FILE.getLongOpt());
+ }
+
+ watchMode = cl.hasOption(WATCH_MODE.getLongOpt());
+
+ isLaunched = !cl.hasOption(NOT_LAUNCHED.getLongOpt());
+
+ runningNodesThreshold = DEFAULT_RUNNING_NODES_THRESHOLD;
+ if (cl.hasOption(RUNNING_NODES_THRESHOLD.getLongOpt())) {
+ runningNodesThreshold =
Float.parseFloat(cl.getOptionValue(RUNNING_NODES_THRESHOLD.getLongOpt()));
+ if (runningNodesThreshold < 0.0f || runningNodesThreshold > 1.0f) {
+ throw new IllegalArgumentException("Running nodes threshold value
should be between 0.0 and 1.0 (inclusive)");
+ }
+ }
+
+ refreshIntervalMs = DEFAULT_STATUS_REFRESH_INTERVAL_MS;
+ if (cl.hasOption(REFRESH_INTERVAL.getLongOpt())) {
+ long refreshIntervalSec =
Long.parseLong(cl.getOptionValue(REFRESH_INTERVAL.getLongOpt()));
+ if (refreshIntervalSec <= 0) {
+ throw new IllegalArgumentException("Refresh interval should be >0");
+ }
+ refreshIntervalMs = refreshIntervalSec * 1000;
+ }
+
+ watchTimeoutMs = DEFAULT_WATCH_MODE_TIMEOUT_MS;
+ if (cl.hasOption(WATCH_TIMEOUT.getLongOpt())) {
+ long watchTimeoutSec =
Long.parseLong(cl.getOptionValue(WATCH_TIMEOUT.getLongOpt()));
+ if (watchTimeoutSec <= 0) {
+ throw new IllegalArgumentException("Watch timeout should be >0");
+ }
+ watchTimeoutMs = watchTimeoutSec * 1000;
+ }
+
+ hiveConf = new Properties();
+ if (cl.hasOption(HIVECONF.getLongOpt())) {
+ hiveConf = cl.getOptionProperties(HIVECONF.getLongOpt());
+ }
+
+ isHelp = cl.hasOption(HELP.getOpt());
+ }
+
+ private static void printUsage() {
+ HelpFormatter hf = new HelpFormatter();
+ try {
+ int width = hf.getWidth();
+ int jlineWidth = TerminalFactory.get().getWidth();
+ width = Math.min(160, Math.max(jlineWidth, width));
+ hf.setWidth(width);
+ } catch (Throwable t) { // Ignore
+ }
+
+ hf.printHelp("llapstatus", OPTIONS);
+ }
+
+ private void printArguments() {
+ LOGGER.info("LLAP status running with the following parsed arguments: \n" +
+ "\tname : " + name + "\n" +
+ "\tfindAppTimeoutMs : " + findAppTimeoutMs + "\n" +
+ "\toutputFile : " + outputFile + "\n" +
+ "\twatchMode : " + watchMode + "\n" +
+ "\tisLaunched : " + isLaunched + "\n" +
+ "\trunningNodesThreshold: " + runningNodesThreshold + "\n" +
+ "\trefreshIntervalMs : " + refreshIntervalMs + "\n" +
+ "\twatchTimeoutMs : " + watchTimeoutMs + "\n" +
+ "\thiveConf : " + hiveConf);
+ }
+
+ String getName() {
+ return name;
+ }
+
+ long getFindAppTimeoutMs() {
+ return findAppTimeoutMs;
+ }
+
+ String getOutputFile() {
+ return outputFile;
+ }
+
+ boolean isWatchMode() {
+ return watchMode;
+ }
+
+ boolean isLaunched() {
+ return isLaunched;
+ }
+
+ float getRunningNodesThreshold() {
+ return runningNodesThreshold;
+ }
+
+ long getRefreshIntervalMs() {
+ return refreshIntervalMs;
+ }
+
+ long getWatchTimeoutMs() {
+ return watchTimeoutMs;
+ }
+
+ Properties getHiveConf() {
+ return hiveConf;
+ }
+
+ boolean isHelp() {
+ return isHelp;
+ }
+}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusServiceDriver.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusServiceDriver.java
similarity index 59%
rename from
llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusServiceDriver.java
rename to
llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusServiceDriver.java
index c1bae653479..e3302b71f8e 100644
---
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusServiceDriver.java
+++
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/LlapStatusServiceDriver.java
@@ -16,40 +16,36 @@
* limitations under the License.
*/
-package org.apache.hadoop.hive.llap.cli;
+package org.apache.hadoop.hive.llap.cli.status;
-import com.google.common.annotations.VisibleForTesting;
-import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.io.Writer;
+import java.nio.charset.Charset;
import java.text.DecimalFormat;
-import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
-import org.apache.hadoop.hive.common.classification.InterfaceAudience;
import org.apache.hadoop.hive.conf.HiveConf;
-import
org.apache.hadoop.hive.llap.cli.LlapStatusOptionsProcessor.LlapStatusOptions;
-import org.apache.hadoop.hive.llap.cli.status.LlapStatusHelpers;
-import
org.apache.hadoop.hive.llap.cli.status.LlapStatusHelpers.AppStatusBuilder;
-import org.apache.hadoop.hive.llap.cli.status.LlapStatusHelpers.LlapInstance;
-import org.apache.hadoop.hive.llap.cli.status.LlapStatusHelpers.State;
+import org.apache.hadoop.hive.llap.cli.LlapSliderUtils;
import org.apache.hadoop.hive.llap.configuration.LlapDaemonConfiguration;
import org.apache.hadoop.hive.llap.registry.LlapServiceInstance;
import org.apache.hadoop.hive.llap.registry.impl.LlapRegistryService;
import org.apache.hadoop.hive.ql.session.SessionState;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ApplicationReport;
import org.apache.hadoop.yarn.api.records.ContainerExitStatus;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.service.api.records.Container;
import org.apache.hadoop.yarn.service.api.records.Service;
@@ -57,20 +53,25 @@ import
org.apache.hadoop.yarn.service.api.records.ServiceState;
import org.apache.hadoop.yarn.service.client.ServiceClient;
import org.apache.hadoop.yarn.util.Clock;
import org.apache.hadoop.yarn.util.SystemClock;
+import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/**
+ * Checks the status of the Llap.
+ */
public class LlapStatusServiceDriver {
+ private static final Logger LOG =
LoggerFactory.getLogger(LlapStatusServiceDriver.class);
+ private static final Logger CONSOLE_LOGGER =
LoggerFactory.getLogger("LlapStatusServiceDriverConsole");
private static final EnumSet<State> NO_YARN_SERVICE_INFO_STATES = EnumSet.of(
State.APP_NOT_FOUND, State.COMPLETE, State.LAUNCHING);
private static final EnumSet<State> LAUNCHING_STATES = EnumSet.of(
State.LAUNCHING, State.RUNNING_PARTIAL, State.RUNNING_ALL);
- private static final Logger LOG =
LoggerFactory.getLogger(LlapStatusServiceDriver.class);
- private static final Logger CONSOLE_LOGGER =
LoggerFactory.getLogger("LlapStatusServiceDriverConsole");
// Defining a bunch of configs here instead of in HiveConf. These are
experimental, and mainly
// for use when retry handling is fixed in Yarn/Hadoop
@@ -79,50 +80,51 @@ public class LlapStatusServiceDriver {
// The following two keys should ideally be used to control RM connect
timeouts. However,
// they don't seem to work. The IPC timeout needs to be set instead.
- @InterfaceAudience.Private
- private static final String CONFIG_YARN_RM_TIMEOUT_MAX_WAIT_MS =
- CONF_PREFIX + "yarn.rm.connect.max-wait-ms";
- private static final long CONFIG_YARN_RM_TIMEOUT_MAX_WAIT_MS_DEFAULT =
10000l;
- @InterfaceAudience.Private
- private static final String CONFIG_YARN_RM_RETRY_INTERVAL_MS =
- CONF_PREFIX + "yarn.rm.connect.retry-interval.ms";
- private static final long CONFIG_YARN_RM_RETRY_INTERVAL_MS_DEFAULT = 5000l;
+ private static final String CONFIG_YARN_RM_TIMEOUT_MAX_WAIT_MS = CONF_PREFIX
+ "yarn.rm.connect.max-wait-ms";
+ private static final long CONFIG_YARN_RM_TIMEOUT_MAX_WAIT_MS_DEFAULT =
10000L;
+ private static final String CONFIG_YARN_RM_RETRY_INTERVAL_MS = CONF_PREFIX +
"yarn.rm.connect.retry-interval.ms";
+ private static final long CONFIG_YARN_RM_RETRY_INTERVAL_MS_DEFAULT = 5000L;
// As of Hadoop 2.7 - this is what controls the RM timeout.
- @InterfaceAudience.Private
- private static final String CONFIG_IPC_CLIENT_CONNECT_MAX_RETRIES =
- CONF_PREFIX + "ipc.client.max-retries";
+ private static final String CONFIG_IPC_CLIENT_CONNECT_MAX_RETRIES =
CONF_PREFIX + "ipc.client.max-retries";
private static final int CONFIG_IPC_CLIENT_CONNECT_MAX_RETRIES_DEFAULT = 2;
- @InterfaceAudience.Private
private static final String CONFIG_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS =
CONF_PREFIX + "ipc.client.connect.retry-interval-ms";
- private static final long
CONFIG_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS_DEFAULT = 1500l;
+ private static final long
CONFIG_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS_DEFAULT = 1500L;
// As of Hadoop 2.8 - this timeout spec behaves in a strnage manner.
"2000,1" means 2000s with 1 retry.
// However it does this - but does it thrice. Essentially - #retries+2 is
the number of times the entire config
// is retried. "2000,1" means 3 retries - each with 1 retry with a random
2000ms sleep.
- @InterfaceAudience.Private
private static final String
CONFIG_TIMELINE_SERVICE_ENTITYGROUP_FS_STORE_RETRY_POLICY_SPEC =
CONF_PREFIX + "timeline.service.fs-store.retry.policy.spec";
private static final String
CONFIG_TIMELINE_SERVICE_ENTITYGROUP_FS_STORE_RETRY_POLICY_SPEC_DEFAULT =
"2000, 1";
- private static final String CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS =
- CONF_PREFIX + "zk-registry.timeout-ms";
- private static final long CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS_DEFAULT =
20000l;
+ private static final String CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS = CONF_PREFIX
+ "zk-registry.timeout-ms";
+ private static final long CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS_DEFAULT =
20000L;
private static final long LOG_SUMMARY_INTERVAL = 15000L; // Log summary
every ~15 seconds.
-
private static final String LLAP_KEY = "llap";
+
private final Configuration conf;
- private final Clock clock = new SystemClock();
private String appName = null;
+ private String applicationId = null;
private ServiceClient serviceClient = null;
private Configuration llapRegistryConf = null;
private LlapRegistryService llapRegistry = null;
- @VisibleForTesting
- AppStatusBuilder appStatusBuilder;
+ private AppStatusBuilder appStatusBuilder;
+
+ private static LlapStatusServiceDriver createServiceDriver() {
+ LlapStatusServiceDriver statusServiceDriver = null;
+ try {
+ statusServiceDriver = new LlapStatusServiceDriver();
+ } catch (Throwable t) {
+ logError(t);
+ System.exit(ExitCode.INTERNAL_ERROR.getCode());
+ }
+ return statusServiceDriver;
+ }
public LlapStatusServiceDriver() {
SessionState ss = SessionState.get();
@@ -141,59 +143,35 @@ public class LlapStatusServiceDriver {
// Once we move to a Hadoop-2.8 dependency, the following paramteer can be
used.
//
conf.set(YarnConfiguration.TIMELINE_SERVICE_ENTITYGROUP_FS_STORE_RETRY_POLICY_SPEC);
conf.set("yarn.timeline-service.entity-group-fs-store.retry-policy-spec",
- conf.get(CONFIG_TIMELINE_SERVICE_ENTITYGROUP_FS_STORE_RETRY_POLICY_SPEC,
-
CONFIG_TIMELINE_SERVICE_ENTITYGROUP_FS_STORE_RETRY_POLICY_SPEC_DEFAULT));
+
conf.get(CONFIG_TIMELINE_SERVICE_ENTITYGROUP_FS_STORE_RETRY_POLICY_SPEC,
+
CONFIG_TIMELINE_SERVICE_ENTITYGROUP_FS_STORE_RETRY_POLICY_SPEC_DEFAULT));
conf.setLong(YarnConfiguration.RESOURCEMANAGER_CONNECT_MAX_WAIT_MS,
- conf.getLong(CONFIG_YARN_RM_TIMEOUT_MAX_WAIT_MS,
- CONFIG_YARN_RM_TIMEOUT_MAX_WAIT_MS_DEFAULT));
+ conf.getLong(CONFIG_YARN_RM_TIMEOUT_MAX_WAIT_MS,
CONFIG_YARN_RM_TIMEOUT_MAX_WAIT_MS_DEFAULT));
conf.setLong(YarnConfiguration.RESOURCEMANAGER_CONNECT_RETRY_INTERVAL_MS,
- conf.getLong(CONFIG_YARN_RM_RETRY_INTERVAL_MS,
CONFIG_YARN_RM_RETRY_INTERVAL_MS_DEFAULT));
+ conf.getLong(CONFIG_YARN_RM_RETRY_INTERVAL_MS,
CONFIG_YARN_RM_RETRY_INTERVAL_MS_DEFAULT));
conf.setInt(CommonConfigurationKeysPublic.IPC_CLIENT_CONNECT_MAX_RETRIES_KEY,
- conf.getInt(CONFIG_IPC_CLIENT_CONNECT_MAX_RETRIES,
- CONFIG_IPC_CLIENT_CONNECT_MAX_RETRIES_DEFAULT));
+ conf.getInt(CONFIG_IPC_CLIENT_CONNECT_MAX_RETRIES,
CONFIG_IPC_CLIENT_CONNECT_MAX_RETRIES_DEFAULT));
conf.setLong(CommonConfigurationKeysPublic.IPC_CLIENT_CONNECT_RETRY_INTERVAL_KEY,
- conf.getLong(CONFIG_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS,
- CONFIG_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS_DEFAULT));
+ conf.getLong(CONFIG_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS,
CONFIG_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS_DEFAULT));
- HiveConf.setVar(conf, HiveConf.ConfVars.HIVE_ZOOKEEPER_SESSION_TIMEOUT,
(conf
- .getLong(CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS,
CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS_DEFAULT) +
- "ms"));
+ HiveConf.setVar(conf, HiveConf.ConfVars.HIVE_ZOOKEEPER_SESSION_TIMEOUT, (
+ conf.getLong(CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS,
CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS_DEFAULT) + "ms"));
llapRegistryConf = new Configuration(conf);
}
- /**
- * Parse command line options.
- *
- * @param args
- * @return command line options.
- */
- public LlapStatusOptions parseOptions(String[] args) throws
- LlapStatusCliException {
-
- LlapStatusOptionsProcessor optionsProcessor = new
LlapStatusOptionsProcessor();
- LlapStatusOptions options;
- try {
- options = optionsProcessor.processOptions(args);
- return options;
- } catch (Exception e) {
- LOG.info("Failed to parse arguments", e);
- throw new LlapStatusCliException(ExitCode.INCORRECT_USAGE, "Incorrect
usage");
- }
- }
-
- public int run(LlapStatusOptions options, long watchTimeoutMs) {
+ public ExitCode run(LlapStatusServiceCommandLine cl, long watchTimeoutMs) {
appStatusBuilder = new AppStatusBuilder();
try {
if (appName == null) {
// user provided configs
- for (Map.Entry<Object, Object> props : options.getConf().entrySet()) {
+ for (Map.Entry<Object, Object> props : cl.getHiveConf().entrySet()) {
conf.set((String) props.getKey(), (String) props.getValue());
}
- appName = options.getName();
+ appName = cl.getName();
if (StringUtils.isEmpty(appName)) {
appName = HiveConf.getVar(conf,
HiveConf.ConfVars.LLAP_DAEMON_SERVICE_HOSTS);
if (appName.startsWith("@") && appName.length() > 1) {
@@ -205,15 +183,11 @@ public class LlapStatusServiceDriver {
}
}
if (StringUtils.isEmpty(appName)) {
- String message =
- "Invalid app name. This must be setup via config or passed in as a
parameter." +
- " This tool works with clusters deployed by YARN Service";
- LOG.info(message);
- return ExitCode.INCORRECT_USAGE.getInt();
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug("Using appName: {}", appName);
+ LOG.error("Invalid app name. This must be setup via config or passed
in as a parameter." +
+ " This tool works with clusters deployed by YARN Service");
+ return ExitCode.INCORRECT_USAGE;
}
+ LOG.debug("Using appName: {}", appName);
llapRegistryConf.set(HiveConf.ConfVars.LLAP_DAEMON_SERVICE_HOSTS.varname, "@" +
appName);
}
@@ -224,20 +198,18 @@ public class LlapStatusServiceDriver {
}
} catch (Exception e) {
LlapStatusCliException le = new LlapStatusCliException(
-
LlapStatusServiceDriver.ExitCode.SERVICE_CLIENT_ERROR_CREATE_FAILED,
- "Failed to create service client", e);
+ ExitCode.SERVICE_CLIENT_ERROR_CREATE_FAILED, "Failed to create
service client", e);
logError(le);
- return le.getExitCode().getInt();
+ return le.getExitCode();
}
// Get the App report from YARN
ApplicationReport appReport;
try {
- appReport = LlapSliderUtils.getAppReport(appName, serviceClient,
- options.getFindAppTimeoutMs());
+ appReport = getAppReport(appName, cl.getFindAppTimeoutMs());
} catch (LlapStatusCliException e) {
logError(e);
- return e.getExitCode().getInt();
+ return e.getExitCode();
}
// Process the report
@@ -246,139 +218,165 @@ public class LlapStatusServiceDriver {
ret = processAppReport(appReport, appStatusBuilder);
} catch (LlapStatusCliException e) {
logError(e);
- return e.getExitCode().getInt();
+ return e.getExitCode();
}
if (ret != ExitCode.SUCCESS) {
- return ret.getInt();
+ return ret;
} else if
(NO_YARN_SERVICE_INFO_STATES.contains(appStatusBuilder.getState())) {
- return ExitCode.SUCCESS.getInt();
+ return ExitCode.SUCCESS;
} else {
// Get information from YARN Service
try {
- ret = populateAppStatusFromServiceStatus(appName, serviceClient,
- appStatusBuilder);
+ ret = populateAppStatusFromServiceStatus(appName, serviceClient,
appStatusBuilder);
} catch (LlapStatusCliException e) {
- // In case of failure, send back whatever is constructed so far -
- // which would be from the AppReport
+ // In case of failure, send back whatever is constructed so far -
which would be from the AppReport
logError(e);
- return e.getExitCode().getInt();
+ return e.getExitCode();
}
}
if (ret != ExitCode.SUCCESS) {
- return ret.getInt();
+ return ret;
} else {
try {
ret = populateAppStatusFromLlapRegistry(appStatusBuilder,
watchTimeoutMs);
} catch (LlapStatusCliException e) {
logError(e);
- return e.getExitCode().getInt();
+ return e.getExitCode();
}
}
- return ret.getInt();
+ return ret;
} finally {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Final AppState: " + appStatusBuilder.toString());
+ LOG.debug("Final AppState: " + appStatusBuilder.toString());
+ }
+ }
+
+ private ApplicationReport getAppReport(String appName, long timeoutMs)
+ throws LlapStatusCliException {
+ Clock clock = SystemClock.getInstance();
+ long startTime = clock.getTime();
+ long timeoutTime = timeoutMs < 0 ? Long.MAX_VALUE : (startTime +
timeoutMs);
+ ApplicationReport appReport = null;
+ ApplicationId appId;
+ try {
+ appId = serviceClient.getAppId(appName);
+ } catch (YarnException | IOException e) {
+ return null;
+ }
+
+ while (appReport == null) {
+ try {
+ appReport = serviceClient.getYarnClient().getApplicationReport(appId);
+ if (timeoutMs == 0) {
+ // break immediately if timeout is 0
+ break;
+ }
+ // Otherwise sleep, and try again.
+ if (appReport == null) {
+ long remainingTime = Math.min(timeoutTime - clock.getTime(), 500L);
+ if (remainingTime > 0) {
+ Thread.sleep(remainingTime);
+ } else {
+ break;
+ }
+ }
+ } catch (Exception e) {
+ if (e instanceof ApplicationNotFoundException) {
+ //This might happen when serviceClient caches an appId from the past
which is now not
+ // valid (i.e. Yarn RM restart). This will force re-creation of
service client in the
+ // next check (if watch mode is on..) which effectively invalidates
such cache.
+ serviceClient = null;
+ }
+ throw new LlapStatusCliException(ExitCode.YARN_ERROR, "Failed to get
Yarn AppReport", e);
}
}
+ return appReport;
}
- public void outputJson(PrintWriter writer) throws
- LlapStatusCliException {
+ public void outputJson(PrintWriter writer) throws LlapStatusCliException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_EMPTY);
+ mapper.setVisibility(JsonMethod.ALL, Visibility.NON_PRIVATE);
try {
writer.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(appStatusBuilder));
} catch (IOException e) {
LOG.warn("Failed to create JSON", e);
- throw new LlapStatusCliException(ExitCode.LLAP_JSON_GENERATION_ERROR,
"Failed to create JSON",
- e);
+ throw new LlapStatusCliException(ExitCode.LLAP_JSON_GENERATION_ERROR,
"Failed to create JSON", e);
}
}
/**
- * Populates parts of the AppStatus
+ * Populates parts of the AppStatus.
*
- * @param appReport
- * @param appStatusBuilder
* @return an ExitCode. An ExitCode other than ExitCode.SUCCESS implies
future progress not possible
* @throws LlapStatusCliException
*/
- private ExitCode processAppReport(ApplicationReport appReport,
- AppStatusBuilder appStatusBuilder) throws
- LlapStatusCliException {
+ private ExitCode processAppReport(ApplicationReport appReport,
AppStatusBuilder appStatusBuilder)
+ throws LlapStatusCliException {
if (appReport == null) {
appStatusBuilder.setState(State.APP_NOT_FOUND);
LOG.info("No Application Found");
return ExitCode.SUCCESS;
}
+ applicationId = appReport.getApplicationId().toString();
+
// TODO Maybe add the YARN URL for the app.
appStatusBuilder.setAmInfo(
- new
LlapStatusHelpers.AmInfo().setAppName(appReport.getName()).setAppType(appReport.getApplicationType()));
+ new
AmInfo().setAppName(appReport.getName()).setAppType(appReport.getApplicationType()));
appStatusBuilder.setAppStartTime(appReport.getStartTime());
switch (appReport.getYarnApplicationState()) {
- case NEW:
- case NEW_SAVING:
- case SUBMITTED:
- appStatusBuilder.setState(State.LAUNCHING);
- return ExitCode.SUCCESS;
- case ACCEPTED:
-
appStatusBuilder.maybeCreateAndGetAmInfo().setAppId(appReport.getApplicationId().toString());
- appStatusBuilder.setState(State.LAUNCHING);
- return ExitCode.SUCCESS;
- case RUNNING:
-
appStatusBuilder.maybeCreateAndGetAmInfo().setAppId(appReport.getApplicationId().toString());
- // If the app state is running, get additional information from YARN
Service
- return ExitCode.SUCCESS;
- case FINISHED:
- case FAILED:
- case KILLED:
-
appStatusBuilder.maybeCreateAndGetAmInfo().setAppId(appReport.getApplicationId().toString());
- appStatusBuilder.setAppFinishTime(appReport.getFinishTime());
- appStatusBuilder.setState(State.COMPLETE);
- // add log links and other diagnostics from YARN Service
- return ExitCode.SUCCESS;
- default:
- throw new LlapStatusCliException(ExitCode.INTERNAL_ERROR,
- "Unknown Yarn Application State: " +
appReport.getYarnApplicationState());
+ case NEW:
+ case NEW_SAVING:
+ case SUBMITTED:
+ appStatusBuilder.setState(State.LAUNCHING);
+ return ExitCode.SUCCESS;
+ case ACCEPTED:
+ appStatusBuilder.maybeCreateAndGetAmInfo().setAppId(applicationId);
+ appStatusBuilder.setState(State.LAUNCHING);
+ return ExitCode.SUCCESS;
+ case RUNNING:
+ appStatusBuilder.maybeCreateAndGetAmInfo().setAppId(applicationId);
+ // If the app state is running, get additional information from YARN
Service
+ return ExitCode.SUCCESS;
+ case FINISHED:
+ case FAILED:
+ case KILLED:
+ appStatusBuilder.maybeCreateAndGetAmInfo().setAppId(applicationId);
+ appStatusBuilder.setAppFinishTime(appReport.getFinishTime());
+ appStatusBuilder.setState(State.COMPLETE);
+ // add log links and other diagnostics from YARN Service
+ return ExitCode.SUCCESS;
+ default:
+ throw new LlapStatusCliException(ExitCode.INTERNAL_ERROR,
+ "Unknown Yarn Application State: " +
appReport.getYarnApplicationState());
}
}
/**
* Populates information from YARN Service Status.
*
- * @param appName
- * @param serviceClient
- * @param appStatusBuilder
- * @return an ExitCode. An ExitCode other than ExitCode.SUCCESS implies
future
- * progress not possible
+ * @return an ExitCode. An ExitCode other than ExitCode.SUCCESS implies
future progress not possible
* @throws LlapStatusCliException
*/
- private ExitCode populateAppStatusFromServiceStatus(String appName,
- ServiceClient serviceClient, AppStatusBuilder appStatusBuilder)
- throws LlapStatusCliException {
+ private ExitCode populateAppStatusFromServiceStatus(String appName,
ServiceClient serviceClient,
+ AppStatusBuilder appStatusBuilder) throws LlapStatusCliException {
ExitCode exitCode = ExitCode.YARN_ERROR;
try {
Service service = serviceClient.getStatus(appName);
if (service != null) {
// How to get config paths and AmInfo
ServiceState state = service.getState();
- appStatusBuilder.setAppStartTime(service.getLaunchTime() == null ? 0
- : service.getLaunchTime().getTime());
- appStatusBuilder.setDesiredInstances(
- service.getComponent(LLAP_KEY).getNumberOfContainers() == null ? 0
- : service.getComponent(LLAP_KEY).getNumberOfContainers()
- .intValue());
- appStatusBuilder.setLiveInstances(
- service.getComponent(LLAP_KEY).getContainers().size());
+ appStatusBuilder.setAppStartTime(service.getLaunchTime() == null ? 0 :
service.getLaunchTime().getTime());
+
appStatusBuilder.setDesiredInstances(service.getComponent(LLAP_KEY).getNumberOfContainers()
== null ? 0
+ :
service.getComponent(LLAP_KEY).getNumberOfContainers().intValue());
+
appStatusBuilder.setLiveInstances(service.getComponent(LLAP_KEY).getContainers().size());
for (Container cont : service.getComponent(LLAP_KEY).getContainers()) {
- LlapInstance llapInstance = new LlapInstance(cont.getHostname(),
- cont.getId());
+ LlapInstance llapInstance = new LlapInstance(cont.getHostname(),
cont.getId());
appStatusBuilder.addNewRunningLlapInstance(llapInstance);
}
if (state == ServiceState.STARTED || state == ServiceState.STABLE ||
state == ServiceState.FLEX) {
@@ -389,8 +387,7 @@ public class LlapStatusServiceDriver {
}
} catch (IOException | YarnException e) {
LlapStatusCliException le = new LlapStatusCliException(
- LlapStatusServiceDriver.ExitCode.SERVICE_CLIENT_ERROR_OTHER,
- "Failed to get service status", e);
+ ExitCode.SERVICE_CLIENT_ERROR_OTHER, "Failed to get service status",
e);
logError(le);
exitCode = le.getExitCode();
}
@@ -400,13 +397,11 @@ public class LlapStatusServiceDriver {
/**
* Populate additional information for containers from the LLAP registry.
Must be invoked
* after YARN Service status and diagnostics.
- * @param appStatusBuilder
* @return an ExitCode. An ExitCode other than ExitCode.SUCCESS implies
future progress not possible
* @throws LlapStatusCliException
*/
- private ExitCode populateAppStatusFromLlapRegistry(
- AppStatusBuilder appStatusBuilder, long watchTimeoutMs) throws
- LlapStatusCliException {
+ private ExitCode populateAppStatusFromLlapRegistry(AppStatusBuilder
appStatusBuilder, long watchTimeoutMs)
+ throws LlapStatusCliException {
if (llapRegistry == null) {
try {
@@ -425,9 +420,7 @@ public class LlapStatusServiceDriver {
}
if (serviceInstances == null || serviceInstances.isEmpty()) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("No information found in the LLAP registry");
- }
+ LOG.debug("No information found in the LLAP registry");
appStatusBuilder.setLiveInstances(0);
appStatusBuilder.setState(State.LAUNCHING);
appStatusBuilder.clearRunningLlapInstances();
@@ -439,10 +432,9 @@ public class LlapStatusServiceDriver {
for (LlapServiceInstance serviceInstance : serviceInstances) {
String containerIdString = serviceInstance.getProperties().get(
- HiveConf.ConfVars.LLAP_DAEMON_CONTAINER_ID.varname);
+ HiveConf.ConfVars.LLAP_DAEMON_CONTAINER_ID.varname);
- LlapInstance llapInstance =
appStatusBuilder.removeAndGetRunningLlapInstanceForContainer(
- containerIdString);
+ LlapInstance llapInstance =
appStatusBuilder.removeAndGetRunningLlapInstanceForContainer(containerIdString);
if (llapInstance != null) {
llapInstance.setMgmtPort(serviceInstance.getManagementPort());
llapInstance.setRpcPort(serviceInstance.getRpcPort());
@@ -461,8 +453,8 @@ public class LlapStatusServiceDriver {
appStatusBuilder.setLiveInstances(validatedInstances.size());
appStatusBuilder.setLaunchingInstances(llapExtraInstances.size());
- if (appStatusBuilder.getDesiredInstances() != null && validatedInstances
- .size() >= appStatusBuilder.getDesiredInstances()) {
+ if (appStatusBuilder.getDesiredInstances() != null &&
+ validatedInstances.size() >= appStatusBuilder.getDesiredInstances())
{
appStatusBuilder.setState(State.RUNNING_ALL);
if (validatedInstances.size() >
appStatusBuilder.getDesiredInstances()) {
LOG.warn("Found more entries in LLAP registry, as compared to
desired entries");
@@ -493,207 +485,40 @@ public class LlapStatusServiceDriver {
return ExitCode.SUCCESS;
}
- private static String
constructCompletedContainerDiagnostics(List<LlapInstance> completedInstances) {
- StringBuilder sb = new StringBuilder();
- if (completedInstances == null || completedInstances.size() == 0) {
- return "";
- } else {
- // TODO HIVE-15865 Ideally sort these by completion time, once that is
available.
- boolean isFirst = true;
- for (LlapInstance instance : completedInstances) {
- if (!isFirst) {
- sb.append("\n");
- } else {
- isFirst = false;
- }
-
- if (instance.getYarnContainerExitStatus() ==
- ContainerExitStatus.KILLED_EXCEEDED_PMEM ||
- instance.getYarnContainerExitStatus() ==
- ContainerExitStatus.KILLED_EXCEEDED_VMEM) {
- sb.append("\tKILLED container (by YARN for exceeding memory limits):
");
- } else {
- // TODO HIVE-15865 Handle additional reasons like OS launch failed
- sb.append("\tFAILED container: ");
- }
- sb.append(" ").append(instance.getContainerId());
- sb.append(", Logs at: ").append(instance.getLogUrl());
- }
- }
- return sb.toString();
- }
-
- /**
- * Helper method to construct a diagnostic message from a complete
- * AppStatusBuilder.
- *
- * @return
- */
- private static String constructDiagnostics(
- AppStatusBuilder appStatusBuilder) {
- StringBuilder sb = new StringBuilder();
-
- switch (appStatusBuilder.getState()) {
- case APP_NOT_FOUND:
- sb.append("LLAP status unknown. Awaiting app launch");
- break;
- case LAUNCHING:
- // This is a catch all state - when containers have not started yet,
or LLAP has not started yet.
- if (StringUtils.isNotBlank(appStatusBuilder.getAmInfo().getAppId())) {
- sb.append("LLAP Starting up with AppId=")
- .append(appStatusBuilder.getAmInfo().getAppId()).append(".");
- if (appStatusBuilder.getDesiredInstances() != null) {
- sb.append(" Started
0/").append(appStatusBuilder.getDesiredInstances()).append(" instances");
- }
-
- String containerDiagnostics = constructCompletedContainerDiagnostics(
- appStatusBuilder.getCompletedInstances());
- if (StringUtils.isNotEmpty(containerDiagnostics)) {
- sb.append("\n").append(containerDiagnostics);
- }
- } else {
- sb.append("Awaiting LLAP startup");
- }
- break;
- case RUNNING_PARTIAL:
- sb.append("LLAP Starting up with ApplicationId=")
- .append(appStatusBuilder.getAmInfo().getAppId());
- sb.append(" Started").append(appStatusBuilder.getLiveInstances())
- .append("/").append(appStatusBuilder.getDesiredInstances())
- .append(" instances");
- String containerDiagnostics = constructCompletedContainerDiagnostics(
- appStatusBuilder.getCompletedInstances());
- if (StringUtils.isNotEmpty(containerDiagnostics)) {
- sb.append("\n").append(containerDiagnostics);
- }
-
- // TODO HIVE-15865: Include information about pending requests, and
last
- // allocation time once YARN Service provides this information.
- break;
- case RUNNING_ALL:
- sb.append("LLAP Application running with ApplicationId=")
- .append(appStatusBuilder.getAmInfo().getAppId());
- break;
- case COMPLETE:
-
- sb.append("LLAP Application already complete. ApplicationId=")
- .append(appStatusBuilder.getAmInfo().getAppId());
- containerDiagnostics = constructCompletedContainerDiagnostics(
- appStatusBuilder.getCompletedInstances());
- if (StringUtils.isNotEmpty(containerDiagnostics)) {
- sb.append("\n").append(containerDiagnostics);
- }
-
- break;
- case UNKNOWN:
- sb.append("LLAP status unknown");
- break;
- }
- if (StringUtils.isNotBlank(appStatusBuilder.getDiagnostics())) {
- sb.append("\n").append(appStatusBuilder.getDiagnostics());
- }
-
- return sb.toString();
- }
-
- public enum ExitCode {
- SUCCESS(0),
- INCORRECT_USAGE(10),
- YARN_ERROR(20),
- SERVICE_CLIENT_ERROR_CREATE_FAILED(30),
- SERVICE_CLIENT_ERROR_OTHER(31),
- LLAP_REGISTRY_ERROR(40),
- LLAP_JSON_GENERATION_ERROR(50),
- // Error in the script itself - likely caused by an incompatible change,
or new functionality / states added.
- INTERNAL_ERROR(100);
-
- private final int exitCode;
-
- ExitCode(int exitCode) {
- this.exitCode = exitCode;
- }
-
- public int getInt() {
- return exitCode;
- }
- }
-
-
- public static class LlapStatusCliException extends Exception {
- final LlapStatusServiceDriver.ExitCode exitCode;
-
-
- public LlapStatusCliException(LlapStatusServiceDriver.ExitCode exitCode,
String message) {
- super(exitCode.getInt() +": " + message);
- this.exitCode = exitCode;
- }
-
- public LlapStatusCliException(LlapStatusServiceDriver.ExitCode exitCode,
String message, Throwable cause) {
- super(message, cause);
- this.exitCode = exitCode;
+ private void close() {
+ if (serviceClient != null) {
+ serviceClient.stop();
}
-
- public LlapStatusServiceDriver.ExitCode getExitCode() {
- return exitCode;
+ if (llapRegistry != null) {
+ llapRegistry.stop();
}
}
-
- private static void logError(Throwable t) {
- LOG.error("FAILED: " + t.getMessage(), t);
- System.err.println("FAILED: " + t.getMessage());
- }
-
-
public static void main(String[] args) {
- LOG.info("LLAP status invoked with arguments = {}", Arrays.toString(args));
- int ret = ExitCode.SUCCESS.getInt();
+ LlapStatusServiceCommandLine cl =
LlapStatusServiceCommandLine.parseArguments(args);
+ LlapStatusServiceDriver statusServiceDriver = createServiceDriver();
+
+ ExitCode ret = ExitCode.SUCCESS;
Clock clock = SystemClock.getInstance();
- long startTime = clock.getTime();
long lastSummaryLogTime = -1;
- LlapStatusServiceDriver statusServiceDriver = null;
- LlapStatusOptions options = null;
- try {
- statusServiceDriver = new LlapStatusServiceDriver();
- options = statusServiceDriver.parseOptions(args);
- } catch (Throwable t) {
- statusServiceDriver.close();
- logError(t);
- if (t instanceof LlapStatusCliException) {
- LlapStatusCliException
- ce = (LlapStatusCliException) t;
- ret = ce.getExitCode().getInt();
- } else {
- ret = ExitCode.INTERNAL_ERROR.getInt();
- }
- }
- if (ret != 0 || options == null) { // Failure / help
- if (statusServiceDriver != null) {
- statusServiceDriver.close();
- }
- System.exit(ret);
- }
-
boolean firstAttempt = true;
- final long refreshInterval = options.getRefreshIntervalMs();
- final boolean watchMode = options.isWatchMode();
- final long watchTimeout = options.getWatchTimeoutMs();
+ final long refreshInterval = cl.getRefreshIntervalMs();
+ final boolean watchMode = cl.isWatchMode();
+ final long watchTimeout = cl.getWatchTimeoutMs();
long numAttempts = watchTimeout / refreshInterval;
numAttempts = watchMode ? numAttempts : 1; // Break out of the loop fast
if watchMode is disabled.
- LlapStatusHelpers.State launchingState = null;
- LlapStatusHelpers.State currentState = null;
+ State launchingState = null;
+ State currentState = null;
boolean desiredStateAttained = false;
- final float runningNodesThreshold = options.getRunningNodesThreshold();
- try (OutputStream os = options.getOutputFile() == null ? System.out :
- new BufferedOutputStream(new FileOutputStream(options.getOutputFile()));
- PrintWriter pw = new PrintWriter(os)) {
+ final float runningNodesThreshold = cl.getRunningNodesThreshold();
+ try (OutputStream os = cl.getOutputFile() == null ? System.out : new
FileOutputStream(cl.getOutputFile());
+ Writer w = new OutputStreamWriter(os, Charset.defaultCharset());
+ PrintWriter pw = new PrintWriter(w)) {
LOG.info("Configured refresh interval: {}s. Watch timeout: {}s. Attempts
remaining: {}." +
- " Watch mode: {}. Running nodes threshold: {}.",
- TimeUnit.SECONDS.convert(refreshInterval, TimeUnit.MILLISECONDS),
- TimeUnit.SECONDS.convert(watchTimeout, TimeUnit.MILLISECONDS),
- numAttempts, watchMode, new
DecimalFormat("#.###").format(runningNodesThreshold));
+ " Watch mode: {}. Running nodes threshold: {}.",
refreshInterval/1000, watchTimeout/1000,
+ numAttempts, watchMode, new
DecimalFormat("#.###").format(runningNodesThreshold));
while (numAttempts > 0) {
if (!firstAttempt) {
if (watchMode) {
@@ -709,17 +534,16 @@ public class LlapStatusServiceDriver {
} else {
firstAttempt = false;
}
- ret = statusServiceDriver.run(options, watchMode ? watchTimeout : 0);
+ ret = statusServiceDriver.run(cl, watchMode ? watchTimeout : 0);
currentState = statusServiceDriver.appStatusBuilder.getState();
try {
- lastSummaryLogTime = LlapStatusServiceDriver
- .maybeLogSummary(clock, lastSummaryLogTime, statusServiceDriver,
- watchMode, watchTimeout, launchingState);
+ lastSummaryLogTime = LlapStatusServiceDriver.maybeLogSummary(clock,
lastSummaryLogTime,
+ statusServiceDriver, watchMode, watchTimeout, launchingState);
} catch (Exception e) {
LOG.warn("Failed to log summary", e);
}
- if (ret == ExitCode.SUCCESS.getInt()) {
+ if (ret == ExitCode.SUCCESS) {
if (watchMode) {
// YARN Service has started llap application, now if for some
reason
@@ -729,10 +553,9 @@ public class LlapStatusServiceDriver {
}
if (currentState.equals(State.COMPLETE)) {
- if (launchingState != null || options.isLaunched()) {
+ if (launchingState != null || cl.isLaunched()) {
LOG.warn("COMPLETE state reached while waiting for RUNNING
state. Failing.");
- System.err.println("Final diagnostics: " +
- statusServiceDriver.appStatusBuilder.getDiagnostics());
+ System.err.println("Final diagnostics: " +
statusServiceDriver.appStatusBuilder.getDiagnostics());
break;
} else {
LOG.info("Found a stopped application; assuming it was a
previous attempt "
@@ -740,19 +563,15 @@ public class LlapStatusServiceDriver {
}
}
- if (!(currentState.equals(State.RUNNING_PARTIAL) ||
currentState.equals(
- State.RUNNING_ALL))) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(
- "Current state: {}. Desired state: {}. {}/{} instances.",
- currentState,
- runningNodesThreshold == 1.0f ?
- State.RUNNING_ALL :
- State.RUNNING_PARTIAL,
- statusServiceDriver.appStatusBuilder.getLiveInstances(),
- statusServiceDriver.appStatusBuilder
- .getDesiredInstances());
- }
+ if (!(currentState.equals(State.RUNNING_PARTIAL) ||
currentState.equals(State.RUNNING_ALL))) {
+ LOG.debug(
+ "Current state: {}. Desired state: {}. {}/{} instances.",
+ currentState,
+ runningNodesThreshold == 1.0f ?
+ State.RUNNING_ALL :
+ State.RUNNING_PARTIAL,
+ statusServiceDriver.appStatusBuilder.getLiveInstances(),
+ statusServiceDriver.appStatusBuilder.getDesiredInstances());
numAttempts--;
continue;
}
@@ -763,17 +582,13 @@ public class LlapStatusServiceDriver {
if (desiredInstances > 0) {
final float ratio = (float) liveInstances / (float)
desiredInstances;
if (ratio < runningNodesThreshold) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(
- "Waiting until running nodes threshold is reached.
Current: {} Desired: {}." +
- " {}/{} instances.",
- new DecimalFormat("#.###").format(ratio),
- new DecimalFormat("#.###")
- .format(runningNodesThreshold),
- statusServiceDriver.appStatusBuilder.getLiveInstances(),
- statusServiceDriver.appStatusBuilder
- .getDesiredInstances());
- }
+ LOG.debug(
+ "Waiting until running nodes threshold is reached.
Current: {} Desired: {}." +
+ " {}/{} instances.",
+ new DecimalFormat("#.###").format(ratio),
+ new DecimalFormat("#.###").format(runningNodesThreshold),
+ statusServiceDriver.appStatusBuilder.getLiveInstances(),
+
statusServiceDriver.appStatusBuilder.getDesiredInstances());
numAttempts--;
continue;
} else {
@@ -785,19 +600,19 @@ public class LlapStatusServiceDriver {
continue;
}
}
- } else if (ret == ExitCode.YARN_ERROR.getInt() && watchMode) {
+ } else if (ret == ExitCode.YARN_ERROR && watchMode) {
LOG.warn("Watch mode enabled and got YARN error. Retrying..");
numAttempts--;
continue;
- } else if (ret == ExitCode.SERVICE_CLIENT_ERROR_CREATE_FAILED.getInt()
&& watchMode) {
+ } else if (ret == ExitCode.SERVICE_CLIENT_ERROR_CREATE_FAILED &&
watchMode) {
LOG.warn("Watch mode enabled and YARN Service client creation
failed. Retrying..");
numAttempts--;
continue;
- } else if (ret == ExitCode.SERVICE_CLIENT_ERROR_OTHER.getInt() &&
watchMode) {
+ } else if (ret == ExitCode.SERVICE_CLIENT_ERROR_OTHER && watchMode) {
LOG.warn("Watch mode enabled and got YARN Service client error.
Retrying..");
numAttempts--;
continue;
- } else if (ret == ExitCode.LLAP_REGISTRY_ERROR.getInt() && watchMode) {
+ } else if (ret == ExitCode.LLAP_REGISTRY_ERROR && watchMode) {
LOG.warn("Watch mode enabled and got LLAP registry error.
Retrying..");
numAttempts--;
continue;
@@ -805,45 +620,47 @@ public class LlapStatusServiceDriver {
break;
}
// Log final state to CONSOLE_LOGGER
- LlapStatusServiceDriver
- .maybeLogSummary(clock, 0L, statusServiceDriver,
- watchMode, watchTimeout, launchingState);
+ maybeLogSummary(clock, 0L, statusServiceDriver, watchMode, watchTimeout,
launchingState);
CONSOLE_LOGGER.info("\n\n\n");
- // print current state before exiting
- statusServiceDriver.outputJson(pw);
- os.flush();
+
+ statusServiceDriver.outputJson(pw); // print current state before exiting
pw.flush();
if (numAttempts == 0 && watchMode && !desiredStateAttained) {
- LOG.warn("Watch timeout {}s exhausted before desired state RUNNING is
attained.",
- TimeUnit.SECONDS.convert(watchTimeout, TimeUnit.MILLISECONDS));
+ LOG.warn("Watch timeout {}s exhausted before desired state RUNNING is
attained.", watchTimeout/1000);
}
} catch (Throwable t) {
logError(t);
if (t instanceof LlapStatusCliException) {
- LlapStatusCliException
- ce = (LlapStatusCliException) t;
- ret = ce.getExitCode().getInt();
+ LlapStatusCliException ce = (LlapStatusCliException) t;
+ ret = ce.getExitCode();
} else {
- ret = ExitCode.INTERNAL_ERROR.getInt();
+ ret = ExitCode.INTERNAL_ERROR;
}
} finally {
LOG.info("LLAP status finished");
+ if (ret != ExitCode.SUCCESS) {
+ LOG.error("LLAP did not start. Check the application log for more
info:\n" +
+ "\tyarn logs --applicationId {} -out <path>",
statusServiceDriver.applicationId);
+ }
statusServiceDriver.close();
}
- if (LOG.isDebugEnabled()) {
- LOG.debug("Completed processing - exiting with " + ret);
+ LOG.debug("Completed processing - exiting with " + ret);
+
+ // HACK: due to the System.exit some log messages may not be present.
+ try {
+ Thread.sleep(1000);
+ } catch (Exception e) {
+ // ignore
}
- System.exit(ret);
+ System.exit(ret.getCode());
}
- private static long maybeLogSummary(Clock clock, long lastSummaryLogTime,
- LlapStatusServiceDriver
statusServiceDriver,
- boolean watchMode, long watchTimeout,
LlapStatusHelpers.State launchingState) {
+ private static long maybeLogSummary(Clock clock, long lastSummaryLogTime,
LlapStatusServiceDriver statusServiceDriver,
+ boolean watchMode, long watchTimeout,
State launchingState) {
long currentTime = clock.getTime();
if (lastSummaryLogTime < currentTime - LOG_SUMMARY_INTERVAL) {
String diagString = null;
- if (launchingState == null &&
statusServiceDriver.appStatusBuilder.getState() ==
- State.COMPLETE && watchMode) {
+ if (launchingState == null &&
statusServiceDriver.appStatusBuilder.getState() == State.COMPLETE && watchMode)
{
// First known state was COMPLETED. Wait for the app launch to start.
diagString = "Awaiting LLAP launch";
// Clear completed instances in this case. Don't want to provide
information from the previous run.
@@ -854,28 +671,112 @@ public class LlapStatusServiceDriver {
if (lastSummaryLogTime == -1) {
if (watchMode) {
- CONSOLE_LOGGER.info("\nLLAPSTATUS WatchMode with timeout={} s",
- TimeUnit.SECONDS.convert(watchTimeout, TimeUnit.MILLISECONDS));
+ CONSOLE_LOGGER.info("\nLLAPSTATUS WatchMode with timeout={} s",
watchTimeout/1000);
} else {
CONSOLE_LOGGER.info("\nLLAPSTATUS");
}
- CONSOLE_LOGGER.info(
-
"--------------------------------------------------------------------------------");
+
CONSOLE_LOGGER.info("--------------------------------------------------------------------------------");
}
CONSOLE_LOGGER.info(diagString);
- CONSOLE_LOGGER.info(
-
"--------------------------------------------------------------------------------");
+
CONSOLE_LOGGER.info("--------------------------------------------------------------------------------");
lastSummaryLogTime = currentTime;
}
return lastSummaryLogTime;
}
- private void close() {
- if (serviceClient != null) {
- serviceClient.stop();
+ /**
+ * Helper method to construct a diagnostic message from a complete
AppStatusBuilder.
+ */
+ private static String constructDiagnostics(AppStatusBuilder
appStatusBuilder) {
+ StringBuilder sb = new StringBuilder();
+
+ switch (appStatusBuilder.getState()) {
+ case APP_NOT_FOUND:
+ sb.append("LLAP status unknown. Awaiting app launch");
+ break;
+ case LAUNCHING:
+ // This is a catch all state - when containers have not started yet, or
LLAP has not started yet.
+ if (StringUtils.isNotBlank(appStatusBuilder.getAmInfo().getAppId())) {
+ sb.append("LLAP Starting up with
AppId=").append(appStatusBuilder.getAmInfo().getAppId()).append(".");
+ if (appStatusBuilder.getDesiredInstances() != null) {
+ sb.append(" Started
0/").append(appStatusBuilder.getDesiredInstances()).append(" instances");
+ }
+
+ String containerDiagnostics = constructCompletedContainerDiagnostics(
+ appStatusBuilder.getCompletedInstances());
+ if (StringUtils.isNotEmpty(containerDiagnostics)) {
+ sb.append("\n").append(containerDiagnostics);
+ }
+ } else {
+ sb.append("Awaiting LLAP startup");
+ }
+ break;
+ case RUNNING_PARTIAL:
+ sb.append("LLAP Starting up with
ApplicationId=").append(appStatusBuilder.getAmInfo().getAppId());
+ sb.append("
Started").append(appStatusBuilder.getLiveInstances()).append("/")
+ .append(appStatusBuilder.getDesiredInstances()).append(" instances");
+ String containerDiagnostics =
constructCompletedContainerDiagnostics(appStatusBuilder.getCompletedInstances());
+ if (StringUtils.isNotEmpty(containerDiagnostics)) {
+ sb.append("\n").append(containerDiagnostics);
+ }
+
+ // TODO HIVE-15865: Include information about pending requests, and last
+ // allocation time once YARN Service provides this information.
+ break;
+ case RUNNING_ALL:
+ sb.append("LLAP Application running with
ApplicationId=").append(appStatusBuilder.getAmInfo().getAppId());
+ break;
+ case COMPLETE:
+ sb.append("LLAP Application already complete.
ApplicationId=").append(appStatusBuilder.getAmInfo().getAppId());
+ containerDiagnostics =
constructCompletedContainerDiagnostics(appStatusBuilder.getCompletedInstances());
+ if (StringUtils.isNotEmpty(containerDiagnostics)) {
+ sb.append("\n").append(containerDiagnostics);
+ }
+
+ break;
+ case UNKNOWN:
+ sb.append("LLAP status unknown");
+ break;
+ default:
+ throw new IllegalStateException("Unknown State: " +
appStatusBuilder.getState());
}
- if (llapRegistry != null) {
- llapRegistry.stop();
+ if (StringUtils.isNotBlank(appStatusBuilder.getDiagnostics())) {
+ sb.append("\n").append(appStatusBuilder.getDiagnostics());
}
+
+ return sb.toString();
+ }
+
+ private static String
constructCompletedContainerDiagnostics(List<LlapInstance> completedInstances) {
+ StringBuilder sb = new StringBuilder();
+ if (completedInstances == null || completedInstances.size() == 0) {
+ return "";
+ } else {
+ // TODO HIVE-15865 Ideally sort these by completion time, once that is
available.
+ boolean isFirst = true;
+ for (LlapInstance instance : completedInstances) {
+ if (!isFirst) {
+ sb.append("\n");
+ } else {
+ isFirst = false;
+ }
+
+ if (instance.getYarnContainerExitStatus() ==
ContainerExitStatus.KILLED_EXCEEDED_PMEM ||
+ instance.getYarnContainerExitStatus() ==
ContainerExitStatus.KILLED_EXCEEDED_VMEM) {
+ sb.append("\tKILLED container (by YARN for exceeding memory limits):
");
+ } else {
+ // TODO HIVE-15865 Handle additional reasons like OS launch failed
+ sb.append("\tFAILED container: ");
+ }
+ sb.append(" ").append(instance.getContainerId());
+ sb.append(", Logs at: ").append(instance.getLogUrl());
+ }
+ }
+ return sb.toString();
+ }
+
+ private static void logError(Throwable t) {
+ LOG.error("FAILED: " + t.getMessage(), t);
+ System.err.println("FAILED: " + t.getMessage());
}
}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/State.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/State.java
new file mode 100644
index 00000000000..40c189a8a11
--- /dev/null
+++ b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/State.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.hive.llap.cli.status;
+
+/**
+ * Enumeration of the potential states of the Llap.
+ */
+enum State {
+ APP_NOT_FOUND,
+ LAUNCHING,
+ RUNNING_PARTIAL,
+ RUNNING_ALL,
+ COMPLETE,
+ UNKNOWN
+}
diff --git
a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/package-info.java
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/package-info.java
new file mode 100644
index 00000000000..79cadc7cb07
--- /dev/null
+++
b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/status/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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 consisting the program LlapStatusServiceDriver (and other classes
used by it)
+ * which is monitoring if Llap is running.
+ */
+package org.apache.hadoop.hive.llap.cli.status;
+
diff --git
a/llap-server/src/test/org/apache/hadoop/hive/llap/cli/status/TestLlapStatusServiceCommandLine.java
b/llap-server/src/test/org/apache/hadoop/hive/llap/cli/status/TestLlapStatusServiceCommandLine.java
new file mode 100644
index 00000000000..3e4f6832a4d
--- /dev/null
+++
b/llap-server/src/test/org/apache/hadoop/hive/llap/cli/status/TestLlapStatusServiceCommandLine.java
@@ -0,0 +1,91 @@
+/*
+ * 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.hive.llap.cli.status;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static junit.framework.TestCase.assertEquals;
+
+import java.util.Properties;
+
+/**
+ * Tests for LlapStatusServiceCommandLine.
+ */
+public class TestLlapStatusServiceCommandLine {
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testArgumentParsingDefault() throws Exception {
+ LlapStatusServiceCommandLine cl = new LlapStatusServiceCommandLine(new
String[] {});
+
+ assertEquals("findAppTimeout should be the default value if not specified
otherwise",
+ cl.getFindAppTimeoutMs(),
LlapStatusServiceCommandLine.DEFAULT_FIND_YARN_APP_TIMEOUT_MS);
+
+ assertEquals("refreshInterval should be the default value if not specified
otherwise",
+ cl.getRefreshIntervalMs(),
LlapStatusServiceCommandLine.DEFAULT_STATUS_REFRESH_INTERVAL_MS);
+
+ assertEquals("watchTimeout should be the default value if not specified
otherwise",
+ cl.getWatchTimeoutMs(),
LlapStatusServiceCommandLine.DEFAULT_WATCH_MODE_TIMEOUT_MS);
+
+ assertEquals("runningNodesThreshold should be the default value if not
specified otherwise",
+ cl.getRunningNodesThreshold(),
LlapStatusServiceCommandLine.DEFAULT_RUNNING_NODES_THRESHOLD);
+
+ assertEquals("hiveConf should be empty properties if not specified
otherwise", cl.getHiveConf(),
+ new Properties());
+
+ assertEquals("isLaunched should be the true if not specified otherwise",
cl.isLaunched(), true);
+
+ assertEquals("watchMode should be the false if not specified otherwise",
cl.isWatchMode(), false);
+ }
+
+ @Test
+ public void testNegativeRefreshInterval() throws Exception {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Refresh interval should be >0");
+
+ new LlapStatusServiceCommandLine(new String[] {"--refreshInterval", "-1"});
+ }
+
+ @Test
+ public void testNegativeWatchTimeout() throws Exception {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Watch timeout should be >0");
+
+ new LlapStatusServiceCommandLine(new String[] {"--watchTimeout", "-1"});
+ }
+
+ @Test
+ public void testNegativeRunningNodesThreshold() throws Exception {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Running nodes threshold value should be between 0.0
and 1.0 (inclusive)");
+
+ new LlapStatusServiceCommandLine(new String[] {"--runningNodesThreshold",
"-1"});
+ }
+
+ @Test
+ public void testRunningNodesThresholdOverOne() throws Exception {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Running nodes threshold value should be between 0.0
and 1.0 (inclusive)");
+
+ new LlapStatusServiceCommandLine(new String[] {"--runningNodesThreshold",
"1.1"});
+ }
+}
diff --git
a/llap-server/src/test/org/apache/hadoop/hive/llap/cli/status/package-info.java
b/llap-server/src/test/org/apache/hadoop/hive/llap/cli/status/package-info.java
new file mode 100644
index 00000000000..9af5dd8ca39
--- /dev/null
+++
b/llap-server/src/test/org/apache/hadoop/hive/llap/cli/status/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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 consisting the tests for the program LlapStatusServiceDriver and
other classes used by it.
+ */
+package org.apache.hadoop.hive.llap.cli.status;
+
diff --git a/service/src/java/org/apache/hive/http/LlapServlet.java
b/service/src/java/org/apache/hive/http/LlapServlet.java
index 2bc59b59b27..ecb8e312313 100644
--- a/service/src/java/org/apache/hive/http/LlapServlet.java
+++ b/service/src/java/org/apache/hive/http/LlapServlet.java
@@ -28,8 +28,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.hadoop.hive.llap.cli.LlapStatusOptionsProcessor;
-import org.apache.hadoop.hive.llap.cli.LlapStatusServiceDriver;
+import org.apache.hadoop.hive.llap.cli.status.ExitCode;
+import org.apache.hadoop.hive.llap.cli.status.LlapStatusServiceCommandLine;
+import org.apache.hadoop.hive.llap.cli.status.LlapStatusServiceDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
@SuppressWarnings("serial")
public class LlapServlet extends HttpServlet {
@@ -96,8 +99,8 @@ public class LlapServlet extends HttpServlet {
LOG.info("Retrieving info for cluster: " + clusterName);
LlapStatusServiceDriver driver = new LlapStatusServiceDriver();
- int ret = driver.run(new
LlapStatusOptionsProcessor.LlapStatusOptions(clusterName), 0);
- if (ret == LlapStatusServiceDriver.ExitCode.SUCCESS.getInt()) {
+ ExitCode ret =
driver.run(LlapStatusServiceCommandLine.parseArguments(new String[] {"-n",
clusterName}), 0);
+ if (ret == ExitCode.SUCCESS) {
driver.outputJson(writer);
}