You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/11/25 13:17:48 UTC
[03/13] incubator-brooklyn git commit: MongoDB: support disabling
direct connection
MongoDB: support disabling direct connection
- Important if MongoDB is locked down such that only ssh access to
the VM is available.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/ec76f129
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/ec76f129
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/ec76f129
Branch: refs/heads/master
Commit: ec76f129e7a977b5c326e38eabe6a2b1cfde7d73
Parents: d6311c2
Author: Aled Sage <al...@gmail.com>
Authored: Wed Nov 18 15:35:49 2015 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Nov 24 13:53:45 2015 +0000
----------------------------------------------------------------------
.../brooklyn/entity/AbstractEc2LiveTest.java | 48 +++++++++-
.../nosql/mongodb/AbstractMongoDBSshDriver.java | 8 +-
.../entity/nosql/mongodb/MongoDBServer.java | 3 +
.../entity/nosql/mongodb/MongoDBServerImpl.java | 96 +++++++++++---------
.../nosql/mongodb/MongoDBEc2LiveTest.java | 42 +++++++--
5 files changed, 145 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ec76f129/software/base/src/test/java/org/apache/brooklyn/entity/AbstractEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/AbstractEc2LiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/AbstractEc2LiveTest.java
index 0a1e9d7..3874346 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/AbstractEc2LiveTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/AbstractEc2LiveTest.java
@@ -18,17 +18,29 @@
*/
package org.apache.brooklyn.entity;
+import static org.testng.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.util.List;
import java.util.Map;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.location.jclouds.JcloudsLocation;
import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.ssh.BashCommands;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -46,6 +58,8 @@ public abstract class AbstractEc2LiveTest extends BrooklynAppLiveTestSupport {
// to say what combo of provider/region/flags should be used. The problem with that is the
// IDE integration: one can't just select a single test to run.
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractEc2LiveTest.class);
+
public static final String PROVIDER = "aws-ec2";
public static final String REGION_NAME = "us-east-1";
public static final String LOCATION_SPEC = PROVIDER + (REGION_NAME == null ? "" : ":" + REGION_NAME);
@@ -136,4 +150,32 @@ public abstract class AbstractEc2LiveTest extends BrooklynAppLiveTestSupport {
}
protected abstract void doTest(Location loc) throws Exception;
+
+ protected void assertExecSsh(SoftwareProcess entity, List<String> commands) {
+ SshMachineLocation machine = Machines.findUniqueMachineLocation(entity.getLocations(), SshMachineLocation.class).get();
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ ByteArrayOutputStream errStream = new ByteArrayOutputStream();
+ int result = machine.execScript(ImmutableMap.of("out", outStream, "err", errStream), "url-reachable", commands);
+ String out = new String(outStream.toByteArray());
+ String err = new String(errStream.toByteArray());
+ if (result == 0) {
+ LOG.debug("Successfully executed: cmds="+commands+"; stderr="+err+"; out="+out);
+ } else {
+ fail("Failed to execute: result="+result+"; cmds="+commands+"; stderr="+err+"; out="+out);
+ }
+ }
+
+ protected void assertViaSshLocalPortListeningEventually(final SoftwareProcess server, final int port) {
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), new Runnable() {
+ public void run() {
+ assertExecSsh(server, ImmutableList.of("netstat -antp", "netstat -antp | grep LISTEN | grep "+port));
+ }});
+ }
+
+ protected void assertViaSshLocalUrlListeningEventually(final SoftwareProcess server, final String url) {
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), new Runnable() {
+ public void run() {
+ assertExecSsh(server, ImmutableList.of(BashCommands.installPackage("curl"), "netstat -antp", "curl -k --retry 3 "+url));
+ }});
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ec76f129/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
index 14c495e..ccbe470 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
@@ -28,6 +28,7 @@ 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;
@@ -115,7 +116,12 @@ public abstract class AbstractMongoDBSshDriver extends AbstractSoftwareProcessSs
@Override
public boolean isRunning() {
try {
- return MongoDBClientSupport.forServer((AbstractMongoDBServer) entity).ping();
+ 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;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ec76f129/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java
index 2ec38dc..34c07d3 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java
@@ -50,6 +50,9 @@ public interface MongoDBServer extends AbstractMongoDBServer {
ConfigKey<Boolean> ENABLE_REST_INTERFACE = ConfigKeys.newBooleanConfigKey(
"mongodb.config.enable_rest", "Adds --rest to server startup flags when true", Boolean.FALSE);
+ @SetFromFlag("useClientMonitoring")
+ ConfigKey<Boolean> USE_CLIENT_MONITORING = ConfigKeys.newConfigKey("clientMonitoring.enabled", "Monitoring via the MongoDB client enabled", Boolean.TRUE);
+
AttributeSensor<String> HTTP_INTERFACE_URL = Sensors.newStringSensor(
"mongodb.server.http_interface", "URL of the server's HTTP console");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ec76f129/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
index 2469046..35b60e8 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
@@ -71,54 +71,58 @@ public class MongoDBServerImpl extends SoftwareProcessImpl implements MongoDBSer
sensors().set(HTTP_INTERFACE_URL, String.format("http://%s:%d",
accessibleAddress.getHostText(), httpConsolePort));
- try {
- client = MongoDBClientSupport.forServer(this);
- } catch (UnknownHostException e) {
- LOG.warn("Unable to create client connection to {}, not connecting sensors: {} ", this, e.getMessage());
- return;
- }
-
- serviceStats = FunctionFeed.builder()
- .entity(this)
- .poll(new FunctionPollConfig<Object, BasicBSONObject>(STATUS_BSON)
- .period(2, TimeUnit.SECONDS)
- .callable(new Callable<BasicBSONObject>() {
- @Override
- public BasicBSONObject call() throws Exception {
- return MongoDBServerImpl.this.sensors().get(SERVICE_UP)
- ? client.getServerStatus()
- : null;
- }
- })
- .onException(Functions.<BasicBSONObject>constant(null)))
- .build();
-
- if (isReplicaSetMember()) {
- replicaSetStats = FunctionFeed.builder()
+ if (clientAccessEnabled()) {
+ try {
+ client = MongoDBClientSupport.forServer(this);
+ } catch (UnknownHostException e) {
+ LOG.warn("Unable to create client connection to {}, not connecting sensors: {} ", this, e.getMessage());
+ return;
+ }
+
+ serviceStats = FunctionFeed.builder()
.entity(this)
- .poll(new FunctionPollConfig<Object, ReplicaSetMemberStatus>(REPLICA_SET_MEMBER_STATUS)
+ .poll(new FunctionPollConfig<Object, BasicBSONObject>(STATUS_BSON)
.period(2, TimeUnit.SECONDS)
- .callable(new Callable<ReplicaSetMemberStatus>() {
- /**
- * Calls {@link MongoDBClientSupport#getReplicaSetStatus} and
- * extracts <code>myState</code> from the response.
- * @return
- * The appropriate {@link org.apache.brooklyn.entity.nosql.mongodb.ReplicaSetMemberStatus}
- * if <code>myState</code> was non-null, {@link ReplicaSetMemberStatus#UNKNOWN} otherwise.
- */
+ .callable(new Callable<BasicBSONObject>() {
@Override
- public ReplicaSetMemberStatus call() {
- BasicBSONObject serverStatus = client.getReplicaSetStatus();
- int state = serverStatus.getInt("myState", -1);
- return ReplicaSetMemberStatus.fromCode(state);
+ public BasicBSONObject call() throws Exception {
+ return MongoDBServerImpl.this.sensors().get(SERVICE_UP)
+ ? client.getServerStatus()
+ : null;
}
})
- .onException(Functions.constant(ReplicaSetMemberStatus.UNKNOWN))
- .suppressDuplicates(true))
+ .onException(Functions.<BasicBSONObject>constant(null)))
.build();
+
+ if (isReplicaSetMember()) {
+ replicaSetStats = FunctionFeed.builder()
+ .entity(this)
+ .poll(new FunctionPollConfig<Object, ReplicaSetMemberStatus>(REPLICA_SET_MEMBER_STATUS)
+ .period(2, TimeUnit.SECONDS)
+ .callable(new Callable<ReplicaSetMemberStatus>() {
+ /**
+ * Calls {@link MongoDBClientSupport#getReplicaSetStatus} and
+ * extracts <code>myState</code> from the response.
+ * @return
+ * The appropriate {@link org.apache.brooklyn.entity.nosql.mongodb.ReplicaSetMemberStatus}
+ * if <code>myState</code> was non-null, {@link ReplicaSetMemberStatus#UNKNOWN} otherwise.
+ */
+ @Override
+ public ReplicaSetMemberStatus call() {
+ BasicBSONObject serverStatus = client.getReplicaSetStatus();
+ int state = serverStatus.getInt("myState", -1);
+ return ReplicaSetMemberStatus.fromCode(state);
+ }
+ })
+ .onException(Functions.constant(ReplicaSetMemberStatus.UNKNOWN))
+ .suppressDuplicates(true))
+ .build();
+ } else {
+ sensors().set(IS_PRIMARY_FOR_REPLICA_SET, false);
+ sensors().set(IS_SECONDARY_FOR_REPLICA_SET, false);
+ }
} else {
- sensors().set(IS_PRIMARY_FOR_REPLICA_SET, false);
- sensors().set(IS_SECONDARY_FOR_REPLICA_SET, false);
+ LOG.info("Not monitoring "+this+" to retrieve state via client API");
}
// Take interesting details from STATUS.
@@ -163,6 +167,10 @@ public class MongoDBServerImpl extends SoftwareProcessImpl implements MongoDBSer
if (replicaSetStats != null) replicaSetStats.stop();
}
+ protected boolean clientAccessEnabled() {
+ return Boolean.TRUE.equals(config().get(MongoDBServer.USE_CLIENT_MONITORING));
+ }
+
@Override
public MongoDBReplicaSet getReplicaSet() {
return config().get(MongoDBServer.REPLICA_SET);
@@ -190,6 +198,9 @@ public class MongoDBServerImpl extends SoftwareProcessImpl implements MongoDBSer
LOG.warn("Attempted to add {} to replica set at server that is not primary: {}", secondary, this);
return false;
}
+ if (!clientAccessEnabled()) {
+ throw new IllegalStateException("client-access disabled for "+this+"; cannot add to replica set member "+secondary+" -> "+id);
+ }
return client.addMemberToReplicaSet(secondary, id);
}
@@ -199,6 +210,9 @@ public class MongoDBServerImpl extends SoftwareProcessImpl implements MongoDBSer
LOG.warn("Attempted to remove {} from replica set at server that is not primary: {}", server, this);
return false;
}
+ if (!clientAccessEnabled()) {
+ throw new IllegalStateException("client-access disabled for "+this+"; cannot remove from replica set member "+server);
+ }
return client.removeMemberFromReplicaSet(server);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ec76f129/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
index 6306b4e..5ad5fa7 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
@@ -18,19 +18,24 @@
*/
package org.apache.brooklyn.entity.nosql.mongodb;
-import com.google.common.collect.ImmutableList;
-import com.mongodb.DBObject;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.EntityAsserts;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import org.apache.brooklyn.entity.AbstractEc2LiveTest;
import org.apache.brooklyn.test.EntityTestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.mongodb.DBObject;
public class MongoDBEc2LiveTest extends AbstractEc2LiveTest {
@@ -50,6 +55,29 @@ public class MongoDBEc2LiveTest extends AbstractEc2LiveTest {
assertEquals(docOut.get("hello"), "world!");
}
+ @Test(groups = {"Live"})
+ public void testWithOnlyPort22() throws Exception {
+ // CentOS-6.3-x86_64-GA-EBS-02-85586466-5b6c-4495-b580-14f72b4bcf51-ami-bb9af1d2.1
+ jcloudsLocation = mgmt.getLocationRegistry().resolve(LOCATION_SPEC, ImmutableMap.of(
+ "tags", ImmutableList.of(getClass().getName()),
+ "imageId", "us-east-1/ami-a96b01c0",
+ "hardwareId", SMALL_HARDWARE_ID));
+
+ MongoDBServer server = app.createAndManageChild(EntitySpec.create(MongoDBServer.class)
+ .configure(MongoDBServer.PROVISIONING_PROPERTIES.subKey(CloudLocationConfig.INBOUND_PORTS.getName()), ImmutableList.of(22))
+ .configure(MongoDBServer.USE_CLIENT_MONITORING, false));
+
+ app.start(ImmutableList.of(jcloudsLocation));
+
+ EntityAsserts.assertAttributeEqualsEventually(server, Attributes.SERVICE_UP, true);
+ EntityAsserts.assertAttributeEqualsEventually(server, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+
+ Integer port = server.getAttribute(MongoDBServer.PORT);
+ assertNotNull(port);
+
+ assertViaSshLocalPortListeningEventually(server, port);
+ }
+
@Test(enabled=false)
public void testDummy() {} // Convince TestNG IDE integration that this really does have test methods