http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java deleted file mode 100644 index 699bc12..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java +++ /dev/null @@ -1,193 +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.brooklyn.BrooklynCampConstants; -import io.brooklyn.camp.brooklyn.BrooklynCampReservedKeys; -import io.brooklyn.camp.spi.PlatformComponentTemplate; -import io.brooklyn.camp.spi.PlatformComponentTemplate.Builder; -import io.brooklyn.camp.spi.pdp.AssemblyTemplateConstructor; -import io.brooklyn.camp.spi.pdp.Service; -import io.brooklyn.camp.spi.resolve.PdpMatcher; - -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.catalog.internal.BasicBrooklynCatalog; -import brooklyn.management.ManagementContext; -import brooklyn.management.classloading.BrooklynClassLoadingContext; -import brooklyn.management.classloading.JavaBrooklynClassLoadingContext; -import brooklyn.util.collections.MutableMap; -import brooklyn.util.net.Urls; -import brooklyn.util.text.Strings; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -public class BrooklynEntityMatcher implements PdpMatcher { - - private static final Logger log = LoggerFactory.getLogger(BrooklynEntityMatcher.class); - - protected final ManagementContext mgmt; - - public BrooklynEntityMatcher(ManagementContext bmc) { - this.mgmt = bmc; - } - - @Override - public boolean accepts(Object deploymentPlanItem) { - return lookupType(deploymentPlanItem) != null; - } - - /** returns the type of the given plan item, - * typically whether a Service can be matched to a Brooklyn entity, - * or null if not supported */ - protected String lookupType(Object deploymentPlanItem) { - if (deploymentPlanItem instanceof Service) { - Service service = (Service)deploymentPlanItem; - - String serviceType = service.getServiceType(); - BrooklynClassLoadingContext loader = BasicBrooklynCatalog.BrooklynLoaderTracker.getLoader(); - if (loader == null) loader = JavaBrooklynClassLoadingContext.create(mgmt); - if (BrooklynComponentTemplateResolver.Factory.supportsType(loader, serviceType)) - return serviceType; - - String protocol = Urls.getProtocol(serviceType); - if (protocol != null) { - if (BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST.contains(protocol)) { - return serviceType; - } else { - log.debug("The reference '" + serviceType + "' looks like a URL (running the CAMP Brooklyn entity-matcher) but the protocol '" + - protocol + "' isn't white listed " + BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST + ". " + - "Not recognized as catalog item or java item as well!"); - } - } - } - return null; - } - - @Override - public boolean apply(Object deploymentPlanItem, AssemblyTemplateConstructor atc) { - if (!(deploymentPlanItem instanceof Service)) return false; - - String type = lookupType(deploymentPlanItem); - if (type==null) return false; - - log.debug("Item "+deploymentPlanItem+" being instantiated with "+type); - - Object old = atc.getInstantiator(); - if (old!=null && !old.equals(BrooklynAssemblyTemplateInstantiator.class)) { - log.warn("Can't mix Brooklyn entities with non-Brooklyn entities (at present): "+old); - return false; - } - - // TODO should we build up a new type, BrooklynEntityComponentTemplate here - // complete w EntitySpec -- ie merge w BrooklynComponentTemplateResolver ? - - Builder<? extends PlatformComponentTemplate> builder = PlatformComponentTemplate.builder(); - builder.type( type.indexOf(':')==-1 ? "brooklyn:"+type : type ); - - // currently instantiator must be brooklyn at the ATC level - // optionally would be nice to support multiple/mixed instantiators, - // ie at the component level, perhaps with the first one responsible for building the app - atc.instantiator(BrooklynAssemblyTemplateInstantiator.class); - - String name = ((Service)deploymentPlanItem).getName(); - if (!Strings.isBlank(name)) builder.name(name); - - // configuration - Map<String, Object> attrs = MutableMap.copyOf( ((Service)deploymentPlanItem).getCustomAttributes() ); - - if (attrs.containsKey("id")) - builder.customAttribute("planId", attrs.remove("id")); - - Object location = attrs.remove("location"); - if (location!=null) - builder.customAttribute("location", location); - Object locations = attrs.remove("locations"); - if (locations!=null) - builder.customAttribute("locations", locations); - - MutableMap<Object, Object> brooklynFlags = MutableMap.of(); - Object origBrooklynFlags = attrs.remove(BrooklynCampReservedKeys.BROOKLYN_FLAGS); - if (origBrooklynFlags!=null) { - if (!(origBrooklynFlags instanceof Map)) - throw new IllegalArgumentException("brooklyn.flags must be a map of brooklyn flags"); - brooklynFlags.putAll((Map<?,?>)origBrooklynFlags); - } - - addCustomMapAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CONFIG); - addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_POLICIES); - addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_ENRICHERS); - addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_INITIALIZERS); - addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CHILDREN); - addCustomMapAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CATALOG); - - brooklynFlags.putAll(attrs); - if (!brooklynFlags.isEmpty()) { - builder.customAttribute(BrooklynCampReservedKeys.BROOKLYN_FLAGS, brooklynFlags); - } - - atc.add(builder.build()); - - return true; - } - - /** - * Looks for the given key in the map of attributes and adds it to the given builder - * as a custom attribute with type List. - * @throws java.lang.IllegalArgumentException if map[key] is not an instance of List - */ - private void addCustomListAttributeIfNonNull(Builder<? extends PlatformComponentTemplate> builder, Map<?,?> attrs, String key) { - Object items = attrs.remove(key); - if (items != null) { - if (items instanceof List) { - List<?> itemList = (List<?>) items; - if (!itemList.isEmpty()) { - builder.customAttribute(key, Lists.newArrayList(itemList)); - } - } else { - throw new IllegalArgumentException(key + " must be a list, is: " + items.getClass().getName()); - } - } - } - - /** - * Looks for the given key in the map of attributes and adds it to the given builder - * as a custom attribute with type Map. - * @throws java.lang.IllegalArgumentException if map[key] is not an instance of Map - */ - private void addCustomMapAttributeIfNonNull(Builder<? extends PlatformComponentTemplate> builder, Map<?,?> attrs, String key) { - Object items = attrs.remove(key); - if (items != null) { - if (items instanceof Map) { - Map<?, ?> itemMap = (Map<?, ?>) items; - if (!itemMap.isEmpty()) { - builder.customAttribute(key, Maps.newHashMap(itemMap)); - } - } else { - throw new IllegalArgumentException(key + " must be a map, is: " + items.getClass().getName()); - } - } - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java deleted file mode 100644 index 3495687..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java +++ /dev/null @@ -1,142 +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 java.util.Arrays; -import java.util.List; -import java.util.Map; - -import brooklyn.location.Location; -import brooklyn.location.LocationDefinition; -import brooklyn.management.ManagementContext; -import brooklyn.util.collections.MutableList; -import brooklyn.util.collections.MutableMap; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.guava.Maybe; -import brooklyn.util.guava.Maybe.Absent; -import brooklyn.util.text.Strings; - -import com.google.common.collect.Iterables; - -public class BrooklynYamlLocationResolver { - - protected final ManagementContext mgmt; - - public BrooklynYamlLocationResolver(ManagementContext bmc) { - this.mgmt = bmc; - } - - /** returns list of locations, if any were supplied, or null if none indicated */ - @SuppressWarnings("unchecked") - public List<Location> resolveLocations(Map<? super String,?> attrs, boolean removeUsedAttributes) { - Object location = attrs.get("location"); - Object locations = attrs.get("locations"); - - if (location==null && locations==null) - return null; - - Location locationFromString = null; - List<Location> locationsFromList = null; - - if (location!=null) { - if (location instanceof String) { - locationFromString = resolveLocationFromString((String)location); - } else if (location instanceof Map) { - locationFromString = resolveLocationFromMap((Map<?,?>)location); - } else { - throw new IllegalStateException("Illegal parameter for 'location'; must be a string or map (but got "+location+")"); - } - } - - if (locations!=null) { - if (!(locations instanceof Iterable)) - throw new IllegalStateException("Illegal parameter for 'locations'; must be an iterable (but got "+locations+")"); - locationsFromList = resolveLocations( (Iterable<Object>)locations ); - } - - if (locationFromString!=null && locationsFromList!=null) { - if (locationsFromList.size() != 1) - throw new IllegalStateException("Conflicting 'location' and 'locations' ("+location+" and "+locations+"); " - + "if both are supplied the list must have exactly one element being the same"); - if (!locationFromString.equals( Iterables.getOnlyElement(locationsFromList) )) - throw new IllegalStateException("Conflicting 'location' and 'locations' ("+location+" and "+locations+"); " - + "different location specified in each"); - } else if (locationFromString!=null) { - locationsFromList = Arrays.asList(locationFromString); - } - - return locationsFromList; - } - - public List<Location> resolveLocations(Iterable<Object> locations) { - List<Location> result = MutableList.of(); - for (Object l: locations) { - Location ll = resolveLocation(l); - if (ll!=null) result.add(ll); - } - return result; - } - - public Location resolveLocation(Object location) { - if (location instanceof String) { - return resolveLocationFromString((String)location); - } else if (location instanceof Map) { - return resolveLocationFromMap((Map<?,?>)location); - } - // could support e.g. location definition - throw new IllegalStateException("Illegal parameter for 'location' ("+location+"); must be a string or map"); - } - - /** resolves the location from the given spec string, either "Named Location", or "named:Named Location" format; - * returns null if input is blank (or null); otherwise guaranteed to resolve or throw error */ - public Location resolveLocationFromString(String location) { - if (Strings.isBlank(location)) return null; - return resolveLocation(location, MutableMap.of()); - } - - public Location resolveLocationFromMap(Map<?,?> location) { - if (location.size() > 1) { - throw new IllegalStateException("Illegal parameter for 'location'; expected a single entry in map ("+location+")"); - } - Object key = Iterables.getOnlyElement(location.keySet()); - Object value = location.get(key); - - if (!(key instanceof String)) { - throw new IllegalStateException("Illegal parameter for 'location'; expected String key ("+location+")"); - } - if (!(value instanceof Map)) { - throw new IllegalStateException("Illegal parameter for 'location'; expected config map ("+location+")"); - } - return resolveLocation((String)key, (Map<?,?>)value); - } - - protected Location resolveLocation(String spec, Map<?,?> flags) { - LocationDefinition ldef = mgmt.getLocationRegistry().getDefinedLocationByName((String)spec); - if (ldef!=null) - // found it as a named location - return mgmt.getLocationRegistry().resolve(ldef, null, flags).get(); - - Maybe<Location> l = mgmt.getLocationRegistry().resolve(spec, null, flags); - if (l.isPresent()) return l.get(); - - RuntimeException exception = ((Absent<?>)l).getException(); - throw new IllegalStateException("Illegal parameter for 'location' ("+spec+"); not resolvable: "+ - Exceptions.collapseText( exception ), exception); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java deleted file mode 100644 index b78f359..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java +++ /dev/null @@ -1,208 +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 java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.management.classloading.BrooklynClassLoadingContext; -import brooklyn.util.collections.MutableMap; -import brooklyn.util.config.ConfigBag; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.guava.Maybe; -import brooklyn.util.javalang.Reflections; -import io.brooklyn.camp.brooklyn.BrooklynCampReservedKeys; - -import com.google.common.annotations.Beta; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; - -/** Assists in loading types referenced from YAML; - * mainly as a way to share logic used in very different contexts. */ -public abstract class BrooklynYamlTypeInstantiator { - - private static final Logger log = LoggerFactory.getLogger(BrooklynYamlTypeInstantiator.class); - - protected final Factory factory; - - @Beta - public static class Factory { - final BrooklynClassLoadingContext loader; - final Object contextForLogging; - - public Factory(BrooklynClassLoadingContext loader, Object contextForLogging) { - this.loader = loader; - this.contextForLogging = contextForLogging; - } - - public InstantiatorFromKey from(Map<?,?> data) { - return new InstantiatorFromKey(this, ConfigBag.newInstance(data)); - } - - public InstantiatorFromKey from(ConfigBag data) { - return new InstantiatorFromKey(this, data); - } - - public InstantiatorFromName type(String typeName) { - return new InstantiatorFromName(this, typeName); - } - - } - - public static class InstantiatorFromKey extends BrooklynYamlTypeInstantiator { - protected final ConfigBag data; - protected String typeKeyPrefix = null; - - /** Nullable only permitted for instances which do not do loading, e.g. LoaderFromKey#lookup */ - protected InstantiatorFromKey(@Nullable Factory factory, ConfigBag data) { - super(factory); - this.data = data; - } - - public static Maybe<String> extractTypeName(String prefix, ConfigBag data) { - if (data==null) return Maybe.absent(); - return new InstantiatorFromKey(null, data).prefix(prefix).getTypeName(); - } - - public InstantiatorFromKey prefix(String prefix) { - typeKeyPrefix = prefix; - return this; - } - - public Maybe<String> getTypeName() { - Maybe<Object> result = data.getStringKeyMaybe(getPreferredKeyName()); - if (result.isAbsent() && typeKeyPrefix!=null) { - // try alternatives if a prefix was specified - result = data.getStringKeyMaybe(typeKeyPrefix+"Type"); - if (result.isAbsent()) result = data.getStringKeyMaybe("type"); - } - - if (result.isAbsent() || result.get()==null) - return Maybe.absent("Missing key '"+getPreferredKeyName()+"'"); - - if (result.get() instanceof String) return Maybe.of((String)result.get()); - - throw new IllegalArgumentException("Invalid value "+result.get().getClass()+" for "+getPreferredKeyName()+"; " - + "expected String, got "+result.get()); - } - - protected String getPreferredKeyName() { - if (typeKeyPrefix!=null) return typeKeyPrefix+"_type"; - return "type"; - } - - /** as {@link #newInstance(Class)} but inferring the type */ - public Object newInstance() { - return newInstance(null); - } - - /** creates a new instance of the type referred to by this description, - * as a subtype of the type supplied here, - * inferring a Map from <code>brooklyn.config</code> key. - * TODO in future also picking up recognized flags and config keys (those declared on the type). - * <p> - * constructs the object using: - * <li> a constructor on the class taking a Map - * <li> a no-arg constructor, only if the inferred map is empty - **/ - public <T> T newInstance(@Nullable Class<T> supertype) { - Class<? extends T> type = getType(supertype); - Map<String, ?> cfg = getConfigMap(); - Optional<? extends T> result = Reflections.invokeConstructorWithArgs(type, cfg); - if (result.isPresent()) - return result.get(); - - ConfigBag cfgBag = ConfigBag.newInstance(cfg); - result = Reflections.invokeConstructorWithArgs(type, cfgBag); - if (result.isPresent()) - return result.get(); - - if (cfg.isEmpty()) { - result = Reflections.invokeConstructorWithArgs(type); - if (result.isPresent()) - return result.get(); - } - - throw new IllegalStateException("No known mechanism for constructing type "+type+" in "+factory.contextForLogging); - } - - /** finds the map of config for the type specified; - * currently only gets <code>brooklyn.config</code>, returning empty map if none, - * but TODO in future should support recognized flags and config keys (those declared on the type), - * incorporating code in {@link BrooklynEntityMatcher}. - */ - @SuppressWarnings("unchecked") - @Nonnull - public Map<String,?> getConfigMap() { - MutableMap<String,Object> result = MutableMap.of(); - Object bc = data.getStringKey(BrooklynCampReservedKeys.BROOKLYN_CONFIG); - if (bc!=null) { - if (bc instanceof Map) - result.putAll((Map<? extends String, ?>) bc); - else - throw new IllegalArgumentException("brooklyn.config key in "+factory.contextForLogging+" should be a map, not "+bc.getClass()+" ("+bc+")"); - } - return result; - } - - } - - public static class InstantiatorFromName extends BrooklynYamlTypeInstantiator { - protected final String typeName; - protected InstantiatorFromName(Factory factory, String typeName) { - super(factory); - this.typeName = typeName; - } - - public Maybe<String> getTypeName() { - return Maybe.fromNullable(typeName); - } - } - - protected BrooklynYamlTypeInstantiator(Factory factory) { - this.factory = factory; - } - - public abstract Maybe<String> getTypeName(); - - public BrooklynClassLoadingContext getClassLoadingContext() { - Preconditions.checkNotNull(factory, "No factory set; cannot use this instance for type loading"); - return factory.loader; - } - - public Class<?> getType() { - return getType(Object.class); - } - - public <T> Class<? extends T> getType(@Nonnull Class<T> type) { - try { - return getClassLoadingContext().loadClass(getTypeName().get(), type); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - log.debug("Unable to resolve " + type + " " + getTypeName().get() + " (rethrowing) in spec " + factory.contextForLogging); - throw Exceptions.propagate(e); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java deleted file mode 100644 index 7d9a62a..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java +++ /dev/null @@ -1,58 +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 static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.entity.proxying.EntitySpec; - -import com.google.common.collect.Maps; - -/** - * Captures the {@link EntitySpec} configuration defined in YAML. - * - * This class does not parse that output; it just stores it. - */ -public class EntitySpecConfiguration { - - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(EntitySpecConfiguration.class); - - private Map<String, Object> specConfiguration; - - public EntitySpecConfiguration(Map<String, ?> specConfiguration) { - this.specConfiguration = Maps.newHashMap(checkNotNull(specConfiguration, "specConfiguration")); - } - - public Map<String, Object> getSpecConfiguration() { - return specConfiguration; - } - - /** - * Allows BrooklynComponentTemplateResolver to traverse the configuration and resolve any entity specs - */ - public void setSpecConfiguration(Map<String, Object> specConfiguration) { - this.specConfiguration = specConfiguration; - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/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 deleted file mode 100644 index 8796d0d..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java +++ /dev/null @@ -1,72 +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.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 org.apache.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/e406d1ad/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 deleted file mode 100644 index d082b13..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java +++ /dev/null @@ -1,78 +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.service; - -import io.brooklyn.camp.spi.PlatformComponentTemplate; - -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.entity.basic.VanillaSoftwareProcess; -import brooklyn.entity.brooklynnode.BrooklynNode; -import brooklyn.entity.group.DynamicCluster; -import brooklyn.entity.group.DynamicRegionsFabric; -import brooklyn.entity.java.VanillaJavaApp; -import brooklyn.entity.proxying.EntitySpec; - -import com.google.common.base.CaseFormat; -import com.google.common.base.Converter; -import com.google.common.collect.ImmutableMap; - -/** - * 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); - - // TODO currently a hardcoded list of aliases; would like that to come from mgmt somehow - private static final Map<String, String> CATALOG_TYPES = ImmutableMap.<String, String>builder() - .put("cluster", DynamicCluster.class.getName()) - .put("fabric", DynamicRegionsFabric.class.getName()) - .put("vanilla", VanillaSoftwareProcess.class.getName()) - .put("software-process", VanillaSoftwareProcess.class.getName()) - .put("java-app", VanillaJavaApp.class.getName()) - .put("brooklyn-node", BrooklynNode.class.getName()) - .put("web-app-cluster","brooklyn.entity.webapp.ControlledDynamicWebAppCluster") - .build(); - - // Allow catalog-type or CatalogType as service type string - private static final Converter<String, String> FMT = CaseFormat.LOWER_HYPHEN.converterTo(CaseFormat.UPPER_CAMEL); - - @Override - public String getTypePrefix() { return "catalog"; } - - @Override - public String getBrooklynType(String serviceType) { - String type = super.getBrooklynType(serviceType); - if (type == null) return null; - - for (String check : CATALOG_TYPES.keySet()) { - if (type.equals(check) || type.equals(FMT.convert(check))) { - return CATALOG_TYPES.get(check); - } - } - - return type; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/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 deleted file mode 100644 index c9ff893..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java +++ /dev/null @@ -1,62 +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.service; - -import io.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver; -import io.brooklyn.camp.spi.PlatformComponentTemplate; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.apache.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 the 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/e406d1ad/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 deleted file mode 100644 index f348ea8..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java +++ /dev/null @@ -1,39 +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.service; - -import io.brooklyn.camp.spi.PlatformComponentTemplate; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.entity.proxying.EntitySpec; - -/** - * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code java:} - * to Brooklyn {@link EntitySpec} instances. - */ -public class JavaServiceTypeResolver extends BrooklynServiceTypeResolver { - - private static final Logger LOG = LoggerFactory.getLogger(ServiceTypeResolver.class); - - @Override - public String getTypePrefix() { return "java"; } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/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 deleted file mode 100644 index 21b48d6..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java +++ /dev/null @@ -1,73 +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.service; - -import java.util.ServiceLoader; - -import io.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver; -import org.apache.brooklyn.catalog.CatalogItem; -import brooklyn.entity.Entity; -import brooklyn.entity.proxying.EntitySpec; - -/** - * Resolves and decorates {@link EntitySpec entity specifications} based on the {@code serviceType} in a template. - * <p> - * The {@link #getTypePrefix()} method returns a string that should match the beginning of the - * service type. The resolver implementation will use the rest of the service type information - * to create and decorate an approprate {@link EntitySpec entity}. - * <p> - * The resolvers are loaded using the {@link ServiceLoader} mechanism, allowing external libraries - * to add extra service type implementations that will be picked up at runtime. - * - * @see BrooklynServiceTypeResolver - * @see ChefServiceTypeResolver - */ -public interface ServiceTypeResolver { - - String DEFAULT_TYPE_PREFIX = "brooklyn"; - - /** - * The service type prefix the resolver is responsible for. - */ - String getTypePrefix(); - - /** - * The name of the Java type that Brooklyn will instantiate to create the - * service. This can be generated from parts of the service type information - * or may be a fixed value. - */ - 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); - - /** - * Takes the provided {@link EntitySpec} and decorates it appropriately for the service type. - * <p> - * This includes setting configuration and adding policies, enrichers and initializers. - * - * @see BrooklynServiceTypeResolver#decorateSpec(BrooklynComponentTemplateResolver, EntitySpec) - */ - <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec); - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java deleted file mode 100644 index 4f65a77..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java +++ /dev/null @@ -1,99 +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.dsl; - -import java.io.Serializable; - -import io.brooklyn.camp.spi.Assembly; -import io.brooklyn.camp.spi.AssemblyTemplate; -import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.config.ConfigKey; -import brooklyn.entity.Entity; -import brooklyn.entity.basic.Entities; -import brooklyn.entity.basic.EntityInternal; -import brooklyn.entity.effector.EffectorTasks; -import brooklyn.management.Task; -import brooklyn.management.TaskFactory; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.task.DeferredSupplier; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** provide an object suitable to resolve chained invocations in a parsed YAML / Deployment Plan DSL, - * which also implements {@link DeferredSupplier} so that they can be resolved when needed - * (e.g. when entity-lookup and execution contexts are available). - * <p> - * implementations of this abstract class are expected to be immutable, - * as instances must support usage in multiple {@link Assembly} instances - * created from a single {@link AssemblyTemplate} - * <p> - * subclasses which return a deferred value are typically only - * resolvable in the context of a {@link Task} on an {@link Entity}; - * these should be only used as the value of a {@link ConfigKey} set in the YAML, - * and should not accessed until after the components / entities are created - * and are being started. - * (TODO the precise semantics of this are under development.) - * <p> - **/ -public abstract class BrooklynDslDeferredSupplier<T> implements DeferredSupplier<T>, TaskFactory<Task<T>>, Serializable { - - private static final long serialVersionUID = -8789624905412198233L; - - private static final Logger log = LoggerFactory.getLogger(BrooklynDslDeferredSupplier.class); - - // TODO json of this object should *be* this, not wrapped this ($brooklyn:literal is a bit of a hack, though it might work!) - @JsonInclude - @JsonProperty(value="$brooklyn:literal") - // currently marked transient because it's only needed for logging - private transient Object dsl = "(gone)"; - - public BrooklynDslDeferredSupplier() { - PlanInterpretationNode sourceNode = BrooklynDslInterpreter.currentNode(); - dsl = sourceNode!=null ? sourceNode.getOriginalValue() : null; - } - - /** returns the current entity; for use in implementations of {@link #get()} */ - protected final static EntityInternal entity() { - // rely on implicit ThreadLocal for now - return (EntityInternal) EffectorTasks.findEntity(); - } - - @Override - public final synchronized T get() { - try { - if (log.isDebugEnabled()) - log.debug("Queuing task to resolve "+dsl); - T result = Entities.submit(entity(), newTask()).get(); - if (log.isDebugEnabled()) - log.debug("Resolved "+result+" from "+dsl); - return result; - } catch (Exception e) { - throw Exceptions.propagate(e); - } - } - - @Override - public abstract Task<T> newTask(); - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java deleted file mode 100644 index d661403..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java +++ /dev/null @@ -1,188 +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.dsl; - -import io.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon; -import io.brooklyn.camp.brooklyn.spi.dsl.parse.DslParser; -import io.brooklyn.camp.brooklyn.spi.dsl.parse.FunctionWithArgs; -import io.brooklyn.camp.brooklyn.spi.dsl.parse.QuotedString; -import io.brooklyn.camp.spi.resolve.PlanInterpreter; -import io.brooklyn.camp.spi.resolve.PlanInterpreter.PlanInterpreterAdapter; -import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode; -import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode.Role; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.javalang.Reflections; -import brooklyn.util.text.Strings; - -import com.google.common.base.Optional; - -/** - * {@link PlanInterpreter} which understands the $brooklyn DSL - */ -public class BrooklynDslInterpreter extends PlanInterpreterAdapter { - - private static final Logger log = LoggerFactory.getLogger(BrooklynDslInterpreter.class); - - @Override - public boolean isInterestedIn(PlanInterpretationNode node) { - return node.matchesPrefix("$brooklyn:") || node.getNewValue() instanceof FunctionWithArgs; - } - - private static ThreadLocal<PlanInterpretationNode> currentNode = new ThreadLocal<PlanInterpretationNode>(); - /** returns the current node, stored in a thread-local, to populate the dsl field of {@link BrooklynDslDeferredSupplier} instances */ - public static PlanInterpretationNode currentNode() { - return currentNode.get(); - } - /** sets the current node */ - public static void currentNode(PlanInterpretationNode node) { - currentNode.set(node); - } - public static void currentNodeClear() { - currentNode.set(null); - } - - @Override - public void applyYamlPrimitive(PlanInterpretationNode node) { - String expression = node.getNewValue().toString(); - - try { - currentNode.set(node); - Object parsedNode = new DslParser(expression).parse(); - if ((parsedNode instanceof FunctionWithArgs) && ((FunctionWithArgs)parsedNode).getArgs()==null) { - if (node.getRoleInParent() == Role.MAP_KEY) { - node.setNewValue(parsedNode); - // will be handled later - } else { - throw new IllegalStateException("Invalid function-only expression '"+((FunctionWithArgs)parsedNode).getFunction()+"'"); - } - } else { - node.setNewValue( evaluate(parsedNode, true) ); - } - } catch (Exception e) { - log.warn("Error evaluating node (rethrowing) '"+expression+"': "+e); - Exceptions.propagateIfFatal(e); - throw new IllegalArgumentException("Error evaluating node '"+expression+"'", e); - } finally { - currentNodeClear(); - } - } - - @Override - public boolean applyMapEntry(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut, - PlanInterpretationNode key, PlanInterpretationNode value) { - if (key.getNewValue() instanceof FunctionWithArgs) { - try { - currentNode.set(node); - - FunctionWithArgs f = (FunctionWithArgs) key.getNewValue(); - if (f.getArgs()!=null) - throw new IllegalStateException("Invalid map key function "+f.getFunction()+"; should not have arguments if taking arguments from map"); - - // means evaluation acts on values - List<Object> args = new ArrayList<Object>(); - if (value.getNewValue() instanceof Iterable<?>) { - for (Object vi: (Iterable<?>)value.getNewValue()) - args.add(vi); - } else { - args.add(value.getNewValue()); - } - - try { - // TODO in future we should support functions of the form 'Maps.clear', 'Maps.reset', 'Maps.remove', etc; - // default approach only supported if mapIn has single item and mapOut is empty - if (mapIn.size()!=1) - throw new IllegalStateException("Map-entry DSL syntax only supported with single item in map, not "+mapIn); - if (mapOut.size()!=0) - throw new IllegalStateException("Map-entry DSL syntax only supported with empty output map-so-far, not "+mapOut); - - node.setNewValue( evaluate(new FunctionWithArgs(f.getFunction(), args), false) ); - return false; - } catch (Exception e) { - log.warn("Error evaluating map-entry (rethrowing) '"+f.getFunction()+args+"': "+e); - Exceptions.propagateIfFatal(e); - throw new IllegalArgumentException("Error evaluating map-entry '"+f.getFunction()+args+"'", e); - } - - } finally { - currentNodeClear(); - } - } - return super.applyMapEntry(node, mapIn, mapOut, key, value); - } - - public Object evaluate(Object f, boolean deepEvaluation) { - if (f instanceof FunctionWithArgs) { - return evaluateOn(BrooklynDslCommon.class, (FunctionWithArgs) f, deepEvaluation); - } - - if (f instanceof List) { - Object o = BrooklynDslCommon.class; - for (Object i: (List<?>)f) { - o = evaluateOn( o, (FunctionWithArgs)i, deepEvaluation ); - } - return o; - } - - if (f instanceof QuotedString) { - return ((QuotedString)f).unwrapped(); - } - - throw new IllegalArgumentException("Unexpected element in parse tree: '"+f+"' (type "+(f!=null ? f.getClass() : null)+")"); - } - - public Object evaluateOn(Object o, FunctionWithArgs f, boolean deepEvaluation) { - if (f.getArgs()==null) - throw new IllegalStateException("Invalid function-only expression '"+f.getFunction()+"'"); - - Class<?> clazz; - if (o instanceof Class) { - clazz = (Class<?>)o; - } else { - clazz = o.getClass(); - } - if (!(clazz.getPackage().getName().startsWith(BrooklynDslCommon.class.getPackage().getName()))) - throw new IllegalArgumentException("Not permitted to invoke function on '"+clazz+"' (outside allowed package scope)"); - - String fn = f.getFunction(); - fn = Strings.removeFromStart(fn, "$brooklyn:"); - try { - List<Object> args = new ArrayList<Object>(); - for (Object arg: f.getArgs()) { - args.add( deepEvaluation ? evaluate(arg, true) : arg ); - } - Optional<Object> v = Reflections.invokeMethodWithArgs(o, fn, args); - if (v.isPresent()) return v.get(); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - throw Exceptions.propagate(new InvocationTargetException(e, "Error invoking '"+fn+"' on '"+o+"'")); - } - - throw new IllegalArgumentException("No such function '"+fn+"' on "+o); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java deleted file mode 100644 index 7ad8abe..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java +++ /dev/null @@ -1,44 +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.dsl; - -import brooklyn.util.task.DeferredSupplier; - -import com.google.common.collect.Iterables; - -public class DslUtils { - - /** true iff none of the args are deferred / tasks */ - public static boolean resolved(Iterable<Object> args) { - return resolved(Iterables.toArray(args, Object.class)); - } - - /** true iff none of the args are deferred / tasks */ - public static boolean resolved(final Object... args) { - boolean allResolved = true; - for (Object arg: args) { - if (arg instanceof DeferredSupplier<?>) { - allResolved = false; - break; - } - } - return allResolved; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java deleted file mode 100644 index efcdd49..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java +++ /dev/null @@ -1,302 +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.dsl.methods; - -import io.brooklyn.camp.brooklyn.BrooklynCampReservedKeys; -import io.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator; -import io.brooklyn.camp.brooklyn.spi.creation.EntitySpecConfiguration; -import io.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslDeferredSupplier; -import io.brooklyn.camp.brooklyn.spi.dsl.DslUtils; -import io.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent.Scope; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.commons.beanutils.BeanUtils; - -import brooklyn.entity.Entity; -import brooklyn.entity.basic.EntityDynamicType; -import brooklyn.entity.trait.Configurable; -import brooklyn.event.Sensor; -import brooklyn.event.basic.DependentConfiguration; -import brooklyn.management.Task; -import brooklyn.management.TaskAdaptable; -import brooklyn.management.TaskFactory; -import brooklyn.util.collections.MutableMap; -import brooklyn.util.config.ConfigBag; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.flags.ClassCoercionException; -import brooklyn.util.flags.FlagUtils; -import brooklyn.util.flags.TypeCoercions; -import brooklyn.util.javalang.Reflections; -import brooklyn.util.task.DeferredSupplier; -import brooklyn.util.text.StringEscapes.JavaStringEscapes; -import brooklyn.util.text.Strings; - -import com.google.common.base.Function; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - -/** static import functions which can be used in `$brooklyn:xxx` contexts */ -public class BrooklynDslCommon { - - // Access specific entities - - public static DslComponent entity(String id) { - return new DslComponent(Scope.GLOBAL, id); - } - public static DslComponent parent() { - return new DslComponent(Scope.PARENT, null); - } - public static DslComponent child(String id) { - return new DslComponent(Scope.CHILD, id); - } - public static DslComponent sibling(String id) { - return new DslComponent(Scope.SIBLING, id); - } - public static DslComponent descendant(String id) { - return new DslComponent(Scope.DESCENDANT, id); - } - public static DslComponent ancestor(String id) { - return new DslComponent(Scope.ANCESTOR, id); - } - // prefer the syntax above to the below now, but not deprecating the below - public static DslComponent component(String id) { - return component("global", id); - } - public static DslComponent component(String scope, String id) { - if (!DslComponent.Scope.isValid(scope)) { - throw new IllegalArgumentException(scope + " is not a valid scope"); - } - return new DslComponent(DslComponent.Scope.fromString(scope), id); - } - - // Access things on entities - - public static BrooklynDslDeferredSupplier<?> config(String keyName) { - return new DslComponent(Scope.THIS, "").config(keyName); - } - - public static BrooklynDslDeferredSupplier<?> attributeWhenReady(String sensorName) { - return new DslComponent(Scope.THIS, "").attributeWhenReady(sensorName); - } - - /** Returns a {@link Sensor}, looking up the sensor on the context if available and using that, - * or else defining an untyped (Object) sensor */ - public static BrooklynDslDeferredSupplier<Sensor<?>> sensor(String sensorName) { - return new DslComponent(Scope.THIS, "").sensor(sensorName); - } - - /** Returns a {@link Sensor} declared on the type (e.g. entity class) declared in the first argument. */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static Sensor<?> sensor(String clazzName, String sensorName) { - try { - // TODO Should use catalog's classloader, rather than Class.forName; how to get that? Should we return a future?! - Class<?> clazz = Class.forName(clazzName); - Sensor<?> sensor; - if (Entity.class.isAssignableFrom(clazz)) { - sensor = new EntityDynamicType((Class<? extends Entity>) clazz).getSensor(sensorName); - } else { - // Some non-entity classes (e.g. ServiceRestarter policy) declare sensors that other - // entities/policies/enrichers may wish to reference. - Map<String,Sensor<?>> sensors = EntityDynamicType.findSensors((Class)clazz, null); - sensor = sensors.get(sensorName); - } - if (sensor == null) { - // TODO could extend API to return a sensor of the given type; useful but makes API ambiguous in theory (unlikely in practise, but still...) - throw new IllegalArgumentException("Sensor " + sensorName + " not found on class " + clazzName); - } - return sensor; - } catch (ClassNotFoundException e) { - throw Exceptions.propagate(e); - } - } - - // Build complex things - - public static EntitySpecConfiguration entitySpec(Map<String, Object> arguments) { - return new EntitySpecConfiguration(arguments); - } - - /** - * Return an instance of the specified class with its fields set according - * to the {@link Map} or a {@link BrooklynDslDeferredSupplier} if the arguments are not - * yet fully resolved. - */ - @SuppressWarnings("unchecked") - public static Object object(Map<String, Object> arguments) { - ConfigBag config = ConfigBag.newInstance(arguments); - String typeName = BrooklynYamlTypeInstantiator.InstantiatorFromKey.extractTypeName("object", config).orNull(); - Map<String,Object> objectFields = (Map<String, Object>) config.getStringKeyMaybe("object.fields").or(MutableMap.of()); - Map<String,Object> brooklynConfig = (Map<String, Object>) config.getStringKeyMaybe(BrooklynCampReservedKeys.BROOKLYN_CONFIG).or(MutableMap.of()); - try { - // TODO Should use catalog's classloader, rather than Class.forName; how to get that? Should we return a future?! - Class<?> type = Class.forName(typeName); - if (!Reflections.hasNoArgConstructor(type)) { - throw new IllegalStateException(String.format("Cannot construct %s bean: No public no-arg constructor available", type)); - } - if ((objectFields.isEmpty() || DslUtils.resolved(objectFields.values())) && - (brooklynConfig.isEmpty() || DslUtils.resolved(brooklynConfig.values()))) { - return DslObject.create(type, objectFields, brooklynConfig); - } else { - return new DslObject(type, objectFields, brooklynConfig); - } - } catch (ClassNotFoundException e) { - throw Exceptions.propagate(e); - } - } - - // String manipulation - - /** Return the expression as a literal string without any further parsing. */ - public static Object literal(Object expression) { - return expression; - } - - /** - * Returns a formatted string or a {@link BrooklynDslDeferredSupplier} if the arguments - * are not yet fully resolved. - */ - public static Object formatString(final String pattern, final Object...args) { - if (DslUtils.resolved(args)) { - // if all args are resolved, apply the format string now - return String.format(pattern, args); - } else { - return new DslFormatString(pattern, args); - } - } - - /** - * Deferred execution of String formatting. - * - * @see DependentConfiguration#formatString(String, Object...) - */ - protected static class DslFormatString extends BrooklynDslDeferredSupplier<String> { - - private static final long serialVersionUID = -4849297712650560863L; - - private String pattern; - private Object[] args; - - public DslFormatString(String pattern, Object ...args) { - this.pattern = pattern; - this.args = args; - } - - @Override - public Task<String> newTask() { - return DependentConfiguration.formatString(pattern, args); - } - - @Override - public String toString() { - return "$brooklyn:formatString("+ - JavaStringEscapes.wrapJavaString(pattern)+ - (args==null || args.length==0 ? "" : ","+Strings.join(args, ","))+")"; - } - } - - /** @deprecated since 0.7.0; use {@link DslFormatString} */ - @SuppressWarnings("serial") - @Deprecated - protected static class FormatString extends DslFormatString { - public FormatString(String pattern, Object[] args) { - super(pattern, args); - } - } - - /** Deferred execution of Object creation. */ - protected static class DslObject extends BrooklynDslDeferredSupplier<Object> { - - private static final long serialVersionUID = 8878388748085419L; - - private Class<?> type; - private Map<String,Object> fields, config; - - public DslObject(Class<?> type, Map<String,Object> fields, Map<String,Object> config) { - this.type = type; - this.fields = MutableMap.copyOf(fields); - this.config = MutableMap.copyOf(config); - } - - @SuppressWarnings("unchecked") - @Override - public Task<Object> newTask() { - List<TaskAdaptable<Object>> tasks = Lists.newLinkedList(); - for (Object value : Iterables.concat(fields.values(), config.values())) { - if (value instanceof TaskAdaptable) { - tasks.add((TaskAdaptable<Object>) value); - } else if (value instanceof TaskFactory) { - tasks.add(((TaskFactory<TaskAdaptable<Object>>) value).newTask()); - } - } - Map<String,?> flags = MutableMap.<String,String>of("displayName", "building '"+type+"' with "+tasks.size()+" task"+(tasks.size()!=1?"s":"")); - return DependentConfiguration.transformMultiple(flags, new Function<List<Object>, Object>() { - @Override - public Object apply(List<Object> input) { - Iterator<Object> values = input.iterator(); - for (String name : fields.keySet()) { - Object value = fields.get(name); - if (value instanceof TaskAdaptable || value instanceof TaskFactory) { - fields.put(name, values.next()); - } else if (value instanceof DeferredSupplier) { - fields.put(name, ((DeferredSupplier<?>) value).get()); - } - } - for (String name : config.keySet()) { - Object value = config.get(name); - if (value instanceof TaskAdaptable || value instanceof TaskFactory) { - config.put(name, values.next()); - } else if (value instanceof DeferredSupplier) { - config.put(name, ((DeferredSupplier<?>) value).get()); - } - } - return create(type, fields, config); - } - }, tasks); - } - - public static <T> T create(Class<T> type, Map<String,?> fields, Map<String,?> config) { - try { - T bean; - try { - bean = (T) TypeCoercions.coerce(fields, type); - } catch (ClassCoercionException ex) { - bean = Reflections.invokeConstructorWithArgs(type).get(); - BeanUtils.populate(bean, fields); - } - if (bean instanceof Configurable && config.size() > 0) { - ConfigBag brooklyn = ConfigBag.newInstance(config); - FlagUtils.setFieldsFromFlags(bean, brooklyn); - FlagUtils.setAllConfigKeys((Configurable) bean, brooklyn, true); - } - return bean; - } catch (Exception e) { - throw Exceptions.propagate(e); - } - } - - @Override - public String toString() { - return "$brooklyn:object(\""+type.getName()+"\")"; - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java deleted file mode 100644 index 1cb52b3..0000000 --- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java +++ /dev/null @@ -1,320 +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.dsl.methods; - -import io.brooklyn.camp.brooklyn.BrooklynCampConstants; -import io.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslDeferredSupplier; - -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.concurrent.Callable; - -import brooklyn.entity.Entity; -import brooklyn.entity.basic.BrooklynTaskTags; -import brooklyn.entity.basic.ConfigKeys; -import brooklyn.entity.basic.Entities; -import brooklyn.entity.basic.EntityInternal; -import brooklyn.entity.basic.EntityPredicates; -import brooklyn.event.AttributeSensor; -import brooklyn.event.Sensor; -import brooklyn.event.basic.DependentConfiguration; -import brooklyn.event.basic.Sensors; -import brooklyn.management.Task; -import brooklyn.management.internal.EntityManagerInternal; -import brooklyn.util.guava.Maybe; -import brooklyn.util.task.TaskBuilder; -import brooklyn.util.task.Tasks; -import brooklyn.util.text.StringEscapes.JavaStringEscapes; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; - -public class DslComponent extends BrooklynDslDeferredSupplier<Entity> { - - private static final long serialVersionUID = -7715984495268724954L; - - private final String componentId; - private final DslComponent scopeComponent; - private final Scope scope; - - public DslComponent(String componentId) { - this(Scope.GLOBAL, componentId); - } - - public DslComponent(Scope scope, String componentId) { - this(null, scope, componentId); - } - - public DslComponent(DslComponent scopeComponent, Scope scope, String componentId) { - Preconditions.checkNotNull(scope, "scope"); - this.scopeComponent = scopeComponent; - this.componentId = componentId; - this.scope = scope; - } - - // --------------------------- - - @Override - public Task<Entity> newTask() { - return TaskBuilder.<Entity>builder().name(toString()).tag(BrooklynTaskTags.TRANSIENT_TASK_TAG) - .body(new EntityInScopeFinder(scopeComponent, scope, componentId)).build(); - } - - protected static class EntityInScopeFinder implements Callable<Entity> { - protected final DslComponent scopeComponent; - protected final Scope scope; - protected final String componentId; - - public EntityInScopeFinder(DslComponent scopeComponent, Scope scope, String componentId) { - this.scopeComponent = scopeComponent; - this.scope = scope; - this.componentId = componentId; - } - - protected EntityInternal getEntity() { - if (scopeComponent!=null) { - return (EntityInternal)scopeComponent.get(); - } else { - return entity(); - } - } - - @Override - public Entity call() throws Exception { - Iterable<Entity> entitiesToSearch = null; - switch (scope) { - case THIS: - return getEntity(); - case PARENT: - return getEntity().getParent(); - case GLOBAL: - entitiesToSearch = ((EntityManagerInternal)getEntity().getManagementContext().getEntityManager()) - .getAllEntitiesInApplication( entity().getApplication() ); - break; - case DESCENDANT: - entitiesToSearch = Entities.descendants(getEntity()); - break; - case ANCESTOR: - entitiesToSearch = Entities.ancestors(getEntity()); - break; - case SIBLING: - entitiesToSearch = getEntity().getParent().getChildren(); - break; - case CHILD: - entitiesToSearch = getEntity().getChildren(); - break; - default: - throw new IllegalStateException("Unexpected scope "+scope); - } - - Optional<Entity> result = Iterables.tryFind(entitiesToSearch, EntityPredicates.configEqualTo(BrooklynCampConstants.PLAN_ID, componentId)); - - if (result.isPresent()) - return result.get(); - - // TODO may want to block and repeat on new entities joining? - throw new NoSuchElementException("No entity matching id " + componentId+ - (scope==Scope.GLOBAL ? "" : ", in scope "+scope+" wrt "+getEntity()+ - (scopeComponent!=null ? " ("+scopeComponent+" from "+entity()+")" : ""))); - } - } - - // ------------------------------- - - // DSL words which move to a new component - - public DslComponent entity(String scopeOrId) { - return new DslComponent(this, Scope.GLOBAL, scopeOrId); - } - public DslComponent child(String scopeOrId) { - return new DslComponent(this, Scope.CHILD, scopeOrId); - } - public DslComponent sibling(String scopeOrId) { - return new DslComponent(this, Scope.SIBLING, scopeOrId); - } - public DslComponent descendant(String scopeOrId) { - return new DslComponent(this, Scope.DESCENDANT, scopeOrId); - } - public DslComponent ancestor(String scopeOrId) { - return new DslComponent(this, Scope.ANCESTOR, scopeOrId); - } - - @Deprecated /** @deprecated since 0.7.0 */ - public DslComponent component(String scopeOrId) { - return new DslComponent(this, Scope.GLOBAL, scopeOrId); - } - - public DslComponent parent() { - return new DslComponent(this, Scope.PARENT, ""); - } - - public DslComponent component(String scope, String id) { - if (!DslComponent.Scope.isValid(scope)) { - throw new IllegalArgumentException(scope + " is not a vlaid scope"); - } - return new DslComponent(this, DslComponent.Scope.fromString(scope), id); - } - - // DSL words which return things - - public BrooklynDslDeferredSupplier<?> attributeWhenReady(final String sensorName) { - return new AttributeWhenReady(this, sensorName); - } - // class simply makes the memento XML files nicer - protected static class AttributeWhenReady extends BrooklynDslDeferredSupplier<Object> { - private static final long serialVersionUID = 1740899524088902383L; - private final DslComponent component; - private final String sensorName; - public AttributeWhenReady(DslComponent component, String sensorName) { - this.component = Preconditions.checkNotNull(component); - this.sensorName = sensorName; - } - @SuppressWarnings("unchecked") - @Override - public Task<Object> newTask() { - Entity targetEntity = component.get(); - Sensor<?> targetSensor = targetEntity.getEntityType().getSensor(sensorName); - if (!(targetSensor instanceof AttributeSensor<?>)) { - targetSensor = Sensors.newSensor(Object.class, sensorName); - } - return (Task<Object>) DependentConfiguration.attributeWhenReady(targetEntity, (AttributeSensor<?>)targetSensor); - } - @Override - public String toString() { - return (component.scope==Scope.THIS ? "" : component.toString()+".") + - "attributeWhenReady("+JavaStringEscapes.wrapJavaString(sensorName)+")"; - } - } - - public BrooklynDslDeferredSupplier<?> config(final String keyName) { - return new DslConfigSupplier(this, keyName); - } - protected final static class DslConfigSupplier extends BrooklynDslDeferredSupplier<Object> { - private final DslComponent component; - private final String keyName; - private static final long serialVersionUID = -4735177561947722511L; - - public DslConfigSupplier(DslComponent component, String keyName) { - this.component = Preconditions.checkNotNull(component); - this.keyName = keyName; - } - - @Override - public Task<Object> newTask() { - return Tasks.builder().name("retrieving config for "+keyName).tag(BrooklynTaskTags.TRANSIENT_TASK_TAG).dynamic(false).body(new Callable<Object>() { - @Override - public Object call() throws Exception { - Entity targetEntity = component.get(); - return targetEntity.getConfig(ConfigKeys.newConfigKey(Object.class, keyName)); - } - }).build(); - } - - @Override - public String toString() { - return (component.scope==Scope.THIS ? "" : component.toString()+".") + - "config("+JavaStringEscapes.wrapJavaString(keyName)+")"; - } - } - - public BrooklynDslDeferredSupplier<Sensor<?>> sensor(final String sensorName) { - return new DslSensorSupplier(this, sensorName); - } - protected final static class DslSensorSupplier extends BrooklynDslDeferredSupplier<Sensor<?>> { - private final DslComponent component; - private final String sensorName; - private static final long serialVersionUID = -4735177561947722511L; - - public DslSensorSupplier(DslComponent component, String sensorName) { - this.component = Preconditions.checkNotNull(component); - this.sensorName = sensorName; - } - - @Override - public Task<Sensor<?>> newTask() { - return Tasks.<Sensor<?>>builder().name("looking up sensor for "+sensorName).dynamic(false).body(new Callable<Sensor<?>>() { - @Override - public Sensor<?> call() throws Exception { - Entity targetEntity = component.get(); - Sensor<?> result = null; - if (targetEntity!=null) { - result = targetEntity.getEntityType().getSensor(sensorName); - } - if (result!=null) return result; - return Sensors.newSensor(Object.class, sensorName); - } - }).build(); - } - - @Override - public String toString() { - return (component.scope==Scope.THIS ? "" : component.toString()+".") + - "sensor("+JavaStringEscapes.wrapJavaString(sensorName)+")"; - } - } - - public static enum Scope { - GLOBAL ("global"), - CHILD ("child"), - PARENT ("parent"), - SIBLING ("sibling"), - DESCENDANT ("descendant"), - ANCESTOR("ancestor"), - THIS ("this"); - - public static final Set<Scope> VALUES = ImmutableSet.of(GLOBAL, CHILD, PARENT, SIBLING, DESCENDANT, ANCESTOR, THIS); - - private final String name; - - private Scope(String name) { - this.name = name; - } - - public static Scope fromString(String name) { - return tryFromString(name).get(); - } - - public static Maybe<Scope> tryFromString(String name) { - for (Scope scope : VALUES) - if (scope.name.toLowerCase().equals(name.toLowerCase())) - return Maybe.of(scope); - return Maybe.absent(new IllegalArgumentException(name + " is not a valid scope")); - } - - public static boolean isValid(String name) { - for (Scope scope : VALUES) - if (scope.name.toLowerCase().equals(name.toLowerCase())) - return true; - return false; - } - } - - - @Override - public String toString() { - return "$brooklyn:entity("+ - (scopeComponent==null ? "" : JavaStringEscapes.wrapJavaString(scopeComponent.toString())+", ")+ - (scope==Scope.GLOBAL ? "" : JavaStringEscapes.wrapJavaString(scope.toString())+", ")+ - JavaStringEscapes.wrapJavaString(componentId)+ - ")"; - } - -} \ No newline at end of file
