YARN-7955. Improve result of calling stop on an already stopped service. Contributed by Gour Saha

This commit is contained in:
Billie Rinaldi 2018-02-28 15:01:56 -08:00
parent 81d9446a92
commit 315f48e791
4 changed files with 79 additions and 63 deletions

View File

@ -59,7 +59,7 @@
import static org.apache.hadoop.yarn.service.api.records.ServiceState.ACCEPTED; import static org.apache.hadoop.yarn.service.api.records.ServiceState.ACCEPTED;
import static org.apache.hadoop.yarn.service.conf.RestApiConstants.*; import static org.apache.hadoop.yarn.service.conf.RestApiConstants.*;
import static org.apache.hadoop.yarn.service.exceptions.LauncherExitCodes.EXIT_SUCCESS; import static org.apache.hadoop.yarn.service.exceptions.LauncherExitCodes.*;
/** /**
* The rest API endpoints for users to manage services on YARN. * The rest API endpoints for users to manage services on YARN.
@ -240,7 +240,7 @@ public Response deleteService(@Context HttpServletRequest request,
private Response stopService(String appName, boolean destroy, private Response stopService(String appName, boolean destroy,
final UserGroupInformation ugi) throws IOException, final UserGroupInformation ugi) throws IOException,
InterruptedException, YarnException, FileNotFoundException { InterruptedException, YarnException, FileNotFoundException {
ugi.doAs(new PrivilegedExceptionAction<Integer>() { int result = ugi.doAs(new PrivilegedExceptionAction<Integer>() {
@Override @Override
public Integer run() throws IOException, YarnException, public Integer run() throws IOException, YarnException,
FileNotFoundException { FileNotFoundException {
@ -249,11 +249,12 @@ public Integer run() throws IOException, YarnException,
sc.init(YARN_CONFIG); sc.init(YARN_CONFIG);
sc.start(); sc.start();
result = sc.actionStop(appName, destroy); result = sc.actionStop(appName, destroy);
if (result == EXIT_SUCCESS) {
LOG.info("Successfully stopped service {}", appName);
}
if (destroy) { if (destroy) {
result = sc.actionDestroy(appName); result = sc.actionDestroy(appName);
LOG.info("Successfully deleted service {}", appName); LOG.info("Successfully deleted service {}", appName);
} else {
LOG.info("Successfully stopped service {}", appName);
} }
sc.close(); sc.close();
return result; return result;
@ -264,8 +265,13 @@ public Integer run() throws IOException, YarnException,
serviceStatus.setDiagnostics("Successfully destroyed service " + serviceStatus.setDiagnostics("Successfully destroyed service " +
appName); appName);
} else { } else {
serviceStatus.setDiagnostics("Successfully stopped service " + if (result == EXIT_COMMAND_ARGUMENT_ERROR) {
appName); serviceStatus
.setDiagnostics("Service " + appName + " is already stopped");
return formatResponse(Status.BAD_REQUEST, serviceStatus);
} else {
serviceStatus.setDiagnostics("Successfully stopped service " + appName);
}
} }
return formatResponse(Status.OK, serviceStatus); return formatResponse(Status.OK, serviceStatus);
} }

View File

@ -88,6 +88,8 @@ public int actionStop(String serviceName, boolean waitForAppStopped)
} }
if (serviceName.equals("jenkins")) { if (serviceName.equals("jenkins")) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} else if (serviceName.equals("jenkins-second-stop")) {
return EXIT_COMMAND_ARGUMENT_ERROR;
} else { } else {
throw new ApplicationNotFoundException(""); throw new ApplicationNotFoundException("");
} }

View File

@ -69,15 +69,14 @@ public void testPathAnnotation() {
this.apiServer.getClass().isAnnotationPresent(Path.class)); this.apiServer.getClass().isAnnotationPresent(Path.class));
final Path path = this.apiServer.getClass() final Path path = this.apiServer.getClass()
.getAnnotation(Path.class); .getAnnotation(Path.class);
assertEquals("The path has /v1 annotation", path.value(), assertEquals("The path has /v1 annotation", "/v1", path.value());
"/v1");
} }
@Test @Test
public void testGetVersion() { public void testGetVersion() {
final Response actual = apiServer.getVersion(); final Response actual = apiServer.getVersion();
assertEquals("Version number is", actual.getStatus(), assertEquals("Version number is", Response.ok().build().getStatus(),
Response.ok().build().getStatus()); actual.getStatus());
} }
@Test @Test
@ -85,8 +84,9 @@ public void testBadCreateService() {
Service service = new Service(); Service service = new Service();
// Test for invalid argument // Test for invalid argument
final Response actual = apiServer.createService(request, service); final Response actual = apiServer.createService(request, service);
assertEquals("Create service is ", actual.getStatus(), assertEquals("Create service is ",
Response.status(Status.BAD_REQUEST).build().getStatus()); Response.status(Status.BAD_REQUEST).build().getStatus(),
actual.getStatus());
} }
@Test @Test
@ -109,52 +109,55 @@ public void testGoodCreateService() {
components.add(c); components.add(c);
service.setComponents(components); service.setComponents(components);
final Response actual = apiServer.createService(request, service); final Response actual = apiServer.createService(request, service);
assertEquals("Create service is ", actual.getStatus(), assertEquals("Create service is ",
Response.status(Status.ACCEPTED).build().getStatus()); Response.status(Status.ACCEPTED).build().getStatus(),
actual.getStatus());
} }
@Test @Test
public void testBadGetService() { public void testBadGetService() {
final Response actual = apiServer.getService(request, "no-jenkins"); final Response actual = apiServer.getService(request, "no-jenkins");
assertEquals("Get service is ", actual.getStatus(), assertEquals("Get service is ",
Response.status(Status.NOT_FOUND).build().getStatus()); Response.status(Status.NOT_FOUND).build().getStatus(),
actual.getStatus());
} }
@Test @Test
public void testBadGetService2() { public void testBadGetService2() {
final Response actual = apiServer.getService(request, null); final Response actual = apiServer.getService(request, null);
assertEquals("Get service is ", actual.getStatus(), assertEquals("Get service is ",
Response.status(Status.NOT_FOUND) Response.status(Status.NOT_FOUND).build().getStatus(),
.build().getStatus()); actual.getStatus());
} }
@Test @Test
public void testGoodGetService() { public void testGoodGetService() {
final Response actual = apiServer.getService(request, "jenkins"); final Response actual = apiServer.getService(request, "jenkins");
assertEquals("Get service is ", actual.getStatus(), assertEquals("Get service is ",
Response.status(Status.OK).build().getStatus()); Response.status(Status.OK).build().getStatus(), actual.getStatus());
} }
@Test @Test
public void testBadDeleteService() { public void testBadDeleteService() {
final Response actual = apiServer.deleteService(request, "no-jenkins"); final Response actual = apiServer.deleteService(request, "no-jenkins");
assertEquals("Delete service is ", actual.getStatus(), assertEquals("Delete service is ",
Response.status(Status.BAD_REQUEST).build().getStatus()); Response.status(Status.BAD_REQUEST).build().getStatus(),
actual.getStatus());
} }
@Test @Test
public void testBadDeleteService2() { public void testBadDeleteService2() {
final Response actual = apiServer.deleteService(request, null); final Response actual = apiServer.deleteService(request, null);
assertEquals("Delete service is ", actual.getStatus(), assertEquals("Delete service is ",
Response.status(Status.BAD_REQUEST) Response.status(Status.BAD_REQUEST).build().getStatus(),
.build().getStatus()); actual.getStatus());
} }
@Test @Test
public void testGoodDeleteService() { public void testGoodDeleteService() {
final Response actual = apiServer.deleteService(request, "jenkins"); final Response actual = apiServer.deleteService(request, "jenkins");
assertEquals("Delete service is ", actual.getStatus(), assertEquals("Delete service is ",
Response.status(Status.OK).build().getStatus()); Response.status(Status.OK).build().getStatus(), actual.getStatus());
} }
@Test @Test
@ -179,8 +182,8 @@ public void testDecreaseContainerAndStop() {
service.setComponents(components); service.setComponents(components);
final Response actual = apiServer.updateService(request, "jenkins", final Response actual = apiServer.updateService(request, "jenkins",
service); service);
assertEquals("update service is ", actual.getStatus(), assertEquals("update service is ",
Response.status(Status.OK).build().getStatus()); Response.status(Status.OK).build().getStatus(), actual.getStatus());
} }
@Test @Test
@ -206,8 +209,9 @@ public void testBadDecreaseContainerAndStop() {
System.out.println("before stop"); System.out.println("before stop");
final Response actual = apiServer.updateService(request, "no-jenkins", final Response actual = apiServer.updateService(request, "no-jenkins",
service); service);
assertEquals("flex service is ", actual.getStatus(), assertEquals("flex service is ",
Response.status(Status.BAD_REQUEST).build().getStatus()); Response.status(Status.BAD_REQUEST).build().getStatus(),
actual.getStatus());
} }
@Test @Test
@ -232,8 +236,8 @@ public void testIncreaseContainersAndStart() {
service.setComponents(components); service.setComponents(components);
final Response actual = apiServer.updateService(request, "jenkins", final Response actual = apiServer.updateService(request, "jenkins",
service); service);
assertEquals("flex service is ", actual.getStatus(), assertEquals("flex service is ",
Response.status(Status.OK).build().getStatus()); Response.status(Status.OK).build().getStatus(), actual.getStatus());
} }
@Test @Test
@ -258,9 +262,9 @@ public void testBadStartServices() {
service.setComponents(components); service.setComponents(components);
final Response actual = apiServer.updateService(request, "no-jenkins", final Response actual = apiServer.updateService(request, "no-jenkins",
service); service);
assertEquals("start service is ", actual.getStatus(), assertEquals("start service is ",
Response.status(Status.BAD_REQUEST).build() Response.status(Status.BAD_REQUEST).build().getStatus(),
.getStatus()); actual.getStatus());
} }
@Test @Test
@ -285,8 +289,8 @@ public void testGoodStartServices() {
service.setComponents(components); service.setComponents(components);
final Response actual = apiServer.updateService(request, "jenkins", final Response actual = apiServer.updateService(request, "jenkins",
service); service);
assertEquals("start service is ", actual.getStatus(), assertEquals("start service is ",
Response.status(Status.OK).build().getStatus()); Response.status(Status.OK).build().getStatus(), actual.getStatus());
} }
@Test @Test
@ -312,35 +316,39 @@ public void testBadStopServices() {
System.out.println("before stop"); System.out.println("before stop");
final Response actual = apiServer.updateService(request, "no-jenkins", final Response actual = apiServer.updateService(request, "no-jenkins",
service); service);
assertEquals("stop service is ", actual.getStatus(), assertEquals("stop service is ",
Response.status(Status.BAD_REQUEST).build().getStatus()); Response.status(Status.BAD_REQUEST).build().getStatus(),
actual.getStatus());
} }
@Test @Test
public void testGoodStopServices() { public void testGoodStopServices() {
Service service = new Service(); Service service = new Service();
service.setState(ServiceState.STARTED); service.setState(ServiceState.STOPPED);
service.setName("jenkins"); service.setName("jenkins");
Artifact artifact = new Artifact();
artifact.setType(TypeEnum.DOCKER);
artifact.setId("jenkins:latest");
Resource resource = new Resource();
resource.setCpus(1);
resource.setMemory("2048");
List<Component> components = new ArrayList<Component>();
Component c = new Component();
c.setName("jenkins");
c.setNumberOfContainers(-1L);
c.setArtifact(artifact);
c.setLaunchCommand("");
c.setResource(resource);
components.add(c);
service.setComponents(components);
System.out.println("before stop"); System.out.println("before stop");
final Response actual = apiServer.updateService(request, "jenkins", final Response actual = apiServer.updateService(request, "jenkins",
service); service);
assertEquals("stop service is ", actual.getStatus(), assertEquals("stop service is ",
Response.status(Status.OK).build().getStatus()); Response.status(Status.OK).build().getStatus(), actual.getStatus());
}
@Test
public void testBadSecondStopServices() throws Exception {
Service service = new Service();
service.setState(ServiceState.STOPPED);
service.setName("jenkins-second-stop");
// simulates stop on an already stopped service
System.out.println("before second stop");
final Response actual = apiServer.updateService(request,
"jenkins-second-stop", service);
assertEquals("stop service should have thrown 400 Bad Request: ",
Response.status(Status.BAD_REQUEST).build().getStatus(),
actual.getStatus());
ServiceStatus serviceStatus = (ServiceStatus) actual.getEntity();
assertEquals("Stop service should have failed with service already stopped",
"Service jenkins-second-stop is already stopped",
serviceStatus.getDiagnostics());
} }
@Test @Test
@ -366,9 +374,9 @@ public void testUpdateService() {
System.out.println("before stop"); System.out.println("before stop");
final Response actual = apiServer.updateService(request, "no-jenkins", final Response actual = apiServer.updateService(request, "no-jenkins",
service); service);
assertEquals("update service is ", actual.getStatus(), assertEquals("update service is ",
Response.status(Status.BAD_REQUEST) Response.status(Status.BAD_REQUEST)
.build().getStatus()); .build().getStatus(), actual.getStatus());
} }
@Test @Test

View File

@ -363,7 +363,7 @@ public int actionStop(String serviceName, boolean waitForAppStopped)
if (terminatedStates.contains(report.getYarnApplicationState())) { if (terminatedStates.contains(report.getYarnApplicationState())) {
LOG.info("Service {} is already in a terminated state {}", serviceName, LOG.info("Service {} is already in a terminated state {}", serviceName,
report.getYarnApplicationState()); report.getYarnApplicationState());
return EXIT_SUCCESS; return EXIT_COMMAND_ARGUMENT_ERROR;
} }
if (preRunningStates.contains(report.getYarnApplicationState())) { if (preRunningStates.contains(report.getYarnApplicationState())) {
String msg = serviceName + " is at " + report.getYarnApplicationState() String msg = serviceName + " is at " + report.getYarnApplicationState()
@ -779,7 +779,7 @@ public int actionStart(String serviceName) throws YarnException, IOException {
Service service = ServiceApiUtil.loadService(fs, serviceName); Service service = ServiceApiUtil.loadService(fs, serviceName);
ServiceApiUtil.validateAndResolveService(service, fs, getConfig()); ServiceApiUtil.validateAndResolveService(service, fs, getConfig());
// see if it is actually running and bail out; // see if it is actually running and bail out;
verifyNoLiveAppInRM(serviceName, "thaw"); verifyNoLiveAppInRM(serviceName, "start");
ApplicationId appId = submitApp(service); ApplicationId appId = submitApp(service);
service.setId(appId.toString()); service.setId(appId.toString());
// write app definition on to hdfs // write app definition on to hdfs