Skip to content

Commit c09779a

Browse files
committed
Detect heapdump-endpoint via OPTIONS request
Since a HEAD request to the heapdump triggers a dump we need to test the availability of the heapdump endppoint via OPTIONS-request. To get this working we need to ensure that the OPTIONS-request are dispatched to the zuul servlet as this wasn't done prio to this commit adding the OptionsDispatchingZuulController.
1 parent 42985d1 commit c09779a

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

spring-boot-admin-server-ui/modules/applications/module.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ module.run(function ($rootScope, $state, $filter, $sce, $http, Notification, App
9292
if (!application.managementUrl || !application.statusInfo.status || application.statusInfo.status === 'OFFLINE') {
9393
return false;
9494
}
95-
return $http.head('api/applications/' + application.id + '/heapdump').then(function () {
96-
return true;
95+
return $http({ method: 'OPTIONS', url: 'api/applications/' + application.id + '/heapdump' }).then(function (response) {
96+
return response.headers('Allow') === 'GET,HEAD'; //Test the exact headers, in case the DispatcherServlet responses to the request for older boot-versions
9797
}).catch(function () {
9898
return false;
9999
});

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/config/RevereseZuulProxyConfiguration.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.cloud.netflix.zuul.filters.TraceProxyRequestHelper;
2929
import org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter;
3030
import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter;
31+
import org.springframework.cloud.netflix.zuul.web.ZuulController;
3132
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
3233
import org.springframework.context.ApplicationEvent;
3334
import org.springframework.context.ApplicationListener;
@@ -38,6 +39,7 @@
3839
import de.codecentric.boot.admin.event.RoutesOutdatedEvent;
3940
import de.codecentric.boot.admin.registry.ApplicationRegistry;
4041
import de.codecentric.boot.admin.zuul.ApplicationRouteLocator;
42+
import de.codecentric.boot.admin.zuul.OptionsDispatchingZuulController;
4143

4244
@Configuration
4345
@AutoConfigureAfter({ AdminServerWebConfiguration.class })
@@ -63,6 +65,12 @@ public ApplicationRouteLocator routeLocator() {
6365
adminServer.getContextPath() + "/api/applications/");
6466
}
6567

68+
@Bean
69+
@Override
70+
public ZuulController zuulController() {
71+
return new OptionsDispatchingZuulController();
72+
}
73+
6674
@Bean
6775
public ProxyRequestHelper proxyRequestHelper() {
6876
TraceProxyRequestHelper helper = new TraceProxyRequestHelper();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package de.codecentric.boot.admin.zuul;
17+
18+
import javax.servlet.http.HttpServletRequest;
19+
import javax.servlet.http.HttpServletResponse;
20+
import javax.servlet.http.HttpSession;
21+
22+
import org.springframework.cloud.netflix.zuul.web.ZuulController;
23+
import org.springframework.web.servlet.ModelAndView;
24+
import org.springframework.web.util.WebUtils;
25+
26+
/**
27+
* This Controller behaves like the original ZuulController except it forwads also the OPTIONS
28+
* request to Servlet instead of handling the request itself.
29+
*
30+
* @author Johannes Edmeier
31+
*/
32+
public class OptionsDispatchingZuulController extends ZuulController {
33+
34+
@Override
35+
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
36+
throws Exception {
37+
// Delegate to WebContentGenerator for checking and preparing.
38+
checkRequest(request);
39+
prepareResponse(response);
40+
41+
// Execute handleRequestInternal in synchronized block if required.
42+
if (this.isSynchronizeOnSession()) {
43+
HttpSession session = request.getSession(false);
44+
if (session != null) {
45+
Object mutex = WebUtils.getSessionMutex(session);
46+
synchronized (mutex) {
47+
return handleRequestInternal(request, response);
48+
}
49+
}
50+
}
51+
52+
return handleRequestInternal(request, response);
53+
}
54+
55+
}

0 commit comments

Comments
 (0)