All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.otto.edison.mongo.configuration.MongoProperties Maven / Gradle / Ivy

The newest version!
package de.otto.edison.mongo.configuration;

import com.mongodb.*;
import com.mongodb.event.CommandListener;
import de.otto.edison.status.domain.Datasource;
import org.bson.codecs.configuration.CodecRegistry;
import org.slf4j.Logger;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

import static com.mongodb.MongoCredential.createCredential;
import static de.otto.edison.status.domain.Datasource.datasource;
import static java.util.Objects.nonNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.stream.Collectors.toList;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Properties used to configure MongoDB clients.
 *
 * @since 1.0.0
 */
@ConfigurationProperties(prefix = "edison.mongo")
@Validated
public class MongoProperties {
    private static final Logger LOG = getLogger(MongoProperties.class);

    /**
     * The MongoDB servers. Comma-separated list of host:port pairs. Can be overridden by specifying uri or uriPattern
     */
    @NotEmpty
    private String[] host = {"localhost"};

    /**
     * The MongoDB connection uri pattern (will be converted to a MongoUri after replacing %s:%s@ with username and password)
     */
    private String uriPattern;

    /**
     * The MongoURI
     */
    private String uri;

    /**
     * The MongoDB database.
     */
    private String authenticationDb = "";

    /**
     * The MongoDB database.
     */
    @NotEmpty
    private String db;

    /**
     * database user name
     */
    private String user = "";

    /**
     * database user password
     */
    private String password = "";

    /**
     * database user password
     */
    private boolean sslEnabled;

    /**
     * Represents preferred replica set members to which a query or command can be sent.
     */
    @NotEmpty
    private String readPreference = "primaryPreferred";

    /**
     * Represents preferred write concern to which a query or command can be sent.
     */
    private String writeConcern;

    /**
     * Maximum time that a thread will block waiting for a connection.
     */
    @Min(10)
    private int maxWaitTime = 5000;

    /**
     * Connection timeout in milliseconds. Must be > 0
     */
    @Min(10)
    private int connectTimeout = 5000;

    /**
     * The default timeout in milliseconds to use for reading operations.
     */
    @Min(10)
    private int defaultReadTimeout = 2000;

    /**
     * The default timeout in milliseconds to use for writing operations.
     */
    @Min(10)
    private int defaultWriteTimeout = 2000;

    /**
     * Sets the server selection timeout in milliseconds, which defines how long the driver will wait for server selection to
     * succeed before throwing an exception.
     */
    @Min(1)
    private int serverSelectionTimeout = 30000;
    @Valid
    private Status status = new Status();
    /**
     * Connection pool properties.
     */
    @Valid
    private Connectionpool connectionpool = new Connectionpool();

