This closes #760. Makes YAML pluggable. I've done effectively a rebase-resolve-squash on the commits from that PR. Doing a formal rebase was very hard due to all the conflicts.
This uses a ServiceLoader to get CAMP stuff, with a list of transformers supported. For the record the commit log of #760, squashed here, is: > commit f7067c2c10942cfea15ecbe0cb4e8e31e8fb6cde > Author: Svetoslav Neykov <[email protected]> > Date: Tue Jul 21 17:25:15 2015 +0300 > > Use plugins to parse yaml plans > > Move all CAMP related code to a CAMP implementation of the plugin. > > commit c9db2547e1fd0e16b23cb09f04f4cffe6db01ad8 > Author: Svetoslav Neykov <[email protected]> > Date: Tue Jul 21 15:01:51 2015 +0300 > > Decrease API surface in CampCatalogUtils > > commit 4e24d5f93d250dbbbcf579f2a406f63e1c315798 > Author: Svetoslav Neykov <[email protected]> > Date: Tue Jul 21 13:17:42 2015 +0300 > > Deduplicate code > > commit a953e059066aa53323db0ed027366a4b5994ecfc > Author: Svetoslav Neykov <[email protected]> > Date: Mon Jul 20 18:55:18 2015 +0300 > > Move all CAMP-related code to a single place - brooklyn-launcher > > Use existing utils methods wrapping CAMP calls - in EntityManagementUtils. > > commit dc4b37f6c07337171b61ab25beb9bcea617d9452 > Author: Svetoslav Neykov <[email protected]> > Date: Mon Jul 20 16:36:32 2015 +0300 > > Move all CAMP-related code to a single place - brooklyn-rest-server > > Use existing utils methods wrapping CAMP calls - in EntityManagementUtils. > > commit 3b8bc66c35ba84db158f2018b967bf501f5811c8 > Author: Svetoslav Neykov <[email protected]> > Date: Mon Jul 20 16:02:36 2015 +0300 > > Move all CAMP-related code to a single place - brooklyn-core > > EntityManagementUtils and CampCatalogUtils interface to the CAMP parser > now. > Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/6ed695e5 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/6ed695e5 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/6ed695e5 Branch: refs/heads/master Commit: 6ed695e51bfda4478187d4a12ab28149caa4914c Parents: 0f6041e Author: Alex Heneveld <[email protected]> Authored: Wed Aug 19 11:02:12 2015 +0100 Committer: Alex Heneveld <[email protected]> Committed: Wed Aug 19 13:48:36 2015 +0100 ---------------------------------------------------------------------- core/pom.xml | 16 +- .../api/AssemblyTemplateSpecInstantiator.java | 35 --- .../catalog/internal/BasicBrooklynCatalog.java | 243 +++--------------- .../core/mgmt/EntityManagementUtils.java | 200 ++++++--------- .../core/plan/PlanNotRecognizedException.java | 40 +++ .../brooklyn/core/plan/PlanToSpecFactory.java | 46 ++++ .../core/plan/PlanToSpecTransformer.java | 35 +++ .../core/server/BrooklynServerConfig.java | 14 - .../core/mgmt/rebind/RebindCatalogItemTest.java | 93 ++++--- ...talogWhenCatalogPersistenceDisabledTest.java | 8 +- .../lite/CampPlatformWithJustBrooklynMgmt.java | 41 --- .../camp/brooklyn/lite/CampYamlLiteTest.java | 255 ------------------- .../camp/brooklyn/lite/TestAppAssembly.java | 36 --- .../lite/TestAppAssemblyInstantiator.java | 90 ------- .../lite/test-app-service-blueprint.yaml | 38 --- usage/camp/pom.xml | 12 + .../camp/brooklyn/BrooklynCampConstants.java | 3 +- .../api/AssemblyTemplateSpecInstantiator.java | 35 +++ .../BrooklynAssemblyTemplateInstantiator.java | 51 ++-- .../BrooklynComponentTemplateResolver.java | 12 +- .../brooklyn/spi/creation/CampCatalogUtils.java | 244 ++++++++++++++++++ .../spi/creation/CampToSpecTransformer.java | 91 +++++++ ...che.brooklyn.core.plan.PlanToSpecTransformer | 19 ++ .../brooklyn/catalog/CatalogYamlCombiTest.java | 7 +- .../lite/CampPlatformWithJustBrooklynMgmt.java | 41 +++ .../brooklyn/test/lite/CampYamlLiteTest.java | 254 ++++++++++++++++++ .../brooklyn/test/lite/TestAppAssembly.java | 36 +++ .../test/lite/TestAppAssemblyInstantiator.java | 90 +++++++ .../test/lite/test-app-service-blueprint.yaml | 38 +++ .../brooklyn/launcher/BrooklynLauncher.java | 46 +--- .../resources/AbstractBrooklynRestResource.java | 4 - .../rest/resources/ApplicationResource.java | 83 +++--- 32 files changed, 1252 insertions(+), 1004 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/pom.xml ---------------------------------------------------------------------- diff --git a/core/pom.xml b/core/pom.xml index 1c8565a..f38b995 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -54,18 +54,6 @@ <version>${project.version}</version> </dependency> <dependency> - <groupId>org.apache.brooklyn.camp</groupId> - <artifactId>camp-base</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.apache.brooklyn.camp</groupId> - <artifactId>camp-base</artifactId> - <version>${project.version}</version> - <classifier>tests</classifier> - <scope>test</scope> - </dependency> - <dependency> <groupId>io.cloudsoft.windows</groupId> <artifactId>winrm4j</artifactId> <version>${winrm4j.version}</version> @@ -172,6 +160,10 @@ <groupId>com.maxmind.geoip2</groupId> <artifactId>geoip2</artifactId> </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> <dependency> <groupId>org.testng</groupId> http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java b/core/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java deleted file mode 100644 index c345a9d..0000000 --- a/core/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java +++ /dev/null @@ -1,35 +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.camp.brooklyn.api; - -import java.util.Set; - -import org.apache.brooklyn.api.entity.EntitySpec; -import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; -import org.apache.brooklyn.camp.CampPlatform; -import org.apache.brooklyn.camp.spi.AssemblyTemplate; -import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator; - -public interface AssemblyTemplateSpecInstantiator extends AssemblyTemplateInstantiator { - - EntitySpec<?> createSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext loader, boolean autoUnwrapIfAppropriate); - EntitySpec<?> createNestedSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext itemLoader, Set<String> encounteredCatalogTypes); - - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/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 4fd7878..23d37ba 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 @@ -30,27 +30,19 @@ import java.util.Set; import javax.annotation.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.yaml.snakeyaml.Yaml; import org.apache.brooklyn.api.catalog.BrooklynCatalog; import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle; import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType; -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.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; -import org.apache.brooklyn.camp.CampPlatform; -import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator; -import org.apache.brooklyn.camp.spi.AssemblyTemplate; -import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator; -import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan; import org.apache.brooklyn.core.catalog.CatalogPredicates; import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes; +import org.apache.brooklyn.core.mgmt.EntityManagementUtils; import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.core.objs.BrooklynObjectInternal.ConfigurationSupportInternal; import org.apache.brooklyn.core.server.BrooklynServerConfig; @@ -64,12 +56,14 @@ import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.javalang.AggregateClassLoader; import org.apache.brooklyn.util.javalang.LoadedClassLoader; import org.apache.brooklyn.util.javalang.Reflections; -import org.apache.brooklyn.util.stream.Streams; import org.apache.brooklyn.util.text.Strings; import org.apache.brooklyn.util.time.Duration; import org.apache.brooklyn.util.time.Time; import org.apache.brooklyn.util.yaml.Yamls; import org.apache.brooklyn.util.yaml.Yamls.YamlExtract; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; import com.google.common.base.Function; import com.google.common.base.Preconditions; @@ -84,8 +78,8 @@ import com.google.common.collect.Iterables; /* TODO the complex tree-structured catalogs are only useful when we are relying on those separate catalog classloaders * to isolate classpaths. with osgi everything is just put into the "manual additions" catalog. */ public class BasicBrooklynCatalog implements BrooklynCatalog { - private static final String POLICIES_KEY = "brooklyn.policies"; - private static final String LOCATIONS_KEY = "brooklyn.locations"; + public static final String POLICIES_KEY = "brooklyn.policies"; + public static final String LOCATIONS_KEY = "brooklyn.locations"; public static final String NO_VERSION = "0.0.0.SNAPSHOT"; private static final Logger log = LoggerFactory.getLogger(BasicBrooklynCatalog.class); @@ -321,45 +315,20 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { } } - @SuppressWarnings("unchecked") @Override public <T, SpecT> SpecT createSpec(CatalogItem<T, SpecT> item) { if (item == null) return null; + @SuppressWarnings("unchecked") CatalogItemDo<T,SpecT> loadedItem = (CatalogItemDo<T, SpecT>) getCatalogItemDo(item.getSymbolicName(), item.getVersion()); if (loadedItem == null) throw new RuntimeException(item+" not in catalog; cannot create spec"); Class<SpecT> specType = loadedItem.getSpecType(); if (specType==null) return null; - String yaml = loadedItem.getPlanYaml(); - - if (yaml!=null) { - // preferred way is to parse the yaml, to resolve references late; - // the parsing on load is to populate some fields, but it is optional. - // TODO messy for location and policy that we need brooklyn.{locations,policies} root of the yaml, but it works; - // see related comment when the yaml is set, in addAbstractCatalogItems - // (not sure if anywhere else relies on that syntax; if not, it should be easy to fix!) - DeploymentPlan plan = makePlanFromYaml(yaml); - BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, item); - SpecT spec; - switch (item.getCatalogItemType()) { - case TEMPLATE: - case ENTITY: - spec = createEntitySpec(loadedItem.getSymbolicName(), plan, loader); - break; - case POLICY: - spec = createPolicySpec(loadedItem.getSymbolicName(), plan, loader); - break; - case LOCATION: - spec = createLocationSpec(plan, loader); - break; - default: throw new RuntimeException("Only entity, policy & location catalog items are supported. Unsupported catalog item type " + item.getCatalogItemType()); + if (loadedItem.getPlanYaml() != null) { + SpecT yamlSpec = (SpecT) EntityManagementUtils.createCatalogSpec(mgmt, loadedItem); + if (yamlSpec != null) { + return yamlSpec; } - ((AbstractBrooklynObjectSpec<?, ?>)spec).catalogItemId(item.getId()); - - if (Strings.isBlank( ((AbstractBrooklynObjectSpec<?, ?>)spec).getDisplayName() )) - ((AbstractBrooklynObjectSpec<?, ?>)spec).displayName(item.getDisplayName()); - - return spec; } // revert to legacy mechanism @@ -373,6 +342,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { } try { if (loadedItem.getJavaType()!=null) { + @SuppressWarnings("unchecked") SpecT specT = (SpecT) method.invoke(null, loadedItem.loadJavaClass(mgmt)); spec = specT; } @@ -387,154 +357,6 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { return spec; } - private <T, SpecT> SpecT createSpec(String optionalId, CatalogItemType ciType, DeploymentPlan plan, BrooklynClassLoadingContext loader) { - Preconditions.checkNotNull(ciType, "catalog item type for "+plan); - switch (ciType) { - case TEMPLATE: - case ENTITY: - return createEntitySpec(optionalId, plan, loader); - case LOCATION: return createLocationSpec(plan, loader); - case POLICY: return createPolicySpec(optionalId, plan, loader); - } - throw new IllegalStateException("Unknown CI Type "+ciType+" for "+plan); - } - - @SuppressWarnings("unchecked") - private <T, SpecT> SpecT createEntitySpec(String symbolicName, DeploymentPlan plan, BrooklynClassLoadingContext loader) { - CampPlatform camp = BrooklynServerConfig.getCampPlatform(mgmt).get(); - - // TODO should not register new AT each time we instantiate from the same plan; use some kind of cache - AssemblyTemplate at; - BrooklynLoaderTracker.setLoader(loader); - try { - at = camp.pdp().registerDeploymentPlan(plan); - } finally { - BrooklynLoaderTracker.unsetLoader(loader); - } - - try { - AssemblyTemplateInstantiator instantiator = at.getInstantiator().newInstance(); - if (instantiator instanceof AssemblyTemplateSpecInstantiator) { - return (SpecT) ((AssemblyTemplateSpecInstantiator)instantiator).createNestedSpec(at, camp, loader, - getInitialEncounteredSymbol(symbolicName)); - } - throw new IllegalStateException("Unable to instantiate YAML; incompatible instantiator "+instantiator+" for "+at); - } catch (Exception e) { - throw Exceptions.propagate(e); - } - } - - private MutableSet<String> getInitialEncounteredSymbol(String symbolicName) { - return symbolicName==null ? MutableSet.<String>of() : MutableSet.of(symbolicName); - } - - private <T, SpecT> SpecT createPolicySpec(String symbolicName, DeploymentPlan plan, BrooklynClassLoadingContext loader) { - return createPolicySpec(plan, loader, getInitialEncounteredSymbol(symbolicName)); - } - - private <T, SpecT> SpecT createPolicySpec(DeploymentPlan plan, BrooklynClassLoadingContext loader, Set<String> encounteredCatalogTypes) { - //Would ideally re-use org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityDecorationResolver.PolicySpecResolver - //but it is CAMP specific and there is no easy way to get hold of it. - Object policies = checkNotNull(plan.getCustomAttributes().get(POLICIES_KEY), "policy config"); - if (!(policies instanceof Iterable<?>)) { - throw new IllegalStateException("The value of " + POLICIES_KEY + " must be an Iterable."); - } - - Object policy = Iterables.getOnlyElement((Iterable<?>)policies); - - return createPolicySpec(loader, policy, encounteredCatalogTypes); - } - - @SuppressWarnings("unchecked") - private <T, SpecT> SpecT createPolicySpec(BrooklynClassLoadingContext loader, Object policy, Set<String> encounteredCatalogTypes) { - Map<String, Object> itemMap; - if (policy instanceof String) { - itemMap = ImmutableMap.<String, Object>of("type", policy); - } else if (policy instanceof Map) { - itemMap = (Map<String, Object>) policy; - } else { - throw new IllegalStateException("Policy expected to be string or map. Unsupported object type " + policy.getClass().getName() + " (" + policy.toString() + ")"); - } - - String versionedId = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "policy_type", "policyType", "type"), "policy type"); - PolicySpec<? extends Policy> spec; - CatalogItem<?, ?> policyItem = CatalogUtils.getCatalogItemOptionalVersion(mgmt, versionedId); - if (policyItem != null && !encounteredCatalogTypes.contains(policyItem.getSymbolicName())) { - if (policyItem.getCatalogItemType() != CatalogItemType.POLICY) { - throw new IllegalStateException("Non-policy catalog item in policy context: " + policyItem); - } - //TODO re-use createSpec - BrooklynClassLoadingContext itemLoader = CatalogUtils.newClassLoadingContext(mgmt, policyItem); - if (policyItem.getPlanYaml() != null) { - DeploymentPlan plan = makePlanFromYaml(policyItem.getPlanYaml()); - encounteredCatalogTypes.add(policyItem.getSymbolicName()); - return createPolicySpec(plan, itemLoader, encounteredCatalogTypes); - } else if (policyItem.getJavaType() != null) { - spec = PolicySpec.create((Class<Policy>)itemLoader.loadClass(policyItem.getJavaType())); - } else { - throw new IllegalStateException("Invalid policy item - neither yaml nor javaType: " + policyItem); - } - } else { - spec = PolicySpec.create(loader.loadClass(versionedId, Policy.class)); - } - Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config"); - if (brooklynConfig != null) { - spec.configure(brooklynConfig); - } - return (SpecT) spec; - } - - private <T, SpecT> SpecT createLocationSpec(DeploymentPlan plan, BrooklynClassLoadingContext loader) { - // See #createPolicySpec; this impl is modeled on that. - // spec.catalogItemId is set by caller - Object locations = checkNotNull(plan.getCustomAttributes().get(LOCATIONS_KEY), "location config"); - if (!(locations instanceof Iterable<?>)) { - throw new IllegalStateException("The value of " + LOCATIONS_KEY + " must be an Iterable."); - } - - Object location = Iterables.getOnlyElement((Iterable<?>)locations); - - return createLocationSpec(loader, location); - } - - @SuppressWarnings("unchecked") - private <T, SpecT> SpecT createLocationSpec(BrooklynClassLoadingContext loader, Object location) { - Map<String, Object> itemMap; - if (location instanceof String) { - itemMap = ImmutableMap.<String, Object>of("type", location); - } else if (location instanceof Map) { - itemMap = (Map<String, Object>) location; - } else { - throw new IllegalStateException("Location expected to be string or map. Unsupported object type " + location.getClass().getName() + " (" + location.toString() + ")"); - } - - String type = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "location_type", "locationType", "type"), "location type"); - Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config"); - Maybe<Class<? extends Location>> javaClass = loader.tryLoadClass(type, Location.class); - if (javaClass.isPresent()) { - LocationSpec<?> spec = LocationSpec.create(javaClass.get()); - if (brooklynConfig != null) { - spec.configure(brooklynConfig); - } - return (SpecT) spec; - } else { - Maybe<Location> loc = mgmt.getLocationRegistry().resolve(type, false, brooklynConfig); - if (loc.isPresent()) { - // TODO extensions? - Map<String, Object> locConfig = ((ConfigurationSupportInternal)loc.get().config()).getBag().getAllConfig(); - Class<? extends Location> locType = loc.get().getClass(); - Set<Object> locTags = loc.get().tags().getTags(); - String locDisplayName = loc.get().getDisplayName(); - return (SpecT) LocationSpec.create(locType) - .configure(locConfig) - .displayName(locDisplayName) - .tags(locTags); - } else { - throw new IllegalStateException("No class or resolver found for location type "+type); - } - } - } - @SuppressWarnings("unchecked") @Override /** @deprecated since 0.7.0 use {@link #createSpec(CatalogItem)} */ @@ -683,7 +505,6 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { else sourceYaml = new Yaml().dump(item); CatalogItemType itemType = TypeCoercions.coerce(getFirstAs(catalogMetadata, Object.class, "itemType", "item_type").orNull(), CatalogItemType.class); - BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, "<load>:0", libraryBundles); String id = getFirstAs(catalogMetadata, String.class, "id").orNull(); String version = getFirstAs(catalogMetadata, String.class, "version").orNull(); @@ -697,7 +518,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { log.warn("Name property will be ignored due to the existence of displayName and at least one of id, symbolicName"); } - PlanInterpreterGuessingType planInterpreter = new PlanInterpreterGuessingType(null, item, sourceYaml, itemType, loader, result).reconstruct(); + PlanInterpreterGuessingType planInterpreter = new PlanInterpreterGuessingType(null, item, sourceYaml, itemType, libraryBundles, result).reconstruct(); if (!planInterpreter.isResolved()) { throw Exceptions.create("Could not resolve item " + (Strings.isNonBlank(id) ? id : Strings.isNonBlank(symbolicName) ? symbolicName : Strings.isNonBlank(name) ? name : "<no-name>") @@ -785,7 +606,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { final Boolean catalogDeprecated = Boolean.valueOf(deprecated); // run again now that we know the ID - planInterpreter = new PlanInterpreterGuessingType(id, item, sourceYaml, itemType, loader, result).reconstruct(); + planInterpreter = new PlanInterpreterGuessingType(id, item, sourceYaml, itemType, libraryBundles, result).reconstruct(); if (!planInterpreter.isResolved()) { throw new IllegalStateException("Could not resolve plan once id and itemType are known (recursive reference?): "+sourceYaml); } @@ -861,19 +682,16 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { final String id; final Map<?,?> item; final String itemYaml; - final BrooklynClassLoadingContext loader; + final Collection<CatalogBundle> libraryBundles; final List<CatalogItemDtoAbstract<?, ?>> itemsDefinedSoFar; CatalogItemType catalogItemType; String planYaml; - @SuppressWarnings("unused") - DeploymentPlan plan; - AbstractBrooklynObjectSpec<?,?> spec; boolean resolved = false; List<Exception> errors = MutableList.of(); public PlanInterpreterGuessingType(@Nullable String id, Object item, String itemYaml, @Nullable CatalogItemType optionalCiType, - BrooklynClassLoadingContext loader, List<CatalogItemDtoAbstract<?,?>> itemsDefinedSoFar) { + Collection<CatalogBundle> libraryBundles, List<CatalogItemDtoAbstract<?,?>> itemsDefinedSoFar) { // ID is useful to prevent recursive references (currently for entities only) this.id = id; @@ -886,7 +704,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { this.itemYaml = itemYaml; } this.catalogItemType = optionalCiType; - this.loader = loader; + this.libraryBundles = libraryBundles; this.itemsDefinedSoFar = itemsDefinedSoFar; } @@ -964,11 +782,13 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { // then try parsing plan - this will use loader try { - DeploymentPlan candidatePlan = makePlanFromYaml(candidateYaml); - spec = createSpec(id, candidateCiType, candidatePlan, loader); + CatalogItem<?, ?> itemToAttempt = createItemBuilder(candidateCiType, getIdWithRandomDefault(), DEFAULT_VERSION) + .plan(candidateYaml) + .libraries(libraryBundles) + .build(); + Object spec = EntityManagementUtils.createCatalogSpec(mgmt, itemToAttempt); if (spec!=null) { catalogItemType = candidateCiType; - plan = candidatePlan; planYaml = candidateYaml; resolved = true; } @@ -994,8 +814,11 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { if (type!=null && key!=null) { try { String cutDownYaml = key + ":\n" + makeAsIndentedList("type: "+type); - DeploymentPlan candidatePlan = makePlanFromYaml(cutDownYaml); - Object cutdownSpec = createSpec(id, candidateCiType, candidatePlan, loader); + CatalogItem<?, ?> itemToAttempt = createItemBuilder(candidateCiType, getIdWithRandomDefault(), DEFAULT_VERSION) + .plan(cutDownYaml) + .libraries(libraryBundles) + .build(); + Object cutdownSpec = EntityManagementUtils.createCatalogSpec(mgmt, itemToAttempt); if (cutdownSpec!=null) { catalogItemType = candidateCiType; planYaml = candidateYaml; @@ -1006,9 +829,16 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { Exceptions.propagateIfFatal(e); } } + // FIXME we should lookup type in the catalog on its own, then infer the type from that, + // and give proper errors (right now e.g. if there are no transformers then we bail out + // with very little information) return false; } + + private String getIdWithRandomDefault() { + return id != null ? id : Strings.makeRandomId(10); + } public Map<?,?> getItem() { return item; } @@ -1057,11 +887,6 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { // return !isEntityPlan(plan) && plan.getCustomAttributes().containsKey(LOCATIONS_KEY); // } - private DeploymentPlan makePlanFromYaml(String yaml) { - CampPlatform camp = BrooklynServerConfig.getCampPlatform(mgmt).get(); - return camp.pdp().parseDeploymentPlan(Streams.newReaderWithContents(yaml)); - } - //------------------------ @Override http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java index d7ce547..1b150f1 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java @@ -18,29 +18,27 @@ */ package org.apache.brooklyn.core.mgmt; -import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; -import java.util.Set; +import java.util.Map; import java.util.concurrent.Callable; import javax.annotation.Nullable; +import org.apache.brooklyn.api.catalog.CatalogItem; 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.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.internal.EntityLocal; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.mgmt.Task; -import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; -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.instantiate.AssemblyTemplateInstantiator; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigKeys; -import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext; -import org.apache.brooklyn.core.server.BrooklynServerConfig; +import org.apache.brooklyn.core.plan.PlanNotRecognizedException; +import org.apache.brooklyn.core.plan.PlanToSpecFactory; +import org.apache.brooklyn.core.plan.PlanToSpecTransformer; import org.apache.brooklyn.effector.core.Effectors; import org.apache.brooklyn.entity.core.Entities; import org.apache.brooklyn.entity.core.EntityFunctions; @@ -49,17 +47,17 @@ import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.core.task.TaskBuilder; import org.apache.brooklyn.util.core.task.Tasks; -import org.apache.brooklyn.util.exceptions.Exceptions; -import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.text.Strings; import org.apache.brooklyn.util.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.annotations.Beta; +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.collect.Maps; /** Utility methods for working with entities and applications */ public class EntityManagementUtils { @@ -79,55 +77,36 @@ public class EntityManagementUtils { return app; } - /** convenience for accessing camp */ - public static Maybe<CampPlatform> getCampPlatform(ManagementContext mgmt) { - return BrooklynServerConfig.getCampPlatform(mgmt); - } - - /** as {@link #createApplication(ManagementContext, EntitySpec)} but for a YAML spec */ + /** as {@link #createUnstarted(ManagementContext, EntitySpec)} but for a YAML spec */ public static <T extends Application> T createUnstarted(ManagementContext mgmt, String yaml) { - AssemblyTemplate at = getCampPlatform(mgmt).get().pdp().registerDeploymentPlan( new StringReader(yaml) ); - return createUnstarted(mgmt, at); + EntitySpec<T> spec = createEntitySpec(mgmt, yaml); + return createUnstarted(mgmt, spec); } - /** as {@link #createApplication(ManagementContext, EntitySpec)} but for an assembly template */ - @SuppressWarnings("unchecked") - public static <T extends Application> T createUnstarted(ManagementContext mgmt, AssemblyTemplate at) { - CampPlatform camp = getCampPlatform(mgmt).get(); - AssemblyTemplateInstantiator instantiator; - try { - instantiator = at.getInstantiator().newInstance(); - } catch (Exception e) { - throw Exceptions.propagate(e); + public static <T extends Application> EntitySpec<T> createEntitySpec(ManagementContext mgmt, String yaml) { + Collection<String> types = new ArrayList<String>(); + for (PlanToSpecTransformer c : PlanToSpecFactory.all(mgmt)) { + try { + return c.createApplicationSpec(yaml); + } catch (PlanNotRecognizedException e) { + types.add(c.getName()); + } } - Assembly assembly; - if (instantiator instanceof AssemblyTemplateSpecInstantiator) { - BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt); - - EntitySpec<?> spec = ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, true); - Entity app = mgmt.getEntityManager().createEntity(spec); - Entities.startManagement((Application)app, mgmt); - return (T) app; - } else { - // currently, all brooklyn plans should produce the above; currently this will always throw Unsupported + throw new PlanNotRecognizedException("Invalid plan, tried parsing with " + types); + } + + public static AbstractBrooklynObjectSpec<?, ?> createCatalogSpec(ManagementContext mgmt, CatalogItem<?, ?> item) { + Collection<String> types = new ArrayList<String>(); + for (PlanToSpecTransformer c : PlanToSpecFactory.all(mgmt)) { try { - assembly = instantiator.instantiate(at, camp); - return (T) mgmt.getEntityManager().getEntity(assembly.getId()); - } catch (UnsupportedOperationException e) { - if (at.getPlatformComponentTemplates()==null || at.getPlatformComponentTemplates().isEmpty()) { - if (at.getCustomAttributes().containsKey("brooklyn.catalog")) - throw new IllegalArgumentException("Unrecognized application blueprint format: expected an application, not a brooklyn.catalog"); - throw new IllegalArgumentException("Unrecognized application blueprint format: no services defined"); - } - // map this (expected) error to a nicer message - throw new IllegalArgumentException("Unrecognized application blueprint format"); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - throw new IllegalArgumentException("Invalid plan: "+at, e); + return c.createCatalogSpec(item); + } catch (PlanNotRecognizedException e) { + types.add(c.getName()); } } + throw new PlanNotRecognizedException("Invalid plan, tried parsing with " + types); } - + /** container for operation which creates something and which wants to return both * the items created and any pending create/start task */ public static class CreationResult<T,U> { @@ -159,10 +138,6 @@ public class EntityManagementUtils { return start(createUnstarted(mgmt, appSpec)); } - public static CreationResult<? extends Application,Void> createStarting(ManagementContext mgmt, AssemblyTemplate at) { - return start(createUnstarted(mgmt, at)); - } - public static <T extends Application> CreationResult<T,Void> start(T app) { Task<Void> task = Entities.invokeEffector((EntityLocal)app, app, Startable.START, // locations already set in the entities themselves; @@ -180,51 +155,37 @@ public class EntityManagementUtils { /** adds entities from the given yaml, under the given parent; but does not start them */ public static List<Entity> addChildrenUnstarted(final EntityLocal parent, String yaml) { log.debug("Creating child of "+parent+" from yaml:\n{}", yaml); - + ManagementContext mgmt = parent.getApplication().getManagementContext(); - CampPlatform camp = BrooklynServerConfig.getCampPlatform(mgmt).get(); - - AssemblyTemplate at = camp.pdp().registerDeploymentPlan( new StringReader(yaml) ); - AssemblyTemplateInstantiator instantiator; - try { - instantiator = at.getInstantiator().newInstance(); - } catch (Exception e) { - throw Exceptions.propagate(e); - } - if (instantiator instanceof AssemblyTemplateSpecInstantiator) { - BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt); - EntitySpec<?> specA = ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, false); + EntitySpec<?> specA = createEntitySpec(mgmt, yaml); - // see whether we can promote children - List<EntitySpec<?>> specs = MutableList.of(); - if (hasNoNameOrCustomKeysOrRoot(at, specA)) { - // we can promote - for (EntitySpec<?> specC: specA.getChildren()) { - collapseSpec(specA, specC); - specs.add(specC); - } - } else { - // if not promoting, set a nice name if needed - if (Strings.isEmpty(specA.getDisplayName())) { - int size = specA.getChildren().size(); - String childrenCountString = size+" "+(size!=1 ? "children" : "child"); - specA.displayName("Dynamically added "+childrenCountString); - } - specs.add(specA); + // see whether we can promote children + List<EntitySpec<?>> specs = MutableList.of(); + if (canPromote(specA)) { + // we can promote + for (EntitySpec<?> specC: specA.getChildren()) { + collapseSpec(specA, specC); + specs.add(specC); } - - final List<Entity> children = MutableList.of(); - for (EntitySpec<?> spec: specs) { - Entity child = (Entity)parent.addChild(spec); - Entities.manage(child); - children.add(child); - } - - return children; } else { - throw new IllegalStateException("Spec could not be parsed to supply a compatible instantiator"); + // if not promoting, set a nice name if needed + if (Strings.isEmpty(specA.getDisplayName())) { + int size = specA.getChildren().size(); + String childrenCountString = size+" "+(size!=1 ? "children" : "child"); + specA.displayName("Dynamically added "+childrenCountString); + } + specs.add(specA); } + + final List<Entity> children = MutableList.of(); + for (EntitySpec<?> spec: specs) { + Entity child = (Entity)parent.addChild(spec); + Entities.manage(child); + children.add(child); + } + + return children; } public static CreationResult<List<Entity>,List<String>> addChildrenStarting(final EntityLocal parent, String yaml) { @@ -273,7 +234,8 @@ public class EntityManagementUtils { // NB: this clobbers child config; might prefer to deeply merge maps etc // (but this should not be surprising, as unwrapping is often parameterising the nested blueprint, so outer config should dominate) - targetToBeExpanded.configure(sourceToBeCollapsed.getConfig()); + Map<ConfigKey<?>, Object> configWithoutWrapperMarker = Maps.filterKeys(sourceToBeCollapsed.getConfig(), Predicates.not(Predicates.<ConfigKey<?>>equalTo(EntityManagementUtils.WRAPPER_APP_MARKER))); + targetToBeExpanded.configure(configWithoutWrapperMarker); targetToBeExpanded.configure(sourceToBeCollapsed.getFlags()); // TODO copying tags to all entities is not ideal; @@ -281,14 +243,26 @@ public class EntityManagementUtils { targetToBeExpanded.tags(sourceToBeCollapsed.getTags()); } - /** worker method to help determine whether child/children can be promoted */ - @Beta //where should this live long-term? - public static boolean hasNoNameOrCustomKeysOrRoot(AssemblyTemplate template, EntitySpec<?> spec) { - if (Strings.isNonEmpty(template.getName())) { + public static boolean canPromote(EntitySpec<?> spec) { + return canPromoteBasedOnName(spec) && + isWrapperApp(spec) && + //equivalent to no keys starting with "brooklyn." + spec.getEnrichers().isEmpty() && + spec.getInitializers().isEmpty() && + spec.getPolicies().isEmpty(); + } + + public static boolean isWrapperApp(EntitySpec<?> spec) { + return Boolean.TRUE.equals(spec.getConfig().get(EntityManagementUtils.WRAPPER_APP_MARKER)); + } + + private static boolean canPromoteBasedOnName(EntitySpec<?> spec) { + if (!Strings.isEmpty(spec.getDisplayName())) { if (spec.getChildren().size()==1) { String childName = Iterables.getOnlyElement(spec.getChildren()).getDisplayName(); - if (Strings.isEmpty(childName) || childName.equals(template.getName())) { + if (Strings.isEmpty(childName) || childName.equals(spec.getDisplayName())) { // if child has no name, or it's the same, could still promote + return true; } else { return false; } @@ -299,25 +273,9 @@ public class EntityManagementUtils { } else if (spec.getChildren().size()>1) { // don't allow multiple children if a name is specified as a root return false; + } else { + return true; } - - Set<String> rootAttrs = template.getCustomAttributes().keySet(); - for (String rootAttr: rootAttrs) { - if (rootAttr.equals("brooklyn.catalog") || rootAttr.equals("brooklyn.config")) { - // these do not block promotion - continue; - } - if (rootAttr.startsWith("brooklyn.")) { - // any others in 'brooklyn' namespace will block promotion - return false; - } - // location is allowed in both, and is copied on promotion - // (name also copied) - // others are root currently are ignored on promotion; they are usually metadata - // TODO might be nice to know what we are excluding - } - - return true; } - + } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java new file mode 100644 index 0000000..2551220 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java @@ -0,0 +1,40 @@ +/* + * 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.plan; + +public class PlanNotRecognizedException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public PlanNotRecognizedException() { + super(); + } + + public PlanNotRecognizedException(String message, Throwable cause) { + super(message, cause); + } + + public PlanNotRecognizedException(String message) { + super(message); + } + + public PlanNotRecognizedException(Throwable cause) { + super(cause); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java new file mode 100644 index 0000000..5d21420 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java @@ -0,0 +1,46 @@ +/* + * 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.plan; + +import java.util.Collection; +import java.util.ServiceLoader; + +import org.apache.brooklyn.api.mgmt.ManagementContext; + +import com.google.common.collect.Lists; + +public class PlanToSpecFactory { + public static PlanToSpecTransformer forMime(ManagementContext mgmt, String mime) { + Collection<PlanToSpecTransformer> transformers = all(mgmt); + for (PlanToSpecTransformer transformer : transformers) { + if (transformer.accepts(mime)) { + return transformer; + } + } + throw new IllegalStateException("PlanToSpecTransformer for type " + mime + " not found. Registered transformers are: " + transformers); + } + + public static Collection<PlanToSpecTransformer> all(ManagementContext mgmt) { + Collection<PlanToSpecTransformer> transformers = Lists.newArrayList(ServiceLoader.load(PlanToSpecTransformer.class)); + for(PlanToSpecTransformer t : transformers) { + t.injectManagementContext(mgmt); + } + return transformers; + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java new file mode 100644 index 0000000..13cd3bb --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java @@ -0,0 +1,35 @@ +/* + * 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.plan; + +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.core.mgmt.ManagementContextInjectable; + +import com.google.common.annotations.Beta; + +public interface PlanToSpecTransformer extends ManagementContextInjectable { + String getName(); + @Beta + boolean accepts(String mime); + <T extends Application> EntitySpec<T> createApplicationSpec(String plan); + AbstractBrooklynObjectSpec<?, ?> createCatalogSpec(CatalogItem<?, ?> item); +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java b/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java index 1b37281..84cdfdb 100644 --- a/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java +++ b/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java @@ -25,12 +25,10 @@ import java.net.URI; import java.util.Map; import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.camp.CampPlatform; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.config.StringConfigMap; import org.apache.brooklyn.core.catalog.internal.CatalogInitialization; import org.apache.brooklyn.core.config.ConfigKeys; -import org.apache.brooklyn.core.server.BrooklynServerConfig; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.os.Os; import org.slf4j.Logger; @@ -123,9 +121,6 @@ public class BrooklynServerConfig { public static final ConfigKey<Boolean> OSGI_CACHE_CLEAN = ConfigKeys.newBooleanConfigKey("brooklyn.osgi.cache.clean", "Whether to delete the OSGi directory before and after use; if unset, it will delete if the node ID forms part of the cache dir path (which by default it does) to avoid file leaks"); - public static final ConfigKey<CampPlatform> CAMP_PLATFORM = ConfigKeys.newConfigKey(CampPlatform.class, "brooklyn.camp.platform", - "Config set at brooklyn management platform to find the CampPlatform instance (bi-directional)"); - /** @see BrooklynServerPaths#getMgmtBaseDir(ManagementContext) */ public static String getMgmtBaseDir(ManagementContext mgmt) { return BrooklynServerPaths.getMgmtBaseDir(mgmt); @@ -173,15 +168,6 @@ public class BrooklynServerConfig { } /** - * @return the CAMP platform associated with a management context, if there is one. - */ - public static Maybe<CampPlatform> getCampPlatform(ManagementContext mgmt) { - CampPlatform result = mgmt.getConfig().getConfig(BrooklynServerConfig.CAMP_PLATFORM); - if (result!=null) return Maybe.of(result); - return Maybe.absent("No CAMP Platform is registered with this Brooklyn management context."); - } - - /** * @return {@link ManagementContext#getManagementNodeUri()}, located in this utility class for convenience. */ public static Maybe<URI> getBrooklynWebUri(ManagementContext mgmt) { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java index 37f569e..b96e5e7 100644 --- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java @@ -25,28 +25,28 @@ import static org.testng.Assert.fail; import java.io.File; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.camp.BasicCampPlatform; -import org.apache.brooklyn.camp.test.mock.web.MockWebPlatform; import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog; import org.apache.brooklyn.core.catalog.internal.CatalogDto; +import org.apache.brooklyn.core.catalog.internal.CatalogEntityItemDto; +import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder; +import org.apache.brooklyn.core.catalog.internal.CatalogLocationItemDto; +import org.apache.brooklyn.core.catalog.internal.CatalogPolicyItemDto; import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement; import org.apache.brooklyn.core.internal.BrooklynProperties; import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext; import org.apache.brooklyn.core.server.BrooklynServerConfig; -import org.apache.brooklyn.core.test.camp.brooklyn.lite.CampPlatformWithJustBrooklynMgmt; -import org.apache.brooklyn.core.test.camp.brooklyn.lite.TestAppAssemblyInstantiator; import org.apache.brooklyn.core.test.entity.TestEntity; -import org.apache.brooklyn.policy.core.AbstractPolicy; import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation; +import org.apache.brooklyn.policy.core.AbstractPolicy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; import com.google.common.base.Joiner; import com.google.common.base.Throwables; @@ -67,8 +67,6 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp { catalogPersistenceWasEnabled = BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_CATALOG_PERSISTENCE_PROPERTY); BrooklynFeatureEnablement.enable(BrooklynFeatureEnablement.FEATURE_CATALOG_PERSISTENCE_PROPERTY); super.setUp(); - BasicCampPlatform platform = new CampPlatformWithJustBrooklynMgmt(origManagementContext); - MockWebPlatform.populate(platform, TestAppAssemblyInstantiator.class); origApp.createAndManageChild(EntitySpec.create(TestEntity.class)); } @@ -110,13 +108,20 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp { @Test public void testAddAndRebindEntity() throws Exception { + String symbolicName = "rebind-yaml-catalog-item-test"; String yaml = - "name: rebind-yaml-catalog-item-test\n" + + "name: " + symbolicName + "\n" + "brooklyn.catalog:\n" + " version: " + TEST_VERSION + "\n" + "services:\n" + "- type: io.camp.mock:AppServer"; - addItem(origManagementContext, yaml); + CatalogEntityItemDto item = + CatalogItemBuilder.newEntity(symbolicName, TEST_VERSION) + .displayName(symbolicName) + .plan(yaml) + .build(); + origManagementContext.getCatalog().addItem(item); + LOG.info("Added item to catalog: {}, id={}", item, item.getId()); rebindAndAssertCatalogsAreEqual(); } @@ -129,7 +134,9 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp { @Test public void testAddAndRebindPolicy() { // Doesn't matter that SamplePolicy doesn't exist - String yaml = "name: Test Policy\n" + + String symbolicName = "Test Policy"; + String yaml = + "name: " + symbolicName + "\n" + "brooklyn.catalog:\n" + " id: sample_policy\n" + " version: " + TEST_VERSION + "\n" + @@ -138,27 +145,39 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp { " brooklyn.config:\n" + " cfg1: 111\n" + " cfg2: 222"; - addItem(origManagementContext, yaml); + CatalogPolicyItemDto item = + CatalogItemBuilder.newPolicy(symbolicName, TEST_VERSION) + .displayName(symbolicName) + .plan(yaml) + .build(); + origManagementContext.getCatalog().addItem(item); + LOG.info("Added item to catalog: {}, id={}", item, item.getId()); rebindAndAssertCatalogsAreEqual(); } @Test public void testAddAndRebindAndDeleteLocation() { + String symbolicName = "sample_location"; String yaml = Joiner.on("\n").join(ImmutableList.of( "name: Test Location", "brooklyn.catalog:", - " id: sample_location", + " id: " + symbolicName, " version: " + TEST_VERSION, "brooklyn.locations:", "- type: "+LocalhostMachineProvisioningLocation.class.getName(), " brooklyn.config:", " cfg1: 111", " cfg2: 222")); - CatalogItem<?, ?> added = addItem(origManagementContext, yaml); - assertEquals(added.getCatalogItemType(), CatalogItemType.LOCATION); + CatalogLocationItemDto item = + CatalogItemBuilder.newLocation(symbolicName, TEST_VERSION) + .displayName(symbolicName) + .plan(yaml) + .build(); + origManagementContext.getCatalog().addItem(item); + assertEquals(item.getCatalogItemType(), CatalogItemType.LOCATION); rebindAndAssertCatalogsAreEqual(); - deleteItem(newManagementContext, added.getSymbolicName(), added.getVersion()); + deleteItem(newManagementContext, item.getSymbolicName(), item.getVersion()); switchOriginalToNewManagementContext(); rebindAndAssertCatalogsAreEqual(); @@ -203,15 +222,20 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp { //The test is not reliable on Windows (doesn't catch the pre-fix problem) - //the store is unable to delete still locked files so the bug doesn't manifest. //TODO investigate if locked files not caused by unclosed streams! + String symbolicName = "rebind-yaml-catalog-item-test"; String yaml = - "name: rebind-yaml-catalog-item-test\n" + + "name: " + symbolicName + "\n" + "brooklyn.catalog:\n" + " version: " + TEST_VERSION + "\n" + "services:\n" + "- type: io.camp.mock:AppServer"; - addItem(origManagementContext, yaml); - BasicBrooklynCatalog catalog = (BasicBrooklynCatalog) origManagementContext.getCatalog(); + CatalogEntityItemDto item = + CatalogItemBuilder.newEntity(symbolicName, TEST_VERSION) + .displayName(symbolicName) + .plan(yaml) + .build(); + catalog.addItem(item); String catalogXml = catalog.toXmlString(); catalog.reset(CatalogDto.newDtoFromXmlContents(catalogXml, "Test reset")); rebindAndAssertCatalogsAreEqual(); @@ -219,30 +243,29 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp { @Test public void testRebindAfterItemDeprecated() { + String symbolicName = "rebind-yaml-catalog-item-test"; String yaml = - "name: rebind-yaml-catalog-item-test\n" + + "name: " + symbolicName + "\n" + "brooklyn.catalog:\n" + " version: " + TEST_VERSION + "\n" + "services:\n" + "- type: io.camp.mock:AppServer"; - CatalogItem<?, ?> catalogItem = addItem(origManagementContext, yaml); - assertNotNull(catalogItem, "catalogItem"); + CatalogEntityItemDto item = + CatalogItemBuilder.newEntity(symbolicName, TEST_VERSION) + .displayName(symbolicName) + .plan(yaml) + .build(); + origManagementContext.getCatalog().addItem(item); + assertNotNull(item, "catalogItem"); BasicBrooklynCatalog catalog = (BasicBrooklynCatalog) origManagementContext.getCatalog(); - catalogItem.setDeprecated(true); - catalog.persist(catalogItem); + item.setDeprecated(true); + catalog.persist(item); rebindAndAssertCatalogsAreEqual(); CatalogItem<?, ?> catalogItemAfterRebind = newManagementContext.getCatalog().getCatalogItem("rebind-yaml-catalog-item-test", TEST_VERSION); assertTrue(catalogItemAfterRebind.isDeprecated(), "Expected item to be deprecated"); } - protected CatalogItem<?, ?> addItem(ManagementContext mgmt, String yaml) { - CatalogItem<?, ?> added = Iterables.getOnlyElement(mgmt.getCatalog().addItems(yaml)); - LOG.info("Added item to catalog: {}, id={}", added, added.getId()); - assertCatalogContains(mgmt.getCatalog(), added); - return added; - } - protected void deleteItem(ManagementContext mgmt, String symbolicName, String version) { mgmt.getCatalog().deleteCatalogItem(symbolicName, version); LOG.info("Deleted item from catalog: {}:{}", symbolicName, version); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java index 7831c1a..62db79f 100644 --- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java @@ -22,17 +22,16 @@ import static org.testng.Assert.assertEquals; import java.io.File; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement; import org.apache.brooklyn.core.internal.BrooklynProperties; import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext; import org.apache.brooklyn.core.server.BrooklynServerConfig; -import org.apache.brooklyn.core.test.camp.brooklyn.lite.CampPlatformWithJustBrooklynMgmt; import org.apache.brooklyn.core.test.entity.TestEntity; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; import com.google.common.collect.Iterables; @@ -47,7 +46,6 @@ public class RebindCatalogWhenCatalogPersistenceDisabledTest extends RebindTestF catalogPersistenceWasPreviouslyEnabled = BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_CATALOG_PERSISTENCE_PROPERTY); BrooklynFeatureEnablement.disable(BrooklynFeatureEnablement.FEATURE_CATALOG_PERSISTENCE_PROPERTY); super.setUp(); - new CampPlatformWithJustBrooklynMgmt(origManagementContext); origApp.createAndManageChild(EntitySpec.create(TestEntity.class)); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampPlatformWithJustBrooklynMgmt.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampPlatformWithJustBrooklynMgmt.java b/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampPlatformWithJustBrooklynMgmt.java deleted file mode 100644 index 95fa64d..0000000 --- a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampPlatformWithJustBrooklynMgmt.java +++ /dev/null @@ -1,41 +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.test.camp.brooklyn.lite; - -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.camp.BasicCampPlatform; -import org.apache.brooklyn.camp.brooklyn.api.HasBrooklynManagementContext; -import org.apache.brooklyn.core.internal.BrooklynProperties; -import org.apache.brooklyn.core.server.BrooklynServerConfig; - -public class CampPlatformWithJustBrooklynMgmt extends BasicCampPlatform implements HasBrooklynManagementContext { - - private ManagementContext mgmt; - - public CampPlatformWithJustBrooklynMgmt(ManagementContext mgmt) { - this.mgmt = mgmt; - ((BrooklynProperties)mgmt.getConfig()).put(BrooklynServerConfig.CAMP_PLATFORM, this); - } - - @Override - public ManagementContext getBrooklynManagementContext() { - return mgmt; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampYamlLiteTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampYamlLiteTest.java b/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampYamlLiteTest.java deleted file mode 100644 index f109737..0000000 --- a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampYamlLiteTest.java +++ /dev/null @@ -1,255 +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.test.camp.brooklyn.lite; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; - -import org.apache.brooklyn.test.TestResourceUnavailableException; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.core.ResourceUtils; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.stream.Streams; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.Assert; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; -import org.apache.brooklyn.api.catalog.CatalogItem; -import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle; -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.camp.spi.Assembly; -import org.apache.brooklyn.camp.spi.AssemblyTemplate; -import org.apache.brooklyn.camp.spi.pdp.PdpYamlTest; -import org.apache.brooklyn.camp.test.mock.web.MockWebPlatform; -import org.apache.brooklyn.core.catalog.CatalogPredicates; -import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog; -import org.apache.brooklyn.core.catalog.internal.CatalogDto; -import org.apache.brooklyn.core.catalog.internal.CatalogUtils; -import org.apache.brooklyn.core.config.ConfigKeys; -import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext; -import org.apache.brooklyn.core.mgmt.osgi.OsgiStandaloneTest; -import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; -import org.apache.brooklyn.core.test.entity.TestApplication; -import org.apache.brooklyn.core.test.entity.TestEntity; -import org.apache.brooklyn.effector.core.AddChildrenEffector; -import org.apache.brooklyn.effector.core.Effectors; -import org.apache.brooklyn.entity.core.Entities; -import org.apache.brooklyn.entity.factory.ApplicationBuilder; - -import com.google.common.base.Joiner; -import com.google.common.base.Predicates; -import com.google.common.collect.Iterables; - -/** Tests of lightweight CAMP integration. Since the "real" integration is in brooklyn-camp project, - * but some aspects of CAMP we want to be able to test here. */ -public class CampYamlLiteTest { - private static final String TEST_VERSION = "0.1.2"; - - private static final Logger log = LoggerFactory.getLogger(CampYamlLiteTest.class); - - protected LocalManagementContext mgmt; - protected CampPlatformWithJustBrooklynMgmt platform; - - @BeforeMethod(alwaysRun=true) - public void setUp() { - mgmt = LocalManagementContextForTests.newInstanceWithOsgi(); - platform = new CampPlatformWithJustBrooklynMgmt(mgmt); - MockWebPlatform.populate(platform, TestAppAssemblyInstantiator.class); - } - - @AfterMethod(alwaysRun=true) - public void tearDown() { - if (mgmt!=null) mgmt.terminate(); - } - - /** based on {@link PdpYamlTest} for parsing, - * then creating a {@link TestAppAssembly} */ - @Test - public void testYamlServiceMatchAndBrooklynInstantiate() throws Exception { - Reader input = new InputStreamReader(getClass().getResourceAsStream("test-app-service-blueprint.yaml")); - AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input); - log.info("AT is:\n"+at.toString()); - Assert.assertEquals(at.getName(), "sample"); - Assert.assertEquals(at.getPlatformComponentTemplates().links().size(), 1); - - // now use brooklyn to instantiate - note it won't be faithful, but it will set some config keys - Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform); - - TestApplication app = ((TestAppAssembly)assembly).getBrooklynApp(); - Assert.assertEquals( app.getConfig(TestEntity.CONF_NAME), "sample" ); - Map<String, String> map = app.getConfig(TestEntity.CONF_MAP_THING); - Assert.assertEquals( map.get("desc"), "Tomcat sample JSP and servlet application." ); - - Assert.assertEquals( app.getChildren().size(), 1 ); - Entity svc = Iterables.getOnlyElement(app.getChildren()); - Assert.assertEquals( svc.getConfig(TestEntity.CONF_NAME), "Hello WAR" ); - map = svc.getConfig(TestEntity.CONF_MAP_THING); - Assert.assertEquals( map.get("type"), MockWebPlatform.APPSERVER.getType() ); - // desc ensures we got the information from the matcher, as this value is NOT in the yaml - Assert.assertEquals( map.get("desc"), MockWebPlatform.APPSERVER.getDescription() ); - } - - /** based on {@link PdpYamlTest} for parsing, - * then creating a {@link TestAppAssembly} */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Test - public void testAddChildrenEffector() throws Exception { - String childYaml = Streams.readFullyString(getClass().getResourceAsStream("test-app-service-blueprint.yaml")); - AddChildrenEffector newEff = new AddChildrenEffector(ConfigBag.newInstance() - .configure(AddChildrenEffector.EFFECTOR_NAME, "add_tomcat") - .configure(AddChildrenEffector.BLUEPRINT_YAML, childYaml) - .configure(AddChildrenEffector.EFFECTOR_PARAMETER_DEFS, MutableMap.of("war", (Object)MutableMap.of( - "defaultValue", "foo.war"))) ) ; - TestApplication app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).addInitializer(newEff), mgmt); - - // test adding, with a parameter - Task<List> task = app.invoke(Effectors.effector(List.class, "add_tomcat").buildAbstract(), MutableMap.of("war", "foo.bar")); - List result = task.get(); - - Entity newChild = Iterables.getOnlyElement(app.getChildren()); - Assert.assertEquals(newChild.getConfig(ConfigKeys.newStringConfigKey("war")), "foo.bar"); - - Assert.assertEquals(Iterables.getOnlyElement(result), newChild.getId()); - Entities.unmanage(newChild); - - // and test default value - task = app.invoke(Effectors.effector(List.class, "add_tomcat").buildAbstract(), MutableMap.<String,Object>of()); - result = task.get(); - - newChild = Iterables.getOnlyElement(app.getChildren()); - Assert.assertEquals(newChild.getConfig(ConfigKeys.newStringConfigKey("war")), "foo.war"); - - Assert.assertEquals(Iterables.getOnlyElement(result), newChild.getId()); - Entities.unmanage(newChild); - } - - @Test - public void testYamlServiceForCatalog() { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); - - CatalogItem<?, ?> realItem = Iterables.getOnlyElement(mgmt.getCatalog().addItems(Streams.readFullyString(getClass().getResourceAsStream("test-app-service-blueprint.yaml")))); - Iterable<CatalogItem<Object, Object>> retrievedItems = mgmt.getCatalog() - .getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo("catalog-name"))); - - Assert.assertEquals(Iterables.size(retrievedItems), 1, "Wrong retrieved items: "+retrievedItems); - CatalogItem<Object, Object> retrievedItem = Iterables.getOnlyElement(retrievedItems); - Assert.assertEquals(retrievedItem, realItem); - - Collection<CatalogBundle> bundles = retrievedItem.getLibraries(); - Assert.assertEquals(bundles.size(), 1); - CatalogBundle bundle = Iterables.getOnlyElement(bundles); - Assert.assertEquals(bundle.getUrl(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL); - Assert.assertEquals(bundle.getVersion(), "0.1.0"); - - EntitySpec<?> spec1 = (EntitySpec<?>) mgmt.getCatalog().createSpec(retrievedItem); - assertNotNull(spec1); - Assert.assertEquals(spec1.getConfig().get(TestEntity.CONF_NAME), "sample"); - - // TODO other assertions, about children - } - - @Test - public void testRegisterCustomEntityWithBundleWhereEntityIsFromCoreAndIconFromBundle() throws IOException { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); - - String symbolicName = "my.catalog.app.id"; - String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL; - String yaml = getSampleMyCatalogAppYaml(symbolicName, bundleUrl); - - mgmt.getCatalog().addItems(yaml); - - assertMgmtHasSampleMyCatalogApp(symbolicName, bundleUrl); - } - - @Test - public void testResetXmlWithCustomEntity() throws IOException { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); - - String symbolicName = "my.catalog.app.id"; - String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL; - String yaml = getSampleMyCatalogAppYaml(symbolicName, bundleUrl); - - LocalManagementContext mgmt2 = LocalManagementContextForTests.newInstanceWithOsgi(); - try { - CampPlatformWithJustBrooklynMgmt platform2 = new CampPlatformWithJustBrooklynMgmt(mgmt2); - MockWebPlatform.populate(platform2, TestAppAssemblyInstantiator.class); - - mgmt2.getCatalog().addItems(yaml); - String xml = ((BasicBrooklynCatalog) mgmt2.getCatalog()).toXmlString(); - ((BasicBrooklynCatalog) mgmt.getCatalog()).reset(CatalogDto.newDtoFromXmlContents(xml, "copy of temporary catalog")); - } finally { - mgmt2.terminate(); - } - - assertMgmtHasSampleMyCatalogApp(symbolicName, bundleUrl); - } - - private String getSampleMyCatalogAppYaml(String symbolicName, String bundleUrl) { - return "brooklyn.catalog:\n" + - " id: " + symbolicName + "\n" + - " name: My Catalog App\n" + - " description: My description\n" + - " icon_url: classpath:/brooklyn/osgi/tests/icon.gif\n" + - " version: " + TEST_VERSION + "\n" + - " libraries:\n" + - " - url: " + bundleUrl + "\n" + - "\n" + - "services:\n" + - "- type: io.camp.mock:AppServer\n"; - } - - private void assertMgmtHasSampleMyCatalogApp(String symbolicName, String bundleUrl) { - CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(symbolicName, TEST_VERSION); - assertNotNull(item, "failed to load item with id=" + symbolicName + " from catalog. Entries were: " + - Joiner.on(",").join(mgmt.getCatalog().getCatalogItems())); - assertEquals(item.getSymbolicName(), symbolicName); - - // stored as yaml, not java - assertNotNull(item.getPlanYaml()); - Assert.assertTrue(item.getPlanYaml().contains("io.camp.mock:AppServer")); - - // and let's check we have libraries - Collection<CatalogBundle> libs = item.getLibraries(); - assertEquals(libs.size(), 1); - CatalogBundle bundle = Iterables.getOnlyElement(libs); - assertEquals(bundle.getUrl(), bundleUrl); - - // now let's check other things on the item - assertEquals(item.getDisplayName(), "My Catalog App"); - assertEquals(item.getDescription(), "My description"); - assertEquals(item.getIconUrl(), "classpath:/brooklyn/osgi/tests/icon.gif"); - - // and confirm we can resolve ICON - byte[] iconData = Streams.readFully(ResourceUtils.create(CatalogUtils.newClassLoadingContext(mgmt, item)).getResourceFromUrl(item.getIconUrl())); - assertEquals(iconData.length, 43); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssembly.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssembly.java b/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssembly.java deleted file mode 100644 index bc9e9bb..0000000 --- a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssembly.java +++ /dev/null @@ -1,36 +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.test.camp.brooklyn.lite; - -import org.apache.brooklyn.camp.spi.Assembly; -import org.apache.brooklyn.core.test.entity.TestApplication; - -public class TestAppAssembly extends Assembly { - - private TestApplication brooklynApp; - - public TestAppAssembly(TestApplication brooklynApp) { - this.brooklynApp = brooklynApp; - } - - public TestApplication getBrooklynApp() { - return brooklynApp; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssemblyInstantiator.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssemblyInstantiator.java b/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssemblyInstantiator.java deleted file mode 100644 index d55cedf..0000000 --- a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssemblyInstantiator.java +++ /dev/null @@ -1,90 +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.test.camp.brooklyn.lite; - -import java.util.Map; -import java.util.Set; - -import org.apache.brooklyn.api.entity.EntitySpec; -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; -import org.apache.brooklyn.camp.CampPlatform; -import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator; -import org.apache.brooklyn.camp.brooklyn.api.HasBrooklynManagementContext; -import org.apache.brooklyn.camp.spi.AbstractResource; -import org.apache.brooklyn.camp.spi.Assembly; -import org.apache.brooklyn.camp.spi.AssemblyTemplate; -import org.apache.brooklyn.camp.spi.PlatformComponentTemplate; -import org.apache.brooklyn.camp.spi.collection.ResolvableLink; -import org.apache.brooklyn.camp.spi.instantiate.BasicAssemblyTemplateInstantiator; -import org.apache.brooklyn.core.test.entity.TestApplication; -import org.apache.brooklyn.core.test.entity.TestEntity; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.core.config.ConfigBag; - -/** simple illustrative instantiator which always makes a {@link TestApplication}, populated with {@link TestEntity} children, - * all setting {@link TestEntity#CONF_NAME} for the name in the plan and in the service specs - * <p> - * the "real" instantiator for brooklyn is in brooklyn-camp project, not visible here, so let's have something we can test */ -public class TestAppAssemblyInstantiator extends BasicAssemblyTemplateInstantiator implements AssemblyTemplateSpecInstantiator { - - @Override - public Assembly instantiate(AssemblyTemplate template, CampPlatform platform) { - if (!(platform instanceof HasBrooklynManagementContext)) { - throw new IllegalStateException("Instantiator can only be used with CAMP platforms with a Brooklyn management context"); - } - ManagementContext mgmt = ((HasBrooklynManagementContext)platform).getBrooklynManagementContext(); - - TestApplication app = (TestApplication) mgmt.getEntityManager().createEntity( createSpec(template, platform, null, false) ); - mgmt.getEntityManager().manage(app); - - return new TestAppAssembly(app); - } - - @Override - public EntitySpec<?> createSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext loader, boolean autoUnwrap) { - EntitySpec<TestApplication> app = EntitySpec.create(TestApplication.class) - .configure(TestEntity.CONF_NAME, template.getName()) - .configure(TestEntity.CONF_MAP_THING, MutableMap.of("type", template.getType(), "desc", template.getDescription())); - applyBrooklynConfig(template, app); - - for (ResolvableLink<PlatformComponentTemplate> t: template.getPlatformComponentTemplates().links()) { - EntitySpec<TestEntity> spec = EntitySpec.create(TestEntity.class) - .configure(TestEntity.CONF_NAME, t.getName()) - .configure(TestEntity.CONF_MAP_THING, MutableMap.of("type", t.resolve().getType(), "desc", t.resolve().getDescription())); - applyBrooklynConfig(t.resolve(), app); - app.child(spec); - } - - return app; - } - - @SuppressWarnings("rawtypes") - private void applyBrooklynConfig(AbstractResource template, EntitySpec<TestApplication> app) { - Object bc = template.getCustomAttributes().get("brooklyn.config"); - if (bc instanceof Map) - app.configure(ConfigBag.newInstance().putAll((Map)bc).getAllConfigAsConfigKeyMap()); - } - - @Override - public EntitySpec<?> createNestedSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext itemLoader, Set<String> encounteredCatalogTypes) { - return createSpec(template, platform, itemLoader, true); - } - -}
