| /* |
| * 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 java.util.Collections; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| |
| import org.apache.brooklyn.api.entity.Entity; |
| import org.apache.brooklyn.api.mgmt.ManagementContext; |
| import org.apache.brooklyn.api.mgmt.Task; |
| import org.apache.brooklyn.api.objs.Configurable; |
| import org.apache.brooklyn.api.sensor.AttributeSensor; |
| import org.apache.brooklyn.config.ConfigKey; |
| import org.apache.brooklyn.config.ConfigKey.HasConfigKey; |
| import org.apache.brooklyn.core.config.ConfigKeys; |
| import org.apache.brooklyn.core.entity.Dumper; |
| import org.apache.brooklyn.core.entity.EntityAsserts; |
| import org.apache.brooklyn.core.mgmt.ManagementContextInjectable; |
| import org.apache.brooklyn.core.sensor.Sensors; |
| import org.apache.brooklyn.core.test.entity.TestEntity; |
| import org.apache.brooklyn.entity.stock.BasicApplication; |
| import org.apache.brooklyn.util.collections.MutableList; |
| import org.apache.brooklyn.util.collections.MutableSet; |
| import org.apache.brooklyn.util.core.config.ConfigBag; |
| import org.apache.brooklyn.util.core.flags.SetFromFlag; |
| import org.apache.brooklyn.util.core.flags.TypeCoercions; |
| import org.apache.brooklyn.util.time.Time; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.testng.Assert; |
| import org.testng.annotations.Test; |
| |
| import com.google.common.base.Charsets; |
| import com.google.common.base.Predicate; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Lists; |
| import com.google.common.hash.HashCode; |
| import com.google.common.hash.Hashing; |
| |
| @Test |
| public class ObjectsYamlTest extends AbstractYamlTest { |
| private static final Logger log = LoggerFactory.getLogger(ObjectsYamlTest.class); |
| |
| private static final AtomicBoolean managementContextInjected = new AtomicBoolean(false); |
| private static final List<String> configKeys = Lists.newLinkedList(); |
| |
| public static class TestObject implements ManagementContextInjectable { |
| private String string; |
| private Integer number; |
| private Object object; |
| private List<String> list; |
| |
| // Factory method. |
| public static TestObject newTestObjectWithNoArgs() { |
| return new TestObject("myDefaultFirst", 1, "myDefaultThird"); |
| } |
| |
| // Factory method. |
| public static TestObject newTestObject(String string, Integer number, Object object) { |
| return new TestObject(string + "-suffix", number + 1, object); |
| } |
| |
| // No-arg constructor. |
| public TestObject() { } |
| |
| // Parameterised constructor. |
| public TestObject(String string, Integer number, Object object) { |
| this.string = string; |
| this.number = number; |
| this.object = object; |
| } |
| |
| public String getString() { return string; } |
| public void setString(String string) { this.string = string; } |
| |
| public Integer getNumber() { return number; } |
| public void setNumber(Integer number) { this.number = number; } |
| |
| public Object getObject() { return object; } |
| public void setObject(Object object) { this.object = object; } |
| |
| public List<String> getList() { return list; } |
| public void setList(List<String> list) { this.list = list; } |
| |
| @Override |
| public void setManagementContext(ManagementContext managementContext) { |
| log.info("Detected injection of {}", managementContext); |
| managementContextInjected.set(true); |
| } |
| } |
| |
| // TODO Copy of org.apache.brooklyn.rest.security.PasswordHasher; but this module does not |
| // have access to brooklyn-rest-resources (and would create a circular reference to do so) |
| public static class PasswordHasher { |
| public static String sha256(String salt, String password) { |
| if (salt == null) salt = ""; |
| byte[] bytes = (salt + password).getBytes(Charsets.UTF_8); |
| HashCode hash = Hashing.sha256().hashBytes(bytes); |
| return hash.toString(); |
| } |
| } |
| |
| public static class ConfigurableObject implements Configurable { |
| public static final ConfigKey<Integer> INTEGER = ConfigKeys.newIntegerConfigKey("config.number"); |
| @SetFromFlag("object") |
| public static final ConfigKey<Object> OBJECT = ConfigKeys.newConfigKey(Object.class, "config.object"); |
| |
| @SetFromFlag("flag") |
| private String string; |
| |
| private Integer number; |
| private Object object; |
| private Double value; |
| BasicConfigurationSupport configSupport = new BasicConfigurationSupport(); |
| |
| public ConfigurableObject() { } |
| |
| public String getString() { return string; } |
| |
| public Integer getNumber() { return number; } |
| |
| public Object getObject() { return object; } |
| |
| public Double getDouble() { return value; } |
| public void setDouble(Double value) { this.value = value; } |
| |
| @Override |
| public <T> T getConfig(ConfigKey<T> key) { |
| return config().get(key); |
| } |
| |
| @Override |
| public ConfigurationSupport config() { |
| return configSupport; |
| } |
| |
| private class BasicConfigurationSupport implements ConfigurationSupport { |
| private final ConfigBag bag = new ConfigBag(); |
| |
| @Override |
| public <T> T get(ConfigKey<T> key) { |
| return bag.get(key); |
| } |
| |
| @Override |
| public <T> T get(HasConfigKey<T> key) { |
| return get(key.getConfigKey()); |
| } |
| |
| @Override |
| public <T> T set(ConfigKey<T> key, T val) { |
| log.info("Detected configuration injection for {}: {}", key.getName(), val); |
| configKeys.add(key.getName()); |
| if ("config.number".equals(key.getName())) number = TypeCoercions.coerce(val, Integer.class); |
| if ("config.object".equals(key.getName())) object = val; |
| T old = bag.get(key); |
| bag.configure(key, val); |
| return old; |
| } |
| |
| @Override |
| public <T> T set(HasConfigKey<T> key, T val) { |
| return set(key.getConfigKey(), val); |
| } |
| |
| @Override |
| public <T> T set(ConfigKey<T> key, Task<T> val) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public <T> T set(HasConfigKey<T> key, Task<T> val) { |
| return set(key.getConfigKey(), val); |
| } |
| |
| @Override |
| public Set<ConfigKey<?>> findKeysDeclared(Predicate<? super ConfigKey<?>> filter) { |
| return MutableSet.copyOf(Iterables.filter(bag.getAllConfigAsConfigKeyMap().keySet(), filter)); |
| } |
| |
| @Override |
| public Set<ConfigKey<?>> findKeysPresent(Predicate<? super ConfigKey<?>> filter) { |
| return findKeysDeclared(filter); |
| } |
| |
| } |
| } |
| |
| protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception { |
| managementContextInjected.set(false); |
| configKeys.clear(); |
| Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", extras)); |
| waitForApplicationTasks(app); |
| |
| Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template"); |
| |
| log.info("App started:"); |
| Dumper.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 entity; |
| } |
| |
| @Test |
| public void testSingleEntity() throws Exception { |
| setupAndCheckTestEntityInBasicYamlWith(); |
| } |
| |
| @Test |
| public void testBrooklynObject() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " object.fields:", |
| " number: 7", |
| " object:", |
| " $brooklyn:object:", |
| " type: org.apache.brooklyn.camp.brooklyn.SimpleTestPojo", |
| " string: \"frog\""); |
| |
| Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT); |
| |
| Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject); |
| Assert.assertTrue(managementContextInjected.get()); |
| Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(7)); |
| Assert.assertEquals(((TestObject) testObject).getString(), "frog"); |
| |
| Object testObjectObject = ((TestObject) testObject).getObject(); |
| Assert.assertTrue(testObjectObject instanceof SimpleTestPojo, "Expected a SimpleTestPojo: "+testObjectObject); |
| } |
| |
| @Test |
| public void testBrooklynConfigurableObject() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$ConfigurableObject", |
| " object.fields:", |
| " double: 1.4", |
| " brooklyn.config:", |
| " flag: frog", |
| " config.number: 7", |
| " object:", |
| " $brooklyn:object:", |
| " type: org.apache.brooklyn.camp.brooklyn.SimpleTestPojo"); |
| |
| Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT); |
| |
| Assert.assertTrue(testObject instanceof ConfigurableObject, "Expected a ConfigurableObject: "+testObject); |
| Assert.assertEquals(((ConfigurableObject) testObject).getDouble(), Double.valueOf(1.4)); |
| Assert.assertEquals(((ConfigurableObject) testObject).getString(), "frog"); |
| Assert.assertEquals(((ConfigurableObject) testObject).getNumber(), Integer.valueOf(7)); |
| |
| Object testObjectObject = ((ConfigurableObject) testObject).getObject(); |
| Assert.assertTrue(testObjectObject instanceof SimpleTestPojo, "Expected a SimpleTestPojo: "+testObjectObject); |
| |
| Assert.assertTrue(configKeys.contains(ConfigurableObject.INTEGER.getName()), "Expected INTEGER key: "+configKeys); |
| Assert.assertTrue(configKeys.contains(ConfigurableObject.OBJECT.getName()), "Expected OBJECT key: "+configKeys); |
| } |
| |
| @Test |
| public void testBrooklynObjectPrefix() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confListPlain:", |
| " - $brooklyn:object:", |
| " objectType: org.apache.brooklyn.camp.brooklyn.SimpleTestPojo", |
| " - $brooklyn:object:", |
| " object_type: org.apache.brooklyn.camp.brooklyn.SimpleTestPojo", |
| " - $brooklyn:object:", |
| " type: org.apache.brooklyn.camp.brooklyn.SimpleTestPojo"); |
| |
| List<?> testList = testEntity.getConfig(TestEntity.CONF_LIST_PLAIN); |
| |
| Assert.assertEquals(testList.size(), 3); |
| for (Object entry : testList) { |
| Assert.assertTrue(entry instanceof SimpleTestPojo, "Expected a SimpleTestPojo: "+entry); |
| } |
| } |
| |
| @Test |
| public void testBrooklynObjectWithFunction() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " object.fields:", |
| " number: 7", |
| " object:", |
| " $brooklyn:object:", |
| " type: org.apache.brooklyn.camp.brooklyn.SimpleTestPojo", |
| " string:", |
| " $brooklyn:formatString(\"%s\", \"frog\")"); |
| |
| Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT); |
| |
| Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject); |
| Assert.assertTrue(managementContextInjected.get()); |
| Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(7)); |
| Assert.assertEquals(((TestObject) testObject).getString(), "frog"); |
| |
| Object testObjectObject = ((TestObject) testObject).getObject(); |
| Assert.assertTrue(testObjectObject instanceof SimpleTestPojo, "Expected a SimpleTestPojo: "+testObjectObject); |
| } |
| |
| @Test |
| public void testBrooklynObjectWithParameterisedConstructor() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " constructor.args:", |
| " - frog", |
| " - 7", |
| " - $brooklyn:object:", |
| " type: org.apache.brooklyn.camp.brooklyn.SimpleTestPojo" |
| ); |
| |
| Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT); |
| |
| Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject); |
| Assert.assertTrue(managementContextInjected.get()); |
| Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(7)); |
| Assert.assertEquals(((TestObject) testObject).getString(), "frog"); |
| |
| Object testObjectObject = ((TestObject) testObject).getObject(); |
| Assert.assertTrue(testObjectObject instanceof SimpleTestPojo, "Expected a SimpleTestPojo: "+testObjectObject); |
| } |
| |
| @Test |
| public void testBrooklynObjectWithFactoryMethod() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " factoryMethod.name: newTestObject", |
| " factoryMethod.args:", |
| " - frog", |
| " - 7", |
| " - $brooklyn:object:", |
| " type: org.apache.brooklyn.camp.brooklyn.SimpleTestPojo" |
| ); |
| |
| Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT); |
| |
| Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject); |
| Assert.assertTrue(managementContextInjected.get()); |
| Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(8)); |
| Assert.assertEquals(((TestObject) testObject).getString(), "frog-suffix"); |
| |
| Object testObjectObject = ((TestObject) testObject).getObject(); |
| Assert.assertTrue(testObjectObject instanceof SimpleTestPojo, "Expected a SimpleTestPojo: "+testObjectObject); |
| } |
| |
| @Test |
| public void testBrooklynObjectWithFactoryMethodNoArgs() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " factoryMethod.name: newTestObjectWithNoArgs"); |
| |
| TestObject testObject = (TestObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| assertEquals(testObject.getString(), "myDefaultFirst"); |
| assertEquals(testObject.getNumber(), Integer.valueOf(1)); |
| assertEquals(testObject.getObject(), "myDefaultThird"); |
| } |
| |
| @Test |
| public void testBrooklynObjectWithFactoryMethodWithArgCoercion() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: " + Time.class.getName(), |
| " factoryMethod.name: makeDateString", |
| " factoryMethod.args:", |
| " - 1000", |
| " - yyyy-MM-dd'T'HH:mm:ss", |
| " - UTC"); |
| |
| String val = (String) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| assertEquals(val, "1970-01-01T00:00:01"); |
| } |
| |
| @Test |
| public void testFieldsAsDeferredSuppliers() throws Exception { |
| // all fields as deferred suppliers |
| { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " object.fields:", |
| " number: $brooklyn:config(\"myint\")", |
| " string: $brooklyn:config(\"mystring\")", |
| " list: ", |
| " - $brooklyn:config(\"mystring\")"); |
| |
| TestObject testObject = (TestObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| Assert.assertEquals(testObject.getNumber(), Integer.valueOf(123)); |
| Assert.assertEquals(testObject.getString(), "myval"); |
| Assert.assertEquals(testObject.getList(), ImmutableList.of("myval")); |
| } |
| |
| // Only first field as deferred supplier |
| { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " object.fields:", |
| " number: $brooklyn:config(\"myint\")", |
| " string: myval"); |
| |
| TestObject testObject = (TestObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| Assert.assertEquals(testObject.getNumber(), Integer.valueOf(123)); |
| Assert.assertEquals(testObject.getString(), "myval"); |
| } |
| |
| // Only second field as deferred supplier |
| { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " object.fields:", |
| " number: 7", |
| " string: $brooklyn:config(\"mystring\")"); |
| |
| TestObject testObject = (TestObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| Assert.assertEquals(testObject.getNumber(), Integer.valueOf(7)); |
| Assert.assertEquals(testObject.getString(), "myval"); |
| } |
| } |
| |
| @Test |
| public void testFieldOfTypeListAsDeferredSuppliersExplicitlyDeferred() throws Exception { |
| { |
| // Using explicit `deferred: true` |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " deferred: true", |
| " object.fields:", |
| " list: ", |
| " - $brooklyn:config(\"mystring\")"); |
| |
| TestObject testObject = (TestObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| Assert.assertEquals(testObject.getList(), ImmutableList.of("myval")); |
| } |
| } |
| |
| // TODO See https://issues.apache.org/jira/browse/BROOKLYN-565 |
| @Test(groups="Broken") |
| public void testFieldOfTypeListAsDeferredSuppliers() throws Exception { |
| { |
| // See https://issues.apache.org/jira/browse/BROOKLYN-565 |
| // should defer evaluation automatically, and resolve config in `getConfig()` |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " object.fields:", |
| " list: ", |
| " - $brooklyn:config(\"mystring\")"); |
| |
| TestObject testObject = (TestObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| Assert.assertEquals(testObject.getList(), ImmutableList.of("myval")); |
| } |
| } |
| |
| @Test |
| public void testConfigAsDeferredSuppliers() throws Exception { |
| // all fields as deferred suppliers |
| { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " mydouble: 1.4", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$ConfigurableObject", |
| " object.fields:", |
| " double: $brooklyn:config(\"mydouble\")", |
| " brooklyn.config:", |
| " flag: $brooklyn:config(\"mystring\")", |
| " config.number: $brooklyn:config(\"myint\")"); |
| |
| ConfigurableObject testObject = (ConfigurableObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| assertEquals(testObject.getDouble(), Double.valueOf(1.4)); |
| assertEquals(testObject.getString(), "myval"); |
| assertEquals(testObject.getNumber(), Integer.valueOf(123)); |
| } |
| |
| // Only only fields (and not config) as deferred supplier |
| { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " mydouble: 1.4", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$ConfigurableObject", |
| " object.fields:", |
| " double: $brooklyn:config(\"mydouble\")", |
| " brooklyn.config:", |
| " flag: myval", |
| " config.number: 123"); |
| |
| ConfigurableObject testObject = (ConfigurableObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| assertEquals(testObject.getDouble(), Double.valueOf(1.4)); |
| assertEquals(testObject.getString(), "myval"); |
| assertEquals(testObject.getNumber(), Integer.valueOf(123)); |
| } |
| |
| // Only config (and not fields) as deferred supplier |
| { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " mydouble: 1.4", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$ConfigurableObject", |
| " object.fields:", |
| " double: 1.4", |
| " brooklyn.config:", |
| " flag: $brooklyn:config(\"mystring\")", |
| " config.number: $brooklyn:config(\"myint\")"); |
| |
| ConfigurableObject testObject = (ConfigurableObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| assertEquals(testObject.getDouble(), Double.valueOf(1.4)); |
| assertEquals(testObject.getString(), "myval"); |
| assertEquals(testObject.getNumber(), Integer.valueOf(123)); |
| } |
| } |
| |
| @Test |
| public void testConstructorArgsAsDeferredSuppliers() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " mydouble: 1.4", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " constructor.args:", |
| " - $brooklyn:config(\"mystring\")", |
| " - $brooklyn:config(\"myint\")", |
| " - myThirdParam"); |
| |
| TestObject testObject = (TestObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| assertEquals(testObject.getNumber(), Integer.valueOf(123)); |
| assertEquals(testObject.getString(), "myval"); |
| assertEquals(testObject.getObject(), "myThirdParam"); |
| } |
| |
| @Test |
| public void testFactorArgsAsDeferredSuppliers() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " mystring: myval", |
| " myint: 123", |
| " mydouble: 1.4", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+ObjectsYamlTest.class.getName()+"$TestObject", |
| " factoryMethod.name: newTestObject", |
| " factoryMethod.args:", |
| " - $brooklyn:config(\"mystring\")", |
| " - $brooklyn:config(\"myint\")", |
| " - myThirdParam"); |
| |
| TestObject testObject = (TestObject) testEntity.getConfig(TestEntity.CONF_OBJECT); |
| assertEquals(testObject.getNumber(), Integer.valueOf(124)); // factory method adds one |
| assertEquals(testObject.getString(), "myval-suffix"); |
| assertEquals(testObject.getObject(), "myThirdParam"); |
| } |
| |
| @Test |
| public void testCallingPasswordHasher() throws Exception { |
| Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " brooklyn.password: mypassword", |
| " brooklyn.password.sha256:", |
| " brooklyn.password.salt: $brooklyn:entityId()", |
| " brooklyn.password.sha256:", |
| " $brooklyn:object:", |
| " type: "+PasswordHasher.class.getName(), |
| " factoryMethod.name: sha256", |
| " factoryMethod.args:", |
| " - $brooklyn:config(\"brooklyn.password.salt\")", |
| " - $brooklyn:config(\"brooklyn.password\")"); |
| |
| String salt = (String) testEntity.config().get(ConfigKeys.newConfigKey(Object.class, "brooklyn.password.salt")); |
| String sha256 = (String) testEntity.config().get(ConfigKeys.newConfigKey(Object.class, "brooklyn.password.sha256")); |
| |
| assertEquals(salt, testEntity.getId()); |
| assertEquals(sha256, PasswordHasher.sha256(salt, "mypassword")); |
| } |
| |
| @Test |
| public void testBrooklynObjectEvaluatedImmediatelyOnlyOnce() throws Exception { |
| CallRecorder.clear(); |
| Entity entity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+CallRecorder.class.getName(), |
| " factoryMethod.name: call", |
| " factoryMethod.args:", |
| " - myval"); |
| |
| // Nothing has called config().get() yet; but expect it to have been evaluated immediate, on entity construction |
| assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval")); |
| |
| // The config value is set to the result of that single call; getting the config will not invoke it again |
| Object val = entity.config().get(TestEntity.CONF_OBJECT); |
| assertEquals(val, "myval"); |
| assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval")); |
| } |
| |
| @Test |
| public void testBrooklynObjectEvaluationDeferredIfRequired() throws Exception { |
| CallRecorder.clear(); |
| Entity entity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " anotherConfig: myval", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " type: "+CallRecorder.class.getName(), |
| " factoryMethod.name: call", |
| " factoryMethod.args:", |
| " - $brooklyn:config(\"anotherConfig\")"); |
| |
| // The value is a DeferredSupplier; nothing in the blueprint will have called config().get() yet. |
| // However, verification will have called it! Therefore not doing: |
| // assertEquals(CallRecorder.getCalls(), ImmutableList.of()); |
| CallRecorder.clear(); |
| |
| // Retrieving the config value causes it to be resolved |
| Object val = entity.config().get(TestEntity.CONF_OBJECT); |
| assertEquals(val, "myval"); |
| assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval")); |
| |
| // Retrieving the config value a second time will resolve it again |
| Object val2 = entity.config().get(TestEntity.CONF_OBJECT); |
| assertEquals(val2, "myval"); |
| assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval", "myval")); |
| } |
| |
| @Test |
| public void testBrooklynObjectEvaluationExplicitlyDeferred() throws Exception { |
| CallRecorder.clear(); |
| Entity entity = setupAndCheckTestEntityInBasicYamlWith( |
| " brooklyn.config:", |
| " test.confObject:", |
| " $brooklyn:object:", |
| " deferred: true", |
| " type: "+CallRecorder.class.getName(), |
| " factoryMethod.name: call", |
| " factoryMethod.args:", |
| " - myval"); |
| |
| // The value is a DeferredSupplier; nothing in the blueprint will have called config().get() yet. |
| // However, verification will have called it! Therefore not doing: |
| // assertEquals(CallRecorder.getCalls(), ImmutableList.of()); |
| CallRecorder.clear(); |
| |
| // Retrieving the config value causes it to be resolved |
| Object val = entity.config().get(TestEntity.CONF_OBJECT); |
| assertEquals(val, "myval"); |
| assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval")); |
| |
| // Retrieving the config value a second time will resolve it again |
| Object val2 = entity.config().get(TestEntity.CONF_OBJECT); |
| assertEquals(val2, "myval"); |
| assertEquals(CallRecorder.getCalls(), ImmutableList.of("myval", "myval")); |
| } |
| |
| @Test |
| public void testBrooklynObjectGuavaCompose() throws Exception { |
| AttributeSensor<String> originalSensor = Sensors.newStringSensor("staticSensor"); |
| AttributeSensor<String> transformedSensorFormatString = Sensors.newStringSensor("staticSensor.transformed.format"); |
| AttributeSensor<String> transformedSensorComposeMethod = Sensors.newStringSensor("staticSensor.transformed.compose"); |
| CallRecorder.clear(); |
| |
| final Entity entity = createAndStartApplication( |
| "services:", |
| "- type: " + BasicApplication.class.getName(), |
| " brooklyn.initializers:", |
| " - type: org.apache.brooklyn.core.sensor.StaticSensor", |
| " brooklyn.config:", |
| " name: staticSensor", |
| " static.value: \"{parent:{child:myValue}}\"", |
| " brooklyn.enrichers:", |
| " - type: org.apache.brooklyn.enricher.stock.Transformer", |
| " brooklyn.config:", |
| " enricher.sourceSensor: " + originalSensor.getName(), |
| " enricher.targetSensor: " + transformedSensorComposeMethod.getName(), |
| " enricher.transformation:", |
| " $brooklyn:object:", |
| " type: \"com.google.guava:com.google.common.base.Functions\"", |
| " factoryMethod.name: \"compose\"", |
| " factoryMethod.args:", |
| " - $brooklyn:object:", |
| " type: \"org.apache.brooklyn.feed.http.JsonFunctions\"", |
| " factoryMethod.name: \"getPath\"", |
| " factoryMethod.args:", |
| " - \"$.parent.child\"", |
| " - $brooklyn:object:", |
| " type: \"org.apache.brooklyn.feed.http.JsonFunctions\"", |
| " factoryMethod.name: \"asJson\"", |
| " - type: org.apache.brooklyn.enricher.stock.Transformer", |
| " brooklyn.config:", |
| " enricher.sourceSensor: "+ originalSensor.getName(), |
| " enricher.targetSensor: " + transformedSensorFormatString.getName(), |
| " enricher.targetValue:", |
| " $brooklyn:formatString:", |
| " - \"JSON: %s\"", |
| " - $brooklyn:attributeWhenReady(\"staticSensor\")" |
| ); |
| |
| EntityAsserts.assertAttributeEqualsEventually(entity, originalSensor, "{parent:{child:myValue}}"); |
| EntityAsserts.assertAttributeEqualsEventually(entity, transformedSensorFormatString, "JSON: {parent:{child:myValue}}"); |
| EntityAsserts.assertAttributeEqualsEventually(entity, transformedSensorComposeMethod, "myValue"); |
| } |
| |
| |
| public static class CallRecorder { |
| private static final List<String> calls = Collections.synchronizedList(Lists.<String>newArrayList()); |
| |
| public static String call(String val) { |
| calls.add(val); |
| return val; |
| } |
| |
| public static void clear() { |
| calls.clear(); |
| } |
| |
| public static List<String> getCalls() { |
| synchronized (calls) { |
| return MutableList.copyOf(calls); |
| } |
| } |
| } |
| |
| @Override |
| protected Logger getLogger() { |
| return log; |
| } |
| |
| } |