diff --git a/core/src/main/scala/org/apache/spark/ui/Page.scala b/core/src/main/scala/org/apache/spark/ui/Page.scala
deleted file mode 100644
index b2a069a37552d..0000000000000
--- a/core/src/main/scala/org/apache/spark/ui/Page.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.spark.ui
-
-private[spark] object Page extends Enumeration {
- val Stages, Storage, Environment, Executors = Value
-}
diff --git a/core/src/main/scala/org/apache/spark/ui/SparkUI.scala b/core/src/main/scala/org/apache/spark/ui/SparkUI.scala
index d8ea1b13362e3..c333dd3784bb7 100644
--- a/core/src/main/scala/org/apache/spark/ui/SparkUI.scala
+++ b/core/src/main/scala/org/apache/spark/ui/SparkUI.scala
@@ -55,8 +55,8 @@ private[spark] class SparkUI(
/** Initialize all components of the server. Must be called before bind(). */
def start() {
- attachTab(new BlockManagerTab(this))
attachTab(new JobProgressTab(this))
+ attachTab(new BlockManagerTab(this))
attachTab(new EnvironmentTab(this))
attachTab(new ExecutorsTab(this))
attachHandler(createStaticHandler(SparkUI.STATIC_RESOURCE_DIR, "/static"))
diff --git a/core/src/main/scala/org/apache/spark/ui/UIUtils.scala b/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
index de4216849dc7d..7cf16b5ed29b1 100644
--- a/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
+++ b/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
@@ -25,8 +25,6 @@ import scala.xml.Node
/** Utility functions for generating XML pages with spark content. */
private[spark] object UIUtils {
- import Page._
-
// SimpleDateFormat is not thread-safe. Don't expose it to avoid improper use.
private val dateFormat = new ThreadLocal[SimpleDateFormat]() {
override def initialValue(): SimpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
@@ -62,26 +60,13 @@ private[spark] object UIUtils {
basePath: String,
appName: String,
title: String,
- page: Page.Value) : Seq[Node] = {
- val jobs = page match {
- case Stages =>
-
Stages
- case _ => Stages
- }
- val storage = page match {
- case Storage =>
- Storage
- case _ => Storage
- }
- val environment = page match {
- case Environment =>
- Environment
- case _ => Environment
- }
- val executors = page match {
- case Executors =>
- Executors
- case _ => Executors
+ tabs: Seq[UITab],
+ activeTab: UITab) : Seq[Node] = {
+
+ val header = tabs.map { tab =>
+
+ {tab.name}
+
}
@@ -100,12 +85,7 @@ private[spark] object UIUtils {
-
- {jobs}
- {storage}
- {environment}
- {executors}
-
+
{appName} application UI
diff --git a/core/src/main/scala/org/apache/spark/ui/WebUI.scala b/core/src/main/scala/org/apache/spark/ui/WebUI.scala
index f20aec893c787..0b847a9a471f0 100644
--- a/core/src/main/scala/org/apache/spark/ui/WebUI.scala
+++ b/core/src/main/scala/org/apache/spark/ui/WebUI.scala
@@ -42,6 +42,10 @@ private[spark] abstract class WebUI(securityManager: SecurityManager, basePath:
protected val handlers = ArrayBuffer[ServletContextHandler]()
protected var serverInfo: Option[ServerInfo] = None
+ def getTabs: Seq[UITab] = tabs.toSeq
+ def getHandlers: Seq[ServletContextHandler] = handlers.toSeq
+ def getListeners: Seq[SparkListener] = tabs.flatMap(_.listener)
+
/** Attach a tab to this UI, along with all of its attached pages. Only valid before bind(). */
def attachTab(tab: UITab) {
tab.start()
@@ -65,12 +69,6 @@ private[spark] abstract class WebUI(securityManager: SecurityManager, basePath:
handlers += handler
}
- /** Return a list of listeners attached to this UI. */
- def getListeners = tabs.flatMap(_.listener)
-
- /** Return a list of handlers attached to this UI. */
- def getHandlers = handlers.toSeq
-
/** Initialize all components of the server. Must be called before bind(). */
def start()
@@ -98,6 +96,7 @@ private[spark] abstract class WebUI(securityManager: SecurityManager, basePath:
private[spark] abstract class UITab(val prefix: String) {
val pages = ArrayBuffer[UIPage]()
var listener: Option[SparkListener] = None
+ var name = prefix.capitalize
/** Attach a page to this tab. This prepends the page's prefix with the tab's own prefix. */
def attachPage(page: UIPage) {
diff --git a/core/src/main/scala/org/apache/spark/ui/env/EnvironmentTab.scala b/core/src/main/scala/org/apache/spark/ui/env/EnvironmentTab.scala
index ad355e59a37aa..6a2304f1ad42f 100644
--- a/core/src/main/scala/org/apache/spark/ui/env/EnvironmentTab.scala
+++ b/core/src/main/scala/org/apache/spark/ui/env/EnvironmentTab.scala
@@ -33,6 +33,8 @@ private[ui] class EnvironmentTab(parent: SparkUI) extends UITab("environment") {
assert(listener.isDefined, "EnvironmentTab has not started yet!")
listener.get.asInstanceOf[EnvironmentListener]
}
+
+ def headerTabs: Seq[UITab] = parent.getTabs
}
/**
diff --git a/core/src/main/scala/org/apache/spark/ui/env/IndexPage.scala b/core/src/main/scala/org/apache/spark/ui/env/IndexPage.scala
index bf1872f18d54e..bde672909bbcc 100644
--- a/core/src/main/scala/org/apache/spark/ui/env/IndexPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/env/IndexPage.scala
@@ -22,7 +22,6 @@ import javax.servlet.http.HttpServletRequest
import scala.xml.Node
import org.apache.spark.ui.{UIUtils, UIPage}
-import org.apache.spark.ui.Page.Environment
private[ui] class IndexPage(parent: EnvironmentTab) extends UIPage("") {
private val appName = parent.appName
@@ -46,7 +45,7 @@ private[ui] class IndexPage(parent: EnvironmentTab) extends UIPage("") {
Classpath Entries
{classpathEntriesTable}
- UIUtils.headerSparkPage(content, basePath, appName, "Environment", Environment)
+ UIUtils.headerSparkPage(content, basePath, appName, "Environment", parent.headerTabs, parent)
}
private def propertyHeader = Seq("Name", "Value")
diff --git a/core/src/main/scala/org/apache/spark/ui/exec/ExecutorsTab.scala b/core/src/main/scala/org/apache/spark/ui/exec/ExecutorsTab.scala
index 3941a1849b182..c1f5ca856ffe1 100644
--- a/core/src/main/scala/org/apache/spark/ui/exec/ExecutorsTab.scala
+++ b/core/src/main/scala/org/apache/spark/ui/exec/ExecutorsTab.scala
@@ -37,6 +37,8 @@ private[ui] class ExecutorsTab(parent: SparkUI) extends UITab("executors") {
assert(listener.isDefined, "ExecutorsTab has not started yet!")
listener.get.asInstanceOf[ExecutorsListener]
}
+
+ def headerTabs: Seq[UITab] = parent.getTabs
}
/**
diff --git a/core/src/main/scala/org/apache/spark/ui/exec/IndexPage.scala b/core/src/main/scala/org/apache/spark/ui/exec/IndexPage.scala
index 9a711d773ae01..1956b6c63929e 100644
--- a/core/src/main/scala/org/apache/spark/ui/exec/IndexPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/exec/IndexPage.scala
@@ -22,7 +22,6 @@ import javax.servlet.http.HttpServletRequest
import scala.xml.Node
import org.apache.spark.ui.{UIPage, UIUtils}
-import org.apache.spark.ui.Page.Executors
import org.apache.spark.util.Utils
private[ui] class IndexPage(parent: ExecutorsTab) extends UIPage("") {
@@ -56,8 +55,8 @@ private[ui] class IndexPage(parent: ExecutorsTab) extends UIPage("") {
;
- UIUtils.headerSparkPage(
- content, basePath, appName, "Executors (" + execInfo.size + ")", Executors)
+ UIUtils.headerSparkPage(content, basePath, appName, "Executors (" + execInfo.size + ")",
+ parent.headerTabs, parent)
}
/** Header fields for the executors table */
diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/IndexPage.scala b/core/src/main/scala/org/apache/spark/ui/jobs/IndexPage.scala
index 5c752793d2342..2b54603af104e 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/IndexPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/IndexPage.scala
@@ -23,7 +23,6 @@ import scala.xml.{Node, NodeSeq}
import org.apache.spark.scheduler.Schedulable
import org.apache.spark.ui.{UIPage, UIUtils}
-import org.apache.spark.ui.Page.Stages
/** Page showing list of all ongoing and recently finished stages and pools */
private[ui] class IndexPage(parent: JobProgressTab) extends UIPage("") {
@@ -92,7 +91,7 @@ private[ui] class IndexPage(parent: JobProgressTab) extends UIPage("") {
Failed Stages ({failedStages.size})
++
failedStagesTable.toNodeSeq
- UIUtils.headerSparkPage(content, basePath, appName, "Spark Stages", Stages)
+ UIUtils.headerSparkPage(content, basePath, appName, "Spark Stages", parent.headerTabs, parent)
}
}
}
diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/JobProgressTab.scala b/core/src/main/scala/org/apache/spark/ui/jobs/JobProgressTab.scala
index 611febe10c1aa..93d26f7dd3632 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/JobProgressTab.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/JobProgressTab.scala
@@ -42,4 +42,6 @@ private[ui] class JobProgressTab(parent: SparkUI) extends UITab("stages") {
}
def isFairScheduler = jobProgressListener.schedulingMode.exists(_ == SchedulingMode.FAIR)
+
+ def headerTabs: Seq[UITab] = parent.getTabs
}
diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/PoolPage.scala b/core/src/main/scala/org/apache/spark/ui/jobs/PoolPage.scala
index 9382251d6e612..7fffe2affb0f2 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/PoolPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/PoolPage.scala
@@ -23,7 +23,6 @@ import scala.xml.Node
import org.apache.spark.scheduler.{Schedulable, StageInfo}
import org.apache.spark.ui.{UIPage, UIUtils}
-import org.apache.spark.ui.Page.Stages
/** Page showing specific pool details */
private[ui] class PoolPage(parent: JobProgressTab) extends UIPage("pool") {
@@ -51,8 +50,8 @@ private[ui] class PoolPage(parent: JobProgressTab) extends UIPage("pool") {
Summary
++ poolTable.toNodeSeq ++
{activeStages.size} Active Stages
++ activeStagesTable.toNodeSeq
- UIUtils.headerSparkPage(
- content, basePath, appName, "Fair Scheduler Pool: " + poolName, Stages)
+ UIUtils.headerSparkPage(content, basePath, appName, "Fair Scheduler Pool: " + poolName,
+ parent.headerTabs, parent)
}
}
}
diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala b/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
index a4f6e5d69c515..372210919cd91 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
@@ -23,7 +23,6 @@ import javax.servlet.http.HttpServletRequest
import scala.xml.Node
import org.apache.spark.ui.{UIPage, UIUtils}
-import org.apache.spark.ui.Page.Stages
import org.apache.spark.util.{Utils, Distribution}
/** Page showing statistics and task list for a given stage */
@@ -42,8 +41,8 @@ private[ui] class StagePage(parent: JobProgressTab) extends UIPage("stage") {
Summary Metrics
No tasks have started yet
Tasks
No tasks have started yet
- return UIUtils.headerSparkPage(
- content, basePath, appName, "Details for Stage %s".format(stageId), Stages)
+ return UIUtils.headerSparkPage(content, basePath, appName,
+ "Details for Stage %s".format(stageId), parent.headerTabs, parent)
}
val tasks = listener.stageIdToTaskData(stageId).values.toSeq.sortBy(_.taskInfo.launchTime)
@@ -204,8 +203,8 @@ private[ui] class StagePage(parent: JobProgressTab) extends UIPage("stage") {
Aggregated Metrics by Executor
++ executorTable.toNodeSeq ++
Tasks
++ taskTable
- UIUtils.headerSparkPage(
- content, basePath, appName, "Details for Stage %d".format(stageId), Stages)
+ UIUtils.headerSparkPage(content, basePath, appName, "Details for Stage %d".format(stageId),
+ parent.headerTabs, parent)
}
}
diff --git a/core/src/main/scala/org/apache/spark/ui/storage/BlockManagerTab.scala b/core/src/main/scala/org/apache/spark/ui/storage/BlockManagerTab.scala
index 2b9cf35fcde55..ac83f71ed31de 100644
--- a/core/src/main/scala/org/apache/spark/ui/storage/BlockManagerTab.scala
+++ b/core/src/main/scala/org/apache/spark/ui/storage/BlockManagerTab.scala
@@ -38,6 +38,8 @@ private[ui] class BlockManagerTab(parent: SparkUI) extends UITab("storage") {
assert(listener.isDefined, "BlockManagerTab has not started yet!")
listener.get.asInstanceOf[BlockManagerListener]
}
+
+ def headerTabs: Seq[UITab] = parent.getTabs
}
/**
diff --git a/core/src/main/scala/org/apache/spark/ui/storage/IndexPage.scala b/core/src/main/scala/org/apache/spark/ui/storage/IndexPage.scala
index 7bfcf13c69c6b..96b08d07d48d2 100644
--- a/core/src/main/scala/org/apache/spark/ui/storage/IndexPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/storage/IndexPage.scala
@@ -23,7 +23,6 @@ import scala.xml.Node
import org.apache.spark.storage.RDDInfo
import org.apache.spark.ui.{UIPage, UIUtils}
-import org.apache.spark.ui.Page.Storage
import org.apache.spark.util.Utils
/** Page showing list of RDD's currently stored in the cluster */
@@ -35,7 +34,7 @@ private[ui] class IndexPage(parent: BlockManagerTab) extends UIPage("") {
override def render(request: HttpServletRequest): Seq[Node] = {
val rdds = listener.rddInfoList
val content = UIUtils.listingTable(rddHeader, rddRow, rdds)
- UIUtils.headerSparkPage(content, basePath, appName, "Storage ", Storage)
+ UIUtils.headerSparkPage(content, basePath, appName, "Storage ", parent.headerTabs, parent)
}
/** Header fields for the RDD table */
diff --git a/core/src/main/scala/org/apache/spark/ui/storage/RDDPage.scala b/core/src/main/scala/org/apache/spark/ui/storage/RDDPage.scala
index 35ccfd505a3ef..a65ba0a020bcd 100644
--- a/core/src/main/scala/org/apache/spark/ui/storage/RDDPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/storage/RDDPage.scala
@@ -23,7 +23,6 @@ import scala.xml.Node
import org.apache.spark.storage.{BlockId, BlockStatus, StorageStatus, StorageUtils}
import org.apache.spark.ui.{UIPage, UIUtils}
-import org.apache.spark.ui.Page.Storage
import org.apache.spark.util.Utils
/** Page showing storage details for a given RDD */
@@ -37,7 +36,8 @@ private[ui] class RddPage(parent: BlockManagerTab) extends UIPage("rdd") {
val storageStatusList = listener.storageStatusList
val rddInfo = listener.rddInfoList.find(_.id == rddId).getOrElse {
// Rather than crashing, render an "RDD Not Found" page
- return UIUtils.headerSparkPage(Seq[Node](), basePath, appName, "RDD Not Found", Storage)
+ return UIUtils.headerSparkPage(Seq[Node](), basePath, appName, "RDD Not Found",
+ parent.headerTabs, parent)
}
// Worker table
@@ -95,8 +95,8 @@ private[ui] class RddPage(parent: BlockManagerTab) extends UIPage("rdd") {
;
- UIUtils.headerSparkPage(
- content, basePath, appName, "RDD Storage Info for " + rddInfo.name, Storage)
+ UIUtils.headerSparkPage(content, basePath, appName, "RDD Storage Info for " + rddInfo.name,
+ parent.headerTabs, parent)
}
/** Header fields for the worker table */