Making HTTP requests from the post filter of Spring cloud gateway

Viewed 417

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?

0 Answers
Related