YARN-2546. Made REST API for application creation/submission use numeric and boolean types instead of the string of them. Contributed by Varun Vasudev.

(cherry picked from commit 72b0881ca6)
This commit is contained in:
Zhijie Shen 2014-09-24 17:57:32 -07:00
parent 3a2e400377
commit 83926b3c57
4 changed files with 62 additions and 57 deletions

View File

@ -414,6 +414,9 @@ Release 2.6.0 - UNRELEASED
YARN-2596. TestWorkPreservingRMRestart fails with FairScheduler. (kasha) YARN-2596. TestWorkPreservingRMRestart fails with FairScheduler. (kasha)
YARN-2546. Made REST API for application creation/submission use numeric and
boolean types instead of the string of them. (Varun Vasudev via zjshen)
Release 2.5.1 - 2014-09-05 Release 2.5.1 - 2014-09-05
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -22,62 +22,61 @@ import com.google.inject.Singleton;
import com.sun.jersey.api.json.JSONConfiguration; import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.api.json.JSONJAXBContext; import com.sun.jersey.api.json.JSONJAXBContext;
import java.util.Arrays; import java.util.*;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider; import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBContext;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.UserInfo; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.UserInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo; import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.*;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppAttemptInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppAttemptsInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ApplicationStatisticsInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppsInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerQueueInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerQueueInfoList;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterMetricsInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.StatisticsItemInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.FifoSchedulerInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodesInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ResourceInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.SchedulerInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.SchedulerTypeInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.UserMetricsInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.UsersInfo;
import org.apache.hadoop.yarn.webapp.RemoteExceptionData; import org.apache.hadoop.yarn.webapp.RemoteExceptionData;
@Singleton @Singleton
@Provider @Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> { public class JAXBContextResolver implements ContextResolver<JAXBContext> {
private JAXBContext context; private final Map<Class, JAXBContext> typesContextMap;
private final Set<Class> types;
// you have to specify all the dao classes here
private final Class[] cTypes = { AppInfo.class, AppAttemptInfo.class,
AppAttemptsInfo.class, ClusterInfo.class,
CapacitySchedulerQueueInfo.class, FifoSchedulerInfo.class,
SchedulerTypeInfo.class, NodeInfo.class, UserMetricsInfo.class,
CapacitySchedulerInfo.class, ClusterMetricsInfo.class,
SchedulerInfo.class, AppsInfo.class, NodesInfo.class,
RemoteExceptionData.class, CapacitySchedulerQueueInfoList.class,
ResourceInfo.class, UsersInfo.class, UserInfo.class,
ApplicationStatisticsInfo.class, StatisticsItemInfo.class};
public JAXBContextResolver() throws Exception { public JAXBContextResolver() throws Exception {
this.types = new HashSet<Class>(Arrays.asList(cTypes));
this.context = new JSONJAXBContext(JSONConfiguration.natural() JAXBContext context;
.rootUnwrapping(false).build(), cTypes); JAXBContext unWrappedRootContext;
// you have to specify all the dao classes here
final Class[] cTypes =
{ AppInfo.class, AppAttemptInfo.class, AppAttemptsInfo.class,
ClusterInfo.class, CapacitySchedulerQueueInfo.class,
FifoSchedulerInfo.class, SchedulerTypeInfo.class, NodeInfo.class,
UserMetricsInfo.class, CapacitySchedulerInfo.class,
ClusterMetricsInfo.class, SchedulerInfo.class, AppsInfo.class,
NodesInfo.class, RemoteExceptionData.class,
CapacitySchedulerQueueInfoList.class, ResourceInfo.class,
UsersInfo.class, UserInfo.class, ApplicationStatisticsInfo.class,
StatisticsItemInfo.class };
// these dao classes need root unwrapping
final Class[] rootUnwrappedTypes =
{ NewApplication.class, ApplicationSubmissionContextInfo.class,
ContainerLaunchContextInfo.class, LocalResourceInfo.class,
DelegationToken.class };
this.typesContextMap = new HashMap<Class, JAXBContext>();
context =
new JSONJAXBContext(JSONConfiguration.natural().rootUnwrapping(false)
.build(), cTypes);
unWrappedRootContext =
new JSONJAXBContext(JSONConfiguration.natural().rootUnwrapping(true)
.build(), rootUnwrappedTypes);
for (Class type : cTypes) {
typesContextMap.put(type, context);
}
for (Class type : rootUnwrappedTypes) {
typesContextMap.put(type, unWrappedRootContext);
}
} }
@Override @Override
public JAXBContext getContext(Class<?> objectType) { public JAXBContext getContext(Class<?> objectType) {
return (types.contains(objectType)) ? context : null; return typesContextMap.get(objectType);
} }
} }

