Repository: incubator-brooklyn Updated Branches: refs/heads/master 4f1eb45cb -> cecaaf02b
Parse service types in YAML using pluggable resolver impls Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/303c3884 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/303c3884 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/303c3884 Branch: refs/heads/master Commit: 303c3884e868b9167bd1551469507137634948fc Parents: 1f14917 Author: Andrew Kennedy <[email protected]> Authored: Tue Apr 7 16:35:19 2015 +0100 Committer: Andrew Kennedy <[email protected]> Committed: Wed Apr 8 20:18:45 2015 +0100 ---------------------------------------------------------------------- .../BrooklynAssemblyTemplateInstantiator.java | 52 ++--- .../BrooklynComponentTemplateResolver.java | 227 ++++++++----------- .../BrooklynEntityDecorationResolver.java | 6 +- .../creation/ChefComponentTemplateResolver.java | 57 ----- .../service/BrooklynServiceTypeResolver.java | 72 ++++++ .../service/CatalogServiceTypeResolver.java | 58 +++++ .../service/ChefServiceTypeResolver.java | 62 +++++ .../service/JavaServiceTypeResolver.java | 30 +++ .../creation/service/ServiceTypeResolver.java | 43 ++++ ...lyn.spi.creation.service.ServiceTypeResolver | 22 ++ 10 files changed, 414 insertions(+), 215 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java index 379cd43..af1cbb0 100644 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java +++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java @@ -64,9 +64,9 @@ import com.google.common.collect.Sets; public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpecInstantiator { private static final Logger log = LoggerFactory.getLogger(BrooklynAssemblyTemplateInstantiator.class); - + public static final String NEVER_UNWRAP_APPS_PROPERTY = "wrappedApp"; - + @Override public Assembly instantiate(AssemblyTemplate template, CampPlatform platform) { Application app = create(template, platform); @@ -80,11 +80,11 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe log.debug("CAMP created {}", instance); return instance; } - + private ManagementContext getBrooklynManagementContext(CampPlatform platform) { return ((HasBrooklynManagementContext)platform).getBrooklynManagementContext(); } - + @SuppressWarnings("unchecked") public EntitySpec<? extends Application> createSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext loader, boolean autoUnwrapIfPossible) { log.debug("CAMP creating application instance for {} ({})", template.getId(), template); @@ -94,24 +94,24 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance( loader, buildWrapperAppTemplate(template)); EntitySpec<? extends Application> app = resolver.resolveSpec(); - + // first build the children into an empty shell app List<EntitySpec<?>> childSpecs = buildTemplateServicesAsSpecs(loader, template, platform); for (EntitySpec<?> childSpec : childSpecs) { app.child(childSpec); } - + if (autoUnwrapIfPossible && shouldUnwrap(template, app)) { EntitySpec<? extends Application> oldApp = app; app = (EntitySpec<? extends Application>) Iterables.getOnlyElement( app.getChildren() ); - + // if promoted, apply the transformations done to the app // (transformations will be done by the resolveSpec call above, but we are collapsing oldApp so transfer to app=newApp) EntityManagementUtils.collapseSpec(oldApp, app); } else { app.configure(EntityManagementUtils.WRAPPER_APP_MARKER, Boolean.TRUE); } - + return app; } @@ -135,10 +135,10 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe if (TypeCoercions.coerce(leaveWrapped, Boolean.class)) return false; } - - if (app.getChildren().size()!=1) + + if (app.getChildren().size()!=1) return false; - + EntitySpec<?> childSpec = Iterables.getOnlyElement(app.getChildren()); if (childSpec.getType()==null || !Application.class.isAssignableFrom(childSpec.getType())) return false; @@ -152,48 +152,48 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe private List<EntitySpec<?>> buildTemplateServicesAsSpecsImpl(BrooklynClassLoadingContext loader, AssemblyTemplate template, CampPlatform platform, Set<String> encounteredCatalogTypes) { List<EntitySpec<?>> result = Lists.newArrayList(); - + for (ResolvableLink<PlatformComponentTemplate> ctl: template.getPlatformComponentTemplates().links()) { PlatformComponentTemplate appChildComponentTemplate = ctl.resolve(); BrooklynComponentTemplateResolver entityResolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, appChildComponentTemplate); EntitySpec<?> spec = resolveSpec(entityResolver, encounteredCatalogTypes); - + result.add(spec); } return result; } protected EntitySpec<?> resolveSpec( - BrooklynComponentTemplateResolver entityResolver, + BrooklynComponentTemplateResolver entityResolver, Set<String> encounteredCatalogTypes) { - ManagementContext mgmt = entityResolver.loader.getManagementContext(); + ManagementContext mgmt = entityResolver.getLoader().getManagementContext(); - String brooklynType = entityResolver.getBrooklynType(); - CatalogItem<Entity, EntitySpec<?>> item = entityResolver.getCatalogItem(); + String brooklynType = entityResolver.getServiceTypeResolver().getBrooklynType(entityResolver.getDeclaredType()); + CatalogItem<Entity, EntitySpec<?>> item = entityResolver.getServiceTypeResolver().getCatalogItem(entityResolver, entityResolver.getDeclaredType()); //Take the symoblicName part of the catalog item only for recursion detection to prevent //cross referencing of different versions. Not interested in non-catalog item types. //Prevent catalog items self-referencing even if explicitly different version. boolean firstOccurrence = (item == null || encounteredCatalogTypes.add(item.getSymbolicName())); boolean recursiveButTryJava = !firstOccurrence; - - if (log.isTraceEnabled()) log.trace("Building CAMP template services: type="+brooklynType+"; item="+item+"; loader="+entityResolver.loader+"; encounteredCatalogTypes="+encounteredCatalogTypes); + + if (log.isTraceEnabled()) log.trace("Building CAMP template services: type="+brooklynType+"; item="+item+"; loader="+entityResolver.getLoader()+"; encounteredCatalogTypes="+encounteredCatalogTypes); EntitySpec<?> spec = null; String protocol = Urls.getProtocol(brooklynType); if (protocol != null) { if (BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST.contains(protocol)) { - spec = tryResolveYamlURLReferenceSpec(brooklynType, entityResolver.loader, encounteredCatalogTypes); + spec = tryResolveYamlURLReferenceSpec(brooklynType, entityResolver.getLoader(), encounteredCatalogTypes); if (spec != null) { entityResolver.populateSpec(spec); } } else { - log.warn("The reference " + brooklynType + " looks like an URL but the protocol " + + log.warn("The reference " + brooklynType + " looks like an URL but the protocol " + protocol + " isn't white listed (" + BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST + "). " + "Will try to load it as catalog item or java type."); } } - + if (spec == null) { // - Load a java class from current loader (item == null || entityResolver.isJavaTypePrefix()) // - Load a java class specified in an old-style catalog item (item != null && item.getJavaType() != null) @@ -225,7 +225,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe } private EntitySpec<?> tryResolveYamlURLReferenceSpec( - String brooklynType, BrooklynClassLoadingContext itemLoader, + String brooklynType, BrooklynClassLoadingContext itemLoader, Set<String> encounteredCatalogTypes) { ManagementContext mgmt = itemLoader.getManagementContext(); Reader yaml; @@ -251,11 +251,11 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe ManagementContext mgmt, CatalogItem<Entity, EntitySpec<?>> item, Set<String> encounteredCatalogTypes) { - + String yaml = item.getPlanYaml(); Reader input = new StringReader(yaml); BrooklynClassLoadingContext itemLoader = CatalogUtils.newClassLoadingContext(mgmt, item); - + return createNestedSpec(mgmt, encounteredCatalogTypes, input, itemLoader); } @@ -263,7 +263,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe Set<String> encounteredCatalogTypes, Reader input, BrooklynClassLoadingContext itemLoader) { CampPlatform platform = BrooklynServerConfig.getCampPlatform(mgmt).get(); - + AssemblyTemplate at; BrooklynLoaderTracker.setLoader(itemLoader); try { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java index da6e395..37fccf8 100644 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java +++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java @@ -19,7 +19,8 @@ package io.brooklyn.camp.brooklyn.spi.creation; import io.brooklyn.camp.brooklyn.BrooklynCampConstants; -import io.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon; +import io.brooklyn.camp.brooklyn.spi.creation.service.BrooklynServiceTypeResolver; +import io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver; import io.brooklyn.camp.spi.AbstractResource; import io.brooklyn.camp.spi.ApplicationComponentTemplate; import io.brooklyn.camp.spi.AssemblyTemplate; @@ -28,6 +29,7 @@ import io.brooklyn.camp.spi.PlatformComponentTemplate; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.ServiceLoader; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -45,23 +47,17 @@ import brooklyn.entity.basic.AbstractEntity; import brooklyn.entity.basic.BrooklynTags; import brooklyn.entity.basic.BrooklynTaskTags; import brooklyn.entity.basic.ConfigKeys; -import brooklyn.entity.basic.EntityInternal; -import brooklyn.entity.basic.VanillaSoftwareProcess; -import brooklyn.entity.group.DynamicCluster; -import brooklyn.entity.group.DynamicRegionsFabric; import brooklyn.entity.proxying.EntitySpec; import brooklyn.entity.proxying.InternalEntityFactory; import brooklyn.location.Location; import brooklyn.management.ManagementContext; import brooklyn.management.ManagementContextInjectable; import brooklyn.management.classloading.BrooklynClassLoadingContext; -import brooklyn.management.classloading.BrooklynClassLoadingContextSequential; import brooklyn.management.classloading.JavaBrooklynClassLoadingContext; import brooklyn.management.internal.ManagementContextInternal; import brooklyn.util.collections.MutableList; import brooklyn.util.collections.MutableSet; import brooklyn.util.config.ConfigBag; -import brooklyn.util.exceptions.Exceptions; import brooklyn.util.flags.FlagUtils; import brooklyn.util.flags.FlagUtils.FlagConfigKeyAndValueRecord; import brooklyn.util.guava.Maybe; @@ -70,6 +66,7 @@ import brooklyn.util.task.Tasks; import brooklyn.util.text.Strings; import com.google.common.base.Function; +import com.google.common.base.Splitter; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; @@ -77,59 +74,80 @@ import com.google.common.collect.Maps; * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code brooklyn:} * to Brooklyn {@link EntitySpec} instances. * <p> - * but TODO this should probably be done by {@link BrooklynEntityMatcher} + * but TODO this should probably be done by {@link BrooklynEntityMatcher} * so we have a spec by the time we come to instantiate. - * (currently privileges "brooklyn.*" key names are checked in both places!) + * (currently privileges "brooklyn.*" key names are checked in both places!) */ public class BrooklynComponentTemplateResolver { - private static final Logger log = LoggerFactory.getLogger(BrooklynDslCommon.class); + private static final Logger log = LoggerFactory.getLogger(BrooklynComponentTemplateResolver.class); - BrooklynClassLoadingContext loader; - final ManagementContext mgmt; - final ConfigBag attrs; - final Maybe<AbstractResource> template; - final BrooklynYamlTypeInstantiator.Factory yamlLoader; - AtomicBoolean alreadyBuilt = new AtomicBoolean(false); + private final BrooklynClassLoadingContext loader; + private final ManagementContext mgmt; + private final ConfigBag attrs; + private final Maybe<AbstractResource> template; + private final BrooklynYamlTypeInstantiator.Factory yamlLoader; + private final String type; + private final ServiceTypeResolver typeResolver; + private final AtomicBoolean alreadyBuilt = new AtomicBoolean(false); + + public BrooklynComponentTemplateResolver(BrooklynClassLoadingContext loader, ConfigBag attrs, AbstractResource optionalTemplate, String type, ServiceTypeResolver typeResolver) { + this.loader = loader; + this.mgmt = loader.getManagementContext(); + this.attrs = ConfigBag.newInstanceCopying(attrs); + this.template = Maybe.fromNullable(optionalTemplate); + this.yamlLoader = new BrooklynYamlTypeInstantiator.Factory(loader, this); + this.type = type; + this.typeResolver = typeResolver; + } + + public BrooklynClassLoadingContext getLoader() { return loader; } + public ManagementContext getManagementContext() { return mgmt; } + public ConfigBag getAttrs() { return attrs; } + public Maybe<AbstractResource> getTemplate() { return template; } + public BrooklynYamlTypeInstantiator.Factory getYamlLoader() { return yamlLoader; } + public ServiceTypeResolver getServiceTypeResolver() { return typeResolver; } + public String getDeclaredType() { return type; } + public Boolean isAlreadyBuilt() { return alreadyBuilt.get(); } public static class Factory { /** returns resolver type based on the service type, inspecting the arguments in order to determine the service type */ - private static Class<? extends BrooklynComponentTemplateResolver> computeResolverType(String knownServiceType, AbstractResource optionalTemplate, ConfigBag attrs) { + private static ServiceTypeResolver computeResolverType(BrooklynClassLoadingContext context, String knownServiceType, AbstractResource optionalTemplate, ConfigBag attrs) { String type = getDeclaredType(knownServiceType, optionalTemplate, attrs); - if (type!=null) { - if (type.startsWith("brooklyn:") || type.startsWith("java:")) return BrooklynComponentTemplateResolver.class; - if (type.equalsIgnoreCase("chef") || type.startsWith("chef:")) return ChefComponentTemplateResolver.class; - // TODO other BrooklynComponentTemplateResolver subclasses detected here - // (perhaps use regexes mapping to subclass name, defined in mgmt?) + return findService(context, type); + } + + protected static ServiceTypeResolver findService(BrooklynClassLoadingContext context, String type) { + String prefix = Splitter.on(":").splitToList(type).get(0); + ServiceLoader<ServiceTypeResolver> loader = ServiceLoader.load(ServiceTypeResolver.class, context.getManagementContext().getCatalog().getRootClassLoader()); + for (ServiceTypeResolver resolver : loader) { + if (prefix.equalsIgnoreCase(resolver.getTypePrefix())) return resolver; } - return null; } - public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext loader, Map<String, ?> childAttrs) { - return newInstance(loader, ConfigBag.newInstance(childAttrs), null); + public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, Map<String, ?> childAttrs) { + return newInstance(context, ConfigBag.newInstance(childAttrs), null); } - public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext loader, AbstractResource template) { - return newInstance(loader, ConfigBag.newInstance(template.getCustomAttributes()), template); + public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, AbstractResource template) { + return newInstance(context, ConfigBag.newInstance(template.getCustomAttributes()), template); } - - public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext loader, String serviceType) { - return newInstance(loader, ConfigBag.newInstance().configureStringKey("serviceType", serviceType), null); + + public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, String serviceType) { + return newInstance(context, ConfigBag.newInstance().configureStringKey("serviceType", serviceType), null); } - - private static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext loader, ConfigBag attrs, AbstractResource optionalTemplate) { - Class<? extends BrooklynComponentTemplateResolver> rt = computeResolverType(null, optionalTemplate, attrs); - if (rt==null) // use default - rt = BrooklynComponentTemplateResolver.class; - - try { - return (BrooklynComponentTemplateResolver) rt.getConstructors()[0].newInstance(loader, attrs, optionalTemplate); - } catch (Exception e) { throw Exceptions.propagate(e); } + + private static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, ConfigBag attrs, AbstractResource optionalTemplate) { + ServiceTypeResolver typeResolver = computeResolverType(context, null, optionalTemplate, attrs); + String type = getDeclaredType(null, optionalTemplate, attrs); + if (typeResolver == null) // use default + typeResolver = new BrooklynServiceTypeResolver(); + return new BrooklynComponentTemplateResolver(context, attrs, optionalTemplate, type, typeResolver); } - private static String getDeclaredType(String knownServiceType, AbstractResource optionalTemplate, @Nullable ConfigBag attrs) { + public static String getDeclaredType(String knownServiceType, AbstractResource optionalTemplate, @Nullable ConfigBag attrs) { String type = knownServiceType; if (type==null && optionalTemplate!=null) { type = optionalTemplate.getType(); @@ -140,67 +158,20 @@ public class BrooklynComponentTemplateResolver { if (type==null) type = extractServiceTypeAttribute(attrs); return type; } - + private static String extractServiceTypeAttribute(@Nullable ConfigBag attrs) { return BrooklynYamlTypeInstantiator.InstantiatorFromKey.extractTypeName("service", attrs).orNull(); } - public static boolean supportsType(BrooklynClassLoadingContext loader, String serviceType) { - Class<? extends BrooklynComponentTemplateResolver> type = computeResolverType(serviceType, null, null); - if (type!=null) return true; - return newInstance(loader, serviceType).canResolve(); + public static boolean supportsType(BrooklynClassLoadingContext context, String serviceType) { + ServiceTypeResolver typeResolver = computeResolverType(context, serviceType, null, null); + if (typeResolver != null) return true; + return newInstance(context, serviceType).canResolve(); } } - public BrooklynComponentTemplateResolver(BrooklynClassLoadingContext loader, ConfigBag attrs, AbstractResource optionalTemplate) { - this.loader = loader; - this.mgmt = loader.getManagementContext(); - this.attrs = ConfigBag.newInstanceCopying(attrs); - this.template = Maybe.fromNullable(optionalTemplate); - this.yamlLoader = new BrooklynYamlTypeInstantiator.Factory(loader, this); - } - - protected String getDeclaredType() { - return Factory.getDeclaredType(null, template.orNull(), attrs); - } - - // TODO Generalise to have other prefixes (e.g. explicit "catalog:" etc)? - protected boolean isJavaTypePrefix() { - String type = getDeclaredType(); - return type != null && (type.toLowerCase().startsWith("java:") || type.toLowerCase().startsWith("brooklyn:java:")); - } - - protected String getBrooklynType() { - String type = getDeclaredType(); - type = Strings.removeFromStart(type, "brooklyn:", "java:"); - if (type == null) return null; - - // TODO currently a hardcoded list of aliases; would like that to come from mgmt somehow - if (type.equals("cluster") || type.equals("Cluster")) return DynamicCluster.class.getName(); - if (type.equals("fabric") || type.equals("Fabric")) return DynamicRegionsFabric.class.getName(); - if (type.equals("vanilla") || type.equals("Vanilla")) return VanillaSoftwareProcess.class.getName(); - if (type.equals("web-app-cluster") || type.equals("WebAppCluster")) - // TODO use service discovery; currently included as string to avoid needing a reference to it - return "brooklyn.entity.webapp.ControlledDynamicWebAppCluster"; - - return type; - } - - /** Returns the CatalogItem if there is one for the given type; - * (if no type, callers should fall back to default classloading) - */ - @Nullable - public CatalogItem<Entity,EntitySpec<?>> getCatalogItem() { - String type = getBrooklynType(); - if (type != null) { - return CatalogUtils.getCatalogItemOptionalVersion(mgmt, Entity.class, type); - } else { - return null; - } - } - - public boolean canResolve() { - if (getCatalogItem()!=null) + protected boolean canResolve() { + if (typeResolver.getCatalogItem(this, type)!=null) return true; if (loader.tryLoadClass(getJavaType(), Entity.class).isPresent()) return true; @@ -208,42 +179,47 @@ public class BrooklynComponentTemplateResolver { } /** returns the entity class, if needed in contexts which scan its statics for example */ - public Class<? extends Entity> loadEntityClass() { + protected Class<? extends Entity> loadEntityClass() { Maybe<Class<? extends Entity>> result = tryLoadEntityClass(); if (result.isAbsent()) - throw new IllegalStateException("Could not find "+getBrooklynType(), ((Maybe.Absent<?>)result).getException()); + throw new IllegalStateException("Could not find "+typeResolver.getBrooklynType(type), ((Maybe.Absent<?>)result).getException()); return result.get(); } - + /** tries to load the Java entity class */ - public Maybe<Class<? extends Entity>> tryLoadEntityClass() { + protected Maybe<Class<? extends Entity>> tryLoadEntityClass() { return loader.tryLoadClass(getJavaType(), Entity.class); } - private String getJavaType() { - CatalogItem<Entity, EntitySpec<?>> item = getCatalogItem(); + // TODO Generalise to have other prefixes (e.g. explicit "catalog:" etc)? + protected boolean isJavaTypePrefix() { + return type != null && (type.toLowerCase().startsWith("java:") || type.toLowerCase().startsWith("brooklyn:java:")); + } + + protected String getJavaType() { + CatalogItem<Entity, EntitySpec<?>> item = typeResolver.getCatalogItem(this, type); if (!isJavaTypePrefix() && item != null && item.getJavaType() != null) { return item.getJavaType(); } else { - return getBrooklynType(); + return typeResolver.getBrooklynType(type); } } /** resolves the spec, updating the loader if a catalog item is loaded */ - public <T extends Entity> EntitySpec<T> resolveSpec() { + protected <T extends Entity> EntitySpec<T> resolveSpec() { if (alreadyBuilt.getAndSet(true)) throw new IllegalStateException("Spec can only be used once: "+this); - + EntitySpec<T> spec = createSpec(); populateSpec(spec); - + return spec; } @SuppressWarnings({ "unchecked", "rawtypes" }) - private <T extends Entity> EntitySpec<T> createSpec() { + protected <T extends Entity> EntitySpec<T> createSpec() { Class<T> type = (Class<T>) loadEntityClass(); - + EntitySpec<T> spec; if (type.isInterface()) { spec = EntitySpec.create(type); @@ -297,19 +273,12 @@ public class BrooklynComponentTemplateResolver { spec.configure(BrooklynCampConstants.TEMPLATE_ID, templateId); if (planId != null) spec.configure(BrooklynCampConstants.PLAN_ID, planId); - + List<Location> childLocations = new BrooklynYamlLocationResolver(mgmt).resolveLocations(attrs.getAllConfig(), true); if (childLocations != null) spec.locations(childLocations); - - decorateSpec(spec); - } - protected <T extends Entity> void decorateSpec(EntitySpec<T> spec) { - new BrooklynEntityDecorationResolver.PolicySpecResolver(yamlLoader).decorate(spec, attrs); - new BrooklynEntityDecorationResolver.EnricherSpecResolver(yamlLoader).decorate(spec, attrs); - new BrooklynEntityDecorationResolver.InitializerResolver(yamlLoader).decorate(spec, attrs); - + typeResolver.decorateSpec(this, spec); configureEntityConfig(spec); } @@ -326,20 +295,20 @@ public class BrooklynComponentTemplateResolver { if (planId != null) { entity.config().set(BrooklynCampConstants.PLAN_ID, planId); } - + if (spec.getLocations().size() > 0) { ((AbstractEntity)entity).addLocations(spec.getLocations()); } - + if (spec.getParent() != null) entity.setParent(spec.getParent()); - + return entity; } @SuppressWarnings({ "unchecked", "rawtypes" }) - private void configureEntityConfig(EntitySpec<?> spec) { + protected void configureEntityConfig(EntitySpec<?> spec) { ConfigBag bag = ConfigBag.newInstance((Map<Object, Object>) attrs.getStringKey("brooklyn.config")); - + // first take *recognised* flags and config keys from the top-level, and put them in the bag (of brooklyn.config) // (for component templates this will have been done already by BrooklynEntityMatcher, but for specs it is needed here) ConfigBag bagFlags = ConfigBag.newInstanceCopying(attrs); @@ -384,14 +353,14 @@ public class BrooklynComponentTemplateResolver { protected final ManagementContext mgmt; /* TODO find a way to make do without loader here? * it is not very nice having to serialize it; but serialization of BLCL is now relatively clean. - * + * * it is only used to instantiate classes, and now most things should be registered with catalog; * the notable exception is when one entity in a bundle is creating another in the same bundle, - * it wants to use his bundle CLC to do that. but we can set up some unique reference to the entity + * it wants to use his bundle CLC to do that. but we can set up some unique reference to the entity * which can be used to find it from mgmt, rather than pass the loader. */ private BrooklynClassLoadingContext loader = null; - + public SpecialFlagsTransformer(BrooklynClassLoadingContext loader) { this.loader = loader; mgmt = loader.getManagementContext(); @@ -405,18 +374,18 @@ public class BrooklynComponentTemplateResolver { return MutableList.copyOf(transformSpecialFlags((Iterable<?>)input)); else if (input instanceof Iterable<?>) return transformSpecialFlags((Iterable<?>)input); - else + else return transformSpecialFlags((Object)input); } - + protected Map<?, ?> transformSpecialFlags(Map<?, ?> flag) { return Maps.transformValues(flag, this); } - + protected Iterable<?> transformSpecialFlags(Iterable<?> flag) { return Iterables.transform(flag, this); } - + protected BrooklynClassLoadingContext getLoader() { if (loader!=null) return loader; // TODO currently loader will non-null unless someone has messed with the rebind files, @@ -426,7 +395,7 @@ public class BrooklynComponentTemplateResolver { if (entity!=null) return CatalogUtils.getClassLoadingContext(entity); return JavaBrooklynClassLoadingContext.create(mgmt); } - + /** * Makes additional transformations to the given flag with the extra knowledge of the flag's management context. * @return The modified flag, or the flag unchanged. @@ -442,7 +411,7 @@ public class BrooklynComponentTemplateResolver { return Factory.newInstance(getLoader(), specConfig.getSpecConfiguration()).resolveSpec(); } if (flag instanceof ManagementContextInjectable) { - if (log.isDebugEnabled()) { log.debug("Injecting Brooklyn management context info object: {}", flag); } + log.debug("Injecting Brooklyn management context info object: {}", flag); ((ManagementContextInjectable) flag).injectManagementContext(loader.getManagementContext()); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java index 8fd080b..ce814b4 100644 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java +++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java @@ -88,7 +88,7 @@ public abstract class BrooklynEntityDecorationResolver<DT> { public static class PolicySpecResolver extends BrooklynEntityDecorationResolver<PolicySpec<?>> { - protected PolicySpecResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); } + public PolicySpecResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); } @Override protected String getDecorationKind() { return "Policy"; } @Override @@ -134,7 +134,7 @@ public abstract class BrooklynEntityDecorationResolver<DT> { public static class EnricherSpecResolver extends BrooklynEntityDecorationResolver<EnricherSpec<?>> { - protected EnricherSpecResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); } + public EnricherSpecResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); } @Override protected String getDecorationKind() { return "Enricher"; } @Override @@ -157,7 +157,7 @@ public abstract class BrooklynEntityDecorationResolver<DT> { public static class InitializerResolver extends BrooklynEntityDecorationResolver<EntityInitializer> { - protected InitializerResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); } + public InitializerResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); } @Override protected String getDecorationKind() { return "Entity initializer"; } @Override http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/ChefComponentTemplateResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/ChefComponentTemplateResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/ChefComponentTemplateResolver.java deleted file mode 100644 index 83bb7cb..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/ChefComponentTemplateResolver.java +++ /dev/null @@ -1,57 +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 io.brooklyn.camp.brooklyn.spi.creation; - -import io.brooklyn.camp.spi.AbstractResource; -import brooklyn.catalog.CatalogItem; -import brooklyn.entity.Entity; -import brooklyn.entity.chef.ChefConfig; -import brooklyn.entity.chef.ChefEntity; -import brooklyn.entity.proxying.EntitySpec; -import brooklyn.management.classloading.BrooklynClassLoadingContext; -import brooklyn.util.config.ConfigBag; -import brooklyn.util.text.Strings; - -public class ChefComponentTemplateResolver extends BrooklynComponentTemplateResolver { - - public ChefComponentTemplateResolver(BrooklynClassLoadingContext loader, ConfigBag attrs, AbstractResource optionalTemplate) { - super(loader, attrs, optionalTemplate); - } - - @Override - protected String getBrooklynType() { - return ChefEntity.class.getName(); - } - - // chef: items are not in catalog - @Override - public CatalogItem<Entity, EntitySpec<?>> getCatalogItem() { - return null; - } - - @Override - protected <T extends Entity> void decorateSpec(EntitySpec<T> spec) { - if (getDeclaredType().startsWith("chef:")) { - spec.configure(ChefConfig.CHEF_COOKBOOK_PRIMARY_NAME, Strings.removeFromStart(getDeclaredType(), "chef:")); - } - - super.decorateSpec(spec); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java new file mode 100644 index 0000000..3528cee --- /dev/null +++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java @@ -0,0 +1,72 @@ +/* + * 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 io.brooklyn.camp.brooklyn.spi.creation.service; + +import io.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver; +import io.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityDecorationResolver; +import io.brooklyn.camp.spi.PlatformComponentTemplate; + +import javax.annotation.Nullable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.catalog.CatalogItem; +import brooklyn.catalog.internal.CatalogUtils; +import brooklyn.entity.Entity; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.util.text.Strings; + +/** + * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code brooklyn:} + * to Brooklyn {@link EntitySpec} instances. + */ +public class BrooklynServiceTypeResolver implements ServiceTypeResolver { + + private static final Logger log = LoggerFactory.getLogger(ServiceTypeResolver.class); + + @Override + public String getTypePrefix() { return DEFAULT_TYPE_PREFIX; } + + @Override + public String getBrooklynType(String serviceType) { + String type = Strings.removeFromStart(serviceType, getTypePrefix() + ":").trim(); + if (type == null) return null; + return type; + } + + @Nullable + @Override + public CatalogItem<Entity,EntitySpec<?>> getCatalogItem(BrooklynComponentTemplateResolver resolver, String serviceType) { + String type = getBrooklynType(serviceType); + if (type != null) { + return CatalogUtils.getCatalogItemOptionalVersion(resolver.getManagementContext(), Entity.class, type); + } else { + return null; + } + } + + @Override + public <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec) { + new BrooklynEntityDecorationResolver.PolicySpecResolver(resolver.getYamlLoader()).decorate(spec, resolver.getAttrs()); + new BrooklynEntityDecorationResolver.EnricherSpecResolver(resolver.getYamlLoader()).decorate(spec, resolver.getAttrs()); + new BrooklynEntityDecorationResolver.InitializerResolver(resolver.getYamlLoader()).decorate(spec, resolver.getAttrs()); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java new file mode 100644 index 0000000..4b33649 --- /dev/null +++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java @@ -0,0 +1,58 @@ +/* + * 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 io.brooklyn.camp.brooklyn.spi.creation.service; + +import io.brooklyn.camp.spi.PlatformComponentTemplate; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.entity.basic.VanillaSoftwareProcess; +import brooklyn.entity.group.DynamicCluster; +import brooklyn.entity.group.DynamicRegionsFabric; +import brooklyn.entity.proxying.EntitySpec; + +/** + * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code catalog:} + * to Brooklyn {@link EntitySpec} instances. + */ +public class CatalogServiceTypeResolver extends BrooklynServiceTypeResolver { + + private static final Logger log = LoggerFactory.getLogger(ServiceTypeResolver.class); + + @Override + public String getTypePrefix() { return "catalog"; } + + @Override + public String getBrooklynType(String serviceType) { + String type = super.getBrooklynType(serviceType); + if (type == null) return null; + + // TODO currently a hardcoded list of aliases; would like that to come from mgmt somehow + if (type.equals("cluster") || type.equals("Cluster")) return DynamicCluster.class.getName(); + if (type.equals("fabric") || type.equals("Fabric")) return DynamicRegionsFabric.class.getName(); + if (type.equals("vanilla") || type.equals("Vanilla")) return VanillaSoftwareProcess.class.getName(); + if (type.equals("web-app-cluster") || type.equals("WebAppCluster")) + // TODO use service discovery; currently included as string to avoid needing a reference to it + return "brooklyn.entity.webapp.ControlledDynamicWebAppCluster"; + + return type; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java new file mode 100644 index 0000000..9f266e5 --- /dev/null +++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java @@ -0,0 +1,62 @@ +/* + * 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 io.brooklyn.camp.brooklyn.spi.creation.service; + +import io.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver; +import io.brooklyn.camp.spi.PlatformComponentTemplate; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.catalog.CatalogItem; +import brooklyn.entity.Entity; +import brooklyn.entity.chef.ChefConfig; +import brooklyn.entity.chef.ChefEntity; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.util.text.Strings; + +/** + * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code chef:} + * to Brooklyn {@link EntitySpec} instances. + */ +public class ChefServiceTypeResolver extends BrooklynServiceTypeResolver { + + private static final Logger log = LoggerFactory.getLogger(ServiceTypeResolver.class); + + @Override + public String getTypePrefix() { return "chef"; } + + @Override + public String getBrooklynType(String serviceType) { + return ChefEntity.class.getName(); + } + + // chef: items are not in catalog + @Override + public CatalogItem<Entity, EntitySpec<?>> getCatalogItem(BrooklynComponentTemplateResolver resolver, String serviceType) { + return null; + } + + @Override + public <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec) { + spec.configure(ChefConfig.CHEF_COOKBOOK_PRIMARY_NAME, Strings.removeFromStart(resolver.getDeclaredType(), "chef:")); + super.decorateSpec(resolver, spec); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java new file mode 100644 index 0000000..7c30c6a --- /dev/null +++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java @@ -0,0 +1,30 @@ +/* + * 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 io.brooklyn.camp.brooklyn.spi.creation.service; + +/** + * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code java:} + * to Brooklyn {@link EntitySpec} instances. + */ +public class JavaServiceTypeResolver extends BrooklynServiceTypeResolver { + + @Override + public String getTypePrefix() { return "java"; } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java new file mode 100644 index 0000000..74c7990 --- /dev/null +++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java @@ -0,0 +1,43 @@ +/* + * 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 io.brooklyn.camp.brooklyn.spi.creation.service; + +import io.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver; +import brooklyn.catalog.CatalogItem; +import brooklyn.entity.Entity; +import brooklyn.entity.proxying.EntitySpec; + +public interface ServiceTypeResolver { + + String DEFAULT_TYPE_PREFIX = "brooklyn"; + + String getTypePrefix(); + + String getBrooklynType(String serviceType); + + /** + * Returns the {@link CatalogItem} if there is one for the given type. + * <p> + * If no type, callers should fall back to default classloading. + */ + CatalogItem<Entity, EntitySpec<?>> getCatalogItem(BrooklynComponentTemplateResolver resolver, String serviceType); + + <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec); + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/303c3884/usage/camp/src/main/resources/META-INF/services/io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/resources/META-INF/services/io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver b/usage/camp/src/main/resources/META-INF/services/io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver new file mode 100644 index 0000000..1a48ccb --- /dev/null +++ b/usage/camp/src/main/resources/META-INF/services/io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver @@ -0,0 +1,22 @@ +# +# 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. +# +io.brooklyn.camp.brooklyn.spi.creation.service.BrooklynServiceTypeResolver +io.brooklyn.camp.brooklyn.spi.creation.service.CatalogServiceTypeResolver +io.brooklyn.camp.brooklyn.spi.creation.service.ChefServiceTypeResolver +io.brooklyn.camp.brooklyn.spi.creation.service.JavaServiceTypeResolver
