Browse Source

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
pull/4896/merge
Andy Wilkinson 10 years ago
parent
commit
69b60f6d8c
  1. 10
      spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java
  2. 7
      spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java
  3. 8
      spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java
  4. 14
      spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java
  5. 16
      spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerPortIntegrationTests.java
  6. 9
      spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointVanillaIntegrationTests.java

10
spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* 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 { @@ -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;
}
}

7
spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* 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 @@ -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;
}

8
spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* 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; @@ -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 { @@ -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

14
spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* 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 { @@ -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 {

16
spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerPortIntegrationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* 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 { @@ -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();

9
spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointVanillaIntegrationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* 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 { @@ -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

Loading…
Cancel
Save