View File

@ -43,6 +43,8 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.Text; import org.apache.hadoop.io.Text;
@ -214,6 +216,7 @@ public class TestRMWebServicesAppsModification extends JerseyTest {
"org.apache.hadoop.yarn.server.resourcemanager.webapp") "org.apache.hadoop.yarn.server.resourcemanager.webapp")
.contextListenerClass(GuiceServletConfig.class) .contextListenerClass(GuiceServletConfig.class)
.filterClass(com.google.inject.servlet.GuiceFilter.class) .filterClass(com.google.inject.servlet.GuiceFilter.class)
.clientConfig(new DefaultClientConfig(JAXBContextResolver.class))
.contextPath("jersey-guice-filter").servletPath("/").build()); .contextPath("jersey-guice-filter").servletPath("/").build());
switch (run) { switch (run) {
case 0: case 0:
@ -550,10 +553,10 @@ public class TestRMWebServicesAppsModification extends JerseyTest {
} }
} }
// Simple test - just post to /apps/id and validate the response // Simple test - just post to /apps/new-application and validate the response
@Test @Test
public void testGetNewApplication() throws Exception { public void testGetNewApplication() throws Exception {
// client().addFilter(new LoggingFilter(System.out)); client().addFilter(new LoggingFilter(System.out));
rm.start(); rm.start();
String mediaTypes[] = String mediaTypes[] =
{ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }; { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML };
@ -653,7 +656,7 @@ public class TestRMWebServicesAppsModification extends JerseyTest {
// create a test app and submit it via rest(after getting an app-id) then // create a test app and submit it via rest(after getting an app-id) then
// get the app details from the rmcontext and check that everything matches // get the app details from the rmcontext and check that everything matches
// client().addFilter(new LoggingFilter(System.out)); client().addFilter(new LoggingFilter(System.out));
String lrKey = "example"; String lrKey = "example";
String queueName = "testqueue"; String queueName = "testqueue";
String appName = "test"; String appName = "test";

View File

@ -2083,12 +2083,12 @@ _01_000001</amContainerLogs>
+---+ +---+
{ {
"application-id":"application_1404198295326_0001", "application-id":"application_1404198295326_0003",
"maximum-resource-capability": "maximum-resource-capability":
{ {
"memory":"8192", "memory":8192,
"vCores":"32" "vCores":32
} }
} }
+---+ +---+
@ -2257,8 +2257,8 @@ _01_000001</amContainerLogs>
"resource":"hdfs://hdfs-namenode:9000/user/testuser/DistributedShell/demo-app/AppMaster.jar", "resource":"hdfs://hdfs-namenode:9000/user/testuser/DistributedShell/demo-app/AppMaster.jar",
"type":"FILE", "type":"FILE",
"visibility":"APPLICATION", "visibility":"APPLICATION",
"size": "43004", "size": 43004,
"timestamp": "1405452071209" "timestamp": 1405452071209
} }
} }
] ]
@ -2290,15 +2290,15 @@ _01_000001</amContainerLogs>
] ]
} }
}, },
"unmanaged-AM":"false", "unmanaged-AM":false,
"max-app-attempts":"2", "max-app-attempts":2,
"resource": "resource":
{ {
"memory":"1024", "memory":1024,
"vCores":"1" "vCores":1
}, },
"application-type":"YARN", "application-type":"YARN",
"keep-containers-across-application-attempts":"false" "keep-containers-across-application-attempts":false
} }
+---+ +---+
@ -2797,8 +2797,8 @@ Server: Jetty(6.1.26)
"renewer":"test-renewer", "renewer":"test-renewer",
"owner":"client@EXAMPLE.COM", "owner":"client@EXAMPLE.COM",
"kind":"RM_DELEGATION_TOKEN", "kind":"RM_DELEGATION_TOKEN",
"expiration-time":"1405153616489", "expiration-time":1405153616489,
"max-validity":"1405672016489" "max-validity":1405672016489
} }
+---+ +---+
@ -2869,7 +2869,7 @@ Server: Jetty(6.1.26)
+---+ +---+
{ {
"expiration-time":"1404112520402" "expiration-time":1404112520402
} }
+---+ +---+