
com.hazelcast.client.config.ClientNetworkConfig Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.client.config;
import com.hazelcast.client.impl.connection.tcp.RoutingMode;
import com.hazelcast.config.AutoDetectionConfig;
import com.hazelcast.config.AwsConfig;
import com.hazelcast.config.AzureConfig;
import com.hazelcast.config.DiscoveryConfig;
import com.hazelcast.config.EurekaConfig;
import com.hazelcast.config.GcpConfig;
import com.hazelcast.config.KubernetesConfig;
import com.hazelcast.config.SSLConfig;
import com.hazelcast.config.SocketInterceptorConfig;
import com.hazelcast.internal.util.Preconditions;
import com.hazelcast.partition.PartitionService;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import static com.hazelcast.internal.util.Preconditions.checkHasText;
import static com.hazelcast.internal.util.Preconditions.isNotNull;
/**
* Contains configuration parameters for client network related behaviour
*/
@SuppressWarnings("MethodCount")
public class ClientNetworkConfig {
private static final int CONNECTION_TIMEOUT = 5000;
private final List addressList;
private ClusterRoutingConfig clusterRoutingConfig = new ClusterRoutingConfig();
private boolean redoOperation;
private int connectionTimeout = CONNECTION_TIMEOUT;
private SocketInterceptorConfig socketInterceptorConfig = new SocketInterceptorConfig();
private SocketOptions socketOptions = new SocketOptions();
private SSLConfig sslConfig;
private AwsConfig awsConfig = new AwsConfig();
private GcpConfig gcpConfig = new GcpConfig();
private AzureConfig azureConfig = new AzureConfig();
private KubernetesConfig kubernetesConfig = new KubernetesConfig();
private EurekaConfig eurekaConfig = new EurekaConfig();
private ClientCloudConfig cloudConfig = new ClientCloudConfig();
private DiscoveryConfig discoveryConfig = new DiscoveryConfig();
private AutoDetectionConfig autoDetectionConfig = new AutoDetectionConfig();
private Collection outboundPortDefinitions;
private Collection outboundPorts;
private ClientIcmpPingConfig clientIcmpPingConfig = new ClientIcmpPingConfig();
public ClientNetworkConfig() {
addressList = new ArrayList<>();
}
public ClientNetworkConfig(ClientNetworkConfig networkConfig) {
addressList = new ArrayList<>(networkConfig.addressList);
clusterRoutingConfig = new ClusterRoutingConfig(networkConfig.getClusterRoutingConfig());
redoOperation = networkConfig.redoOperation;
connectionTimeout = networkConfig.connectionTimeout;
socketInterceptorConfig = new SocketInterceptorConfig(networkConfig.socketInterceptorConfig);
socketOptions = new SocketOptions(networkConfig.socketOptions);
sslConfig = networkConfig.sslConfig == null ? null : new SSLConfig(networkConfig.sslConfig);
awsConfig = new AwsConfig(networkConfig.awsConfig);
gcpConfig = new GcpConfig(networkConfig.gcpConfig);
azureConfig = new AzureConfig(networkConfig.azureConfig);
kubernetesConfig = new KubernetesConfig(networkConfig.kubernetesConfig);
eurekaConfig = new EurekaConfig(networkConfig.eurekaConfig);
cloudConfig = new ClientCloudConfig(networkConfig.cloudConfig);
discoveryConfig = new DiscoveryConfig(networkConfig.discoveryConfig);
outboundPortDefinitions = networkConfig.outboundPortDefinitions == null
? null : new HashSet<>(networkConfig.outboundPortDefinitions);
outboundPorts = networkConfig.outboundPorts == null ? null : new HashSet<>(networkConfig.outboundPorts);
clientIcmpPingConfig = new ClientIcmpPingConfig(networkConfig.clientIcmpPingConfig);
}
/**
* Returns the configuration of the Hazelcast Discovery SPI and configured discovery providers
*
* @return Discovery Provider SPI configuration
*/
public DiscoveryConfig getDiscoveryConfig() {
return discoveryConfig;
}
/**
* Defines the Discovery Provider SPI configuration
*
* @param discoveryConfig the Discovery Provider SPI configuration
* @return this configuration
* @throws java.lang.IllegalArgumentException if discoveryConfig is null
*/
public ClientNetworkConfig setDiscoveryConfig(DiscoveryConfig discoveryConfig) {
this.discoveryConfig = isNotNull(discoveryConfig, "discoveryConfig");
return this;
}
/**
* Returns the configuration of the Auto Detection discovery.
*
* @return Configuration of Auto Detection discovery
*/
public AutoDetectionConfig getAutoDetectionConfig() {
return autoDetectionConfig;
}
/**
* Any other connect configuration takes precedence over auto-discovery, so auto-discovery is enabled only when no other
* strategy is enabled.
*
* @return true if auto-detection is enabled
*/
@SuppressWarnings("checkstyle:booleanexpressioncomplexity")
public boolean isAutoDetectionEnabled() {
return autoDetectionConfig.isEnabled()
&& addressList.isEmpty()
&& !cloudConfig.isEnabled()
&& !awsConfig.isEnabled()
&& !gcpConfig.isEnabled()
&& !azureConfig.isEnabled()
&& !kubernetesConfig.isEnabled()
&& !eurekaConfig.isEnabled()
&& !discoveryConfig.isEnabled();
}
/**
* Defines the Auto Detection configuration.
*
* @param autoDetectionConfig Auto Detection configuration
* @return this configuration
* @throws java.lang.IllegalArgumentException if autoDetectionConfig is null
*/
public ClientNetworkConfig setAutoDetectionConfig(AutoDetectionConfig autoDetectionConfig) {
this.autoDetectionConfig = isNotNull(autoDetectionConfig, "autoDetectionConfig");
return this;
}
/**
* See {@link com.hazelcast.client.config.ClientNetworkConfig#setSmartRouting(boolean)} for details
*
* @deprecated since 5.5, this option is superseded by {@link ClusterRoutingConfig#getRoutingMode()}
* @return true if client is smart
*/
@Deprecated(since = "5.5")
public boolean isSmartRouting() {
return clusterRoutingConfig.getRoutingMode() == RoutingMode.ALL_MEMBERS;
}
/**
* If {@code true}, client will route the key-based operations to owner of the key on best-effort basis.
* Note that it uses a cached version of {@link PartitionService#getPartitions()} and doesn't
* guarantee that the operation will always be executed on the owner. The cached table is updated every 10 seconds.
*
* If {@code smartRouting == false}, all operations will be routed to single member. Operations will need two
* hops if the chosen member is not owner of the key. Client will have only single open connection. Useful, if
* there are many clients, and we want to avoid each of them connecting to each member.
*
* Default value is {@code true}.
*
* @deprecated since 5.5, this option is superseded by {@link ClusterRoutingConfig#setRoutingMode(RoutingMode)}}.
* @param smartRouting true if smart routing should be enabled.
* @return configured {@link com.hazelcast.client.config.ClientNetworkConfig} for chaining
*/
@Deprecated(since = "5.5")
public ClientNetworkConfig setSmartRouting(boolean smartRouting) {
clusterRoutingConfig.setRoutingMode(smartRouting ? RoutingMode.ALL_MEMBERS : RoutingMode.SINGLE_MEMBER);
return this;
}
/**
* @return socket interceptor config that will be called with the Socket,
* each time client creates a connection to any Member.
*/
public SocketInterceptorConfig getSocketInterceptorConfig() {
return socketInterceptorConfig;
}
/**
* @param socketInterceptorConfig will be called with the Socket,
* each time client creates a connection to any Member.
* @return configured {@link com.hazelcast.client.config.ClientNetworkConfig} for chaining
*/
public ClientNetworkConfig setSocketInterceptorConfig(SocketInterceptorConfig socketInterceptorConfig) {
this.socketInterceptorConfig = isNotNull(socketInterceptorConfig, "socketInterceptorConfig");
return this;
}
/**
* Timeout value in millis for nodes to accept client connection requests.
*
* @return connection timeout value in millis
*/
public int getConnectionTimeout() {
return connectionTimeout;
}
/**
* @param connectionTimeoutInMillis Timeout value in millis for nodes to accept client connection requests.
* A zero value means wait until connection established or an error occurs.
* @return configured {@link com.hazelcast.client.config.ClientNetworkConfig} for chaining
*/
public ClientNetworkConfig setConnectionTimeout(int connectionTimeoutInMillis) {
if (connectionTimeoutInMillis < 0) {
throw new IllegalArgumentException("connectionTimeout cannot be negative");
}
this.connectionTimeout = connectionTimeoutInMillis;
return this;
}
/**
* Adds given addresses to candidate address list that client will use to establish initial connection
*
* @param addresses to be added to initial address list
* @return configured {@link com.hazelcast.client.config.ClientNetworkConfig} for chaining
*/
public ClientNetworkConfig addAddress(String... addresses) {
isNotNull(addresses, "addresses");
for (String address : addresses) {
isNotNull(address, "address");
checkHasText(address.trim(), "member must contain text");
}
Collections.addAll(addressList, addresses);
return this;
}
/**
* Sets given addresses as candidate address list that client will use to establish initial connection
*
* @param addresses to be added to initial address list
* @return configured {@link com.hazelcast.client.config.ClientNetworkConfig} for chaining
*/
// required for spring module
public ClientNetworkConfig setAddresses(List addresses) {
isNotNull(addresses, "addresses");
addressList.clear();
addressList.addAll(addresses);
return this;
}
/**
* Returns the list of candidate addresses that client will use to establish initial connection
*
* @return list of addresses
*/
public List getAddresses() {
return addressList;
}
/**
* See {@link com.hazelcast.client.config.ClientNetworkConfig#setRedoOperation(boolean)} for details
*
* @return true if redo operations are enabled
*/
public boolean isRedoOperation() {
return redoOperation;
}
/**
* If true, client will redo the operations that were executing on the server and client lost the connection.
* This can be because of network, or simply because the member died. However it is not clear whether the
* application is performed or not. For idempotent operations this is harmless, but for non idempotent ones
* retrying can cause to undesirable effects. Note that the redo can perform on any member.
*
* If false, the operation will throw {@link RuntimeException} that is wrapping {@link java.io.IOException}.
* TODO clear what is the exception here
*
* @param redoOperation true if redo operations are enabled
* @return configured {@link com.hazelcast.client.config.ClientNetworkConfig} for chaining
*/
public ClientNetworkConfig setRedoOperation(boolean redoOperation) {
this.redoOperation = redoOperation;
return this;
}
/**
* @return TCP Socket options
*/
public SocketOptions getSocketOptions() {
return socketOptions;
}
/**
* @param socketOptions TCP Socket options
* @return configured {@link com.hazelcast.client.config.ClientNetworkConfig} for chaining
*/
public ClientNetworkConfig setSocketOptions(SocketOptions socketOptions) {
this.socketOptions = socketOptions;
return this;
}
/**
* Returns the current {@link SSLConfig}. It is possible that null is returned if no SSLConfig has been
* set.
*
* @return the SSLConfig.
* @see #setSSLConfig(SSLConfig)
*/
public SSLConfig getSSLConfig() {
return sslConfig;
}
/**
* Sets the {@link SSLConfig}. null value indicates that no SSLConfig should be used.
*
* @param sslConfig the SSLConfig.
* @return the updated ClientNetworkConfig.
* @see #getSSLConfig()
*/
public ClientNetworkConfig setSSLConfig(SSLConfig sslConfig) {
this.sslConfig = sslConfig;
return this;
}
/**
* Sets configuration to connect nodes in AWS environment.
*
* @param clientAwsConfig the ClientAwsConfig
* @see #getAwsConfig()
*/
public ClientNetworkConfig setAwsConfig(AwsConfig clientAwsConfig) {
isNotNull(clientAwsConfig, "clientAwsConfig");
this.awsConfig = clientAwsConfig;
return this;
}
/**
* Returns the current {@link AwsConfig}.
*
* @return ClientAwsConfig
* @see #setAwsConfig(AwsConfig)
*/
public AwsConfig getAwsConfig() {
return awsConfig;
}
/**
* Sets configuration to connect nodes in GCP environment.
*
* @param gcpConfig the GcpConfig
* @see #getGcpConfig()
*/
public ClientNetworkConfig setGcpConfig(GcpConfig gcpConfig) {
isNotNull(gcpConfig, "gcpConfig");
this.gcpConfig = gcpConfig;
return this;
}
/**
* Returns the current {@link GcpConfig}.
*
* @return GcpConfig
* @see #setGcpConfig(GcpConfig)
*/
public GcpConfig getGcpConfig() {
return gcpConfig;
}
/**
* Sets configuration to connect nodes in Azure environment.
*
* @param azureConfig the AzureConfig
* @see #getAzureConfig()
*/
public ClientNetworkConfig setAzureConfig(AzureConfig azureConfig) {
isNotNull(azureConfig, "azureConfig");
this.azureConfig = azureConfig;
return this;
}
/**
* Returns the current {@link AzureConfig}.
*
* @return AzureConfig
* @see #setAzureConfig(AzureConfig)
*/
public AzureConfig getAzureConfig() {
return azureConfig;
}
/**
* Sets configuration to connect nodes in Kubernetes environment.
*
* @param kubernetesConfig the KubernetesConfig
* @see #getKubernetesConfig()
*/
public ClientNetworkConfig setKubernetesConfig(KubernetesConfig kubernetesConfig) {
isNotNull(kubernetesConfig, "kubernetesConfig");
this.kubernetesConfig = kubernetesConfig;
return this;
}
/**
* Returns the current {@link KubernetesConfig}.
*
* @return KubernetesConfig
* @see #setKubernetesConfig(KubernetesConfig)
*/
public KubernetesConfig getKubernetesConfig() {
return kubernetesConfig;
}
/**
* Sets configuration to connect nodes in Eureka environment.
*
* @param eurekaConfig the EurekaConfig
* @see #getEurekaConfig()
*/
public ClientNetworkConfig setEurekaConfig(EurekaConfig eurekaConfig) {
isNotNull(eurekaConfig, "eurekaConfig");
this.eurekaConfig = eurekaConfig;
return this;
}
/**
* Returns the current {@link EurekaConfig}.
*
* @return EurekaConfig
* @see #setEurekaConfig(EurekaConfig)
*/
public EurekaConfig getEurekaConfig() {
return eurekaConfig;
}
public ClientCloudConfig getCloudConfig() {
return cloudConfig;
}
public ClientNetworkConfig setCloudConfig(ClientCloudConfig cloudConfig) {
isNotNull(cloudConfig, "cloudConfig");
this.cloudConfig = cloudConfig;
return this;
}
/**
* Returns the outbound port definitions. It is possible that null is returned if not defined.
*
* @return list of outbound port definitions
*/
public Collection getOutboundPortDefinitions() {
return outboundPortDefinitions;
}
/**
* Returns the outbound ports. It is possible that null is returned if not defined.
*
* @return list of outbound ports
*/
public Collection getOutboundPorts() {
return outboundPorts;
}
/**
* Set outbound port definitions
*
* @param outboundPortDefinitions outbound port definitions
* @return ClientNetworkConfig
*/
public ClientNetworkConfig setOutboundPortDefinitions(final Collection outboundPortDefinitions) {
this.outboundPortDefinitions = outboundPortDefinitions;
return this;
}
/**
* Set outbound ports
*
* @param outboundPorts outbound ports
* @return ClientNetworkConfig
*/
public ClientNetworkConfig setOutboundPorts(final Collection outboundPorts) {
this.outboundPorts = outboundPorts;
return this;
}
/**
* Add outbound port to the outbound port list
*
* @param port outbound port
* @return ClientNetworkConfig
*/
public ClientNetworkConfig addOutboundPort(int port) {
if (outboundPorts == null) {
outboundPorts = new HashSet<>();
}
outboundPorts.add(port);
return this;
}
/**
* Add outbound port definition to the outbound port definition list
*
* @param portDef outbound port definition
* @return ClientNetworkConfig
*/
public ClientNetworkConfig addOutboundPortDefinition(String portDef) {
if (outboundPortDefinitions == null) {
outboundPortDefinitions = new HashSet<>();
}
outboundPortDefinitions.add(portDef);
return this;
}
/**
* ICMP ping is used to detect if machine that a remote hazelcast member runs on alive or not
*
* @return current configuration for client icmp ping, returns the default configuration if not set by user
*/
public ClientIcmpPingConfig getClientIcmpPingConfig() {
return clientIcmpPingConfig;
}
/**
* ICMP ping is used to detect if machine that a remote hazelcast member runs on alive or not
*
* @param clientIcmpPingConfig configuration for client icmp ping
* @return ClientNetworkConfig for chaining
*/
public ClientNetworkConfig setClientIcmpPingConfig(ClientIcmpPingConfig clientIcmpPingConfig) {
this.clientIcmpPingConfig = clientIcmpPingConfig;
return this;
}
/**
* @return config for managing how the client routes to members of the cluster.
*/
public ClusterRoutingConfig getClusterRoutingConfig() {
return clusterRoutingConfig;
}
/**
* Sets config for managing how the client routes to members of the cluster.
*
* @param clusterRoutingConfig clusterRoutingConfig object
* @return this {@link ClientNetworkConfig} object
*/
public ClientNetworkConfig setClusterRoutingConfig(ClusterRoutingConfig clusterRoutingConfig) {
this.clusterRoutingConfig = Preconditions.checkNotNull(clusterRoutingConfig,
"clusterRoutingConfig cannot be null");
return this;
}
@Override
@SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity", "checkstyle:methodlength"})
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ClientNetworkConfig that = (ClientNetworkConfig) o;
if (redoOperation != that.redoOperation) {
return false;
}
if (connectionTimeout != that.connectionTimeout) {
return false;
}
if (!addressList.equals(that.addressList)) {
return false;
}
if (!socketInterceptorConfig.equals(that.socketInterceptorConfig)) {
return false;
}
if (!socketOptions.equals(that.socketOptions)) {
return false;
}
if (!Objects.equals(sslConfig, that.sslConfig)) {
return false;
}
if (!awsConfig.equals(that.awsConfig)) {
return false;
}
if (!gcpConfig.equals(that.gcpConfig)) {
return false;
}
if (!azureConfig.equals(that.azureConfig)) {
return false;
}
if (!kubernetesConfig.equals(that.kubernetesConfig)) {
return false;
}
if (!eurekaConfig.equals(that.eurekaConfig)) {
return false;
}
if (!cloudConfig.equals(that.cloudConfig)) {
return false;
}
if (!discoveryConfig.equals(that.discoveryConfig)) {
return false;
}
if (!Objects.equals(outboundPortDefinitions, that.outboundPortDefinitions)) {
return false;
}
if (!Objects.equals(outboundPorts, that.outboundPorts)) {
return false;
}
if (!clusterRoutingConfig.equals(that.clusterRoutingConfig)) {
return false;
}
return clientIcmpPingConfig.equals(that.clientIcmpPingConfig);
}
@Override
public int hashCode() {
int result = addressList.hashCode();
result = 31 * result + (redoOperation ? 1 : 0);
result = 31 * result + connectionTimeout;
result = 31 * result + socketInterceptorConfig.hashCode();
result = 31 * result + socketOptions.hashCode();
result = 31 * result + (sslConfig != null ? sslConfig.hashCode() : 0);
result = 31 * result + awsConfig.hashCode();
result = 31 * result + gcpConfig.hashCode();
result = 31 * result + azureConfig.hashCode();
result = 31 * result + kubernetesConfig.hashCode();
result = 31 * result + eurekaConfig.hashCode();
result = 31 * result + cloudConfig.hashCode();
result = 31 * result + discoveryConfig.hashCode();
result = 31 * result + (outboundPortDefinitions != null ? outboundPortDefinitions.hashCode() : 0);
result = 31 * result + (outboundPorts != null ? outboundPorts.hashCode() : 0);
result = 31 * result + clientIcmpPingConfig.hashCode();
result = 31 * result + clusterRoutingConfig.hashCode();
return result;
}
@Override
public String toString() {
return "ClientNetworkConfig{"
+ "addressList=" + addressList
+ ", redoOperation=" + redoOperation
+ ", connectionTimeout=" + connectionTimeout
+ ", socketInterceptorConfig=" + socketInterceptorConfig
+ ", socketOptions=" + socketOptions
+ ", sslConfig=" + sslConfig
+ ", awsConfig=" + awsConfig
+ ", gcpConfig=" + gcpConfig
+ ", azureConfig=" + azureConfig
+ ", kubernetesConfig=" + kubernetesConfig
+ ", eurekaConfig=" + eurekaConfig
+ ", cloudConfig=" + cloudConfig
+ ", discoveryConfig=" + discoveryConfig
+ ", outboundPortDefinitions=" + outboundPortDefinitions
+ ", outboundPorts=" + outboundPorts
+ ", clientIcmpPingConfig=" + clientIcmpPingConfig
+ ", clusterRoutingConfig=" + clusterRoutingConfig
+ '}';
}
}