More conversion to new-style TypePlanTransformer, and fixes
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/c712ad5e Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/c712ad5e Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/c712ad5e Branch: refs/heads/master Commit: c712ad5e6ed0b0cc6ea0a4e501091fc0dd77c9d9 Parents: e480402 Author: Alex Heneveld <[email protected]> Authored: Mon Nov 9 21:42:02 2015 +0000 Committer: Alex Heneveld <[email protected]> Committed: Tue Nov 10 17:13:02 2015 +0000 ---------------------------------------------------------------------- .../catalog/internal/BasicBrooklynCatalog.java | 2 +- .../core/typereg/BasicBrooklynTypeRegistry.java | 2 +- .../typereg/RegisteredTypeLoadingContexts.java | 6 +- .../brooklyn/core/typereg/RegisteredTypes.java | 18 ++- .../policy/basic/AbstractEntityAdjunctTest.java | 52 --------- .../internal/SpecParameterInMetaTest.java | 65 +++++++++-- .../internal/StaticTypePlanTransformer.java | 115 +++++++++++++++++++ .../catalog/internal/TestToSpecTransformer.java | 82 ++++++------- .../core/objs/AbstractEntityAdjunctTest.java | 52 +++++++++ ...che.brooklyn.core.plan.PlanToSpecTransformer | 19 --- .../brooklyn/spi/creation/CampCatalogUtils.java | 2 +- .../brooklyn/spi/creation/CampResolver.java | 17 +-- .../spi/creation/CampToSpecTransformer.java | 2 +- .../spi/creation/CampTypePlanTransformer.java | 4 + .../service/UrlServiceSpecResolver.java | 2 +- .../camp/brooklyn/LocationsYamlTest.java | 4 +- .../brooklyn/catalog/CatalogParametersTest.java | 49 +++++++- .../brooklyn/test/lite/CampYamlLiteTest.java | 2 - .../rest/resources/ApplicationResource.java | 9 +- 19 files changed, 352 insertions(+), 152 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java index 75c727a..1b5d381 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java @@ -301,7 +301,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { if (loadedItem == null) throw new RuntimeException(item+" not in catalog; cannot create spec"); if (loadedItem.getSpecType()==null) return null; - SpecT spec = internalCreateSpecLegacy(mgmt, loadedItem, MutableSet.<String>of(), false); + SpecT spec = internalCreateSpecLegacy(mgmt, loadedItem, MutableSet.<String>of(), true); if (spec != null) { return spec; } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java index b5c85c1..1bc4a9f 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java @@ -148,7 +148,7 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry { throw new IllegalStateException("should have failed getting type resolution for "+type); } catch (Exception e0) { // prefer older exception, until the new transformer is the primary pathway - throw Exceptions.create("Unable to instantiate "+type, MutableList.of(e, e0)); + throw Exceptions.create("Unable to instantiate "+type, MutableList.of(e0, e)); } } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypeLoadingContexts.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypeLoadingContexts.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypeLoadingContexts.java index 22ea294..594bdfd 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypeLoadingContexts.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypeLoadingContexts.java @@ -134,8 +134,9 @@ public class RegisteredTypeLoadingContexts { BasicRegisteredTypeLoadingContext constraint = new BasicRegisteredTypeLoadingContext(source); if (source==null) source = constraint; if (superType==null) return source; + constraint.expectedSuperType = superType; if (source.getExpectedJavaSuperType()==null || source.getExpectedJavaSuperType().isAssignableFrom( superType )) { - // the constraint was weaker than present; return the new constraint + // the old constraint was weaker than present; return the new constraint return constraint; } if (superType.isAssignableFrom( source.getExpectedJavaSuperType() )) { @@ -153,8 +154,9 @@ public class RegisteredTypeLoadingContexts { BasicRegisteredTypeLoadingContext constraint = new BasicRegisteredTypeLoadingContext(source); if (source==null) source = constraint; if (superType==null) return source; + constraint.expectedSuperType = superType; if (source.getExpectedJavaSuperType()==null || source.getExpectedJavaSuperType().isAssignableFrom( superType )) { - // the constraint was weaker than present; return the new constraint + // the old constraint was weaker than present; return the new constraint return constraint; } if (superType.isAssignableFrom( source.getExpectedJavaSuperType() )) { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java index a4a0460..1e48e46 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java @@ -21,6 +21,7 @@ package org.apache.brooklyn.core.typereg; import java.lang.reflect.Method; import java.util.Iterator; import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; @@ -112,11 +113,11 @@ public class RegisteredTypes { * @param mgmt */ @Beta // TODO should this be on the AbstractTypePlanTransformer ? - public static Class<?> loadActualJavaType(String javaTypeName, ManagementContext mgmt, RegisteredType type, RegisteredTypeLoadingContext constraint) throws Exception { + public static Class<?> loadActualJavaType(String javaTypeName, ManagementContext mgmt, RegisteredType type, RegisteredTypeLoadingContext context) throws Exception { Class<?> result = ((BasicRegisteredType)type).getCache().get(ACTUAL_JAVA_TYPE); if (result!=null) return result; - result = CatalogUtils.newClassLoadingContext(mgmt, type).loadClass( javaTypeName ); + result = CatalogUtils.newClassLoadingContext(mgmt, type, context==null ? null : context.getLoader()).loadClass( javaTypeName ); Preconditions.checkNotNull(result, "Could not load class "+javaTypeName+"; returned null (should have thrown a different exception!)"); ((BasicRegisteredType)type).getCache().put(ACTUAL_JAVA_TYPE, result); @@ -178,7 +179,7 @@ public class RegisteredTypes { Iterator<Object> ri = result.iterator(); if (!ri.hasNext()) return Maybe.absent("YAML has no elements in it"); Object r1 = ri.next(); - if (!ri.hasNext()) return Maybe.absent("YAML has multiple elements in it"); + if (ri.hasNext()) return Maybe.absent("YAML has multiple elements in it"); if (r1 instanceof Map) return Maybe.of((Map<Object,Object>)r1); return Maybe.absent("YAML does not contain a map"); } @@ -187,12 +188,19 @@ public class RegisteredTypes { * Queries recursively the supertypes of {@link RegisteredType} to see whether it * declares a supertype compatible with the given {@link Class} */ public static boolean isSubTypeOf(RegisteredType type, Class<?> superType) { - for (Object st: type.getSuperTypes()) { + return isSubTypeOf(type.getSuperTypes(), superType); + } + + /** + * Queries recursively the given types (either {@link Class} or {@link RegisteredType}) + * to see whether any are compatible with the given {@link Class} */ + public static boolean isSubTypeOf(Set<Object> allKnownTypes, Class<?> superType) { + for (Object st: allKnownTypes) { if (st instanceof Class) { if (superType.isAssignableFrom((Class<?>)st)) return true; } } - for (Object st: type.getSuperTypes()) { + for (Object st: allKnownTypes) { if (st instanceof RegisteredType) { if (isSubTypeOf((RegisteredType)st, superType)) return true; } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/core/src/test/java/brooklyn/policy/basic/AbstractEntityAdjunctTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/brooklyn/policy/basic/AbstractEntityAdjunctTest.java b/core/src/test/java/brooklyn/policy/basic/AbstractEntityAdjunctTest.java deleted file mode 100644 index d6d41de..0000000 --- a/core/src/test/java/brooklyn/policy/basic/AbstractEntityAdjunctTest.java +++ /dev/null @@ -1,52 +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 brooklyn.policy.basic; - -import java.util.Map; - -import org.apache.brooklyn.api.mgmt.rebind.RebindSupport; -import org.apache.brooklyn.core.objs.AbstractEntityAdjunct; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableMap; - -public class AbstractEntityAdjunctTest { - private static class TestAdjunct extends AbstractEntityAdjunct { - public TestAdjunct(Map<?, ?> properties) { - super(properties); - } - - @Override - public RebindSupport<?> getRebindSupport() { - return null; - } - - @Override - protected void onChanged() { - } - } - - @Test - public void testImmutableFlags() { - //shouldn't try to mutate passed flags map (or previous references to it) - TestAdjunct testAdjunct = new TestAdjunct(ImmutableMap.of("unusedKey", "unusedValue")); - testAdjunct.configure(ImmutableMap.of("finalKey", "finalValue")); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/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 index 2f50c47..5437765 100644 --- 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 @@ -27,15 +27,21 @@ 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.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.objs.SpecParameter; +import org.apache.brooklyn.api.typereg.RegisteredType; +import org.apache.brooklyn.core.plan.PlanToSpecFactory; 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.Assert; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; import com.google.common.reflect.TypeToken; @@ -43,18 +49,40 @@ import com.google.common.reflect.TypeToken; public class SpecParameterInMetaTest { private ManagementContext mgmt; private BrooklynCatalog catalog; - private String spec; + private String specId; @BeforeMethod(alwaysRun=true) public void setUp() { mgmt = LocalManagementContextForTests.newInstanceWithOsgi(); catalog = mgmt.getCatalog(); - spec = TestToSpecTransformer.registerSpec(EntitySpec.create(BasicEntity.class)); + StaticTypePlanTransformer.forceInstall(); + PlanToSpecFactory.forceAvailable(TestToSpecTransformer.class, JavaCatalogToSpecTransformer.class); + specId = StaticTypePlanTransformer.registerSpec(EntitySpec.create(BasicEntity.class)); } + @AfterMethod(alwaysRun=true) + public void tearDown() { + StaticTypePlanTransformer.clearForced(); + PlanToSpecFactory.clearForced(); + } + + @Test + public void testCanRetrieveWithNew() { + AbstractBrooklynObjectSpec<?, ?> spec = mgmt.getTypeRegistry().createSpecFromPlan(null, specId, null, null); + Assert.assertNotNull(spec); + } + + // it's not actually added to the catalog; probably it would be cleaner if it is; + // but for now when we resolve in PlanToSpecFactory we make explicit reference to StaticTypePlanTransformer +// @Test +// public void testCanLookupNew() { +// RegisteredType type = mgmt.getTypeRegistry().get(specId); +// Assert.assertNotNull(type); +// } + @Test public void testYamlInputsParsed() { - CatalogItem<?, ?> item = add( + String itemId = add( "brooklyn.catalog:", " id: test.inputs", " version: 0.0.1", @@ -63,7 +91,9 @@ public class SpecParameterInMetaTest { " - name: explicit_name", " - name: third_input", " type: integer", - " item: " + spec); + " item: " + specId); + + EntitySpec<?> item = mgmt.getTypeRegistry().createSpec(mgmt.getTypeRegistry().get(itemId), null, EntitySpec.class); List<SpecParameter<?>> inputs = item.getParameters(); assertEquals(inputs.size(), 3); SpecParameter<?> firstInput = inputs.get(0); @@ -89,7 +119,7 @@ public class SpecParameterInMetaTest { public void testOsgiType() { TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH); - CatalogItem<?, ?> item = add( + String itemId = add( "brooklyn.catalog:", " id: test.inputs", " version: 0.0.1", @@ -98,7 +128,8 @@ public class SpecParameterInMetaTest { " parameters:", " - name: simple", " type: " + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY, - " item: " + spec); + " item: " + specId); + EntitySpec<?> item = mgmt.getTypeRegistry().createSpec(mgmt.getTypeRegistry().get(itemId), null, EntitySpec.class); List<SpecParameter<?>> inputs = item.getParameters(); assertEquals(inputs.size(), 1); SpecParameter<?> firstInput = inputs.get(0); @@ -110,6 +141,7 @@ public class SpecParameterInMetaTest { @Test public void testOsgiClassScanned() { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH); TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH); addMulti("brooklyn.catalog:", @@ -117,23 +149,32 @@ public class SpecParameterInMetaTest { " - scanJavaAnnotations: true", " version: 2.0.test_java", " libraries:", + " - classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH, " - 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); + RegisteredType itemT = mgmt.getTypeRegistry().get(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY); + assertEquals(itemT.getVersion(), "2.0.test_java"); + assertEquals(itemT.getLibraries().size(), 2); + + EntitySpec<?> item = mgmt.getTypeRegistry().createSpec(itemT, null, EntitySpec.class); 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) { + private String add(String... def) { return Iterables.getOnlyElement(addMulti(def)); } - private Iterable<? extends CatalogItem<?, ?>> addMulti(String... def) { - return catalog.addItems(Joiner.on('\n').join(def)); + private Iterable<String> addMulti(String... def) { + return Iterables.transform(catalog.addItems(Joiner.on('\n').join(def)), + new Function<CatalogItem<?,?>, String>() { + @Override + public String apply(CatalogItem<?, ?> input) { + return input.getId(); + } + }); } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/core/src/test/java/org/apache/brooklyn/core/catalog/internal/StaticTypePlanTransformer.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/StaticTypePlanTransformer.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/StaticTypePlanTransformer.java new file mode 100644 index 0000000..c5568ca --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/StaticTypePlanTransformer.java @@ -0,0 +1,115 @@ +/* + * 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 java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; +import org.apache.brooklyn.api.typereg.RegisteredType; +import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext; +import org.apache.brooklyn.core.typereg.AbstractTypePlanTransformer; +import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer; +import org.apache.brooklyn.core.typereg.TypePlanTransformers; +import org.apache.brooklyn.util.text.Identifiers; + +/** + * Resolves previously registered specs by id. + * First create a spec and register it, keeping the returned ID: + * <pre> {@code + * String specId = StaticTypePlanTransformer.registerSpec(EntitySpec.create(BasicEntity.class)); + * }</pre> + * + * Then build a plan to be resolved such as: + * <pre> {@code + * brooklyn.catalog: + * id: test.inputs + * version: 0.0.1 + * item: <specId> + * } </pre> + */ +public class StaticTypePlanTransformer extends AbstractTypePlanTransformer { + + public StaticTypePlanTransformer() { + super("static-types", "Static Type", "Static transformer for use in tests"); + } + + private static final Map<String, AbstractBrooklynObjectSpec<?, ?>> REGISTERED_SPECS = new ConcurrentHashMap<>(); + + public static void forceInstall() { + TypePlanTransformers.forceAvailable(StaticTypePlanTransformer.class, JavaClassNameTypePlanTransformer.class); + } + + public static void clearForced() { + TypePlanTransformers.clearForced(); + } + + public static String registerSpec(AbstractBrooklynObjectSpec<?, ?> spec) { + String id = Identifiers.makeRandomId(10); + REGISTERED_SPECS.put(id, spec); + return id; + } + + @Override + public double scoreForTypeDefinition(String formatCode, Object catalogData) { + // not supported + return 0; + } + + @Override + public List<RegisteredType> createFromTypeDefinition(String formatCode, Object catalogData) { + // not supported + return null; + } + + @Override + protected double scoreForNullFormat(Object planData, RegisteredType type, RegisteredTypeLoadingContext context) { + if (REGISTERED_SPECS.containsKey(type.getId())) return 1; + if (REGISTERED_SPECS.containsKey(planData)) return 1; + return 0; + } + + @Override + protected double scoreForNonmatchingNonnullFormat(String planFormat, Object planData, RegisteredType type, RegisteredTypeLoadingContext context) { + // not supported + return 0; + } + + @Override + protected AbstractBrooklynObjectSpec<?, ?> createSpec(RegisteredType type, RegisteredTypeLoadingContext context) throws Exception { + if (REGISTERED_SPECS.containsKey(type.getId())) + return get(type.getId()); + if (REGISTERED_SPECS.containsKey(type.getPlan().getPlanData())) + return get((String)type.getPlan().getPlanData()); + return null; + } + + @Override + protected Object createBean(RegisteredType type, RegisteredTypeLoadingContext context) throws Exception { + // not supported + return null; + } + + public static AbstractBrooklynObjectSpec<?, ?> get(String typeName) { + return REGISTERED_SPECS.get(typeName); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/core/src/test/java/org/apache/brooklyn/core/catalog/internal/TestToSpecTransformer.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/TestToSpecTransformer.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/TestToSpecTransformer.java index 0dfe291..9f9440a 100644 --- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/TestToSpecTransformer.java +++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/TestToSpecTransformer.java @@ -20,43 +20,36 @@ package org.apache.brooklyn.core.catalog.internal; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; +import org.apache.brooklyn.api.catalog.BrooklynCatalog; import org.apache.brooklyn.api.catalog.CatalogItem; 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.mgmt.ManagementContext; +import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.core.plan.PlanNotRecognizedException; import org.apache.brooklyn.core.plan.PlanToSpecTransformer; -import org.apache.brooklyn.util.text.Identifiers; +import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer; +import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts; +import org.apache.brooklyn.util.collections.MutableSet; import org.apache.brooklyn.util.yaml.Yamls; +import com.google.common.collect.Iterables; + /** - * Resolves previously registered specs by id. - * First create a spec and register it, keeping the returned ID: - * <pre> {@code - * String specId = TestToSpecTransformer.registerSpec(EntitySpec.create(BasicEntity.class)); - * }</pre> - * - * Then build a plan to be resolved such as: - * <pre> {@code - * brooklyn.catalog: - * id: test.inputs - * version: 0.0.1 - * item: <specId> - * } </pre> + * For use in conjunction with {@link StaticTypePlanTransformer}; + * this will lookup an item by ID or in a map "type: id". + * <p> + * Should be removed when catalog is able to function using new-style lookups. */ public class TestToSpecTransformer implements PlanToSpecTransformer { - private static final Map<String, AbstractBrooklynObjectSpec<?, ?>> REGISTERED_SPECS = new ConcurrentHashMap<>(); - public static String registerSpec(AbstractBrooklynObjectSpec<?, ?> spec) { - String id = Identifiers.makeRandomId(10); - REGISTERED_SPECS.put(id, spec); - return id; - } + + private ManagementContext mgmt; @Override public void injectManagementContext(ManagementContext managementContext) { + mgmt = managementContext; } @Override @@ -72,47 +65,56 @@ public class TestToSpecTransformer implements PlanToSpecTransformer { @SuppressWarnings("unchecked") @Override public EntitySpec<? extends Application> createApplicationSpec(String plan) throws PlanNotRecognizedException { - return (EntitySpec<? extends Application>) getSpec(plan); + return (EntitySpec<? extends Application>) getSpec(plan, null, MutableSet.<String>of()); } @SuppressWarnings("unchecked") @Override public <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(CatalogItem<T, SpecT> item, Set<String> encounteredTypes) throws PlanNotRecognizedException { - return (SpecT) getSpecFromPlan(item.getPlanYaml()); + return (SpecT) getSpecFromPlan(item.getPlanYaml(), item, encounteredTypes); } - private AbstractBrooklynObjectSpec<?,?> getSpecFromPlan(String plan) { + @SuppressWarnings("unchecked") + private AbstractBrooklynObjectSpec<?,?> getSpecFromPlan(String plan, CatalogItem<?,?> item, Set<String> encounteredTypes) { if (plan != null) { Object planRaw = Yamls.parseAll(plan).iterator().next(); if (planRaw instanceof String) { - return getSpec((String)planRaw); + return getSpec((String)planRaw, item, encounteredTypes); } else if (planRaw instanceof Map) { // The catalog parser assumes it's dealing with CAMP specs so will helpfully // prepend "type: " if it's an inline item. - return getSpec((String)((Map<?, ?>)planRaw).get("type")); - } else { - throw notRecognized(); + Map<?, ?> planMap = (Map<?, ?>)planRaw; + if (planMap.size()==1 && planMap.containsKey("services")) { + planMap = Iterables.getOnlyElement( (Iterable<Map<?,?>>)(planMap.get("services")) ); + } + if (planMap.size()==1 && planMap.containsKey("type")) + return getSpec((String)(planMap.get("type")), item, encounteredTypes); } - } else { - throw notRecognized(); } + throw notRecognized("unknown format "+plan); } - private AbstractBrooklynObjectSpec<?,?> getSpec(String plan) { - if (plan == null) { - throw notRecognized(); + private AbstractBrooklynObjectSpec<?,?> getSpec(String typeName, CatalogItem<?,?> item, Set<String> encounteredTypes) { + if (typeName == null) { + throw notRecognized("null type "+typeName); } - AbstractBrooklynObjectSpec<?, ?> spec = REGISTERED_SPECS.get(plan); - if (spec != null) { - return spec; - } else { - throw notRecognized(); + + RegisteredType type = mgmt.getTypeRegistry().get(typeName); + if (type==null) { + AbstractBrooklynObjectSpec<?,?> spec = StaticTypePlanTransformer.get(typeName); + if (spec!=null) return spec; + + throw notRecognized("no type "+typeName); } + + return mgmt.getTypeRegistry().createSpecFromPlan( + JavaClassNameTypePlanTransformer.FORMAT, + typeName, RegisteredTypeLoadingContexts.loader(CatalogUtils.newClassLoadingContext(mgmt, item)), null); } - private PlanNotRecognizedException notRecognized() { - return new PlanNotRecognizedException("Not recognized as registered spec"); + private PlanNotRecognizedException notRecognized(String message) { + return new PlanNotRecognizedException("Not recognized as registered spec: "+message); } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/core/src/test/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunctTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunctTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunctTest.java new file mode 100644 index 0000000..73b9d2d --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunctTest.java @@ -0,0 +1,52 @@ +/* + * 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 java.util.Map; + +import org.apache.brooklyn.api.mgmt.rebind.RebindSupport; +import org.apache.brooklyn.core.objs.AbstractEntityAdjunct; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; + +public class AbstractEntityAdjunctTest { + private static class TestAdjunct extends AbstractEntityAdjunct { + public TestAdjunct(Map<?, ?> properties) { + super(properties); + } + + @Override + public RebindSupport<?> getRebindSupport() { + return null; + } + + @Override + protected void onChanged() { + } + } + + @Test + public void testImmutableFlags() { + //shouldn't try to mutate passed flags map (or previous references to it) + TestAdjunct testAdjunct = new TestAdjunct(ImmutableMap.of("unusedKey", "unusedValue")); + testAdjunct.configure(ImmutableMap.of("finalKey", "finalValue")); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/core/src/test/resources/META-INF/services/org.apache.brooklyn.core.plan.PlanToSpecTransformer ---------------------------------------------------------------------- diff --git a/core/src/test/resources/META-INF/services/org.apache.brooklyn.core.plan.PlanToSpecTransformer b/core/src/test/resources/META-INF/services/org.apache.brooklyn.core.plan.PlanToSpecTransformer deleted file mode 100644 index 34d91b4..0000000 --- a/core/src/test/resources/META-INF/services/org.apache.brooklyn.core.plan.PlanToSpecTransformer +++ /dev/null @@ -1,19 +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. -# -org.apache.brooklyn.core.catalog.internal.TestToSpecTransformer http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/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 32f7c0e..706d6f2 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 @@ -30,7 +30,7 @@ import org.apache.brooklyn.core.typereg.RegisteredTypes; public class CampCatalogUtils { public static AbstractBrooklynObjectSpec<?, ?> createSpec(ManagementContext mgmt, CatalogItem<?, ?> item, Set<String> parentEncounteredTypes) { - return CampResolver.createSpecFromFull(mgmt, RegisteredTypes.of(item), parentEncounteredTypes, null); + return CampResolver.createSpecFromFull(mgmt, RegisteredTypes.of(item), item.getCatalogItemJavaType(), parentEncounteredTypes, null); } public static CampPlatform getCampPlatform(ManagementContext mgmt) { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampResolver.java index 3070280..e6c514a 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampResolver.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampResolver.java @@ -37,6 +37,7 @@ import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator; import org.apache.brooklyn.core.catalog.internal.CatalogUtils; import org.apache.brooklyn.core.mgmt.EntityManagementUtils; import org.apache.brooklyn.core.typereg.RegisteredTypes; +import org.apache.brooklyn.util.collections.MutableSet; import org.apache.brooklyn.util.text.Strings; import com.google.common.collect.ImmutableSet; @@ -72,10 +73,10 @@ class CampResolver { // TODO new-style approach: // AbstractBrooklynObjectSpec<?, ?> spec = RegisteredTypes.newSpecInstance(mgmt, /* 'type' key */); // spec.configure(keysAndValues); - return createSpecFromFull(mgmt, type, context.getAlreadyEncounteredTypes(), context.getLoader()); + return createSpecFromFull(mgmt, type, context.getExpectedJavaSuperType(), context.getAlreadyEncounteredTypes(), context.getLoader()); } - static AbstractBrooklynObjectSpec<?, ?> createSpecFromFull(ManagementContext mgmt, RegisteredType item, Set<String> parentEncounteredTypes, BrooklynClassLoadingContext loaderO) { + static AbstractBrooklynObjectSpec<?, ?> createSpecFromFull(ManagementContext mgmt, RegisteredType item, Class<?> expectedType, Set<String> parentEncounteredTypes, BrooklynClassLoadingContext loaderO) { // for this method, a prefix "services" or "brooklyn.{location,policies}" is required at the root; // we now prefer items to come in "{ type: .. }" format, except for application roots which // should have a "services: [ ... ]" block (and which may subsequently be unwrapped) @@ -94,13 +95,15 @@ class CampResolver { AbstractBrooklynObjectSpec<?, ?> spec; String planYaml = RegisteredTypes.getImplementationDataStringForSpec(item); - if (RegisteredTypes.isSubTypeOf(item, Policy.class)) { + MutableSet<Object> supers = MutableSet.copyOf(item.getSuperTypes()); + supers.addIfNotNull(expectedType); + if (RegisteredTypes.isSubTypeOf(supers, Policy.class)) { spec = CampInternalUtils.createPolicySpec(planYaml, loader, encounteredTypes); - } else if (RegisteredTypes.isSubTypeOf(item, Location.class)) { + } else if (RegisteredTypes.isSubTypeOf(supers, Location.class)) { spec = CampInternalUtils.createLocationSpec(planYaml, loader, encounteredTypes); - } else if (RegisteredTypes.isSubTypeOf(item, Application.class)) { + } else if (RegisteredTypes.isSubTypeOf(supers, Application.class)) { spec = createEntitySpecFromServicesBlock(planYaml, loader, encounteredTypes, true); - } else if (RegisteredTypes.isSubTypeOf(item, Entity.class)) { + } else if (RegisteredTypes.isSubTypeOf(supers, Entity.class)) { spec = createEntitySpecFromServicesBlock(planYaml, loader, encounteredTypes, false); } else { // try any of them??? @@ -123,9 +126,9 @@ class CampResolver { AssemblyTemplateInstantiator instantiator = CampInternalUtils.getInstantiator(at); if (instantiator instanceof AssemblyTemplateSpecInstantiator) { EntitySpec<? extends Application> appSpec = ((AssemblyTemplateSpecInstantiator)instantiator).createApplicationSpec(at, camp, loader, encounteredTypes); - CampInternalUtils.resetSpecIfTemplateHasNoExplicitParameters(at, appSpec); if (!isApplication && EntityManagementUtils.canPromoteChildrenInWrappedApplication(appSpec) && appSpec.getChildren().size()==1) { + CampInternalUtils.resetSpecIfTemplateHasNoExplicitParameters(at, appSpec); EntitySpec<?> childSpec = appSpec.getChildren().get(0); EntityManagementUtils.mergeWrapperParentSpecToChildEntity(appSpec, childSpec); return childSpec; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java index f2b224c..a1c8150 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java @@ -99,7 +99,7 @@ public class CampToSpecTransformer implements PlanToSpecTransformer { } // Not really clear what should happen to the top-level attributes, ignored until a good use case appears. - return (SpecT) CampResolver.createSpecFromFull(mgmt, RegisteredTypes.of(item), encounteredTypes, null); + return (SpecT) CampResolver.createSpecFromFull(mgmt, RegisteredTypes.of(item), item.getCatalogItemJavaType(), encounteredTypes, null); } @Override http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampTypePlanTransformer.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampTypePlanTransformer.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampTypePlanTransformer.java index 4793a59..56eeb99 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampTypePlanTransformer.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampTypePlanTransformer.java @@ -48,6 +48,10 @@ public class CampTypePlanTransformer extends AbstractTypePlanTransformer { Maybe<Map<Object, Object>> plan = RegisteredTypes.getAsYamlMap(planData); if (plan.isAbsent()) return 0; if (plan.get().containsKey("services")) return 0.8; + if (plan.get().containsKey("type")) return 0.4; + // TODO these should become legacy + if (plan.get().containsKey("brooklyn.locations")) return 0.7; + if (plan.get().containsKey("brooklyn.policies")) return 0.7; return 0; } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/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 3799418..c87626c 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 @@ -65,7 +65,7 @@ public class UrlServiceSpecResolver implements EntitySpecResolver { } // Referenced specs are expected to be CAMP format as well. - // XXX somehow specify to allow full syntax for services + // TODO somehow specify to allow full syntax for services EntitySpec<?> item = loader.getManagementContext().getTypeRegistry().createSpecFromPlan( CampTypePlanTransformer.FORMAT, yaml, http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java index b046a70..269ff16 100644 --- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java @@ -162,7 +162,7 @@ public class LocationsYamlTest extends AbstractYamlTest { try { createStartWaitAndLogApplication(new StringReader(yaml)); - } catch (IllegalStateException e) { + } catch (Exception e) { if (!e.toString().contains("Conflicting 'location' and 'locations'")) throw e; } } @@ -178,7 +178,7 @@ public class LocationsYamlTest extends AbstractYamlTest { try { createStartWaitAndLogApplication(new StringReader(yaml)); - } catch (IllegalStateException e) { + } catch (Exception e) { if (!e.toString().contains("must be a string or map")) throw e; } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogParametersTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogParametersTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogParametersTest.java index 6407d4a..010e42d 100644 --- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogParametersTest.java +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogParametersTest.java @@ -273,7 +273,54 @@ public class CatalogParametersTest extends AbstractYamlTest { } @Test - public void testParametersCoercedOnSetAndReferences() throws Exception { + public void testParametersOnItemCoercedOnSetAndReferences() throws Exception { + Integer testValue = Integer.valueOf(55); + addCatalogItems( + "brooklyn.catalog:", + " id: " + SYMBOLIC_NAME, + " version: " + TEST_VERSION, + " item:", + " type: " + BasicApplication.class.getName(), + " brooklyn.parameters:", + " - name: num", + " type: integer", + " brooklyn.children:", + " - type: " + ConfigEntityForTest.class.getName(), + " brooklyn.config:", + " refConfig: $brooklyn:scopeRoot().config(\"num\")", + " - type: " + ConfigEntityForTest.class.getName(), + " brooklyn.config:", + " refConfig: $brooklyn:config(\"num\")"); //inherited config + + Entity app = createAndStartApplication( + "services:", + "- type: " + BasicApplication.class.getName(), + " brooklyn.children:", + " - type: " + ver(SYMBOLIC_NAME), + " brooklyn.config:", + " num: \"" + testValue + "\""); + + Entity scopeRoot = Iterables.getOnlyElement(app.getChildren()); + + ConfigKey<Object> numKey = ConfigKeys.newConfigKey(Object.class, "num"); + assertEquals(scopeRoot.config().get(numKey), testValue); + + ConfigKey<Object> refConfigKey = ConfigKeys.newConfigKey(Object.class, "refConfig"); + + Iterator<Entity> childIter = scopeRoot.getChildren().iterator(); + Entity c1 = childIter.next(); + assertEquals(c1.config().get(refConfigKey), testValue); + Entity c2 = childIter.next(); + assertEquals(c2.config().get(refConfigKey), testValue); + assertFalse(childIter.hasNext()); + } + + // XXX TODO parameters on the root don't work with new type registry; + // they require the CI being able to keep them, + // or else modifying the plan. TODO should they be permitted as metadata in this way? + // or treaded like a declaration of config keys on the entity? i (alex) prefer the latter. + @Test(groups="WIP") + public void testParametersAtRootCoercedOnSetAndReferences() throws Exception { Integer testValue = Integer.valueOf(55); addCatalogItems( "brooklyn.catalog:", http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java index 93507aa..1558db3 100644 --- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java +++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java @@ -30,11 +30,9 @@ import java.util.Map; import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle; -import org.apache.brooklyn.api.entity.Application; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.mgmt.Task; -import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry; import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl; import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.camp.spi.Assembly; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c712ad5e/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java index a0c5d8f..c22082b 100644 --- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java +++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java @@ -45,7 +45,6 @@ import org.apache.brooklyn.api.mgmt.Task; import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.api.sensor.AttributeSensor; import org.apache.brooklyn.api.sensor.Sensor; -import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind; import org.apache.brooklyn.core.config.ConstraintViolationException; import org.apache.brooklyn.core.entity.Attributes; import org.apache.brooklyn.core.entity.EntityPredicates; @@ -372,14 +371,14 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements private EntitySpec<? extends Application> createEntitySpecForApplication(String potentialYaml) { try { return EntityManagementUtils.createEntitySpecForApplication(mgmt(), potentialYaml); - } catch (IllegalStateException e) { - // An IllegalArgumentException for creating the entity spec gets wrapped in a ISE. + } catch (Exception e) { + // An IllegalArgumentException for creating the entity spec gets wrapped in a ISE, and possibly a Compound. // But we want to return a 400 rather than 500, so ensure we throw IAE. - IllegalArgumentException iae = (IllegalArgumentException) Exceptions.getFirstThrowableOfType(e.getCause(), IllegalArgumentException.class); + IllegalArgumentException iae = (IllegalArgumentException) Exceptions.getFirstThrowableOfType(e, IllegalArgumentException.class); if (iae != null) { throw new IllegalArgumentException("Cannot create spec for app: "+iae.getMessage(), e); } else { - throw e; + throw Exceptions.propagate(e); } } }