    /**
     * Sets whether client server connections will be compressed.
     * Set to "true", to enable.
     * 

* You need to add dependencies to your application in order to use certain compression algorithms: *

    *
  • for ZstdCompressor, add the dependency to com.github.luben:zstd-jni:1.4.4-9
  • *
  • for SnappyCompressor, add the dependency to org.xerial.snappy:snappy-java:1.1.7.4
  • *
*/ private boolean clientServerCompressionEnabled = false; public Status getStatus() { return status; } public void setStatus(final Status status) { this.status = status; } public int getDefaultReadTimeout() { return defaultReadTimeout; } public void setDefaultReadTimeout(int defaultReadTimeout) { this.defaultReadTimeout = defaultReadTimeout; } public int getDefaultWriteTimeout() { return defaultWriteTimeout; } public void setDefaultWriteTimeout(int defaultWriteTimeout) { this.defaultWriteTimeout = defaultWriteTimeout; } public List toDatasources() { return Stream.of(getHost()) .map(host -> datasource(host + "/" + getDb())) .collect(toList()); } public List getServers() { return Stream.of(host) .filter(Objects::nonNull) .map(this::toServerAddress) .filter(Objects::nonNull) .collect(toList()); } public String[] getHost() { return host; } public void setHost(final String[] host) { this.host = host; } public String getUriPattern() { return uriPattern; } public void setUriPattern(final String uriPattern) { this.uriPattern = uriPattern; } public String getUri() { return uri; } public void setUri(String uri) { this.uri = uri; } public String getAuthenticationDb() { return authenticationDb; } public void setAuthenticationDb(final String authenticationDb) { this.authenticationDb = authenticationDb; } public String getDb() { return db; } public void setDb(final String db) { this.db = db; } public String getUser() { return user; } public void setUser(final String user) { this.user = user; } public String getPassword() { return password; } public void setPassword(final String password) { this.password = password; } public boolean isSslEnabled() { return sslEnabled; } public void setSslEnabled(final boolean sslEnabled) { this.sslEnabled = sslEnabled; } public String getReadPreference() { return readPreference; } public void setReadPreference(final String readPreference) { this.readPreference = readPreference; } public String getWriteConcern() { return writeConcern; } public void setWriteConcern(final String writeConcern) { this.writeConcern = writeConcern; } public int getMaxWaitTime() { return maxWaitTime; } public void setMaxWaitTime(final int maxWaitTime) { this.maxWaitTime = maxWaitTime; } public int getConnectTimeout() { return connectTimeout; } public void setConnectTimeout(final int connectTimeout) { this.connectTimeout = connectTimeout; } public int getServerSelectionTimeout() { return serverSelectionTimeout; } public void setServerSelectionTimeout(final int serverSelectionTimeout) { this.serverSelectionTimeout = serverSelectionTimeout; } public Connectionpool getConnectionpool() { return connectionpool; } public void setConnectionpool(final Connectionpool connectionpool) { this.connectionpool = connectionpool; } public boolean isClientServerCompressionEnabled() { return clientServerCompressionEnabled; } public void setClientServerCompressionEnabled(boolean clientServerCompressionEnabled) { this.clientServerCompressionEnabled = clientServerCompressionEnabled; } public MongoClientSettings toMongoClientSettings(final CodecRegistry codecRegistry, final List possibleCompressors, final List commandListeners) { MongoClientSettings.Builder clientOptionsBuilder = MongoClientSettings.builder() .applyToSslSettings(builder -> builder.enabled(sslEnabled)) .codecRegistry(codecRegistry) .readPreference(ReadPreference.valueOf(readPreference)) .applyToConnectionPoolSettings(pool -> pool .minSize(connectionpool.getMinSize()) .maxSize(connectionpool.getMaxSize()) .maxConnectionIdleTime(connectionpool.getMaxIdleTime(), MILLISECONDS) .maxConnectionLifeTime(connectionpool.getMaxLifeTime(), MILLISECONDS) .maxWaitTime(maxWaitTime, MILLISECONDS)) .applyToSocketSettings(socket -> socket .connectTimeout(connectTimeout, MILLISECONDS)); if (nonNull(uriPattern) && !uriPattern.isBlank()) { clientOptionsBuilder .applyConnectionString(getConnectionString()) .applyToClusterSettings(cluster -> cluster .serverSelectionTimeout(serverSelectionTimeout, MILLISECONDS)); } else if (nonNull(uri) && !uri.isBlank()) { clientOptionsBuilder .applyConnectionString(new ConnectionString(uri)) .applyToClusterSettings(cluster -> cluster .serverSelectionTimeout(serverSelectionTimeout, MILLISECONDS)); if (useAuthorizedConnection()) { clientOptionsBuilder.credential(getMongoCredentials()); } } else { clientOptionsBuilder.applyToClusterSettings(cluster -> cluster .hosts(getServers()) .serverSelectionTimeout(serverSelectionTimeout, MILLISECONDS)); if (useAuthorizedConnection()) { clientOptionsBuilder.credential(getMongoCredentials()); } } if (isClientServerCompressionEnabled()) { clientOptionsBuilder.compressorList(possibleCompressors); } if (nonNull(writeConcern)) { clientOptionsBuilder.writeConcern(WriteConcern.valueOf(writeConcern)); } if (nonNull(commandListeners)) { commandListeners.forEach(e->clientOptionsBuilder.addCommandListener(e)); } return clientOptionsBuilder.build(); } private ConnectionString getConnectionString() { final String connectionString = uriPattern.contains("%s:%s@") ? String.format(getUriPattern(), getUser(), getPassword()) : getUriPattern(); return new ConnectionString(connectionString); } private boolean useAuthorizedConnection() { return !getUser().isEmpty() && !getPassword().isEmpty(); } private MongoCredential getMongoCredentials() { return createCredential( getUser(), getAuthenticationDb(), getPassword().toCharArray() ); } private ServerAddress toServerAddress(final String server) { try { if (server.contains(":")) { final String[] hostNamePortPair = server.split(":"); return new ServerAddress(hostNamePortPair[0], Integer.parseInt(hostNamePortPair[1])); } else { return new ServerAddress(server); } } catch (final NumberFormatException e) { LOG.warn("Invalid portNumber: " + e.getMessage(), e); return null; } } /** * Creates a StatusDetailIndicator that checks the MongoDB connection through a ping command */ public static class Status { /** * Enable / disable the MongoDB StatusDetailIndicator */ private boolean enabled = true; public boolean isEnabled() { return enabled; } public void setEnabled(final boolean enabled) { this.enabled = enabled; } } public static class Connectionpool { /** * Maximum number of connections allowed per host. */ @Min(1) private int maxSize = 100; /** * The minimum number of connections per host. A value of 0 will create connections lazily. */ @Min(0) private int minSize = 2; /** * This multiplier, multiplied with the maxSize property, gives the maximum number of threads that may be waiting for a * connection to become available from the pool. */ @Min(1) private int blockedConnectionMultiplier = 2; /** * Maximum life time for a pooled connection. */ @Min(1) private int maxLifeTime = 100000; /** * Maximum idle time for a pooled connection. */ @Min(1) private int maxIdleTime = 10000; public int getMaxSize() { return maxSize; } public void setMaxSize(final int maxSize) { this.maxSize = maxSize; } public int getMinSize() { return minSize; } public void setMinSize(final int minSize) { this.minSize = minSize; } public int getBlockedConnectionMultiplier() { return blockedConnectionMultiplier; } public void setBlockedConnectionMultiplier(final int blockedConnectionMultiplier) { this.blockedConnectionMultiplier = blockedConnectionMultiplier; } public int getMaxLifeTime() { return maxLifeTime; } public void setMaxLifeTime(final int maxLifeTime) { this.maxLifeTime = maxLifeTime; } public int getMaxIdleTime() { return maxIdleTime; } public void setMaxIdleTime(final int maxIdleTime) { this.maxIdleTime = maxIdleTime; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy