Ver Fonte

YARN-8047. RMWebApp make external class pluggable.

Contributed by Bilwa S T.
Prabhu Joseph há 4 anos atrás
pai
commit
3a4d05b850

+ 6 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java

@@ -2390,6 +2390,12 @@ public class YarnConfiguration extends Configuration {
   public static final boolean DEFAULT_NM_DOCKER_ALLOW_HOST_PID_NAMESPACE =
       false;
 
+  public static final String YARN_HTTP_WEBAPP_EXTERNAL_CLASSES =
+      "yarn.http.rmwebapp.external.classes";
+
+  public static final String YARN_HTTP_WEBAPP_SCHEDULER_PAGE =
+      "hadoop.http.rmwebapp.scheduler.page.class";
+
   /**
    * Whether or not users are allowed to request that Docker containers honor
    * the debug deletion delay. This is useful for troubleshooting Docker

+ 20 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml

@@ -3330,6 +3330,26 @@
     <value>20</value>
   </property>
 
+  <property>
+    <description>
+    Used to specify custom web services for Resourcemanager. Value can be
+    classnames separated by comma.
+    Ex: org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebServices,
+    org.apache.hadoop.yarn.server.resourcemanager.webapp.DummyClass
+    </description>
+    <name>yarn.http.rmwebapp.external.classes</name>
+    <value></value>
+  </property>
+
+  <property>
+    <description>
+    Used to specify custom scheduler page
+    </description>
+    <name>hadoop.http.rmwebapp.scheduler.page.class</name>
+    <value></value>
+  </property>
+
+
   <property>
     <description>The Node Label script to run. Script output Line starting with
      "NODE_PARTITION:" will be considered as Node Label Partition. In case of

+ 11 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java

@@ -55,6 +55,7 @@ public class RMWebApp extends WebApp implements YarnWebParams {
     bind(RMWebServices.class);
     bind(GenericExceptionHandler.class);
     bind(RMWebApp.class).toInstance(this);
+    bindExternalClasses();
 
     if (rm != null) {
       bind(ResourceManager.class).toInstance(rm);
@@ -97,6 +98,16 @@ public class RMWebApp extends WebApp implements YarnWebParams {
       return super.getRedirectPath();
   }
 
+  private void bindExternalClasses() {
+    YarnConfiguration yarnConf = new YarnConfiguration(rm.getConfig());
+    Class<?>[] externalClasses = yarnConf
+        .getClasses(YarnConfiguration.YARN_HTTP_WEBAPP_EXTERNAL_CLASSES);
+    for (Class<?> c : externalClasses) {
+      bind(c);
+    }
+  }
+
+
   private String buildRedirectPath() {
     // make a copy of the original configuration so not to mutate it. Also use
     // an YarnConfiguration to force loading of yarn-site.xml.

+ 50 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java

@@ -21,13 +21,17 @@ package org.apache.hadoop.yarn.server.resourcemanager.webapp;
 import static org.apache.hadoop.yarn.util.StringHelper.join;
 import static org.apache.hadoop.yarn.webapp.YarnWebParams.QUEUE_NAME;
 
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
 import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
 import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
 import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler;
 import org.apache.hadoop.yarn.util.StringHelper;
 import org.apache.hadoop.yarn.webapp.Controller;
+import org.apache.hadoop.yarn.webapp.View;
 import org.apache.hadoop.yarn.webapp.YarnWebParams;
 
 import com.google.inject.Inject;
@@ -92,9 +96,52 @@ public class RmController extends Controller {
       render(FairSchedulerPage.class);
       return;
     }
-    
-    setTitle("Default Scheduler");
-    render(DefaultSchedulerPage.class);
+
+    if (rs instanceof FifoScheduler) {
+      setTitle("FIFO Scheduler");
+      render(DefaultSchedulerPage.class);
+      return;
+    }
+
+    renderOtherPluginScheduler(rm);
+  }
+
+  private void renderOtherPluginScheduler(ResourceManager rm) {
+    ResourceScheduler rs = rm.getResourceScheduler();
+    String schedulerName = rs.getClass().getSimpleName();
+
+    Class<? extends View> cls = PluginSchedulerPageHelper
+        .getPageClass(rm.getConfig());
+    if (cls != null) {
+      setTitle(schedulerName);
+      render(cls);
+    } else {
+      LOG.warn(
+          "Render default scheduler page as scheduler page configured doesn't exist");
+      setTitle("Default Scheduler");
+      render(DefaultSchedulerPage.class);
+    }
+  }
+
+  static class PluginSchedulerPageHelper {
+    private static boolean hasLoaded = false;
+    private static Class<? extends View> pageClass = null;
+    public static Class<? extends View> getPageClass(Configuration conf) {
+      if (!hasLoaded) {
+        loadPluginSchedulerPageClass(conf);
+        hasLoaded = true;
+      }
+      return pageClass;
+    }
+
+    private static void loadPluginSchedulerPageClass(Configuration conf) {
+      Class<?> configuredClass = conf
+          .getClass(YarnConfiguration.YARN_HTTP_WEBAPP_SCHEDULER_PAGE, null);
+      if (!View.class.isAssignableFrom(configuredClass)) {
+        return;
+      }
+      pageClass = (Class<? extends View>) configuredClass;
+    }
   }
 
   public void queue() {