feign-reactive icon indicating copy to clipboard operation
feign-reactive copied to clipboard

How can I set the webClient bean used by WebReactiveFeign?

Open rjbgaspar opened this issue 1 year ago • 0 comments

Hi,

I have two api each one using a different bearer token.

In the first api the bearer token is set using ServerOAuth2AuthorizedClientExchangeFilterFunction, as follow:

@Slf4j
@Configuration
@RequiredArgsConstructor
public class Oauth2ClientConfiguration {
    final ApplicationProperties applicationProperties;

    final ReactiveOAuth2AuthorizedClientService authorizedClientService;

    @Bean
    public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
            ReactiveClientRegistrationRepository clientRegistrationRepository,
            ReactiveOAuth2AuthorizedClientService authorizedClientService) {

        ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
                ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
                        .clientCredentials()
                        .refreshToken()
                        .build();
        AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
                new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
                        clientRegistrationRepository, authorizedClientService);
        authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);


        return authorizedClientManager;
    }

    @Bean
    public WebClient webClient(
            ReactiveOAuth2AuthorizedClientManager authorizedClientManager,
            WebClient.Builder webClientBuilder
    ) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction
                oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);

        oauth.setDefaultClientRegistrationId("oidc");
        oauth.setAuthorizationFailureHandler(authorizationFailureHandler());


        return webClientBuilder.exchangeStrategies(
                ExchangeStrategies.builder()
                        .codecs(configurer -> configurer
                                .defaultCodecs()
                                .maxInMemorySize(16 * 1024 * 1024)
                        )
                        .build()
                )
//                .filter(retryOn401(authorizedClientManager))
                .filter(retryOn401TwentyTimes())
                .baseUrl(applicationProperties.getGateway().getBaseUrl())
                .filter(oauth)
                .filter(logRequest())
                .build();

    }
(...)
}

The second api, which is dagger uses ReactiveHttpRequestInterceptor for setting up the token, configured as:

@Configuration
@EnableReactiveFeignClients(basePackages = "com.gv.bearcat.service.pdm.dagger")
public class ReactiveFeignConfiguration {


    @Bean
    public Contract useFeignAnnotations() {
        return new Contract.Default();
    }

    @Bean
    public WebClient.Builder daggerWebClientBuilder() {
        return WebClient.builder();
    }

    @Bean
    //@Primary <---
    public WebClient daggerWebClient(@Qualifier("daggerWebClientBuilder") WebClient.Builder webClientBuilder) {
        return webClientBuilder.build();
    }

    @Bean
    public DaggerApi daggerApi(@Qualifier("daggerWebClient") WebClient webClient) {
        return WebReactiveFeign
                .<DaggerApi>builder(webClient.mutate())
                .target(DaggerApi.class, "http://localhost:50051");
    }
}

and

@ReactiveFeignClient(name="dagger-client", url="${application.dagger.base-url}", configuration = DaggerClientConfiguration.class)
public interface DaggerApi {
    @RequestLine("POST /api/v1/sorter-parts")
    Mono<ResponseEntity<Mono<String>>> create(SorterArticleDTO sorterArticleDTO);
}

and

@Configuration
public class DaggerClientConfiguration {
    @Bean
    public ReactiveHttpRequestInterceptor apiKeyIntercepter() {
        return ReactiveHttpRequestInterceptors.addHeader("Authorization", "Bearer my-token");
    }

    @Bean
    public ReactiveLoggerListener loggerListener() {
        return new DefaultReactiveLogger(Clock.systemUTC(), LoggerFactory.getLogger(DaggerClientConfiguration.class.getName()));
    }
}

The token is set according to the bean which is marked as primary.

Is there any away to override this behavior, e.g. set the webClient bean to be used in daggerApi Thanks in advance.

rjbgaspar avatar Jul 05 '23 13:07 rjbgaspar