EOFException with GZIP Compression - http-post

I enabled the GZIP compression for the REST API and during testing, I am getting an EOFException exception.
The Endpoint annotations are here:-
#POST
#Path("/")
#Consumes("application/json")
#Produces("application/json")
#GZIP
Even though I removed the #ZIP annotation still I am getting the same error.
The test case code is here:-
val compressedPayLoad = EntityBuilder.create()
.setText(jsonLoader.loadAsString("abc.json"))
.gzipCompress()
.build()
val req = HttpPost("$rootPath/").entity(compressedPayLoad).addAuthorization()
req.addHeader(HttpHeaders.CONTENT_ENCODING, "gzip")
req.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
val resp = execute(req)
assertEquals(200, resp.statusLine.statusCode)
I added the Provider classes in the METE-INF.services folder
org.jboss.resteasy.plugins.interceptors.GZIPDecodingInterceptor
org.jboss.resteasy.plugins.interceptors.GZIPEncodingInterceptor
org.jboss.resteasy.plugins.interceptors.AcceptEncodingGZIPFilter
During debugging I found the Interparator method called twice and My assumption is that stream is being consumed twice on the server-side, making it “empty” for the second consumer.
Note:- .addAuthorization() is our internal helper function.
The logs from the service are here:-
Interceptor Context: org.jboss.resteasy.core.interception.jaxrs.ServerReaderInterceptorContext, Method : proceed
DEBUG o.j.r.r.i18n ReaderInterceptor: org.jboss.resteasy.plugins.interceptors.GZIPDecodingInterceptor
DEBUG o.j.r.r.i18n Interceptor : org.jboss.resteasy.plugins.interceptors.GZIPDecodingInterceptor, Method : aroundReadFrom
DEBUG o.j.r.r.i18n Interceptor Context: org.jboss.resteasy.core.interception.jaxrs.ServerReaderInterceptorContext, Method : proceed
DEBUG o.j.r.r.i18n MessageBodyReader: org.jboss.resteasy.core.providerfactory.SortedKey
DEBUG o.j.r.r.i18n MessageBodyReader: org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider
DEBUG o.j.r.r.i18n Provider : org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider, Method : readFrom
DEBUG o.j.r.r.i18n Interceptor : org.jboss.resteasy.plugins.interceptors.GZIPDecodingInterceptor$FinishableGZIPInputStream, Method : read
DEBUG o.j.r.r.i18n Interceptor Context: org.jboss.resteasy.core.interception.jaxrs.ServerReaderInterceptorContext, Method : proceed
DEBUG o.j.r.r.i18n ReaderInterceptor: org.jboss.resteasy.plugins.interceptors.GZIPDecodingInterceptor
DEBUG o.j.r.r.i18n Interceptor : org.jboss.resteasy.plugins.interceptors.GZIPDecodingInterceptor, Method : aroundReadFrom
ERROR c.t.s.e.CatchAllExceptionMapper Unhandled exception
java.io.EOFException: null
Here we can see the aroundReadFrom method called twice. Is there anything that I am missing or anyone faced this issue before. Please help me with this.

Related

Prevent DispatcherServlet from logging endpoint in Spring Boot Actuator

