Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different actuator management server port changes response on errors #21036

Closed
maiksensi opened this issue Apr 20, 2020 · 3 comments
Closed

Different actuator management server port changes response on errors #21036

maiksensi opened this issue Apr 20, 2020 · 3 comments
Assignees
Labels
type: blocker An issue that is blocking us from releasing type: bug A general bug
Milestone

Comments

@maiksensi
Copy link

maiksensi commented Apr 20, 2020

In our plugin Chaos Monkey For Spring Boot, we are experiencing a strange problem, regarding different ports of the management server.
If we change the default management port then the error messages change. Inputs to our Actuator REST API are @Validated (in this case against min/max).

Port different via management.server.port:
https://i.stack.imgur.com/ozRYN.png

Request:

echo  '{"level": -2}' | curl -X POST -H "Content-Type: application/json" -d @- http://localhost:8888/actuator/chaosmonkey/assaults

Response:

{
    "timestamp": "2020-04-20T13:18:40.267+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "No message available",
    "path": "/actuator/chaosmonkey/assaults"
}

Same port as application:
https://i.stack.imgur.com/cAoNf.png

Request:

echo  '{"level": -2}' | curl -X POST -H "Content-Type: application/json" -d @- http://localhost:8080/actuator/chaosmonkey/assaults

Response:

{
    "timestamp": "2020-04-20T13:15:47.652+0000",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "Min.assaultPropertiesUpdate.level",
                "Min.level",
                "Min.java.lang.Integer",
                "Min"
            ],
            "arguments": [
                {
                    "codes": [
                        "assaultPropertiesUpdate.level",
                        "level"
                    ],
                    "arguments": null,
                    "defaultMessage": "level",
                    "code": "level"
                },
                1
            ],
            "defaultMessage": "must be greater than or equal to 1",
            "objectName": "assaultPropertiesUpdate",
            "field": "level",
            "rejectedValue": -2,
            "bindingFailure": false,
            "code": "Min"
        }
    ],
    "message": "Validation failed for object='assaultPropertiesUpdate'. Error count: 1",
    "trace": "org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<?> de.codecentric.spring.boot.chaos.monkey.endpoints.ChaosMonkeyRestEndpoint.updateAssaultProperties(de.codecentric.spring.boot.chaos.monkey.endpoints.AssaultPropertiesUpdate): [Field error in object 'assaultPropertiesUpdate' on field 'level': rejected value [-2]; codes [Min.assaultPropertiesUpdate.level,Min.level,Min.java.lang.Integer,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [assaultPropertiesUpdate.level,level]; arguments []; default message [level],1]; default message [must be greater than or equal to 1]] \n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:138)\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:127)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:660)\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:741)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:88)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:114)\n\tat org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:104)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n\tat java.base/java.lang.Thread.run(Thread.java:834)\n",
    "path": "/actuator/chaosmonkey/assaults"
}

We're guessing that this might be related to: #10560 where the HTTP status code was fixed to be the same in both cases.

I am not 100 % sure this is a bug, or whether this is the intended behavior. We also asked on Stackoverflow (https://stackoverflow.com/questions/61267877/different-actuator-management-server-port-changes-http-response) for any ideas on how to get around the different messages (without too much customization on our side), because we would like to supply our plugin users always the same error message. We would prefer the second, descriptive error message.

Maybe good to know, we did not apply any custom filters in Chaos Monkey for Spring Boot.

Please let me know if there's anything we can do to help.

Spring Version: 2.2.6.RELEASE
Chaos Monkey For Spring Boot also needs the appropriate spring-boot-starter-web

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 20, 2020
@scottfrederick scottfrederick self-assigned this May 4, 2020
@scottfrederick
Copy link
Contributor

I've confirmed this with 2.2.6.

When the application port and management port are the same, all errors are handled by a Controller and run through DispatcherServlet. The DefaultHandlerExceptionResolver resolves the exception to an empty ModelAndView, then DispatcherServlet stores the exception in the request so that the error handler can later retrieve it.

When the management port is different from the application port, actuator exceptions go through a different path. DefaultHandlerExceptionResolver resolves the exception in the same way, but after that it is handled by CompositeHandlerExceptionResolver, which just returns the empty ModelAndView. The result is that the exception is lost in this path.

@scottfrederick scottfrederick added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels May 4, 2020
@scottfrederick scottfrederick added this to the 2.2.x milestone May 4, 2020
@wilkinsona wilkinsona modified the milestones: 2.2.x, 2.2.8 May 12, 2020
@scottfrederick scottfrederick modified the milestones: 2.2.8, 2.3.0 May 12, 2020
@wilkinsona
Copy link
Member

I think this has caused the regression reported in #21591. 2.2.8 hasn't shipped yet so the 2.2.x regression's only in snapshots. Re-opening so we can address it before 2.2.8 is released.

@wilkinsona wilkinsona reopened this Jun 2, 2020
@wilkinsona
Copy link
Member

We now set the javax.servlet.error.exception attribute on the request:

This attribute is found by Tomcat and results in a 500 response being sent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: blocker An issue that is blocking us from releasing type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants