最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

circuit breaker - How do I get a spring cloud GatewayFilter to trigger a fallback route with a CircuitBreaker? - Stack Overflow

programmeradmin0浏览0评论

I have an oauth2 token fetching gateway filter that I need to wire a circuit breaker in. If I can't connect to the provider or authentication fails, I need to use the fallback route.

My filter is below:


import .springframework.cloud.gateway.filter.GatewayFilter;
import .springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import .springframework.http.HttpHeaders;
import .springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import .springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
import .springframework.stereotype.Component;

@Component
public class Oauth2GatewayFilterFactory extends AbstractGatewayFilterFactory<Oauth2GatewayFilterFactory.Config> {

    private final ReactiveOAuth2AuthorizedClientManager authorizedClientManager;

    public Oauth2GatewayFilterFactory(
            ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
        super(Config.class);
        this.authorizedClientManager = authorizedClientManager;
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            final var clientRegistrationId = config.getClientRegistrationId();
            final var oauth2Request = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId)
                    .principal("N/A")
                    .build();
            return authorizedClientManager.authorize(oauth2Request)
                    .map(authorizedClient -> exchange.mutate()
                            .request(r -> r.headers(
                                    headers -> headers.set(HttpHeaders.AUTHORIZATION,
                                            "Bearer " + authorizedClient.getAccessToken().getTokenValue())))
                            .build())
                    .defaultIfEmpty(exchange)
                    .flatMap(chain::filter);
        };
    }

    public static class Config {

        private String clientRegistrationId;

        public String getClientRegistrationId() {
            return clientRegistrationId;
        }

        public void setClientRegistrationId(String clientRegistrationId) {
            this.clientRegistrationId = clientRegistrationId;
        }

    }

}

I've attempted wiring the circuit breaker into the filter factory and then doing a transformDeferred

return authorizedClientManager.authorize(oauth2Request)
        .transformDeferred(CircuitBreakerOperator.of(circuitBreaker))
        .map(authorizedClient -> {

but this doesn't help me.

How do I wire in the circuit breaker?

I have an oauth2 token fetching gateway filter that I need to wire a circuit breaker in. If I can't connect to the provider or authentication fails, I need to use the fallback route.

My filter is below:


import .springframework.cloud.gateway.filter.GatewayFilter;
import .springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import .springframework.http.HttpHeaders;
import .springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import .springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
import .springframework.stereotype.Component;

@Component
public class Oauth2GatewayFilterFactory extends AbstractGatewayFilterFactory<Oauth2GatewayFilterFactory.Config> {

    private final ReactiveOAuth2AuthorizedClientManager authorizedClientManager;

    public Oauth2GatewayFilterFactory(
            ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
        super(Config.class);
        this.authorizedClientManager = authorizedClientManager;
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            final var clientRegistrationId = config.getClientRegistrationId();
            final var oauth2Request = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId)
                    .principal("N/A")
                    .build();
            return authorizedClientManager.authorize(oauth2Request)
                    .map(authorizedClient -> exchange.mutate()
                            .request(r -> r.headers(
                                    headers -> headers.set(HttpHeaders.AUTHORIZATION,
                                            "Bearer " + authorizedClient.getAccessToken().getTokenValue())))
                            .build())
                    .defaultIfEmpty(exchange)
                    .flatMap(chain::filter);
        };
    }

    public static class Config {

        private String clientRegistrationId;

        public String getClientRegistrationId() {
            return clientRegistrationId;
        }

        public void setClientRegistrationId(String clientRegistrationId) {
            this.clientRegistrationId = clientRegistrationId;
        }

    }

}

I've attempted wiring the circuit breaker into the filter factory and then doing a transformDeferred

return authorizedClientManager.authorize(oauth2Request)
        .transformDeferred(CircuitBreakerOperator.of(circuitBreaker))
        .map(authorizedClient -> {

but this doesn't help me.

How do I wire in the circuit breaker?

Share Improve this question asked Feb 1 at 14:00 jlfeld1jlfeld1 1 2
  • Why doesn't it help you? What happens? – shotor Commented Feb 2 at 2:51
  • @shotor It doesn’t make a difference. The failover doesn’t happen and the error gets relayed to the client – jlfeld1 Commented Feb 2 at 12:36
Add a comment  | 

1 Answer 1

Reset to default 0

I got around it without the circuit breaker by using a pattern like this:

return authorizedClientManager.authorize(oauth2Request)
        .map(authorizedClient -> exchange.mutate()
                .request(r -> r.headers(
                        headers -> headers.set(HttpHeaders.AUTHORIZATION,
                                "Bearer " + authorizedClient.getAccessToken().getTokenValue())))
                .build())
        .onErrorResume(e -> Mono.empty())  // Ignore the error
        .defaultIfEmpty(exchange)  // Then continue if an occurred, allowing routed request to fail with a 401
        .flatMap(chain::filter);

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论