public WebClient instance(Mono<Instance> instance) { return webClient.mutate() .filters(filters -> filters.add(0, InstanceExchangeFilterFunctions.setInstance(instance))) .build(); }
public WebClient instance(Instance instance) { return webClient.mutate() .filters(filters -> filters.add(0, InstanceExchangeFilterFunctions.setInstance(instance))) .build(); }
public InstanceWebClient build() { WebClient.Builder webClientBuilder; if (this.webClient == null) { webClientBuilder = createDefaultWebClient(this.connectTimeout, this.readTimeout); } else { webClientBuilder = this.webClient.mutate(); } webClientBuilder.filters(webClientFilters -> { webClientFilters.add(InstanceExchangeFilterFunctions.addHeaders(this.httpHeadersProvider)); webClientFilters.add(InstanceExchangeFilterFunctions.rewriteEndpointUrl()); webClientFilters.add(InstanceExchangeFilterFunctions.setDefaultAcceptHeader()); webClientFilters.add(InstanceExchangeFilterFunctions.convertLegacyEndpoint(LegacyEndpointConverters.health())); webClientFilters.add(InstanceExchangeFilterFunctions.convertLegacyEndpoint(LegacyEndpointConverters.info())); webClientFilters.add(InstanceExchangeFilterFunctions.convertLegacyEndpoint(LegacyEndpointConverters.env())); webClientFilters.add(InstanceExchangeFilterFunctions.convertLegacyEndpoint(LegacyEndpointConverters.httptrace())); webClientFilters.add(InstanceExchangeFilterFunctions.convertLegacyEndpoint(LegacyEndpointConverters.threaddump())); webClientFilters.add(InstanceExchangeFilterFunctions.convertLegacyEndpoint(LegacyEndpointConverters.liquibase())); webClientFilters.add(InstanceExchangeFilterFunctions.convertLegacyEndpoint(LegacyEndpointConverters.flyway())); webClientFilters.add(InstanceExchangeFilterFunctions.retry(this.defaultRetries, this.retriesPerEndpoint)); this.filters.forEach(filter -> webClientFilters.add(InstanceExchangeFilterFunctions.toExchangeFilterFunction( filter))); }); webClientCustomizer.customize(webClientBuilder); return new InstanceWebClient(webClientBuilder.build()); }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebClient) { WebClient webClient = (WebClient) bean; return webClient.mutate() .filters(addTraceExchangeFilterFunctionIfNotPresent()).build(); } else if (bean instanceof WebClient.Builder) { WebClient.Builder webClientBuilder = (WebClient.Builder) bean; return webClientBuilder.filters(addTraceExchangeFilterFunctionIfNotPresent()); } return bean; }
.build(); WebClient client1a = client1.mutate() .filter((request, next) -> next.exchange(request)) .defaultHeader("baz", "qux") WebClient.Builder builder1 = client1.mutate(); builder1.filters(filters -> assertEquals(1, filters.size())); builder1.defaultHeaders(headers -> assertEquals(1, headers.size())); builder1.defaultCookies(cookies -> assertEquals(1, cookies.size())); WebClient.Builder builder2 = client2.mutate(); builder2.filters(filters -> assertEquals(2, filters.size())); builder2.defaultHeaders(headers -> assertEquals(2, headers.size())); builder2.defaultCookies(cookies -> assertEquals(2, cookies.size())); WebClient.Builder builder1a = client1a.mutate(); builder1a.filters(filters -> assertEquals(2, filters.size())); builder1a.defaultHeaders(headers -> assertEquals(2, headers.size()));
WebClient filteredClient = this.webClient.mutate().filter(filter).build();
@Test public void shouldApplyExchangeFilter() { prepareResponse(response -> response.setHeader("Content-Type", "text/plain") .setBody("Hello Spring!")); WebClient filteredClient = this.webClient.mutate() .filter((request, next) -> { ClientRequest filteredRequest = ClientRequest.from(request).header("foo", "bar").build(); return next.exchange(filteredRequest); }) .build(); Mono<String> result = filteredClient.get() .uri("/greeting?name=Spring") .retrieve() .bodyToMono(String.class); StepVerifier.create(result) .expectNext("Hello Spring!") .expectComplete() .verify(Duration.ofSeconds(3)); expectRequestCount(1); expectRequest(request -> assertEquals("bar", request.getHeader("foo"))); }
/** * Create a session-bound {@link WebClient} to be used by {@link VaultTemplate} for * Vault communication given {@link VaultEndpointProvider} and * {@link ClientHttpConnector} for calls that require an authenticated context. * {@link VaultEndpointProvider} is used to contribute host and port details for * relative URLs typically used by the Template API. Subclasses may override this * method to customize the {@link WebClient}. * * @param endpointProvider must not be {@literal null}. * @param connector must not be {@literal null}. * @return the {@link WebClient} used for Vault communication. * @since 2.1 */ protected WebClient doCreateSessionWebClient(VaultEndpointProvider endpointProvider, ClientHttpConnector connector) { Assert.notNull(endpointProvider, "VaultEndpointProvider must not be null"); Assert.notNull(connector, "ClientHttpConnector must not be null"); ExchangeFilterFunction filter = ofRequestProcessor(request -> vaultTokenSupplier .getVaultToken().map(token -> { return ClientRequest.from(request).headers(headers -> { headers.set(VaultHttpHeaders.VAULT_TOKEN, token.getToken()); }).build(); })); return doCreateWebClient(endpointProvider, connector).mutate().filter(filter) .build(); }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebClient) { WebClient webClient = (WebClient) bean; return webClient.mutate() .filters(addTraceExchangeFilterFunctionIfNotPresent()).build(); } else if (bean instanceof WebClient.Builder) { WebClient.Builder webClientBuilder = (WebClient.Builder) bean; return webClientBuilder.filters(addTraceExchangeFilterFunctionIfNotPresent()); } return bean; }
WebClient.Builder builder = getClient().mutate();
@Override public Builder<T> options(ReactiveOptions options) { if (!options.isEmpty()) { ReactorClientHttpConnector connector = new ReactorClientHttpConnector( opts -> { if (options.getConnectTimeoutMillis() != null) { opts.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, options.getConnectTimeoutMillis().intValue()); } if (options.getReadTimeoutMillis() != null) { opts.afterNettyContextInit(ctx -> { ctx.addHandlerLast(new ReadTimeoutHandler( options.getReadTimeoutMillis(), TimeUnit.MILLISECONDS)); }); } if (options.isTryUseCompression() != null) { opts.compression(options.isTryUseCompression()); } }); setWebClient(webClient.mutate().clientConnector(connector).build()); } return this; }
/** * Sets request options using Feign {@link Request.Options} * * @param options Feign {@code Request.Options} object * @return this builder */ public Builder<T> options(final ReactiveOptions options) { if (!options.isEmpty()) { ReactorClientHttpConnector connector = new ReactorClientHttpConnector( opts -> { if (options.getConnectTimeoutMillis() != null) { opts.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, options.getConnectTimeoutMillis()); } if (options.getReadTimeoutMillis() != null) { opts.afterNettyContextInit(ctx -> { ctx.addHandlerLast(new ReadTimeoutHandler( options.getReadTimeoutMillis(), TimeUnit.MILLISECONDS)); }); } if (options.isTryUseCompression() != null) { opts.compression(options.isTryUseCompression()); } }); this.webClient = webClient.mutate().clientConnector(connector).build(); } return this; }