com.mongodb.MongoClientURI Maven / Gradle / Ivy
/*
* Copyright 2008-present MongoDB, Inc.
*
* 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.mongodb;
import com.mongodb.lang.Nullable;
import java.util.List;
import static com.mongodb.assertions.Assertions.notNull;
/**
* Represents a URI
* which can be used to create a MongoClient instance. The URI describes the hosts to
* be used and options.
* The format of the URI is:
*
* mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database.collection][?options]]
*
*
* - {@code mongodb://} is a required prefix to identify that this is a string in the standard connection format.
* - {@code username:password@} are optional. If given, the driver will attempt to login to a database after
* connecting to a database server. For some authentication mechanisms, only the username is specified and the password is not,
* in which case the ":" after the username is left off as well
* - {@code host1} is the only required part of the connection string. It identifies a server address to connect to.
* Support for Unix domain sockets was added in 3.7. Note: The path must be urlencoded eg: {@code mongodb://%2Ftmp%2Fmongodb-27017.sock}
* and the {@code jnr.unixsocket} library installed.
*
- {@code :portX} is optional and defaults to :27017 if not provided.
* - {@code /database} is the name of the database to login to and thus is only relevant if the
* {@code username:password@} syntax is used. If not specified the "admin" database will be used by default.
* - {@code ?options} are connection options. Note that if {@code database} is absent there is still a {@code /}
* required between the last host and the {@code ?} introducing the options. Options are name=value pairs and the pairs
* are separated by "&". For backwards compatibility, ";" is accepted as a separator in addition to "&",
* but should be considered as deprecated.
*
* An alternative format, using the mongodb+srv protocol, is:
*
* mongodb+srv://[username:password@]host[/[database][?options]]
*
*
* - {@code mongodb+srv://} is a required prefix for this format.
* - {@code username:password@} are optional. If given, the driver will attempt to login to a database after
* connecting to a database server. For some authentication mechanisms, only the username is specified and the password is not,
* in which case the ":" after the username is left off as well
* - {@code host} is the only required part of the URI. It identifies a single host name for which SRV records are looked up
* from a Domain Name Server after prefixing the host name with {@code "_mongodb._tcp"}. The host/port for each SRV record becomes the
* seed list used to connect, as if each one were provided as host/port pair in a URI using the normal mongodb protocol.
* - {@code /database} is the name of the database to login to and thus is only relevant if the
* {@code username:password@} syntax is used. If not specified the "admin" database will be used by default.
* - {@code ?options} are connection options. Note that if {@code database} is absent there is still a {@code /}
* required between the last host and the {@code ?} introducing the options. Options are name=value pairs and the pairs
* are separated by "&". For backwards compatibility, ";" is accepted as a separator in addition to "&",
* but should be considered as deprecated. Additionally with the mongodb+srv protocol, TXT records are looked up from a Domain Name
* Server for the given host, and the text value of each one is prepended to any options on the URI itself. Because the last specified
* value for any option wins, that means that options provided on the URI will override any that are provided via TXT records.
*
* The following options are supported (case insensitive):
*
* Server Selection Configuration:
*
* - {@code serverSelectionTimeoutMS=ms}: How long the driver will wait for server selection to succeed before throwing an exception.
* - {@code localThresholdMS=ms}: When choosing among multiple MongoDB servers to send a request, the driver will only
* send that request to a server whose ping time is less than or equal to the server with the fastest ping time plus the local
* threshold.
*
* Server Monitoring Configuration:
*
* - {@code heartbeatFrequencyMS=ms}: The frequency that the driver will attempt to determine the current state of each server in the
* cluster.
*
* Replica set configuration:
*
* - {@code replicaSet=name}: Implies that the hosts given are a seed list, and the driver will attempt to find
* all members of the set.
*
*
* Connection Configuration:
*
* - {@code ssl=true|false}: Whether to connect using TLS.
* - {@code tls=true|false}: Whether to connect using TLS. Supersedes the ssl option
* - {@code tlsInsecure=true|false}: If connecting with TLS, this option enables insecure TLS connections. Currently this has the
* same effect of setting tlsAllowInvalidHostnames to true. Other mechanism for relaxing TLS security constraints must be handled in
* the application by customizing the {@link javax.net.ssl.SSLContext}
* - {@code sslInvalidHostNameAllowed=true|false}: Whether to allow invalid host names for TLS connections.
* - {@code tlsAllowInvalidHostnames=true|false}: Whether to allow invalid host names for TLS connections. Supersedes the
* sslInvalidHostNameAllowed option
* - {@code connectTimeoutMS=ms}: How long a connection can take to be opened before timing out.
* - {@code socketTimeoutMS=ms}: How long a send or receive on a socket can take before timing out.
* - {@code maxIdleTimeMS=ms}: Maximum idle time of a pooled connection. A connection that exceeds this limit will be closed
* - {@code maxLifeTimeMS=ms}: Maximum life time of a pooled connection. A connection that exceeds this limit will be closed
*
*
* Connection pool configuration:
*
* - {@code maxPoolSize=n}: The maximum number of connections in the connection pool.
* - {@code waitQueueMultiple=n} : this multiplier, multiplied with the maxPoolSize setting, gives the maximum number of
* threads that may be waiting for a connection to become available from the pool. All further threads will get an
* exception right away. Note that this configuration option is deprecated and will be removed in the next major release.
* - {@code waitQueueTimeoutMS=ms}: The maximum wait time in milliseconds that a thread may wait for a connection to
* become available.
*
*
* Write concern configuration:
*
* - {@code safe=true|false}
*
* - {@code true}: the driver ensures that all writes are acknowledged by the MongoDB server, or else throws an exception.
* (see also {@code w} and {@code wtimeoutMS}).
* - {@code false}: the driver does not ensure that all writes are acknowledged by the MongoDB server.
*
*
* - {@code journal=true|false}
*
* - {@code true}: the driver waits for the server to group commit to the journal file on disk.
* - {@code false}: the driver does not wait for the server to group commit to the journal file on disk.
*
*
* - {@code w=wValue}
*
* - The driver adds { w : wValue } to all write commands. Implies {@code safe=true}.
* - wValue is typically a number, but can be any string in order to allow for specifications like
* {@code "majority"}
*
*
* - {@code wtimeoutMS=ms}
*
* - The driver adds { wtimeout : ms } to all write commands. Implies {@code safe=true}.
* - Used in combination with {@code w}
*
*
* - {@code retryWrites=true|false}. If true the driver will retry supported write operations if they fail due to a network error.
* Defaults to false.
* - {@code retryReads=true|false}. If true the driver will retry supported read operations if they fail due to a network error.
* Defaults to false.
*
*
*
* Read preference configuration:
*
* - {@code slaveOk=true|false}: Whether a driver connected to a replica set will send reads to slaves/secondaries.
* - {@code readPreference=enum}: The read preference for this connection. If set, it overrides any slaveOk value.
*
* - Enumerated values:
*
* - {@code primary}
* - {@code primaryPreferred}
* - {@code secondary}
* - {@code secondaryPreferred}
* - {@code nearest}
*
*
*
*
* - {@code readPreferenceTags=string}. A representation of a tag set as a comma-separated list of colon-separated
* key-value pairs, e.g. {@code "dc:ny,rack:1}". Spaces are stripped from beginning and end of all keys and values.
* To specify a list of tag sets, using multiple readPreferenceTags,
* e.g. {@code readPreferenceTags=dc:ny,rack:1;readPreferenceTags=dc:ny;readPreferenceTags=}
*
* - Note the empty value for the last one, which means match any secondary as a last resort.
* - Order matters when using multiple readPreferenceTags.
*
*
* - {@code maxStalenessSeconds=seconds}. The maximum staleness in seconds. For use with any non-primary read preference, the driver
* estimates the staleness of each secondary, based on lastWriteDate values provided in server isMaster responses, and selects only those
* secondaries whose staleness is less than or equal to maxStalenessSeconds. Not providing the parameter or explicitly setting it to -1
* indicates that there should be no max staleness check. The maximum staleness feature is designed to prevent badly-lagging servers from
* being selected. The staleness estimate is imprecise and shouldn't be used to try to select "up-to-date" secondaries. The minimum value
* is either 90 seconds, or the heartbeat frequency plus 10 seconds, whichever is greatest.
*
*
* Authentication configuration:
*
* - {@code authMechanism=MONGO-CR|GSSAPI|PLAIN|MONGODB-X509}: The authentication mechanism to use if a credential was supplied.
* The default is unspecified, in which case the client will pick the most secure mechanism available based on the sever version. For the
* GSSAPI and MONGODB-X509 mechanisms, no password is accepted, only the username.
*
* - {@code authSource=string}: The source of the authentication credentials. This is typically the database that
* the credentials have been created. The value defaults to the database specified in the path portion of the URI.
* If the database is specified in neither place, the default value is "admin". This option is only respected when using the MONGO-CR
* mechanism (the default).
*
* - {@code gssapiServiceName=string}: This option only applies to the GSSAPI mechanism and is used to alter the service name..
*
*
* Server Handshake configuration:
*
* - {@code appName=string}: Sets the logical name of the application. The application name may be used by the client to identify
* the application to the server, for use in server logs, slow query logs, and profile collection.
*
* Compressor configuration:
*
* - {@code compressors=string}: A comma-separated list of compressors to request from the server. The supported compressors
* currently are 'zlib', 'snappy' and 'zstd'.
* - {@code zlibCompressionLevel=integer}: Integer value from -1 to 9 representing the zlib compression level. Lower values will make
* compression faster, while higher values will make compression better.
*
* General configuration:
*
* - {@code retryWrites=true|false}. If true the driver will retry supported write operations if they fail due to a network error.
* Defaults to true.
* - {@code retryReads=true|false}. If true the driver will retry supported read operations if they fail due to a network error.
* Defaults to true.
* - {@code uuidRepresentation=unspecified|standard|javaLegacy|csharpLegacy|pythonLegacy}. See
* {@link MongoClientOptions#getUuidRepresentation()} for documentation of semantics of this parameter. Defaults to "javaLegacy", but
* will change to "unspecified" in the next major release.
*
*
* Note: This class is a replacement for {@code MongoURI}, to be used with {@code MongoClient}. The main difference in
* behavior is that the default write concern is {@code WriteConcern.ACKNOWLEDGED}.
*
* @mongodb.driver.manual reference/connection-string Connection String URI Format
* @see MongoClientOptions for the default values for all options
* @since 2.10.0
*/
@SuppressWarnings({ "deprecation" })
public class MongoClientURI {
private final ConnectionString proxied;
private final MongoClientOptions.Builder builder;
/**
* Creates a MongoURI from the given string.
*
* @param uri the URI
*/
public MongoClientURI(final String uri) {
this(uri, new MongoClientOptions.Builder());
}
/**
* Creates a MongoURI from the given URI string, and MongoClientOptions.Builder. The builder can be configured with default options,
* which may be overridden by options specified in the URI string.
*
*
* The {@code MongoClientURI} takes ownership of the {@code MongoClientOptions.Builder} instance that is passed to this constructor,
* and may modify it.
*
*
* @param uri the URI
* @param builder a non-null Builder, which may be modified within this constructor,
* @since 2.11.0
*/
public MongoClientURI(final String uri, final MongoClientOptions.Builder builder) {
this.builder = notNull("builder", builder);
proxied = new ConnectionString(uri);
}
ConnectionString getProxied() {
return proxied;
}
// ---------------------------------
/**
* Gets the username
*
* @return the username
*/
@Nullable
public String getUsername() {
return proxied.getUsername();
}
/**
* Gets the password
*
* @return the password
*/
@Nullable
public char[] getPassword() {
return proxied.getPassword();
}
/**
* Gets the list of hosts
*
* @return the host list
*/
public List getHosts() {
return proxied.getHosts();
}
/**
* Gets the database name
*
* @return the database name
*/
@Nullable
public String getDatabase() {
return proxied.getDatabase();
}
/**
* Gets the collection name
*
* @return the collection name
*/
@Nullable
public String getCollection() {
return proxied.getCollection();
}
/**
* Get the unparsed URI.
*
* @return the URI
*/
public String getURI() {
return proxied.getConnectionString();
}
/**
* Gets the credentials.
*
* @return the credentials
*/
@Nullable
public MongoCredential getCredentials() {
return proxied.getCredential();
}
/**
* Gets the options
*
* @return the MongoClientOptions based on this URI.
*/
public MongoClientOptions getOptions() {
ReadPreference readPreference = proxied.getReadPreference();
if (readPreference != null) {
builder.readPreference(readPreference);
}
ReadConcern readConcern = proxied.getReadConcern();
if (readConcern != null) {
builder.readConcern(readConcern);
}
WriteConcern writeConcern = proxied.getWriteConcern();
if (writeConcern != null) {
builder.writeConcern(writeConcern);
}
if (proxied.getRetryWritesValue() != null) {
builder.retryWrites(proxied.getRetryWritesValue());
}
if (proxied.getRetryReads() != null) {
builder.retryReads(proxied.getRetryReads());
}
Integer maxConnectionPoolSize = proxied.getMaxConnectionPoolSize();
if (maxConnectionPoolSize != null) {
builder.connectionsPerHost(maxConnectionPoolSize);
}
Integer integer = proxied.getMinConnectionPoolSize();
if (integer != null) {
builder.minConnectionsPerHost(integer);
}
Integer maxWaitTime = proxied.getMaxWaitTime();
if (maxWaitTime != null) {
builder.maxWaitTime(maxWaitTime);
}
Integer threadsAllowedToBlockForConnectionMultiplier = proxied.getThreadsAllowedToBlockForConnectionMultiplier();
if (threadsAllowedToBlockForConnectionMultiplier != null) {
builder.threadsAllowedToBlockForConnectionMultiplier(threadsAllowedToBlockForConnectionMultiplier);
}
Integer maxConnectionIdleTime = proxied.getMaxConnectionIdleTime();
if (maxConnectionIdleTime != null) {
builder.maxConnectionIdleTime(maxConnectionIdleTime);
}
Integer maxConnectionLifeTime = proxied.getMaxConnectionLifeTime();
if (maxConnectionLifeTime != null) {
builder.maxConnectionLifeTime(maxConnectionLifeTime);
}
Integer socketTimeout = proxied.getSocketTimeout();
if (socketTimeout != null) {
builder.socketTimeout(socketTimeout);
}
Integer connectTimeout = proxied.getConnectTimeout();
if (connectTimeout != null) {
builder.connectTimeout(connectTimeout);
}
String requiredReplicaSetName = proxied.getRequiredReplicaSetName();
if (requiredReplicaSetName != null) {
builder.requiredReplicaSetName(requiredReplicaSetName);
}
Boolean sslEnabled = proxied.getSslEnabled();
if (sslEnabled != null) {
builder.sslEnabled(sslEnabled);
}
Boolean sslInvalidHostnameAllowed = proxied.getSslInvalidHostnameAllowed();
if (sslInvalidHostnameAllowed != null) {
builder.sslInvalidHostNameAllowed(sslInvalidHostnameAllowed);
}
Integer serverSelectionTimeout = proxied.getServerSelectionTimeout();
if (serverSelectionTimeout != null) {
builder.serverSelectionTimeout(serverSelectionTimeout);
}
Integer localThreshold = proxied.getLocalThreshold();
if (localThreshold != null) {
builder.localThreshold(localThreshold);
}
Integer heartbeatFrequency = proxied.getHeartbeatFrequency();
if (heartbeatFrequency != null) {
builder.heartbeatFrequency(heartbeatFrequency);
}
String applicationName = proxied.getApplicationName();
if (applicationName != null) {
builder.applicationName(applicationName);
}
if (!proxied.getCompressorList().isEmpty()) {
builder.compressorList(proxied.getCompressorList());
}
return builder.build();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MongoClientURI that = (MongoClientURI) o;
if (!getHosts().equals(that.getHosts())) {
return false;
}
String database = getDatabase();
if (database != null ? !database.equals(that.getDatabase()) : that.getDatabase() != null) {
return false;
}
String collection = getCollection();
if (collection != null ? !collection.equals(that.getCollection()) : that.getCollection() != null) {
return false;
}
MongoCredential credentials = getCredentials();
if (credentials != null ? !credentials.equals(that.getCredentials()) : that.getCredentials() != null) {
return false;
}
if (!getOptions().equals(that.getOptions())) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = getOptions().hashCode();
result = 31 * result + getHosts().hashCode();
MongoCredential credentials = getCredentials();
result = 31 * result + (credentials != null ? credentials.hashCode() : 0);
String database = getDatabase();
result = 31 * result + (database != null ? database.hashCode() : 0);
String collection = getCollection();
result = 31 * result + (collection != null ? collection.hashCode() : 0);
return result;
}
@Override
public String toString() {
return proxied.toString();
}
}