Gulshan Kumar
Gulshan Kumar

Reputation: 74

Calling micro service from spring cloud gateway

In spring cloud gateway, added a filter that check for the authentication and authorization for further processing of request. I am calling authentication service using feign client, but I am getting the below error while invoking my service through spring cloud gateway.

java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-epoll-3\n\tat reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:83)\n\tSuppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: \nError has been observed at the following site(s):\n\t|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter ....."

I would like to know is it wrong architecture I am using. How to proceed? I am stuck at this error.

@Autowired
private AuthenticationService authService;

// route validator
@Autowired
private RouterValidator routerValidator;

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
     ServerHttpRequest request = exchange.getRequest();
     if (routerValidator.isSecured.test(request)) {
         log.info("Accessing the restricted path");
         if (this.isAuthMissing(request))
             return this.onError(exchange, "Authorization header is missing in request", HttpStatus.UNAUTHORIZED);
         
         final String token = this.getAuthHeader(request);
         log.info("before authservice call");
         AuthenticationResponse user = authService.isTokenValid(token);
         log.info("after authservice call");
         if (!user.isValid())
             return this.onError(exchange, "Authorization header is invalid", HttpStatus.UNAUTHORIZED);
         log.info("before calling populatedRequest");
         this.populateRequestWithHeaders(exchange, user);
     }
     return chain.filter(exchange);
}
private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) {
    ServerHttpResponse response = exchange.getResponse();
    response.setStatusCode(httpStatus);
    return response.setComplete();
}

private String getAuthHeader(ServerHttpRequest request) {
    return request.getHeaders().getOrEmpty("Authorization").get(0);
}

private boolean isAuthMissing(ServerHttpRequest request) {
    log.info("inside auth missing");
    return !request.getHeaders().containsKey("Authorization");
}

private void populateRequestWithHeaders(ServerWebExchange exchange, AuthenticationResponse authRes) {
    log.info("About to mutate the request->{}",exchange);
    exchange.getRequest().mutate()
            .header("id",Integer.toString(authRes.getUserId()))
            .build();
}

Feign interface

@Autowired
private AuthenticationFeign auth;

public AuthenticationResponse isTokenValid(String token) {
    return auth.getValidity(token);
}

Upvotes: 1

Views: 2759

Answers (1)

onur
onur

Reputation: 1

I couldn't clearly read it. But problem is that: you can not make blocking call in filter pipeline. Current reactive impl. is like that. if you want, u can use .then() method of WebClient. U should use webclient. because it's reactive.

this link may help you: https://github.com/spring-cloud/spring-cloud-gateway/issues/980

There was a long time, but i want to give answer. I hope, this help u, please response back, it works or not.

Upvotes: 0

Related Questions