Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 5bb7cc693 -> 841db6a25


Adds mongoDB authentication


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/1d0e2548
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/1d0e2548
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/1d0e2548

Branch: refs/heads/master
Commit: 1d0e2548cc9b5a5ddf81138c4753c5e915644129
Parents: 07ec193
Author: Martin Harris <[email protected]>
Authored: Fri Aug 14 14:13:55 2015 +0100
Committer: Martin Harris <[email protected]>
Committed: Mon Sep 14 16:36:21 2015 +0100

----------------------------------------------------------------------
 .../hello-world-sql/src/main/webapp/mongo.jsp   | 12 ++-
 software/nosql/pom.xml                          |  1 +
 .../nosql/mongodb/AbstractMongoDBServer.java    |  3 +-
 .../nosql/mongodb/AbstractMongoDBSshDriver.java | 81 ++++++++++++++++----
 .../mongodb/MongoDBAuthenticationMixins.java    | 51 ++++++++++++
 .../mongodb/MongoDBAuthenticationUtils.java     | 79 +++++++++++++++++++
 .../nosql/mongodb/MongoDBClientSupport.java     | 26 +++++--
 .../entity/nosql/mongodb/MongoDBReplicaSet.java |  2 +-
 .../nosql/mongodb/MongoDBReplicaSetImpl.java    |  8 +-
 .../entity/nosql/mongodb/MongoDBServerImpl.java |  1 -
 .../sharding/CoLocatedMongoDBRouterImpl.java    | 44 ++++++++---
 .../sharding/MongoDBRouterSshDriver.java        |  4 +
 .../sharding/MongoDBShardedDeploymentImpl.java  | 40 +++++++---
 .../nosql/src/test/resources/mongodb-keyfile    | 16 ++++
 .../resources/mongo-sharded-authentication.yaml | 45 +++++++++++
 .../src/test/resources/mongo-sharded.yaml       |  6 +-
 usage/launcher/src/test/resources/mongo.key     | 16 ++++
 .../apache/brooklyn/util/ssh/BashCommands.java  |  7 ++
 18 files changed, 392 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp
----------------------------------------------------------------------
diff --git a/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp 
b/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp
index 50a9a68..7e110cc 100644
--- a/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp
+++ b/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp
@@ -1,4 +1,5 @@
 <%@ page language="java" import="java.sql.*,com.mongodb.*"%>
+<%@ page import="java.util.Arrays" %>
 
 <html>
 <!--
@@ -39,6 +40,9 @@
 
 <%
 String port=System.getProperty("brooklyn.example.mongodb.port");
+String username=System.getProperty("brooklyn.example.mongodb.username");
+String password=System.getProperty("brooklyn.example.mongodb.password");
+String 
authenticationDatabase=System.getProperty("brooklyn.example.mongodb.authenticationDatabase");
 //URL should be supplied e.g. 