I've turned off the Logging for an actuator endpoint, but DispatcherServlet (and RequestReponseBodyMethodProcessor) still log the mapping and response.
How can i prevent this logging for just this one endpoint? I've already turned them off
management.logging.level.org.springframework.boot.actuate.health=OFF
logging.level.org.springframework.boot.actuate.health=OFF
org.springframework.boot.actuate.health.Logger=OFF
but it still comes like this:
2020-05-06 17:14:01.545 DEBUG 58588 --- [nio-9095-exec-5] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/health]
2020-05-06 17:14:01.552 DEBUG 58588 --- [nio-9095-exec-5] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/health] is: -1
2020-05-06 17:14:01.848 DEBUG 58588 --- [nio-9095-exec-5] m.m.a.RequestResponseBodyMethodProcessor : Written [UP {}] as "application/vnd.spring-boot.actuator.v1+json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#144409aa]
2020-05-06 17:14:01.849 DEBUG 58588 --- [nio-9095-exec-5] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2020-05-06 17:14:01.849 DEBUG 58588 --- [nio-9095-exec-5] o.s.web.servlet.DispatcherServlet : Successfully completed request
Just set in application.properties log level to WARN
logging.level.org.springframework.web.servlet.DispatcherServlet=WARN
logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor=WARN
please check if this solves the issue
In annotation SpringBootApplication add exclude DispatcherServletAutoConfiguration class in main class.
#SpringBootApplication(exclude = { DispatcherServletAutoConfiguration.class })
reference :
Switch off DispatcherServlet on Spring Boot
If your goal is logging all the incoming HTTP requests, the solution is not enabling DEBUG logging level in the DispatcherServlet.
You can define a bean of type:
org.springframework.web.filter.CommonsRequestLoggingFilter
and override the method:
org.springframework.web.filter.CommonsRequestLoggingFilter.shouldLog(HttpServletRequest)
So you can decide which requests are logged or not.
Obviously, you must set the logging level of the filter to DEBUG:
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG
More info at Baeldubg site.
Just use the below in the .properties
logging.level.org.springframework.web=WARN
Sorry to necro a thread, but here's the answer I came up with:
Create a bean as below:
package com.package.your.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CommonsRequestLoggingFilter;
import javax.servlet.http.HttpServletRequest;
#Configuration
public class RequestLoggingFilterConfig {
#Bean
public CommonsRequestLoggingFilter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter() {
#Override
public void beforeRequest(HttpServletRequest request, String message) {
// Don't log any actuator endpoints
if (!request.getRequestURI().contains("actuator")) {
this.logger.debug(message);
}
}
#Override
public void afterRequest(HttpServletRequest request, String message) {
// Empty because it logs the same content as beforeRequest
}
};
filter.setBeforeMessagePrefix("");
filter.setBeforeMessageSuffix("");
filter.setIncludeClientInfo(true);
filter.setIncludeHeaders(true);
filter.setIncludePayload(true);
filter.setIncludeQueryString(true);
return filter;
}
}
Add the following to applications.properties instead of setting DispatcherServlet to debug:
logging.level.com.package.your.config.RequestLoggingFilterConfig=debug
This works beautifully as intended. Filtering is controlled by the if statement in the beforeRequest method.

Spring integration (IntegrationFlowContext): Dynamically registering new paths to same websocket server

