Merge pull request #819 from mposolda/master

KEYCLOAK-799 - Configurable connections pooling for mongo client
This commit is contained in:
Marek Posolda 2014-10-30 11:20:03 +01:00
commit 0234bdb619
3 changed files with 55 additions and 4 deletions

View file

@ -2,6 +2,7 @@ package org.keycloak.connections.mongo;
import com.mongodb.DB; import com.mongodb.DB;
import com.mongodb.MongoClient; import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential; import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress; import com.mongodb.ServerAddress;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -12,6 +13,7 @@ import org.keycloak.connections.mongo.impl.context.TransactionMongoStoreInvocati
import org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider; import org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
/** /**
@ -68,11 +70,13 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
String user = config.get("user"); String user = config.get("user");
String password = config.get("password"); String password = config.get("password");
MongoClientOptions clientOptions = getClientOptions();
if (user != null && password != null) { if (user != null && password != null) {
MongoCredential credential = MongoCredential.createMongoCRCredential(user, dbName, password.toCharArray()); MongoCredential credential = MongoCredential.createMongoCRCredential(user, dbName, password.toCharArray());
client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential)); client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential), clientOptions);
} else { } else {
client = new MongoClient(host, port); client = new MongoClient(new ServerAddress(host, port), clientOptions);
} }
this.db = client.getDB(dbName); this.db = client.getDB(dbName);
@ -117,4 +121,43 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
return "default"; return "default";
} }
protected MongoClientOptions getClientOptions() {
MongoClientOptions.Builder builder = MongoClientOptions.builder();
checkIntOption("connectionsPerHost", builder);
checkIntOption("threadsAllowedToBlockForConnectionMultiplier", builder);
checkIntOption("maxWaitTime", builder);
checkIntOption("connectTimeout", builder);
checkIntOption("socketTimeout", builder);
checkBooleanOption("socketKeepAlive", builder);
checkBooleanOption("autoConnectRetry", builder);
if (config.getLong("maxAutoConnectRetryTime") != null) {
builder.maxAutoConnectRetryTime(config.getLong("maxAutoConnectRetryTime"));
}
return builder.build();
}
protected void checkBooleanOption(String optionName, MongoClientOptions.Builder builder) {
Boolean val = config.getBoolean(optionName);
if (val != null) {
try {
Method m = MongoClientOptions.Builder.class.getMethod(optionName, boolean.class);
m.invoke(builder, val);
} catch (Exception e) {
throw new IllegalStateException("Problem configuring boolean option " + optionName + " for mongo client. Ensure you used correct value true or false and if this option is supported by mongo driver", e);
}
}
}
protected void checkIntOption(String optionName, MongoClientOptions.Builder builder) {
Integer val = config.getInt(optionName);
if (val != null) {
try {
Method m = MongoClientOptions.Builder.class.getMethod(optionName, int.class);
m.invoke(builder, val);
} catch (Exception e) {
throw new IllegalStateException("Problem configuring int option " + optionName + " for mongo client. Ensure you used correct value (number) and if this option is supported by mongo driver", e);
}
}
}
} }

View file

@ -370,7 +370,8 @@ keycloak-war-dist-all-&project.version;/
"default": { "default": {
"host": "127.0.0.1", "host": "127.0.0.1",
"port": "27017", "port": "27017",
"db": "keycloak" "db": "keycloak",
"connectionsPerHost": 100
} }
} }
]]></programlisting> ]]></programlisting>
@ -380,6 +381,12 @@ keycloak-war-dist-all-&project.version;/
if you want authenticate against your MongoDB. If user and password are not specified, Keycloak will connect if you want authenticate against your MongoDB. If user and password are not specified, Keycloak will connect
unauthenticated to your MongoDB. unauthenticated to your MongoDB.
</para> </para>
<para>Finally there is set of optional configuration options, which can be used to specify connection-pooling capabilities of Mongo client. Supported int options are:
<literal>connectionsPerHost</literal>, <literal>threadsAllowedToBlockForConnectionMultiplier</literal>, <literal>maxWaitTime</literal>, <literal>connectTimeout</literal>
<literal>socketTimeout</literal>. Supported boolean options are: <literal>socketKeepAlive</literal>, <literal>autoConnectRetry</literal>.
Supported long option is <literal>maxAutoConnectRetryTime</literal>. See <ulink url="http://api.mongodb.org/java/2.11.4/com/mongodb/MongoClientOptions.html">Mongo documentation</ulink>
for details about those options and their default values.
</para>
</section> </section>
<section> <section>

View file

@ -78,7 +78,8 @@
"host": "${keycloak.connectionsMongo.host:127.0.0.1}", "host": "${keycloak.connectionsMongo.host:127.0.0.1}",
"port": "${keycloak.connectionsMongo.port:27017}", "port": "${keycloak.connectionsMongo.port:27017}",
"db": "${keycloak.connectionsMongo.db:keycloak}", "db": "${keycloak.connectionsMongo.db:keycloak}",
"databaseSchema": "${keycloak.connectionsMongo.databaseSchema:update}" "databaseSchema": "${keycloak.connectionsMongo.databaseSchema:update}",
"connectionsPerHost": "${keycloak.connectionsMongo.connectionsPerHost:100}"
} }
} }
} }