I am new to reactive programming in Java and got stuck on this. I have implemented a filter that is working fine till the pre-filter phase but we want to make HTTP requests to other services in the post-filter.
My filter looks like this:
@Override
public GatewayFilter apply (AuthFilter.AuthenticationFilterConfigBean config) {
return (exchange, chain) -> {
ServerHttpRequest originalRequest = exchange.getRequest();
HttpHeaders requestHeaders = originalRequest.getHeaders();
WebClient.RequestHeadersSpec requestAuthentication = webClientAuthentication.post()
.uri("/xyzAuth")
.header("Header key","value")
.bodyValue("req body...");
Mono<ClientResponse> responseAuthentication = requestAuthentication.exchange();
return responseAuthentication.flatMap(clientResponseAuthentication -> {
return clientResponseAuthentication.bodyToMono(String.class).flatMap(bodyAuthentication -> {
if (!clientResponseAuthentication.statusCode().equals(HttpStatus.OK)) {
return this.handleExceptionCases(exchange, bodyAuthentication, clientResponseAuthentication.statusCode());
}
final AuthenticationResponse authenticationResponse;
try {
authenticationResponse = objectMapper.readValue(bodyAuthentication, AuthenticationResponse.class);
exchange.getRequest().mutate().headers(headersFromAuthService -> {
headersFromAuthService.addAll(getHeadermap(authenticationResponse.getHeaderInfo()));
}).build();
} catch (JsonProcessingException e) {
LOGGER.error("Failed parsing Authentication Response: " + e.getMessage());
return handleExceptionCases(exchange, null, HttpStatus.INTERNAL_SERVER_ERROR);
}
LOGGER.info("Prefilter Completed");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
LOGGER.info("Postfilter Begins");
ServerHttpResponse response = exchange.getResponse();
if(response.getStatusCode().is2xxSuccessful()) {
WebClient.RequestHeadersSpec requestPostHandler = webClientPostHandler.post()
.uri("/xyzPostHandler")
.header("Header key","value")
.bodyValue("req body....");
Mono<ClientResponse> responsePostHandler = requestPostHandler.exchange();
LOGGER.info("Going to call postHandler");
return responsePostHandler.flatMap(postHandlerResponse -> {
return postHandlerResponse.bodyToMono(void.class).flatMap(postHandlerBody -> {
if (!postHandlerBody.statusCode().equals(HttpStatus.OK)) {
return this.handleExceptionCases(exchange, postHandlerBody.toString(), postHandlerResponse.statusCode());
}
});
});
}
}));
});
});
};
}
The pre filters are working fine (both the Authentication request and PreHandler requests are getting made) and the actual API is also getting hit. The problem arises when I am trying this in the post filter.
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
LOGGER.info("Postfilter Begins");
ServerHttpResponse response = exchange.getResponse();
if(response.getStatusCode().is2xxSuccessful()) {
WebClient.RequestHeadersSpec requestPostHandler = webClientPostHandler.post()
.uri("/xyzPostHandler")
.header("Header key","value")
.bodyValue("req body....");
Mono<ClientResponse> responsePostHandler = requestPostHandler.exchange();
LOGGER.info("Going to call postHandler");
return responsePostHandler.flatMap(postHandlerResponse -> {
return postHandlerResponse.bodyToMono(void.class).flatMap(postHandlerBody -> {
if (!postHandlerBody.statusCode().equals(HttpStatus.OK)) {
return this.handleExceptionCases(exchange, postHandlerBody.toString(), postHandlerResponse.statusCode());
}
});
});
}}));
Eclipse is showing warning Void methods cannot return a value. Is this the correct way to make HTTP requests in the post filter? And what am I doing wrong?