I was trying to implement spring websocket solution with JavaDsl by following the link i.e https://github.com/joshlong/techtips/tree/master/examples/spring-integration-4.1-websockets-example
And I successfully tested it by subscribing to the path(i.e /messages) with my stomp client.
Next, I tried the same thing by registering the integration flow with IntegrationFlowContext.
It executed successfully on the server-side, but when I tried to make a request by my stomp client I received an exception of 404 not found.
While going through the logs , i found that previously the "AbstractHandlerMapping" was mapping to SockJsHttpRequestHandler and now it is mapping to ResourceHttpRequestHandler
With Spring-managed integration flow (Successful)
DEBUG [http-nio-8081-exec-1] o.s.c.l.LogFormatUtils: GET "/messages/websocket", parameters={}
DEBUG [http-nio-8081-exec-1] o.s.w.s.h.AbstractHandlerMapping: Mapped to org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler#46185a1b
DEBUG [http-nio-8081-exec-1] o.s.w.s.s.s.AbstractSockJsService: Processing transport request: GET http://localhost:8081/messages/websocket
DEBUG [http-nio-8081-exec-1] o.s.w.s.FrameworkServlet: Completed 101 SWITCHING_PROTOCOLS
DEBUG [http-nio-8081-exec-1] o.s.w.s.h.LoggingWebSocketHandlerDecorator: New StandardWebSocketSession[id=e11b5ef5-d2e5-e5c7-819d-493f42f4a7c8, uri=ws://localhost:8081/messages/websocket]
And with IntegrationFlow context managed flow (Failure)
DEBUG [http-nio-8081-exec-1] o.s.c.l.LogFormatUtils: GET "/messages/websocket", parameters={}
DEBUG [http-nio-8081-exec-1] o.s.w.s.h.AbstractHandlerMapping: Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
DEBUG [http-nio-8081-exec-1] o.s.w.s.r.ResourceHttpRequestHandler: Resource not found
DEBUG [http-nio-8081-exec-1] o.s.w.s.FrameworkServlet: Completed 404 NOT_FOUND
DEBUG [http-nio-8081-exec-1] o.s.c.l.LogFormatUtils: "ERROR" dispatch for GET "/error", parameters={}
DEBUG [http-nio-8081-exec-1] o.s.w.s.h.AbstractHandlerMapping: Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
DEBUG [http-nio-8081-exec-1] o.s.w.s.m.m.a.AbstractMessageConverterMethodProcessor: Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
DEBUG [http-nio-8081-exec-1] o.s.c.l.LogFormatUtils: Writing [{timestamp=Tue Feb 25 17:06:58 IST
You have a different Mapped to ... because of getHandler(HttpServletRequest request) logic in the AbstractHandlerMapping:
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
We don't support dynamic WS endpoints because we don't scan them in the internal WebSocketHandlerMappingFactoryBean.
Feel free to raise a GH issue https://github.com/spring-projects/spring-integration/issues and we will take a look what we can do for that.

Why there is no exception stack trace in spring webflux with default configuration?

Question
I built a server following Webflux functional programming, and added below code to my Router: route(GET("/test/{Id}"), request -> throw new RuntimeException("123")).
But when I call /test/{Id}, the only error log in console is:
TRACE 153036 --- [ctor-http-nio-7] o.s.w.r.function.server.RouterFunctions : [fc7e809d] Matched org.springframework.web.reactive.function.server.RequestPredicates$$Lambda$827/1369035321#9d8c274
DEBUG 153036 --- [ctor-http-nio-7] org.springframework.web.HttpLogging : [fc7e809d] Resolved [RuntimeException: 123] for HTTP GET /test/job
TRACE 153036 --- [ctor-http-nio-7] org.springframework.web.HttpLogging : [fc7e809d] Encoding [{timestamp=Mon Dec 17 15:34:43 CST 2018, path=/test/123, status=500, error=Internal Server Error, message=123}]
TRACE 153036 --- [ctor-http-nio-7] o.s.w.s.adapter.HttpWebHandlerAdapter : [fc7e809d] Completed 500 INTERNAL_SERVER_ERROR, headers={masked}
TRACE 153036 --- [ctor-http-nio-7] org.springframework.web.HttpLogging : [fc7e809d] Handling completed
No stack trace, but why? It should be handled by spring or netty, not my customized code, right? Setting logging.level.org.springframework.web: trace is not a solution, there're too many logs.
Here is what I found so far, but still confused:
I've checked why spring mvc has stack trace, because there is a log.error in try-catch in tomcat and it's proven by debugging.
Then I thought does Netty has these logic too? Actually it has! But what's confuse me is that I can't pause the code in this try-catch with any breakpoints.
Which means there may exists some Mono.onErrorResume swallowing the exception, so netty can't catch anything. But I don't know how to debug a large Mono to check the root cause. And why swallow it?
Option 1A: Set application properties as follows:
server.error.includeStacktrace=ALWAYS
Option 1B: Set application properties as follows:
server.error.includeStacktrace=ON_TRACE_PARAM
And, specify request parameter trace to true.
Option 2: Add a customized WebExceptionHandler, and make sure it's in the component scan scope.
#Component
#Order(-2)
public class LoggingErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(LoggingErrorWebExceptionHandler.class);
public LoggingErrorWebExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
ServerProperties serverProperties, ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer) {
super(errorAttributes, resourceProperties, serverProperties.getError(), applicationContext);
super.setMessageWriters(serverCodecConfigurer.getWriters());
super.setMessageReaders(serverCodecConfigurer.getReaders());
}
#Override
protected void logError(ServerRequest request, HttpStatus errorStatus) {
Throwable ex = getError(request);
logger.error("Error Occurred:", ex);
super.logError(request, errorStatus);
}
}
See https://www.baeldung.com/spring-webflux-errors for more details.

Spring MVC directly returns a View skipping the content inside the method

I am working in a springMVC application. I have a request mapping which is directly returning a view without processing the lines in between.
#RequestMapping(value = { "/testCnt" }, method = { RequestMethod.GET })
public ModelAndView testContent(HttpServletRequest request) {
log.debug("testing debug);
ModelAndView mnv = new ModelAndView();
log.debug("testssss");
log.debug("test purpose");
//some procesing here....Calling other methods and doing the required process
........
........
mnv.setViewName("returnjsp");
return mnv;
}
So for the above code i can see the following in the log statements:
2017-11-26 22:01:56,388 DEBUG org.springframework.web.servlet.DispatcherServlet DispatcherServlet with name 'SiteServlet' processing GET request for [/mysite/site/ContentTest/testCnt]
2017-11-26 22:01:56,389 DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping Looking up handler method for path /ContentTest/testCnt
2017-11-26 22:01:56,394 DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping Returning handler method [public org.springframework.web.servlet.ModelAndView myproject.org.com.TestCountController.testContent(javax.servlet.http.HttpServletRequest)]
2017-11-26 22:01:56,394 DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory Returning cached instance of singleton bean 'testCountController'
2017-11-26 22:01:56,401 DEBUG org.springframework.web.servlet.DispatcherServlet Last-Modified value for [/portal/site/ContentTest/testCnt
] is: -1
2017-11-26 22:01:58,850 DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory Invoking afterPropertiesSet() on bean with name 'returnjsp'
I dont see my log statements in the log which is the very first line of the execution. It directly returns a view to "returnjsp" without processing the content in this method. Please help
Try adding a timer or a sleep function below the log. lines.
Use java.util.concurrent.TimeUnit and then:
TimeUnit.SECONDS.sleep(1);

exceptionListener and errorHandler in apache camle jms component, not working for me

I am connecting to IBM MQ using apache camel Jms component using below code and configuration. When MQ manager goes down by any reason while message polling or is down at the time of camel route startup, my errorHandler or exceptionListener is not invoked.
jmsComponenet = JmsComponent.jmsComponentAutoAcknowledge((ConnectionFactory) obj);
camelContext.addComponent("ibm-mq", jmsComponenet);
camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("ibm-mq:queue:PE_OUTBOUND?concurrentConsumers=5&exceptionListener=#exceptionListener&errorHandler=#errorHandler").to(
"mqprocessor");
}
});
Spring Application-Context :
<bean id="exceptionListener" class="com.*****.JMSExceptionListener" />
<bean id="errorHandler" class="com.*****.JMSConnectionErrorHandler" />
The classess implements required interface
javax.jms.ExceptionListener and org.springframework.util.ErrorHandler
Despite of specifying Handler and Listener still MQ Connection error is just logged as WARN message in log and controll do not reach these classes.
I am missing / doing anything incorrect here?
Here is DEBUG log -
11:18:20,783 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (http-localhost/127.0.0.1:8080-1) Returning cached instance of singleton bean 'errorHandler'
11:18:20,784 DEBUG [org.apache.camel.util.IntrospectionSupport] (http-localhost/127.0.0.1:8080-1) Configured property: errorHandler on bean: org.apache.camel.component.jms.JmsConfiguration#17b86db4 with value: com.manh.processors.JMSConnectionErrorHandler#4d2a5096
11:18:20,784 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] (http-localhost/127.0.0.1:8080-1) Returning cached instance of singleton bean 'exceptionListener'
11:18:20,784 DEBUG [org.apache.camel.util.IntrospectionSupport] (http-localhost/127.0.0.1:8080-1) Configured property: exceptionListener on bean: org.apache.camel.component.jms.JmsConfiguration#17b86db4 with value: com.manh.processors.JMSExceptionListener#6c8b8e49
11:18:20,785 DEBUG [org.apache.camel.spring.SpringCamelContext] (http-localhost/127.0.0.1:8080-1) ibm-mq://queue:PE_OUTBOUND?concurrentConsumers=5&errorHandler=%23errorHandler&exceptionListener=%23exceptionListener converted to endpoint: Endpoint[ibm-mq://queue:PE_OUTBOUND?concurrentConsumers=5&errorHandler=%23errorHandler&exceptionListener=%23exceptionListener] by component: org.apache.camel.component.jms.JmsComponent#fb03c67
11:18:20,785 TRACE [org.apache.camel.management.DefaultManagementLifecycleStrategy] (http-localhost/127.0.0.1:8080-1) Checking whether to register Endpoint[ibm-mq://queue:PE_OUTBOUND?concurrentConsumers=5&errorHandler=%23errorHandler&exceptionListener=%23exceptionListener] from route: null
default testConnectionOnStartup = false. I set it to ture and got exception on startup of route.
ErrorHandler come into play only if exception occurs while processing of message.
Thank you for the help Daniel.
Logging with a warn message is default when an error handler cannot be found, so I suspect Camel is not able to find an instance of the provided bean. Try setting the camel log level to debug and see what it says when the route is started, I would expect some kind of message saying that the referenced beans cannot be found.

Resources