Here I'm using Spring integration's http outbound gateway to make a http call. I have also added timeout for the call. I have configured the timeout using restemplate. Here whenever it's taking more time then it's throwing an ResourceAccessException but I want to handle that exception and want to send proper msg to the user. Even though I'm using a custom error handler but the exception is not getting handled by that. Below the code where I'm using scatter gather pattern and flow2 is the http call where I want to handle the exception-
@Autowired private RestTemplateConfig resttemplateconfig.
@Bean
public IntegrationFlow mainFlow() {
return flow ->
flow.split()
.channel(c -> c.executor(Executors.newCachedThreadPool()))
.scatterGather(
scatterer ->
scatterer
.applySequence(true)
.recipientFlow(flow1())
.recipientFlow(flow2()),
gatherer ->
gatherer
.releaseLockBeforeSend(true)
.releaseStrategy(group -> group.size() == 1))
.aggregate()
.to(saveCDResponseToDB());
}
@Bean
public IntegrationFlow flow2() {
return flow ->
flow.channel(c -> c.executor(Executors.newCachedThreadPool()))
.handle(
Http.outboundGateway(
"http://localhost:4444/test", resttemplateconfig.restTemplate())
.extractPayload(true)
.httpMethod(HttpMethod.POST)
.expectedResponseType(String.class));
}
//RestTemplateConfig - The Resttemplate Config class where I'm setting the timeout and errorhandler.
@Configuration
public class RestTemplateConfig {
private final int TIMEOUT = (int) TimeUnit.SECONDS.toMillis(6);
@Autowired CustomErrorHandler errorHandler;
@Bean
public RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(TIMEOUT);
requestFactory.setReadTimeout(TIMEOUT);
RestTemplate restTemplate = new RestTemplate(requestFactory);
errorHandler.setMessageConverters(restTemplate.getMessageConverters());
restTemplate.setErrorHandler(errorHandler);
return restTemplate;
}
}
//custom error handler
@Component
public class CustomServiceErrorHandler implements ResponseErrorHandler {
private List<HttpMessageConverter<?>> messageConverters;
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return hasError(response.getStatusCode());
}
protected boolean hasError(HttpStatus statusCode) {
return (statusCode.is4xxClientError() || statusCode.is5xxServerError());
}
@Override
public void handleError(ClientHttpResponse httpResponse) throws IOException {
if (httpResponse.getStatusCode().series() == SERVER_ERROR) {
// handle SERVER_ERROR
System.out.println("SERVER_ERROR");
} else if (httpResponse.getStatusCode().series() == CLIENT_ERROR) {
// handle CLIENT_ERROR
System.out.println("CLIENT_ERROR");
} else {
System.out.println("SOME_ERROR");
}
}
public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
this.messageConverters = messageConverters;
}
}
I'm getting below error that I want to handle -
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:4444/test": Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out
If I'm adding .errorHandler(new CustomErrorHandler())
in Http.outboundgateway then I'm getting error saying -
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flow2' defined in class path resource [example/common/config/SpringIntegrationConfiguration.class]: Initialization of bean failed; nested exception is java.lang.RuntimeException: java.lang.IllegalArgumentException: the 'errorHandler' must be specified on the provided 'restTemplate'