Skip to content

Commit

Permalink
Add support for additional paths for HomepageForwardingFilterConfig
Browse files Browse the repository at this point in the history
  • Loading branch information
genuss committed Oct 9, 2022
1 parent f865a09 commit 77c1641
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -85,8 +86,9 @@ public AdminServerUiAutoConfiguration(AdminServerUiProperties adminUi, AdminServ
public UiController homeUiController(UiExtensions uiExtensions) throws IOException {
List<String> extensionRoutes = new UiRoutesScanner(this.applicationContext)
.scan(this.adminUi.getExtensionResourceLocations());
List<String> routes = Stream.concat(DEFAULT_UI_ROUTES.stream(), extensionRoutes.stream())
.collect(Collectors.toList());
List<String> routes = Stream
.of(DEFAULT_UI_ROUTES.stream(), extensionRoutes.stream(), this.adminUi.getAdditionalRoutes().stream())
.flatMap(Function.identity()).collect(Collectors.toList());

Settings uiSettings = Settings.builder().brand(this.adminUi.getBrand()).title(this.adminUi.getTitle())
.loginIcon(this.adminUi.getLoginIcon()).favicon(this.adminUi.getFavicon())
Expand Down Expand Up @@ -155,12 +157,15 @@ public HomepageForwardingFilterConfig homepageForwardingFilterConfig() throws IO

List<String> extensionRoutes = new UiRoutesScanner(this.applicationContext)
.scan(this.adminUi.getExtensionResourceLocations());
List<String> routesIncludes = Stream.concat(DEFAULT_UI_ROUTES.stream(), extensionRoutes.stream())
.map(this.adminServer::path).collect(Collectors.toList());
List<String> routesIncludes = Stream
.of(DEFAULT_UI_ROUTES.stream(), extensionRoutes.stream(),
this.adminUi.getAdditionalRoutes().stream())
.flatMap(Function.identity()).map(this.adminServer::path).collect(Collectors.toList());
routesIncludes.add("");

List<String> routesExcludes = DEFAULT_UI_ROUTE_EXCLUDES.stream().map(this.adminServer::path)
.collect(Collectors.toList());
List<String> routesExcludes = Stream
.concat(DEFAULT_UI_ROUTE_EXCLUDES.stream(), this.adminUi.getAdditionalRouteExcludes().stream())
.map(this.adminServer::path).collect(Collectors.toList());

return new HomepageForwardingFilterConfig(homepage, routesIncludes, routesExcludes);
}
Expand Down Expand Up @@ -213,10 +218,13 @@ public HomepageForwardingFilterConfig homepageForwardingFilterConfig() throws IO

List<String> extensionRoutes = new UiRoutesScanner(this.applicationContext)
.scan(this.adminUi.getExtensionResourceLocations());
List<String> routesIncludes = Stream.concat(DEFAULT_UI_ROUTES.stream(), extensionRoutes.stream())
List<String> routesIncludes = Stream
.of(DEFAULT_UI_ROUTES.stream(), this.adminUi.getAdditionalRoutes().stream(),
extensionRoutes.stream())
.flatMap(Function.identity()).map(this.adminServer::path).collect(Collectors.toList());
List<String> routesExcludes = Stream
.concat(DEFAULT_UI_ROUTE_EXCLUDES.stream(), this.adminUi.getAdditionalRouteExcludes().stream())
.map(this.adminServer::path).collect(Collectors.toList());
List<String> routesExcludes = DEFAULT_UI_ROUTE_EXCLUDES.stream().map(this.adminServer::path)
.collect(Collectors.toList());

return new HomepageForwardingFilterConfig(homepage, routesIncludes, routesExcludes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ public class AdminServerUiProperties {

private PollTimer pollTimer = new PollTimer();

/**
* Additional routes for home page redirecting filter. Any request to these routes
* will be redirected to home page internally
*/
private List<String> additionalRoutes = new ArrayList<>();

/**
* Additional routes to exclude from home page redirecting filter. Requests to these
* routes will not redirected to home page
*/
private List<String> additionalRouteExcludes = new ArrayList<>();

@lombok.Data
public static class PollTimer {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@
import de.codecentric.boot.admin.server.ui.web.reactive.HomepageForwardingFilter;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atMostOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

@ExtendWith(MockitoExtension.class)
Expand All @@ -58,7 +58,9 @@ public class AdminServerUiAutoConfigurationTest implements WithAssertions {
public class ReactiveUiConfigurationTest {

private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
.withPropertyValues("--spring.boot.admin.ui.available-languages=de", "--spring.webflux.base-path=test")
.withPropertyValues("--spring.boot.admin.ui.available-languages=de", "--spring.webflux.base-path=test",
"--spring.boot.admin.contextPath=test", "--spring.boot.admin.ui.additional-routes[0]=/info/**",
"--spring.boot.admin.ui.additional-route-excludes[0]=/instances/*/actuator/some-extension/**")
.withBean(AdminServerProperties.class).withBean(WebFluxProperties.class)
.withConfiguration(AutoConfigurations.of(AdminServerUiAutoConfiguration.class));

Expand All @@ -67,7 +69,7 @@ public class ReactiveUiConfigurationTest {

@ParameterizedTest
@CsvSource({ "/test/extensions/myextension", "/test/instances/1/actuator/heapdump",
"/test/instances/1/actuator/logfile" })
"/test/instances/1/actuator/logfile", "/test/instances/1/actuator/some-extension/file.html" })
public void contextPathIsRespectedInExcludedRoutes(String routeExcludes) {
MockServerHttpRequest serverHttpRequest = MockServerHttpRequest.get(routeExcludes)
.header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML_VALUE).build();
Expand All @@ -85,7 +87,7 @@ public void contextPathIsRespectedInExcludedRoutes(String routeExcludes) {

@ParameterizedTest
@CsvSource({ "/test/about", "/test/applications", "/test/instances", "/test/journal", "/test/wallboard",
"/test/external" })
"/test/external", "/test/info/something" })
public void contextPathIsRespectedInIncludedRoutes(String routeIncludes) {
MockServerHttpRequest serverHttpRequest = MockServerHttpRequest.get(routeIncludes)
.header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML_VALUE).build();
Expand All @@ -97,7 +99,7 @@ public void contextPathIsRespectedInIncludedRoutes(String routeIncludes) {
HomepageForwardingFilter bean = context.getBean(HomepageForwardingFilter.class);
bean.filter(serverWebExchange, webFilterChain);

verify(serverWebExchange, atMostOnce()).mutate();
verify(serverWebExchange, times(1)).mutate();
});
}

Expand All @@ -108,13 +110,14 @@ public class ServletUiConfiguration {

private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withPropertyValues("--spring.boot.admin.ui.available-languages=de",
"--spring.boot.admin.contextPath=test")
"--spring.boot.admin.contextPath=test", "--spring.boot.admin.ui.additional-routes[0]=/info/**",
"--spring.boot.admin.ui.additional-route-excludes[0]=/instances/*/actuator/some-extension/**")
.withBean(AdminServerProperties.class)
.withConfiguration(AutoConfigurations.of(AdminServerUiAutoConfiguration.class));

@ParameterizedTest
@CsvSource({ "/test/extensions/myextension", "/test/instances/1/actuator/heapdump",
"/test/instances/1/actuator/logfile" })
"/test/instances/1/actuator/logfile", "/test/instances/1/actuator/some-extension/file.html" })
public void contextPathIsRespectedInExcludedRoutes(String routeExcludes) {
MockHttpServletRequest httpServletRequest = spy(new MockHttpServletRequest("GET", routeExcludes));
httpServletRequest.addHeader(HttpHeaders.ACCEPT, MediaType.TEXT_HTML_VALUE);
Expand All @@ -131,7 +134,7 @@ public void contextPathIsRespectedInExcludedRoutes(String routeExcludes) {

@ParameterizedTest
@CsvSource({ "/test/about", "/test/applications", "/test/instances", "/test/journal", "/test/wallboard",
"/test/external" })
"/test/external", "/test/info/something" })
public void contextPathIsRespectedInIncludedRoutes(String routeIncludes) {
MockHttpServletRequest httpServletRequest = spy(new MockHttpServletRequest("GET", routeIncludes));
httpServletRequest.addHeader(HttpHeaders.ACCEPT, MediaType.TEXT_HTML_VALUE);
Expand All @@ -142,7 +145,7 @@ public void contextPathIsRespectedInIncludedRoutes(String routeIncludes) {
de.codecentric.boot.admin.server.ui.web.servlet.HomepageForwardingFilter.class);
bean.doFilter(httpServletRequest, new MockHttpServletResponse(), mock(FilterChain.class));

verify(httpServletRequest, atMostOnce()).getRequestDispatcher(any());
verify(httpServletRequest, times(1)).getRequestDispatcher(any());
});
}

Expand Down

0 comments on commit 77c1641

Please sign in to comment.