private DefaultWebTestClientBuilder(@Nullable WebClient.Builder webClientBuilder, @Nullable WebHttpHandlerBuilder httpHandlerBuilder, @Nullable ClientHttpConnector connector, @Nullable Duration responseTimeout) { Assert.isTrue(httpHandlerBuilder != null || connector != null, "Either WebHttpHandlerBuilder or ClientHttpConnector must be provided"); this.webClientBuilder = (webClientBuilder != null ? webClientBuilder : WebClient.builder()); this.httpHandlerBuilder = (httpHandlerBuilder != null ? httpHandlerBuilder.clone() : null); this.connector = connector; this.responseTimeout = responseTimeout; }
@Bean @LoadBalanced public WebClient.Builder loadBalancedWebClientBuilder() { return WebClient.builder(); }
@Before public void setup() { MockitoAnnotations.initMocks(this); this.exchangeFunction = mock(ExchangeFunction.class); when(this.exchangeFunction.exchange(this.captor.capture())).thenReturn(Mono.empty()); this.builder = WebClient.builder().baseUrl("/base").exchangeFunction(this.exchangeFunction); }
@Bean @ConditionalOnMissingBean public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver( Optional<WebClient.Builder> optional, ProxyProperties proxy) { WebClient.Builder builder = optional.orElse(WebClient.builder()); WebClient template = builder.build(); ProxyExchangeArgumentResolver resolver = new ProxyExchangeArgumentResolver( template); resolver.setHeaders(proxy.convertHeaders()); resolver.setSensitive(proxy.getSensitive()); // can be null return resolver; }
private static WebClient.Builder createDefaultWebClient(Duration connectTimeout, Duration readTimeout) { HttpClient httpClient = HttpClient.create() .compress(true) .tcpConfiguration(tcp -> tcp.bootstrap(bootstrap -> bootstrap.option( ChannelOption.CONNECT_TIMEOUT_MILLIS, (int) connectTimeout.toMillis() )).observe((connection, newState) -> { if (ConnectionObserver.State.CONNECTED.equals(newState)) { connection.addHandlerLast(new ReadTimeoutHandler(readTimeout.toMillis(), TimeUnit.MILLISECONDS )); } })); ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient); return WebClient.builder().clientConnector(connector); } }
protected WebClient createWebClientForSocketAddress(InetSocketAddress socketAddress) { Builder builder = WebClient.builder().defaultHeaders(it -> it.addAll(getDefaultHeaders())); if (connector != null) { builder = builder.clientConnector(connector); } String baseUrl = String.format("%s://%s:%d", this.scheme, socketAddress.getHostString(), socketAddress.getPort()); return builder.baseUrl(baseUrl).filter((request, next) -> next.exchange(request).doOnError(errorListener)).build(); } }
@Before public void setup() { this.server = new MockWebServer(); this.webClient = WebClient .builder() .clientConnector(this.connector) .baseUrl(this.server.url("/").toString()) .build(); }
@Override @Before public void setup() throws Exception { super.setup(); this.webClient = WebClient .builder() .clientConnector(this.connector) .baseUrl("http://localhost:" + this.port + "/sse") .build(); }
@Test // SPR-15782 public void shouldFailWithRelativeUrls() { String uri = "/api/v4/groups/1"; Mono<ClientResponse> responseMono = WebClient.builder().build().get().uri(uri).exchange(); StepVerifier.create(responseMono) .expectErrorMessage("URI is not absolute: " + uri) .verify(Duration.ofSeconds(5)); }
@Before public void setUp() { this.factory = new ReactorResourceFactory(); this.factory.afterPropertiesSet(); this.server = new MockWebServer(); this.webClient = WebClient .builder() .clientConnector(initConnector()) .baseUrl(this.server.url("/").toString()) .build(); }
@Test public void setWebClientCustomThenCustomClientIsUsed() { WebClient customClient = mock(WebClient.class); when(customClient.post()).thenReturn(WebClient.builder().build().post()); this.client.setWebClient(customClient); ClientRegistration registration = this.clientRegistration.build(); enqueueJson("{\n" + " \"access_token\":\"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3\",\n" + " \"token_type\":\"bearer\",\n" + " \"expires_in\":3600,\n" + " \"refresh_token\":\"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk\"\n" + "}"); OAuth2ClientCredentialsGrantRequest request = new OAuth2ClientCredentialsGrantRequest(registration); OAuth2AccessTokenResponse response = this.client.getTokenResponse(request).block(); verify(customClient, atLeastOnce()).post(); }
@Test public void setCustomWebClientThenCustomWebClientIsUsed() { WebClient customClient = mock(WebClient.class); when(customClient.post()).thenReturn(WebClient.builder().build().post()); tokenResponseClient.setWebClient(customClient); String accessTokenSuccessResponse = "{\n" + " \"access_token\": \"access-token-1234\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": \"3600\",\n" + " \"scope\": \"openid profile\"\n" + "}\n"; this.server.enqueue(jsonResponse(accessTokenSuccessResponse)); this.clientRegistration.scope("openid", "profile", "email", "address"); OAuth2AccessTokenResponse response = this.tokenResponseClient.getTokenResponse(authorizationCodeGrantRequest()).block(); verify(customClient, atLeastOnce()).post(); } }
@Test public void nonStandardHeadersInResponse() { URI uri = UriComponentsBuilder .fromUriString(this.baseUri + "/get-image") .build(true) .toUri(); String contentType = WebClient.builder() .baseUrl(baseUri) .build() .get() .uri(uri) .exchange() .map(clientResponse -> clientResponse.headers().asHttpHeaders().getFirst(HttpHeaders.CONTENT_TYPE)) .block(); assertEquals(CONTENT_TYPE_IMAGE, contentType); }
@Before public void setup() { ClientHttpConnector httpConnector = new ReactorClientHttpConnector(); baseUri = "http://localhost:" + port; this.webClient = WebClient.builder().clientConnector(httpConnector) .baseUrl(baseUri).build(); this.testClient = WebTestClient.bindToServer().baseUrl(baseUri).build(); }
@Before public void setup() { try { SslContext sslContext = SslContextBuilder.forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); HttpClient httpClient = HttpClient.create().secure(ssl -> { ssl.sslContext(sslContext); }); ClientHttpConnector httpConnector = new ReactorClientHttpConnector( httpClient); baseUri = "https://localhost:" + port; this.webClient = WebClient.builder().clientConnector(httpConnector) .baseUrl(baseUri).build(); this.testClient = WebTestClient.bindToServer(httpConnector).baseUrl(baseUri).build(); } catch (SSLException e) { throw new RuntimeException(e); } }
WebClient.Builder builder = WebClient.builder() .filter((request, next) -> next.exchange(request)) .defaultHeader("foo", "bar")
@Test public void testReactiveConnectErrorOneWay() { ClientHttpConnector httpConnector = new HttpHandlerConnector((request, response) -> { throw new RuntimeException("Intentional connection error"); }); WebClient webClient = WebClient.builder() .clientConnector(httpConnector) .build(); String destinationUri = "http://www.springsource.org/spring-integration"; WebFluxRequestExecutingMessageHandler reactiveHandler = new WebFluxRequestExecutingMessageHandler(destinationUri, webClient); reactiveHandler.setExpectReply(false); QueueChannel errorChannel = new QueueChannel(); reactiveHandler.handleMessage(MessageBuilder.withPayload("hello, world") .setErrorChannel(errorChannel) .build()); Message<?> errorMessage = errorChannel.receive(10000); assertNotNull(errorMessage); assertThat(errorMessage, instanceOf(ErrorMessage.class)); Throwable throwable = (Throwable) errorMessage.getPayload(); assertThat(throwable.getMessage(), containsString("Intentional connection error")); }
@Test public void testReactiveErrorOneWay() { ClientHttpConnector httpConnector = new HttpHandlerConnector((request, response) -> { response.setStatusCode(HttpStatus.UNAUTHORIZED); return Mono.defer(response::setComplete); }); WebClient webClient = WebClient.builder() .clientConnector(httpConnector) .build(); String destinationUri = "http://www.springsource.org/spring-integration"; WebFluxRequestExecutingMessageHandler reactiveHandler = new WebFluxRequestExecutingMessageHandler(destinationUri, webClient); reactiveHandler.setExpectReply(false); QueueChannel errorChannel = new QueueChannel(); reactiveHandler.handleMessage(MessageBuilder.withPayload("hello, world") .setErrorChannel(errorChannel) .build()); Message<?> errorMessage = errorChannel.receive(10000); assertNotNull(errorMessage); assertThat(errorMessage, instanceOf(ErrorMessage.class)); Throwable throwable = (Throwable) errorMessage.getPayload(); assertThat(throwable.getMessage(), containsString("401 Unauthorized")); }
@Test public void testHttpReactiveProxyFlow() throws Exception { ClientHttpConnector httpConnector = new HttpHandlerConnector((request, response) -> { response.setStatusCode(HttpStatus.OK); response.getHeaders().setContentType(MediaType.TEXT_PLAIN); return response.writeWith(Mono.just(response.bufferFactory().wrap("FOO".getBytes()))) .then(Mono.defer(response::setComplete)); }); WebClient webClient = WebClient.builder() .clientConnector(httpConnector) .build(); new DirectFieldAccessor(this.httpReactiveProxyFlow) .setPropertyValue("webClient", webClient); this.mockMvc.perform( get("/service2") .with(httpBasic("guest", "guest")) .param("name", "foo")) .andExpect( content() .string("FOO")); }
@Test public void testReactiveReturn() { ClientHttpConnector httpConnector = new HttpHandlerConnector((request, response) -> { response.setStatusCode(HttpStatus.OK); return Mono.defer(response::setComplete); }); WebClient webClient = WebClient.builder() .clientConnector(httpConnector) .build(); String destinationUri = "http://www.springsource.org/spring-integration"; WebFluxRequestExecutingMessageHandler reactiveHandler = new WebFluxRequestExecutingMessageHandler(destinationUri, webClient); FluxMessageChannel ackChannel = new FluxMessageChannel(); reactiveHandler.setOutputChannel(ackChannel); reactiveHandler.handleMessage(MessageBuilder.withPayload("hello, world").build()); reactiveHandler.handleMessage(MessageBuilder.withPayload("hello, world").build()); StepVerifier.create(ackChannel, 2) .assertNext(m -> assertThat(m, hasHeader(HttpHeaders.STATUS_CODE, HttpStatus.OK))) .assertNext(m -> assertThat(m, hasHeader(HttpHeaders.STATUS_CODE, HttpStatus.OK))) .then(() -> ((Subscriber<?>) TestUtils.getPropertyValue(ackChannel, "subscribers", List.class).get(0)) .onComplete()) .verifyComplete(); }