You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/02/01 18:47:49 UTC

[13/51] [abbrv] [partial] brooklyn-library git commit: move subdir from incubator up a level as it is promoted to its own repo (first non-incubator commit!)

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNodeSshDriver.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNodeSshDriver.java
deleted file mode 100644
index 2a9b9c5..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNodeSshDriver.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.hazelcast;
-
-import static java.lang.String.format;
-
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.core.entity.Entities;
-
-import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.os.Os;
-import org.apache.brooklyn.util.ssh.BashCommands;
-import org.apache.brooklyn.util.text.Strings;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-public class HazelcastNodeSshDriver extends JavaSoftwareProcessSshDriver implements HazelcastNodeDriver {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(HazelcastNodeSshDriver.class);
-
-    public HazelcastNodeSshDriver(HazelcastNodeImpl entity, SshMachineLocation machine) {
-        super(entity, machine);
-    }
-
-    @Override
-    public void preInstall() {
-        resolver = Entities.newDownloader(this);
-    }
-
-    @Override
-    public void install() {
-        List<String> urls = resolver.getTargets();
-        String saveAs = resolver.getFilename();
-        
-        List<String> commands = ImmutableList.<String>builder()
-            .add(BashCommands.installJavaLatestOrWarn())
-            .addAll(BashCommands.commandsToDownloadUrlsAs(urls, saveAs))
-            .build();
-        
-        newScript(INSTALLING).body.append(commands).execute();
-    }
-
-    @Override
-    public void customize() {
-        if (LOG.isInfoEnabled()) {
-            LOG.info("Customizing {}", entity.getAttribute(HazelcastNode.NODE_NAME));
-        }
-        
-        ImmutableList.Builder<String> commands = new ImmutableList.Builder<String>()
-                .add("mkdir -p lib conf log")
-                .add(String.format("cp %s/%s %s/lib/", getInstallDir(), resolver.getFilename(), getRunDir()));
-
-        newScript(CUSTOMIZING)
-                .body.append(commands.build())
-                .failOnNonZeroResultCode()
-                .execute();
-        
-        copyTemplate(entity.getConfig(HazelcastNode.CONFIG_TEMPLATE_URL), Os.mergePathsUnix(getRunDir(), "conf", getConfigFileName()));
-        
-    }
-
-    @Override
-    public void launch() {
-        
-        entity.sensors().set(HazelcastNode.PID_FILE, Os.mergePathsUnix(getRunDir(), PID_FILENAME));
-        
-        String maxHeapMemorySize = getHeapMemorySize();
-        
-        if (LOG.isInfoEnabled()) {
-            LOG.info("Launching {} with heap memory of {}", entity, maxHeapMemorySize);
-        }
-        
-        // Setting initial heap size (Xms) size to match max heap size (Xms) at first
-        String initialHeapMemorySize = maxHeapMemorySize;
-        
-        ImmutableList<String> commands = ImmutableList.<String>builder()
-            .add(format("nohup java -cp ./lib/%s", resolver.getFilename()))
-            .add(format("-Xmx%s -Xms%s", maxHeapMemorySize, initialHeapMemorySize))
-            .add(format("-Dhazelcast.config=./conf/%s", getConfigFileName()))
-            .add(format("com.hazelcast.core.server.StartServer >> %s 2>&1 </dev/null &", getLogFileLocation()))
-            .build();
-        
-        newScript(MutableMap.of(USE_PID_FILE, true), LAUNCHING)
-            .updateTaskAndFailOnNonZeroResultCode()
-            .body.append(Joiner.on(" ").join(commands))
-            .execute();
-    }
-       
-    public String getConfigFileName() {
-        return entity.getConfig(HazelcastNode.CONFIG_FILE_NAME);
-    }
-    
-    public String getHeapMemorySize() {
-        return entity.getConfig(HazelcastNode.NODE_HEAP_MEMORY_SIZE);
-    }
-    
-    @Override
-    public boolean isRunning() {
-        return newScript(MutableMap.of(USE_PID_FILE, true), CHECK_RUNNING).execute() == 0;
-    }
-    
-    @Override
-    public void stop() {
-        newScript(MutableMap.of(USE_PID_FILE, true), STOPPING).execute();
-    }
-    
-    @Override
-    public void kill() {
-        newScript(MutableMap.of(USE_PID_FILE, true), KILLING).execute();
-    }
-
-    public List<String> getHazelcastNodesList() {
-        List<String> result = Lists.newArrayList();
-
-        if (Strings.isBlank(entity.getAttribute(HazelcastNode.NODE_CLUSTER_NAME))) {
-            result.add(String.format("%s:%d", entity.getAttribute(HazelcastNode.SUBNET_ADDRESS),
-                                              entity.getAttribute(HazelcastNode.NODE_PORT)));
-        } else {
-            HazelcastCluster cluster = (HazelcastCluster) entity.getParent();
-
-            for (Entity member : cluster.getMembers()) {
-                String address = Entities.attributeSupplierWhenReady(member, HazelcastNode.SUBNET_ADDRESS).get();
-                Integer port = Entities.attributeSupplierWhenReady(member, HazelcastNode.NODE_PORT).get();
-                String addressAndPort = String.format("%s:%d", address, port);
-
-                if (LOG.isInfoEnabled()) {
-                    LOG.info("Adding {} to the members' list of {}", addressAndPort, entity.getAttribute(HazelcastNode.NODE_NAME));
-                }
-                result.add(addressAndPort);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    protected String getLogFileLocation() {
-        return Os.mergePathsUnix(getRunDir(),"/log/out.log");
-    }
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
deleted file mode 100644
index 3475a7d..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.entity.Entity;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.util.core.ResourcePredicates;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-
-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.
-    // Should update mongo.config to yaml format, but no rush for that.
-    
-    @SetFromFlag("dataDirectory")
-    ConfigKey<String> DATA_DIRECTORY = ConfigKeys.newStringConfigKey(
-            "mongodb.data.directory", "Data directory to store MongoDB journals");
-
-    @SetFromFlag("mongodbConfTemplateUrl")
-    ConfigKey<String> MONGODB_CONF_TEMPLATE_URL = ConfigKeys.builder(String.class)
-            .name("mongodb.config.url")
-            .description("Template file (in freemarker format) for a MongoDB configuration file")
-            .defaultValue("classpath://org/apache/brooklyn/entity/nosql/mongodb/default.conf")
-            .constraint(ResourcePredicates.urlIsBlankOrExists())
-            .build();
-
-    @SetFromFlag("version")
-    ConfigKey<String> SUGGESTED_VERSION =
-            ConfigKeys.newConfigKeyWithDefault(SoftwareProcess.SUGGESTED_VERSION, "2.6.5");
-
-    // TODO: Windows support
-    // e.g. http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.2.2.tgz,
-    // http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-2.2.2.tgz
-    // http://downloads.mongodb.org/win32/mongodb-win32-x86_64-1.8.5.zip
-    // Note Windows download is a zip.
-    @SetFromFlag("downloadUrl")
-    AttributeSensorAndConfigKey<String, String> DOWNLOAD_URL = new BasicAttributeSensorAndConfigKey<String>(
-            SoftwareProcess.DOWNLOAD_URL, "http://fastdl.mongodb.org/${driver.osDir}/${driver.osTag}-${version}.tgz");
-
-    @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/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
deleted file mode 100644
index ccbe470..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * 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 java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-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.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.internal.ssh.SshTool;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.net.Networking;
-import org.apache.brooklyn.util.os.Os;
-import org.apache.brooklyn.util.ssh.BashCommands;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public abstract class AbstractMongoDBSshDriver extends AbstractSoftwareProcessSshDriver {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractMongoDBSshDriver.class);
-    
-    public AbstractMongoDBSshDriver(EntityLocal entity, SshMachineLocation machine) {
-        super(entity, machine);
-    }
-
-    @Override
-    public void preInstall() {
-        resolver = Entities.newDownloader(this);
-        setExpandedInstallDir(Os.mergePaths(getInstallDir(), resolver.getUnpackedDirectoryName(getBaseName())));
-    }
-
-    @Override
-    public void install() {
-        List<String> urls = resolver.getTargets();
-        String saveAs = resolver.getFilename();
-    
-        List<String> commands = new LinkedList<>();
-        commands.addAll(BashCommands.commandsToDownloadUrlsAs(urls, saveAs));
-        commands.add(BashCommands.INSTALL_TAR);
-        commands.add("tar xzfv " + saveAs);
-
-        newScript(INSTALLING)
-                .failOnNonZeroResultCode()
-                .body.append(commands).execute();
-    }
-    
-    @Override
-    public void customize() {
-        Map<?,?> ports = ImmutableMap.of("port", getServerPort());
-        Networking.checkPortsValid(ports);
-        List<String> commands = new LinkedList<>();
-        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 (Strings.isNullOrEmpty(keyfileContents)) {
-                String keyfileUrl = entity.config().get(AbstractMongoDBServer.MONGODB_KEYFILE_URL);
-                if (Strings.isNullOrEmpty(keyfileUrl)) {
-                    throw new IllegalStateException("MongoDBAuthenticationUtils.usesAuthentication returned true, but neither keyfileContents nor keyfileUrl are set");
-                }
-                copyResource(keyfileUrl, destinationLocation);
-            } else {
-                commands.add(BashCommands.pipeTextToFile(keyfileContents, destinationLocation));
-            }
-            commands.add("chmod 600 " + destinationLocation);
-        }
-
-        newScript(CUSTOMIZING)
-                .updateTaskAndFailOnNonZeroResultCode()
-                .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 {
-            if (entity instanceof MongoDBServerImpl && !((MongoDBServerImpl)entity).clientAccessEnabled()) {
-                // No direct access via MongoDB port; only use ssh-port
-                return newScript(MutableMap.of(USE_PID_FILE, getPidFile()), CHECK_RUNNING).execute() == 0;
-            } else {
-                return MongoDBClientSupport.forServer((AbstractMongoDBServer) entity).ping();
-            }
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            return false;
-        }
-    }
-    
-    /**
-     * Kills the server with SIGINT. Sending SIGKILL is likely to result in data corruption.
-     * @see <a href="http://docs.mongodb.org/manual/tutorial/manage-mongodb-processes/#sending-a-unix-int-or-term-signal">http://docs.mongodb.org/manual/tutorial/manage-mongodb-processes/#sending-a-unix-int-or-term-signal</a>
-     */
-    @Override
-    public void stop() {
-        // TODO: Wait for process to terminate. Currently, this will send the signal and then immediately continue with next steps, 
-        // which could involve stopping VM etc.
-        
-        // We could also use SIGTERM (15)
-        new ScriptHelper(this, "Send SIGINT to MongoDB server")
-                .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();
-    }
-
-    protected String getBaseName() {
-        return getOsTag() + "-" + entity.getConfig(AbstractMongoDBServer.SUGGESTED_VERSION);
-    }
-
-    // IDE note: This is used by MongoDBServer.DOWNLOAD_URL
-    public String getOsDir() {
-        return (getLocation().getOsDetails().isMac()) ? "osx" : "linux";
-    }
-
-    public String getOsTag() {
-        OsDetails os = getLocation().getOsDetails();
-        if (os == null) {
-            // Default to generic linux
-            return "mongodb-linux-x86_64";
-        } else if (os.isMac()) {
-            // Mac is 64bit only
-            return "mongodb-osx-x86_64";
-        } else {
-            String arch = os.is64bit() ? "x86_64" : "i686";
-            return "mongodb-linux-" + arch;
-        }
-    }
-
-    public String getDataDirectory() {
-        String result = entity.getConfig(MongoDBServer.DATA_DIRECTORY);
-        if (result!=null) return result;
-        return getRunDir() + "/data";
-    }
-
-    protected String getLogFile() {
-        return getRunDir() + "/log.txt";
-    }
-
-    protected String getPidFile() {
-        return getRunDir() + "/pid";
-    }
-
-    protected Integer getServerPort() {
-        return entity.getAttribute(MongoDBServer.PORT);
-    }
-
-    protected String getConfFile() {
-        return getRunDir() + "/mongo.conf";
-    }
-
-    protected String getRootUsername() {
-        return entity.config().get(AbstractMongoDBServer.ROOT_USERNAME);
-    }
-
-    protected ImmutableList.Builder<String> getArgsBuilderWithDefaults(AbstractMongoDBServer server) {
-        ImmutableList.Builder<String> builder = getArgsBuilderWithNoAuthentication(server);
-        if (MongoDBAuthenticationUtils.usesAuthentication(entity)) {
-            builder.add("--keyFile", entity.getAttribute(AbstractMongoDBServer.MONGODB_KEYFILE_DESTINATION));
-        }
-        return builder;
-    }
-
-    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);
-
-        newScript(LAUNCHING)
-                .setFlag(SshTool.PROP_CONNECT_TIMEOUT, Duration.TEN_SECONDS.toMilliseconds())
-                .updateTaskAndFailOnNonZeroResultCode()
-                .body.append(command).execute();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java
deleted file mode 100644
index 0ad885b..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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. If mongodb.keyfile.contents and mongodb.keyfile.url are both set, mongodb.keyfile.contents will take precedence");
-
-    @SetFromFlag("mongodbKeyfileUrl")
-    ConfigKey<String> MONGODB_KEYFILE_URL = ConfigKeys.newStringConfigKey(
-            "mongodb.keyfile.url", "Location of the keyfile used for authentication. If mongodb.keyfile.contents and mongodb.keyfile.url are both set, mongodb.keyfile.contents will take precedence");
-
-    @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/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java
deleted file mode 100644
index 41808ae..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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);
-        return Strings.isNonBlank(keyfileContents) || Strings.isNonBlank(keyfileUrl);
-    }
-
-    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(16);
-            entity.sensors().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, password);
-            entity.config().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, password);
-        }
-        return password;
-    }
-
-    /**
-     * Configures the {@code spec} with authentication configuration from {@code source}
-     */
-    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));
-        }
-    }
-
-    /**
-     * Configures the {@code spec} with authentication configuration from {@code 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/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClient.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClient.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClient.java
deleted file mode 100644
index 4e124a7..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClient.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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 java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.annotation.Effector;
-import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.effector.MethodEffector;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-
-import com.google.common.reflect.TypeToken;
-
-@ImplementedBy(MongoDBClientImpl.class)
-public interface MongoDBClient extends AbstractMongoDBServer {
-    
-    MethodEffector<Void> RUN_SCRIPT = new MethodEffector<Void>(MongoDBClient.class, "runScript");
-    
-    @SuppressWarnings("serial")
-    @SetFromFlag("startupJsScripts")
-    ConfigKey<List<String>> STARTUP_JS_SCRIPTS = ConfigKeys.newConfigKey(
-            new TypeToken<List<String>>(){}, "mongodb.client.startupJsScripts", 
-                "List of scripts defined in mongodb.client.scripts to be run on startup");
-    
-    @SuppressWarnings("serial")
-    @SetFromFlag("scripts")
-    ConfigKey<Map<String, String>> JS_SCRIPTS = ConfigKeys.newConfigKey(
-            new TypeToken<Map<String, String>>(){}, "mongodb.client.scripts", "List of javascript scripts to be copied "
-                    + "to the server. These scripts can be run using the runScript effector");
-    
-    @SetFromFlag("shardedDeployment")
-    ConfigKey<MongoDBShardedDeployment> SHARDED_DEPLOYMENT = ConfigKeys.newConfigKey(MongoDBShardedDeployment.class, 
-            "mongodb.client.shardeddeployment", "Sharded deployment that the client will use to run scripts. "
-                    + "If both SERVER and SHARDED_DEPLOYMENT are specified, SERVER will be used");
-    
-    @SetFromFlag("server")
-    ConfigKey<AbstractMongoDBServer> SERVER = ConfigKeys.newConfigKey(AbstractMongoDBServer.class, 
-            "mongodb.client.server", "MongoDBServer that the client will use to run scripts. "
-                    + "If both SERVER and SHARDED_DEPLOYMENT are specified, SERVER will be used");
-    
-    @Effector(description="Runs one of the scripts defined in mongodb.client.scripts")
-    void runScript(@EffectorParam(name="preStart", description="use this to create parameters that can be used by the script, e.g.:<p><code>var loopCount = 10</code>") String preStart,
-            @EffectorParam(name="scriptName", description="Name of the script as defined in mongodb.client.scripts") String scriptName);
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientDriver.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientDriver.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientDriver.java
deleted file mode 100644
index f48f743..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientDriver.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.entity.software.base.SoftwareProcessDriver;
-
-public interface MongoDBClientDriver extends SoftwareProcessDriver {
-    void runScript(String preStart, String scriptName);
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientImpl.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientImpl.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientImpl.java
deleted file mode 100644
index 419c09e..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientImpl.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.core.entity.trait.Startable;
-import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-
-public class MongoDBClientImpl extends SoftwareProcessImpl implements MongoDBClient {
-    
-    @Override
-    protected void connectSensors() {
-        super.connectSensors();
-        sensors().set(Startable.SERVICE_UP, true);
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Override
-    public Class getDriverInterface() {
-        return MongoDBClientDriver.class;
-    }
-
-    @Override
-    public void runScript(String preStart, String scriptName) {
-        ((MongoDBClientDriver)getDriver()).runScript(preStart, scriptName);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
deleted file mode 100644
index bd5e552..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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 java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.core.sensor.DependentConfiguration;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouter;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouterCluster;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.math.MathPredicates;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicates;
-
-public class MongoDBClientSshDriver extends AbstractMongoDBSshDriver implements MongoDBClientDriver {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(MongoDBClientSshDriver.class);
-
-    private boolean isRunning = false;
-
-    public MongoDBClientSshDriver(EntityLocal entity, SshMachineLocation machine) {
-        super(entity, machine);
-    }
-    
-    @Override
-    public void customize() {
-        String command = String.format("mkdir -p %s", getUserScriptDir());
-        newScript(CUSTOMIZING)
-            .updateTaskAndFailOnNonZeroResultCode()
-            .body.append(command).execute();
-        Map<String, String> scripts = entity.getConfig(MongoDBClient.JS_SCRIPTS);
-        for (String scriptName : scripts.keySet()) {
-            copyResource(scripts.get(scriptName), getUserScriptDir() + scriptName + ".js");
-        }
-    }
-
-    @Override
-    public void launch() {
-        AbstractMongoDBServer server = getServer();
-        // The scripts are going to be run on the machine via SSH so it shouldn't matter
-        // that the accessible host and port might be different.
-        String host = server.getAttribute(AbstractMongoDBServer.HOSTNAME);
-        Integer port = server.getAttribute(AbstractMongoDBServer.PORT);
-
-        List<String> scripts = entity.getConfig(MongoDBClient.STARTUP_JS_SCRIPTS);
-        if (scripts!=null) {
-            for (String scriptName : scripts) {
-                try {
-                    LOG.debug("Running MongoDB script "+scriptName+" at "+getEntity());
-                    runScript("", scriptName, host, port);
-                } catch (Exception e) {
-                    LOG.warn("Error running MongoDB script "+scriptName+" at "+getEntity()+", throwing: "+e);
-                    isRunning = false;
-                    Exceptions.propagateIfFatal(e);
-                    throw new IllegalStateException("Error running MongoDB script "+scriptName+" at "+entity+": "+e, e);
-                }
-            }
-        }
-        isRunning = true;
-    }
-    
-    @Override
-    public boolean isRunning() {
-        // TODO better would be to get some confirmation
-        return isRunning;
-    }
-    
-    @Override
-    public void stop() {
-        try {
-            super.stop();
-        } finally {
-            isRunning = false;
-        }
-    }
-    
-    private String getUserScriptDir() {
-        return getRunDir() + "/userScripts/" ;
-    }
-    
-    public void runScript(String preStart, String scriptName) {
-        AbstractMongoDBServer server = getServer();
-        String host = server.getAttribute(AbstractMongoDBServer.HOSTNAME);
-        Integer port = server.getAttribute(AbstractMongoDBServer.PORT);
-        runScript(preStart, scriptName, host, port);
-    }
-    
-    private void runScript(String preStart, String scriptName, String host, Integer port) {
-        // TODO: escape preStart to prevent injection attack
-        String command = String.format("%s/bin/mongo %s:%s --eval \"%s\" %s/%s > out.log 2> err.log < /dev/null", getExpandedInstallDir(), 
-                host, port, preStart, getUserScriptDir(), scriptName + ".js");
-        newScript(LAUNCHING)
-            .updateTaskAndFailOnNonZeroResultCode()
-            .body.append(command).execute();
-    }
-    
-    private AbstractMongoDBServer getServer() {
-        AbstractMongoDBServer server = entity.getConfig(MongoDBClient.SERVER);
-        MongoDBShardedDeployment deployment = entity.getConfig(MongoDBClient.SHARDED_DEPLOYMENT);
-        if (server == null) {
-            Preconditions.checkNotNull(deployment, "Either server or shardedDeployment must be specified for %s", this);
-            server = DependentConfiguration.builder()
-                    .attributeWhenReady(deployment.getRouterCluster(), MongoDBRouterCluster.ANY_ROUTER)
-                    .blockingDetails("any available router")
-                    .runNow();
-            DependentConfiguration.builder()
-                    .attributeWhenReady(server, MongoDBRouter.SHARD_COUNT)
-                    .readiness(MathPredicates.<Integer>greaterThan(0))
-                    .runNow();
-        } else {
-            if (deployment != null) {
-                log.warn("Server and ShardedDeployment defined for {}; using server ({} instead of {})", 
-                        new Object[] {this, server, deployment});
-            }
-            DependentConfiguration.builder()
-                    .attributeWhenReady(server, Startable.SERVICE_UP)
-                    .readiness(Predicates.equalTo(true))
-                    .runNow();
-        }
-        return server;
-    }
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
deleted file mode 100644
index c0ec6e7..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * 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 java.net.UnknownHostException;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
-import org.apache.brooklyn.util.repeat.Repeater;
-import org.apache.brooklyn.util.time.Duration;
-import org.bson.BSONObject;
-import org.bson.BasicBSONObject;
-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;
-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;
-
-/**
- * Manages connections to standalone MongoDB servers.
- *
- * @see <a href="http://docs.mongodb.org/manual/reference/command/">MongoDB database command documentation</a>
- */
-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 baseClient(connectionOptions);
-    }
-
-    private MongoClient fastClient() {
-        MongoClientOptions fastConnectionOptions = MongoClientOptions.builder()
-                .connectTimeout(1000 * 10)
-                .maxWaitTime(1000 * 10)
-                .serverSelectionTimeout(1000 * 10)
-                .build();
-
-        return baseClient(fastConnectionOptions);
-    }
-
-    private MongoClient baseClient(MongoClientOptions 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.
-    private static final MongoClientOptions connectionOptions = MongoClientOptions.builder()
-            .socketKeepAlive(true)
-            .build();
-
-    private static final BasicBSONObject EMPTY_RESPONSE = new BasicBSONObject();
-
-    public MongoDBClientSupport(ServerAddress standalone) {
-        address = standalone;
-        usesAuthentication = false;
-    }
-
-    public MongoDBClientSupport(ServerAddress standalone, 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 = true;
-        this.username = username;
-        this.password = password;
-        this.authenticationDatabase = authenticationDatabase;
-    }
-
-    /**
-     * Creates a {@link MongoDBClientSupport} instance in standalone mode.
-     */
-    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());
-        if (MongoDBAuthenticationUtils.usesAuthentication(standalone)) {
-            return new MongoDBClientSupport(address, standalone.sensors().get(MongoDBAuthenticationMixins.ROOT_USERNAME),
-                    standalone.sensors().get(MongoDBAuthenticationMixins.ROOT_PASSWORD), standalone.sensors().get(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE));
-        } else {
-            return new MongoDBClientSupport(address);
-        }
-    }
-
-    private ServerAddress getServerAddress() {
-        MongoClient client = client();
-        try {
-            return client.getServerAddressList().get(0);
-        } finally {
-            client.close();
-        }
-    }
-
-    private HostAndPort getServerHostAndPort() {
-        ServerAddress address = getServerAddress();
-        return HostAndPort.fromParts(address.getHost(), address.getPort());
-    }
-
-    public Optional<CommandResult> runDBCommand(String database, String command) {
-        return runDBCommand(database, new BasicDBObject(command, Boolean.TRUE));
-    }
-
-    private Optional<CommandResult> runDBCommand(String database, final DBObject command) {
-        MongoClient client = client();
-        try {
-            final DB db = client.getDB(database);
-            final CommandResult[] status = new CommandResult[1];
-
-            // The mongoDB client can occasionally fail to connect. Try up to 5 times to run the command
-            boolean commandResult = Repeater.create().backoff(Duration.ONE_SECOND, 1.5, null).limitIterationsTo(5)
-                    .until(new Callable<Boolean>() {
-                        @Override
-                        public Boolean call() throws Exception {
-                            try {
-                                status[0] = db.command(command);
-                                return true;
-                            } catch (Exception e) {
-                                LOG.warn("Command " + command + " on " + address.getHost() + " failed", e);
-                                return false;
-                            }
-                        }
-            }).run();
-
-            if (!commandResult) {
-                return Optional.absent();
-            }
-
-            if (!status[0].ok()) {
-                LOG.debug("Unexpected result of {} on {}: {}",
-                        new Object[] { command, getServerAddress(), status[0].getErrorMessage() });
-            }
-            return Optional.of(status[0]);
-        } finally {
-            client.close();
-        }
-    }
-    
-    public long getShardCount() {
-        MongoClient client = client();
-        try {
-            return client.getDB("config").getCollection("shards").getCount();
-        } finally {
-            client.close();
-        }
-    }
-
-    public BasicBSONObject getServerStatus() {
-        Optional<CommandResult> result = runDBCommand("admin", "serverStatus");
-        if (result.isPresent() && result.get().ok()) {
-            return result.get();
-        } else {
-            return EMPTY_RESPONSE;
-        }
-    }
-    
-    public boolean ping() {
-        MongoClient client = fastClient();
-        DBObject command = new BasicDBObject("ping", "1");
-        final DB db = client.getDB("admin");
-
-        try {
-            CommandResult status = db.command(command);
-            return status.ok();
-        } catch (MongoException e) {
-            LOG.warn("Pinging server {} failed with {}", address.getHost(), e);
-        } finally {
-            client.close();
-        }
-        return false;
-    }
-
-    public boolean initializeReplicaSet(String replicaSetName, Integer id) {
-        HostAndPort primary = getServerHostAndPort();
-        BasicBSONObject config = ReplicaSetConfig.builder(replicaSetName)
-                .member(primary, id)
-                .build();
-
-        BasicDBObject dbObject = new BasicDBObject("replSetInitiate", config);
-        LOG.debug("Initiating replica set with: " + dbObject);
-
-        Optional<CommandResult> result = runDBCommand("admin", dbObject);
-        if (result.isPresent() && result.get().ok() && LOG.isDebugEnabled()) {
-            LOG.debug("Completed initiating MongoDB replica set {} on entity {}", replicaSetName, this);
-        }
-        return result.isPresent() && result.get().ok();
-    }
-
-    /**
-     * Java equivalent of calling rs.conf() in the console.
-     */
-    private BSONObject getReplicaSetConfig() {
-        MongoClient client = client();
-        try {
-            return client.getDB("local").getCollection("system.replset").findOne();
-        } catch (MongoException e) {
-            LOG.error("Failed to get replica set config on "+client, e);
-            return null;
-        } finally {
-            client.close();
-        }
-    }
-
-    /**
-     * Runs <code>replSetGetStatus</code> on the admin database.
-     *
-     * @return The result of <code>replSetGetStatus</code>, or
-     *         an empty {@link BasicBSONObject} if the command threw an exception (e.g. if
-     *         the connection was reset) or if the resultant {@link CommandResult#ok} was false.
-     *
-     * @see <a href="http://docs.mongodb.org/manual/reference/replica-status/">Replica set status reference</a>
-     * @see <a href="http://docs.mongodb.org/manual/reference/command/replSetGetStatus/">replSetGetStatus documentation</a>
-     */
-    public BasicBSONObject getReplicaSetStatus() {
-        Optional<CommandResult> result = runDBCommand("admin", "replSetGetStatus");
-        if (result.isPresent() && result.get().ok()) {
-            return result.get();
-        } else {
-            return EMPTY_RESPONSE;
-        }
-    }
-
-    /**
-     * Reconfigures the replica set that this client is the primary member of to include a new member.
-     * <p/>
-     * Note that this can cause long downtime (typically 10-20s, even up to a minute).
-     *
-     * @param secondary New member of the set.
-     * @param id The id for the new set member. Must be unique within the set.
-     * @return True if successful
-     */
-    public boolean addMemberToReplicaSet(MongoDBServer secondary, Integer id) {
-        // We need to:
-        // - get the existing configuration
-        // - update its version
-        // - add the new member to its list of members
-        // - run replSetReconfig with the new configuration.
-        BSONObject existingConfig = getReplicaSetConfig();
-        if (existingConfig == null) {
-            LOG.warn("Couldn't load existing config for replica set from {}. Server {} not added.",
-                    getServerAddress(), secondary);
-            return false;
-        }
-
-        BasicBSONObject newConfig = ReplicaSetConfig.fromExistingConfig(existingConfig)
-                .primary(getServerHostAndPort())
-                .member(secondary, id)
-                .build();
-        return reconfigureReplicaSet(newConfig);
-    }
-
-    /**
-     * Reconfigures the replica set that this client is the primary member of to
-     * remove the given server.
-     * @param server The server to remove
-     * @return True if successful
-     */
-    public boolean removeMemberFromReplicaSet(MongoDBServer server) {
-        BSONObject existingConfig = getReplicaSetConfig();
-        if (existingConfig == null) {
-            LOG.warn("Couldn't load existing config for replica set from {}. Server {} not removed.",
-                    getServerAddress(), server);
-            return false;
-        }
-        BasicBSONObject newConfig = ReplicaSetConfig.fromExistingConfig(existingConfig)
-                .primary(getServerHostAndPort())
-                .remove(server)
-                .build();
-        return reconfigureReplicaSet(newConfig);
-    }
-
-    /**
-     * Runs replSetReconfig with the given BasicBSONObject. Returns true if the result's
-     * status is ok.
-     */
-    private boolean reconfigureReplicaSet(BasicBSONObject newConfig) {
-        BasicDBObject command = new BasicDBObject("replSetReconfig", newConfig);
-        LOG.debug("Reconfiguring replica set to: " + command);
-        Optional<CommandResult> result = runDBCommand("admin", command);
-        return result.isPresent() && result.get().ok();
-    }
-
-    public boolean addShardToRouter(String hostAndPort) {
-        LOG.debug("Adding shard " + hostAndPort);
-        BasicDBObject command = new BasicDBObject("addShard", hostAndPort);
-        Optional<CommandResult> result = runDBCommand("admin", command);
-        return result.isPresent() && result.get().ok();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBDriver.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBDriver.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBDriver.java
deleted file mode 100644
index e66b8e7..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBDriver.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.entity.software.base.SoftwareProcessDriver;
-
-public interface MongoDBDriver extends SoftwareProcessDriver {
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
deleted file mode 100644
index 6ebc17e..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 java.util.Collection;
-import java.util.List;
-
-import org.apache.brooklyn.api.entity.ImplementedBy;
-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.Sensors;
-import org.apache.brooklyn.entity.database.DatastoreMixins.HasDatastoreUrl;
-import org.apache.brooklyn.entity.group.Cluster;
-import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-
-import com.google.common.reflect.TypeToken;
-
-/**
- * A replica set of {@link MongoDBServer}s, based on {@link DynamicCluster} which can be resized by a policy
- * if required.
- *
- * <p/><b>Note</b>
- * An issue with <code>mongod</code> on Mac OS X can cause unpredictable failure of servers at start-up.
- * See <a href="https://groups.google.com/forum/#!topic/mongodb-user/QRQYdIXOR2U">this mailing list post</a>
- * for more information.
- *
- * <p/>This replica set implementation has been tested on OS X 10.6 and Ubuntu 12.04.
- *
- * @see <a href="http://docs.mongodb.org/manual/replication/">http://docs.mongodb.org/manual/replication/</a>
- */
-@ImplementedBy(MongoDBReplicaSetImpl.class)
-public interface MongoDBReplicaSet extends DynamicCluster, MongoDBAuthenticationMixins, HasDatastoreUrl {
-
-    @SetFromFlag("replicaSetName")
-    ConfigKey<String> REPLICA_SET_NAME = ConfigKeys.newStringConfigKey(
-            "mongodb.replicaSet.name", "Name of the MongoDB replica set", "BrooklynCluster");
-
-    ConfigKey<Integer> INITIAL_SIZE = ConfigKeys.newConfigKeyWithDefault(Cluster.INITIAL_SIZE, 3);
-
-    AttributeSensor<MongoDBServer> PRIMARY_ENTITY = Sensors.newSensor(
-            MongoDBServer.class, "mongodb.replicaSet.primary.entity", "The entity acting as primary");
-
-    @SuppressWarnings("serial")
-    AttributeSensor<List<String>> REPLICA_SET_ENDPOINTS = Sensors.newSensor(new TypeToken<List<String>>() {}, 
-        "mongodb.replicaSet.endpoints", "Endpoints active for this replica set");
-    
-
-    /**
-     * The name of the replica set.
-     */
-    String getName();
-
-    /**
-     * @return The primary MongoDB server in the replica set.
-     */
-    MongoDBServer getPrimary();
-
-    /**
-     * @return The secondary servers in the replica set.
-     */
-    Collection<MongoDBServer> getSecondaries();
-
-    /**
-     * @return All servers in the replica set.
-     */
-    Collection<MongoDBServer> getReplicas();
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/02abbab0/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java b/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
deleted file mode 100644
index 1a80c3a..0000000
--- a/brooklyn-library/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * 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 static com.google.common.base.Preconditions.checkArgument;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
-import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.enricher.stock.Enrichers;
-import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
-import org.apache.brooklyn.entity.group.DynamicClusterImpl;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableSet;
-import org.apache.brooklyn.util.text.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Sets;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-/**
- * Implementation of {@link MongoDBReplicaSet}.
- *
- * Replica sets have a <i>minimum</i> of three members.
- *
- * Removal strategy is always {@link #NON_PRIMARY_REMOVAL_STRATEGY}.
- */
-public class MongoDBReplicaSetImpl extends DynamicClusterImpl implements MongoDBReplicaSet {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MongoDBReplicaSetImpl.class);
-
-    // Provides IDs for replica set members. The first member will have ID 0.
-    private final AtomicInteger nextMemberId = new AtomicInteger(0);
-
-    private MemberTrackingPolicy policy;
-    private final AtomicBoolean mustInitialise = new AtomicBoolean(true);
-
-    @SuppressWarnings("unchecked")
-    protected static final List<AttributeSensor<Long>> SENSORS_TO_SUM = Arrays.asList(
-        MongoDBServer.OPCOUNTERS_INSERTS,
-        MongoDBServer.OPCOUNTERS_QUERIES,
-        MongoDBServer.OPCOUNTERS_UPDATES,
-        MongoDBServer.OPCOUNTERS_DELETES,
-        MongoDBServer.OPCOUNTERS_GETMORE,
-        MongoDBServer.OPCOUNTERS_COMMAND,
-        MongoDBServer.NETWORK_BYTES_IN,
-        MongoDBServer.NETWORK_BYTES_OUT,
-        MongoDBServer.NETWORK_NUM_REQUESTS);
-    
-    public MongoDBReplicaSetImpl() {
-    }
-
-    /**
-     * Manages member addition and removal.
-     *
-     * It's important that this is a single thread: the concurrent addition and removal
-     * of members from the set would almost certainly have unintended side effects,
-     * like reconfigurations using outdated ReplicaSetConfig instances.
-     */
-    private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
-
-    /** true iff input is a non-null MongoDBServer with attribute REPLICA_SET_MEMBER_STATUS PRIMARY. */
-    static final Predicate<Entity> IS_PRIMARY = new Predicate<Entity>() {
-        // getPrimary relies on instanceof check
-        @Override public boolean apply(@Nullable Entity input) {
-            return input != null
-                    && input instanceof MongoDBServer
-                    && ReplicaSetMemberStatus.PRIMARY.equals(input.sensors().get(MongoDBServer.REPLICA_SET_MEMBER_STATUS));
-        }
-    };
-
-    /** true iff. input is a non-null MongoDBServer with attribute REPLICA_SET_MEMBER_STATUS SECONDARY. */
-    static final Predicate<Entity> IS_SECONDARY = new Predicate<Entity>() {
-        @Override public boolean apply(@Nullable Entity input) {
-            // getSecondaries relies on instanceof check
-            return input != null
-                    && input instanceof MongoDBServer
-                    && ReplicaSetMemberStatus.SECONDARY.equals(input.sensors().get(MongoDBServer.REPLICA_SET_MEMBER_STATUS));
-        }
-    };
-
-    /**
-     * {@link Function} for use as the cluster's removal strategy. Chooses any entity with
-     * {@link MongoDBServer#IS_PRIMARY_FOR_REPLICA_SET} true last of all.
-     */
-    private static final Function<Collection<Entity>, Entity> NON_PRIMARY_REMOVAL_STRATEGY = new Function<Collection<Entity>, Entity>() {
-        @Override
-        public Entity apply(@Nullable Collection<Entity> entities) {
-            checkArgument(entities != null && entities.size() > 0, "Expect list of MongoDBServers to have at least one entry");
-            return Iterables.tryFind(entities, Predicates.not(IS_PRIMARY)).or(Iterables.get(entities, 0));
-        }
-    };
-    
-    @Override
-    public void init() {
-        super.init();
-        enrichers().add(Enrichers.builder()
-                .aggregating(MongoDBAuthenticationMixins.ROOT_USERNAME)
-                .publishing(MongoDBAuthenticationMixins.ROOT_USERNAME)
-                .fromMembers()
-                .valueToReportIfNoSensors(null)
-                .computing(new RootUsernameReducer())
-                .build());
-    }
-
-    public static class RootUsernameReducer implements Function<Collection<String>, String>{
-        @Override
-        public String apply(Collection<String> input) {
-            // when authentication is used all members have the same value
-            return (input == null || input.isEmpty()) ? null : Iterables.getFirst(input, null);
-        };
-    }
-
-    /** @return {@link #NON_PRIMARY_REMOVAL_STRATEGY} */
-    @Override
-    public Function<Collection<Entity>, Entity> getRemovalStrategy() {
-        return NON_PRIMARY_REMOVAL_STRATEGY;
-    }
-
-    @Override
-    protected EntitySpec<?> getMemberSpec() {
-        EntitySpec<?> spec = config().get(MEMBER_SPEC);
-        if (spec == null) {
-            spec = EntitySpec.create(MongoDBServer.class);
-            config().set(MEMBER_SPEC, spec);
-        }
-        MongoDBAuthenticationUtils.setAuthenticationConfig(spec, this);
-        return spec;
-    }
-
-    /**
-     * Sets {@link MongoDBServer#REPLICA_SET}.
-     */
-    @Override
-    protected Map<?,?> getCustomChildFlags() {
-        return ImmutableMap.builder()
-                .putAll(super.getCustomChildFlags())
-                .put(MongoDBServer.REPLICA_SET, getProxy())
-                .build();
-    }
-
-    @Override
-    public String getName() {
-        // FIXME: Names must be unique if the replica sets are used in a sharded cluster
-        return config().get(REPLICA_SET_NAME) + this.getId();
-    }
-
-    @Override
-    public MongoDBServer getPrimary() {
-        return Iterables.tryFind(getReplicas(), IS_PRIMARY).orNull();
-    }
-
-    @Override
-    public Collection<MongoDBServer> getSecondaries() {
-        return FluentIterable.from(getReplicas())
-                .filter(IS_SECONDARY)
-                .toList();
-    }
-
-    @Override
-    public Collection<MongoDBServer> getReplicas() {
-        return FluentIterable.from(getMembers())
-                .transform(new Function<Entity, MongoDBServer>() {
-                    @Override public MongoDBServer apply(Entity input) {
-                        return MongoDBServer.class.cast(input);
-                    }
-                })
-                .toList();
-    }
-
-    /**
-     * Initialises the replica set with the given server as primary if {@link #mustInitialise} is true,
-     * otherwise schedules the addition of a new secondary.
-     */
-    private void serverAdded(MongoDBServer server) {
-        try {
-            LOG.debug("Server added: {}. SERVICE_UP: {}", server, server.sensors().get(MongoDBServer.SERVICE_UP));
-
-            // Set the primary if the replica set hasn't been initialised.
-            if (mustInitialise.compareAndSet(true, false)) {
-                if (LOG.isInfoEnabled())
-                    LOG.info("First server up in {} is: {}", getName(), server);
-                boolean replicaSetInitialised = server.initializeReplicaSet(getName(), nextMemberId.getAndIncrement());
-                if (replicaSetInitialised) {
-                    sensors().set(PRIMARY_ENTITY, server);
-                    sensors().set(Startable.SERVICE_UP, true);
-                } else {
-                    ServiceStateLogic.ServiceNotUpLogic.updateNotUpIndicator(this, "initialization", "replicaset failed to initialize");
-                    ServiceStateLogic.setExpectedState(this, Lifecycle.ON_FIRE);
-                }
-            } else {
-                if (LOG.isDebugEnabled())
-                    LOG.debug("Scheduling addition of member to {}: {}", getName(), server);
-                addSecondaryWhenPrimaryIsNonNull(server);
-            }
-        } catch (Exception e) {
-            ServiceStateLogic.ServiceNotUpLogic.updateNotUpIndicator((EntityLocal)server, "Failed to update replicaset", e);
-        }
-    }
-
-    /**
-     * Adds a server as a secondary in the replica set.
-     * <p/>
-     * If {@link #getPrimary} returns non-null submit the secondary to the primary's
-     * {@link MongoDBClientSupport}. Otherwise, reschedule the task to run again in three
-     * seconds time (in the hope that next time the primary will be available).
-     */
-    private void addSecondaryWhenPrimaryIsNonNull(final MongoDBServer secondary) {
-        // TODO Don't use executor, use ExecutionManager
-        executor.submit(new Runnable() {
-            @Override
-            public void run() {
-                // SERVICE_UP is not guaranteed when additional members are added to the set.
-                Boolean isAvailable = secondary.sensors().get(MongoDBServer.SERVICE_UP);
-                MongoDBServer primary = getPrimary();
-                boolean reschedule;
-                if (Boolean.TRUE.equals(isAvailable) && primary != null) {
-                    boolean added = primary.addMemberToReplicaSet(secondary, nextMemberId.incrementAndGet());
-                    if (added) {
-                        LOG.info("{} added to replica set {}", secondary, getName());
-                        reschedule = false;
-                    } else {
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("{} could not be added to replica set via {}; rescheduling", secondary, getName());
-                        }
-                        reschedule = true;
-                    }
-                } else {
-                    if (LOG.isTraceEnabled()) {
-                        LOG.trace("Rescheduling addition of member {} to replica set {}: service_up={}, primary={}",
-                            new Object[] {secondary, getName(), isAvailable, primary});
-                    }
-                    reschedule = true;
-                }
-                
-                if (reschedule) {
-                    // TODO Could limit number of retries
-                    executor.schedule(this, 3, TimeUnit.SECONDS);
-                }
-            }
-        });
-    }
-
-    /**
-     * Removes a server from the replica set.
-     * <p/>
-     * Submits a task that waits for the member to be down and for the replica set to have a primary
-     * member, then reconfigures the set to remove the member, to {@link #executor}. If either of the
-     * two conditions are not met then the task reschedules itself.
-     *
-     * @param member The server to be removed from the replica set.
-     */
-    private void serverRemoved(final MongoDBServer member) {
-        try {
-            if (LOG.isDebugEnabled())
-                LOG.debug("Scheduling removal of member from {}: {}", getName(), member);
-            // FIXME is there a chance of race here?
-            if (member.equals(sensors().get(PRIMARY_ENTITY)))
-                sensors().set(PRIMARY_ENTITY, null);
-            executor.submit(new Runnable() {
-                @Override
-                public void run() {
-                    // Wait until the server has been stopped before reconfiguring the set. Quoth the MongoDB doc:
-                    // for best results always shut down the mongod instance before removing it from a replica set.
-                    Boolean isAvailable = member.sensors().get(MongoDBServer.SERVICE_UP);
-                    // Wait for the replica set to elect a new primary if the set is reconfiguring itself.
-                    MongoDBServer primary = getPrimary();
-                    boolean reschedule;
-
-                    if (primary != null && !isAvailable) {
-                        boolean removed = primary.removeMemberFromReplicaSet(member);
-                        if (removed) {
-                            LOG.info("Removed {} from replica set {}", member, getName());
-                            reschedule = false;
-                        } else {
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("{} could not be removed from replica set via {}; rescheduling", member, getName());
-                            }
-                            reschedule = true;
-                        }
-
-                    } else {
-                        if (LOG.isTraceEnabled()) {
-                            LOG.trace("Rescheduling removal of member {} from replica set {}: service_up={}, primary={}",
-                                    new Object[]{member, getName(), isAvailable, primary});
-                        }
-                        reschedule = true;
-                    }
-
-                    if (reschedule) {
-                        // TODO Could limit number of retries
-                        executor.schedule(this, 3, TimeUnit.SECONDS);
-                    }
-                }
-            });
-        } catch (Exception e) {
-            ServiceStateLogic.ServiceNotUpLogic.updateNotUpIndicator((EntityLocal)member, "Failed to update replicaset", e);
-        }
-    }
-
-    @Override
-    public void start(Collection<? extends Location> locations) {
-        // Promises that all the cluster's members have SERVICE_UP true on returning.
-        super.start(locations);
-        policy = policies().add(PolicySpec.create(MemberTrackingPolicy.class)
-                .displayName(getName() + " membership tracker")
-                .configure("group", this));
-
-        for (AttributeSensor<Long> sensor: SENSORS_TO_SUM)
-            enrichers().add(Enrichers.builder()
-                    .aggregating(sensor)
-                    .publishing(sensor)
-                    .fromMembers()
-                    .computingSum()
-                    .valueToReportIfNoSensors(null)
-                    .defaultValueForUnreportedSensors(null)
-                    .build());
-        
-        // FIXME would it be simpler to have a *subscription* on four or five sensors on allMembers, including SERVICE_UP
-        // (which we currently don't check), rather than an enricher, and call to an "update" method?
-        enrichers().add(Enrichers.builder()
-                .aggregating(MongoDBServer.REPLICA_SET_PRIMARY_ENDPOINT)
-                .publishing(MongoDBServer.REPLICA_SET_PRIMARY_ENDPOINT)
-                .fromMembers()
-                .valueToReportIfNoSensors(null)
-                .computing(new Function<Collection<String>, String>() {
-                        @Override
-                        public String apply(Collection<String> input) {
-                            if (input==null || input.isEmpty()) return null;
-                            Set<String> distinct = MutableSet.of();
-                            for (String endpoint: input)
-                                if (!Strings.isBlank(endpoint))
-                                    distinct.add(endpoint);
-                            if (distinct.size()>1)
-                                LOG.warn("Mongo replica set "+MongoDBReplicaSetImpl.this+" detetcted multiple masters (transitioning?): "+distinct);
-                            return input.iterator().next();
-                        }})
-                .build());
-
-        enrichers().add(Enrichers.builder()
-                .aggregating(MongoDBServer.MONGO_SERVER_ENDPOINT)
-                .publishing(REPLICA_SET_ENDPOINTS)
-                .fromMembers()
-                .valueToReportIfNoSensors(null)
-                .computing(new Function<Collection<String>, List<String>>() {
-                        @Override
-                        public List<String> apply(Collection<String> input) {
-                            Set<String> endpoints = new TreeSet<String>();
-                            for (String endpoint: input) {
-                                if (!Strings.isBlank(endpoint)) {
-                                    endpoints.add(endpoint);
-                                }
-                            }
-                            return MutableList.copyOf(endpoints);
-                        }})
-                .build());
-        
-        enrichers().add(Enrichers.builder()
-                .transforming(REPLICA_SET_ENDPOINTS)
-                .publishing(DATASTORE_URL)
-                .computing(new EndpointsToDatastoreUrlMapper(this))
-                .build());
-
-        subscriptions().subscribeToMembers(this, MongoDBServer.IS_PRIMARY_FOR_REPLICA_SET, new SensorEventListener<Boolean>() {
-            @Override public void onEvent(SensorEvent<Boolean> event) {
-                if (Boolean.TRUE == event.getValue())
-                    sensors().set(PRIMARY_ENTITY, (MongoDBServer)event.getSource());
-            }
-        });
-
-    }
-    
-    public static class EndpointsToDatastoreUrlMapper implements Function<Collection<String>, String> {
-        
-        private Entity entity;
-
-        public EndpointsToDatastoreUrlMapper(Entity entity) {
-            this.entity = entity;
-        }
-        
-        @Override
-        public String apply(Collection<String> input) {
-            String credentials = MongoDBAuthenticationUtils.usesAuthentication(entity) 
-                    ? String.format("%s:%s@", 
-                            entity.config().get(MongoDBAuthenticationMixins.ROOT_USERNAME), 
-                            entity.config().get(MongoDBAuthenticationMixins.ROOT_PASSWORD)) 
-                    : "";
-            return String.format("mongodb://%s%s", credentials, Strings.join(input, ","));
-        }
-    }
-
-    @Override
-    public void stop() {
-        // Do we want to remove the members from the replica set?
-        //  - if the set is being stopped forever it's irrelevant
-        //  - if the set might be restarted I think it just inconveniences us
-        // Terminate the executor immediately.
-        // TODO Note that after this the executor will not run if the set is restarted.
-        executor.shutdownNow();
-        super.stop();
-        sensors().set(Startable.SERVICE_UP, false);
-    }
-
-    @Override
-    public void onManagementStopped() {
-        super.onManagementStopped();
-        executor.shutdownNow();
-    }
-    
-    public static class MemberTrackingPolicy extends AbstractMembershipTrackingPolicy {
-        @Override protected void onEntityChange(Entity member) {
-            // Ignored
-        }
-        @Override protected void onEntityAdded(Entity member) {
-            ((MongoDBReplicaSetImpl) entity).serverAdded((MongoDBServer) member);
-        }
-        @Override protected void onEntityRemoved(Entity member) {
-            ((MongoDBReplicaSetImpl) entity).serverRemoved((MongoDBServer) member);
-        }
-    }
-}