( NOT Premature end of Content-Length delimited message body (expected:)
I have a set up of 3 apps talking to each other and each of them is sitting behind an apache http server in the following format
App A (Monolithic Spring app)
App B (Spring boot microservice - acting as intermediate)
App C (Spring boot microservice - serving some data)
App A makes a GET request to App B, App B reads the request and Invokes a GET request to App C, App C gets the data and sends a ResponseEntity to App B, and finally App B sends that ResponseEntity to App A as show in the code below.
//Service A making a request to Service B.
public static Response executeGetMethod(CustomRestTemplate restTemplate, String microServiceURL) {
Response returnedResponse = null;
ResponseEntity<?> msResponse = null;
try {
// special handling for octet-stream
if (restTemplate.getAccepts().stream().anyMatch(accept -> MediaType.APPLICATION_OCTET_STREAM_TYPE.equals(accept))) {
msResponse = restTemplate.getRestTemplate().getForEntity(microServiceURL, byte[].class);
} else {
msResponse = restTemplate.getRestTemplate().getForEntity(microServiceURL, Object.class);
}
returnedResponse = Response.status(msResponse.getStatusCode().value()).entity(msResponse.getBody()).build();
//Just reading the headers from msResponse and adding it to returnedResponse.
addHeaderToReturnedResponse(returnedResponse.getHeaders(), msResponse.getHeaders());
} catch (HttpClientErrorException ex) {
returnedResponse = Response.serverError().status(ex.getStatusCode().value()).entity(ex.getResponseBodyAsString()).build();
} catch (HttpServerErrorException ex) {
returnedResponse = Response.serverError().status(ex.getStatusCode().value()).entity(ex.getResponseBodyAsString()).build();
}
return returnedResponse;
}
// Service B making request to Service C
@GetMapping(value = "/templates", produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<?> getReportTemplate() throws Exception {
validateUser();
// route to reporting-microservices
Map<String, String> headers = new HashMap<>();
headers.put(RestServiceConstants.CONTENT_TYPE, RestServiceConstants.APPLICATION_JSON);
ResponseEntity<?> response = restService.invokeGetApi(headers,
REPORT_MS_URL.concat(REPORT_TEMPLATE_URL));
return response;
}
// Service C get the data and returning it to Service B
@GetMapping(value = "/templates", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<List<ReportTemplate>> getReportTemplate() throws Exception {
List<ReportTemplate> reportTemplates = reportService.getAllReportTemplates();
return ResponseEntity.ok(reportTemplates);
}
// Advice in Service C to add Content-Length and Connection headers before sending response
@Slf4j
@ControllerAdvice
public class ResponseFilter implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if(mediaType.equals(MediaType.APPLICATION_JSON)){
ObjectMapper mapper = new ObjectMapper();
try {
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(o);
log.info("===========================================================================");
log.info(String.valueOf(json.length()));
serverHttpResponse.getHeaders().add("Content-Length", String.valueOf(json.length()));
serverHttpResponse.getHeaders().add("Connection", "keep-alive");
log.info(serverHttpResponse.getHeaders().toSingleValueMap().toString());
log.info("===========================================================================");
} catch (JsonProcessingException e) {
log.error(e.getOriginalMessage());
}
}
return o;
}
}
Now the problem is, I get the following error when I try to run it
Error while extracting response for type [class java.lang.Object] and content type [application/json;charset=UTF-8]; nested exception is org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 1,493; received: 1,111)"
When I have the three apps talking together directly without using httpd as proxy it works fine, but as soon as I enable it, I get that error.
Any help is very appreciated.