Merge pull request #1119 from richardcloudsoft/brooklynnode-fixes
BrooklynNode, various fixes
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
index 2196e34..8a166ac 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
@@ -18,6 +18,7 @@
import brooklyn.util.collections.MutableMap;
import brooklyn.util.flags.SetFromFlag;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Functions;
@@ -146,8 +147,9 @@
String.class, "brooklynnode.webconsole.bindAddress", "Specifies the IP address of the NIC to bind the Brooklyn Management Console to", null);
@SetFromFlag("classpath")
- public static final BasicAttributeSensorAndConfigKey<List<String>> CLASSPATH = new BasicAttributeSensorAndConfigKey(
- List.class, "brooklynnode.classpath", "classpath to use, as list of URL entries", Lists.newArrayList());
+ @Beta // ideally this should be List<String>, but this will require support for defining lists in brooklyn.properties
+ public static final BasicAttributeSensorAndConfigKey<String> CLASSPATH = new BasicAttributeSensorAndConfigKey(
+ String.class, "brooklynnode.classpath", "classpath to use, as a string of semi-colon separated URL entries", null);
@SetFromFlag("portMapper")
public static final ConfigKey<Function<? super Integer, ? extends Integer>> PORT_MAPPER = (ConfigKey) ConfigKeys.newConfigKey(Function.class,
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 68d9761..686e08c 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -3,6 +3,8 @@
import java.net.URI;
import java.util.List;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,8 +42,14 @@
return BrooklynNodeDriver.class;
}
- public List<String> getClasspath() {
- return getConfig(CLASSPATH);
+ public Iterable<String> getClasspath() {
+ String classpath = getConfig(CLASSPATH);
+ if (Strings.isBlank(classpath)) {
+ classpath = getManagementContext().getConfig().getConfig(CLASSPATH);
+ }
+ return Strings.isNonBlank(classpath)
+ ? Splitter.on(';').trimResults().omitEmptyStrings().split(classpath)
+ : ImmutableList.<String>of();
}
protected List<String> getEnabledHttpProtocols() {
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
index 536ef24..86fee36 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
@@ -99,6 +99,10 @@
newScript(CUSTOMIZING)
.failOnNonZeroResultCode()
.body.append(
+ // workaround for AMP distribution placing everything in the root of this archive, but
+ // brooklyn distribution placing everything in a subdirectory: check to see if subdirectory
+ // with expect name exists; symlink to same directory if it doesn't
+ format("[ -d %1$s/brooklyn-%2%s ] || ln -s . %1$s/brooklyn-%2$s", getInstallDir(), getVersion()),
format("cp -R %s/brooklyn-%s/{bin,conf} .", getInstallDir(), getVersion()),
"mkdir -p ./lib/")
.execute();
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
index a379393..0abf9fd 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
@@ -53,7 +53,7 @@
EntityLocal entity = brooklyn().getEntity(application, entityToken);
ConfigKey<?> ck = entity.getEntityType().getConfigKey(configKeyName);
if (ck==null) ck = new BasicConfigKey<Object>(Object.class, configKeyName);
- return getValueForDisplay(entity, ((AbstractEntity)entity).getConfigMap().getRawConfig(ck));
+ return getValueForDisplay(entity, entity.getConfig(ck));
}
private String getValueForDisplay(EntityLocal entity, Object value) {
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityConfigResourceTest.java b/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityConfigResourceTest.java
new file mode 100644
index 0000000..c6e0094
--- /dev/null
+++ b/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityConfigResourceTest.java
@@ -0,0 +1,101 @@
+package brooklyn.rest.resources;
+
+import brooklyn.rest.domain.ApplicationSpec;
+import brooklyn.rest.domain.EntityConfigSummary;
+import brooklyn.rest.domain.EntitySpec;
+import brooklyn.rest.testing.BrooklynRestResourceTest;
+import brooklyn.rest.testing.mocks.RestMockSimpleEntity;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.GenericType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import javax.annotation.Nullable;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+@Test(singleThreaded = true)
+public class EntityConfigResourceTest extends BrooklynRestResourceTest {
+
+ private final static Logger log = LoggerFactory.getLogger(EntityConfigResourceTest.class);
+ private URI application;
+
+ @Override
+ protected void setUpResources() throws Exception {
+ addResources();
+ }
+
+ @BeforeClass
+ @Override
+ public void setUp() throws Exception {
+ super.setUp(); // We require that the superclass setup is done first, as we will be calling out to Jersey
+
+ // Deploy an application that we'll use to read the configuration of
+ final ApplicationSpec simpleSpec = ApplicationSpec.builder().name("simple-app").
+ entities(ImmutableSet.of(new EntitySpec("simple-ent", RestMockSimpleEntity.class.getName(), ImmutableMap.of("install.version", "1.0.0")))).
+ locations(ImmutableSet.of("localhost")).
+ build();
+
+ ClientResponse response = client().resource("/v1/applications").post(ClientResponse.class, simpleSpec);
+ application = response.getLocation();
+ waitForApplicationToBeRunning(application);
+ }
+
+ @Test
+ public void testList() throws Exception {
+ List<EntityConfigSummary> entityConfigSummaries = client().resource(
+ URI.create("/v1/applications/simple-app/entities/simple-ent/config"))
+ .get(new GenericType<List<EntityConfigSummary>>() {
+ });
+
+ // Default entities have over a dozen config entries, but it's unnecessary to test them all; just pick one
+ // representative config key
+ Optional<EntityConfigSummary> configKeyOptional = Iterables.tryFind(entityConfigSummaries, new Predicate<EntityConfigSummary>() {
+ @Override
+ public boolean apply(@Nullable EntityConfigSummary input) {
+ return input != null && "install.version".equals(input.getName());
+ }
+ });
+ assertTrue(configKeyOptional.isPresent());
+
+ assertEquals(configKeyOptional.get().getType(), "java.lang.String");
+ assertEquals(configKeyOptional.get().getDescription(), "Suggested version");
+ assertFalse(configKeyOptional.get().isReconfigurable());
+ assertNull(configKeyOptional.get().getDefaultValue());
+ assertNull(configKeyOptional.get().getLabel());
+ assertNull(configKeyOptional.get().getPriority());
+ }
+
+ @Test
+ public void testBatchConfigRead() throws Exception {
+ Map<String, Object> currentState = client().resource(
+ URI.create("/v1/applications/simple-app/entities/simple-ent/config/current-state"))
+ .get(new GenericType<Map<String, Object>>() {
+ });
+ assertTrue(currentState.containsKey("install.version"));
+ assertEquals(currentState.get("install.version"), "1.0.0");
+ }
+
+ @Test
+ public void testGet() throws Exception {
+ String configValue = client().resource(
+ URI.create("/v1/applications/simple-app/entities/simple-ent/config/install.version"))
+ .get(String.class);
+ assertEquals(configValue, "1.0.0");
+ }
+
+}