|
@@ -375,8 +375,14 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
.save(fs.getFileSystem(), ServiceApiUtil.getServiceJsonPath(fs, serviceName),
|
|
|
persistedService, true);
|
|
|
|
|
|
+ ApplicationId appId = getAppId(serviceName);
|
|
|
+ if (appId == null) {
|
|
|
+ String message = "Application ID doesn't exist for " + serviceName;
|
|
|
+ LOG.error(message);
|
|
|
+ throw new YarnException(message);
|
|
|
+ }
|
|
|
ApplicationReport appReport =
|
|
|
- yarnClient.getApplicationReport(getAppId(serviceName));
|
|
|
+ yarnClient.getApplicationReport(appId);
|
|
|
if (appReport.getYarnApplicationState() != RUNNING) {
|
|
|
String message =
|
|
|
serviceName + " is at " + appReport.getYarnApplicationState()
|
|
@@ -408,10 +414,16 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
throws YarnException, IOException {
|
|
|
ServiceApiUtil.validateNameFormat(serviceName, getConfig());
|
|
|
ApplicationId currentAppId = getAppId(serviceName);
|
|
|
+ if (currentAppId == null) {
|
|
|
+ LOG.info("Application ID doesn't exist for service {}", serviceName);
|
|
|
+ cleanUpRegistry(serviceName);
|
|
|
+ return EXIT_COMMAND_ARGUMENT_ERROR;
|
|
|
+ }
|
|
|
ApplicationReport report = yarnClient.getApplicationReport(currentAppId);
|
|
|
if (terminatedStates.contains(report.getYarnApplicationState())) {
|
|
|
LOG.info("Service {} is already in a terminated state {}", serviceName,
|
|
|
report.getYarnApplicationState());
|
|
|
+ cleanUpRegistry(serviceName);
|
|
|
return EXIT_COMMAND_ARGUMENT_ERROR;
|
|
|
}
|
|
|
if (preRunningStates.contains(report.getYarnApplicationState())) {
|
|
@@ -419,6 +431,7 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
+ ", forcefully killed by user!";
|
|
|
yarnClient.killApplication(currentAppId, msg);
|
|
|
LOG.info(msg);
|
|
|
+ cleanUpRegistry(serviceName);
|
|
|
return EXIT_SUCCESS;
|
|
|
}
|
|
|
if (StringUtils.isEmpty(report.getHost())) {
|
|
@@ -438,10 +451,12 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
yarnClient.killApplication(currentAppId,
|
|
|
serviceName + " is forcefully killed by user!");
|
|
|
LOG.info("Forcefully kill the service: " + serviceName);
|
|
|
+ cleanUpRegistry(serviceName);
|
|
|
return EXIT_SUCCESS;
|
|
|
}
|
|
|
|
|
|
if (!waitForAppStopped) {
|
|
|
+ cleanUpRegistry(serviceName);
|
|
|
return EXIT_SUCCESS;
|
|
|
}
|
|
|
// Wait until the app is killed.
|
|
@@ -471,6 +486,7 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
+ e.getMessage() + ", forcefully kill the app.");
|
|
|
yarnClient.killApplication(currentAppId, "Forcefully kill the app");
|
|
|
}
|
|
|
+ cleanUpRegistry(serviceName);
|
|
|
return EXIT_SUCCESS;
|
|
|
}
|
|
|
|
|
@@ -484,7 +500,7 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
FileSystem fileSystem = fs.getFileSystem();
|
|
|
// remove from the appId cache
|
|
|
cachedAppInfo.remove(serviceName);
|
|
|
- boolean destroySucceed = true;
|
|
|
+ int ret = EXIT_SUCCESS;
|
|
|
if (fileSystem.exists(appDir)) {
|
|
|
if (fileSystem.delete(appDir, true)) {
|
|
|
LOG.info("Successfully deleted service dir for " + serviceName + ": "
|
|
@@ -498,13 +514,34 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
} else {
|
|
|
LOG.info("Service '" + serviceName + "' doesn't exist at hdfs path: "
|
|
|
+ appDir);
|
|
|
- destroySucceed = false;
|
|
|
+ ret = EXIT_NOT_FOUND;
|
|
|
}
|
|
|
try {
|
|
|
deleteZKNode(serviceName);
|
|
|
+ // don't set destroySucceed to false if no ZK node exists because not
|
|
|
+ // all services use a ZK node
|
|
|
} catch (Exception e) {
|
|
|
throw new IOException("Could not delete zk node for " + serviceName, e);
|
|
|
}
|
|
|
+ if (!cleanUpRegistry(serviceName)) {
|
|
|
+ if (ret == EXIT_SUCCESS) {
|
|
|
+ ret = EXIT_OTHER_FAILURE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (ret == EXIT_SUCCESS) {
|
|
|
+ LOG.info("Successfully destroyed service {}", serviceName);
|
|
|
+ return ret;
|
|
|
+ } else if (ret == EXIT_NOT_FOUND) {
|
|
|
+ LOG.error("Error on destroy '" + serviceName + "': not found.");
|
|
|
+ return ret;
|
|
|
+ } else {
|
|
|
+ LOG.error("Error on destroy '" + serviceName + "': error cleaning up " +
|
|
|
+ "registry.");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean cleanUpRegistry(String serviceName) throws SliderException {
|
|
|
String registryPath =
|
|
|
ServiceRegistryUtils.registryPathForInstance(serviceName);
|
|
|
try {
|
|
@@ -514,18 +551,13 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
LOG.info(
|
|
|
"Service '" + serviceName + "' doesn't exist at ZK registry path: "
|
|
|
+ registryPath);
|
|
|
- destroySucceed = false;
|
|
|
+ // not counted as a failure if the registry entries don't exist
|
|
|
}
|
|
|
} catch (IOException e) {
|
|
|
LOG.warn("Error deleting registry entry {}", registryPath, e);
|
|
|
+ return false;
|
|
|
}
|
|
|
- if (destroySucceed) {
|
|
|
- LOG.info("Successfully destroyed service {}", serviceName);
|
|
|
- return EXIT_SUCCESS;
|
|
|
- } else {
|
|
|
- LOG.error("Error on destroy '" + serviceName + "': not found.");
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
private synchronized RegistryOperations getRegistryClient()
|
|
@@ -540,17 +572,25 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
return registryClient;
|
|
|
}
|
|
|
|
|
|
- private boolean deleteZKNode(String clusterName) throws Exception {
|
|
|
+ /**
|
|
|
+ * Delete service's ZK node. This is a different node from the service's
|
|
|
+ * registry entry and is set aside for the service to use for its own ZK data.
|
|
|
+ *
|
|
|
+ * @param serviceName service name
|
|
|
+ * @return true if the node was deleted, false if the node doesn't exist
|
|
|
+ * @throws Exception if the node couldn't be deleted
|
|
|
+ */
|
|
|
+ private boolean deleteZKNode(String serviceName) throws Exception {
|
|
|
CuratorFramework curatorFramework = getCuratorClient();
|
|
|
String user = RegistryUtils.currentUser();
|
|
|
- String zkPath = ServiceRegistryUtils.mkServiceHomePath(user, clusterName);
|
|
|
+ String zkPath = ServiceRegistryUtils.mkServiceHomePath(user, serviceName);
|
|
|
if (curatorFramework.checkExists().forPath(zkPath) != null) {
|
|
|
curatorFramework.delete().deletingChildrenIfNeeded().forPath(zkPath);
|
|
|
LOG.info("Deleted zookeeper path: " + zkPath);
|
|
|
return true;
|
|
|
} else {
|
|
|
LOG.info(
|
|
|
- "Service '" + clusterName + "' doesn't exist at ZK path: " + zkPath);
|
|
|
+ "Service '" + serviceName + "' doesn't exist at ZK path: " + zkPath);
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
@@ -963,6 +1003,9 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
public String updateLifetime(String serviceName, long lifetime)
|
|
|
throws YarnException, IOException {
|
|
|
ApplicationId currentAppId = getAppId(serviceName);
|
|
|
+ if (currentAppId == null) {
|
|
|
+ throw new YarnException("Application ID not found for " + serviceName);
|
|
|
+ }
|
|
|
ApplicationReport report = yarnClient.getApplicationReport(currentAppId);
|
|
|
if (report == null) {
|
|
|
throw new YarnException("Service not found for " + serviceName);
|
|
@@ -1008,8 +1051,8 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
throws IOException, YarnException {
|
|
|
try {
|
|
|
// try parsing appIdOrName, if it succeeds, it means it's appId
|
|
|
- ApplicationId.fromString(appIdOrName);
|
|
|
- return getStatusByAppId(appIdOrName);
|
|
|
+ ApplicationId appId = ApplicationId.fromString(appIdOrName);
|
|
|
+ return getStatusByAppId(appId);
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
// not appId format, it could be appName.
|
|
|
Service status = getStatus(appIdOrName);
|
|
@@ -1017,10 +1060,10 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private String getStatusByAppId(String appId)
|
|
|
+ private String getStatusByAppId(ApplicationId appId)
|
|
|
throws IOException, YarnException {
|
|
|
ApplicationReport appReport =
|
|
|
- yarnClient.getApplicationReport(ApplicationId.fromString(appId));
|
|
|
+ yarnClient.getApplicationReport(appId);
|
|
|
|
|
|
if (appReport.getYarnApplicationState() != RUNNING) {
|
|
|
return "";
|
|
@@ -1037,10 +1080,14 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
public Service getStatus(String serviceName)
|
|
|
throws IOException, YarnException {
|
|
|
ServiceApiUtil.validateNameFormat(serviceName, getConfig());
|
|
|
- ApplicationId currentAppId = getAppId(serviceName);
|
|
|
- ApplicationReport appReport = yarnClient.getApplicationReport(currentAppId);
|
|
|
Service appSpec = new Service();
|
|
|
appSpec.setName(serviceName);
|
|
|
+ ApplicationId currentAppId = getAppId(serviceName);
|
|
|
+ if (currentAppId == null) {
|
|
|
+ LOG.info("Service {} does not have an application ID", serviceName);
|
|
|
+ return appSpec;
|
|
|
+ }
|
|
|
+ ApplicationReport appReport = yarnClient.getApplicationReport(currentAppId);
|
|
|
appSpec.setState(convertState(appReport.getYarnApplicationState()));
|
|
|
ApplicationTimeout lifetime =
|
|
|
appReport.getApplicationTimeouts().get(ApplicationTimeoutType.LIFETIME);
|
|
@@ -1167,7 +1214,11 @@ public class ServiceClient extends AppAdminClient implements SliderExitCodes,
|
|
|
throw new YarnException("Service " + serviceName
|
|
|
+ " doesn't exist on hdfs. Please check if the app exists in RM");
|
|
|
}
|
|
|
- ApplicationId currentAppId = ApplicationId.fromString(persistedService.getId());
|
|
|
+ if (persistedService.getId() == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ ApplicationId currentAppId = ApplicationId.fromString(persistedService
|
|
|
+ .getId());
|
|
|
cachedAppInfo.put(serviceName, new AppInfo(currentAppId, persistedService
|
|
|
.getKerberosPrincipal().getPrincipalName()));
|
|
|
return currentAppId;
|