From e4550e1aefcd344eeff0a0fbdec043b0ce71661e Mon Sep 17 00:00:00 2001 From: slfan1989 <55643692+slfan1989@users.noreply.github.com> Date: Mon, 11 Sep 2023 13:28:31 +0800 Subject: [PATCH] YARN-6476. Advanced Federation UI based on YARN UI v2. (#5920) Contributed by Shilun Fan. Reviewed-by: Inigo Goiri Signed-off-by: Shilun Fan --- .../hadoop/yarn/server/router/Router.java | 50 ++++++++++++++++++- .../hadoop/yarn/server/router/TestRouter.java | 2 +- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/Router.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/Router.java index 62153242f7..56bb91db52 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/Router.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/Router.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.net.InetAddress; +import java.net.URL; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -38,6 +39,7 @@ import org.apache.hadoop.util.JvmPauseMonitor; import org.apache.hadoop.util.ShutdownHookManager; import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.util.VersionInfo; import org.apache.hadoop.yarn.YarnUncaughtExceptionHandler; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; @@ -55,6 +57,7 @@ import org.apache.hadoop.yarn.webapp.WebApps.Builder; import org.apache.hadoop.yarn.webapp.util.WebAppUtils; import org.apache.hadoop.yarn.webapp.util.WebServiceClient; +import org.eclipse.jetty.webapp.WebAppContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -106,6 +109,8 @@ public class Router extends CompositeService { private static final String METRICS_NAME = "Router"; + private static final String UI2_WEBAPP_NAME = "/ui2"; + private ScheduledThreadPoolExecutor scheduledExecutorService; private SubClusterCleaner subClusterCleaner; @@ -226,7 +231,50 @@ public void startWepApp() { String[] proxyParts = proxyHostAndPort.split(":"); builder.withAttribute(WebAppProxy.PROXY_HOST_ATTRIBUTE, proxyParts[0]); } - webApp = builder.start(new RouterWebApp(this)); + webApp = builder.start(new RouterWebApp(this), getUIWebAppContext()); + } + + private WebAppContext getUIWebAppContext() { + WebAppContext uiWebAppContext = null; + boolean isWebUI2Enabled = conf.getBoolean(YarnConfiguration.YARN_WEBAPP_UI2_ENABLE, + YarnConfiguration.DEFAULT_YARN_WEBAPP_UI2_ENABLE); + + if(isWebUI2Enabled) { + String onDiskPath = conf.get(YarnConfiguration.YARN_WEBAPP_UI2_WARFILE_PATH); + uiWebAppContext = new WebAppContext(); + uiWebAppContext.setContextPath(UI2_WEBAPP_NAME); + + if (null == onDiskPath) { + String war = "hadoop-yarn-ui-" + VersionInfo.getVersion() + ".war"; + URL url = getClass().getClassLoader().getResource(war); + if (null == url) { + onDiskPath = getWebAppsPath("ui2"); + } else { + onDiskPath = url.getFile(); + } + } + + if (onDiskPath == null || onDiskPath.isEmpty()) { + LOG.error("No war file or webapps found for yarn federation!"); + } else { + if (onDiskPath.endsWith(".war")) { + uiWebAppContext.setWar(onDiskPath); + LOG.info("Using war file at: {}.", onDiskPath); + } else { + uiWebAppContext.setResourceBase(onDiskPath); + LOG.info("Using webapps at: {}.", onDiskPath); + } + } + } + return uiWebAppContext; + } + + private String getWebAppsPath(String appName) { + URL url = getClass().getClassLoader().getResource("webapps/" + appName); + if (url == null) { + return ""; + } + return url.toString(); } public static String getProxyHostAndPort(Configuration conf) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/TestRouter.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/TestRouter.java index 2bc202f618..5fb5e045e6 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/TestRouter.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/TestRouter.java @@ -143,7 +143,7 @@ public void testRouterSupportCrossOrigin() throws ServletException, IOException WebAppContext webAppContext = httpServer2.getWebAppContext(); ServletHandler servletHandler = webAppContext.getServletHandler(); FilterHolder holder = servletHandler.getFilter("Cross Origin Filter"); - CrossOriginFilter filter = CrossOriginFilter.class.cast(holder.getFilter()); + CrossOriginFilter filter = (CrossOriginFilter) holder.getFilter(); // 1. Simulate [example.com] for access HttpServletRequest mockReq = Mockito.mock(HttpServletRequest.class);