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);
- }
- }
-}