""-Dbrooklyn.example.db.url=jdbc:mysql://localhost/visitors?user=brooklyn&password=br00k11n"
 //(note quoting needed due to ampersand)
 if (port==null) {
@@ -51,7 +55,13 @@ if (port==null) {
 
 <%
 /* begin database-enabled block */ }
-MongoClient client = new MongoClient("localhost", new Integer(port));
+MongoCredential credential = MongoCredential.createMongoCRCredential(username, 
authenticationDatabase, password.toCharArray());
+ServerAddress address = new ServerAddress("localhost", new Integer(port));
+MongoClientOptions connectionOptions = MongoClientOptions.builder()
+    .autoConnectRetry(true)
+    .socketKeepAlive(true)
+    .build();
+MongoClient client = new MongoClient(address, 
Arrays.asList(credential),connectionOptions);
 DB database = client.getDB("visitors");
 DBCollection messages =  database.getCollection("messages");
 int i=0;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/pom.xml
----------------------------------------------------------------------
diff --git a/software/nosql/pom.xml b/software/nosql/pom.xml
index b0d5b6c..be0887d 100644
--- a/software/nosql/pom.xml
+++ b/software/nosql/pom.xml
@@ -265,6 +265,7 @@
                 <exclude>src/test/resources/test-mongodb.conf</exclude>
                 
<exclude>src/test/resources/test-mongodb-configserver.conf</exclude>
                 <exclude>src/test/resources/test-mongodb-router.conf</exclude>
+                <exclude>src/test/resources/mongodb-keyfile</exclude>
                 
<exclude>src/main/resources/org/apache/brooklyn/entity/nosql/redis/redis.conf</exclude>
                 
<exclude>src/main/resources/org/apache/brooklyn/entity/nosql/redis/slave.conf</exclude>
                 
<exclude>src/main/resources/org/apache/brooklyn/entity/nosql/riak/app.config</exclude>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
index 52e24d8..5947a43 100644
--- 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
@@ -27,7 +27,7 @@ import 
org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
 import org.apache.brooklyn.util.core.flags.SetFromFlag;
 
-public interface AbstractMongoDBServer extends SoftwareProcess, Entity {
+public interface AbstractMongoDBServer extends SoftwareProcess, Entity, 
MongoDBAuthenticationMixins {
 
     // TODO Need to properly test v2.4.x and v2.5.x support.
     // I think the v2.5.x were dev releases.
@@ -58,4 +58,5 @@ public interface AbstractMongoDBServer extends 
SoftwareProcess, Entity {
     @SetFromFlag("port")
     PortAttributeSensorAndConfigKey PORT =
             new PortAttributeSensorAndConfigKey("mongodb.server.port", "Server 
port", "27017+");
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
index c6974d4..9fe949d 100644
--- 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
@@ -27,6 +27,8 @@ import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.core.entity.Entities;
 import 
org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
 import org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
@@ -63,7 +65,7 @@ public abstract class AbstractMongoDBSshDriver extends 
AbstractSoftwareProcessSs
         commands.addAll(BashCommands.commandsToDownloadUrlsAs(urls, saveAs));
         commands.add(BashCommands.INSTALL_TAR);
         commands.add("tar xzfv " + saveAs);
-    
+
         newScript(INSTALLING)
                 .failOnNonZeroResultCode()
                 .body.append(commands).execute();
@@ -73,14 +75,40 @@ public abstract class AbstractMongoDBSshDriver extends 
AbstractSoftwareProcessSs
     public void customize() {
         Map<?,?> ports = ImmutableMap.of("port", getServerPort());
         Networking.checkPortsValid(ports);
-        String command = String.format("mkdir -p %s", getDataDirectory());
+        List<String> commands = new LinkedList<String>();
+        commands.add(String.format("mkdir -p %s", getDataDirectory()));
+
+        if (MongoDBAuthenticationUtils.usesAuthentication(entity)) {
+            String destinationLocation = Os.mergePaths(getRunDir(), 
"mongodb-keyfile");
+            
entity.sensors().set(AbstractMongoDBServer.MONGODB_KEYFILE_DESTINATION, 
destinationLocation);
+            String keyfileContents = 
entity.config().get(AbstractMongoDBServer.MONGODB_KEYFILE_CONTENTS);
+            if (keyfileContents == null) {
+                String keyfileUrl = 
entity.config().get(AbstractMongoDBServer.MONGODB_KEYFILE_URL);
+                copyResource(keyfileUrl, destinationLocation);
+            } else {
+                commands.add(BashCommands.pipeTextToFile(keyfileContents, 
destinationLocation));
+                commands.add("chmod 600 " + destinationLocation);
+            }
+        }
+
         newScript(CUSTOMIZING)
                 .updateTaskAndFailOnNonZeroResultCode()
-                .body.append(command).execute();
+                .body.append(commands).execute();
         String templateUrl = 
entity.getConfig(MongoDBServer.MONGODB_CONF_TEMPLATE_URL);
         if (!Strings.isNullOrEmpty(templateUrl)) copyTemplate(templateUrl, 
getConfFile());
+        if (MongoDBAuthenticationUtils.usesAuthentication(entity)) {
+            launch(getArgsBuilderWithNoAuthentication((AbstractMongoDBServer) 
getEntity())
+                    .add("--dbpath", getDataDirectory()));
+            newScript("create-user")
+                    .body.append(String.format("%s --port %s" +
+                            " --host localhost admin --eval 
\"db.createUser({user: '%s',pwd: '%s',roles: [ 'root' ]})\"",
+                    Os.mergePaths(getExpandedInstallDir(), "bin/mongo"), 
getServerPort(), getRootUsername(), 
MongoDBAuthenticationUtils.getRootPassword(entity)))
+                    .updateTaskAndFailOnNonZeroResultCode()
+                    .execute();
+            stop();
+        }
     }
-    
+
     @Override
     public boolean isRunning() {
         try {
@@ -102,7 +130,14 @@ public abstract class AbstractMongoDBSshDriver extends 
AbstractSoftwareProcessSs
         
         // We could also use SIGTERM (15)
         new ScriptHelper(this, "Send SIGINT to MongoDB server")
-                .body.append("kill -2 $(cat " + getPidFile() + ")")
+                .body.append("MONGO_PID=$(cat " + getPidFile() + ")\n")
+                .body.append("kill -2 $MONGO_PID\n")
+                .body.append("for i in {1..10}\n" +
+                    "do\n" +
+                    "    kill -0 $MONGO_PID || exit \n" +
+                    "    sleep 1\n" +
+                    "done\n" +
+                    "echo \"mongoDB process still running after 10 seconds; 
continuing but may subsequently fail\"")
                 .execute();
     }
 
@@ -151,24 +186,38 @@ public abstract class AbstractMongoDBSshDriver extends 
AbstractSoftwareProcessSs
         return getRunDir() + "/mongo.conf";
     }
 
+    protected String getRootUsername() {
+        return entity.config().get(AbstractMongoDBServer.ROOT_USERNAME);
+    }
+
     protected ImmutableList.Builder<String> 
getArgsBuilderWithDefaults(AbstractMongoDBServer server) {
-        Integer port = server.getAttribute(MongoDBServer.PORT);
+        ImmutableList.Builder<String> builder = 
getArgsBuilderWithNoAuthentication(server);
+        String keyfileContents = 
entity.config().get(AbstractMongoDBServer.MONGODB_KEYFILE_CONTENTS);
+        if (keyfileContents != null) {
+            builder.add("--keyFile", 
entity.getAttribute(AbstractMongoDBServer.MONGODB_KEYFILE_DESTINATION));
+        }
+        return builder;
+    }
 
-        return ImmutableList.<String>builder()
-                .add("--config", getConfFile())
-                .add("--pidfilepath", getPidFile())
-                .add("--logpath", getLogFile())
-                .add("--port", port.toString())
-                .add("--fork");
+    protected ImmutableList.Builder<String> 
getArgsBuilderWithNoAuthentication(AbstractMongoDBServer server) {
+        Integer port = server.getAttribute(MongoDBServer.PORT);
+        ImmutableList.Builder<String> builder = ImmutableList.builder();
+        builder.add("--config", getConfFile());
+        builder.add("--pidfilepath", getPidFile());
+        builder.add("--logpath", getLogFile());
+        builder.add("--port", port.toString());
+        builder.add("--fork");
+        return builder;
     }
     
     protected void launch(ImmutableList.Builder<String> argsBuilder) {
         String args = Joiner.on(" ").join(argsBuilder.build());
-        String command = String.format("%s/bin/mongod %s > out.log 2> err.log 
< /dev/null", getExpandedInstallDir(), args);
-        LOG.info(command);
+        List<String> commands = new LinkedList<String>();
+        commands.add(String.format("%s/bin/mongod %s > out.log 2> err.log < 
/dev/null", getExpandedInstallDir(), args));
+
         newScript(LAUNCHING)
                 .updateTaskAndFailOnNonZeroResultCode()
-                .body.append(command).execute();
+                .body.append(commands).execute();
     }
- 
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java
new file mode 100644
index 0000000..a47c384
--- /dev/null
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.brooklyn.entity.nosql.mongodb;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.util.core.flags.SetFromFlag;
+
+public interface MongoDBAuthenticationMixins {
+    @SetFromFlag("mongodbKeyfileContents")
+    ConfigKey<String> MONGODB_KEYFILE_CONTENTS = ConfigKeys.newStringConfigKey(
+            "mongodb.keyfile.contents", "Contents of the keyfile used for 
authentication");
+
+    @SetFromFlag("mongodbKeyfileUrl")
+    ConfigKey<String> MONGODB_KEYFILE_URL = ConfigKeys.newStringConfigKey(
+            "mongodb.keyfile.url", "Location of the keyfile used for 
authentication");
+
+    @SetFromFlag("rootUsername")
+    BasicAttributeSensorAndConfigKey<String> ROOT_USERNAME =
+            new BasicAttributeSensorAndConfigKey<>(String.class, 
"mongodb.root.username", "Username of the initial admin user", "superuser");
+
+    @SetFromFlag("rootPassword")
+    BasicAttributeSensorAndConfigKey<String> ROOT_PASSWORD =
+            new BasicAttributeSensorAndConfigKey<>(String.class, 
"mongodb.root.password", "Password for the initial admin user, auto-generated 
if not set");
+
+    @SetFromFlag("authenticationDatabase")
+    BasicAttributeSensorAndConfigKey<String> AUTHENTICATION_DATABASE =
+            new BasicAttributeSensorAndConfigKey<>(String.class, 
"mongodb.authentication.database", "Database to be used to store authentication 
details (if used)", "admin");
+
+    AttributeSensor<String> MONGODB_KEYFILE_DESTINATION = 
Sensors.newStringSensor("mongodb.keyfile.destination",
+            "Destination of the keyfile used for authentication on the target 
server");
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java
new file mode 100644
index 0000000..0c337a0
--- /dev/null
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.brooklyn.entity.nosql.mongodb;
+
+import org.apache.brooklyn.util.text.Strings;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.brooklyn.api.entity.Entity;
+
+
+public class MongoDBAuthenticationUtils {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(MongoDBAuthenticationUtils.class);
+
+    private MongoDBAuthenticationUtils(){}
+
+    /**
+     * @return true if either the keyfile contents or keyfile url is set, 
false otherwise. If both are set, an IllegalStateException is thrown
+     */
+    public static boolean usesAuthentication(Entity entity) {
+        String keyfileContents = 
entity.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS);
+        String keyfileUrl = 
entity.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL);
+        if (!(Strings.isEmpty(keyfileContents) || 
Strings.isEmpty(keyfileUrl))) {
+            throw new IllegalStateException("keyfile contents and keyfile 
location cannot both be set");
+        }
+        if (Strings.isEmpty(keyfileContents) && Strings.isEmpty(keyfileUrl)) {
+            return false;
+        }
+        return true;
+    }
+
+    public static String getRootPassword(Entity entity) {
+        String password = 
entity.config().get(MongoDBAuthenticationMixins.ROOT_PASSWORD);
+        if (Strings.isEmpty(password)) {
+            LOG.debug(entity + " has no password specified for " + 
MongoDBAuthenticationMixins.ROOT_PASSWORD.getName() + "; using a random 
string");
+            password = Strings.makeRandomId(8);
+            entity.sensors().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, 
password);
+            entity.config().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, 
password);
+        }
+        return password;
+    }
+
+    public static void setAuthenticationConfig(EntitySpec<?> spec, Entity 
source) {
+        if (MongoDBAuthenticationUtils.usesAuthentication(source)) {
+            
spec.configure(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS, 
source.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS));
+            spec.configure(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL, 
source.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL));
+            spec.configure(MongoDBAuthenticationMixins.ROOT_USERNAME, 
source.config().get(MongoDBAuthenticationMixins.ROOT_USERNAME));
+            spec.configure(MongoDBAuthenticationMixins.ROOT_PASSWORD, 
getRootPassword(source));
+        }
+    }
+
+    public static void setAuthenticationConfig(Entity entity, Entity source) {
+        if (MongoDBAuthenticationUtils.usesAuthentication(source)) {
+            
entity.config().set(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS, 
source.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS));
+            
entity.config().set(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL, 
source.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL));
+            entity.config().set(MongoDBAuthenticationMixins.ROOT_USERNAME, 
source.config().get(MongoDBAuthenticationMixins.ROOT_USERNAME));
+            entity.config().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, 
getRootPassword(source));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
index 3a6c398..fa2022f 100644
--- 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
@@ -27,6 +27,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
 import com.google.common.net.HostAndPort;
 import com.mongodb.BasicDBObject;
 import com.mongodb.CommandResult;
@@ -34,6 +35,7 @@ import com.mongodb.DB;
 import com.mongodb.DBObject;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoClientOptions;
+import com.mongodb.MongoCredential;
 import com.mongodb.MongoException;
 import com.mongodb.ServerAddress;
 
@@ -45,11 +47,20 @@ import com.mongodb.ServerAddress;
 public class MongoDBClientSupport {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(MongoDBClientSupport.class);
-
     private ServerAddress address;
-    
+
+    private boolean usesAuthentication;
+    private String username;
+    private String password;
+    private String authenticationDatabase;
+
     private MongoClient client() {
-        return new MongoClient(address, connectionOptions);
+        if (usesAuthentication) {
+            MongoCredential credential = 
MongoCredential.createMongoCRCredential(username, authenticationDatabase, 
password.toCharArray());
+            return new MongoClient(address, ImmutableList.of(credential), 
connectionOptions);
+        } else {
+            return new MongoClient(address, connectionOptions);
+        }
     }
 
     // Set client to automatically reconnect to servers.
@@ -60,9 +71,13 @@ public class MongoDBClientSupport {
 
     private static final BasicBSONObject EMPTY_RESPONSE = new 
BasicBSONObject();
 
-    public MongoDBClientSupport(ServerAddress standalone) {
+    public MongoDBClientSupport(ServerAddress standalone, boolean 
usesAuthentication, String username, String password, String 
authenticationDatabase) {
         // We could also use a MongoClient to access an entire replica set. 
See MongoClient(List<ServerAddress>).
         address = standalone;
+        this.usesAuthentication = usesAuthentication;
+        this.username = username;
+        this.password = password;
+        this.authenticationDatabase = authenticationDatabase;
     }
 
     /**
@@ -71,7 +86,8 @@ public class MongoDBClientSupport {
     public static MongoDBClientSupport forServer(AbstractMongoDBServer 
standalone) throws UnknownHostException {
         HostAndPort hostAndPort = 
BrooklynAccessUtils.getBrooklynAccessibleAddress(standalone, 
standalone.getAttribute(MongoDBServer.PORT));
         ServerAddress address = new ServerAddress(hostAndPort.getHostText(), 
hostAndPort.getPort());
-        return new MongoDBClientSupport(address);
+        return new MongoDBClientSupport(address, 
MongoDBAuthenticationUtils.usesAuthentication(standalone), 
standalone.sensors().get(MongoDBAuthenticationMixins.ROOT_USERNAME),
+                
standalone.sensors().get(MongoDBAuthenticationMixins.ROOT_PASSWORD), 
standalone.sensors().get(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE));
     }
 
     private ServerAddress getServerAddress() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
index 14d0eb8..12bbe87 100644
--- 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
@@ -46,7 +46,7 @@ import com.google.common.reflect.TypeToken;
  * @see <a 
href="http://docs.mongodb.org/manual/replication/";>http://docs.mongodb.org/manual/replication/</a>
  */
 @ImplementedBy(MongoDBReplicaSetImpl.class)
-public interface MongoDBReplicaSet extends DynamicCluster {
+public interface MongoDBReplicaSet extends DynamicCluster, 
MongoDBAuthenticationMixins {
 
     @SetFromFlag("replicaSetName")
     ConfigKey<String> REPLICA_SET_NAME = ConfigKeys.newStringConfigKey(

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
index 399ea91..a9db033 100644
--- 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
@@ -141,7 +141,12 @@ public class MongoDBReplicaSetImpl extends 
DynamicClusterImpl implements MongoDB
 
     @Override
     protected EntitySpec<?> getMemberSpec() {
-        return getConfig(MEMBER_SPEC, EntitySpec.create(MongoDBServer.class));
+        EntitySpec<?> spec = config().get(MEMBER_SPEC);
+        if (spec == null) {
+            spec = EntitySpec.create(MongoDBServer.class);
+        }
+        MongoDBAuthenticationUtils.setAuthenticationConfig(spec, this);
+        return spec;
     }
 
     /**
@@ -200,6 +205,7 @@ public class MongoDBReplicaSetImpl extends 
DynamicClusterImpl implements MongoDB
                 setAttribute(PRIMARY_ENTITY, server);
                 setAttribute(Startable.SERVICE_UP, true);
             } else {
+                ServiceStateLogic.ServiceNotUpLogic.updateNotUpIndicator(this, 
"initialization", "replicaset failed to initialize");
                 ServiceStateLogic.setExpectedState(this, Lifecycle.ON_FIRE);
             }
         } else {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
index ea9c406..941dd8e 100644
--- 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
@@ -210,5 +210,4 @@ public class MongoDBServerImpl extends SoftwareProcessImpl 
implements MongoDBSer
                 .add("port", getAttribute(PORT))
                 .toString();
     }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
index 7817dbc..0c81de2 100644
--- 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
@@ -19,32 +19,47 @@
 package org.apache.brooklyn.entity.nosql.mongodb.sharding;
 
 import java.util.Collection;
+import java.util.concurrent.ExecutionException;
 
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.core.sensor.DependentConfiguration;
 import org.apache.brooklyn.enricher.stock.Enrichers;
+import org.apache.brooklyn.entity.group.AbstractGroup;
+import org.apache.brooklyn.entity.nosql.mongodb.MongoDBAuthenticationMixins;
+import org.apache.brooklyn.entity.nosql.mongodb.MongoDBAuthenticationUtils;
 import org.apache.brooklyn.entity.software.base.SameServerEntityImpl;
+import org.apache.brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
 
-public class CoLocatedMongoDBRouterImpl extends SameServerEntityImpl 
implements CoLocatedMongoDBRouter {
+public class CoLocatedMongoDBRouterImpl extends SameServerEntityImpl 
implements CoLocatedMongoDBRouter, MongoDBAuthenticationMixins {
+
+    private MongoDBRouter router;
+
     @Override
     public void init() {
         super.init();
-        
+        router = addChild(EntitySpec.create(MongoDBRouter.class)
+                .configure(MongoDBRouter.CONFIG_SERVERS,
+                        DependentConfiguration.attributeWhenReady(
+                                
getConfig(CoLocatedMongoDBRouter.SHARDED_DEPLOYMENT),
+                                
MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES)));
         for (EntitySpec<?> siblingSpec : 
getConfig(CoLocatedMongoDBRouter.SIBLING_SPECS)) {
             addChild(siblingSpec);
         }
+        sensors().set(ROUTER, (MongoDBRouter) Iterables.tryFind(getChildren(), 
Predicates.instanceOf(MongoDBRouter.class)).get());
     }
 
     @Override
     protected void doStart(Collection<? extends Location> locations) {
+
         // TODO Changed to create the router child after init as a workaround.
-        // When we use `mongo-sharded.yaml`, and we call 
+        // When we use `mongo-sharded.yaml`, and we call
         // `getConfig(CoLocatedMongoDBRouter.SHARDED_DEPLOYMENT)`,
         // the value is `$brooklyn:component("shardeddeployment")`.
         // To look up the component, it tries to do 
`entity().getApplication()` to
@@ -54,17 +69,24 @@ public class CoLocatedMongoDBRouterImpl extends 
SameServerEntityImpl implements
         //
         // We should move this code back to `init()` once we have a solution 
for that.
         // We can also remove the call to Entities.manage() once this is in 
init() again.
-        
-        MongoDBRouter router = addChild(EntitySpec.create(MongoDBRouter.class)
-                .configure(MongoDBRouter.CONFIG_SERVERS,
-                        DependentConfiguration.attributeWhenReady(
-                                
getConfig(CoLocatedMongoDBRouter.SHARDED_DEPLOYMENT), 
-                                
MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES)));
+
+        try {
+            // Do not attempt to read the configuration until after the router 
has been added to the cluster
+            // as it is at this point that the authentication configuration is 
set
+            Task<?> clusterTask = 
DependentConfiguration.attributeWhenReady(router, AbstractGroup.FIRST);
+            Entities.submit(this, clusterTask);
+            clusterTask.get();
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+        }
+        MongoDBAuthenticationUtils.setAuthenticationConfig(router, this);
+        router.sensors().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, 
router.config().get(MongoDBAuthenticationMixins.ROOT_PASSWORD));
+        router.sensors().set(MongoDBAuthenticationMixins.ROOT_USERNAME, 
router.config().get(MongoDBAuthenticationMixins.ROOT_USERNAME));
+        
router.sensors().set(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE, 
router.config().get(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE));
         Entities.manage(router);
-        setAttribute(ROUTER, (MongoDBRouter) Iterables.tryFind(getChildren(), 
Predicates.instanceOf(MongoDBRouter.class)).get());
         
addEnricher(Enrichers.builder().propagating(MongoDBRouter.PORT).from(router).build());
         
         super.doStart(locations);
-        setAttribute(Startable.SERVICE_UP, true);
+        sensors().set(Startable.SERVICE_UP, true);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java
index 816906d..df73868 100644
--- 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java
@@ -48,4 +48,8 @@ public class MongoDBRouterSshDriver extends 
AbstractMongoDBSshDriver implements
                 .body.append(command).execute();
     }
 
+    @Override
+    public boolean isRunning() {
+        return super.isRunning();
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
----------------------------------------------------------------------
diff --git 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
index 9ef50b9..0b8a1b6 100644
--- 
a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
+++ 
b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
@@ -25,7 +25,6 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.core.entity.AbstractEntity;
@@ -42,10 +41,12 @@ import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.brooklyn.entity.nosql.mongodb.MongoDBAuthenticationMixins;
+import org.apache.brooklyn.entity.nosql.mongodb.MongoDBAuthenticationUtils;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
-public class MongoDBShardedDeploymentImpl extends AbstractEntity implements 
MongoDBShardedDeployment {
+public class MongoDBShardedDeploymentImpl extends AbstractEntity implements 
MongoDBShardedDeployment, MongoDBAuthenticationMixins {
     
     @SuppressWarnings("unused")
     private static final Logger LOG = 
LoggerFactory.getLogger(MongoDBShardedDeploymentImpl.class);
@@ -53,22 +54,36 @@ public class MongoDBShardedDeploymentImpl extends 
AbstractEntity implements Mong
     @Override
     public void init() {
         super.init();
-        
-        setAttribute(CONFIG_SERVER_CLUSTER, 
addChild(EntitySpec.create(MongoDBConfigServerCluster.class)
+
+        EntitySpec<MongoDBConfigServerCluster> configServerClusterSpec = 
EntitySpec.create(MongoDBConfigServerCluster.class)
                 .configure(MongoDBConfigServerCluster.MEMBER_SPEC, 
getConfig(MONGODB_CONFIG_SERVER_SPEC))
-                .configure(DynamicCluster.INITIAL_SIZE, 
getConfig(CONFIG_CLUSTER_SIZE))));
-        setAttribute(ROUTER_CLUSTER, 
addChild(EntitySpec.create(MongoDBRouterCluster.class)
+                .configure(DynamicCluster.INITIAL_SIZE, 
getConfig(CONFIG_CLUSTER_SIZE));
+        
MongoDBAuthenticationUtils.setAuthenticationConfig(configServerClusterSpec, 
this);
+        sensors().set(CONFIG_SERVER_CLUSTER, 
addChild(configServerClusterSpec));
+
+        EntitySpec<MongoDBRouterCluster> routerClusterSpec = 
EntitySpec.create(MongoDBRouterCluster.class)
                 .configure(MongoDBRouterCluster.MEMBER_SPEC, 
getConfig(MONGODB_ROUTER_SPEC))
                 .configure(DynamicCluster.INITIAL_SIZE, 
getConfig(INITIAL_ROUTER_CLUSTER_SIZE))
-                .configure(MongoDBRouter.CONFIG_SERVERS, 
attributeWhenReady(getAttribute(CONFIG_SERVER_CLUSTER), 
MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES))));
-        setAttribute(SHARD_CLUSTER, 
addChild(EntitySpec.create(MongoDBShardCluster.class)
+                .configure(MongoDBRouter.CONFIG_SERVERS, 
attributeWhenReady(getAttribute(CONFIG_SERVER_CLUSTER), 
MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES));
+        MongoDBAuthenticationUtils.setAuthenticationConfig(routerClusterSpec, 
this);
+        sensors().set(ROUTER_CLUSTER, addChild(routerClusterSpec));
+
+        EntitySpec<MongoDBShardCluster> shardClusterSpec = 
EntitySpec.create(MongoDBShardCluster.class)
                 .configure(MongoDBShardCluster.MEMBER_SPEC, 
getConfig(MONGODB_REPLICA_SET_SPEC))
-                .configure(DynamicCluster.INITIAL_SIZE, 
getConfig(INITIAL_SHARD_CLUSTER_SIZE))));
+                .configure(DynamicCluster.INITIAL_SIZE, 
getConfig(INITIAL_SHARD_CLUSTER_SIZE));
+        MongoDBAuthenticationUtils.setAuthenticationConfig(shardClusterSpec, 
this);
+        sensors().set(SHARD_CLUSTER, addChild(shardClusterSpec));
+
         addEnricher(Enrichers.builder()
                 
.propagating(MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES)
                 .from(getAttribute(CONFIG_SERVER_CLUSTER))
                 .build());
-        
+
+        // Advertise even if default are used (root password is set in 
MongoDBAuthenticationUtils)
+        sensors().set(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE, 
config().get(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE));
+        sensors().set(MongoDBAuthenticationMixins.ROOT_USERNAME, 
config().get(MongoDBAuthenticationMixins.ROOT_USERNAME));
+        sensors().set(MongoDBAuthenticationMixins.MONGODB_KEYFILE_DESTINATION, 
config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS));
+
         ServiceNotUpLogic.updateNotUpIndicator(this, 
Attributes.SERVICE_STATE_ACTUAL, "stopped");
     }
 
@@ -85,7 +100,7 @@ public class MongoDBShardedDeploymentImpl extends 
AbstractEntity implements Mong
             if (getConfigRaw(MongoDBShardedDeployment.CO_LOCATED_ROUTER_GROUP, 
true).isPresent()) {
                 
addPolicy(PolicySpec.create(ColocatedRouterTrackingPolicy.class)
                         .displayName("Co-located router tracker")
-                        .configure("group", 
(Group)getConfig(MongoDBShardedDeployment.CO_LOCATED_ROUTER_GROUP)));
+                        .configure("group", 
getConfig(MongoDBShardedDeployment.CO_LOCATED_ROUTER_GROUP)));
             }
             ServiceNotUpLogic.clearNotUpIndicator(this, 
Attributes.SERVICE_STATE_ACTUAL);
             ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
@@ -99,6 +114,7 @@ public class MongoDBShardedDeploymentImpl extends 
AbstractEntity implements Mong
     public static class ColocatedRouterTrackingPolicy extends 
AbstractMembershipTrackingPolicy {
         @Override
         protected void onEntityAdded(Entity member) {
+            MongoDBAuthenticationUtils.setAuthenticationConfig(member, entity);
             MongoDBRouterCluster cluster = entity.getAttribute(ROUTER_CLUSTER);
             
cluster.addMember(member.getAttribute(CoLocatedMongoDBRouter.ROUTER));
         }
@@ -107,7 +123,7 @@ public class MongoDBShardedDeploymentImpl extends 
AbstractEntity implements Mong
             MongoDBRouterCluster cluster = entity.getAttribute(ROUTER_CLUSTER);
             
cluster.removeMember(member.getAttribute(CoLocatedMongoDBRouter.ROUTER));
         }
-    };
+    }
 
     @Override
     public void stop() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/test/resources/mongodb-keyfile
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/resources/mongodb-keyfile 
b/software/nosql/src/test/resources/mongodb-keyfile
new file mode 100644
index 0000000..6d4640a
--- /dev/null
+++ b/software/nosql/src/test/resources/mongodb-keyfile
@@ -0,0 +1,16 @@
+df1DzycxICi2RFa1xsDP5uiVcVtZ4EQBxffQ+FDuD4n81iOGW7pNOS49aH4t9PW6
+s0t+mASRnY/IVOsiTNT5VQWeMhf6b0/aYuXJp9ZZNQ9PmyA60a8x5x9K3YIoGYAd
+/RGenkIOIG9EjXnqTT1QgN66xVIUp8v2w0iuER0jiG+GcjBVVWGgqKcj6ZLQRecC
+6xSETYuJRbXdPanpnlk8oRYrtWFgcmQ8pl0/0hc/8i82PjTC8DdkqRqYQzhAvexh
+Fo8ZOPiS8xmiDWDsKBJscf6J5KKlgr/3ws0Kv5Qqxmq7oelAmZ+xRvyFBYbao3cz
+3XKBC9SBYfexnl25S9Ef94IV6bqls6SwQMTNS5W0sn3L/Mi55yEWFN44pcYCJ4ng
+oHMDaQyOC+Fi0rRcRduFZWYHlw7ibX0AaRQhwhh0YEbgFY2O7QoTNxwNycxLeKLr
+VMY8ZcTRzvmypAfetWHlwx97G+yXebCsZZ+TbAR/txficwmLFw/M5Qit8Op7YVFM
+zsrKnJZq/Ar8kLzw2UrIFfecaRl3hqT4CI8htaVW+fbc94RHNiZpHg5k/I+aNT45
+9uxRNNPcZiDln7ZV3skhVwQ0UeUZUBp0UZj33N2f/5JXxoRc5slb2mMFEKe+FH6a
+0M86QphH356jrIBSalm7duLAFzB8oyf7+JQgbpwooiO5D+KqIJevpwZXtjuaKVCU
+4bOJNq8AaJU6yjPNihHiGuGLv3/TmXP1Q8Cr4XSyzpv9pxZvvb0XYdlxWIQg0szv
+5QSTkgx6CCBoeDbVoWJh4bE3lobFponKC9o5j3nVAqPbxZocq6Lr6TWrXfwlNRcg
+Cvenxs8mjRQV7Hg7956P/dJtavN3UpSTwbius5h/oIf9ywBmVLNAIhbOS3kcacOC
+YlnJZGN+m1Wo9AvsmLz+yl5GB3W/zA4vUyhWnUY24BoKKEFYef594wi2sagz9TVC
+nLrWCE8djB9j4tudcz6PdFFhQHmB

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/usage/launcher/src/test/resources/mongo-sharded-authentication.yaml
----------------------------------------------------------------------
diff --git 
a/usage/launcher/src/test/resources/mongo-sharded-authentication.yaml 
b/usage/launcher/src/test/resources/mongo-sharded-authentication.yaml
new file mode 100644
index 0000000..2d59f1c
--- /dev/null
+++ b/usage/launcher/src/test/resources/mongo-sharded-authentication.yaml
@@ -0,0 +1,45 @@
+name: Sharded MongoDB With Web App
+description: Auto-scaling web app backed by MongoDB
+location: softlayer:ams01
+services:
+- type: 
org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment
+  id: mongo
+  name: Mongo DB Backend
+  brooklyn.config:
+    initialShardClusterSize: 5
+    shardReplicaSetSize: 3
+    coLocatedRouterGroup: 
$brooklyn:component("webappcluster").attributeWhenReady("controlleddynamicwebappcluster.cluster")
+    mongodb.keyfile.url: classpath://mongo.key
+    mongodb.root.username: mongouser
+
+- type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+  id: webappcluster
+  brooklyn.config:
+    memberSpec:
+      $brooklyn:entitySpec:
+        type: 
org.apache.brooklyn.entity.nosql.mongodb.sharding.CoLocatedMongoDBRouter
+        brooklyn.enrichers:
+          - type: brooklyn.enricher.basic.Propagator
+            brooklyn.config:
+              enricher.propagating.sensorMapping:
+                
$brooklyn:sensor("org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", 
"http.port"): 
$brooklyn:sensor("org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", 
"http.port")
+              enricher.producer: $brooklyn:component("child", "appserver")
+        brooklyn.config:
+          mongodb.keyfile.url: classpath://mongo.key
+          brooklyn.example.mongodb.username: 
$brooklyn:component("mongo").attributeWhenReady("mongodb.root.username")
+          brooklyn.example.mongodb.password: 
$brooklyn:component("mongo").attributeWhenReady("mongodb.root.password")
+          brooklyn.example.mongodb.authenticationDatabase: 
$brooklyn:component("mongo").attributeWhenReady("mongodb.authentication.database")
+          shardedDeployment: $brooklyn:component("mongo")
+          siblingSpecs:
+          - $brooklyn:entitySpec:
+              id: appserver
+              type: org.apache.brooklyn.entity.webapp.tomcat.TomcatServer
+              brooklyn.config:
+                war: "classpath://brooklyn-example-hello-world-sql-webapp.war"
+                java.sysprops:
+                  brooklyn.example.mongodb.port: $brooklyn:component("parent", 
"").attributeWhenReady("mongodb.server.port")
+                  brooklyn.example.mongodb.username: 
$brooklyn:component("mongo").attributeWhenReady("mongodb.root.username")
+                  brooklyn.example.mongodb.password: 
$brooklyn:component("mongo").attributeWhenReady("mongodb.root.password")
+                  brooklyn.example.mongodb.authenticationDatabase: 
$brooklyn:component("mongo").attributeWhenReady("mongodb.authentication.database")
+          - $brooklyn:entitySpec:
+              type: brooklyn.entity.basic.EmptySoftwareProcess

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/usage/launcher/src/test/resources/mongo-sharded.yaml
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/resources/mongo-sharded.yaml 
b/usage/launcher/src/test/resources/mongo-sharded.yaml
index 1a7a0bc..75b5413 100644
--- a/usage/launcher/src/test/resources/mongo-sharded.yaml
+++ b/usage/launcher/src/test/resources/mongo-sharded.yaml
@@ -24,10 +24,11 @@ services:
   id: mongo
   name: Mongo DB Backend
   brooklyn.config:
-    initialRouterClusterSize: 1
     initialShardClusterSize: 5
     shardReplicaSetSize: 3
     coLocatedRouterGroup: 
$brooklyn:component("webappcluster").attributeWhenReady("controlleddynamicwebappcluster.cluster")
+    mongodb.keyfile.url: classpath://mongo.key
+    mongodb.root.user: mongouser
 
 - type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
   id: webappcluster
@@ -51,5 +52,8 @@ services:
                 war: "classpath://brooklyn-example-hello-world-sql-webapp.war"
                 java.sysprops:
                   brooklyn.example.mongodb.port: $brooklyn:component("parent", 
"").attributeWhenReady("mongodb.server.port")
+                  brooklyn.example.mongodb.username: 
$brooklyn:component("parent", "").attributeWhenReady("mongodb.root.username")
+                  brooklyn.example.mongodb.password: 
$brooklyn:component("parent", "").attributeWhenReady("mongodb.root.password")
+                  brooklyn.example.mongodb.authenticationDatabase: 
$brooklyn:component("parent", "").attributeWhenReady("mongodb.root.password")
           - $brooklyn:entitySpec:
               type: 
org.apache.brooklyn.entity.software.base.EmptySoftwareProcess

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/usage/launcher/src/test/resources/mongo.key
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/resources/mongo.key 
b/usage/launcher/src/test/resources/mongo.key
new file mode 100644
index 0000000..029e424
--- /dev/null
+++ b/usage/launcher/src/test/resources/mongo.key
@@ -0,0 +1,16 @@
+df1DzycxICi2RFa1xsDP5uiVcVtZ4EQBxffQ+FDuD4n81iOGW7pNOS49aH4t9PW6
+s0t+mASRnY/IVOsiTNT5VQWeMhf6b0/aYuXJp9ZZNQ9PmyA60a8x5x9K3YIoGYAd
+/RGenkIOIG9EjXnqTT1QgN66xVIUp8v2w0iuER0jiG+GcjBVVWGgqKcj6ZLQRecC
+6xSETYuJRbXdPanpnlk8oRYrtWFgcmQ8pl0/0hc/8i82PjTC8DdkqRqYQzhAvexh
+Fo8ZOPiS8xmiDWDsKBJscf6J5KKlgr/3ws0Kv5Qqxmq7oelAmZ+xRvyFBYbao3cz
+3XKBC9SBYfexnl25S9Ef94IV6bqls6SwQMTNS5W0sn3L/Mi55yEWFN44pcYCJ4ng
+oHMDaQyOC+Fi0rRcRduFZWYHlw7ibX0AaRQhwhh0YEbgFY2O7QoTNxwNycxLeKLr
+VMY8ZcTRzvmypAfetWHlwx97G+yXebCsZZ+TbAR/txficwmLFw/M5Qit8Op7YVFM
+zsrKnJZq/Ar8kLzw2UrIFfecaRl3hqT4CI8htaVW+fbc94RHNiZpHg5k/I+aNT45
+9uxRNNPcZiDln7ZV3skhVwQ0UeUZUBp0UZj33N2f/5JXxoRc5slb2mMFEKe+FH6a
+0M86QphH356jrIBSalm7duLAFzB8oyf7+JQgbpwooiO5D+KqIJevpwZXtjuaKVCU
+4bOJNq8AaJU6yjPNihHiGuGLv3/TmXP1Q8Cr4XSyzpv9pxZvvb0XYdlxWIQg0szv
+5QSTkgx6CCBoeDbVoWJh4bE3lobFponKC9o5j3nVAqPbxZocq6Lr6TWrXfwlNRcg
+Cvenxs8mjRQV7Hg7956P/dJtavN3UpSTwbius5h/oIf9ywBmVLNAIhbOS3kcacOC
+YlnJZGN+m1Wo9AvsmLz+yl5GB3W/zA4vUyhWnUY24BoKKEFYef594wi2sagz9TVC
+nLrWCE8djB9j4tudcz6PdFFhQHm
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java 
b/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java
index 4019a67..e91d60c 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java
@@ -625,6 +625,13 @@ public class BashCommands {
                 +"\n"+"EOF_"+id+"\n";
     }
 
+    public static String pipeTextToFile(String text, String filepath) {
+        String id = Identifiers.makeRandomId(8);
+        return "cat > " + filepath + " << EOL_" + id + "\n"
+                + text
+                + "EOL_" + id + "\n";
+    }
+
     public static String prependToEtcHosts(String ip, String... hostnames) {
         String tempFileId = "bak"+Identifiers.makeRandomId(4);
         return sudo(String.format("sed -i."+tempFileId+" -e '1i\\\n%s %s' 
/etc/hosts", ip, Joiner.on(" ").join(hostnames)));

Reply via email to