diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java index 60fbfcd..52cac3d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java @@ -19,6 +19,7 @@ package org.apache.hadoop.yarn.server.resourcemanager.webapp; import java.io.IOException; +import java.security.PrivilegedExceptionAction; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; @@ -31,19 +32,26 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authorize.AuthorizationException; import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest; +import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest; +import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationResponse; import org.apache.hadoop.yarn.api.records.ApplicationAccessType; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationReport; @@ -56,6 +64,8 @@ import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; +import org.apache.hadoop.yarn.server.resourcemanager.RMAuditLogger; +import org.apache.hadoop.yarn.server.resourcemanager.RMAuditLogger.AuditConstants; import org.apache.hadoop.yarn.server.resourcemanager.RMServerUtils; import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; @@ -590,4 +600,153 @@ public AppAttemptsInfo getAppAttempts(@PathParam("appid") String appId) { return appAttemptsInfo; } + + // can't return POJO because we can't control the status code + // it's always set to 200 when we need to allow it to be set + // to 202 + + @PUT + @Path("/apps/{appid}") + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public Response updateApp(AppInfo appInfo, @Context HttpServletRequest hsr, + @PathParam("appid") String appId) throws AuthorizationException, + YarnException, InterruptedException, IOException { + + init(); + UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr); + if(callerUGI == null) { + String msg = "Unable to obtain user name, user not authenticated"; + throw new AuthorizationException(msg); + } + + String userName = callerUGI.getUserName(); + RMApp app = null; + try { + app = getRMAppForAppId(appId); + } + catch(NotFoundException e) { + RMAuditLogger.logFailure(userName, + AuditConstants.KILL_APP_REQUEST, "UNKNOWN", "RMWebService", + "Trying to kill/move an absent application " + appId); + throw e; + } + + if(!app.getState().toString().equals(appInfo.getState())) { + // user is attempting to change state. right we only + // allow users to kill the app + if(appInfo.getState().equals(YarnApplicationState.KILLED.toString())) { + return killApp(app, callerUGI, hsr); + } + throw new BadRequestException("Only '" + + YarnApplicationState.KILLED.toString() + + "' is allowed as a target state."); + } + + AppInfo ret = new AppInfo( + app, hasAccess(app, hsr), hsr.getScheme() + "://"); + return Response.status(Status.OK).entity(ret).build(); + } + + protected Response killApp(RMApp app, UserGroupInformation callerUGI, + HttpServletRequest hsr) throws IOException, InterruptedException { + + if(app == null) { + throw new IllegalArgumentException("app cannot be null"); + } + String userName = callerUGI.getUserName(); + if(app != null && + !hasAppAcess(app, callerUGI, ApplicationAccessType.MODIFY_APP)) { + String appId = app.getApplicationId().toString(); + String msg = "Unauthorized attempt to kill appid " + + appId + "by remote user " + userName; + RMAuditLogger.logFailure(userName, AuditConstants.KILL_APP_REQUEST, + "UNKNOWN", "RMWebService", + "Unauthorized attempt to kill appid " + appId); + return Response.status(Status.FORBIDDEN).entity(msg).build(); + } + + final ApplicationId appid = app.getApplicationId(); + KillApplicationResponse resp = callerUGI.doAs( + new PrivilegedExceptionAction() { + @Override + public KillApplicationResponse run() throws IOException, YarnException { + KillApplicationRequest req = + KillApplicationRequest.newInstance(appid); + return rm.getClientRMService().forceKillApplication(req); + } + }); + + AppInfo ret = new AppInfo( + app, hasAppAcess(app, callerUGI, ApplicationAccessType.MODIFY_APP), + hsr.getScheme() + "://"); + + if (resp.getIsKillCompleted()) { + RMAuditLogger.logSuccess(userName, AuditConstants.KILL_APP_REQUEST, + "RMWebService", app.getApplicationId()); + } else { + return Response.status(Status.ACCEPTED) + .entity(ret) + .header("Location", hsr.getRequestURL().toString()).build(); + } + + return Response.status(Status.OK).entity(ret).build(); + } + + private RMApp getRMAppForAppId(String appId) { + + if(appId == null || appId.isEmpty()) { + throw new NotFoundException("appId, " + appId + ", is empty or null"); + } + ApplicationId id; + try { + id = ConverterUtils.toApplicationId(recordFactory, appId); + } + catch(NumberFormatException e) { + throw new NotFoundException("appId is invalid"); + } + if(id == null) { + throw new NotFoundException("appId is invalid"); + } + RMApp app = rm.getRMContext().getRMApps().get(id); + if(app == null) { + throw new NotFoundException("app with id: " + appId + " not found"); + } + return app; + } + + private UserGroupInformation + getCallerUserGroupInformation(HttpServletRequest hsr) { + + String remoteUser = hsr.getRemoteUser(); + UserGroupInformation callerUGI = null; + if (remoteUser != null) { + callerUGI = UserGroupInformation.createRemoteUser(remoteUser); + } + + return callerUGI; + } + + protected Boolean hasAppAcess(RMApp app, + UserGroupInformation callerUGI, ApplicationAccessType type) { + if (callerUGI != null) { + if(!this.aclsManager.checkAccess(callerUGI, type, + app.getUser(), app.getApplicationId())) { + return false; + } + } + return true; + } + + protected Boolean hasQueueAcess(RMApp app, + UserGroupInformation callerUGI, QueueACL type) { + if (callerUGI != null) { + if(!this.queueACLsManager.checkAccess(callerUGI, type, + app.getQueue())) { + return false; + } + } + return true; + } + } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/AppInfo.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/AppInfo.java index 6cb6114..849bdfd 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/AppInfo.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/AppInfo.java @@ -256,5 +256,113 @@ public int getAllocatedMB() { public int getAllocatedVCores() { return this.allocatedVCores; } + + public void setAppIdNum(String appIdNum) { + this.appIdNum = appIdNum; + } + + public void setTrackingUrlIsNotReady(boolean trackingUrlIsNotReady) { + this.trackingUrlIsNotReady = trackingUrlIsNotReady; + } + + public void setTrackingUrlPretty(String trackingUrlPretty) { + this.trackingUrlPretty = trackingUrlPretty; + } + + public void setAmContainerLogsExist(boolean amContainerLogsExist) { + this.amContainerLogsExist = amContainerLogsExist; + } + + public void setApplicationId(ApplicationId applicationId) { + this.applicationId = applicationId; + } + + public void setSchemePrefix(String schemePrefix) { + this.schemePrefix = schemePrefix; + } + + public void setId(String id) { + this.id = id; + } + + public void setUser(String user) { + this.user = user; + } + + public void setName(String name) { + this.name = name; + } + + public void setQueue(String queue) { + this.queue = queue; + } + + public void setState(YarnApplicationState state) { + this.state = state; + } + + public void setFinalStatus(FinalApplicationStatus finalStatus) { + this.finalStatus = finalStatus; + } + + public void setProgress(float progress) { + this.progress = progress; + } + + public void setTrackingUI(String trackingUI) { + this.trackingUI = trackingUI; + } + + public void setTrackingUrl(String trackingUrl) { + this.trackingUrl = trackingUrl; + } + + public void setDiagnostics(String diagnostics) { + this.diagnostics = diagnostics; + } + + public void setClusterId(long clusterId) { + this.clusterId = clusterId; + } + + public void setApplicationType(String applicationType) { + this.applicationType = applicationType; + } + + public void setApplicationTags(String applicationTags) { + this.applicationTags = applicationTags; + } + + public void setStartedTime(long startedTime) { + this.startedTime = startedTime; + } + + public void setFinishedTime(long finishedTime) { + this.finishedTime = finishedTime; + } + + public void setElapsedTime(long elapsedTime) { + this.elapsedTime = elapsedTime; + } + + public void setAmContainerLogs(String amContainerLogs) { + this.amContainerLogs = amContainerLogs; + } + + public void setAmHostHttpAddress(String amHostHttpAddress) { + this.amHostHttpAddress = amHostHttpAddress; + } + + public void setAllocatedMB(int allocatedMB) { + this.allocatedMB = allocatedMB; + } + + public void setAllocatedVCores(int allocatedVCores) { + this.allocatedVCores = allocatedVCores; + } + + public void setRunningContainers(int runningContainers) { + this.runningContainers = runningContainers; + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMCustomAuthFilter.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMCustomAuthFilter.java new file mode 100644 index 0000000..d0a0404 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMCustomAuthFilter.java @@ -0,0 +1,57 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.yarn.server.resourcemanager.webapp; + +import java.util.Enumeration; +import java.util.Properties; + +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; + +import org.apache.hadoop.security.authentication.server.AuthenticationFilter; +import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHandler; + +import com.google.inject.Singleton; + +/* + * Helper class to allow testing of RM web services which require authorization + * Add this class as a filter in the Guice injector for the MockRM + * + */ + +@Singleton +public class TestRMCustomAuthFilter extends AuthenticationFilter { + + @Override + protected Properties getConfiguration(String configPrefix, FilterConfig filterConfig) throws ServletException { + Properties props = new Properties(); + Enumeration names = filterConfig.getInitParameterNames(); + while (names.hasMoreElements()) { + String name = (String) names.nextElement(); + if (name.startsWith(configPrefix)) { + String value = filterConfig.getInitParameter(name); + props.put(name.substring(configPrefix.length()), value); + } + } + props.put(AuthenticationFilter.AUTH_TYPE, "simple"); + props.put(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, "false"); + return props; + } + +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java index 45b3803..b5cc77c 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java @@ -22,12 +22,18 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.IOException; import java.io.StringReader; +import java.io.StringWriter; +import java.util.Arrays; import java.util.Collection; import javax.ws.rs.core.MediaType; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.UserGroupInformation; @@ -47,58 +53,51 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler; import org.apache.hadoop.yarn.server.resourcemanager.security.QueueACLsManager; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo; import org.apache.hadoop.yarn.server.security.ApplicationACLsManager; import org.apache.hadoop.yarn.webapp.GenericExceptionHandler; import org.apache.hadoop.yarn.webapp.WebServicesTestUtils; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; +import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; +import org.xml.sax.SAXException; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.servlet.GuiceServletContextListener; import com.google.inject.servlet.ServletModule; +import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse.Status; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.WebResource.Builder; +import com.sun.jersey.api.json.JSONJAXBContext; +import com.sun.jersey.api.json.JSONMarshaller; import com.sun.jersey.core.util.MultivaluedMapImpl; import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; import com.sun.jersey.test.framework.JerseyTest; import com.sun.jersey.test.framework.WebAppDescriptor; +@RunWith(Parameterized.class) public class TestRMWebServicesApps extends JerseyTest { private static MockRM rm; - + private static final int CONTAINER_MB = 1024; - private Injector injector = Guice.createInjector(new ServletModule() { - @Override - protected void configureServlets() { - bind(JAXBContextResolver.class); - bind(RMWebServices.class); - bind(GenericExceptionHandler.class); - Configuration conf = new Configuration(); - conf.setInt(YarnConfiguration.RM_AM_MAX_ATTEMPTS, - YarnConfiguration.DEFAULT_RM_AM_MAX_ATTEMPTS); - conf.setClass(YarnConfiguration.RM_SCHEDULER, FifoScheduler.class, - ResourceScheduler.class); - rm = new MockRM(conf); - bind(ResourceManager.class).toInstance(rm); - bind(RMContext.class).toInstance(rm.getRMContext()); - bind(ApplicationACLsManager.class).toInstance( - rm.getApplicationACLsManager()); - bind(QueueACLsManager.class).toInstance(rm.getQueueACLsManager()); - serve("/*").with(GuiceContainer.class); - } - }); + private Injector injector; + private String webserviceUserName = "testuser"; public class GuiceServletConfig extends GuiceServletContextListener { @@ -108,18 +107,82 @@ protected Injector getInjector() { } } + private Injector getNoAuthInjector() { + return Guice.createInjector(new ServletModule() { + @Override + protected void configureServlets() { + bind(JAXBContextResolver.class); + bind(RMWebServices.class); + bind(GenericExceptionHandler.class); + Configuration conf = new Configuration(); + conf.setInt(YarnConfiguration.RM_AM_MAX_ATTEMPTS, + YarnConfiguration.DEFAULT_RM_AM_MAX_ATTEMPTS); + conf.setClass(YarnConfiguration.RM_SCHEDULER, FifoScheduler.class, + ResourceScheduler.class); + rm = new MockRM(conf); + bind(ResourceManager.class).toInstance(rm); + bind(RMContext.class).toInstance(rm.getRMContext()); + bind(ApplicationACLsManager.class).toInstance( + rm.getApplicationACLsManager()); + bind(QueueACLsManager.class).toInstance(rm.getQueueACLsManager()); + serve("/*").with(GuiceContainer.class); + } + }); + } + + private Injector getSimpleAuthInjector() { + return Guice.createInjector(new ServletModule() { + @Override + protected void configureServlets() { + bind(JAXBContextResolver.class); + bind(RMWebServices.class); + bind(GenericExceptionHandler.class); + Configuration conf = new Configuration(); + conf.setInt(YarnConfiguration.RM_AM_MAX_ATTEMPTS, + YarnConfiguration.DEFAULT_RM_AM_MAX_ATTEMPTS); + conf.setClass(YarnConfiguration.RM_SCHEDULER, FifoScheduler.class, + ResourceScheduler.class); + conf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, true); + // set the admin acls otherwise all users are considered admins + // and we can't test authorization + conf.setStrings(YarnConfiguration.YARN_ADMIN_ACL, "testuser1"); + rm = new MockRM(conf); + bind(ResourceManager.class).toInstance(rm); + bind(RMContext.class).toInstance(rm.getRMContext()); + bind(ApplicationACLsManager.class).toInstance( + rm.getApplicationACLsManager()); + bind(QueueACLsManager.class).toInstance(rm.getQueueACLsManager()); + filter("/*").through(TestRMCustomAuthFilter.class); + serve("/*").with(GuiceContainer.class); + } + }); + } + + @Parameters + public static Collection guiceConfigs() { + return Arrays.asList(new Object[][] { { 0 }, { 1 } }); + } + @Before @Override public void setUp() throws Exception { super.setUp(); } - public TestRMWebServicesApps() { + public TestRMWebServicesApps(int run) { super(new WebAppDescriptor.Builder( - "org.apache.hadoop.yarn.server.resourcemanager.webapp") - .contextListenerClass(GuiceServletConfig.class) - .filterClass(com.google.inject.servlet.GuiceFilter.class) - .contextPath("jersey-guice-filter").servletPath("/").build()); + "org.apache.hadoop.yarn.server.resourcemanager.webapp") + .contextListenerClass(GuiceServletConfig.class) + .filterClass(com.google.inject.servlet.GuiceFilter.class) + .contextPath("jersey-guice-filter").servletPath("/").build()); + switch (run) { + case 0: + injector = getNoAuthInjector(); + break; + case 1: + injector = getSimpleAuthInjector(); + break; + } } @Test @@ -158,10 +221,11 @@ public void testAppsXML() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); RMApp app1 = rm.submitApp(CONTAINER_MB, "testwordcount", "user1"); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").accept(MediaType.APPLICATION_XML) - .get(ClientResponse.class); + + ClientResponse response = + this.constructWebResource("apps").accept(MediaType.APPLICATION_XML) + .get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType()); String xml = response.getEntity(String.class); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); @@ -185,11 +249,9 @@ public void testAppsXMLMulti() throws JSONException, Exception { rm.submitApp(2048, "testwordcount2", "user1"); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").accept(MediaType.APPLICATION_XML) - .get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps").accept(MediaType.APPLICATION_XML) + .get(ClientResponse.class); assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType()); String xml = response.getEntity(String.class); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); @@ -206,10 +268,9 @@ public void testAppsXMLMulti() throws JSONException, Exception { public void testAppsHelper(String path, RMApp app, String media) throws JSONException, Exception { - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path(path).accept(media).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource(path).accept(media).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -227,12 +288,11 @@ public void testAppsQueryState() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); RMApp app1 = rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps") - .queryParam("state", YarnApplicationState.ACCEPTED.toString()) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("state", YarnApplicationState.ACCEPTED.toString()) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -254,12 +314,11 @@ public void testAppsQueryStates() throws JSONException, Exception { amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); MultivaluedMapImpl params = new MultivaluedMapImpl(); params.add("states", YarnApplicationState.ACCEPTED.toString()); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParams(params) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps").queryParams(params) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -268,15 +327,14 @@ public void testAppsQueryStates() throws JSONException, Exception { JSONArray array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 1, array.length()); assertEquals("state not equal to ACCEPTED", "ACCEPTED", array - .getJSONObject(0).getString("state")); + .getJSONObject(0).getString("state")); - r = resource(); params = new MultivaluedMapImpl(); params.add("states", YarnApplicationState.ACCEPTED.toString()); params.add("states", YarnApplicationState.KILLED.toString()); - response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParams(params) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + response = + this.constructWebResource("apps").queryParams(params) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -284,11 +342,11 @@ public void testAppsQueryStates() throws JSONException, Exception { assertEquals("incorrect number of elements", 1, apps.length()); array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 2, array.length()); - assertTrue("both app states of ACCEPTED and KILLED are not present", - (array.getJSONObject(0).getString("state").equals("ACCEPTED") && - array.getJSONObject(1).getString("state").equals("KILLED")) || - (array.getJSONObject(0).getString("state").equals("KILLED") && - array.getJSONObject(1).getString("state").equals("ACCEPTED"))); + assertTrue("both app states of ACCEPTED and KILLED are not present", (array + .getJSONObject(0).getString("state").equals("ACCEPTED") && array + .getJSONObject(1).getString("state").equals("KILLED")) + || (array.getJSONObject(0).getString("state").equals("KILLED") && array + .getJSONObject(1).getString("state").equals("ACCEPTED"))); rm.stop(); } @@ -303,12 +361,11 @@ public void testAppsQueryStatesComma() throws JSONException, Exception { amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); MultivaluedMapImpl params = new MultivaluedMapImpl(); params.add("states", YarnApplicationState.ACCEPTED.toString()); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParams(params) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps").queryParams(params) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -317,15 +374,14 @@ public void testAppsQueryStatesComma() throws JSONException, Exception { JSONArray array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 1, array.length()); assertEquals("state not equal to ACCEPTED", "ACCEPTED", array - .getJSONObject(0).getString("state")); + .getJSONObject(0).getString("state")); - r = resource(); params = new MultivaluedMapImpl(); params.add("states", YarnApplicationState.ACCEPTED.toString() + "," + YarnApplicationState.KILLED.toString()); - response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParams(params) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + response = + this.constructWebResource("apps").queryParams(params) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -333,12 +389,12 @@ public void testAppsQueryStatesComma() throws JSONException, Exception { assertEquals("incorrect number of elements", 1, apps.length()); array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 2, array.length()); - assertTrue("both app states of ACCEPTED and KILLED are not present", - (array.getJSONObject(0).getString("state").equals("ACCEPTED") && - array.getJSONObject(1).getString("state").equals("KILLED")) || - (array.getJSONObject(0).getString("state").equals("KILLED") && - array.getJSONObject(1).getString("state").equals("ACCEPTED"))); - + assertTrue("both app states of ACCEPTED and KILLED are not present", (array + .getJSONObject(0).getString("state").equals("ACCEPTED") && array + .getJSONObject(1).getString("state").equals("KILLED")) + || (array.getJSONObject(0).getString("state").equals("KILLED") && array + .getJSONObject(1).getString("state").equals("ACCEPTED"))); + rm.stop(); } @@ -348,12 +404,10 @@ public void testAppsQueryStatesNone() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps") - .queryParam("states", YarnApplicationState.RUNNING.toString()) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("states", YarnApplicationState.RUNNING.toString()) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -367,12 +421,12 @@ public void testAppsQueryStateNone() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps") - .queryParam("state", YarnApplicationState.RUNNING.toString()) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("state", YarnApplicationState.RUNNING.toString()) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -386,12 +440,10 @@ public void testAppsQueryStatesInvalid() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); try { - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("states", "INVALID_test") - .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); + this.constructWebResource("apps").queryParam("states", "INVALID_test") + .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); fail("should have thrown exception on invalid state query"); } catch (UniformInterfaceException ue) { ClientResponse response = ue.getResponse(); @@ -403,14 +455,12 @@ public void testAppsQueryStatesInvalid() throws JSONException, Exception { String message = exception.getString("message"); String type = exception.getString("exception"); String classname = exception.getString("javaClassName"); - WebServicesTestUtils.checkStringContains( - "exception message", - "Invalid application-state INVALID_test", - message); + WebServicesTestUtils.checkStringContains("exception message", + "Invalid application-state INVALID_test", message); WebServicesTestUtils.checkStringMatch("exception type", - "BadRequestException", type); + "BadRequestException", type); WebServicesTestUtils.checkStringMatch("exception classname", - "org.apache.hadoop.yarn.webapp.BadRequestException", classname); + "org.apache.hadoop.yarn.webapp.BadRequestException", classname); } finally { rm.stop(); @@ -423,12 +473,10 @@ public void testAppsQueryStateInvalid() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); try { - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("state", "INVALID_test") - .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); + this.constructWebResource("apps").queryParam("state", "INVALID_test") + .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); fail("should have thrown exception on invalid state query"); } catch (UniformInterfaceException ue) { ClientResponse response = ue.getResponse(); @@ -440,14 +488,12 @@ public void testAppsQueryStateInvalid() throws JSONException, Exception { String message = exception.getString("message"); String type = exception.getString("exception"); String classname = exception.getString("javaClassName"); - WebServicesTestUtils.checkStringContains( - "exception message", - "Invalid application-state INVALID_test", - message); + WebServicesTestUtils.checkStringContains("exception message", + "Invalid application-state INVALID_test", message); WebServicesTestUtils.checkStringMatch("exception type", - "BadRequestException", type); + "BadRequestException", type); WebServicesTestUtils.checkStringMatch("exception classname", - "org.apache.hadoop.yarn.webapp.BadRequestException", classname); + "org.apache.hadoop.yarn.webapp.BadRequestException", classname); } finally { rm.stop(); @@ -460,11 +506,12 @@ public void testAppsQueryFinalStatus() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); RMApp app1 = rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("finalStatus", FinalApplicationStatus.UNDEFINED.toString()) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this + .constructWebResource("apps") + .queryParam("finalStatus", + FinalApplicationStatus.UNDEFINED.toString()) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -483,11 +530,10 @@ public void testAppsQueryFinalStatusNone() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("finalStatus", FinalApplicationStatus.KILLED.toString()) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("finalStatus", FinalApplicationStatus.KILLED.toString()) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -501,12 +547,11 @@ public void testAppsQueryFinalStatusInvalid() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); try { - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("finalStatus", "INVALID_test") - .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); + this.constructWebResource("apps") + .queryParam("finalStatus", "INVALID_test") + .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); fail("should have thrown exception on invalid state query"); } catch (UniformInterfaceException ue) { ClientResponse response = ue.getResponse(); @@ -519,14 +564,14 @@ public void testAppsQueryFinalStatusInvalid() throws JSONException, Exception { String type = exception.getString("exception"); String classname = exception.getString("javaClassName"); WebServicesTestUtils - .checkStringContains( - "exception message", - "org.apache.hadoop.yarn.api.records.FinalApplicationStatus.INVALID_test", - message); + .checkStringContains( + "exception message", + "org.apache.hadoop.yarn.api.records.FinalApplicationStatus.INVALID_test", + message); WebServicesTestUtils.checkStringMatch("exception type", - "IllegalArgumentException", type); + "IllegalArgumentException", type); WebServicesTestUtils.checkStringMatch("exception classname", - "java.lang.IllegalArgumentException", classname); + "java.lang.IllegalArgumentException", classname); } finally { rm.stop(); @@ -541,15 +586,13 @@ public void testAppsQueryUser() throws JSONException, Exception { rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - ClientResponse response = r - .path("ws") - .path("v1") - .path("cluster") - .path("apps") - .queryParam("user", + + ClientResponse response = + this + .constructWebResource("apps") + .queryParam("user", UserGroupInformation.getCurrentUser().getShortUserName()) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); @@ -569,11 +612,9 @@ public void testAppsQueryQueue() throws JSONException, Exception { rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("queue", "default") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps").queryParam("queue", "default") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -591,10 +632,9 @@ public void testAppsQueryLimit() throws JSONException, Exception { rm.submitApp(CONTAINER_MB); rm.submitApp(CONTAINER_MB); rm.submitApp(CONTAINER_MB); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("limit", "2") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps").queryParam("limit", "2") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -614,10 +654,10 @@ public void testAppsQueryStartBegin() throws JSONException, Exception { rm.submitApp(CONTAINER_MB); rm.submitApp(CONTAINER_MB); rm.submitApp(CONTAINER_MB); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("startedTimeBegin", String.valueOf(start)) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("startedTimeBegin", String.valueOf(start)) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -637,10 +677,10 @@ public void testAppsQueryStartBeginSome() throws JSONException, Exception { long start = System.currentTimeMillis(); Thread.sleep(1); rm.submitApp(CONTAINER_MB); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("startedTimeBegin", String.valueOf(start)) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("startedTimeBegin", String.valueOf(start)) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -660,10 +700,10 @@ public void testAppsQueryStartEnd() throws JSONException, Exception { rm.submitApp(CONTAINER_MB); rm.submitApp(CONTAINER_MB); rm.submitApp(CONTAINER_MB); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("startedTimeEnd", String.valueOf(end)) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("startedTimeEnd", String.valueOf(end)) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -682,11 +722,11 @@ public void testAppsQueryStartBeginEnd() throws JSONException, Exception { long end = System.currentTimeMillis(); Thread.sleep(1); rm.submitApp(CONTAINER_MB); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("startedTimeBegin", String.valueOf(start)) - .queryParam("startedTimeEnd", String.valueOf(end)) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("startedTimeBegin", String.valueOf(start)) + .queryParam("startedTimeEnd", String.valueOf(end)) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -706,19 +746,18 @@ public void testAppsQueryFinishBegin() throws JSONException, Exception { RMApp app1 = rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); // finish App - MockAM am = rm - .sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); + MockAM am = + rm.sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); am.registerAppAttempt(); am.unregisterAppAttempt(); amNodeManager.nodeHeartbeat(app1.getCurrentAppAttempt().getAppAttemptId(), - 1, ContainerState.COMPLETE); + 1, ContainerState.COMPLETE); rm.submitApp(CONTAINER_MB); rm.submitApp(CONTAINER_MB); - - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("finishedTimeBegin", String.valueOf(start)) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("finishedTimeBegin", String.valueOf(start)) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -736,21 +775,21 @@ public void testAppsQueryFinishEnd() throws JSONException, Exception { RMApp app1 = rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); // finish App - MockAM am = rm - .sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); + MockAM am = + rm.sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); am.registerAppAttempt(); am.unregisterAppAttempt(); amNodeManager.nodeHeartbeat(app1.getCurrentAppAttempt().getAppAttemptId(), - 1, ContainerState.COMPLETE); + 1, ContainerState.COMPLETE); rm.submitApp(CONTAINER_MB); rm.submitApp(CONTAINER_MB); long end = System.currentTimeMillis(); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("finishedTimeEnd", String.valueOf(end)) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("finishedTimeEnd", String.valueOf(end)) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -770,22 +809,22 @@ public void testAppsQueryFinishBeginEnd() throws JSONException, Exception { RMApp app1 = rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); // finish App - MockAM am = rm - .sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); + MockAM am = + rm.sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); am.registerAppAttempt(); am.unregisterAppAttempt(); amNodeManager.nodeHeartbeat(app1.getCurrentAppAttempt().getAppAttemptId(), - 1, ContainerState.COMPLETE); + 1, ContainerState.COMPLETE); rm.submitApp(CONTAINER_MB); rm.submitApp(CONTAINER_MB); long end = System.currentTimeMillis(); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("finishedTimeBegin", String.valueOf(start)) - .queryParam("finishedTimeEnd", String.valueOf(end)) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("finishedTimeBegin", String.valueOf(start)) + .queryParam("finishedTimeEnd", String.valueOf(end)) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -804,22 +843,22 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { RMApp app1 = rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); // finish App - MockAM am = rm - .sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); + MockAM am = + rm.sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); am.registerAppAttempt(); am.unregisterAppAttempt(); amNodeManager.nodeHeartbeat(app1.getCurrentAppAttempt().getAppAttemptId(), - 1, ContainerState.COMPLETE); + 1, ContainerState.COMPLETE); rm.submitApp(CONTAINER_MB, "", UserGroupInformation.getCurrentUser() - .getShortUserName(), null, false, null, 2, null, "MAPREDUCE"); + .getShortUserName(), null, false, null, 2, null, "MAPREDUCE"); rm.submitApp(CONTAINER_MB, "", UserGroupInformation.getCurrentUser() - .getShortUserName(), null, false, null, 2, null, "NON-YARN"); + .getShortUserName(), null, false, null, 2, null, "NON-YARN"); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("applicationTypes", "MAPREDUCE") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps") + .queryParam("applicationTypes", "MAPREDUCE") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -828,14 +867,13 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { JSONArray array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 1, array.length()); assertEquals("MAPREDUCE", - array.getJSONObject(0).getString("applicationType")); + array.getJSONObject(0).getString("applicationType")); - r = resource(); response = - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("applicationTypes", "YARN") - .queryParam("applicationTypes", "MAPREDUCE") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + this.constructWebResource("apps") + .queryParam("applicationTypes", "YARN") + .queryParam("applicationTypes", "MAPREDUCE") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -844,17 +882,15 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 2, array.length()); assertTrue((array.getJSONObject(0).getString("applicationType") - .equals("YARN") && array.getJSONObject(1).getString("applicationType") - .equals("MAPREDUCE")) || - (array.getJSONObject(1).getString("applicationType").equals("YARN") - && array.getJSONObject(0).getString("applicationType") - .equals("MAPREDUCE"))); + .equals("YARN") && array.getJSONObject(1).getString("applicationType") + .equals("MAPREDUCE")) + || (array.getJSONObject(1).getString("applicationType").equals("YARN") && array + .getJSONObject(0).getString("applicationType").equals("MAPREDUCE"))); - r = resource(); response = - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("applicationTypes", "YARN,NON-YARN") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + this.constructWebResource("apps") + .queryParam("applicationTypes", "YARN,NON-YARN") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -863,16 +899,14 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 2, array.length()); assertTrue((array.getJSONObject(0).getString("applicationType") - .equals("YARN") && array.getJSONObject(1).getString("applicationType") - .equals("NON-YARN")) || - (array.getJSONObject(1).getString("applicationType").equals("YARN") - && array.getJSONObject(0).getString("applicationType") - .equals("NON-YARN"))); - - r = resource(); - response = r.path("ws").path("v1").path("cluster") - .path("apps").queryParam("applicationTypes", "") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + .equals("YARN") && array.getJSONObject(1).getString("applicationType") + .equals("NON-YARN")) + || (array.getJSONObject(1).getString("applicationType").equals("YARN") && array + .getJSONObject(0).getString("applicationType").equals("NON-YARN"))); + + response = + this.constructWebResource("apps").queryParam("applicationTypes", "") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -881,12 +915,11 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 3, array.length()); - r = resource(); response = - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("applicationTypes", "YARN,NON-YARN") - .queryParam("applicationTypes", "MAPREDUCE") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + this.constructWebResource("apps") + .queryParam("applicationTypes", "YARN,NON-YARN") + .queryParam("applicationTypes", "MAPREDUCE") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -895,12 +928,11 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 3, array.length()); - r = resource(); response = - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("applicationTypes", "YARN") - .queryParam("applicationTypes", "") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + this.constructWebResource("apps") + .queryParam("applicationTypes", "YARN") + .queryParam("applicationTypes", "") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -908,14 +940,12 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { assertEquals("incorrect number of elements", 1, apps.length()); array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 1, array.length()); - assertEquals("YARN", - array.getJSONObject(0).getString("applicationType")); + assertEquals("YARN", array.getJSONObject(0).getString("applicationType")); - r = resource(); response = - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("applicationTypes", ",,, ,, YARN ,, ,") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + this.constructWebResource("apps") + .queryParam("applicationTypes", ",,, ,, YARN ,, ,") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -923,14 +953,12 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { assertEquals("incorrect number of elements", 1, apps.length()); array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 1, array.length()); - assertEquals("YARN", - array.getJSONObject(0).getString("applicationType")); + assertEquals("YARN", array.getJSONObject(0).getString("applicationType")); - r = resource(); response = - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("applicationTypes", ",,, ,, ,, ,") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + this.constructWebResource("apps") + .queryParam("applicationTypes", ",,, ,, ,, ,") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -939,11 +967,10 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 3, array.length()); - r = resource(); response = - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("applicationTypes", "YARN, ,NON-YARN, ,,") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + this.constructWebResource("apps") + .queryParam("applicationTypes", "YARN, ,NON-YARN, ,,") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -952,18 +979,16 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 2, array.length()); assertTrue((array.getJSONObject(0).getString("applicationType") - .equals("YARN") && array.getJSONObject(1).getString("applicationType") - .equals("NON-YARN")) || - (array.getJSONObject(1).getString("applicationType").equals("YARN") - && array.getJSONObject(0).getString("applicationType") - .equals("NON-YARN"))); + .equals("YARN") && array.getJSONObject(1).getString("applicationType") + .equals("NON-YARN")) + || (array.getJSONObject(1).getString("applicationType").equals("YARN") && array + .getJSONObject(0).getString("applicationType").equals("NON-YARN"))); - r = resource(); response = - r.path("ws").path("v1").path("cluster").path("apps") - .queryParam("applicationTypes", " YARN, , ,,,") - .queryParam("applicationTypes", "MAPREDUCE , ,, ,") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + this.constructWebResource("apps") + .queryParam("applicationTypes", " YARN, , ,,,") + .queryParam("applicationTypes", "MAPREDUCE , ,, ,") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -972,11 +997,10 @@ public void testAppsQueryAppTypes() throws JSONException, Exception { array = apps.getJSONArray("app"); assertEquals("incorrect number of elements", 2, array.length()); assertTrue((array.getJSONObject(0).getString("applicationType") - .equals("YARN") && array.getJSONObject(1).getString("applicationType") - .equals("MAPREDUCE")) || - (array.getJSONObject(1).getString("applicationType").equals("YARN") - && array.getJSONObject(0).getString("applicationType") - .equals("MAPREDUCE"))); + .equals("YARN") && array.getJSONObject(1).getString("applicationType") + .equals("MAPREDUCE")) + || (array.getJSONObject(1).getString("applicationType").equals("YARN") && array + .getJSONObject(0).getString("applicationType").equals("MAPREDUCE"))); rm.stop(); } @@ -987,27 +1011,28 @@ public void testAppStatistics() throws JSONException, Exception { rm.start(); MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 4096); Thread.sleep(1); - RMApp app1 = rm.submitApp(CONTAINER_MB, "", UserGroupInformation.getCurrentUser() - .getShortUserName(), null, false, null, 2, null, "MAPREDUCE"); + RMApp app1 = + rm.submitApp(CONTAINER_MB, "", UserGroupInformation.getCurrentUser() + .getShortUserName(), null, false, null, 2, null, "MAPREDUCE"); amNodeManager.nodeHeartbeat(true); // finish App - MockAM am = rm - .sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); + MockAM am = + rm.sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); am.registerAppAttempt(); am.unregisterAppAttempt(); - amNodeManager.nodeHeartbeat(app1.getCurrentAppAttempt().getAppAttemptId(), - 1, ContainerState.COMPLETE); + amNodeManager.nodeHeartbeat( + app1.getCurrentAppAttempt().getAppAttemptId(), 1, + ContainerState.COMPLETE); rm.submitApp(CONTAINER_MB, "", UserGroupInformation.getCurrentUser() - .getShortUserName(), null, false, null, 2, null, "MAPREDUCE"); + .getShortUserName(), null, false, null, 2, null, "MAPREDUCE"); rm.submitApp(CONTAINER_MB, "", UserGroupInformation.getCurrentUser() - .getShortUserName(), null, false, null, 2, null, "OTHER"); + .getShortUserName(), null, false, null, 2, null, "OTHER"); // zero type, zero state - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("appstatistics") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("appstatistics") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -1015,13 +1040,13 @@ public void testAppStatistics() throws JSONException, Exception { assertEquals("incorrect number of elements", 1, appsStatInfo.length()); JSONArray statItems = appsStatInfo.getJSONArray("statItem"); assertEquals("incorrect number of elements", - YarnApplicationState.values().length, statItems.length()); + YarnApplicationState.values().length, statItems.length()); for (int i = 0; i < YarnApplicationState.values().length; ++i) { assertEquals("*", statItems.getJSONObject(0).getString("type")); if (statItems.getJSONObject(0).getString("state").equals("ACCEPTED")) { assertEquals("2", statItems.getJSONObject(0).getString("count")); - } else if ( - statItems.getJSONObject(0).getString("state").equals("FINISHED")) { + } else if (statItems.getJSONObject(0).getString("state") + .equals("FINISHED")) { assertEquals("1", statItems.getJSONObject(0).getString("count")); } else { assertEquals("0", statItems.getJSONObject(0).getString("count")); @@ -1029,11 +1054,10 @@ public void testAppStatistics() throws JSONException, Exception { } // zero type, one state - r = resource(); - response = r.path("ws").path("v1").path("cluster") - .path("appstatistics") - .queryParam("states", YarnApplicationState.ACCEPTED.toString()) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + response = + this.constructWebResource("appstatistics") + .queryParam("states", YarnApplicationState.ACCEPTED.toString()) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -1046,11 +1070,10 @@ public void testAppStatistics() throws JSONException, Exception { assertEquals("2", statItems.getJSONObject(0).getString("count")); // one type, zero state - r = resource(); - response = r.path("ws").path("v1").path("cluster") - .path("appstatistics") - .queryParam("applicationTypes", "MAPREDUCE") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + response = + this.constructWebResource("appstatistics") + .queryParam("applicationTypes", "MAPREDUCE") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -1058,13 +1081,13 @@ public void testAppStatistics() throws JSONException, Exception { assertEquals("incorrect number of elements", 1, appsStatInfo.length()); statItems = appsStatInfo.getJSONArray("statItem"); assertEquals("incorrect number of elements", - YarnApplicationState.values().length, statItems.length()); + YarnApplicationState.values().length, statItems.length()); for (int i = 0; i < YarnApplicationState.values().length; ++i) { assertEquals("mapreduce", statItems.getJSONObject(0).getString("type")); if (statItems.getJSONObject(0).getString("state").equals("ACCEPTED")) { assertEquals("1", statItems.getJSONObject(0).getString("count")); - } else if ( - statItems.getJSONObject(0).getString("state").equals("FINISHED")) { + } else if (statItems.getJSONObject(0).getString("state") + .equals("FINISHED")) { assertEquals("1", statItems.getJSONObject(0).getString("count")); } else { assertEquals("0", statItems.getJSONObject(0).getString("count")); @@ -1072,11 +1095,10 @@ public void testAppStatistics() throws JSONException, Exception { } // two types, zero state - r = resource(); - response = r.path("ws").path("v1").path("cluster") - .path("appstatistics") - .queryParam("applicationTypes", "MAPREDUCE,OTHER") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + response = + this.constructWebResource("appstatistics") + .queryParam("applicationTypes", "MAPREDUCE,OTHER") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus()); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); @@ -1087,20 +1109,22 @@ public void testAppStatistics() throws JSONException, Exception { String type = exception.getString("exception"); String className = exception.getString("javaClassName"); WebServicesTestUtils.checkStringContains("exception message", - "we temporarily support at most one applicationType", message); + "we temporarily support at most one applicationType", message); WebServicesTestUtils.checkStringEqual("exception type", - "BadRequestException", type); + "BadRequestException", type); WebServicesTestUtils.checkStringEqual("exception className", - "org.apache.hadoop.yarn.webapp.BadRequestException", className); + "org.apache.hadoop.yarn.webapp.BadRequestException", className); // one type, two states - r = resource(); - response = r.path("ws").path("v1").path("cluster") - .path("appstatistics") - .queryParam("states", YarnApplicationState.FINISHED.toString() - + "," + YarnApplicationState.ACCEPTED.toString()) - .queryParam("applicationTypes", "MAPREDUCE") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + response = + this + .constructWebResource("appstatistics") + .queryParam( + "states", + YarnApplicationState.FINISHED.toString() + "," + + YarnApplicationState.ACCEPTED.toString()) + .queryParam("applicationTypes", "MAPREDUCE") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -1110,20 +1134,20 @@ public void testAppStatistics() throws JSONException, Exception { assertEquals("incorrect number of elements", 2, statItems.length()); JSONObject statItem1 = statItems.getJSONObject(0); JSONObject statItem2 = statItems.getJSONObject(1); - assertTrue((statItem1.getString("state").equals("ACCEPTED") && - statItem2.getString("state").equals("FINISHED")) || - (statItem2.getString("state").equals("ACCEPTED") && - statItem1.getString("state").equals("FINISHED"))); + assertTrue((statItem1.getString("state").equals("ACCEPTED") && statItem2 + .getString("state").equals("FINISHED")) + || (statItem2.getString("state").equals("ACCEPTED") && statItem1 + .getString("state").equals("FINISHED"))); assertEquals("mapreduce", statItem1.getString("type")); assertEquals("1", statItem1.getString("count")); assertEquals("mapreduce", statItem2.getString("type")); assertEquals("1", statItem2.getString("count")); // invalid state - r = resource(); - response = r.path("ws").path("v1").path("cluster") - .path("appstatistics").queryParam("states", "wrong_state") - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + response = + this.constructWebResource("appstatistics") + .queryParam("states", "wrong_state") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus()); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); json = response.getEntity(JSONObject.class); @@ -1134,11 +1158,11 @@ public void testAppStatistics() throws JSONException, Exception { type = exception.getString("exception"); className = exception.getString("javaClassName"); WebServicesTestUtils.checkStringContains("exception message", - "Invalid application-state wrong_state", message); + "Invalid application-state wrong_state", message); WebServicesTestUtils.checkStringEqual("exception type", - "BadRequestException", type); + "BadRequestException", type); WebServicesTestUtils.checkStringEqual("exception className", - "org.apache.hadoop.yarn.webapp.BadRequestException", className); + "org.apache.hadoop.yarn.webapp.BadRequestException", className); } finally { rm.stop(); } @@ -1151,7 +1175,7 @@ public void testSingleApp() throws JSONException, Exception { RMApp app1 = rm.submitApp(CONTAINER_MB, "testwordcount", "user1"); amNodeManager.nodeHeartbeat(true); testSingleAppsHelper(app1.getApplicationId().toString(), app1, - MediaType.APPLICATION_JSON); + MediaType.APPLICATION_JSON); rm.stop(); } @@ -1162,7 +1186,7 @@ public void testSingleAppsSlash() throws JSONException, Exception { RMApp app1 = rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); testSingleAppsHelper(app1.getApplicationId().toString() + "/", app1, - MediaType.APPLICATION_JSON); + MediaType.APPLICATION_JSON); rm.stop(); } @@ -1182,12 +1206,10 @@ public void testInvalidApp() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); try { - r.path("ws").path("v1").path("cluster").path("apps") - .path("application_invalid_12").accept(MediaType.APPLICATION_JSON) - .get(JSONObject.class); + this.constructWebResource("apps", "application_invalid_12") + .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); fail("should have thrown exception on invalid appid"); } catch (UniformInterfaceException ue) { ClientResponse response = ue.getResponse(); @@ -1201,11 +1223,11 @@ public void testInvalidApp() throws JSONException, Exception { String type = exception.getString("exception"); String classname = exception.getString("javaClassName"); WebServicesTestUtils.checkStringMatch("exception message", - "For input string: \"invalid\"", message); + "For input string: \"invalid\"", message); WebServicesTestUtils.checkStringMatch("exception type", - "NumberFormatException", type); + "NumberFormatException", type); WebServicesTestUtils.checkStringMatch("exception classname", - "java.lang.NumberFormatException", classname); + "java.lang.NumberFormatException", classname); } finally { rm.stop(); @@ -1218,12 +1240,10 @@ public void testNonexistApp() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB, "testwordcount", "user1"); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); try { - r.path("ws").path("v1").path("cluster").path("apps") - .path("application_00000_0099").accept(MediaType.APPLICATION_JSON) - .get(JSONObject.class); + this.constructWebResource("apps", "application_00000_0099") + .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); fail("should have thrown exception on invalid appid"); } catch (UniformInterfaceException ue) { ClientResponse response = ue.getResponse(); @@ -1238,12 +1258,12 @@ public void testNonexistApp() throws JSONException, Exception { String type = exception.getString("exception"); String classname = exception.getString("javaClassName"); WebServicesTestUtils.checkStringMatch("exception message", - "java.lang.Exception: app with id: application_00000_0099 not found", - message); + "java.lang.Exception: app with id: application_00000_0099 not found", + message); WebServicesTestUtils.checkStringMatch("exception type", - "NotFoundException", type); + "NotFoundException", type); WebServicesTestUtils.checkStringMatch("exception classname", - "org.apache.hadoop.yarn.webapp.NotFoundException", classname); + "org.apache.hadoop.yarn.webapp.NotFoundException", classname); } finally { rm.stop(); } @@ -1251,9 +1271,9 @@ public void testNonexistApp() throws JSONException, Exception { public void testSingleAppsHelper(String path, RMApp app, String media) throws JSONException, Exception { - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").path(path).accept(media).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps", path).accept(media) + .get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); @@ -1267,10 +1287,9 @@ public void testSingleAppsXML() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); RMApp app1 = rm.submitApp(CONTAINER_MB, "testwordcount", "user1"); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").path(app1.getApplicationId().toString()) - .accept(MediaType.APPLICATION_XML).get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps", app1.getApplicationId().toString()) + .accept(MediaType.APPLICATION_XML).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType()); String xml = response.getEntity(String.class); @@ -1288,29 +1307,29 @@ public void testSingleAppsXML() throws JSONException, Exception { public void verifyAppsXML(NodeList nodes, RMApp app) throws JSONException, Exception { - for (int i = 0; i < nodes.getLength(); i++) { + for (int i = 0; i < nodes.getLength(); i++) { Element element = (Element) nodes.item(i); verifyAppInfoGeneric(app, - WebServicesTestUtils.getXmlString(element, "id"), - WebServicesTestUtils.getXmlString(element, "user"), - WebServicesTestUtils.getXmlString(element, "name"), - WebServicesTestUtils.getXmlString(element, "applicationType"), - WebServicesTestUtils.getXmlString(element, "queue"), - WebServicesTestUtils.getXmlString(element, "state"), - WebServicesTestUtils.getXmlString(element, "finalStatus"), - WebServicesTestUtils.getXmlFloat(element, "progress"), - WebServicesTestUtils.getXmlString(element, "trackingUI"), - WebServicesTestUtils.getXmlString(element, "diagnostics"), - WebServicesTestUtils.getXmlLong(element, "clusterId"), - WebServicesTestUtils.getXmlLong(element, "startedTime"), - WebServicesTestUtils.getXmlLong(element, "finishedTime"), - WebServicesTestUtils.getXmlLong(element, "elapsedTime"), - WebServicesTestUtils.getXmlString(element, "amHostHttpAddress"), - WebServicesTestUtils.getXmlString(element, "amContainerLogs"), - WebServicesTestUtils.getXmlInt(element, "allocatedMB"), - WebServicesTestUtils.getXmlInt(element, "allocatedVCores"), - WebServicesTestUtils.getXmlInt(element, "runningContainers")); + WebServicesTestUtils.getXmlString(element, "id"), + WebServicesTestUtils.getXmlString(element, "user"), + WebServicesTestUtils.getXmlString(element, "name"), + WebServicesTestUtils.getXmlString(element, "applicationType"), + WebServicesTestUtils.getXmlString(element, "queue"), + WebServicesTestUtils.getXmlString(element, "state"), + WebServicesTestUtils.getXmlString(element, "finalStatus"), + WebServicesTestUtils.getXmlFloat(element, "progress"), + WebServicesTestUtils.getXmlString(element, "trackingUI"), + WebServicesTestUtils.getXmlString(element, "diagnostics"), + WebServicesTestUtils.getXmlLong(element, "clusterId"), + WebServicesTestUtils.getXmlLong(element, "startedTime"), + WebServicesTestUtils.getXmlLong(element, "finishedTime"), + WebServicesTestUtils.getXmlLong(element, "elapsedTime"), + WebServicesTestUtils.getXmlString(element, "amHostHttpAddress"), + WebServicesTestUtils.getXmlString(element, "amContainerLogs"), + WebServicesTestUtils.getXmlInt(element, "allocatedMB"), + WebServicesTestUtils.getXmlInt(element, "allocatedVCores"), + WebServicesTestUtils.getXmlInt(element, "runningContainers")); } } @@ -1321,53 +1340,54 @@ public void verifyAppInfo(JSONObject info, RMApp app) throws JSONException, assertEquals("incorrect number of elements", 20, info.length()); verifyAppInfoGeneric(app, info.getString("id"), info.getString("user"), - info.getString("name"), info.getString("applicationType"), info.getString("queue"), - info.getString("state"), info.getString("finalStatus"), - (float) info.getDouble("progress"), info.getString("trackingUI"), - info.getString("diagnostics"), info.getLong("clusterId"), - info.getLong("startedTime"), info.getLong("finishedTime"), - info.getLong("elapsedTime"), info.getString("amHostHttpAddress"), - info.getString("amContainerLogs"), info.getInt("allocatedMB"), - info.getInt("allocatedVCores"), info.getInt("runningContainers")); + info.getString("name"), info.getString("applicationType"), + info.getString("queue"), info.getString("state"), + info.getString("finalStatus"), (float) info.getDouble("progress"), + info.getString("trackingUI"), info.getString("diagnostics"), + info.getLong("clusterId"), info.getLong("startedTime"), + info.getLong("finishedTime"), info.getLong("elapsedTime"), + info.getString("amHostHttpAddress"), info.getString("amContainerLogs"), + info.getInt("allocatedMB"), info.getInt("allocatedVCores"), + info.getInt("runningContainers")); } public void verifyAppInfoGeneric(RMApp app, String id, String user, - String name, String applicationType, String queue, String state, String finalStatus, - float progress, String trackingUI, String diagnostics, long clusterId, - long startedTime, long finishedTime, long elapsedTime, - String amHostHttpAddress, String amContainerLogs, int allocatedMB, - int allocatedVCores, int numContainers) throws JSONException, - Exception { + String name, String applicationType, String queue, String state, + String finalStatus, float progress, String trackingUI, + String diagnostics, long clusterId, long startedTime, long finishedTime, + long elapsedTime, String amHostHttpAddress, String amContainerLogs, + int allocatedMB, int allocatedVCores, int numContainers) + throws JSONException, Exception { WebServicesTestUtils.checkStringMatch("id", app.getApplicationId() - .toString(), id); + .toString(), id); WebServicesTestUtils.checkStringMatch("user", app.getUser(), user); WebServicesTestUtils.checkStringMatch("name", app.getName(), name); WebServicesTestUtils.checkStringMatch("applicationType", app.getApplicationType(), applicationType); WebServicesTestUtils.checkStringMatch("queue", app.getQueue(), queue); WebServicesTestUtils.checkStringMatch("state", app.getState().toString(), - state); + state); WebServicesTestUtils.checkStringMatch("finalStatus", app - .getFinalApplicationStatus().toString(), finalStatus); + .getFinalApplicationStatus().toString(), finalStatus); assertEquals("progress doesn't match", 0, progress, 0.0); WebServicesTestUtils.checkStringMatch("trackingUI", "UNASSIGNED", - trackingUI); + trackingUI); WebServicesTestUtils.checkStringMatch("diagnostics", app.getDiagnostics() - .toString(), diagnostics); + .toString(), diagnostics); assertEquals("clusterId doesn't match", - ResourceManager.getClusterTimeStamp(), clusterId); + ResourceManager.getClusterTimeStamp(), clusterId); assertEquals("startedTime doesn't match", app.getStartTime(), startedTime); assertEquals("finishedTime doesn't match", app.getFinishTime(), - finishedTime); + finishedTime); assertTrue("elapsed time not greater than 0", elapsedTime > 0); WebServicesTestUtils.checkStringMatch("amHostHttpAddress", app - .getCurrentAppAttempt().getMasterContainer().getNodeHttpAddress(), - amHostHttpAddress); + .getCurrentAppAttempt().getMasterContainer().getNodeHttpAddress(), + amHostHttpAddress); assertTrue("amContainerLogs doesn't match", - amContainerLogs.startsWith("http://")); + amContainerLogs.startsWith("http://")); assertTrue("amContainerLogs doesn't contain user info", - amContainerLogs.endsWith("/" + app.getUser())); + amContainerLogs.endsWith("/" + app.getUser())); assertEquals("allocatedMB doesn't match", 1024, allocatedMB); assertEquals("allocatedVCores doesn't match", 1, allocatedVCores); assertEquals("numContainers doesn't match", 1, numContainers); @@ -1380,24 +1400,25 @@ public void testAppAttempts() throws JSONException, Exception { RMApp app1 = rm.submitApp(CONTAINER_MB, "testwordcount", "user1"); amNodeManager.nodeHeartbeat(true); testAppAttemptsHelper(app1.getApplicationId().toString(), app1, - MediaType.APPLICATION_JSON); + MediaType.APPLICATION_JSON); rm.stop(); } - @Test (timeout = 20000) + @Test(timeout = 20000) public void testMultipleAppAttempts() throws JSONException, Exception { rm.start(); MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 8192); RMApp app1 = rm.submitApp(CONTAINER_MB, "testwordcount", "user1"); MockAM am = MockRM.launchAndRegisterAM(app1, rm, amNodeManager); - int maxAppAttempts = rm.getConfig().getInt( - YarnConfiguration.RM_AM_MAX_ATTEMPTS, - YarnConfiguration.DEFAULT_RM_AM_MAX_ATTEMPTS); + int maxAppAttempts = + rm.getConfig().getInt(YarnConfiguration.RM_AM_MAX_ATTEMPTS, + YarnConfiguration.DEFAULT_RM_AM_MAX_ATTEMPTS); assertTrue(maxAppAttempts > 1); int numAttempt = 1; while (true) { // fail the AM by sending CONTAINER_FINISHED event without registering. - amNodeManager.nodeHeartbeat(am.getApplicationAttemptId(), 1, ContainerState.COMPLETE); + amNodeManager.nodeHeartbeat(am.getApplicationAttemptId(), 1, + ContainerState.COMPLETE); am.waitForState(RMAppAttemptState.FAILED); if (numAttempt == maxAppAttempts) { rm.waitForState(app1.getApplicationId(), RMAppState.FAILED); @@ -1408,10 +1429,10 @@ public void testMultipleAppAttempts() throws JSONException, Exception { am = MockRM.launchAndRegisterAM(app1, rm, amNodeManager); numAttempt++; } - assertEquals("incorrect number of attempts", maxAppAttempts, - app1.getAppAttempts().values().size()); + assertEquals("incorrect number of attempts", maxAppAttempts, app1 + .getAppAttempts().values().size()); testAppAttemptsHelper(app1.getApplicationId().toString(), app1, - MediaType.APPLICATION_JSON); + MediaType.APPLICATION_JSON); rm.stop(); } @@ -1422,7 +1443,7 @@ public void testAppAttemptsSlash() throws JSONException, Exception { RMApp app1 = rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); testAppAttemptsHelper(app1.getApplicationId().toString() + "/", app1, - MediaType.APPLICATION_JSON); + MediaType.APPLICATION_JSON); rm.stop(); } @@ -1442,12 +1463,10 @@ public void testInvalidAppAttempts() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); try { - r.path("ws").path("v1").path("cluster").path("apps") - .path("application_invalid_12").accept(MediaType.APPLICATION_JSON) - .get(JSONObject.class); + this.constructWebResource("apps", "application_invalid_12") + .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); fail("should have thrown exception on invalid appid"); } catch (UniformInterfaceException ue) { ClientResponse response = ue.getResponse(); @@ -1461,11 +1480,11 @@ public void testInvalidAppAttempts() throws JSONException, Exception { String type = exception.getString("exception"); String classname = exception.getString("javaClassName"); WebServicesTestUtils.checkStringMatch("exception message", - "For input string: \"invalid\"", message); + "For input string: \"invalid\"", message); WebServicesTestUtils.checkStringMatch("exception type", - "NumberFormatException", type); + "NumberFormatException", type); WebServicesTestUtils.checkStringMatch("exception classname", - "java.lang.NumberFormatException", classname); + "java.lang.NumberFormatException", classname); } finally { rm.stop(); @@ -1478,12 +1497,10 @@ public void testNonexistAppAttempts() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); rm.submitApp(CONTAINER_MB, "testwordcount", "user1"); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); try { - r.path("ws").path("v1").path("cluster").path("apps") - .path("application_00000_0099").accept(MediaType.APPLICATION_JSON) - .get(JSONObject.class); + this.constructWebResource("apps", "application_00000_0099") + .accept(MediaType.APPLICATION_JSON).get(JSONObject.class); fail("should have thrown exception on invalid appid"); } catch (UniformInterfaceException ue) { ClientResponse response = ue.getResponse(); @@ -1498,12 +1515,12 @@ public void testNonexistAppAttempts() throws JSONException, Exception { String type = exception.getString("exception"); String classname = exception.getString("javaClassName"); WebServicesTestUtils.checkStringMatch("exception message", - "java.lang.Exception: app with id: application_00000_0099 not found", - message); + "java.lang.Exception: app with id: application_00000_0099 not found", + message); WebServicesTestUtils.checkStringMatch("exception type", - "NotFoundException", type); + "NotFoundException", type); WebServicesTestUtils.checkStringMatch("exception classname", - "org.apache.hadoop.yarn.webapp.NotFoundException", classname); + "org.apache.hadoop.yarn.webapp.NotFoundException", classname); } finally { rm.stop(); } @@ -1511,10 +1528,9 @@ public void testNonexistAppAttempts() throws JSONException, Exception { public void testAppAttemptsHelper(String path, RMApp app, String media) throws JSONException, Exception { - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").path(path).path("appattempts").accept(media) - .get(ClientResponse.class); + ClientResponse response = + this.constructWebResource("apps", path, "appattempts").accept(media) + .get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); JSONObject json = response.getEntity(JSONObject.class); assertEquals("incorrect number of elements", 1, json.length()); @@ -1524,7 +1540,7 @@ public void testAppAttemptsHelper(String path, RMApp app, String media) Collection attempts = app.getAppAttempts().values(); assertEquals("incorrect number of elements", attempts.size(), - jsonArray.length()); + jsonArray.length()); // Verify these parallel arrays are the same int i = 0; @@ -1541,11 +1557,11 @@ public void testAppAttemptsXML() throws JSONException, Exception { MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); RMApp app1 = rm.submitApp(CONTAINER_MB, "testwordcount", user); amNodeManager.nodeHeartbeat(true); - WebResource r = resource(); - ClientResponse response = r.path("ws").path("v1").path("cluster") - .path("apps").path(app1.getApplicationId().toString()) - .path("appattempts").accept(MediaType.APPLICATION_XML) - .get(ClientResponse.class); + ClientResponse response = + this + .constructWebResource("apps", app1.getApplicationId().toString(), + "appattempts").accept(MediaType.APPLICATION_XML) + .get(ClientResponse.class); assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType()); String xml = response.getEntity(String.class); @@ -1563,54 +1579,261 @@ public void testAppAttemptsXML() throws JSONException, Exception { } public void verifyAppAttemptsXML(NodeList nodes, RMAppAttempt appAttempt, - String user) - throws JSONException, Exception { + String user) throws JSONException, Exception { for (int i = 0; i < nodes.getLength(); i++) { Element element = (Element) nodes.item(i); verifyAppAttemptInfoGeneric(appAttempt, - WebServicesTestUtils.getXmlInt(element, "id"), - WebServicesTestUtils.getXmlLong(element, "startTime"), - WebServicesTestUtils.getXmlString(element, "containerId"), - WebServicesTestUtils.getXmlString(element, "nodeHttpAddress"), - WebServicesTestUtils.getXmlString(element, "nodeId"), - WebServicesTestUtils.getXmlString(element, "logsLink"), user); + WebServicesTestUtils.getXmlInt(element, "id"), + WebServicesTestUtils.getXmlLong(element, "startTime"), + WebServicesTestUtils.getXmlString(element, "containerId"), + WebServicesTestUtils.getXmlString(element, "nodeHttpAddress"), + WebServicesTestUtils.getXmlString(element, "nodeId"), + WebServicesTestUtils.getXmlString(element, "logsLink"), user); } } public void verifyAppAttemptsInfo(JSONObject info, RMAppAttempt appAttempt, - String user) - throws JSONException, Exception { + String user) throws JSONException, Exception { assertEquals("incorrect number of elements", 6, info.length()); verifyAppAttemptInfoGeneric(appAttempt, info.getInt("id"), - info.getLong("startTime"), info.getString("containerId"), - info.getString("nodeHttpAddress"), info.getString("nodeId"), - info.getString("logsLink"), user); + info.getLong("startTime"), info.getString("containerId"), + info.getString("nodeHttpAddress"), info.getString("nodeId"), + info.getString("logsLink"), user); } public void verifyAppAttemptInfoGeneric(RMAppAttempt appAttempt, int id, - long startTime, String containerId, String nodeHttpAddress, String nodeId, - String logsLink, String user) - throws JSONException, Exception { + long startTime, String containerId, String nodeHttpAddress, + String nodeId, String logsLink, String user) throws JSONException, + Exception { assertEquals("id doesn't match", appAttempt.getAppAttemptId() - .getAttemptId(), id); + .getAttemptId(), id); assertEquals("startedTime doesn't match", appAttempt.getStartTime(), - startTime); + startTime); WebServicesTestUtils.checkStringMatch("containerId", appAttempt - .getMasterContainer().getId().toString(), containerId); + .getMasterContainer().getId().toString(), containerId); WebServicesTestUtils.checkStringMatch("nodeHttpAddress", appAttempt - .getMasterContainer().getNodeHttpAddress(), nodeHttpAddress); + .getMasterContainer().getNodeHttpAddress(), nodeHttpAddress); WebServicesTestUtils.checkStringMatch("nodeId", appAttempt - .getMasterContainer().getNodeId().toString(), nodeId); + .getMasterContainer().getNodeId().toString(), nodeId); assertTrue("logsLink doesn't match", logsLink.startsWith("//")); - assertTrue( - "logsLink doesn't contain user info", logsLink.endsWith("/" - + user)); + assertTrue("logsLink doesn't contain user info", + logsLink.endsWith("/" + user)); } -} + private WebResource constructWebResource(WebResource r, String... paths) { + WebResource rt = r; + for (String path : paths) { + rt = rt.path(path); + } + if (rm.getConfig() + .getBoolean(YarnConfiguration.YARN_ACL_ENABLE, false) == true) { + rt = rt.queryParam("user.name", webserviceUserName); + } + return rt; + } + + private WebResource constructWebResource(String... paths) { + WebResource r = resource(); + WebResource ws = r.path("ws").path("v1").path("cluster"); + return this.constructWebResource(ws, paths); + } + + @Test(timeout = 90000) + public void testSingleAppKill() throws Exception { + rm.start(); + MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); + + String[] mediaTypes = + { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }; + MediaType[] contentTypes = + { MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_XML_TYPE }; + for (String mediaType : mediaTypes) { + for(MediaType contentType: contentTypes) { + RMApp app = rm.submitApp(CONTAINER_MB, "", webserviceUserName); + amNodeManager.nodeHeartbeat(true); + ClientResponse response = this + .constructWebResource("apps", app.getApplicationId().toString()) + .accept(mediaType).get(ClientResponse.class); + AppInfo info = response.getEntity(AppInfo.class); + info.setState(YarnApplicationState.KILLED); + + Object entity; + if(contentType == MediaType.APPLICATION_JSON_TYPE) { + entity = appInfoToJSON(info); + } + else { + entity = info; + } + response = this + .constructWebResource("apps", app.getApplicationId().toString()) + .entity(entity, contentType) + .accept(mediaType) + .put(ClientResponse.class); + + + if (rm.getConfig() + .getBoolean(YarnConfiguration.YARN_ACL_ENABLE, false) == false) { + assertEquals(Status.UNAUTHORIZED, + response.getClientResponseStatus()); + continue; + } + assertEquals(Status.ACCEPTED, response.getClientResponseStatus()); + if (mediaType == MediaType.APPLICATION_JSON) { + verifyAppKillJson(response, RMAppState.ACCEPTED); + } else { + verifyAppKillXML(response, RMAppState.ACCEPTED); + } + String locationHeaderValue = + response.getHeaders().getFirst("Location"); + Client c = Client.create(); + WebResource tmp = c.resource(locationHeaderValue); + if (rm.getConfig() + .getBoolean(YarnConfiguration.YARN_ACL_ENABLE, false) == true) { + tmp = tmp.queryParam("user.name", webserviceUserName); + } + response = tmp.get(ClientResponse.class); + assertEquals(Status.OK, response.getClientResponseStatus()); + assertTrue(locationHeaderValue.endsWith("/ws/v1/cluster/apps/" + + app.getApplicationId().toString())); + + while (true) { + Thread.sleep(1000); + response = this + .constructWebResource("apps", app.getApplicationId().toString()) + .accept(mediaType).entity(entity, contentType) + .put(ClientResponse.class); + assertTrue((response.getClientResponseStatus() == Status.ACCEPTED) + || (response.getClientResponseStatus() == Status.OK)); + if (response.getClientResponseStatus() == Status.OK) { + if (mediaType == MediaType.APPLICATION_JSON) { + verifyAppKillJson(response, RMAppState.KILLED); + } else { + verifyAppKillXML(response, RMAppState.KILLED); + } + break; + } + } + } + } + + rm.stop(); + return; + } + + private static String appInfoToJSON(AppInfo info) throws Exception { + StringWriter sw = new StringWriter(); + JSONJAXBContext ctx = new JSONJAXBContext(AppInfo.class); + JSONMarshaller jm = ctx.createJSONMarshaller(); + jm.marshallToJSON(info, sw); + String json = "{\"app\":"; + json = json.concat(sw.toString()); + json = json.concat("}"); + return json; + } + + protected static void verifyAppKillJson(ClientResponse response, + RMAppState state) throws JSONException { + + assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); + JSONObject json = response.getEntity(JSONObject.class); + assertEquals("incorrect number of elements", 1, json.length()); + JSONObject appObj = json.getJSONObject("app"); + assertEquals("app state incorrect", state.toString(), + appObj.getString("state")); + return; + } + + protected static void verifyAppKillXML(ClientResponse response, + RMAppState appState) throws ParserConfigurationException, IOException, + SAXException { + assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType()); + String xml = response.getEntity(String.class); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + InputSource is = new InputSource(); + is.setCharacterStream(new StringReader(xml)); + Document dom = db.parse(is); + NodeList nodes = dom.getElementsByTagName("app"); + assertEquals("incorrect number of elements", 1, nodes.getLength()); + Element element = (Element) nodes.item(0); + String state = WebServicesTestUtils.getXmlString(element, "state"); + assertEquals("app state incorrect", appState.toString(), state); + return; + } + + @Test(timeout = 30000) + public void testSingleAppKillUnauthorized() throws Exception { + rm.start(); + MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); + + String[] mediaTypes = + { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }; + for (String mediaType : mediaTypes) { + RMApp app = rm.submitApp(CONTAINER_MB, "test", "someuser"); + amNodeManager.nodeHeartbeat(true); + ClientResponse response = this + .constructWebResource("apps", app.getApplicationId().toString()) + .accept(mediaType).get(ClientResponse.class); + AppInfo info = response.getEntity(AppInfo.class); + info.setState(YarnApplicationState.KILLED); + + response = this + .constructWebResource("apps", app.getApplicationId().toString()) + .accept(mediaType).entity(info, MediaType.APPLICATION_XML) + .put(ClientResponse.class); + if (rm.getConfig() + .getBoolean(YarnConfiguration.YARN_ACL_ENABLE, false) == false) { + assertEquals(Status.UNAUTHORIZED, response.getClientResponseStatus()); + } else { + assertEquals(Status.FORBIDDEN, response.getClientResponseStatus()); + } + } + + // there's a condition where if the rm is stopped while an app + // is being killed, it can lead to the test timing out, hence the sleep + Thread.sleep(3000); + + rm.stop(); + return; + + } + + @Test + public void testSingleAppKillInvalidId() throws Exception { + rm.start(); + MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); + amNodeManager.nodeHeartbeat(true); + String[] testAppIds = { "application_1391705042196_0001", + "random_string" }; + for (String testAppId : testAppIds) { + AppInfo info = new AppInfo(); + ClientResponse response = + this.constructWebResource("apps", testAppId) + .accept(MediaType.APPLICATION_XML).entity(info, MediaType.APPLICATION_XML) + .put(ClientResponse.class); + if (rm.getConfig() + .getBoolean(YarnConfiguration.YARN_ACL_ENABLE, false) == false) { + assertEquals(Status.UNAUTHORIZED, response.getClientResponseStatus()); + continue; + } + assertEquals(Status.NOT_FOUND, response.getClientResponseStatus()); + } + rm.stop(); + return; + } + + @After + @Override + public void tearDown() throws Exception { + if (rm != null) { + rm.stop(); + } + super.tearDown(); + } +}