Commit af1278a4 by Dave Syer

Ensure static resources load from relative paths

Most browsers support <base href="..."> these days and there was one already in statut.ftl (but not in navbar). Added a test that asserts the css is loadable as well. Fixes gh-55
parent e2e193ea
......@@ -6,16 +6,17 @@ import com.netflix.appinfo.DataCenterInfo;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.config.ConfigurationManager;
import com.netflix.discovery.shared.*;
import com.netflix.discovery.shared.Application;
import com.netflix.eureka.PeerAwareInstanceRegistry;
import com.netflix.eureka.cluster.PeerEurekaNode;
import com.netflix.eureka.resources.StatusResource;
import com.netflix.eureka.util.StatusInfo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletRequest;
import java.net.URI;
import java.util.*;
......@@ -69,7 +70,8 @@ public class EurekaController {
}
private void populateBase(HttpServletRequest request, Map<String, Object> model) {
String path = request.getContextPath();
String servletPath = request.getServletPath();
String path = request.getContextPath() + (servletPath==null ? "" : servletPath);
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
model.put("time", new Date());
......@@ -104,7 +106,7 @@ public class EurekaController {
for (PeerEurekaNode node : list) {
try {
URI uri = new URI(node.getServiceUrl());
String href = "http://" + uri.getHost() + ":" + uri.getPort() + request.getContextPath();
String href = node.getServiceUrl();
replicas.put(uri.getHost(), href);
} catch(Exception e) {
//ignore?
......
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/"><span></span></a>
<a class="navbar-brand" href="${basePath}"><span></span></a>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
......@@ -12,7 +12,7 @@
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/">Home</a>
<a href="${basePath}">Home</a>
</li>
<li>
<a href="lastn">Last 1000 since startup</a>
......
......@@ -4,8 +4,9 @@
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<base href="${basePath}">
<title>Eureka - Last N events</title>
<link rel="stylesheet" type="text/css" href="/eureka/css/wro.css">
<link rel="stylesheet" type="text/css" href="eureka/css/wro.css">
</head>
<body id="three">
......@@ -59,8 +60,8 @@
</div>
</div>
</div>
<script type="text/javascript" src="/webjars/jquery/2.1.1jquery-min.js" ></script>
<script type="text/javascript" src="/webjars/bootstrap/3.2.0/js/bootstrap.min.js" ></script>
<script type="text/javascript" src="webjars/jquery/2.1.1/jquery.min.js" ></script>
<script type="text/javascript" src="webjars/bootstrap/3.2.0/js/bootstrap.min.js" ></script>
<script type="text/javascript">
$(function () {
$('#myTab a:last').tab('show')
......
......@@ -11,7 +11,7 @@
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="/eureka/css/wro.css">
<link rel="stylesheet" href="eureka/css/wro.css">
</head>
......@@ -101,8 +101,8 @@
</tbody>
</table>
</div>
<script type="text/javascript" src="/webjars/jquery/2.1.1/jquery.min.js" ></script>
<script type="text/javascript" src="/webjars/bootstrap/3.2.0/js/bootstrap.min.js" ></script>
<script type="text/javascript" src="webjars/jquery/2.1.1/jquery.min.js" ></script>
<script type="text/javascript" src="webjars/bootstrap/3.2.0/js/bootstrap.min.js" ></script>
<script type="text/javascript">
$(document).ready(function() {
$('table.stripeable tr:odd').addClass('odd');
......
......@@ -8,7 +8,7 @@
}
.navbar a.navbar-brand {
background: url("images/spring-logo-xd.png") -1px -1px no-repeat;
background: url("../images/spring-logo-xd.png") -1px -1px no-repeat;
margin: 12px 0 6px;
width: 229px;
height: 46px;
......@@ -21,7 +21,7 @@
display: block;
width: 229px;
height: 46px;
background: url("images/spring-logo-xd.png") -1px -48px no-repeat;
background: url("../images/spring-logo-xd.png") -1px -48px no-repeat;
opacity: 0;
-moz-transition: opacity 0.12s ease-in-out;
-webkit-transition: opacity 0.12s ease-in-out;
......
......@@ -12,7 +12,7 @@
width: 148px;
height: 50px;
float: none;
background: url("images/spring-logo-xd-mobile.png") 0 center no-repeat;
background: url("../images/spring-logo-xd-mobile.png") 0 center no-repeat;
}
.homepage-billboard .homepage-subtitle {
......
@font-face {
font-family: 'varela_roundregular';
src: url('fonts/varela_round-webfont.eot');
src: url('fonts/varela_round-webfont.eot?#iefix') format('embedded-opentype'),
url('fonts/varela_round-webfont.woff') format('woff'),
url('fonts/varela_round-webfont.ttf') format('truetype'),
url('fonts/varela_round-webfont.svg#varela_roundregular') format('svg');
src: url('../fonts/varela_round-webfont.eot');
src: url('../fonts/varela_round-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/varela_round-webfont.woff') format('woff'),
url('../fonts/varela_round-webfont.ttf') format('truetype'),
url('../fonts/varela_round-webfont.svg#varela_roundregular') format('svg');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'montserratregular';
src: url('fonts/montserrat-webfont.eot');
src: url('fonts/montserrat-webfont.eot?#iefix') format('embedded-opentype'),
url('fonts/montserrat-webfont.woff') format('woff'),
url('fonts/montserrat-webfont.ttf') format('truetype'),
url('fonts/montserrat-webfont.svg#montserratregular') format('svg');
src: url('../fonts/montserrat-webfont.eot');
src: url('../fonts/montserrat-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/montserrat-webfont.woff') format('woff'),
url('../fonts/montserrat-webfont.ttf') format('truetype'),
url('../fonts/montserrat-webfont.svg#montserratregular') format('svg');
font-weight: normal;
font-style: normal;
}
......
package org.springframework.cloud.netflix.eureka.server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.cloud.netflix.eureka.server.ApplicationContextTests.Application;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest({ "server.port=0", "spring.application.name=eureka",
"server.contextPath=/context" })
public class ApplicationContextTests {
@Value("${local.server.port}")
private int port = 0;
@Configuration
@EnableAutoConfiguration
@EnableEurekaServer
protected static class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).properties(
"spring.application.name=eureka", "server.contextPath=/context").run(
args);
}
}
@Test
public void catalogLoads() {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
"http://localhost:" + port + "/context/eureka/apps", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
}
@Test
public void dashboardLoads() {
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
"http://localhost:" + port + "/context/", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
String body = entity.getBody();
// System.err.println(body);
assertTrue(body.contains("webjars/"));
assertTrue(body.contains("eureka/css"));
// The "DS Replicas"
assertTrue(body.contains("<a href=\"http://localhost:8761/eureka/\">localhost</a>"));
}
@Test
public void cssAvailable() {
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
"http://localhost:" + port + "/context/eureka/css/wro.css", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
}
@Test
public void adminLoads() {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
"http://localhost:" + port + "/context/env", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
}
}
package org.springframework.cloud.netflix.eureka.server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.cloud.netflix.eureka.server.ApplicationServletPathTests.Application;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest({ "server.port=0", "spring.application.name=eureka",
"server.servletPath=/servlet" })
public class ApplicationServletPathTests {
@Value("${local.server.port}")
private int port = 0;
@Configuration
@EnableAutoConfiguration
@EnableEurekaServer
protected static class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).properties(
"spring.application.name=eureka", "server.servletPath=/servlet").run(
args);
}
}
@Test
public void catalogLoads() {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
"http://localhost:" + port + "/eureka/apps", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
}
@Test
public void dashboardLoads() {
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
"http://localhost:" + port + "/servlet/", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
String body = entity.getBody();
// System.err.println(body);
assertTrue(body.contains("webjars/"));
assertTrue(body.contains("eureka/css"));
// The "DS Replicas"
assertTrue(body.contains("<a href=\"http://localhost:8761/eureka/\">localhost</a>"));
}
@Test
public void cssAvailable() {
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
"http://localhost:" + port + "/servlet/eureka/css/wro.css", String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
}
@Test
public void adminLoads() {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
"http://localhost:" + port + "/servlet/env", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
}
}
......@@ -22,7 +22,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest({ "server.port=0", "spring.application.name=eureka", "spring.jmx.enabled=true" })
@IntegrationTest({ "server.port=0", "spring.jmx.enabled=true" })
public class ApplicationTests {
@Value("${local.server.port}")
......@@ -34,8 +34,7 @@ public class ApplicationTests {
protected static class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).properties(
"spring.application.name=eureka", "management.contextPath=/admin")
.run(args);
"spring.application.name=eureka").run(args);
}
}
......
spring.application.name=eureka
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment