/*
* 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.facebook.presto.mongodb;
import com.google.common.base.Splitter;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import io.airlift.configuration.Config;
import io.airlift.configuration.DefunctConfig;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Arrays;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
import static com.mongodb.MongoCredential.createCredential;
@DefunctConfig("mongodb.connection-per-host")
public class MongoClientConfig
{
private static final Splitter SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
private static final Splitter PORT_SPLITTER = Splitter.on(':').trimResults().omitEmptyStrings();
private static final Splitter USER_SPLITTER = Splitter.onPattern("[:@]").trimResults().omitEmptyStrings();
private String schemaCollection = "_schema";
private List<ServerAddress> seeds = ImmutableList.of();
private List<MongoCredential> credentials = ImmutableList.of();
private int minConnectionsPerHost = 0;
private int connectionsPerHost = 100;
private int maxWaitTime = 120_000;
private int connectionTimeout = 10_000;
private int socketTimeout = 0;
private boolean socketKeepAlive = false;
private boolean sslEnabled = false;
// query configurations
private int cursorBatchSize = 0; // use driver default
private ReadPreferenceType readPreference = ReadPreferenceType.PRIMARY;
private WriteConcernType writeConcern = WriteConcernType.ACKNOWLEDGED;
private String requiredReplicaSetName;
private String implicitRowFieldPrefix = "_pos";
@NotNull
public String getSchemaCollection()
{
return schemaCollection;
}
@Config("mongodb.schema-collection")
public MongoClientConfig setSchemaCollection(String schemaCollection)
{
this.schemaCollection = schemaCollection;
return this;
}
@NotNull
@Size(min = 1)
public List<ServerAddress> getSeeds()
{
return seeds;
}
@Config("mongodb.seeds")
public MongoClientConfig setSeeds(String commaSeparatedList)
{
this.seeds = buildSeeds(SPLITTER.split(commaSeparatedList));
return this;
}
public MongoClientConfig setSeeds(String... seeds)
{
this.seeds = buildSeeds(Arrays.asList(seeds));
return this;
}
@NotNull
@Size(min = 0)
public List<MongoCredential> getCredentials()
{
return credentials;
}
@Config("mongodb.credentials")
public MongoClientConfig setCredentials(String credentials)
{
this.credentials = buildCredentials(SPLITTER.split(credentials));
return this;
}
public MongoClientConfig setCredentials(String... credentials)
{
this.credentials = buildCredentials(Arrays.asList(credentials));
return this;
}
private List<ServerAddress> buildSeeds(Iterable<String> hostPorts)
{
ImmutableList.Builder<ServerAddress> builder = ImmutableList.builder();
for (String hostPort : hostPorts) {
List<String> values = PORT_SPLITTER.splitToList(hostPort);
checkArgument(values.size() == 1 || values.size() == 2, "Invalid ServerAddress format. Requires host[:port]");
try {
if (values.size() == 1) {
builder.add(new ServerAddress(values.get(0)));
}
else {
builder.add(new ServerAddress(values.get(0), Integer.parseInt(values.get(1))));
}
}
catch (NumberFormatException e) {
throw Throwables.propagate(e);
}
}
return builder.build();
}
private List<MongoCredential> buildCredentials(Iterable<String> userPasses)
{
ImmutableList.Builder<MongoCredential> builder = ImmutableList.builder();
for (String userPass : userPasses) {
List<String> values = USER_SPLITTER.splitToList(userPass);
checkArgument(values.size() == 3, "Invalid Credential format. Requires user:password@collection");
builder.add(createCredential(values.get(0), values.get(2), values.get(1).toCharArray()));
}
return builder.build();
}
@Min(0)
public int getMinConnectionsPerHost()
{
return minConnectionsPerHost;
}
@Config("mongodb.min-connections-per-host")
public MongoClientConfig setMinConnectionsPerHost(int minConnectionsPerHost)
{
this.minConnectionsPerHost = minConnectionsPerHost;
return this;
}
@Min(1)
public int getConnectionsPerHost()
{
return connectionsPerHost;
}
@Config("mongodb.connections-per-host")
public MongoClientConfig setConnectionsPerHost(int connectionsPerHost)
{
this.connectionsPerHost = connectionsPerHost;
return this;
}
@Min(0)
public int getMaxWaitTime()
{
return maxWaitTime;
}
@Config("mongodb.max-wait-time")
public MongoClientConfig setMaxWaitTime(int maxWaitTime)
{
this.maxWaitTime = maxWaitTime;
return this;
}
@Min(0)
public int getConnectionTimeout()
{
return connectionTimeout;
}
@Config("mongodb.connection-timeout")
public MongoClientConfig setConnectionTimeout(int connectionTimeout)
{
this.connectionTimeout = connectionTimeout;
return this;
}
@Min(0)
public int getSocketTimeout()
{
return socketTimeout;
}
@Config("mongodb.socket-timeout")
public MongoClientConfig setSocketTimeout(int socketTimeout)
{
this.socketTimeout = socketTimeout;
return this;
}
public boolean getSocketKeepAlive()
{
return socketKeepAlive;
}
@Config("mongodb.socket-keep-alive")
public MongoClientConfig setSocketKeepAlive(boolean socketKeepAlive)
{
this.socketKeepAlive = socketKeepAlive;
return this;
}
public ReadPreferenceType getReadPreference()
{
return readPreference;
}
@Config("mongodb.read-preference")
public MongoClientConfig setReadPreference(ReadPreferenceType readPreference)
{
this.readPreference = readPreference;
return this;
}
public WriteConcernType getWriteConcern()
{
return writeConcern;
}
@Config("mongodb.write-concern")
public MongoClientConfig setWriteConcern(WriteConcernType writeConcern)
{
this.writeConcern = writeConcern;
return this;
}
public String getRequiredReplicaSetName()
{
return requiredReplicaSetName;
}
@Config("mongodb.required-replica-set")
public MongoClientConfig setRequiredReplicaSetName(String requiredReplicaSetName)
{
this.requiredReplicaSetName = requiredReplicaSetName;
return this;
}
public int getCursorBatchSize()
{
return cursorBatchSize;
}
@Config("mongodb.cursor-batch-size")
public MongoClientConfig setCursorBatchSize(int cursorBatchSize)
{
this.cursorBatchSize = cursorBatchSize;
return this;
}
public String getImplicitRowFieldPrefix()
{
return implicitRowFieldPrefix;
}
@Config("mongodb.implicit-row-field-prefix")
public MongoClientConfig setImplicitRowFieldPrefix(String implicitRowFieldPrefix)
{
this.implicitRowFieldPrefix = implicitRowFieldPrefix;
return this;
}
public boolean getSslEnabled()
{
return this.sslEnabled;
}
@Config("mongodb.ssl.enabled")
public MongoClientConfig setSslEnabled(boolean sslEnabled)
{
this.sslEnabled = sslEnabled;
return this;
}
}