/** Connect to server via Reactor Netty. */ DefaultWebTestClientBuilder() { this(new ReactorClientHttpConnector()); }
@Override public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri, Function<? super ClientHttpRequest, Mono<Void>> requestCallback) { if (!uri.isAbsolute()) { return Mono.error(new IllegalArgumentException("URI is not absolute: " + uri)); } return this.httpClient .request(io.netty.handler.codec.http.HttpMethod.valueOf(method.name())) .uri(uri.toString()) .send((request, outbound) -> requestCallback.apply(adaptRequest(method, uri, request, outbound))) .responseConnection((res, con) -> Mono.just(adaptResponse(res, con.inbound(), con.outbound().alloc()))) .next(); }
/** * Constructor with externally managed Reactor Netty resources, including * {@link LoopResources} for event loop threads, and {@link ConnectionProvider} * for the connection pool. * <p>This constructor should be used only when you don't want the client * to participate in the Reactor Netty global resources. By default the * client participates in the Reactor Netty global resources held in * {@link reactor.netty.http.HttpResources}, which is recommended since * fixed, shared resources are favored for event loop concurrency. However, * consider declaring a {@link ReactorResourceFactory} bean with * {@code globalResources=true} in order to ensure the Reactor Netty global * resources are shut down when the Spring ApplicationContext is closed. * @param factory the resource factory to obtain the resources from * @param mapper a mapper for further initialization of the created client * @since 5.1 */ public ReactorClientHttpConnector(ReactorResourceFactory factory, Function<HttpClient, HttpClient> mapper) { this.httpClient = defaultInitializer.andThen(mapper).apply(initHttpClient(factory)); }
@Override public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri, Function<? super ClientHttpRequest, Mono<Void>> requestCallback) { if (!uri.isAbsolute()) { return Mono.error(new IllegalArgumentException("URI is not absolute: " + uri)); } return this.httpClient .request(adaptHttpMethod(method), uri.toString(), request -> requestCallback.apply(adaptRequest(method, uri, request))) .map(this::adaptResponse); }
private ExchangeFunction initExchangeFunction() { if (this.exchangeFunction != null) { return this.exchangeFunction; } else if (this.connector != null) { return ExchangeFunctions.create(this.connector, this.exchangeStrategies); } else { return ExchangeFunctions.create(new ReactorClientHttpConnector(), this.exchangeStrategies); } }
@Override public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri, Function<? super ClientHttpRequest, Mono<Void>> requestCallback) { if (!uri.isAbsolute()) { return Mono.error(new IllegalArgumentException("URI is not absolute: " + uri)); } return this.httpClient .request(io.netty.handler.codec.http.HttpMethod.valueOf(method.name())) .uri(uri.toString()) .send((request, outbound) -> requestCallback.apply(adaptRequest(method, uri, request, outbound))) .responseConnection((res, con) -> Mono.just(adaptResponse(res, con.inbound(), con.outbound().alloc()))) .next(); }
/** * Constructor with externally managed Reactor Netty resources, including * {@link LoopResources} for event loop threads, and {@link ConnectionProvider} * for the connection pool. * <p>This constructor should be used only when you don't want the client * to participate in the Reactor Netty global resources. By default the * client participates in the Reactor Netty global resources held in * {@link reactor.netty.http.HttpResources}, which is recommended since * fixed, shared resources are favored for event loop concurrency. However, * consider declaring a {@link ReactorResourceFactory} bean with * {@code globalResources=true} in order to ensure the Reactor Netty global * resources are shut down when the Spring ApplicationContext is closed. * @param factory the resource factory to obtain the resources from * @param mapper a mapper for further initialization of the created client * @since 5.1 */ public ReactorClientHttpConnector(ReactorResourceFactory factory, Function<HttpClient, HttpClient> mapper) { this.httpClient = defaultInitializer.andThen(mapper).apply(initHttpClient(factory)); }
private ReactorClientHttpConnector initConnector() { if (bufferFactory instanceof NettyDataBufferFactory) { ByteBufAllocator allocator = ((NettyDataBufferFactory) bufferFactory).getByteBufAllocator(); return new ReactorClientHttpConnector(this.factory, httpClient -> httpClient.tcpConfiguration(tcpClient -> tcpClient.option(ChannelOption.ALLOCATOR, allocator))); } else { return new ReactorClientHttpConnector(); } }
@Override public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri, Function<? super ClientHttpRequest, Mono<Void>> requestCallback) { if (!uri.isAbsolute()) { return Mono.error(new IllegalArgumentException("URI is not absolute: " + uri)); } return this.httpClient .request(io.netty.handler.codec.http.HttpMethod.valueOf(method.name())) .uri(uri.toString()) .send((request, outbound) -> requestCallback.apply(adaptRequest(method, uri, request, outbound))) .responseConnection((res, con) -> Mono.just(adaptResponse(res, con.inbound(), con.outbound().alloc()))) .next(); }
/** * Constructor with externally managed Reactor Netty resources, including * {@link LoopResources} for event loop threads, and {@link ConnectionProvider} * for the connection pool. * <p>This constructor should be used only when you don't want the client * to participate in the Reactor Netty global resources. By default the * client participates in the Reactor Netty global resources held in * {@link reactor.netty.http.HttpResources}, which is recommended since * fixed, shared resources are favored for event loop concurrency. However, * consider declaring a {@link ReactorResourceFactory} bean with * {@code globalResources=true} in order to ensure the Reactor Netty global * resources are shut down when the Spring ApplicationContext is closed. * @param factory the resource factory to obtain the resources from * @param mapper a mapper for further initialization of the created client * @since 5.1 */ public ReactorClientHttpConnector(ReactorResourceFactory factory, Function<HttpClient, HttpClient> mapper) { this.httpClient = defaultInitializer.andThen(mapper).apply(initHttpClient(factory)); }
@Parameterized.Parameters(name = "webClient [{0}]") public static Object[][] arguments() { return new Object[][] { {new JettyClientHttpConnector()}, {new ReactorClientHttpConnector()} }; }
@Parameterized.Parameters(name = "server [{0}] webClient [{1}]") public static Object[][] arguments() { File base = new File(System.getProperty("java.io.tmpdir")); return new Object[][] { {new JettyHttpServer(), new ReactorClientHttpConnector()}, {new JettyHttpServer(), new JettyClientHttpConnector()}, {new ReactorHttpServer(), new ReactorClientHttpConnector()}, {new ReactorHttpServer(), new JettyClientHttpConnector()}, {new TomcatHttpServer(base.getAbsolutePath()), new ReactorClientHttpConnector()}, {new TomcatHttpServer(base.getAbsolutePath()), new JettyClientHttpConnector()}, {new UndertowHttpServer(), new ReactorClientHttpConnector()}, {new UndertowHttpServer(), new JettyClientHttpConnector()} }; }
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); } }
private static WebClientProvider getWebClientProvider(ClientConfiguration clientConfiguration) { Duration connectTimeout = clientConfiguration.getConnectTimeout(); Duration soTimeout = clientConfiguration.getSocketTimeout(); TcpClient tcpClient = TcpClient.create(); if (!connectTimeout.isNegative()) { tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.toIntExact(connectTimeout.toMillis())); } if (!soTimeout.isNegative()) { tcpClient = tcpClient.doOnConnected(connection -> connection // .addHandlerLast(new ReadTimeoutHandler(soTimeout.toMillis(), TimeUnit.MILLISECONDS)) .addHandlerLast(new WriteTimeoutHandler(soTimeout.toMillis(), TimeUnit.MILLISECONDS))); } String scheme = "http"; HttpClient httpClient = HttpClient.from(tcpClient); if (clientConfiguration.useSsl()) { httpClient = httpClient.secure(sslConfig -> { Optional<SSLContext> sslContext = clientConfiguration.getSslContext(); sslContext.ifPresent(it -> sslConfig.sslContext(new JdkSslContext(it, true, ClientAuth.NONE))); }); scheme = "https"; } ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient); WebClientProvider provider = WebClientProvider.create(scheme, connector); return provider.withDefaultHeaders(clientConfiguration.getDefaultHeaders()); }
@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); } }
/** Connect to server via Reactor Netty. */ DefaultWebTestClientBuilder() { this(new ReactorClientHttpConnector()); }
/** Connect to server via Reactor Netty. */ DefaultWebTestClientBuilder() { this(new ReactorClientHttpConnector()); }
@Configuration public class WebClientConfig { @Bean public ObjectMapper jacksonObjectMapper(){ return new ObjectMapper(); } @Bean public WebClient webClient(){ WebClient webClient = new WebClient(new ReactorClientHttpConnector()); return webClient; } }
protected ReactorClientHttpConnector buildTrustAllSslConnector() { HttpClient client = HttpClient.create().secure( (sslContextSpec) -> sslContextSpec.sslContext(createSslContext())); return new ReactorClientHttpConnector(client); }