diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index b7252222e5c..14aa00a31eb 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -2454,7 +2454,13 @@ public class YarnConfiguration extends Configuration { "yarn.http.rmwebapp.external.classes"; public static final String YARN_HTTP_WEBAPP_SCHEDULER_PAGE = - "hadoop.http.rmwebapp.scheduler.page.class"; + "yarn.http.rmwebapp.scheduler.page.class"; + + public static final String YARN_HTTP_WEBAPP_CUSTOM_DAO_CLASSES = + "yarn.http.rmwebapp.custom.dao.classes"; + + public static final String YARN_HTTP_WEBAPP_CUSTOM_UNWRAPPED_DAO_CLASSES = + "yarn.http.rmwebapp.custom.unwrapped.dao.classes"; /** * Whether or not users are allowed to request that Docker containers honor diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml index 4c0aca934c4..8f0de6badab 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml @@ -3444,10 +3444,26 @@ Used to specify custom scheduler page - hadoop.http.rmwebapp.scheduler.page.class + yarn.http.rmwebapp.scheduler.page.class + + + Used to specify custom DAO classes used by custom web services. + + yarn.http.rmwebapp.custom.dao.classes + + + + + + Used to specify custom DAO classes used by custom web services which requires + root unwrapping. + + yarn.http.rmwebapp.custom.unwrapped.dao.classes + + The Node Label script to run. Script output Line starting with 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/JAXBContextResolver.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/JAXBContextResolver.java index f6eb2adf726..a31434b3adc 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/JAXBContextResolver.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/JAXBContextResolver.java @@ -18,6 +18,7 @@ package org.apache.hadoop.yarn.server.resourcemanager.webapp; +import com.google.inject.Inject; import com.google.inject.Singleton; import com.sun.jersey.api.json.JSONConfiguration; import com.sun.jersey.api.json.JSONJAXBContext; @@ -28,6 +29,10 @@ import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; import javax.xml.bind.JAXBContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.UserInfo; import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.*; import org.apache.hadoop.yarn.webapp.RemoteExceptionData; @@ -36,9 +41,17 @@ import org.apache.hadoop.yarn.webapp.RemoteExceptionData; @Provider public class JAXBContextResolver implements ContextResolver { + private static final Log LOG = + LogFactory.getLog(JAXBContextResolver.class.getName()); + private final Map typesContextMap; public JAXBContextResolver() throws Exception { + this(new Configuration()); + } + + @Inject + public JAXBContextResolver(Configuration conf) throws Exception { JAXBContext context; JAXBContext unWrappedRootContext; @@ -65,17 +78,54 @@ public class JAXBContextResolver implements ContextResolver { DelegationToken.class, AppQueue.class, AppPriority.class, ResourceOptionInfo.class }; + ArrayList finalcTypesList = new ArrayList<>(); + ArrayList finalRootUnwrappedTypesList = new ArrayList<>(); + + Collections.addAll(finalcTypesList, cTypes); + Collections.addAll(finalRootUnwrappedTypesList, rootUnwrappedTypes); + + // Add Custom DAO Classes + Class[] daoClasses = null; + Class[] unwrappedDaoClasses = null; + boolean loadCustom = true; + try { + daoClasses = conf + .getClasses(YarnConfiguration.YARN_HTTP_WEBAPP_CUSTOM_DAO_CLASSES); + unwrappedDaoClasses = conf.getClasses( + YarnConfiguration.YARN_HTTP_WEBAPP_CUSTOM_UNWRAPPED_DAO_CLASSES); + } catch (Exception e) { + LOG.warn("Failed to load custom dao class: " + e); + loadCustom = false; + } + + if (loadCustom) { + if (daoClasses != null) { + Collections.addAll(finalcTypesList, daoClasses); + LOG.debug("Added custom dao classes: " + Arrays.toString(daoClasses)); + } + if (unwrappedDaoClasses != null) { + Collections.addAll(finalRootUnwrappedTypesList, unwrappedDaoClasses); + LOG.debug("Added custom Unwrapped dao classes: " + + Arrays.toString(unwrappedDaoClasses)); + } + } + + final Class[] finalcTypes = finalcTypesList + .toArray(new Class[finalcTypesList.size()]); + final Class[] finalRootUnwrappedTypes = finalRootUnwrappedTypesList + .toArray(new Class[finalRootUnwrappedTypesList.size()]); + this.typesContextMap = new HashMap(); context = new JSONJAXBContext(JSONConfiguration.natural().rootUnwrapping(false) - .build(), cTypes); + .build(), finalcTypes); unWrappedRootContext = new JSONJAXBContext(JSONConfiguration.natural().rootUnwrapping(true) - .build(), rootUnwrappedTypes); - for (Class type : cTypes) { + .build(), finalRootUnwrappedTypes); + for (Class type : finalcTypes) { typesContextMap.put(type, context); } - for (Class type : rootUnwrappedTypes) { + for (Class type : finalRootUnwrappedTypes) { typesContextMap.put(type, unWrappedRootContext); } }