reactor.net.tcp.spec.TcpClientSpec Maven / Gradle / Ivy
The newest version!
package reactor.net.tcp.spec;
import reactor.core.Environment;
import reactor.core.Reactor;
import reactor.core.spec.support.EventRoutingComponentSpec;
import reactor.function.Consumer;
import reactor.io.Buffer;
import reactor.io.encoding.Codec;
import reactor.net.NetChannel;
import reactor.net.config.ClientSocketOptions;
import reactor.net.config.SslOptions;
import reactor.net.tcp.TcpClient;
import reactor.util.Assert;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Constructor;
import java.net.InetSocketAddress;
import java.util.*;
/**
* A helper class for specifying a {@code TcpClient}
*
* @param
* The type that will be received by the client
* @param
* The type that will be sent by the client
*
* @author Jon Brisbin
*/
public class TcpClientSpec extends EventRoutingComponentSpec, TcpClient> {
private final Constructor> clientImplConstructor;
private InetSocketAddress connectAddress;
private ClientSocketOptions options = new ClientSocketOptions();
private Collection> consumers = Collections.emptyList();
private SslOptions sslOptions = null;
private Codec codec;
/**
* Create a {@code TcpClient.Spec} using the given implementation class.
*
* @param clientImpl
* The concrete implementation of {@link TcpClient} to instantiate.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public TcpClientSpec(@Nonnull Class extends TcpClient> clientImpl) {
Assert.notNull(clientImpl, "TcpClient implementation class cannot be null.");
try {
this.clientImplConstructor = (Constructor>)clientImpl.getDeclaredConstructor(
Environment.class,
Reactor.class,
InetSocketAddress.class,
ClientSocketOptions.class,
SslOptions.class,
Codec.class,
Collection.class
);
this.clientImplConstructor.setAccessible(true);
} catch(NoSuchMethodException e) {
throw new IllegalArgumentException(
"No public constructor found that matches the signature of the one found in the TcpClient class.");
}
}
/**
* Set the common {@link ClientSocketOptions} for connections made in this client.
*
* @param options
* The socket options to apply to new connections.
*
* @return {@literal this}
*/
public TcpClientSpec options(ClientSocketOptions options) {
this.options = options;
return this;
}
/**
* Set the options to use for configuring SSL. Setting this to {@code null} means don't use SSL at all (the default).
*
* @param sslOptions
* The options to set when configuring SSL
*
* @return {@literal this}
*/
public TcpClientSpec ssl(@Nullable SslOptions sslOptions) {
this.sslOptions = sslOptions;
return this;
}
/**
* The host and port to which this client should connect.
*
* @param host
* The host to connect to.
* @param port
* The port to connect to.
*
* @return {@literal this}
*/
public TcpClientSpec connect(@Nonnull String host, int port) {
return connect(new InetSocketAddress(host, port));
}
/**
* The address to which this client should connect.
*
* @param connectAddress
* The address to connect to.
*
* @return {@literal this}
*/
public TcpClientSpec connect(@Nonnull InetSocketAddress connectAddress) {
Assert.isNull(this.connectAddress, "Connect address is already set.");
this.connectAddress = connectAddress;
return this;
}
/**
* The {@link Codec} to use to encode and decode data.
*
* @param codec
* The codec to use.
*
* @return {@literal this}
*/
public TcpClientSpec codec(@Nullable Codec codec) {
Assert.isNull(this.codec, "Codec has already been set.");
this.codec = codec;
return this;
}
/**
* The {@link reactor.function.Consumer} to use to ingest incoming data.
*
* @param consumer
* the incoming data {@link reactor.function.Consumer}
*
* @return {@literal this}
*/
@SuppressWarnings("unchecked")
public TcpClientSpec consume(Consumer consumer) {
consume(Arrays.asList(consumer));
return this;
}
/**
* The {@link reactor.function.Consumer Consumers} to use to ingest the incoming data.
*
* @param consumers
* the incoming data {@link reactor.function.Consumer Consumers}
*
* @return {@literal this}
*/
public TcpClientSpec consume(Collection> consumers) {
Assert.notNull(consumers, "Consumers cannot be null");
this.consumers = consumers;
return this;
}
@Override
protected TcpClient configure(Reactor reactor, Environment env) {
List>> channelConsumers = new ArrayList>>();
channelConsumers.add(new Consumer>() {
@Override
public void accept(NetChannel netChannel) {
for(Consumer consumer : consumers) {
netChannel.consume(consumer);
}
}
});
try {
return clientImplConstructor.newInstance(
env,
reactor,
connectAddress,
options,
sslOptions,
codec,
channelConsumers
);
} catch(Throwable t) {
throw new IllegalStateException(t);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy