/*
* 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.camp.brooklyn;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.io.StringReader;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon;
import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent;
import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent.Scope;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityFunctions;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.mgmt.internal.EntityManagerInternal;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.group.DynamicFabric;
import org.apache.brooklyn.entity.software.base.SameServerEntity;
import org.apache.brooklyn.entity.stock.BasicEntity;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Functionals;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.stream.Streams;
import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
import org.testng.collections.Lists;
import com.google.common.base.Joiner;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@Test
public class EntitiesYamlTest extends AbstractYamlTest {
private static final Logger log = LoggerFactory.getLogger(EntitiesYamlTest.class);
protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", extras));
waitForApplicationTasks(app);
Entities.dumpInfo(app);
Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
log.info("App started:");
Entities.dumpInfo(app);
Assert.assertTrue(app.getChildren().iterator().hasNext(), "Expected app to have child entity");
Entity entity = app.getChildren().iterator().next();
Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
return (TestEntity)entity;
}
@Test
public void testSingleEntity() throws Exception {
setupAndCheckTestEntityInBasicYamlWith();
}
@Test
public void testBrooklynConfig() throws Exception {
Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
" brooklyn.config:",
" test.confName: Test Entity Name",
" test.confMapPlain:",
" foo: bar",
" baz: qux",
" test.confListPlain:",
" - dogs",
" - cats",
" - badgers",
" test.confSetPlain: !!set",
" ? square",
" ? circle",
" ? triangle",
" test.confMapThing:",
" foo: bar",
" baz: qux",
" test.confListThing:",
" - dogs",
" - cats",
" - badgers",
" test.confSetThing: !!set",
" ? square",
" ? circle",
" ? triangle",
" test.confObject: 5");
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Test Entity Name");
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_OBJECT), 5);
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_LIST_PLAIN), ImmutableList.of("dogs", "cats", "badgers"));
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_MAP_PLAIN), ImmutableMap.of("foo", "bar", "baz", "qux"));
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_SET_PLAIN), ImmutableSet.of("square", "circle", "triangle"));
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_LIST_THING), ImmutableList.of("dogs", "cats", "badgers"));
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_MAP_THING), ImmutableMap.of("foo", "bar", "baz", "qux"));
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_SET_THING), ImmutableSet.of("square", "circle", "triangle"));
}
@Test
public void testFlagInBrooklynConfig() throws Exception {
Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
" brooklyn.config:",
" confName: Foo Bar");
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
}
@Test
public void testUndeclaredItemInBrooklynConfig() throws Exception {
Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
" brooklyn.config:",
" test.dynamic.confName: Foo Bar");
Assert.assertEquals(testEntity.getConfig(ConfigKeys.newStringConfigKey("test.dynamic.confName")), "Foo Bar");
}
@Test
public void testFlagAtRoot() throws Exception {
Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
" confName: Foo Bar");
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
}
@Test
public void testFlagAtRootEntityImpl() throws Exception {
Entity app = createAndStartApplication(
"services:",
"- serviceType: " + TestEntityImpl.class.getName(),
" confName: Foo Bar");
Entity testEntity = Iterables.getOnlyElement(app.getChildren());
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
}
@Test
public void testConfigKeyAtRoot() throws Exception {
Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
" test.confName: Foo Bar");
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
}
@Test
public void testUndeclaredItemAtRootIgnored() throws Exception {
Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
" test.dynamic.confName: Foo Bar");
// should NOT be set (and there should be a warning in the log)
String dynamicConfNameValue = testEntity.getConfig(ConfigKeys.newStringConfigKey("test.dynamic.confName"));
Assert.assertNull(dynamicConfNameValue);
}
@Test
public void testExplicitFlags() throws Exception {
Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
" brooklyn.flags:",
" confName: Foo Bar");
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
}
@Test
public void testExplicitFlagsEntityImpl() throws Exception {
Entity app = createAndStartApplication(
"services:",
"- serviceType: " + TestEntityImpl.class.getName(),
" brooklyn.flags:",
" confName: Foo Bar");
Entity testEntity = Iterables.getOnlyElement(app.getChildren());
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
}
@Test
public void testUndeclaredExplicitFlagsIgnored() throws Exception {
Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
" brooklyn.flags:",
" test.dynamic.confName: Foo Bar");
String dynamicConfNameValue = testEntity.getConfig(ConfigKeys.newStringConfigKey("test.dynamic.confName"));
Assert.assertNull(dynamicConfNameValue);
}
@SuppressWarnings("unchecked")
@Test
public void testEmptyConfig() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
" brooklyn.config:",
" test.confName: \"\"",
" test.confListPlain: !!seq []",
" test.confMapPlain: !!map {}",
" test.confSetPlain: !!set {}",
" test.confObject: \"\""));
waitForApplicationTasks(app);
Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
log.info("App started:");
Entities.dumpInfo(app);
Entity entity = app.getChildren().iterator().next();
Assert.assertNotNull(entity, "Expected app to have child entity");
Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
TestEntity testEntity = (TestEntity) entity;
Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "");
List<String> list = testEntity.getConfig(TestEntity.CONF_LIST_PLAIN);
Assert.assertEquals(list, ImmutableList.of());
Map<String, String> map = testEntity.getConfig(TestEntity.CONF_MAP_PLAIN);
Assert.assertEquals(map, ImmutableMap.of());
// TODO: CONF_SET_PLAIN is being set to an empty ArrayList - may be a snakeyaml issue?
// Set<String> plainSet = (Set<String>)testEntity.getConfig(TestEntity.CONF_SET_PLAIN);
// Assert.assertEquals(plainSet, ImmutableSet.of());
Object object = testEntity.getConfig(TestEntity.CONF_OBJECT);
Assert.assertEquals(object, "");
}
@SuppressWarnings("unchecked")
public void testEmptyStructuredConfig() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
" brooklyn.config:",
" test.confName: \"\"",
" test.confListThing: !!seq []",
" test.confSetThing: !!set {}",
" test.confMapThing: !!map {}"));
waitForApplicationTasks(app);
Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
log.info("App started:");
Entities.dumpInfo(app);
Entity entity = app.getChildren().iterator().next();
Assert.assertNotNull(entity, "Expected app to have child entity");
Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
TestEntity testEntity = (TestEntity) entity;
List<String> thingList = (List<String>)testEntity.getConfig(TestEntity.CONF_LIST_THING);
Set<String> thingSet = (Set<String>)testEntity.getConfig(TestEntity.CONF_SET_THING);
Map<String, String> thingMap = (Map<String, String>)testEntity.getConfig(TestEntity.CONF_MAP_THING);
Assert.assertEquals(thingList, Lists.newArrayList());
Assert.assertEquals(thingSet, ImmutableSet.of());
Assert.assertEquals(thingMap, ImmutableMap.of());
}
@Test
public void testSensor() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
" brooklyn.config:",
" test.confObject: $brooklyn:sensor(\"org.apache.brooklyn.core.test.entity.TestEntity\", \"test.sequence\")"));
waitForApplicationTasks(app);
Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
log.info("App started:");
Entities.dumpInfo(app);
Entity entity = app.getChildren().iterator().next();
Assert.assertNotNull(entity, "Expected app to have child entity");
Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
TestEntity testEntity = (TestEntity) entity;
Object object = testEntity.getConfig(TestEntity.CONF_OBJECT);
Assert.assertNotNull(object);
Assert.assertTrue(object instanceof AttributeSensor, "attributeSensor="+object);
Assert.assertEquals(object, TestEntity.SEQUENCE);
}
@Test
public void testSensorOnArbitraryClass() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
" brooklyn.config:",
" test.confObject: $brooklyn:sensor(\""+EntitiesYamlTest.class.getName()+"$ArbitraryClassWithSensor\", \"mysensor\")"));
waitForApplicationTasks(app);
log.info("App started:");
Entities.dumpInfo(app);
TestEntity entity = (TestEntity) app.getChildren().iterator().next();
Object object = entity.getConfig(TestEntity.CONF_OBJECT);
Assert.assertEquals(object, ArbitraryClassWithSensor.MY_SENSOR);
}
public static class ArbitraryClassWithSensor {
public static final AttributeSensor<String> MY_SENSOR = Sensors.newStringSensor("mysensor");
}
@Test
public void testComponent() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
" brooklyn.config:",
" test.confName: first entity",
" id: te1",
"- serviceType: org.apache.brooklyn.core.test.entity.TestEntity",
" name: second entity",
" brooklyn.config:",
" test.confObject: $brooklyn:component(\"te1\")"));
waitForApplicationTasks(app);
Entity firstEntity = null;
Entity secondEntity = null;
Assert.assertEquals(app.getChildren().size(), 2);
for (Entity entity : app.getChildren()) {
if (entity.getDisplayName().equals("testentity"))
firstEntity = entity;
else if (entity.getDisplayName().equals("second entity"))
secondEntity = entity;
}
final Entity[] entities = {firstEntity, secondEntity};
Assert.assertNotNull(entities[0], "Expected app to contain child named 'testentity'");
Assert.assertNotNull(entities[1], "Expected app to contain child named 'second entity'");
Object object = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Object>() {
public Object call() {
return entities[1].getConfig(TestEntity.CONF_OBJECT);
}}).get();
Assert.assertNotNull(object);
Assert.assertEquals(object, firstEntity, "Expected second entity's test.confObject to contain first entity");
}
@Test
public void testGrandchildEntities() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
" brooklyn.config:",
" test.confName: first entity",
" brooklyn.children:",
" - serviceType: org.apache.brooklyn.core.test.entity.TestEntity",
" name: Child Entity",
" brooklyn.config:",
" test.confName: Name of the first Child",
" brooklyn.children:",
" - serviceType: org.apache.brooklyn.core.test.entity.TestEntity",
" name: Grandchild Entity",
" brooklyn.config:",
" test.confName: Name of the Grandchild",
" - serviceType: org.apache.brooklyn.core.test.entity.TestEntity",
" name: Second Child",
" brooklyn.config:",
" test.confName: Name of the second Child"));
waitForApplicationTasks(app);
Assert.assertEquals(app.getChildren().size(), 1);
Entity firstEntity = app.getChildren().iterator().next();
Assert.assertEquals(firstEntity.getConfig(TestEntity.CONF_NAME), "first entity");
Assert.assertEquals(firstEntity.getChildren().size(), 2);
Entity firstChild = null;
Entity secondChild = null;
for (Entity entity : firstEntity.getChildren()) {
if (entity.getConfig(TestEntity.CONF_NAME).equals("Name of the first Child"))
firstChild = entity;
if (entity.getConfig(TestEntity.CONF_NAME).equals("Name of the second Child"))
secondChild = entity;
}
Assert.assertNotNull(firstChild, "Expected a child of 'first entity' with the name 'Name of the first Child'");
Assert.assertNotNull(secondChild, "Expected a child of 'first entity' with the name 'Name of the second Child'");
Assert.assertEquals(firstChild.getChildren().size(), 1);
Entity grandchild = firstChild.getChildren().iterator().next();
Assert.assertEquals(grandchild.getConfig(TestEntity.CONF_NAME), "Name of the Grandchild");
Assert.assertEquals(secondChild.getChildren().size(), 0);
}
@Test
public void testWithInitConfig() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-with-init-config.yaml"));
waitForApplicationTasks(app);
Assert.assertEquals(app.getDisplayName(), "test-entity-with-init-config");
TestEntityWithInitConfig testWithConfigInit = null;
TestEntity testEntity = null;
Assert.assertEquals(app.getChildren().size(), 2);
for (Entity entity : app.getChildren()) {
if (entity instanceof TestEntity)
testEntity = (TestEntity) entity;
if (entity instanceof TestEntityWithInitConfig)
testWithConfigInit = (TestEntityWithInitConfig) entity;
}
Assert.assertNotNull(testEntity, "Expected app to contain TestEntity child");
Assert.assertNotNull(testWithConfigInit, "Expected app to contain TestEntityWithInitConfig child");
Assert.assertEquals(testWithConfigInit.getEntityCachedOnInit(), testEntity);
log.info("App started:");
Entities.dumpInfo(app);
}
@Test
public void testMultipleReferencesJava() throws Exception {
final Entity app = createAndStartApplication(loadYaml("test-referencing-entities.yaml"));
waitForApplicationTasks(app);
Entity root1 = Tasks.resolving(new DslComponent(Scope.ROOT, "xxx").newTask(), Entity.class).context( ((EntityInternal)app).getExecutionContext() ).embedResolutionInTask(true).get();
Assert.assertEquals(root1, app);
Entity c1 = Tasks.resolving(new DslComponent("c1").newTask(), Entity.class).context( ((EntityInternal)app).getExecutionContext() ).embedResolutionInTask(true).get();
Assert.assertEquals(c1, Entities.descendants(app, EntityPredicates.displayNameEqualTo("child 1")).iterator().next());
Entity e1 = Tasks.resolving(new DslComponent(Scope.PARENT, "xxx").newTask(), Entity.class).context( ((EntityInternal)c1).getExecutionContext() ).embedResolutionInTask(true).get();
Assert.assertEquals(e1, Entities.descendants(app, EntityPredicates.displayNameEqualTo("entity 1")).iterator().next());
Entity root2 = Tasks.resolving(new DslComponent(Scope.ROOT, "xxx").newTask(), Entity.class).context( ((EntityInternal)c1).getExecutionContext() ).embedResolutionInTask(true).get();
Assert.assertEquals(root2, app);
Entity c1a = Tasks.resolving(BrooklynDslCommon.descendant("c1").newTask(), Entity.class).context( ((EntityInternal)e1).getExecutionContext() ).embedResolutionInTask(true).get();
Assert.assertEquals(c1a, c1);
Entity e1a = Tasks.resolving(BrooklynDslCommon.ancestor("e1").newTask(), Entity.class).context( ((EntityInternal)c1).getExecutionContext() ).embedResolutionInTask(true).get();
Assert.assertEquals(e1a, e1);
try {
Tasks.resolving(BrooklynDslCommon.ancestor("c1").newTask(), Entity.class).context( ((EntityInternal)e1).getExecutionContext() ).embedResolutionInTask(true).get();
Assert.fail("Should not have found c1 as ancestor of e1");
} catch (Exception e) { /* expected */ }
}
@Test
public void testMultipleReferences() throws Exception {
final Entity app = createAndStartApplication(loadYaml("test-referencing-entities.yaml"));
waitForApplicationTasks(app);
Entities.dumpInfo(app);
Assert.assertEquals(app.getDisplayName(), "test-referencing-entities");
Entity entity1 = null, entity2 = null, child1 = null, child2 = null, grandchild1 = null, grandchild2 = null;
Assert.assertEquals(app.getChildren().size(), 2);
for (Entity child : app.getChildren()) {
if (child.getDisplayName().equals("entity 1"))
entity1 = child;
if (child.getDisplayName().equals("entity 2"))
entity2 = child;
}
Assert.assertNotNull(entity1);
Assert.assertNotNull(entity2);
Assert.assertEquals(entity1.getChildren().size(), 2);
for (Entity child : entity1.getChildren()) {
if (child.getDisplayName().equals("child 1"))
child1 = child;
if (child.getDisplayName().equals("child 2"))
child2 = child;
}
Assert.assertNotNull(child1);
Assert.assertNotNull(child2);
Assert.assertEquals(child1.getChildren().size(), 2);
for (Entity child : child1.getChildren()) {
if (child.getDisplayName().equals("grandchild 1"))
grandchild1 = child;
if (child.getDisplayName().equals("grandchild 2"))
grandchild2 = child;
}
Assert.assertNotNull(grandchild1);
Assert.assertNotNull(grandchild2);
Map<ConfigKey<Entity>, Entity> keyToEntity = new ImmutableMap.Builder<ConfigKey<Entity>, Entity>()
.put(ReferencingYamlTestEntity.TEST_REFERENCE_ROOT, app)
.put(ReferencingYamlTestEntity.TEST_REFERENCE_SCOPE_ROOT, app)
.put(ReferencingYamlTestEntity.TEST_REFERENCE_APP, app)
.put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1, entity1)
.put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1_ALT, entity1)
.put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY2, entity2)
.put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD1, child1)
.put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD2, child2)
.put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD1, grandchild1)
.put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD2, grandchild2)
.build();
Iterable<Entity> entitiesInApp = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Iterable<Entity>>() {
@Override
public Iterable<Entity> call() throws Exception {
return ((EntityManagerInternal)((EntityInternal)app).getManagementContext().getEntityManager()).getAllEntitiesInApplication((Application)app);
}
}).get();
for (Entity entityInApp : entitiesInApp) {
checkReferences(entityInApp, keyToEntity);
try {
getResolvedConfigInTask(entityInApp, ReferencingYamlTestEntity.TEST_REFERENCE_BOGUS);
Assert.fail("Should not have resolved "+ReferencingYamlTestEntity.TEST_REFERENCE_BOGUS+" at "+entityInApp);
} catch (Exception e) {
/* expected */
}
}
}
@Test
public void testScopeReferences() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" items:",
" - id: ref_child",
" item:",
" type: " + ReferencingYamlTestEntity.class.getName(),
" test.reference.root: $brooklyn:root()",
" test.reference.scope_root: $brooklyn:scopeRoot()",
" brooklyn.children:",
" - type: " + ReferencingYamlTestEntity.class.getName(),
" test.reference.root: $brooklyn:root()",
" test.reference.scope_root: $brooklyn:scopeRoot()",
" - id: ref_parent",
" item:",
" type: " + ReferencingYamlTestEntity.class.getName(),
" test.reference.root: $brooklyn:root()",
" test.reference.scope_root: $brooklyn:scopeRoot()",
" brooklyn.children:",
" - type: " + ReferencingYamlTestEntity.class.getName(),
" test.reference.root: $brooklyn:root()",
" test.reference.scope_root: $brooklyn:scopeRoot()",
" brooklyn.children:",
" - type: ref_child");
Entity app = createAndStartApplication(
"brooklyn.config:",
" test.reference.root: $brooklyn:root()",
" test.reference.scope_root: $brooklyn:scopeRoot()",
"services:",
"- type: " + ReferencingYamlTestEntity.class.getName(),
" test.reference.root: $brooklyn:root()",
" test.reference.scope_root: $brooklyn:scopeRoot()",
" brooklyn.children:",
" - type: " + ReferencingYamlTestEntity.class.getName(),
" test.reference.root: $brooklyn:root()",
" test.reference.scope_root: $brooklyn:scopeRoot()",
" brooklyn.children:",
" - type: ref_parent");
assertScopes(app, app, app);
Entity e1 = nextChild(app);
assertScopes(e1, app, app);
Entity e2 = nextChild(e1);
assertScopes(e2, app, app);
Entity e3 = nextChild(e2);
assertScopes(e3, app, e3);
Entity e4 = nextChild(e3);
assertScopes(e4, app, e3);
Entity e5 = nextChild(e4);
assertScopes(e5, app, e5);
Entity e6 = nextChild(e5);
assertScopes(e6, app, e5);
}
private static Entity nextChild(Entity entity) {
return Iterables.getOnlyElement(entity.getChildren());
}
private static void assertScopes(Entity entity, Entity root, Entity scopeRoot) {
assertEquals(entity.config().get(ReferencingYamlTestEntity.TEST_REFERENCE_ROOT), root);
assertEquals(entity.config().get(ReferencingYamlTestEntity.TEST_REFERENCE_SCOPE_ROOT), scopeRoot);
}
private void checkReferences(final Entity entity, Map<ConfigKey<Entity>, Entity> keyToEntity) throws Exception {
for (final ConfigKey<Entity> key : keyToEntity.keySet()) {
try {
Assert.assertEquals(getResolvedConfigInTask(entity, key).get(), keyToEntity.get(key), "For entity " + entity.toString() + ":");
} catch (Throwable t) {
Exceptions.propagateIfFatal(t);
Assert.fail("Wrong value for "+entity+":"+key+", "+((EntityInternal)entity).config().getLocalRaw(key)+": "+t, t);
}
}
}
private Maybe<Entity> getResolvedConfigInTask(final Entity entity, final ConfigKey<Entity> key) {
return Tasks.resolving(Tasks.<Entity>builder().body(
Functionals.callable(Suppliers.compose(EntityFunctions.config(key), Suppliers.ofInstance(entity))) ).build())
.as(Entity.class)
.context( ((EntityInternal)entity).getExecutionContext() ).embedResolutionInTask(true)
.getMaybe();
}
public void testWithAppLocation() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
"location: localhost:(name=yaml name)"));
waitForApplicationTasks(app);
Assert.assertEquals(app.getLocations().size(), 1);
Location location = app.getLocations().iterator().next();
Assert.assertNotNull(location);
Assert.assertEquals(location.getDisplayName(), "yaml name");
Assert.assertEquals(app.getChildren().size(), 1);
Entity entity = app.getChildren().iterator().next();
Assert.assertNotNull(entity);
Assert.assertEquals(entity.getLocations().size(), 0);
}
@Test
public void testWithEntityLocation() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
" location: localhost:(name=yaml name)\n"));
waitForApplicationTasks(app);
Assert.assertEquals(app.getLocations().size(), 0);
Assert.assertEquals(app.getChildren().size(), 1);
Entity entity = app.getChildren().iterator().next();
Assert.assertEquals(entity.getLocations().size(), 1);
Location location = entity.getLocations().iterator().next();
Assert.assertNotNull(location);
Assert.assertEquals(location.getDisplayName(), "yaml name");
Assert.assertNotNull(entity);
}
@Test
public void testWith2AppLocations() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
"locations:",
"- localhost:(name=localhost name)",
"- byon:(hosts=\"1.1.1.1\", name=byon name)"));
waitForApplicationTasks(app);
Assert.assertEquals(app.getLocations().size(), 2);
Location localhostLocation = null, byonLocation = null;
for (Location location : app.getLocations()) {
if (location.getDisplayName().equals("localhost name"))
localhostLocation = location;
else if (location.getDisplayName().equals("byon name"))
byonLocation = location;
}
Assert.assertNotNull(localhostLocation);
Assert.assertNotNull(byonLocation);
Assert.assertEquals(app.getChildren().size(), 1);
Entity entity = app.getChildren().iterator().next();
Assert.assertNotNull(entity);
// 2016-01 locations now not set on entity unless explicitly passed to "start"
Assert.assertEquals(entity.getLocations().size(), 0);
}
@Test
public void testWith2EntityLocations() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
" locations:",
" - localhost:(name=localhost name)",
" - byon:(hosts=\"1.1.1.1\", name=byon name)"));
waitForApplicationTasks(app);
Assert.assertEquals(app.getLocations().size(), 0);
Assert.assertEquals(app.getChildren().size(), 1);
Entity entity = app.getChildren().iterator().next();
Assert.assertEquals(entity.getLocations().size(), 2);
Location localhostLocation = null, byonLocation = null;
for (Location location : entity.getLocations()) {
if (location.getDisplayName().equals("localhost name"))
localhostLocation = location;
else if (location.getDisplayName().equals("byon name"))
byonLocation = location;
}
Assert.assertNotNull(localhostLocation);
Assert.assertNotNull(byonLocation);
}
@Test
public void testWithAppAndEntityLocations() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
" location: localhost:(name=localhost name)",
"location: byon:(hosts=\"1.1.1.1\", name=byon name)"));
waitForApplicationTasks(app);
Assert.assertEquals(app.getLocations().size(), 1);
Assert.assertEquals(app.getChildren().size(), 1);
Entity entity = app.getChildren().iterator().next();
Assert.assertEquals(entity.getLocations().size(), 1);
Iterator<Location> entityLocationIterator = entity.getLocations().iterator();
Assert.assertEquals(entityLocationIterator.next().getDisplayName(), "localhost name");
Location appLocation = app.getLocations().iterator().next();
Assert.assertEquals(appLocation.getDisplayName(), "byon name");
}
@Test
public void testWithEntityLocationsAndStartInLocation() throws Exception {
Entity app = createAndStartApplication(Streams.readFully(loadYaml("test-entity-basic-template.yaml",
" location: localhost:(name=localhost name)")),
// must pass as JSON list because otherwise the comma confuses the list parser
MutableMap.of("locations", "[ "+JavaStringEscapes.wrapJavaString(
"byon:(hosts=\"1.1.1.1\", name=\"byon name\")")+" ]") );
waitForApplicationTasks(app);
Assert.assertEquals(app.getLocations().size(), 1);
Assert.assertEquals(app.getChildren().size(), 1);
Entity entity = app.getChildren().iterator().next();
Assert.assertEquals(entity.getLocations().size(), 2);
Iterator<Location> entityLocationIterator = entity.getLocations().iterator();
Assert.assertEquals(entityLocationIterator.next().getDisplayName(), "localhost name");
Assert.assertEquals(entityLocationIterator.next().getDisplayName(), "byon name");
Location appLocation = app.getLocations().iterator().next();
Assert.assertEquals(appLocation.getDisplayName(), "byon name");
}
@Test
public void testCreateClusterWithMemberSpec() throws Exception {
Entity app = createAndStartApplication(loadYaml("test-cluster-with-member-spec.yaml"));
waitForApplicationTasks(app);
assertEquals(app.getChildren().size(), 1);
Entity clusterEntity = Iterables.getOnlyElement(app.getChildren());
assertTrue(clusterEntity instanceof DynamicCluster, "cluster="+clusterEntity);
DynamicCluster cluster = DynamicCluster.class.cast(clusterEntity);
assertEquals(cluster.getMembers().size(), 2, "members="+cluster.getMembers());
for (Entity member : cluster.getMembers()) {
assertTrue(member instanceof TestEntity, "member="+member);
assertEquals(member.getConfig(TestEntity.CONF_NAME), "yamlTest");
}
}
@Test
public void testCreateFabricWithLocationsAtTopLevel() throws Exception {
String yaml = Joiner.on("\n").join(
"services:",
"- type: org.apache.brooklyn.entity.group.DynamicFabric",
" memberSpec:",
" $brooklyn:entitySpec:",
" type: org.apache.brooklyn.core.test.entity.TestEntity",
"locations:",
"- byon(hosts=\"1.1.1.1\")",
"- byon(hosts=\"1.1.1.2\")"
);
Entity app = createAndStartApplication(yaml);
waitForApplicationTasks(app);
DynamicFabric fabric = Iterables.getOnlyElement(Entities.descendants(app, DynamicFabric.class));
Iterable<TestEntity> members = Entities.descendants(fabric, TestEntity.class);
assertEquals(Iterables.size(members), 2);
}
@Test
public void testCreateFabricWithLocationsInline() throws Exception {
String yaml = Joiner.on("\n").join(
"services:",
"- type: org.apache.brooklyn.entity.group.DynamicFabric",
" memberSpec:",
" $brooklyn:entitySpec:",
" type: org.apache.brooklyn.core.test.entity.TestEntity",
" locations:",
" - byon(hosts=\"1.1.1.1\")",
" - byon(hosts=\"1.1.1.2\")"
);
Entity app = createAndStartApplication(yaml);
waitForApplicationTasks(app);
DynamicFabric fabric = Iterables.getOnlyElement(Entities.descendants(app, DynamicFabric.class));
Iterable<TestEntity> members = Entities.descendants(fabric, TestEntity.class);
assertEquals(Iterables.size(members), 2);
}
@Test
public void testEntitySpecConfig() throws Exception {
String yaml =
"services:\n"+
"- serviceType: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.config:\n"+
" test.childSpec:\n"+
" $brooklyn:entitySpec:\n"+
" type: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.config:\n"+
" test.confName: inchildspec\n";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
}
@Test
public void testEntitySpecFlags() throws Exception {
String yaml =
"services:\n"+
"- serviceType: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" confName: inParent\n"+
" brooklyn.config:\n"+
" test.childSpec:\n"+
" $brooklyn:entitySpec:\n"+
" type: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" confName: inchildspec\n";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
}
@Test
public void testEntitySpecExplicitFlags() throws Exception {
String yaml =
"services:\n"+
"- serviceType: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.flags:\n"+
" confName: inParent\n"+
" brooklyn.config:\n"+
" test.childSpec:\n"+
" $brooklyn:entitySpec:\n"+
" type: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.flags:\n"+
" confName: inchildspec\n";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
}
@Test
public void testEntitySpecWithChildren() throws Exception {
String yaml =
"services:\n"+
"- serviceType: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.config:\n"+
" test.childSpec:\n"+
" $brooklyn:entitySpec:\n"+
" type: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.config:\n"+
" test.confName: child\n"+
" brooklyn.children:\n"+
" - type: org.apache.brooklyn.core.test.entity.TestEntity\n" +
" brooklyn.config:\n" +
" test.confName: grandchild\n" +
" brooklyn.children:\n"+
" - type: org.apache.brooklyn.core.test.entity.TestEntity\n" +
" brooklyn.config:\n" +
" test.confName: greatgrandchild\n";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
assertEquals(child.getConfig(TestEntity.CONF_NAME), "child");
assertEquals(child.getChildren().size(), 1, "Child entity should have exactly one child of its own");
TestEntity grandchild = (TestEntity) Iterables.getOnlyElement(child.getChildren());
assertEquals(grandchild.getConfig(TestEntity.CONF_NAME), "grandchild");
assertEquals(grandchild.getChildren().size(), 1, "Grandchild entity should have exactly one child of its own");
TestEntity greatgrandchild = (TestEntity) Iterables.getOnlyElement(grandchild.getChildren());
assertEquals(greatgrandchild.getConfig(TestEntity.CONF_NAME), "greatgrandchild");
}
@Test
public void testNestedEntitySpecConfigs() throws Exception {
String yaml =
"services:\n"+
"- serviceType: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.config:\n"+
" test.childSpec:\n"+
" $brooklyn:entitySpec:\n"+
" type: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.config:\n"+
" test.confName: inchildspec\n"+
" test.childSpec:\n"+
" $brooklyn:entitySpec:\n"+
" type: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.config:\n"+
" test.confName: ingrandchildspec\n";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
TestEntity grandchild = (TestEntity) child.createAndManageChildFromConfig();
assertEquals(grandchild.getConfig(TestEntity.CONF_NAME), "ingrandchildspec");
}
@Test
public void testEntitySpecInUnmatchedConfig() throws Exception {
String yaml =
"services:\n"+
"- serviceType: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.config:\n"+
" key.does.not.match:\n"+
" $brooklyn:entitySpec:\n"+
" type: org.apache.brooklyn.core.test.entity.TestEntity\n"+
" brooklyn.config:\n"+
" test.confName: inchildspec\n";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
EntitySpec<?> entitySpec = (EntitySpec<?>) entity.config().getBag().getStringKey("key.does.not.match");
assertEquals(entitySpec.getType(), TestEntity.class);
assertEquals(entitySpec.getConfig(), ImmutableMap.of(TestEntity.CONF_NAME, "inchildspec"));
}
@Test
public void testAppWithSameServerEntityStarts() throws Exception {
Entity app = createAndStartApplication(loadYaml("same-server-entity-test.yaml"));
waitForApplicationTasks(app);
assertNotNull(app);
assertEquals(app.getAttribute(Attributes.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING, "service state");
assertTrue(app.getAttribute(Attributes.SERVICE_UP), "service up");
assertEquals(app.getChildren().size(), 1);
Entity entity = Iterables.getOnlyElement(app.getChildren());
assertTrue(entity instanceof SameServerEntity, "entity="+entity);
SameServerEntity sse = (SameServerEntity) entity;
assertEquals(sse.getChildren().size(), 2);
for (Entity child : sse.getChildren()) {
assertTrue(child instanceof BasicEntity, "child="+child);
}
}
@Test
public void testEntityImplExposesAllInterfacesIncludingStartable() throws Exception {
String yaml =
"services:\n"+
"- serviceType: org.apache.brooklyn.core.test.entity.TestEntityImpl\n";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
assertTrue(entity.getCallHistory().contains("start"), "history="+entity.getCallHistory());
}
@Test
public void testEntityWithInitializer() throws Exception {
String yaml =
"services:\n"+
"- type: "+TestEntity.class.getName()+"\n"+
" brooklyn.initializers: [ { type: "+TestSensorAndEffectorInitializer.class.getName()+" } ]";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
Effector<?> hi = entity.getEffector(TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO);
Assert.assertNotNull(hi);
Assert.assertNotNull( entity.getEntityType().getSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED) );
Assert.assertNotNull( entity.getEntityType().getSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED_EMITTED) );
Assert.assertNull( entity.getEntityType().getSensor(TestSensorAndEffectorInitializer.SENSOR_LAST_HELLO) );
Assert.assertNull( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_LAST_HELLO)) );
Assert.assertNull( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED)) );
Assert.assertEquals( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED_EMITTED)),
"1");
Task<String> saying = entity.invoke(Effectors.effector(String.class, TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO).buildAbstract(),
MutableMap.of("name", "Bob"));
Assert.assertEquals(saying.get(Duration.TEN_SECONDS), "Hello Bob");
Assert.assertEquals( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_LAST_HELLO)),
"Bob");
}
@Test
public void testEntityWithConfigurableInitializerEmpty() throws Exception {
String yaml =
"services:\n"+
"- type: "+TestEntity.class.getName()+"\n"+
" brooklyn.initializers: [ { type: "+TestSensorAndEffectorInitializer.TestConfigurableInitializer.class.getName()+" } ]";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
Task<String> saying = entity.invoke(Effectors.effector(String.class, TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO).buildAbstract(),
MutableMap.of("name", "Bob"));
Assert.assertEquals(saying.get(Duration.TEN_SECONDS), "Hello Bob");
}
@Test
public void testEntityWithConfigurableInitializerNonEmpty() throws Exception {
String yaml =
"services:\n"+
"- type: "+TestEntity.class.getName()+"\n"+
" brooklyn.initializers: [ { "
+ "type: "+TestSensorAndEffectorInitializer.TestConfigurableInitializer.class.getName()+","
+ "brooklyn.config: { "+TestSensorAndEffectorInitializer.TestConfigurableInitializer.HELLO_WORD+": Hey }"
+ " } ]";
Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
Task<String> saying = entity.invoke(Effectors.effector(String.class, TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO).buildAbstract(),
MutableMap.of("name", "Bob"));
Assert.assertEquals(saying.get(Duration.TEN_SECONDS), "Hey Bob");
}
@Test
public void testEntityTypeAsImpl() throws Exception {
String yaml =
"services:"+"\n"+
"- type: "+CustomTestEntityImpl.class.getName()+"\n";
Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
Entity testEntity = Iterables.getOnlyElement(app.getChildren());
assertEquals(testEntity.getEntityType().getName(), "CustomTestEntityImpl");
}
public static class CustomTestEntityImpl extends TestEntityImpl {
public CustomTestEntityImpl() {
System.out.println("in CustomTestEntityImpl");
}
@Override
protected String getEntityTypeName() {
return "CustomTestEntityImpl";
}
}
@Override
protected Logger getLogger() {
return log;
}
}