Make hystrix dashboard work with a context path
I didn't see a way to do this without dynamic rendering, so now we have a freemarker dependency (not huge I guess). Fixes gh-51
This commit is contained in:
@@ -10,11 +10,13 @@ import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.configuration.ConfigurationBuilder;
|
||||
import org.apache.commons.configuration.EnvironmentConfiguration;
|
||||
import org.apache.commons.configuration.SystemConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
@@ -27,6 +29,7 @@ import com.netflix.config.DynamicURLConfiguration;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ConcurrentCompositeConfiguration.class, ConfigurationBuilder.class})
|
||||
public class ArchaiusAutoConfiguration {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ArchaiusAutoConfiguration.class);
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
@@ -28,10 +32,6 @@
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
@@ -48,5 +48,10 @@
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>d3js</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -37,6 +37,11 @@ public class HystrixDashboardConfiguration {
|
||||
return new ServletRegistrationBean(new ProxyStreamServlet(), "/proxy.stream");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HystrixDashboardController hsytrixDashboardController() {
|
||||
return new HystrixDashboardController();
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy an EventStream request (data.stream via proxy.stream) since EventStream does not yet support CORS (https://bugs.webkit.org/show_bug.cgi?id=61862)
|
||||
* so that a UI can request a stream from a different server.
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.cloud.netflix.hystrix.dashboard;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
public class HystrixDashboardController {
|
||||
|
||||
@RequestMapping("/hystrix")
|
||||
public String home(Model model, WebRequest request) {
|
||||
model.addAttribute("basePath", extractPath(request));
|
||||
return "index";
|
||||
}
|
||||
|
||||
@RequestMapping("/hystrix/monitor")
|
||||
public String monitor(Model model, WebRequest request) {
|
||||
model.addAttribute("basePath", extractPath(request));
|
||||
model.addAttribute("contextPath", request.getContextPath());
|
||||
return "monitor";
|
||||
}
|
||||
|
||||
private String extractPath(WebRequest request) {
|
||||
String path = request.getContextPath()
|
||||
+ (String) request
|
||||
.getAttribute(
|
||||
"org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping",
|
||||
WebRequest.SCOPE_REQUEST);
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,10 +2,10 @@
|
||||
(function(window) {
|
||||
|
||||
// cache the templates we use on this page as global variables (asynchronously)
|
||||
jQuery.get(getRelativePath("../components/hystrixCommand/templates/hystrixCircuit.html"), function(data) {
|
||||
jQuery.get(getRelativePath("components/hystrixCommand/templates/hystrixCircuit.html"), function(data) {
|
||||
hystrixTemplateCircuit = data;
|
||||
});
|
||||
jQuery.get(getRelativePath("../components/hystrixCommand/templates/hystrixCircuitContainer.html"), function(data) {
|
||||
jQuery.get(getRelativePath("components/hystrixCommand/templates/hystrixCircuitContainer.html"), function(data) {
|
||||
hystrixTemplateCircuitContainer = data;
|
||||
});
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
(function(window) {
|
||||
|
||||
// cache the templates we use on this page as global variables (asynchronously)
|
||||
jQuery.get(getRelativePath("../components/hystrixThreadPool/templates/hystrixThreadPool.html"), function(data) {
|
||||
jQuery.get(getRelativePath("components/hystrixThreadPool/templates/hystrixThreadPool.html"), function(data) {
|
||||
htmlTemplate = data;
|
||||
});
|
||||
jQuery.get(getRelativePath("../components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html"), function(data) {
|
||||
jQuery.get(getRelativePath("components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html"), function(data) {
|
||||
htmlTemplateContainer = data;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<base href="${basePath}">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Hystrix Dashboard</title>
|
||||
|
||||
<!-- Javascript to monitor and display -->
|
||||
<script src="/webjars/jquery/2.1.1/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="webjars/jquery/2.1.1/jquery.min.js" type="text/javascript"></script>
|
||||
|
||||
<script>
|
||||
function sendToMonitor() {
|
||||
|
||||
if($('#stream').val().length > 0) {
|
||||
var url = "/hystrix/monitor/monitor.html?stream=" + encodeURIComponent($('#stream').val()) + "";
|
||||
var url = "hystrix/monitor?stream=" + encodeURIComponent($('#stream').val()) + "";
|
||||
if($('#delay').val().length > 0) {
|
||||
url += "&delay=" + $('#delay').val();
|
||||
}
|
||||
@@ -1,31 +1,32 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<base href="${basePath}">
|
||||
<meta charset="utf-8" />
|
||||
<title>Hystrix Monitor</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<!-- Setup base for everything -->
|
||||
<link rel="stylesheet" type="text/css" href="../css/global.css" />
|
||||
<link rel="stylesheet" type="text/css" href="css/global.css" />
|
||||
|
||||
<!-- Our custom CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="monitor.css" />
|
||||
<link rel="stylesheet" type="text/css" href="css/monitor.css" />
|
||||
|
||||
<!-- d3 -->
|
||||
<script type="text/javascript" src="/webjars/d3js/3.4.11/d3.min.js" ></script>
|
||||
<script type="text/javascript" src="../webjars/d3js/3.4.11/d3.min.js" ></script>
|
||||
|
||||
<!-- Javascript to monitor and display -->
|
||||
<script type="text/javascript" src="/webjars/jquery/2.1.1/jquery.min.js" ></script>
|
||||
<script type="text/javascript" src="../js/jquery.tinysort.min.js"></script>
|
||||
<script type="text/javascript" src="../js/tmpl.js"></script>
|
||||
<script type="text/javascript" src="../webjars/jquery/2.1.1/jquery.min.js" ></script>
|
||||
<script type="text/javascript" src="js/jquery.tinysort.min.js"></script>
|
||||
<script type="text/javascript" src="js/tmpl.js"></script>
|
||||
|
||||
<!-- HystrixCommand -->
|
||||
<script type="text/javascript" src="../components/hystrixCommand/hystrixCommand.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../components/hystrixCommand/hystrixCommand.css" />
|
||||
<script type="text/javascript" src="components/hystrixCommand/hystrixCommand.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="components/hystrixCommand/hystrixCommand.css" />
|
||||
|
||||
<!-- HystrixThreadPool -->
|
||||
<script type="text/javascript" src="../components/hystrixThreadPool/hystrixThreadPool.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../components/hystrixThreadPool/hystrixThreadPool.css" />
|
||||
<script type="text/javascript" src="components/hystrixThreadPool/hystrixThreadPool.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="components/hystrixThreadPool/hystrixThreadPool.css" />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
@@ -96,8 +97,8 @@
|
||||
stream = stream + "&delay=" + getUrlVars()["delay"];
|
||||
}
|
||||
|
||||
var commandStream = "/proxy.stream?origin=" + stream;
|
||||
var poolStream = "/proxy.stream?origin=" + stream;
|
||||
var commandStream = "${contextPath}/proxy.stream?origin=" + stream;
|
||||
var poolStream = "${contextPath}/proxy.stream?origin=" + stream;
|
||||
|
||||
if(getUrlVars()["title"] != undefined) {
|
||||
$('#title_name').html("Hystrix Stream: " + decodeURIComponent(getUrlVars()["title"]))
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.cloud.netflix.hystrix.dashboard;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
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.hystrix.dashboard.HystrixDashboardContextTests.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;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest({ "server.port=0", "spring.application.name=hystrix-dashboard", "server.contextPath=/context" })
|
||||
public class HystrixDashboardContextTests {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
|
||||
@Test
|
||||
public void homePage() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + port + "/context/hystrix", String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cssAvailable() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + port + "/context/hystrix/css/global.css", String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void webjarsAvailable() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + port + "/context/webjars/jquery/2.1.1/jquery.min.js", String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void monitorPage() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + port + "/context/hystrix/monitor", String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableHystrixDashboard
|
||||
protected static class Application {
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=hystrix-dashboard", "server.contextPath=/context").run();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.cloud.netflix.hystrix.dashboard;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
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.hystrix.dashboard.HystrixDashboardTests.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;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest({ "server.port=0", "spring.application.name=hystrix-dashboard" })
|
||||
public class HystrixDashboardTests {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
|
||||
@Test
|
||||
public void homePage() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + port + "/hystrix", String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cssAvailable() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + port + "/hystrix/css/global.css", String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void monitorPage() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + port + "/hystrix/monitor", String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableHystrixDashboard
|
||||
protected static class Application {
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=hystrix-dashboard").run();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user