org.infinispan.hotrod.configuration.HotRodConfigurationBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of infinispan-hotrod-jakarta Show documentation
Show all versions of infinispan-hotrod-jakarta Show documentation
Infinispan Hot Rod Client Jakarta EE
The newest version!
package org.infinispan.hotrod.configuration;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.BATCH_SIZE;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.CLIENT_INTELLIGENCE;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.CONNECT_TIMEOUT;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.CONSISTENT_HASH_IMPL;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.DNS_RESOLVER_MAX_TTL;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.DNS_RESOLVER_MIN_TTL;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.DNS_RESOLVER_NEGATIVE_TTL;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.FORCE_RETURN_VALUES;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.MARSHALLER;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.MARSHALLER_CLASS;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.MAX_RETRIES;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.SOCKET_TIMEOUT;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.TCP_KEEPALIVE;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.TCP_NODELAY;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.TRANSACTION_TIMEOUT;
import static org.infinispan.hotrod.configuration.HotRodConfiguration.VERSION;
import static org.infinispan.hotrod.impl.logging.Log.HOTROD;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.infinispan.api.configuration.Configuration;
import org.infinispan.commons.configuration.Builder;
import org.infinispan.commons.configuration.Combine;
import org.infinispan.commons.configuration.attributes.AttributeSet;
import org.infinispan.commons.marshall.Marshaller;
import org.infinispan.commons.marshall.ProtoStreamMarshaller;
import org.infinispan.commons.util.Features;
import org.infinispan.commons.util.Util;
import org.infinispan.hotrod.HotRod;
import org.infinispan.hotrod.impl.ConfigurationProperties;
import org.infinispan.hotrod.impl.HotRodURI;
import org.infinispan.hotrod.impl.consistenthash.ConsistentHash;
import org.infinispan.hotrod.impl.logging.Log;
import org.infinispan.hotrod.impl.logging.LogFactory;
import org.infinispan.hotrod.impl.transport.tcp.RoundRobinBalancingStrategy;
import org.infinispan.protostream.SerializationContextInitializer;
/**
* ConfigurationBuilder used to generate immutable {@link HotRodConfiguration} objects to pass to the
* {@link org.infinispan.api.Infinispan#create(Configuration)} method.
*
* If you prefer to configure the client declaratively, see {@link org.infinispan.hotrod.configuration}
*
* @since 14.0
*/
public class HotRodConfigurationBuilder implements ConfigurationChildBuilder, Builder {
private static final Log log = LogFactory.getLog(HotRodConfigurationBuilder.class, Log.class);
private final AttributeSet attributes = HotRodConfiguration.attributeDefinitionSet();
// Match IPv4 (host:port) or IPv6 ([host]:port) addresses
private static final Pattern ADDRESS_PATTERN = Pattern
.compile("(\\[([0-9A-Fa-f:]+)\\]|([^:/?#]*))(?::(\\d*))?");
private static final int CACHE_PREFIX_LENGTH = ConfigurationProperties.CACHE_PREFIX.length();
private final ExecutorFactoryConfigurationBuilder asyncExecutorFactory;
private Supplier balancingStrategyFactory = RoundRobinBalancingStrategy::new;
private final ConnectionPoolConfigurationBuilder connectionPool;
private final List servers = new ArrayList<>();
private final SecurityConfigurationBuilder security;
private final List allowListRegExs = new ArrayList<>();
private final StatisticsConfigurationBuilder statistics;
private final List clusters = new ArrayList<>();
private Features features;
private final List contextInitializers = new ArrayList<>();
private final Map remoteCacheBuilders;
private TransportFactory transportFactory = TransportFactory.DEFAULT;
private boolean tracingPropagationEnabled = ConfigurationProperties.DEFAULT_TRACING_PROPAGATION_ENABLED;
public HotRodConfigurationBuilder() {
this.connectionPool = new ConnectionPoolConfigurationBuilder(this);
this.asyncExecutorFactory = new ExecutorFactoryConfigurationBuilder(this);
this.security = new SecurityConfigurationBuilder(this);
this.statistics = new StatisticsConfigurationBuilder(this);
this.remoteCacheBuilders = new HashMap<>();
}
@Override
public AttributeSet attributes() {
return attributes;
}
@Override
public ServerConfigurationBuilder addServer() {
ServerConfigurationBuilder builder = new ServerConfigurationBuilder(this);
this.servers.add(builder);
return builder;
}
@Override
public ClusterConfigurationBuilder addCluster(String clusterName) {
ClusterConfigurationBuilder builder = new ClusterConfigurationBuilder(this, clusterName);
this.clusters.add(builder);
return builder;
}
@Override
public HotRodConfigurationBuilder addServers(String servers) {
parseServers(servers, (host, port) -> addServer().host(host).port(port));
return this;
}
public List servers() {
return servers;
}
public static void parseServers(String servers, BiConsumer c) {
for (String server : servers.split(";")) {
Matcher matcher = ADDRESS_PATTERN.matcher(server.trim());
if (matcher.matches()) {
String v6host = matcher.group(2);
String v4host = matcher.group(3);
String host = v6host != null ? v6host : v4host;
String portString = matcher.group(4);
int port = portString == null
? ConfigurationProperties.DEFAULT_HOTROD_PORT
: Integer.parseInt(portString);
c.accept(host, port);
} else {
throw HOTROD.parseErrorServerAddress(server);
}
}
}
@Override
public ExecutorFactoryConfigurationBuilder asyncExecutorFactory() {
return this.asyncExecutorFactory;
}
@Override
public HotRodConfigurationBuilder balancingStrategy(String balancingStrategy) {
this.balancingStrategyFactory = () -> Util.getInstance(balancingStrategy, HotRod.class.getClassLoader());
return this;
}
@Override
public HotRodConfigurationBuilder balancingStrategy(Supplier balancingStrategyFactory) {
this.balancingStrategyFactory = balancingStrategyFactory;
return this;
}
@Override
public HotRodConfigurationBuilder balancingStrategy(Class extends FailoverRequestBalancingStrategy> balancingStrategy) {
this.balancingStrategyFactory = () -> Util.getInstance(balancingStrategy);
return this;
}
@Override
public HotRodConfigurationBuilder clientIntelligence(ClientIntelligence clientIntelligence) {
attributes.attribute(CLIENT_INTELLIGENCE).set(clientIntelligence);
return this;
}
@Override
public ConnectionPoolConfigurationBuilder connectionPool() {
return connectionPool;
}
@Override
public HotRodConfigurationBuilder connectionTimeout(int connectionTimeout) {
attributes.attribute(CONNECT_TIMEOUT).set(connectionTimeout);
return this;
}
@Override
public HotRodConfigurationBuilder consistentHashImpl(int version, Class extends ConsistentHash> consistentHashClass) {
if (version == 1) {
log.warn("Hash function version 1 is no longer supported.");
} else {
attributes.attribute(CONSISTENT_HASH_IMPL).get()[version - 1] = consistentHashClass;
}
return this;
}
@Override
public HotRodConfigurationBuilder consistentHashImpl(int version, String consistentHashClass) {
return consistentHashImpl(version, Util.loadClass(consistentHashClass, HotRod.class.getClassLoader()));
}
@Override
public HotRodConfigurationBuilder dnsResolverMinTTL(int ttl) {
attributes.attribute(DNS_RESOLVER_MIN_TTL).set(ttl);
return this;
}
@Override
public HotRodConfigurationBuilder dnsResolverMaxTTL(int ttl) {
attributes.attribute(DNS_RESOLVER_MAX_TTL).set(ttl);
return this;
}
@Override
public HotRodConfigurationBuilder dnsResolverNegativeTTL(int ttl) {
attributes.attribute(DNS_RESOLVER_NEGATIVE_TTL).set(ttl);
return this;
}
@Override
public HotRodConfigurationBuilder forceReturnValues(boolean forceReturnValues) {
attributes.attribute(FORCE_RETURN_VALUES).set(forceReturnValues);
return this;
}
@Override
public HotRodConfigurationBuilder marshaller(String marshallerClassName) {
return marshaller(marshallerClassName == null ? null : Util.loadClass(marshallerClassName, HotRod.class.getClassLoader()));
}
@Override
public HotRodConfigurationBuilder marshaller(Class extends Marshaller> marshallerClass) {
attributes.attribute(MARSHALLER).set(marshallerClass == null ? null : Util.getInstance(marshallerClass));
attributes.attribute(MARSHALLER_CLASS).set(marshallerClass);
return this;
}
@Override
public HotRodConfigurationBuilder marshaller(Marshaller marshaller) {
attributes.attribute(MARSHALLER).set(marshaller);
attributes.attribute(MARSHALLER_CLASS).set(marshaller == null ? null : marshaller.getClass());
return this;
}
@Override
public HotRodConfigurationBuilder addContextInitializer(String contextInitializer) {
SerializationContextInitializer sci = Util.getInstance(contextInitializer, HotRod.class.getClassLoader());
return addContextInitializers(sci);
}
@Override
public HotRodConfigurationBuilder addContextInitializer(SerializationContextInitializer contextInitializer) {
if (contextInitializer != null)
this.contextInitializers.add(contextInitializer);
return this;
}
@Override
public HotRodConfigurationBuilder addContextInitializers(SerializationContextInitializer... contextInitializers) {
this.contextInitializers.addAll(Arrays.asList(contextInitializers));
return this;
}
@Override
public HotRodConfigurationBuilder version(ProtocolVersion protocolVersion) {
attributes.attribute(VERSION).set(protocolVersion);
return this;
}
@Override
public SecurityConfigurationBuilder security() {
return security;
}
@Override
public HotRodConfigurationBuilder socketTimeout(int socketTimeout) {
attributes.attribute(SOCKET_TIMEOUT).set(socketTimeout);
return this;
}
@Override
public HotRodConfigurationBuilder tcpNoDelay(boolean tcpNoDelay) {
attributes.attribute(TCP_NODELAY).set(tcpNoDelay);
return this;
}
@Override
public HotRodConfigurationBuilder tcpKeepAlive(boolean keepAlive) {
attributes.attribute(TCP_KEEPALIVE).set(keepAlive);
return this;
}
@Override
public HotRodConfigurationBuilder uri(URI uri) {
// it returns this
return HotRodURI.create(uri).toConfigurationBuilder(this);
}
@Override
public HotRodConfigurationBuilder uri(String uri) {
return uri(java.net.URI.create(uri));
}
@Override
public HotRodConfigurationBuilder maxRetries(int maxRetries) {
attributes.attribute(MAX_RETRIES).set(maxRetries);
return this;
}
@Override
public HotRodConfigurationBuilder addJavaSerialAllowList(String... regEx) {
this.allowListRegExs.addAll(Arrays.asList(regEx));
return this;
}
@Override
public HotRodConfigurationBuilder batchSize(int batchSize) {
if (batchSize <= 0) {
throw new IllegalArgumentException("batchSize must be greater than 0");
}
attributes.attribute(BATCH_SIZE).set(batchSize);
return this;
}
@Override
public StatisticsConfigurationBuilder statistics() {
return statistics;
}
@Override
public RemoteCacheConfigurationBuilder remoteCache(String name) {
return remoteCacheBuilders.computeIfAbsent(name, (n) -> new RemoteCacheConfigurationBuilder(this, n));
}
@Override
public HotRodConfigurationBuilder transactionTimeout(long timeout, TimeUnit timeUnit) {
attributes.attribute(TRANSACTION_TIMEOUT).set(timeUnit.toMillis(timeout));
return this;
}
@Override
public HotRodConfigurationBuilder transportFactory(TransportFactory transportFactory) {
this.transportFactory = transportFactory;
return this;
}
public HotRodConfigurationBuilder disableTracingPropagation() {
this.tracingPropagationEnabled = false;
return this;
}
@Override
public HotRodConfigurationBuilder withProperties(Properties properties) {
//FIXME
return this;
}
@Override
public void validate() {
attributes.validate();
connectionPool.validate();
asyncExecutorFactory.validate();
security.validate();
statistics.validate();
if (attributes.attribute(MAX_RETRIES).get() < 0) {
throw HOTROD.invalidMaxRetries(attributes.attribute(MAX_RETRIES).get());
}
Set clusterNameSet = new HashSet<>(clusters.size());
for (ClusterConfigurationBuilder clusterConfigBuilder : clusters) {
if (!clusterNameSet.add(clusterConfigBuilder.getClusterName())) {
throw HOTROD.duplicateClusterDefinition(clusterConfigBuilder.getClusterName());
}
clusterConfigBuilder.validate();
}
}
@Override
public HotRodConfiguration create() {
List servers = new ArrayList<>();
if (this.servers.size() > 0)
for (ServerConfigurationBuilder server : this.servers) {
servers.add(server.create());
}
else {
servers.add(new ServerConfiguration(ServerConfiguration.attributeDefinitionSet().protect()));
}
List serverClusterConfigs = clusters.stream()
.map(ClusterConfigurationBuilder::create).collect(Collectors.toList());
Map remoteCaches = remoteCacheBuilders.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey, e -> e.getValue().create()));
return new HotRodConfiguration(attributes.protect(),
asyncExecutorFactory.create(),
balancingStrategyFactory,
connectionPool.create(),
servers,
security.create(),
serverClusterConfigs,
statistics.create(),
features,
contextInitializers,
remoteCaches,
transportFactory,
tracingPropagationEnabled);
}
// Method that handles default marshaller - needed as a placeholder
private Marshaller handleNullMarshaller() {
return new ProtoStreamMarshaller();
}
@Override
public HotRodConfiguration build() {
features = new Features(HotRod.class.getClassLoader());
return build(true);
}
public HotRodConfiguration build(boolean validate) {
if (validate) {
validate();
}
return create();
}
@Override
public HotRodConfigurationBuilder read(HotRodConfiguration template, Combine combine) {
this.attributes.read(template.attributes(), combine);
this.asyncExecutorFactory.read(template.asyncExecutorFactory(), combine);
this.balancingStrategyFactory = template.balancingStrategyFactory();
this.connectionPool.read(template.connectionPool(), combine);
this.servers.clear();
for (ServerConfiguration server : template.servers()) {
this.addServer().host(server.host()).port(server.port());
}
this.clusters.clear();
template.clusters().forEach(cluster -> this.addCluster(cluster.getClusterName()).read(cluster, combine));
this.security.read(template.security(), combine);
this.transportFactory = template.transportFactory();
this.statistics.read(template.statistics(), combine);
this.contextInitializers.clear();
this.contextInitializers.addAll(template.getContextInitializers());
return this;
}
@Override
public HotRodConfigurationBuilder read(HotRodConfiguration template) {
return read(template, Combine.DEFAULT);
}
}