keycloak-aplcache

Merge pull request #819 from mposolda/master KEYCLOAK-799

10/30/2014 8:20:03 AM

Details

diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
index f800dfb..341cb01 100644
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
@@ -2,6 +2,7 @@ package org.keycloak.connections.mongo;
 
 import com.mongodb.DB;
 import com.mongodb.MongoClient;
+import com.mongodb.MongoClientOptions;
 import com.mongodb.MongoCredential;
 import com.mongodb.ServerAddress;
 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.models.KeycloakSession;
 
+import java.lang.reflect.Method;
 import java.util.Collections;
 
 /**
@@ -68,11 +70,13 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
 
                         String user = config.get("user");
                         String password = config.get("password");
+
+                        MongoClientOptions clientOptions = getClientOptions();
                         if (user != null && password != null) {
                             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 {
-                            client = new MongoClient(host, port);
+                            client = new MongoClient(new ServerAddress(host, port), clientOptions);
                         }
 
                         this.db = client.getDB(dbName);
@@ -117,4 +121,43 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
         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);
+            }
+        }
+    }
+
 }
diff --git a/docbook/reference/en/en-US/modules/server-installation.xml b/docbook/reference/en/en-US/modules/server-installation.xml
index 5ca0cd8..e39fc4d 100755
--- a/docbook/reference/en/en-US/modules/server-installation.xml
+++ b/docbook/reference/en/en-US/modules/server-installation.xml
@@ -370,7 +370,8 @@ keycloak-war-dist-all-&project.version;/
     "default": {
         "host": "127.0.0.1",
         "port": "27017",
-        "db": "keycloak"
+        "db": "keycloak",
+        "connectionsPerHost": 100
     }
 }
 ]]></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
                 unauthenticated to your MongoDB.
             </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>
diff --git a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
index 728631d..188db1e 100755
--- a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
@@ -78,7 +78,8 @@
             "host": "${keycloak.connectionsMongo.host:127.0.0.1}",
             "port": "${keycloak.connectionsMongo.port:27017}",
             "db": "${keycloak.connectionsMongo.db:keycloak}",
-            "databaseSchema": "${keycloak.connectionsMongo.databaseSchema:update}"
+            "databaseSchema": "${keycloak.connectionsMongo.databaseSchema:update}",
+            "connectionsPerHost": "${keycloak.connectionsMongo.connectionsPerHost:100}"
         }
     }
 }
\ No newline at end of file