Commit 69b60f6d authored by Andy Wilkinson's avatar Andy Wilkinson

Remove HalJsonMvcEndpoint’s redirect and add links to both paths instead

Previously, HalJsonMvcEndpoint used a redirect to go from path/ to path.
When the actuator’s configured to use a custom context path this
redirect was leading to an infinite redirect loop.

This commit removes the redirect in favour of updating the controller
advice to apply the links to requests for path and path/.

Closes gh-4853
parent c4f756da
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
......@@ -196,8 +196,12 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
}
private boolean isActuatorEndpointPath(String path) {
return this.halJsonMvcEndpoint != null && (this.management.getContextPath()
+ this.halJsonMvcEndpoint.getPath()).equals(path);
if (this.halJsonMvcEndpoint != null) {
String toMatch = this.management.getContextPath()
+ this.halJsonMvcEndpoint.getPath();
return toMatch.equals(path) || (toMatch + "/").equals(path);
}
return false;
}
}
......
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
......@@ -87,11 +87,6 @@ public class HalJsonMvcEndpoint extends WebMvcConfigurerAdapter
return new ResourceSupport();
}
@RequestMapping(path = "/", produces = MediaType.APPLICATION_JSON_VALUE)
public String forward() {
return "redirect:" + this.managementServletContext.getContextPath() + this.path;
}
public void setPath(String path) {
this.path = path;
}
......
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
......@@ -39,7 +39,6 @@ import org.springframework.web.context.WebApplicationContext;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
......@@ -77,10 +76,9 @@ public class HalBrowserMvcEndpointManagementContextPathIntegrationTests {
}
@Test
public void redirectJson() throws Exception {
public void actuatorHomeWithTrailingSlashJson() throws Exception {
this.mockMvc.perform(get("/admin/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isFound())
.andExpect(header().string("location", "/admin"));
.andExpect(status().isOk()).andExpect(jsonPath("$._links").exists());
}
@Test
......
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
......@@ -97,6 +97,18 @@ public class HalBrowserMvcEndpointServerContextPathIntegrationTests {
entity.getBody().contains("\"_links\":"));
}
@Test
public void actuatorLinksWithTrailingSlash() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
ResponseEntity<String> entity = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/spring/actuator/", HttpMethod.GET,
new HttpEntity<Void>(null, headers), String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertTrue("Wrong body: " + entity.getBody(),
entity.getBody().contains("\"_links\":"));
}
@MinimalActuatorHypermediaApplication
@RestController
public static class SpringBootHypermediaApplication {
......
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
......@@ -75,6 +75,20 @@ public class HalBrowserMvcEndpointServerPortIntegrationTests {
entity.getBody().contains(":" + this.port));
}
@Test
public void linksWithTrailingSlash() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
ResponseEntity<String> entity = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/actuator/", HttpMethod.GET,
new HttpEntity<Void>(null, headers), String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertTrue("Wrong body: " + entity.getBody(),
entity.getBody().contains("\"_links\":"));
assertTrue("Wrong body: " + entity.getBody(),
entity.getBody().contains(":" + this.port));
}
@Test
public void browser() throws Exception {
HttpHeaders headers = new HttpHeaders();
......
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
......@@ -78,6 +78,13 @@ public class HalBrowserMvcEndpointVanillaIntegrationTests {
.andExpect(header().doesNotExist("cache-control"));
}
@Test
public void linksWithTrailingSlash() throws Exception {
this.mockMvc.perform(get("/actuator/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()).andExpect(jsonPath("$._links").exists())
.andExpect(header().doesNotExist("cache-control"));
}
@Test
public void browser() throws Exception {
MvcResult response = this.mockMvc
......
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