keycloak-uncached

Merge pull request #1700 from kodemaniak/master URI based

10/14/2015 2:07: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 90e8c98..bd5a2a2 100755
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
@@ -3,6 +3,7 @@ package org.keycloak.connections.mongo;
 import com.mongodb.DB;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoClientOptions;
+import com.mongodb.MongoClientURI;
 import com.mongodb.MongoCredential;
 import com.mongodb.ServerAddress;
 
@@ -147,31 +148,47 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
      * @throws UnknownHostException
      */
     protected MongoClient createMongoClient() throws UnknownHostException {
-        String host = config.get("host", ServerAddress.defaultHost());
-        int port = config.getInt("port", ServerAddress.defaultPort());
+        operationalInfo = new LinkedHashMap<>();
         String dbName = config.get("db", "keycloak");
 
-        String user = config.get("user");
-        String password = config.get("password");
+        String uriString = config.get("uri");
+        if (uriString != null) {
+            MongoClientURI uri = new MongoClientURI(uriString);
+            MongoClient client = new MongoClient(uri);
 
-        MongoClientOptions clientOptions = getClientOptions();
+            String hosts = String.join(", ", uri.getHosts());
+            operationalInfo.put("mongoHosts", hosts);
+            operationalInfo.put("mongoDatabaseName", dbName);
+            operationalInfo.put("mongoUser", uri.getUsername());
+            operationalInfo.put("mongoDriverVersion", client.getVersion());
 
-        MongoClient client;
-        if (user != null && password != null) {
-            MongoCredential credential = MongoCredential.createMongoCRCredential(user, dbName, password.toCharArray());
-            client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential), clientOptions);
+            logger.debugv("Initialized mongo model. host(s): %s, db: %s", uri.getHosts(), dbName);
+            return client;
         } else {
-            client = new MongoClient(new ServerAddress(host, port), clientOptions);
+            String host = config.get("host", ServerAddress.defaultHost());
+            int port = config.getInt("port", ServerAddress.defaultPort());
+
+            String user = config.get("user");
+            String password = config.get("password");
+
+            MongoClientOptions clientOptions = getClientOptions();
+
+            MongoClient client;
+            if (user != null && password != null) {
+                MongoCredential credential = MongoCredential.createMongoCRCredential(user, dbName, password.toCharArray());
+                client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential), clientOptions);
+            } else {
+                client = new MongoClient(new ServerAddress(host, port), clientOptions);
+            }
+
+            operationalInfo.put("mongoServerAddress", client.getAddress().toString());
+            operationalInfo.put("mongoDatabaseName", dbName);
+            operationalInfo.put("mongoUser", user);
+            operationalInfo.put("mongoDriverVersion", client.getVersion());
+
+            logger.debugv("Initialized mongo model. host: %s, port: %d, db: %s", host, port, dbName);
+            return client;
         }
-        
-        operationalInfo = new LinkedHashMap<>();
-        operationalInfo.put("mongoServerAddress", client.getAddress().toString());
-        operationalInfo.put("mongoDatabaseName", dbName);
-        operationalInfo.put("mongoUser", user);
-        operationalInfo.put("mongoDriverVersion", client.getVersion());
-    		
-        logger.debugv("Initialized mongo model. host: %s, port: %d, db: %s", host, port, dbName);
-        return client;
     }
 
     protected MongoClientOptions getClientOptions() {
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml b/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml
index c702020..2f7a23a 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml
@@ -329,6 +329,30 @@
                 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>
+            <para>
+                Alternatively, you can configure MongoDB using a MongoDB <ulink url="http://docs.mongodb.org/manual/reference/connection-string/">connection URI</ulink>.
+                In this case, you define all information concerning the connection and authentication within the URI, as described in the MongoDB documentation.
+                Please note that the database specified within the URI is only used for authentication. To change the database used by keycloak you have to set
+                <literal>db</literal> property as before. Therefore, a configuration like the
+                following
+                <programlisting><![CDATA[
+"connectionsMongo": {
+    "default": {
+        "uri": "mongodb://user:password@127.0.0.1/authentication",
+        "db": "keycloak"
+    }
+}
+]]></programlisting>
+                will authenticate the user against the authentication database, but store all keycloak related data in the keycloak database.
+
+            </para>
+            <section>
+                <title>MongoDB Replica Sets</title>
+                <para>
+                    In order to use a mongo replica set for Keycloak, one has to use URI based configuration, which supports the
+                    definition of replica sets out of the box: <literal>mongodb://host1:27017,host2:27017,host3:27017/</literal>.
+                </para>
+            </section>
         </section>
         
         <section>