diff --git a/core/src/main/scala/org/apache/spark/deploy/history/HistoryPage.scala b/core/src/main/scala/org/apache/spark/deploy/history/HistoryPage.scala index b347cb3be69f7a5feaa05c0b1791f12f731bfdd4..642d71b18c9e2bbd32f3b74a28153bddc9a88a5a 100644 --- a/core/src/main/scala/org/apache/spark/deploy/history/HistoryPage.scala +++ b/core/src/main/scala/org/apache/spark/deploy/history/HistoryPage.scala @@ -161,7 +161,7 @@ private[history] class HistoryPage(parent: HistoryServer) extends WebUIPage("") info: ApplicationHistoryInfo, attempt: ApplicationAttemptInfo, isFirst: Boolean): Seq[Node] = { - val uiAddress = HistoryServer.getAttemptURI(info.id, attempt.attemptId) + val uiAddress = UIUtils.prependBaseUri(HistoryServer.getAttemptURI(info.id, attempt.attemptId)) val startTime = UIUtils.formatDate(attempt.startTime) val endTime = if (attempt.endTime > 0) UIUtils.formatDate(attempt.endTime) else "-" val duration = @@ -190,8 +190,7 @@ private[history] class HistoryPage(parent: HistoryServer) extends WebUIPage("") { if (renderAttemptIdColumn) { if (info.attempts.size > 1 && attempt.attemptId.isDefined) { - <td><a href={HistoryServer.getAttemptURI(info.id, attempt.attemptId)}> - {attempt.attemptId.get}</a></td> + <td><a href={uiAddress}>{attempt.attemptId.get}</a></td> } else { <td> </td> } @@ -218,9 +217,9 @@ private[history] class HistoryPage(parent: HistoryServer) extends WebUIPage("") } private def makePageLink(linkPage: Int, showIncomplete: Boolean): String = { - "/?" + Array( + UIUtils.prependBaseUri("/?" + Array( "page=" + linkPage, "showIncomplete=" + showIncomplete - ).mkString("&") + ).mkString("&")) } } diff --git a/core/src/test/scala/org/apache/spark/deploy/history/HistoryServerSuite.scala b/core/src/test/scala/org/apache/spark/deploy/history/HistoryServerSuite.scala index e5b5e1bb6533794fbf6428d7340de031e1bc5bcc..4b7fd4f13b6924fe422d65ec668a378efeefd02f 100644 --- a/core/src/test/scala/org/apache/spark/deploy/history/HistoryServerSuite.scala +++ b/core/src/test/scala/org/apache/spark/deploy/history/HistoryServerSuite.scala @@ -29,7 +29,7 @@ import org.scalatest.{BeforeAndAfter, Matchers} import org.scalatest.mock.MockitoSugar import org.apache.spark.{JsonTestUtils, SecurityManager, SparkConf, SparkFunSuite} -import org.apache.spark.ui.SparkUI +import org.apache.spark.ui.{SparkUI, UIUtils} /** * A collection of tests against the historyserver, including comparing responses from the json @@ -261,7 +261,24 @@ class HistoryServerSuite extends SparkFunSuite with BeforeAndAfter with Matchers l <- links attrs <- l.attribute("href") } yield (attrs.toString) - justHrefs should contain(link) + justHrefs should contain (UIUtils.prependBaseUri(resource = link)) + } + + test("relative links are prefixed with uiRoot (spark.ui.proxyBase)") { + val proxyBaseBeforeTest = System.getProperty("spark.ui.proxyBase") + val uiRoot = Option(System.getenv("APPLICATION_WEB_PROXY_BASE")).getOrElse("/testwebproxybase") + val page = new HistoryPage(server) + val request = mock[HttpServletRequest] + + // when + System.setProperty("spark.ui.proxyBase", uiRoot) + val response = page.render(request) + System.setProperty("spark.ui.proxyBase", Option(proxyBaseBeforeTest).getOrElse("")) + + // then + val urls = response \\ "@href" map (_.toString) + val siteRelativeLinks = urls filter (_.startsWith("/")) + all (siteRelativeLinks) should startWith (uiRoot) } def getContentAndCode(path: String, port: Int = port): (Int, Option[String], Option[String]) = {