/** * A variant of {@link #ReactorNettyTcpClient(String, int, ReactorNettyCodec)} * that still manages the lifecycle of the {@link TcpClient} and underlying * resources, but allows for direct configuration of other properties of the * client through a {@code Function<TcpClient, TcpClient>}. * @param clientConfigurer the configurer function * @param codec for encoding and decoding the input/output byte streams * @since 5.1.3 * @see org.springframework.messaging.simp.stomp.StompReactorNettyCodec */ public ReactorNettyTcpClient(Function<TcpClient, TcpClient> clientConfigurer, ReactorNettyCodec<P> codec) { Assert.notNull(codec, "ReactorNettyCodec is required"); this.channelGroup = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE); this.loopResources = LoopResources.create("tcp-client-loop"); this.poolResources = ConnectionProvider.elastic("tcp-client-pool"); this.codec = codec; this.tcpClient = clientConfigurer.apply(TcpClient .create(this.poolResources) .runOn(this.loopResources, false) .doOnConnected(conn -> this.channelGroup.add(conn.channel()))); }
/** * Simple constructor with the host and port to use to connect to. * <p>This constructor manages the lifecycle of the {@link TcpClient} and * underlying resources such as {@link ConnectionProvider}, * {@link LoopResources}, and {@link ChannelGroup}. * <p>For full control over the initialization and lifecycle of the * TcpClient, use {@link #ReactorNettyTcpClient(TcpClient, ReactorNettyCodec)}. * @param host the host to connect to * @param port the port to connect to * @param codec for encoding and decoding the input/output byte streams * @see org.springframework.messaging.simp.stomp.StompReactorNettyCodec */ public ReactorNettyTcpClient(String host, int port, ReactorNettyCodec<P> codec) { Assert.notNull(host, "host is required"); Assert.notNull(codec, "ReactorNettyCodec is required"); this.channelGroup = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE); this.loopResources = LoopResources.create("tcp-client-loop"); this.poolResources = ConnectionProvider.elastic("tcp-client-pool"); this.codec = codec; this.tcpClient = TcpClient.create(this.poolResources) .host(host).port(port) .runOn(this.loopResources, false) .doOnConnected(conn -> this.channelGroup.add(conn.channel())); }
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()); }
/** * Creates a new instance * * @param address the address to connect to * @return a new instance * @throws NullPointerException if {@code address} is {@code null} */ public static WebsocketClientTransport create(InetSocketAddress address) { Objects.requireNonNull(address, "address must not be null"); TcpClient client = TcpClient.create().addressSupplier(() -> address); return create(client); }
/** * Creates a new instance * * @param address the address to connect to * @return a new instance * @throws NullPointerException if {@code address} is {@code null} */ public static TcpClientTransport create(InetSocketAddress address) { Objects.requireNonNull(address, "address must not be null"); TcpClient tcpClient = TcpClient.create().addressSupplier(() -> address); return create(tcpClient); }
/** * Creates a new instance connecting to localhost * * @param port the port to connect to * @return a new instance */ public static TcpClientTransport create(int port) { TcpClient tcpClient = TcpClient.create().port(port); return create(tcpClient); }
/** * Creates a new instance connecting to localhost * * @param port the port to connect to * @return a new instance */ public static WebsocketClientTransport create(int port) { TcpClient client = TcpClient.create().port(port); return create(client); }
/** * Creates a new instance * * @param bindAddress the address to connect to * @param port the port to connect to * @return a new instance * @throws NullPointerException if {@code bindAddress} is {@code null} */ public static TcpClientTransport create(String bindAddress, int port) { Objects.requireNonNull(bindAddress, "bindAddress must not be null"); TcpClient tcpClient = TcpClient.create().host(bindAddress).port(port); return create(tcpClient); }
/** * Creates a new instance * * @param bindAddress the address to connect to * @param port the port to connect to * @return a new instance * @throws NullPointerException if {@code bindAddress} is {@code null} */ public static WebsocketClientTransport create(String bindAddress, int port) { Objects.requireNonNull(bindAddress, "bindAddress must not be null"); TcpClient client = TcpClient.create().host(bindAddress).port(port); return create(client); }
@DisplayName("creates client with TcpClient") @Test void createTcpClient() { assertThat(TcpClientTransport.create(TcpClient.create())).isNotNull(); } }
/** * A variant of {@link #ReactorNettyTcpClient(String, int, ReactorNettyCodec)} * that still manages the lifecycle of the {@link TcpClient} and underlying * resources, but allows for direct configuration of other properties of the * client through a {@code Function<TcpClient, TcpClient>}. * @param clientConfigurer the configurer function * @param codec for encoding and decoding the input/output byte streams * @since 5.1.3 * @see org.springframework.messaging.simp.stomp.StompReactorNettyCodec */ public ReactorNettyTcpClient(Function<TcpClient, TcpClient> clientConfigurer, ReactorNettyCodec<P> codec) { Assert.notNull(codec, "ReactorNettyCodec is required"); this.channelGroup = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE); this.loopResources = LoopResources.create("tcp-client-loop"); this.poolResources = ConnectionProvider.elastic("tcp-client-pool"); this.codec = codec; this.tcpClient = clientConfigurer.apply(TcpClient .create(this.poolResources) .runOn(this.loopResources, false) .doOnConnected(conn -> this.channelGroup.add(conn.channel()))); }
/** * Simple constructor with the host and port to use to connect to. * <p>This constructor manages the lifecycle of the {@link TcpClient} and * underlying resources such as {@link ConnectionProvider}, * {@link LoopResources}, and {@link ChannelGroup}. * <p>For full control over the initialization and lifecycle of the * TcpClient, use {@link #ReactorNettyTcpClient(TcpClient, ReactorNettyCodec)}. * @param host the host to connect to * @param port the port to connect to * @param codec for encoding and decoding the input/output byte streams * @see org.springframework.messaging.simp.stomp.StompReactorNettyCodec */ public ReactorNettyTcpClient(String host, int port, ReactorNettyCodec<P> codec) { Assert.notNull(host, "host is required"); Assert.notNull(codec, "ReactorNettyCodec is required"); this.channelGroup = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE); this.loopResources = LoopResources.create("tcp-client-loop"); this.poolResources = ConnectionProvider.elastic("tcp-client-pool"); this.codec = codec; this.tcpClient = TcpClient.create(this.poolResources) .host(host).port(port) .runOn(this.loopResources, false) .doOnConnected(conn -> this.channelGroup.add(conn.channel())); }
/** * Prepare a pooled {@link TcpClient} * * @return a {@link TcpClient} */ public static TcpClient create() { return create(TcpResources.get()); }
/** * Prepare a pooled {@link TcpClient} * * @return a {@link TcpClient} */ public static TcpClient create() { return create(TcpResources.get()); }
/** * Prepare an {@link HttpClient}. {@link UriConfiguration#uri(String)} or * {@link #baseUrl(String)} should be invoked before a verb * {@link #request(HttpMethod)} is selected. * * @return a {@link HttpClient} */ public static HttpClient create(ConnectionProvider connectionProvider) { return new HttpClientConnect(TcpClient.create(connectionProvider) .port(80)); }
@Test public void connectionWillRetryConnectionAttemptWhenItFailsElastic() throws InterruptedException { connectionWillRetryConnectionAttemptWhenItFails( TcpClient.create() .host("localhost") .port(abortServerPort + 3) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 100)); }
@Test public void gettingOptionsDuplicates() { TcpClient client = TcpClient.create().host("foo").port(123); Assertions.assertThat(client.configure()) .isNotSameAs(TcpClient.DEFAULT_BOOTSTRAP) .isNotSameAs(client.configure()); }
@Test public void connectionWillRetryConnectionAttemptWhenItFailsFixedChannelPool() throws InterruptedException { connectionWillRetryConnectionAttemptWhenItFails( TcpClient.create(ConnectionProvider.fixed("test", 1)) .host("localhost") .port(abortServerPort + 3) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 100)); }
@Test public void disableSsl() { TcpClient secureClient = TcpClient.create() .secure(); assertTrue(secureClient.isSecure()); assertFalse(secureClient.noSSL().isSecure()); }