http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java deleted file mode 100644 index 8b477b9..0000000 --- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.brooklyn.core.catalog.internal; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; - -import java.util.List; - -import org.apache.brooklyn.api.catalog.BrooklynCatalog; -import org.apache.brooklyn.api.catalog.CatalogItem; -import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput; -import org.apache.brooklyn.api.entity.EntitySpec; -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.core.mgmt.osgi.OsgiTestResources; -import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; -import org.apache.brooklyn.entity.stock.BasicEntity; -import org.apache.brooklyn.test.support.TestResourceUnavailableException; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import com.google.common.base.Joiner; -import com.google.common.collect.Iterables; -import com.google.common.reflect.TypeToken; - -public class CatalogInputTest { - private ManagementContext mgmt; - private BrooklynCatalog catalog; - private String spec; - - @BeforeMethod(alwaysRun=true) - public void setUp() { - mgmt = LocalManagementContextForTests.newInstanceWithOsgi(); - catalog = mgmt.getCatalog(); - spec = TestToSpecTransformer.registerSpec(EntitySpec.create(BasicEntity.class)); - } - - @Test - public void testYamlInputsParsed() { - CatalogItem<?, ?> item = add( - "brooklyn.catalog:", - " id: test.inputs", - " version: 0.0.1", - " inputs:", - " - simple", - " - name: explicit_name", - " - name: third_input", - " type: integer", - " item: " + spec); - List<CatalogInput<?>> inputs = item.getInputs(); - assertEquals(inputs.size(), 3); - CatalogInput<?> firstInput = inputs.get(0); - assertEquals(firstInput.getLabel(), "simple"); - assertEquals(firstInput.isPinned(), true); - assertEquals(firstInput.getType().getName(), "simple"); - assertEquals(firstInput.getType().getTypeToken(), TypeToken.of(String.class)); - - CatalogInput<?> secondInput = inputs.get(1); - assertEquals(secondInput.getLabel(), "explicit_name"); - assertEquals(secondInput.isPinned(), true); - assertEquals(secondInput.getType().getName(), "explicit_name"); - assertEquals(secondInput.getType().getTypeToken(), TypeToken.of(String.class)); - - CatalogInput<?> thirdInput = inputs.get(2); - assertEquals(thirdInput.getLabel(), "third_input"); - assertEquals(thirdInput.isPinned(), true); - assertEquals(thirdInput.getType().getName(), "third_input"); - assertEquals(thirdInput.getType().getTypeToken(), TypeToken.of(Integer.class)); - } - - @Test - public void testOsgiType() { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH); - - CatalogItem<?, ?> item = add( - "brooklyn.catalog:", - " id: test.inputs", - " version: 0.0.1", - " libraries:", - " - classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH, - " inputs:", - " - name: simple", - " type: " + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY, - " item: " + spec); - List<CatalogInput<?>> inputs = item.getInputs(); - assertEquals(inputs.size(), 1); - CatalogInput<?> firstInput = inputs.get(0); - assertEquals(firstInput.getLabel(), "simple"); - assertTrue(firstInput.isPinned()); - assertEquals(firstInput.getType().getName(), "simple"); - assertEquals(firstInput.getType().getTypeToken().getRawType().getName(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY); - } - - @Test - public void testOsgiClassScanned() { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH); - - addMulti("brooklyn.catalog:", - " items:", - " - scanJavaAnnotations: true", - " version: 2.0.test_java", - " libraries:", - " - classpath://" + OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH); - - CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt, OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY); - assertEquals(item.getVersion(), "2.0.test_java"); - assertEquals(item.getLibraries().size(), 1); - CatalogInput<?> input = item.getInputs().get(0); - assertEquals(input.getLabel(), "more_config"); - assertFalse(input.isPinned()); - assertEquals(input.getType().getName(), "more_config"); - } - - private CatalogItem<?,?> add(String... def) { - return Iterables.getOnlyElement(addMulti(def)); - } - - private Iterable<? extends CatalogItem<?, ?>> addMulti(String... def) { - return catalog.addItems(Joiner.on('\n').join(def)); - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/catalog/internal/SpecParameterInMetaTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/SpecParameterInMetaTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/SpecParameterInMetaTest.java new file mode 100644 index 0000000..2f50c47 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/SpecParameterInMetaTest.java @@ -0,0 +1,139 @@ +/* + * 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.core.catalog.internal; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.util.List; + +import org.apache.brooklyn.api.catalog.BrooklynCatalog; +import org.apache.brooklyn.api.catalog.CatalogItem; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.objs.SpecParameter; +import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; +import org.apache.brooklyn.entity.stock.BasicEntity; +import org.apache.brooklyn.test.support.TestResourceUnavailableException; +import org.apache.brooklyn.util.osgi.OsgiTestResources; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Joiner; +import com.google.common.collect.Iterables; +import com.google.common.reflect.TypeToken; + +public class SpecParameterInMetaTest { + private ManagementContext mgmt; + private BrooklynCatalog catalog; + private String spec; + + @BeforeMethod(alwaysRun=true) + public void setUp() { + mgmt = LocalManagementContextForTests.newInstanceWithOsgi(); + catalog = mgmt.getCatalog(); + spec = TestToSpecTransformer.registerSpec(EntitySpec.create(BasicEntity.class)); + } + + @Test + public void testYamlInputsParsed() { + CatalogItem<?, ?> item = add( + "brooklyn.catalog:", + " id: test.inputs", + " version: 0.0.1", + " parameters:", + " - simple", + " - name: explicit_name", + " - name: third_input", + " type: integer", + " item: " + spec); + List<SpecParameter<?>> inputs = item.getParameters(); + assertEquals(inputs.size(), 3); + SpecParameter<?> firstInput = inputs.get(0); + assertEquals(firstInput.getLabel(), "simple"); + assertEquals(firstInput.isPinned(), true); + assertEquals(firstInput.getType().getName(), "simple"); + assertEquals(firstInput.getType().getTypeToken(), TypeToken.of(String.class)); + + SpecParameter<?> secondInput = inputs.get(1); + assertEquals(secondInput.getLabel(), "explicit_name"); + assertEquals(secondInput.isPinned(), true); + assertEquals(secondInput.getType().getName(), "explicit_name"); + assertEquals(secondInput.getType().getTypeToken(), TypeToken.of(String.class)); + + SpecParameter<?> thirdInput = inputs.get(2); + assertEquals(thirdInput.getLabel(), "third_input"); + assertEquals(thirdInput.isPinned(), true); + assertEquals(thirdInput.getType().getName(), "third_input"); + assertEquals(thirdInput.getType().getTypeToken(), TypeToken.of(Integer.class)); + } + + @Test + public void testOsgiType() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH); + + CatalogItem<?, ?> item = add( + "brooklyn.catalog:", + " id: test.inputs", + " version: 0.0.1", + " libraries:", + " - classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH, + " parameters:", + " - name: simple", + " type: " + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY, + " item: " + spec); + List<SpecParameter<?>> inputs = item.getParameters(); + assertEquals(inputs.size(), 1); + SpecParameter<?> firstInput = inputs.get(0); + assertEquals(firstInput.getLabel(), "simple"); + assertTrue(firstInput.isPinned()); + assertEquals(firstInput.getType().getName(), "simple"); + assertEquals(firstInput.getType().getTypeToken().getRawType().getName(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY); + } + + @Test + public void testOsgiClassScanned() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH); + + addMulti("brooklyn.catalog:", + " items:", + " - scanJavaAnnotations: true", + " version: 2.0.test_java", + " libraries:", + " - classpath://" + OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH); + + CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt, OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY); + assertEquals(item.getVersion(), "2.0.test_java"); + assertEquals(item.getLibraries().size(), 1); + SpecParameter<?> input = item.getParameters().get(0); + assertEquals(input.getLabel(), "more_config"); + assertFalse(input.isPinned()); + assertEquals(input.getType().getName(), "more_config"); + } + + private CatalogItem<?,?> add(String... def) { + return Iterables.getOnlyElement(addMulti(def)); + } + + private Iterable<? extends CatalogItem<?, ?>> addMulti(String... def) { + return catalog.addItems(Joiner.on('\n').join(def)); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTypeConfigTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTypeConfigTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTypeConfigTest.java new file mode 100644 index 0000000..ca71d15 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTypeConfigTest.java @@ -0,0 +1,126 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.util.List; +import java.util.Set; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.entity.ImplementedBy; +import org.apache.brooklyn.api.sensor.SensorEvent; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.ConfigKeys; +import org.apache.brooklyn.core.objs.BasicSpecParameter; +import org.apache.brooklyn.core.sensor.BasicSensorEvent; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.util.collections.MutableSet; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +public class DynamicEntityTypeConfigTest extends BrooklynAppUnitTestSupport { + + @ImplementedBy(ConfigEntityForTestingImpl.class) + public static interface ConfigEntityForTesting extends Entity { + ConfigKey<String> SUGGESTED_VERSION = BrooklynConfigKeys.SUGGESTED_VERSION; + ConfigKey<String> INSTALL_UNIQUE_LABEL = BrooklynConfigKeys.INSTALL_UNIQUE_LABEL; + } + public static class ConfigEntityForTestingImpl extends AbstractEntity implements ConfigEntityForTesting { + public static final ConfigKey<String> PRE_INSTALL_COMMAND = BrooklynConfigKeys.PRE_INSTALL_COMMAND; + public static final ConfigKey<String> POST_INSTALL_COMMAND = BrooklynConfigKeys.POST_INSTALL_COMMAND; + } + private static final ConfigKey<?> NEW_CONFIG = ConfigKeys.newStringConfigKey("new.config"); + private static final ConfigKey<?> SPEC_CONFIG = ConfigKeys.newStringConfigKey("spec.config"); + + private EntityInternal entity; + @SuppressWarnings("rawtypes") + private RecordingSensorEventListener<ConfigKey> listener; + + public final static Set<ConfigKey<?>> DEFAULT_CONFIG_KEYS = ImmutableSet.<ConfigKey<?>>of( + ConfigEntityForTesting.SUGGESTED_VERSION, + ConfigEntityForTesting.INSTALL_UNIQUE_LABEL, + ConfigEntityForTestingImpl.PRE_INSTALL_COMMAND, + ConfigEntityForTestingImpl.POST_INSTALL_COMMAND, + SPEC_CONFIG); + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception{ + super.setUp(); + entity = (EntityInternal) app.createAndManageChild(EntitySpec.create(ConfigEntityForTesting.class) + .parameters(ImmutableList.of(new BasicSpecParameter<>("spec config", true, SPEC_CONFIG)))); + listener = new RecordingSensorEventListener<>(); + app.subscriptions().subscribe(entity, AbstractEntity.CONFIG_KEY_ADDED, listener); + app.subscriptions().subscribe(entity, AbstractEntity.CONFIG_KEY_REMOVED, listener); + } + + private void assertEventuallyListenerEventsEqual(@SuppressWarnings("rawtypes") final List<SensorEvent<ConfigKey>> sensorEvents) { + EntityTypeTest.assertEventuallyListenerEventsEqual(listener, sensorEvents); + } + + @Test + public void testGetConfigKeys() throws Exception{ + assertEquals(entity.getEntityType().getConfigKeys(), DEFAULT_CONFIG_KEYS); + } + + @Test + public void testAddConfigKey() throws Exception{ + entity.getMutableEntityType().addConfigKey(NEW_CONFIG); + assertEquals(entity.getEntityType().getConfigKeys(), + ImmutableSet.builder().addAll(DEFAULT_CONFIG_KEYS).add(NEW_CONFIG).build()); + + assertEventuallyListenerEventsEqual(ImmutableList.of(BasicSensorEvent.ofUnchecked(AbstractEntity.CONFIG_KEY_ADDED, entity, NEW_CONFIG))); + } + + @Test + public void testAddConfigKeyThroughEntity() throws Exception{ + ((AbstractEntity)Entities.deproxy(entity)).configure(ImmutableList.<ConfigKey<?>>of(NEW_CONFIG)); + assertEquals(entity.getEntityType().getConfigKeys(), + ImmutableSet.builder().addAll(DEFAULT_CONFIG_KEYS).add(NEW_CONFIG).build()); + + assertEventuallyListenerEventsEqual(ImmutableList.of(BasicSensorEvent.ofUnchecked(AbstractEntity.CONFIG_KEY_ADDED, entity, NEW_CONFIG))); + } + + @Test + public void testRemoveConfigKey() throws Exception { + entity.getMutableEntityType().removeConfigKey(ConfigEntityForTesting.INSTALL_UNIQUE_LABEL); + assertEquals(entity.getEntityType().getConfigKeys(), + MutableSet.builder().addAll(DEFAULT_CONFIG_KEYS).remove(ConfigEntityForTesting.INSTALL_UNIQUE_LABEL).build().asUnmodifiable()); + + assertEventuallyListenerEventsEqual(ImmutableList.of( + BasicSensorEvent.ofUnchecked(AbstractEntity.CONFIG_KEY_REMOVED, entity, ConfigEntityForTesting.INSTALL_UNIQUE_LABEL))); + } + + @Test + public void testGetConfigKey() throws Exception { + ConfigKey<?> expected = ConfigEntityForTesting.INSTALL_UNIQUE_LABEL; + ConfigKey<?> configKey = entity.getEntityType().getConfigKey(expected.getName()); + assertEquals(configKey.getDescription(), expected.getDescription()); + assertEquals(configKey.getName(), expected.getName()); + + assertNull(entity.getEntityType().getConfigKey("does.not.exist")); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java index 6f31b6e..641f97b2 100644 --- a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java @@ -20,6 +20,8 @@ package org.apache.brooklyn.core.entity; import static org.apache.brooklyn.core.entity.AbstractEntity.CHILD_ADDED; import static org.apache.brooklyn.core.entity.AbstractEntity.CHILD_REMOVED; +import static org.apache.brooklyn.core.entity.AbstractEntity.CONFIG_KEY_ADDED; +import static org.apache.brooklyn.core.entity.AbstractEntity.CONFIG_KEY_REMOVED; import static org.apache.brooklyn.core.entity.AbstractEntity.EFFECTOR_ADDED; import static org.apache.brooklyn.core.entity.AbstractEntity.EFFECTOR_CHANGED; import static org.apache.brooklyn.core.entity.AbstractEntity.EFFECTOR_REMOVED; @@ -47,10 +49,8 @@ import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.sensor.AttributeSensor; import org.apache.brooklyn.api.sensor.Sensor; +import org.apache.brooklyn.api.sensor.SensorEvent; import org.apache.brooklyn.core.effector.MethodEffector; -import org.apache.brooklyn.core.entity.AbstractEntity; -import org.apache.brooklyn.core.entity.Entities; -import org.apache.brooklyn.core.entity.EntityInternal; import org.apache.brooklyn.core.sensor.BasicSensorEvent; import org.apache.brooklyn.core.sensor.Sensors; import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; @@ -69,10 +69,12 @@ import com.google.common.collect.Iterables; public class EntityTypeTest extends BrooklynAppUnitTestSupport { private static final AttributeSensor<String> TEST_SENSOR = Sensors.newStringSensor("test.sensor"); private EntityInternal entity; + @SuppressWarnings("rawtypes") private RecordingSensorEventListener<Sensor> listener; public final static Set<Sensor<?>> DEFAULT_SENSORS = ImmutableSet.<Sensor<?>>of( SENSOR_ADDED, SENSOR_REMOVED, + CONFIG_KEY_ADDED, CONFIG_KEY_REMOVED, EFFECTOR_ADDED, EFFECTOR_REMOVED, EFFECTOR_CHANGED, POLICY_ADDED, POLICY_REMOVED, CHILD_ADDED, CHILD_REMOVED, @@ -175,8 +177,11 @@ public class EntityTypeTest extends BrooklynAppUnitTestSupport { assertEquals(entity.getEntityType().getSensors(), DEFAULT_SENSORS); } - protected <T> void assertEventuallyListenerEventsEqual(final List<T> sensorEvents) { - final RecordingSensorEventListener listener = this.listener; + private void assertEventuallyListenerEventsEqual(@SuppressWarnings("rawtypes") final List<SensorEvent<Sensor>> sensorEvents) { + assertEventuallyListenerEventsEqual(listener, sensorEvents); + } + + protected static <T> void assertEventuallyListenerEventsEqual(final RecordingSensorEventListener<T> listener, final List<SensorEvent<T>> sensorEvents) { Asserts.succeedsEventually(new Runnable() { @Override public void run() { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java new file mode 100644 index 0000000..2009c98 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java @@ -0,0 +1,65 @@ +/* + * 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.core.objs; + +import static org.testng.Assert.assertEquals; + +import java.util.List; + +import org.apache.brooklyn.api.catalog.CatalogConfig; +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.objs.SpecParameter; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.ConfigKeys; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.reflect.TypeToken; + +public class BasicSpecParameterFromClassTest { + public interface SpecParameterTestEntity extends Entity { + @CatalogConfig(label="String Key", priority=3) + ConfigKey<String> STRING_KEY = ConfigKeys.newStringConfigKey("string_key"); + + @CatalogConfig(label="Integer Key", priority=2) + ConfigKey<Integer> INTEGER_KEY = ConfigKeys.newIntegerConfigKey("integer_key"); + + @SuppressWarnings("serial") + @CatalogConfig(label="Predicate Key", priority=1) + ConfigKey<Predicate<String>> PREDICATE_KEY = ConfigKeys.newConfigKey(new TypeToken<Predicate<String>>() {}, "predicate_key"); + + ConfigKey<String> UNPINNNED_KEY = ConfigKeys.newStringConfigKey("unpinned_key"); + } + + @Test + public void testFullDefinition() { + List<SpecParameter<?>> inputs = BasicSpecParameter.fromClass(SpecParameterTestEntity.class); + assertInput(inputs.get(0), "Predicate Key", true, SpecParameterTestEntity.PREDICATE_KEY); + assertInput(inputs.get(1), "Integer Key", true, SpecParameterTestEntity.INTEGER_KEY); + assertInput(inputs.get(2), "String Key", true, SpecParameterTestEntity.STRING_KEY); + assertInput(inputs.get(3), "unpinned_key", false, SpecParameterTestEntity.UNPINNNED_KEY); + } + + private void assertInput(SpecParameter<?> input, String label, boolean pinned, ConfigKey<?> type) { + assertEquals(input.getLabel(), label); + assertEquals(input.isPinned(), pinned); + assertEquals(input.getType(), type); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java new file mode 100644 index 0000000..0f48dad --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java @@ -0,0 +1,186 @@ +/* + * 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.core.objs; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import java.util.List; + +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.objs.SpecParameter; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; +import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext; +import org.apache.brooklyn.core.objs.BasicSpecParameter; +import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; +import org.apache.brooklyn.util.text.StringPredicates; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.reflect.TypeToken; + +public class BasicSpecParameterFromListTest { + private ManagementContext mgmt; + + @BeforeMethod(alwaysRun=true) + public void setUp() { + mgmt = LocalManagementContextForTests.newInstance(); + } + + @Test + public void testInlineName() { + String name = "minRam"; + SpecParameter<?> input = parse(name); + assertEquals(input.getLabel(), name); + assertTrue(input.isPinned()); + ConfigKey<?> type = input.getType(); + assertEquals(type.getName(), name); + assertEquals(type.getTypeToken(), TypeToken.of(String.class)); + assertNull(type.getDefaultValue()); + assertNull(type.getDescription()); + assertNull(type.getInheritance()); + assertConstraint(type.getConstraint(), Predicates.alwaysTrue()); + } + + @Test + public void testOnlyName() { + String name = "minRam"; + SpecParameter<?> input = parse(ImmutableMap.of("name", name)); + assertEquals(input.getLabel(), name); + assertEquals(input.getType().getName(), name); + assertEquals(input.getType().getTypeToken(), TypeToken.of(String.class)); + } + + @Test + public void testUnusualName() { + parse(ImmutableMap.of("name", "name with spaces")); + } + + @Test + public void testFullDefinition() { + String name = "minRam"; + String label = "Minimum Ram"; + String description = "Some description"; + String inputType = "string"; + String defaultValue = "VALUE"; + String constraint = "required"; + SpecParameter<?> input = parse(ImmutableMap.builder() + .put("name", name) + .put("label", label) + .put("description", description) + .put("type", inputType) + .put("default", defaultValue) + .put("constraints", constraint) + .build()); + + assertEquals(input.getLabel(), label); + assertTrue(input.isPinned()); + + ConfigKey<?> type = input.getType(); + assertEquals(type.getName(), name); + assertEquals(type.getTypeToken(), TypeToken.of(String.class)); + assertEquals(type.getDefaultValue(), defaultValue); + assertEquals(type.getDescription(), description); + assertNull(type.getInheritance()); + assertConstraint(type.getConstraint(), StringPredicates.isNonBlank()); + } + + @Test + public void testUnexpectedType() { + String name = "1234"; + String label = "1234"; + String description = "5678.56"; + String defaultValue = "444.12"; + SpecParameter<?> input = parse(ImmutableMap.of( + "name", name, + "label", label, + "description", description, + "default", defaultValue)); + + assertEquals(input.getLabel(), name); + assertTrue(input.isPinned()); + + ConfigKey<?> type = input.getType(); + assertEquals(type.getName(), name); + assertEquals(type.getDefaultValue(), defaultValue); + assertEquals(type.getDescription(), description); + assertNull(type.getInheritance()); + } + + @Test + public void testConstraintAsArray() { + String name = "minRam"; + String constraint = "required"; + SpecParameter<?> input = parse(ImmutableMap.of( + "name", name, + "constraints", ImmutableList.of(constraint))); + ConfigKey<?> type = input.getType(); + assertConstraint(type.getConstraint(), StringPredicates.isNonBlank()); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testMissingName() { + parse(ImmutableMap.of( + "type", "string")); + } + + @Test + public void testJavaType() { + String name = "minRam"; + SpecParameter<?> input = parse(ImmutableMap.of( + "name", name, + "type", BasicSpecParameterFromListTest.class.getName())); + assertEquals(input.getType().getTypeToken(), TypeToken.of(BasicSpecParameterFromListTest.class)); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalidType() { + String name = "minRam"; + parse(ImmutableMap.of( + "name", name, + "type", "missing_type")); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalidConstraint() { + String name = "minRam"; + parse(ImmutableMap.of( + "name", name, + "type", "missing_type")); + } + + private SpecParameter<?> parse(Object def) { + BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt); + List<SpecParameter<?>> inputs = BasicSpecParameter.fromConfigList(ImmutableList.of(def), loader); + return Iterables.getOnlyElement(inputs); + } + + private void assertConstraint(Predicate<?> actual, Predicate<?> expected) { + //How to compare predicates correctly, re-creating the same predicate doesn't work + assertEquals(actual.toString(), expected.toString()); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatform.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatform.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatform.java index bc6a9fd..14a7c59 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatform.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatform.java @@ -55,6 +55,7 @@ public class BrooklynCampPlatform extends AggregatingCampPlatform implements Has // --- brooklyn setup + @Override public ManagementContext getBrooklynManagementContext() { return bmc; } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java index bbfe2ab..be2488b 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java @@ -25,6 +25,7 @@ import com.google.common.annotations.Beta; @Beta public class BrooklynCampPlatformLauncherNoServer extends BrooklynCampPlatformLauncherAbstract { + @Override public void stopServers() { // nothing to do } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java index 7fe6030..52f52e9 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java @@ -25,5 +25,6 @@ public interface BrooklynCampReservedKeys { public static final String BROOKLYN_ENRICHERS = "brooklyn.enrichers"; public static final String BROOKLYN_CHILDREN = "brooklyn.children"; public static final String BROOKLYN_INITIALIZERS = "brooklyn.initializers"; + public static final String BROOKLYN_PARAMETERS = "brooklyn.parameters"; public static final String BROOKLYN_CATALOG = "brooklyn.catalog"; } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java index 3368df2..a400758 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java @@ -19,7 +19,6 @@ package org.apache.brooklyn.camp.brooklyn.spi.creation; import java.util.List; -import java.util.Map.Entry; import java.util.Set; import org.apache.brooklyn.api.entity.Application; @@ -29,7 +28,6 @@ import org.apache.brooklyn.camp.CampPlatform; import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator; import org.apache.brooklyn.camp.spi.Assembly; import org.apache.brooklyn.camp.spi.AssemblyTemplate; -import org.apache.brooklyn.camp.spi.AssemblyTemplate.Builder; import org.apache.brooklyn.camp.spi.PlatformComponentTemplate; import org.apache.brooklyn.camp.spi.collection.ResolvableLink; import org.apache.brooklyn.core.mgmt.EntityManagementUtils; @@ -37,12 +35,10 @@ import org.apache.brooklyn.core.mgmt.EntityManagementUtils.CreationResult; import org.apache.brooklyn.core.mgmt.HasBrooklynManagementContext; import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext; -import org.apache.brooklyn.entity.stock.BasicApplicationImpl; import org.apache.brooklyn.util.core.flags.TypeCoercions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -86,9 +82,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe // AssemblyTemplates created via PDP, _specifying_ then entities to put in - BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance( - loader, buildWrapperAppTemplate(template)); - EntitySpec<? extends Application> app = resolver.resolveSpec(ImmutableSet.<String>of()); + EntitySpec<? extends Application> app = CampUtils.createWrapperApp(template, loader); app.configure(EntityManagementUtils.WRAPPER_APP_MARKER, Boolean.TRUE); // first build the children into an empty shell app @@ -104,20 +98,6 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe return app; } - private AssemblyTemplate buildWrapperAppTemplate(AssemblyTemplate template) { - Builder<? extends AssemblyTemplate> builder = AssemblyTemplate.builder(); - builder.type("brooklyn:" + BasicApplicationImpl.class.getName()); - builder.id(template.getId()); - builder.name(template.getName()); - builder.sourceCode(template.getSourceCode()); - for (Entry<String, Object> entry : template.getCustomAttributes().entrySet()) { - builder.customAttribute(entry.getKey(), entry.getValue()); - } - builder.instantiator(template.getInstantiator()); - AssemblyTemplate wrapTemplate = builder.build(); - return wrapTemplate; - } - private boolean shouldUnwrap(AssemblyTemplate template, EntitySpec<? extends Application> app) { if (Boolean.TRUE.equals(TypeCoercions.coerce(template.getCustomAttributes().get(NEVER_UNWRAP_APPS_PROPERTY), Boolean.class))) return false; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java index a273c50..c150ddc 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java @@ -233,6 +233,7 @@ public class BrooklynComponentTemplateResolver { new BrooklynEntityDecorationResolver.PolicySpecResolver(yamlLoader).decorate(spec, attrs); new BrooklynEntityDecorationResolver.EnricherSpecResolver(yamlLoader).decorate(spec, attrs); new BrooklynEntityDecorationResolver.InitializerResolver(yamlLoader).decorate(spec, attrs); + new BrooklynEntityDecorationResolver.SpecParameterResolver(yamlLoader).decorate(spec, attrs); configureEntityConfig(spec); } @@ -299,6 +300,7 @@ public class BrooklynComponentTemplateResolver { for (Class<?> iface : spec.getAdditionalInterfaces()) { allKeys.addAll(FlagUtils.findAllFlagsAndConfigKeys(null, iface, bagFlags)); } + allKeys.addAll(FlagUtils.findAllParameterConfigKeys(spec.getParameters(), bagFlags)); return allKeys; } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java index b1d5dce..efe2d9d 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java @@ -24,19 +24,21 @@ import java.util.Map; import org.apache.brooklyn.api.entity.EntityInitializer; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.objs.SpecParameter; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.api.sensor.Enricher; import org.apache.brooklyn.api.sensor.EnricherSpec; -import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry; import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys; import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator.InstantiatorFromKey; +import org.apache.brooklyn.core.objs.BasicSpecParameter; import org.apache.brooklyn.core.typereg.RegisteredTypeConstraints; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.core.config.ConfigBag; import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableList; /** * Pattern for resolving "decorations" on service specs / entity specs, such as policies, enrichers, etc. @@ -53,21 +55,18 @@ public abstract class BrooklynEntityDecorationResolver<DT> { public abstract void decorate(EntitySpec<?> entitySpec, ConfigBag attrs); - protected Iterable<? extends DT> buildListOfTheseDecorationsFromEntityAttributes(ConfigBag attrs) { + protected List<? extends DT> buildListOfTheseDecorationsFromEntityAttributes(ConfigBag attrs) { Object value = getDecorationAttributeJsonValue(attrs); - List<DT> decorations = MutableList.of(); - if (value==null) return decorations; + if (value==null) return MutableList.of(); if (value instanceof Iterable) { - for (Object decorationJson: (Iterable<?>)value) - addDecorationFromJsonMap(checkIsMap(decorationJson), decorations); + return buildListOfTheseDecorationsFromIterable((Iterable<?>)value); } else { // in future may support types other than iterables here, // e.g. a map short form where the key is the type throw new IllegalArgumentException(getDecorationKind()+" body should be iterable, not " + value.getClass()); } - return decorations; } - + protected Map<?,?> checkIsMap(Object decorationJson) { if (!(decorationJson instanceof Map)) throw new IllegalArgumentException(getDecorationKind()+" value must be a Map, not " + @@ -75,6 +74,13 @@ public abstract class BrooklynEntityDecorationResolver<DT> { return (Map<?,?>) decorationJson; } + protected List<DT> buildListOfTheseDecorationsFromIterable(Iterable<?> value) { + List<DT> decorations = MutableList.of(); + for (Object decorationJson: value) + addDecorationFromJsonMap(checkIsMap(decorationJson), decorations); + return decorations; + } + protected abstract String getDecorationKind(); protected abstract Object getDecorationAttributeJsonValue(ConfigBag attrs); @@ -102,7 +108,6 @@ public abstract class BrooklynEntityDecorationResolver<DT> { } @Override - @SuppressWarnings("unchecked") protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<PolicySpec<?>> decorations) { InstantiatorFromKey decoLoader = instantiator.from(decorationJson).prefix("policy"); @@ -110,9 +115,14 @@ public abstract class BrooklynEntityDecorationResolver<DT> { ManagementContext mgmt = instantiator.loader.getManagementContext(); RegisteredType item = mgmt.getTypeRegistry().get(policyType, RegisteredTypeConstraints.spec(Policy.class)); - PolicySpec<? extends Policy> spec; - if (item!=null) spec = mgmt.getTypeRegistry().createSpec(item, null, PolicySpec.class); - else spec = PolicySpec.create(decoLoader.getType(Policy.class)); + PolicySpec<?> spec; + if (item!=null) { + spec = mgmt.getTypeRegistry().createSpec(item, null, PolicySpec.class); + } else { + Class<? extends Policy> type = decoLoader.getType(Policy.class); + spec = PolicySpec.create(type) + .parameters(BasicSpecParameter.fromClass(mgmt, type)); + } spec.configure( decoLoader.getConfigMap() ); decorations.add(spec); } @@ -136,8 +146,10 @@ public abstract class BrooklynEntityDecorationResolver<DT> { @Override protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<EnricherSpec<?>> decorations) { InstantiatorFromKey decoLoader = instantiator.from(decorationJson).prefix("enricher"); - decorations.add(EnricherSpec.create(decoLoader.getType(Enricher.class)) - .configure( decoLoader.getConfigMap() )); + Class<? extends Enricher> type = decoLoader.getType(Enricher.class); + decorations.add(EnricherSpec.create(type) + .configure(decoLoader.getConfigMap()) + .parameters(BasicSpecParameter.fromClass(instantiator.loader.getManagementContext(), type))); } } @@ -161,6 +173,38 @@ public abstract class BrooklynEntityDecorationResolver<DT> { decorations.add(instantiator.from(decorationJson).prefix("initializer").newInstance(EntityInitializer.class)); } } - + + // Not much value from extending from BrooklynEntityDecorationResolver, but let's not break the convention + public static class SpecParameterResolver extends BrooklynEntityDecorationResolver<SpecParameter<?>> { + + protected SpecParameterResolver(BrooklynYamlTypeInstantiator.Factory instantiator) { super(instantiator); } + @Override protected String getDecorationKind() { return "Spec Parameter initializer"; } + + @Override + public void decorate(EntitySpec<?> entitySpec, ConfigBag attrs) { + List<? extends SpecParameter<?>> explicitParams = buildListOfTheseDecorationsFromEntityAttributes(attrs); + if (!explicitParams.isEmpty()) { + entitySpec.parameters(explicitParams); + } + if (entitySpec.getParameters().isEmpty()) { + entitySpec.parameters(BasicSpecParameter.fromSpec(instantiator.loader.getManagementContext(), entitySpec)); + } + } + + @Override + protected List<SpecParameter<?>> buildListOfTheseDecorationsFromIterable(Iterable<?> value) { + return BasicSpecParameter.fromConfigList(ImmutableList.copyOf(value), instantiator.loader); + } + + @Override + protected Object getDecorationAttributeJsonValue(ConfigBag attrs) { + return attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS); + } + + @Override + protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<SpecParameter<?>> decorations) { + throw new IllegalStateException("Not called"); + } + } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java index 96e8c4e..07a8267 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java @@ -126,6 +126,7 @@ public class BrooklynEntityMatcher implements PdpMatcher { addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_ENRICHERS); addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_INITIALIZERS); addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CHILDREN); + addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_PARAMETERS); addCustomMapAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CATALOG); brooklynFlags.putAll(attrs); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java index 55f9603..b1b5876 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java @@ -89,6 +89,7 @@ public abstract class BrooklynYamlTypeInstantiator { return this; } + @Override public Maybe<String> getTypeName() { Maybe<Object> result = data.getStringKeyMaybe(getPreferredKeyName()); if (result.isAbsent() && typeKeyPrefix!=null) { @@ -174,6 +175,7 @@ public abstract class BrooklynYamlTypeInstantiator { this.typeName = typeName; } + @Override public Maybe<String> getTypeName() { return Maybe.fromNullable(typeName); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java index 29791dd..d4c5142 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java @@ -18,11 +18,9 @@ */ package org.apache.brooklyn.camp.brooklyn.spi.creation; -import java.util.List; import java.util.Set; import org.apache.brooklyn.api.catalog.CatalogItem; -import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.camp.CampPlatform; @@ -59,7 +57,7 @@ public class CampCatalogUtils { switch (item.getCatalogItemType()) { case TEMPLATE: case ENTITY: - spec = createEntitySpec(item.getPlanYaml(), loader, encounteredTypes); + spec = CampUtils.createRootServiceSpec(item.getPlanYaml(), loader, encounteredTypes); break; case LOCATION: spec = CampUtils.createLocationSpec(item.getPlanYaml(), loader, encounteredTypes); @@ -78,14 +76,6 @@ public class CampCatalogUtils { return spec; } - - private static EntitySpec<?> createEntitySpec(String plan, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) { - List<EntitySpec<?>> serviceEntitySpecs = CampUtils.createServiceSpecs(plan, loader, encounteredTypes); - if (serviceEntitySpecs.size() > 1) { - throw new UnsupportedOperationException("Only supporting single service in catalog item currently: got "+serviceEntitySpecs); - } - return serviceEntitySpecs.get(0); - } public static CampPlatform getCampPlatform(ManagementContext mgmt) { return CampUtils.getCampPlatform(mgmt); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java index bcb18df..b396f37 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java @@ -23,48 +23,94 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.io.StringReader; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import org.apache.brooklyn.api.entity.Application; import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.objs.SpecParameter; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.camp.CampPlatform; import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants; +import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys; import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator; import org.apache.brooklyn.camp.spi.AssemblyTemplate; +import org.apache.brooklyn.camp.spi.AssemblyTemplate.Builder; import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator; import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan; import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog; import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker; +import org.apache.brooklyn.core.mgmt.EntityManagementUtils; import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; +import org.apache.brooklyn.core.objs.BasicSpecParameter; import org.apache.brooklyn.core.objs.BrooklynObjectInternal.ConfigurationSupportInternal; +import org.apache.brooklyn.entity.stock.BasicApplicationImpl; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.stream.Streams; import org.apache.brooklyn.util.yaml.Yamls; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; //TODO-type-registry public class CampUtils { - public static List<EntitySpec<?>> createServiceSpecs(String plan, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) { + public static EntitySpec<?> createRootServiceSpec(String plan, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) { CampPlatform camp = getCampPlatform(loader.getManagementContext()); AssemblyTemplate at = registerDeploymentPlan(plan, loader, camp); AssemblyTemplateInstantiator instantiator = getInstantiator(at); if (instantiator instanceof AssemblyTemplateSpecInstantiator) { - return ((AssemblyTemplateSpecInstantiator)instantiator).createServiceSpecs(at, camp, loader, encounteredTypes); + List<EntitySpec<?>> serviceSpecs = ((AssemblyTemplateSpecInstantiator)instantiator).createServiceSpecs(at, camp, loader, encounteredTypes); + if (serviceSpecs.size() > 1) { + throw new UnsupportedOperationException("Single service expected, but got "+serviceSpecs); + } + EntitySpec<?> rootSpec = serviceSpecs.get(0); + EntitySpec<? extends Application> wrapperApp = createWrapperApp(at, loader); + EntityManagementUtils.mergeWrapperParentSpecToChildEntity(wrapperApp, rootSpec); + return rootSpec; } else { throw new IllegalStateException("Unable to instantiate YAML; incompatible instantiator "+instantiator+" for "+at); } } + public static EntitySpec<? extends Application> createWrapperApp(AssemblyTemplate template, BrooklynClassLoadingContext loader) { + BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance( + loader, buildWrapperAppTemplate(template)); + EntitySpec<Application> wrapperSpec = resolver.resolveSpec(ImmutableSet.<String>of()); + if (!hasExplicitParams(template)) { + wrapperSpec.parameters(ImmutableList.<SpecParameter<?>>of()); + } + return wrapperSpec; + } + + private static boolean hasExplicitParams(AssemblyTemplate at) { + return at.getCustomAttributes().containsKey(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS); + } + + private static AssemblyTemplate buildWrapperAppTemplate(AssemblyTemplate template) { + Builder<? extends AssemblyTemplate> builder = AssemblyTemplate.builder(); + builder.type("brooklyn:" + BasicApplicationImpl.class.getName()); + builder.id(template.getId()); + builder.name(template.getName()); + builder.sourceCode(template.getSourceCode()); + for (Entry<String, Object> entry : template.getCustomAttributes().entrySet()) { + builder.customAttribute(entry.getKey(), entry.getValue()); + } + builder.instantiator(template.getInstantiator()); + AssemblyTemplate wrapTemplate = builder.build(); + return wrapTemplate; + } + public static AssemblyTemplateInstantiator getInstantiator(AssemblyTemplate at) { try { return at.getInstantiator().newInstance(); @@ -109,11 +155,13 @@ public class CampUtils { } String versionedId = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "policy_type", "policyType", "type"), "policy type"); - PolicySpec<? extends Policy> spec = resolveSpec(versionedId, loader, encounteredCatalogTypes); - Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config"); + PolicySpec<? extends Policy> spec = resolvePolicySpec(versionedId, loader, encounteredCatalogTypes); + Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get(BrooklynCampReservedKeys.BROOKLYN_CONFIG); if (brooklynConfig != null) { spec.configure(brooklynConfig); } + List<?> parameters = (List<?>) itemMap.get(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS); + initParameters(parameters, spec, loader); return spec; } @@ -125,8 +173,7 @@ public class CampUtils { } Object location = Iterables.getOnlyElement((Iterable<?>)locations); - - return createLocationSpec(loader, location); + return createLocationSpec(loader, location); } @SuppressWarnings("unchecked") @@ -142,7 +189,18 @@ public class CampUtils { String type = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "location_type", "locationType", "type"), "location type"); Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config"); - return resolveLocationSpec(type, brooklynConfig, loader); + LocationSpec<?> locationSpec = resolveLocationSpec(type, brooklynConfig, loader); + List<?> explicitParams = (List<?>) itemMap.get(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS); + initParameters(explicitParams, locationSpec, loader); + return locationSpec; + } + + private static void initParameters(List<?> explicitParams, AbstractBrooklynObjectSpec<?, ?> spec, BrooklynClassLoadingContext loader) { + if (explicitParams != null) { + spec.parameters(BasicSpecParameter.fromConfigList(explicitParams, loader)); + } else { + spec.parameters(BasicSpecParameter.fromSpec(loader.getManagementContext(), spec)); + } } public static DeploymentPlan makePlanFromYaml(ManagementContext mgmt, String yaml) { @@ -160,7 +218,7 @@ public class CampUtils { } @SuppressWarnings("unchecked") - private static PolicySpec<? extends Policy> resolveSpec( + private static PolicySpec<? extends Policy> resolvePolicySpec( String versionedId, BrooklynClassLoadingContext loader, Set<String> encounteredCatalogTypes) { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java index ab058c7..387212c 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java @@ -18,7 +18,6 @@ */ package org.apache.brooklyn.camp.brooklyn.spi.creation.service; -import java.util.List; import java.util.Set; import org.apache.brooklyn.api.entity.EntitySpec; @@ -58,11 +57,7 @@ public class UrlServiceSpecResolver implements EntitySpecResolver { return null; } // Referenced specs are expected to be CAMP format as well. - List<EntitySpec<?>> serviceSpecs = CampUtils.createServiceSpecs(yaml, loader, encounteredTypes); - if (serviceSpecs.size() > 1) { - throw new UnsupportedOperationException("Only supporting single service in remotely referenced plans: got "+serviceSpecs); - } - return serviceSpecs.get(0); + return CampUtils.createRootServiceSpec(yaml, loader, encounteredTypes); } @Override http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java index 0d874bf..7135480 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java @@ -63,6 +63,7 @@ public class BrooklynImmutableCampPlatform extends CampPlatform implements HasBr // --- brooklyn setup + @Override public ManagementContext getBrooklynManagementContext() { return bmc; } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java index fdc21fe..4d72cf8 100644 --- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java +++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Set; import org.apache.brooklyn.api.catalog.CatalogItem; -import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput; import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType; import org.apache.brooklyn.api.effector.Effector; import org.apache.brooklyn.api.entity.Entity; @@ -31,6 +30,7 @@ import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.entity.EntityType; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.location.LocationSpec; +import org.apache.brooklyn.api.objs.SpecParameter; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.api.sensor.Sensor; @@ -69,7 +69,7 @@ public class CatalogTransformer { EntityDynamicType typeMap = BrooklynTypes.getDefinedEntityType(spec.getType()); EntityType type = typeMap.getSnapshot(); - for (CatalogInput<?> input: item.getInputs()) + for (SpecParameter<?> input: item.getParameters()) config.add(EntityTransformer.entityConfigSummary(input)); for (Sensor<?> x: type.getSensors()) sensors.add(SensorTransformer.sensorSummaryForCatalog(x)); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java index 9637e75..803acd9 100644 --- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java +++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java @@ -26,9 +26,9 @@ import java.util.List; import java.util.Map; import org.apache.brooklyn.api.catalog.CatalogConfig; -import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput; import org.apache.brooklyn.api.entity.Application; import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.objs.SpecParameter; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.render.RendererHints; import org.apache.brooklyn.rest.domain.EntityConfigSummary; @@ -153,7 +153,7 @@ public class EntityTransformer { return entityConfigSummary(config, label, priority, null); } - public static EntityConfigSummary entityConfigSummary(CatalogInput<?> input) { + public static EntityConfigSummary entityConfigSummary(SpecParameter<?> input) { Double priority = input.isPinned() ? Double.valueOf(1d) : null; return entityConfigSummary(input.getType(), input.getLabel(), priority, null); }
