Reputation: 39354
Background Information
I have a Spring Boot web application using Actuator for the production utilities.
The application works fine, and the management port works great. I can browse statistics, check health etc. I also enabled the remote shut-down endpoint, and it properly shows up in the localhost:{mgmt_port}/actuator list of endpoints.
My Problem
When I go to localhost:{mgmt_port}/shutdown though, I see:
<Map>
<timestamp>1453905900007</timestamp>
<status>500</status>
<error>Internal Server Error</error>
<exception>org.springframework.web.HttpRequestMethodNotSupportedException</exception>
<message>Request method 'GET' not supported</message>
<path>/shutdown</path>
</Map>
Useful Information
The whole application still seems to be running after hitting the shut-down link. I can still pull data from my custom application endpoints.
The management URL provided by Spring actuator also seems to still be running fine after hitting shut down.
Console Output Before Issue
10:01:42.496 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 8002 (http) 10:01:42.499 [main] INFO com.xyz.api.Main - Started Main in 5.956 seconds (JVM running for 6.381)
Console Output After Issue
10:03:29.090 [http-nio-8003-exec-1] INFO o.a.c.c.C.[Tomcat-1].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet' 10:03:29.090 [http-nio-8003-exec-1] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started 10:03:29.126 [http-nio-8003-exec-1] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 36 ms 10:03:29.151 [http-nio-8003-exec-1] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request method 'GET' not supported] with root cause org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:204) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:382) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:322) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:60) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:351) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcChildContextConfiguration$CompositeHandlerMapping.getHandler(EndpointWebMvcChildContextConfiguration.java:212) ~[spring-boot-actuator-1.3.2.RELEASE.jar!/:1.3.2.RELEASE] at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1120) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:932) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:860) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845) ~[spring-webmvc-4.2.4.RELEASE.jar!/:4.2.4.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) ~[tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_51] at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_51] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.30.jar!/:8.0.30] at java.lang.Thread.run(Unknown Source) [na:1.8.0_51]
Upvotes: 0
Views: 3251
Reputation: 39354
Answering my own question to help others in the future. I'm a chump... The /actuator
URL lists all available commands, and all of them work based on a GET
request.
The /shutdown
URL actually requires a HTTP POST
to be sent to it in order to activate it though. I didn't see this noted anywhere in the docs.
Sample CURL Command:
> curl -X POST http://hostname:8003/shutdown
Output Of Shutdown Command:
<SingletonMap><message>Shutting down, bye...</message></SingletonMap>
Upvotes: 3