http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/config/render/RendererHints.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/config/render/RendererHints.java b/core/src/main/java/brooklyn/config/render/RendererHints.java deleted file mode 100644 index 7628ac1..0000000 --- a/core/src/main/java/brooklyn/config/render/RendererHints.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package brooklyn.config.render; - -import groovy.lang.Closure; - -import java.util.Set; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.event.AttributeSensor; -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.util.GroovyJavaMethods; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; -import com.google.common.base.Functions; -import com.google.common.base.Objects; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicates; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.Multimaps; -import com.google.common.collect.SetMultimap; -import com.google.common.collect.Sets; - -/** - * Registry of hints for displaying items such as sensors, e.g. in the web console. - */ -public class RendererHints { - - private static final Logger log = LoggerFactory.getLogger(RendererHints.class); - - private static SetMultimap<Object, Hint<?>> registry = Multimaps.synchronizedSetMultimap(LinkedHashMultimap.<Object, Hint<?>>create()); - - @VisibleForTesting - public static SetMultimap<Object, Hint<?>> getRegistry() { return registry; } - - /** - * Registers a {@link Hint} against the given element. - * <p> - * Returns the element, for convenience when used in a with block after defining the element. - */ - public static <T> AttributeSensor<T> register(AttributeSensor<T> element, Hint<? super T> hintForThatElement) { return _register(element, hintForThatElement); } - /** as {@link #register(AttributeSensor, Hint)} */ - public static <T> ConfigKey<T> register(ConfigKey<T> element, Hint<? super T> hintForThatElement) { return _register(element, hintForThatElement); } - /** as {@link #register(AttributeSensor, Hint)} */ - public static <T> Class<T> register(Class<T> element, Hint<? super T> hintForThatElement) { return _register(element, hintForThatElement); } - - private static <T> T _register(T element, Hint<?> hintForThatElement) { - if (element==null) { - // can happen if being done in a static initializer in an inner class - log.error("Invalid null target for renderer hint "+hintForThatElement, new Throwable("Trace for invalid null target for renderer hint")); - } - registry.put(element, hintForThatElement); - return element; - } - - /** Returns all registered hints against the given element */ - public static Set<Hint<?>> getHintsFor(AttributeSensor<?> element) { return _getHintsFor(element, null); } - /** as {@link #getHintsFor(AttributeSensor)} */ - public static Set<Hint<?>> getHintsFor(ConfigKey<?> element) { return _getHintsFor(element, null); } - /** as {@link #getHintsFor(AttributeSensor)} */ - public static Set<Hint<?>> getHintsFor(Class<?> element) { return _getHintsFor(element, null); } - - @Deprecated /** @deprecated since 0.7.0 only supported for certain types */ - public static Set<Hint<?>> getHintsFor(Object element) { return getHintsFor(element, null); } - - @Deprecated /** @deprecated since 0.7.0 only supported for certain types */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static Set<Hint<?>> getHintsFor(Object element, Class<? extends Hint> optionalHintSuperClass) { return (Set<Hint<?>>) _getHintsFor(element, optionalHintSuperClass); } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static <T extends Hint> Set<T> _getHintsFor(Object element, Class<T> optionalHintSuperClass) { - Set<Hint<?>> found = ImmutableSet.copyOf(registry.get(element)); - if (found.isEmpty() && element instanceof Class && !Object.class.equals(element)) { - // try superclasses of the element; this seems overkill for the main use case, Entity; - // (other classes registered are typically final) - found = (Set<Hint<?>>) _getHintsFor(((Class)element).getSuperclass(), optionalHintSuperClass); - if (found.isEmpty()) { - for (Class<?> parentInterface: ((Class)element).getInterfaces()) { - found = (Set<Hint<?>>) _getHintsFor(parentInterface, optionalHintSuperClass); - if (!found.isEmpty()) - break; - } - } - } - if (optionalHintSuperClass != null) { - return (Set<T>)Sets.filter(found, Predicates.instanceOf(optionalHintSuperClass)); - } else { - return (Set<T>)found; - } - } - - /** Applies the (first) display value hint registered against the given target to the given initialValue */ - public static Object applyDisplayValueHint(AttributeSensor<?> target, Object initialValue) { return applyDisplayValueHintUnchecked(target, initialValue); } - /** as {@link #applyDisplayValueHint(AttributeSensor, Object)} */ - public static Object applyDisplayValueHint(ConfigKey<?> target, Object initialValue) { return applyDisplayValueHintUnchecked(target, initialValue); } - /** as {@link #applyDisplayValueHint(AttributeSensor, Object)} */ - public static Object applyDisplayValueHint(Class<?> target, Object initialValue) { return applyDisplayValueHintUnchecked(target, initialValue); } - - /** as {@link #applyDisplayValueHint(AttributeSensor, Object)}, but without type checking; public for those few cases where we may have lost the type */ - @Beta - public static Object applyDisplayValueHintUnchecked(Object target, Object initialValue) { return _applyDisplayValueHint(target, initialValue, true); } - @SuppressWarnings("rawtypes") - private static Object _applyDisplayValueHint(Object target, Object initialValue, boolean includeClass) { - Iterable<RendererHints.DisplayValue> hints = RendererHints._getHintsFor(target, RendererHints.DisplayValue.class); - if (Iterables.size(hints) > 1) { - log.warn("Multiple display value hints set for {}; Only one will be applied, using first", target); - } - - Optional<RendererHints.DisplayValue> hint = Optional.fromNullable(Iterables.getFirst(hints, null)); - Object value = hint.isPresent() ? hint.get().getDisplayValue(initialValue) : initialValue; - if (includeClass && value!=null && !(value instanceof String) && !(value instanceof Number) && !(value.getClass().isPrimitive())) { - value = _applyDisplayValueHint(value.getClass(), value, false); - } - return value; - } - - - /** Parent marker class for hints. */ - public static abstract class Hint<T> { } - - public static interface NamedAction { - String getActionName(); - } - - /** - * This hint describes a named action possible on something, e.g. a sensor; - * currently used in web client to show actions on sensors - */ - public static class NamedActionWithUrl<T> extends Hint<T> implements NamedAction { - private final String actionName; - private final Function<T, String> postProcessing; - - public NamedActionWithUrl(String actionName) { - this(actionName, (Function<T, String>)null); - } - - @SuppressWarnings("unchecked") @Deprecated /** @deprecated since 0.7.0 use Function */ - public NamedActionWithUrl(String actionName, Closure<String> postProcessing) { - this.actionName = actionName; - this.postProcessing = (Function<T, String>) ((postProcessing == null) ? null : GroovyJavaMethods.functionFromClosure(postProcessing)); - } - - public NamedActionWithUrl(String actionName, Function<T, String> postProcessing) { - this.actionName = actionName; - this.postProcessing = postProcessing; - } - - /** @deprecated since 0.7.0 call {@link #getUrlFromValue(Object)}, parsing the sensor value yourself */ @Deprecated - public String getUrl(Entity e, AttributeSensor<T> s) { - return getUrlFromValue(e.getAttribute(s)); - } - - public String getActionName() { - return actionName; - } - - /** this is the method invoked by web console SensorSummary, at the moment */ - public String getUrlFromValue(T v) { - String v2; - if (postProcessing != null) { - v2 = postProcessing.apply(v); - } else { - v2 = (v==null ? null : v.toString()); - } - if (v2 == null) return v2; - return v2.toString(); - } - - @Override - public int hashCode() { - return Objects.hashCode(actionName, postProcessing); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof NamedActionWithUrl)) return false; - NamedActionWithUrl<?> o = (NamedActionWithUrl<?>) obj; - return Objects.equal(actionName, o.actionName) && Objects.equal(postProcessing, o.postProcessing); - } - } - - /** - * This hint describes a transformation used to generate a display value for config keys and sensors. - * <p> - * <em><strong>Warning</strong> This is currently a {@link Beta} implementation, and - * may be changed or removed if there is a suitable alternative mechanism to achieve - * this functionality.</em> - */ - @Beta - public static class DisplayValue<T> extends Hint<T> { - private final Function<Object, String> transform; - - @SuppressWarnings("unchecked") - protected DisplayValue(Function<?, String> transform) { - this.transform = (Function<Object, String>) Preconditions.checkNotNull(transform, "transform"); - } - - public String getDisplayValue(Object v) { - String dv = transform.apply(v); - return Strings.nullToEmpty(dv); - } - - @Override - public int hashCode() { - return Objects.hashCode(transform); - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof DisplayValue)) return false; - return Objects.equal(transform, ((DisplayValue<?>)obj).transform); - } - } - - @Beta - public static <T> DisplayValue<T> displayValue(Function<T,String> transform) { - return new DisplayValue<T>(transform); - } - - @Beta - public static <T> NamedActionWithUrl<T> namedActionWithUrl(String actionName, Function<T,String> transform) { - return new NamedActionWithUrl<T>(actionName, transform); - } - - @Beta - public static <T> NamedActionWithUrl<T> namedActionWithUrl(String actionName) { - return new NamedActionWithUrl<T>(actionName); - } - - @Beta - public static <T> NamedActionWithUrl<T> namedActionWithUrl(Function<T,String> transform) { - return openWithUrl(transform); - } - - @Beta - public static <T> NamedActionWithUrl<T> namedActionWithUrl() { - return openWithUrl(); - } - - @Beta - public static <T> NamedActionWithUrl<T> openWithUrl() { - return openWithUrl((Function<T,String>) null); - } - - @Beta - public static <T> NamedActionWithUrl<T> openWithUrl(Function<T,String> transform) { - return new NamedActionWithUrl<T>("Open", transform); - } - - /** - * Forces the given sensor or config key's value to be censored. It will be - * presented as <code>********</code>. - */ - @Beta - public static <T> DisplayValue<T> censoredValue() { - return new DisplayValue<T>(Functions.constant("********")); - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java b/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java index 965d7ca..ca081e1 100644 --- a/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java +++ b/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java @@ -30,13 +30,12 @@ import org.apache.brooklyn.api.event.AttributeSensor; import org.apache.brooklyn.api.event.Sensor; import org.apache.brooklyn.api.event.SensorEvent; import org.apache.brooklyn.api.event.SensorEventListener; +import org.apache.brooklyn.core.config.BrooklynLogging; import org.apache.brooklyn.core.util.flags.TypeCoercions; import org.apache.brooklyn.util.collections.MutableMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.BrooklynLogging; - import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/enricher/basic/Aggregator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/enricher/basic/Aggregator.java b/core/src/main/java/brooklyn/enricher/basic/Aggregator.java index 4ea9b80..33c3164 100644 --- a/core/src/main/java/brooklyn/enricher/basic/Aggregator.java +++ b/core/src/main/java/brooklyn/enricher/basic/Aggregator.java @@ -31,6 +31,7 @@ import org.apache.brooklyn.api.event.Sensor; import org.apache.brooklyn.api.event.SensorEvent; import org.apache.brooklyn.api.event.SensorEventListener; import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.BrooklynLogging; import org.apache.brooklyn.core.util.flags.SetFromFlag; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; @@ -39,7 +40,6 @@ import org.apache.brooklyn.util.text.StringPredicates; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.BrooklynLogging; import brooklyn.enricher.Enrichers; import brooklyn.entity.basic.ConfigKeys; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java index 0b52b4a..6209394 100644 --- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java +++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java @@ -56,6 +56,8 @@ import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.config.ConfigKey.HasConfigKey; import org.apache.brooklyn.core.catalog.internal.CatalogUtils; +import org.apache.brooklyn.core.config.BrooklynLogging; +import org.apache.brooklyn.core.config.render.RendererHints; import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement; import org.apache.brooklyn.core.internal.BrooklynInitialization; import org.apache.brooklyn.core.internal.storage.BrooklynStorage; @@ -77,8 +79,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.brooklyn.basic.AbstractBrooklynObject; -import brooklyn.config.BrooklynLogging; -import brooklyn.config.render.RendererHints; import brooklyn.enricher.basic.AbstractEnricher; import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic; import brooklyn.entity.rebind.BasicEntityRebindSupport; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/basic/Attributes.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/basic/Attributes.java b/core/src/main/java/brooklyn/entity/basic/Attributes.java index e250062..c572264 100644 --- a/core/src/main/java/brooklyn/entity/basic/Attributes.java +++ b/core/src/main/java/brooklyn/entity/basic/Attributes.java @@ -25,9 +25,9 @@ import java.util.Map; import org.apache.brooklyn.api.event.AttributeSensor; import org.apache.brooklyn.api.event.Sensor; import org.apache.brooklyn.api.management.ManagementContext; +import org.apache.brooklyn.core.config.render.RendererHints; import org.apache.brooklyn.util.net.UserAndHostAndPort; -import brooklyn.config.render.RendererHints; import brooklyn.event.basic.BasicAttributeSensor; import brooklyn.event.basic.BasicAttributeSensorAndConfigKey; import brooklyn.event.basic.BasicNotificationSensor; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java b/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java index 82a69bf..82fa7b9 100644 --- a/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java +++ b/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java @@ -20,13 +20,13 @@ package brooklyn.entity.basic; import static brooklyn.entity.basic.ConfigKeys.*; -import brooklyn.config.BrooklynServerConfig; import brooklyn.entity.trait.Startable; import brooklyn.event.basic.AttributeSensorAndConfigKey; import brooklyn.event.basic.TemplatedStringAttributeSensorAndConfigKey; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.BrooklynServerConfig; import org.apache.brooklyn.core.util.internal.ssh.ShellTool; import org.apache.brooklyn.core.util.internal.ssh.SshTool; import org.apache.brooklyn.util.time.Duration; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/basic/DelegateEntity.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/basic/DelegateEntity.java b/core/src/main/java/brooklyn/entity/basic/DelegateEntity.java index 4731620..f355d0b 100644 --- a/core/src/main/java/brooklyn/entity/basic/DelegateEntity.java +++ b/core/src/main/java/brooklyn/entity/basic/DelegateEntity.java @@ -24,8 +24,8 @@ import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.Group; import org.apache.brooklyn.api.entity.proxying.ImplementedBy; import org.apache.brooklyn.api.event.AttributeSensor; +import org.apache.brooklyn.core.config.render.RendererHints; -import brooklyn.config.render.RendererHints; import brooklyn.event.basic.AttributeSensorAndConfigKey; import brooklyn.event.basic.Sensors; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/basic/DynamicGroupImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/basic/DynamicGroupImpl.java b/core/src/main/java/brooklyn/entity/basic/DynamicGroupImpl.java index 9451d96..68aaddf 100644 --- a/core/src/main/java/brooklyn/entity/basic/DynamicGroupImpl.java +++ b/core/src/main/java/brooklyn/entity/basic/DynamicGroupImpl.java @@ -28,6 +28,8 @@ import org.apache.brooklyn.api.event.Sensor; import org.apache.brooklyn.api.event.SensorEvent; import org.apache.brooklyn.api.event.SensorEventListener; import org.apache.brooklyn.api.management.Task; +import org.apache.brooklyn.core.config.BrooklynLogging; +import org.apache.brooklyn.core.config.BrooklynLogging.LoggingLevel; import org.apache.brooklyn.core.management.internal.CollectionChangeListener; import org.apache.brooklyn.core.management.internal.ManagementContextInternal; import org.apache.brooklyn.core.util.task.Tasks; @@ -36,9 +38,6 @@ import org.apache.brooklyn.util.exceptions.Exceptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.BrooklynLogging; -import brooklyn.config.BrooklynLogging.LoggingLevel; - import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/basic/Entities.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/basic/Entities.java b/core/src/main/java/brooklyn/entity/basic/Entities.java index d5790c2..a9699ff 100644 --- a/core/src/main/java/brooklyn/entity/basic/Entities.java +++ b/core/src/main/java/brooklyn/entity/basic/Entities.java @@ -61,6 +61,7 @@ import org.apache.brooklyn.api.policy.Enricher; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.config.ConfigKey.HasConfigKey; +import org.apache.brooklyn.core.config.BrooklynProperties; import org.apache.brooklyn.core.management.internal.EffectorUtils; import org.apache.brooklyn.core.management.internal.EntityManagerInternal; import org.apache.brooklyn.core.management.internal.LocalManagementContext; @@ -79,7 +80,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.brooklyn.basic.BrooklynObjectInternal; -import brooklyn.config.BrooklynProperties; import brooklyn.entity.effector.Effectors; import brooklyn.entity.proxying.EntityProxyImpl; import brooklyn.entity.trait.Startable; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/basic/EntityConfigMap.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/basic/EntityConfigMap.java b/core/src/main/java/brooklyn/entity/basic/EntityConfigMap.java index 409f72f..7b05572 100644 --- a/core/src/main/java/brooklyn/entity/basic/EntityConfigMap.java +++ b/core/src/main/java/brooklyn/entity/basic/EntityConfigMap.java @@ -30,6 +30,7 @@ import org.apache.brooklyn.api.management.ExecutionContext; import org.apache.brooklyn.api.management.Task; import org.apache.brooklyn.config.ConfigInheritance; import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.internal.AbstractConfigMapImpl; import org.apache.brooklyn.core.util.config.ConfigBag; import org.apache.brooklyn.core.util.flags.FlagUtils; import org.apache.brooklyn.core.util.flags.SetFromFlag; @@ -40,7 +41,6 @@ import org.apache.brooklyn.util.guava.Maybe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.internal.AbstractConfigMapImpl; import brooklyn.event.basic.StructuredConfigKey; import com.google.common.base.Predicate; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/basic/Lifecycle.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/basic/Lifecycle.java b/core/src/main/java/brooklyn/entity/basic/Lifecycle.java index 177ddd3..e3a80d5 100644 --- a/core/src/main/java/brooklyn/entity/basic/Lifecycle.java +++ b/core/src/main/java/brooklyn/entity/basic/Lifecycle.java @@ -23,14 +23,13 @@ import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; -import brooklyn.config.render.RendererHints; - import com.google.common.base.CaseFormat; import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.core.config.render.RendererHints; import org.apache.brooklyn.core.util.flags.TypeCoercions; import org.apache.brooklyn.util.text.StringFunctions; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java index 1baffd4..d81d5e2 100644 --- a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java +++ b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java @@ -39,6 +39,8 @@ import org.apache.brooklyn.api.policy.EnricherSpec; import org.apache.brooklyn.api.policy.EnricherSpec.ExtensibleEnricherSpec; import org.apache.brooklyn.config.ConfigInheritance; import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.BrooklynLogging; +import org.apache.brooklyn.core.config.BrooklynLogging.LoggingLevel; import org.apache.brooklyn.core.util.task.ValueResolver; import org.apache.brooklyn.util.collections.CollectionFunctionals; import org.apache.brooklyn.util.collections.MutableList; @@ -53,8 +55,6 @@ import org.apache.brooklyn.util.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.BrooklynLogging; -import brooklyn.config.BrooklynLogging.LoggingLevel; import brooklyn.enricher.Enrichers; import brooklyn.enricher.basic.AbstractEnricher; import brooklyn.enricher.basic.AbstractMultipleSensorAggregator; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java b/core/src/main/java/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java index 2c00e99..276011b 100644 --- a/core/src/main/java/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java +++ b/core/src/main/java/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java @@ -30,13 +30,13 @@ import org.apache.brooklyn.api.event.Sensor; import org.apache.brooklyn.api.event.SensorEvent; import org.apache.brooklyn.api.event.SensorEventListener; import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.BrooklynLogging; import org.apache.brooklyn.core.policy.basic.AbstractPolicy; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.javalang.JavaClassNames; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.BrooklynLogging; import brooklyn.entity.basic.Attributes; import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.basic.DynamicGroup; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java index b999fdf..9a40cda 100644 --- a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java +++ b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java @@ -38,6 +38,7 @@ import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.location.MachineProvisioningLocation; import org.apache.brooklyn.api.management.Task; import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.core.config.render.RendererHints; import org.apache.brooklyn.core.util.flags.TypeCoercions; import org.apache.brooklyn.core.util.task.DynamicTasks; import org.apache.brooklyn.core.util.task.TaskTags; @@ -45,7 +46,6 @@ import org.apache.brooklyn.core.util.task.Tasks; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.render.RendererHints; import brooklyn.entity.basic.AbstractGroupImpl; import brooklyn.entity.basic.DelegateEntity; import brooklyn.entity.basic.Entities; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/rebind/InitialFullRebindIteration.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/InitialFullRebindIteration.java b/core/src/main/java/brooklyn/entity/rebind/InitialFullRebindIteration.java index d6e61a6..cb57ca3 100644 --- a/core/src/main/java/brooklyn/entity/rebind/InitialFullRebindIteration.java +++ b/core/src/main/java/brooklyn/entity/rebind/InitialFullRebindIteration.java @@ -26,6 +26,7 @@ import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.rebind.RebindExceptionHandler; import org.apache.brooklyn.api.management.ha.ManagementNodeState; import org.apache.brooklyn.api.mementos.BrooklynMementoPersister; +import org.apache.brooklyn.core.config.BrooklynLogging; import org.apache.brooklyn.core.management.internal.BrooklynObjectManagementMode; import org.apache.brooklyn.core.management.internal.EntityManagerInternal; import org.apache.brooklyn.core.management.internal.LocationManagerInternal; @@ -34,7 +35,6 @@ import org.apache.brooklyn.util.text.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.BrooklynLogging; import brooklyn.entity.basic.EntityInternal; import brooklyn.entity.rebind.persister.PersistenceActivityMetrics; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java index 77a90c5..9369bd2 100644 --- a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java +++ b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java @@ -64,6 +64,8 @@ import org.apache.brooklyn.api.policy.Enricher; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.core.catalog.internal.CatalogInitialization; import org.apache.brooklyn.core.catalog.internal.CatalogUtils; +import org.apache.brooklyn.core.config.BrooklynLogging; +import org.apache.brooklyn.core.config.BrooklynLogging.LoggingLevel; import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement; import org.apache.brooklyn.core.management.internal.BrooklynObjectManagementMode; import org.apache.brooklyn.core.management.internal.BrooklynObjectManagerInternal; @@ -74,8 +76,6 @@ import org.apache.brooklyn.core.management.internal.ManagementTransitionMode; import org.apache.brooklyn.core.policy.basic.AbstractPolicy; import org.apache.brooklyn.core.util.flags.FlagUtils; -import brooklyn.config.BrooklynLogging; -import brooklyn.config.BrooklynLogging.LoggingLevel; import brooklyn.enricher.basic.AbstractEnricher; import brooklyn.entity.basic.AbstractApplication; import brooklyn.entity.basic.AbstractEntity; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java index a758c99..dfef70b 100644 --- a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java +++ b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java @@ -44,6 +44,7 @@ import org.apache.brooklyn.api.mementos.BrooklynMementoPersister; import org.apache.brooklyn.api.mementos.BrooklynMementoRawData; import org.apache.brooklyn.api.mementos.TreeNode; import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.BrooklynServerConfig; import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement; import org.apache.brooklyn.core.management.ha.HighAvailabilityManagerImpl; import org.apache.brooklyn.core.management.internal.ManagementContextInternal; @@ -60,7 +61,6 @@ import org.apache.brooklyn.util.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.BrooklynServerConfig; import brooklyn.enricher.basic.AbstractEnricher; import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.basic.Entities; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java index be116a3..3a5d093 100644 --- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java +++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java @@ -40,13 +40,13 @@ import org.apache.brooklyn.api.mementos.BrooklynMementoRawData; import org.apache.brooklyn.api.mementos.Memento; import org.apache.brooklyn.api.policy.Enricher; import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.core.config.BrooklynServerConfig; +import org.apache.brooklyn.core.config.BrooklynServerPaths; import org.apache.brooklyn.core.management.ha.ManagementPlaneSyncRecordPersisterToObjectStore; import org.apache.brooklyn.core.management.internal.LocalLocationManager; import org.apache.brooklyn.core.management.internal.ManagementContextInternal; import org.apache.brooklyn.core.util.ResourceUtils; -import brooklyn.config.BrooklynServerConfig; -import brooklyn.config.BrooklynServerPaths; import brooklyn.entity.basic.Entities; import brooklyn.entity.basic.EntityInternal; import brooklyn.entity.rebind.PersistenceExceptionHandlerImpl; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/entity/rebind/persister/FileBasedObjectStore.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/FileBasedObjectStore.java b/core/src/main/java/brooklyn/entity/rebind/persister/FileBasedObjectStore.java index aa4de92..1f46d82 100644 --- a/core/src/main/java/brooklyn/entity/rebind/persister/FileBasedObjectStore.java +++ b/core/src/main/java/brooklyn/entity/rebind/persister/FileBasedObjectStore.java @@ -36,6 +36,7 @@ import javax.annotation.Nullable; import org.apache.brooklyn.api.management.ManagementContext; import org.apache.brooklyn.api.management.ha.HighAvailabilityMode; +import org.apache.brooklyn.core.config.BrooklynServerConfig; import org.apache.brooklyn.core.util.internal.ssh.process.ProcessTool; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; @@ -47,8 +48,6 @@ import org.apache.brooklyn.util.os.Os.DeletionResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.BrooklynServerConfig; - import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Preconditions; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/event/basic/AttributeMap.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/event/basic/AttributeMap.java b/core/src/main/java/brooklyn/event/basic/AttributeMap.java index 1877a6c..43f173d 100644 --- a/core/src/main/java/brooklyn/event/basic/AttributeMap.java +++ b/core/src/main/java/brooklyn/event/basic/AttributeMap.java @@ -26,12 +26,12 @@ import java.util.Map; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.event.AttributeSensor; +import org.apache.brooklyn.core.config.BrooklynLogging; import org.apache.brooklyn.core.util.flags.TypeCoercions; import org.apache.brooklyn.util.guava.Maybe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.BrooklynLogging; import brooklyn.entity.basic.AbstractEntity; import com.google.common.base.Function; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/brooklyn/event/basic/Sensors.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/event/basic/Sensors.java b/core/src/main/java/brooklyn/event/basic/Sensors.java index d3d995f..207bb6f 100644 --- a/core/src/main/java/brooklyn/event/basic/Sensors.java +++ b/core/src/main/java/brooklyn/event/basic/Sensors.java @@ -28,13 +28,12 @@ import javax.annotation.Nullable; import org.apache.brooklyn.api.event.AttributeSensor; import org.apache.brooklyn.api.event.AttributeSensor.SensorPersistenceMode; +import org.apache.brooklyn.core.config.render.RendererHints; import org.apache.brooklyn.util.net.UserAndHostAndPort; import org.apache.brooklyn.util.text.StringFunctions; import org.apache.brooklyn.util.time.Duration; import org.apache.brooklyn.util.time.Time; -import brooklyn.config.render.RendererHints; - import com.google.common.annotations.Beta; import com.google.common.base.Function; import com.google.common.net.HostAndPort; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java index fc0ab56..7db7c9a 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java @@ -54,11 +54,9 @@ import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator; import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan; import org.apache.brooklyn.core.catalog.CatalogPredicates; import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes; +import org.apache.brooklyn.core.config.BrooklynServerConfig; import org.apache.brooklyn.core.management.internal.ManagementContextInternal; import org.apache.brooklyn.core.util.flags.TypeCoercions; - -import brooklyn.config.BrooklynServerConfig; - import org.apache.brooklyn.location.basic.BasicLocationRegistry; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java index ee36265..5eb99ef 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java @@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.management.ManagementContext; import org.apache.brooklyn.api.management.ha.ManagementNodeState; +import org.apache.brooklyn.core.config.BrooklynServerConfig; import org.apache.brooklyn.core.management.ManagementContextInjectable; import org.apache.brooklyn.core.management.internal.ManagementContextInternal; import org.apache.brooklyn.core.util.ResourceUtils; @@ -40,8 +41,6 @@ import org.apache.brooklyn.util.javalang.JavaClassNames; import org.apache.brooklyn.util.os.Os; import org.apache.brooklyn.util.text.Strings; -import brooklyn.config.BrooklynServerConfig; - import com.google.common.annotations.Beta; import com.google.common.base.Function; import com.google.common.base.Preconditions; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java index 426562e..e86d5df 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java @@ -33,6 +33,7 @@ import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.management.ManagementContext; import org.apache.brooklyn.api.management.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker; +import org.apache.brooklyn.core.config.BrooklynLogging; import org.apache.brooklyn.core.management.classloading.BrooklynClassLoadingContextSequential; import org.apache.brooklyn.core.management.classloading.JavaBrooklynClassLoadingContext; import org.apache.brooklyn.core.management.classloading.OsgiBrooklynClassLoadingContext; @@ -42,7 +43,6 @@ import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.text.Strings; import org.apache.brooklyn.util.time.Time; -import brooklyn.config.BrooklynLogging; import brooklyn.entity.basic.EntityInternal; import brooklyn.entity.rebind.RebindManagerImpl.RebindTracker; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/org/apache/brooklyn/core/config/BrooklynLogging.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/config/BrooklynLogging.java b/core/src/main/java/org/apache/brooklyn/core/config/BrooklynLogging.java new file mode 100644 index 0000000..7cd9ca9 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/config/BrooklynLogging.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.core.config; + +import org.apache.brooklyn.api.entity.Entity; +import org.slf4j.Logger; + +import brooklyn.entity.basic.EntityInternal; + +/** contains common logging categories */ +public class BrooklynLogging { + + public static final String SSH_IO = "brooklyn.SSH"; + + public static final String REST = "brooklyn.REST"; + + /** For convenience here, since SLF4J does not define such an enum */ + public static enum LoggingLevel { ERROR, WARN, INFO, DEBUG, TRACE } + + /** As methods on {@link Logger} but taking the level as an argument */ + public static final void log(Logger logger, LoggingLevel level, String message, Object... args) { + switch (level) { + case ERROR: logger.error(message, args); break; + case WARN: logger.warn(message, args); break; + case INFO: logger.info(message, args); break; + case DEBUG: logger.debug(message, args); break; + case TRACE: logger.trace(message, args); break; + } + } + + /** As methods on {@link Logger} but taking the level as an argument */ + public static final void log(Logger logger, LoggingLevel level, String message, Throwable t) { + switch (level) { + case ERROR: logger.error(message, t); break; + case WARN: logger.warn(message, t); break; + case INFO: logger.info(message, t); break; + case DEBUG: logger.debug(message, t); break; + case TRACE: logger.trace(message, t); break; + } + } + + /** returns one of three log levels depending on the read-only status of the entity; + * unknown should only be the case very early in the management cycle */ + public static LoggingLevel levelDependingIfReadOnly(Entity entity, LoggingLevel levelIfWriting, LoggingLevel levelIfReadOnly, LoggingLevel levelIfUnknown) { + if (entity==null) return levelIfUnknown; + Boolean ro = ((EntityInternal)entity).getManagementSupport().isReadOnlyRaw(); + if (ro==null) return levelIfUnknown; + if (ro) return levelIfReadOnly; + return levelIfWriting; + } + + /** as {@link #levelDependendingIfReadOnly(Entity)} with {@link LoggingLevel#DEBUG} as the default, + * but {@link LoggingLevel#TRACE} for read-only */ + public static LoggingLevel levelDebugOrTraceIfReadOnly(Entity entity) { + return levelDependingIfReadOnly(entity, LoggingLevel.DEBUG, LoggingLevel.TRACE, LoggingLevel.DEBUG); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/org/apache/brooklyn/core/config/BrooklynProperties.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/config/BrooklynProperties.java b/core/src/main/java/org/apache/brooklyn/core/config/BrooklynProperties.java new file mode 100644 index 0000000..590b208 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/config/BrooklynProperties.java @@ -0,0 +1,483 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.core.config; + +import static com.google.common.base.Preconditions.checkNotNull; +import groovy.lang.Closure; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Properties; + +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.config.ConfigKey.HasConfigKey; +import org.apache.brooklyn.config.StringConfigMap; +import org.apache.brooklyn.core.util.ResourceUtils; +import org.apache.brooklyn.core.util.config.ConfigBag; +import org.apache.brooklyn.core.util.flags.TypeCoercions; +import org.apache.brooklyn.util.collections.MutableMap; +import org.apache.brooklyn.util.guava.Maybe; +import org.apache.brooklyn.util.os.Os; +import org.apache.brooklyn.util.text.StringFunctions; +import org.apache.brooklyn.util.text.Strings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.annotations.Beta; +import com.google.common.base.CharMatcher; +import com.google.common.base.Objects; +import com.google.common.base.Predicate; +import com.google.common.base.Throwables; +import com.google.common.collect.Maps; + +import brooklyn.event.basic.BasicConfigKey; + +/** utils for accessing command-line and system-env properties; + * doesn't resolve anything (unless an execution context is supplied) + * and treats ConfigKeys as of type object when in doubt, + * or string when that is likely wanted (e.g. {@link #getFirst(Map, String...)} + * <p> + * TODO methods in this class are not thread safe. + * intention is that they are set during startup and not modified thereafter. */ +@SuppressWarnings("rawtypes") +public class BrooklynProperties extends LinkedHashMap implements StringConfigMap { + + private static final long serialVersionUID = -945875483083108978L; + private static final Logger LOG = LoggerFactory.getLogger(BrooklynProperties.class); + + public static class Factory { + /** creates a new empty {@link BrooklynProperties} */ + public static BrooklynProperties newEmpty() { + return new BrooklynProperties(); + } + + /** creates a new {@link BrooklynProperties} with contents loaded + * from the usual places, including *.properties files and environment variables */ + public static BrooklynProperties newDefault() { + return new Builder(true).build(); + } + + public static Builder builderDefault() { + return new Builder(true); + } + + public static Builder builderEmpty() { + return new Builder(true); + } + + public static class Builder { + private String defaultLocationMetadataUrl; + private String globalLocationMetadataFile = null; + private String globalPropertiesFile = null; + private String localPropertiesFile = null; + private BrooklynProperties originalProperties = null; + + /** @deprecated since 0.7.0 use static methods in {@link Factory} to create */ + public Builder() { + this(true); + } + + // TODO it's always called with true here, perhaps we don't need the argument? + private Builder(boolean setGlobalFileDefaults) { + resetDefaultLocationMetadataUrl(); + if (setGlobalFileDefaults) { + resetGlobalFiles(); + } + } + + public Builder resetDefaultLocationMetadataUrl() { + defaultLocationMetadataUrl = "classpath://brooklyn/location-metadata.properties"; + return this; + } + public Builder resetGlobalFiles() { + defaultLocationMetadataUrl = "classpath://brooklyn/location-metadata.properties"; + globalLocationMetadataFile = Os.mergePaths(Os.home(), ".brooklyn", "location-metadata.properties"); + globalPropertiesFile = Os.mergePaths(Os.home(), ".brooklyn", "brooklyn.properties"); + return this; + } + + /** + * Creates a Builder that when built, will return the BrooklynProperties passed to this constructor + */ + private Builder(BrooklynProperties originalProperties) { + this.originalProperties = new BrooklynProperties().addFromMap(originalProperties); + } + + /** + * The URL of a default location-metadata.properties (for meta-data about different locations, such as iso3166 and global lat/lon). + * Defaults to classpath://brooklyn/location-metadata.properties + */ + public Builder defaultLocationMetadataUrl(String val) { + defaultLocationMetadataUrl = checkNotNull(val, "file"); + return this; + } + + /** + * The URL of a location-metadata.properties file that appends to and overwrites values in the locationMetadataUrl. + * Defaults to ~/.brooklyn/location-metadata.properties + */ + public Builder globalLocationMetadataFile(String val) { + globalLocationMetadataFile = checkNotNull(val, "file"); + return this; + } + + /** + * The URL of a shared brooklyn.properties file. Defaults to ~/.brooklyn/brooklyn.properties. + * Can be null to disable. + */ + public Builder globalPropertiesFile(String val) { + globalPropertiesFile = val; + return this; + } + + @Beta + public boolean hasDelegateOriginalProperties() { + return this.originalProperties==null; + } + + /** + * The URL of a brooklyn.properties file specific to this launch. Appends to and overwrites values in globalPropertiesFile. + */ + public Builder localPropertiesFile(String val) { + localPropertiesFile = val; + return this; + } + + public BrooklynProperties build() { + if (originalProperties != null) + return new BrooklynProperties().addFromMap(originalProperties); + + BrooklynProperties properties = new BrooklynProperties(); + + // TODO Could also read from http://brooklyn.io, for up-to-date values? + // But might that make unit tests run very badly when developer is offline? + addPropertiesFromUrl(properties, defaultLocationMetadataUrl, false); + + addPropertiesFromFile(properties, globalLocationMetadataFile); + addPropertiesFromFile(properties, globalPropertiesFile); + addPropertiesFromFile(properties, localPropertiesFile); + + properties.addEnvironmentVars(); + properties.addSystemProperties(); + + return properties; + } + + public static Builder fromProperties(BrooklynProperties brooklynProperties) { + return new Builder(brooklynProperties); + } + + @Override + public String toString() { + return Objects.toStringHelper(this) + .omitNullValues() + .add("originalProperties", originalProperties) + .add("defaultLocationMetadataUrl", defaultLocationMetadataUrl) + .add("globalLocationMetadataUrl", globalLocationMetadataFile) + .add("globalPropertiesFile", globalPropertiesFile) + .add("localPropertiesFile", localPropertiesFile) + .toString(); + } + } + + private static void addPropertiesFromUrl(BrooklynProperties p, String url, boolean warnIfNotFound) { + if (url==null) return; + + try { + p.addFrom(ResourceUtils.create(BrooklynProperties.class).getResourceFromUrl(url)); + } catch (Exception e) { + if (warnIfNotFound) + LOG.warn("Could not load {}; continuing", url); + if (LOG.isTraceEnabled()) LOG.trace("Could not load "+url+"; continuing", e); + } + } + + private static void addPropertiesFromFile(BrooklynProperties p, String file) { + if (file==null) return; + + String fileTidied = Os.tidyPath(file); + File f = new File(fileTidied); + + if (f.exists()) { + p.addFrom(f); + } + } + } + + protected BrooklynProperties() { + } + + public BrooklynProperties addEnvironmentVars() { + addFrom(System.getenv()); + return this; + } + + public BrooklynProperties addSystemProperties() { + addFrom(System.getProperties()); + return this; + } + + public BrooklynProperties addFrom(ConfigBag cfg) { + addFrom(cfg.getAllConfig()); + return this; + } + + @SuppressWarnings("unchecked") + public BrooklynProperties addFrom(Map map) { + putAll(Maps.transformValues(map, StringFunctions.trim())); + return this; + } + + public BrooklynProperties addFrom(InputStream i) { + // Ugly way to load them in order, but Properties is a Hashtable so loses order otherwise. + @SuppressWarnings({ "serial" }) + Properties p = new Properties() { + @Override + public synchronized Object put(Object key, Object value) { + // Trim the string values to remove leading and trailing spaces + String s = (String) value; + if (Strings.isBlank(s)) { + s = Strings.EMPTY; + } else { + s = CharMatcher.BREAKING_WHITESPACE.trimFrom(s); + } + return BrooklynProperties.this.put(key, s); + } + }; + try { + p.load(i); + } catch (IOException e) { + throw Throwables.propagate(e); + } + return this; + } + + public BrooklynProperties addFrom(File f) { + if (!f.exists()) { + LOG.warn("Unable to find file '"+f.getAbsolutePath()+"' when loading properties; ignoring"); + return this; + } else { + try { + return addFrom(new FileInputStream(f)); + } catch (FileNotFoundException e) { + throw Throwables.propagate(e); + } + } + } + public BrooklynProperties addFrom(URL u) { + try { + return addFrom(u.openStream()); + } catch (IOException e) { + throw new RuntimeException("Error reading properties from "+u+": "+e, e); + } + } + /** + * @see ResourceUtils#getResourceFromUrl(String) + * + * of the form form file:///home/... or http:// or classpath://xx ; + * for convenience if not starting with xxx: it is treated as a classpath reference or a file; + * throws if not found (but does nothing if argument is null) + */ + public BrooklynProperties addFromUrl(String url) { + try { + if (url==null) return this; + return addFrom(ResourceUtils.create(this).getResourceFromUrl(url)); + } catch (Exception e) { + throw new RuntimeException("Error reading properties from "+url+": "+e, e); + } + } + + /** expects a property already set in scope, whose value is acceptable to {@link #addFromUrl(String)}; + * if property not set, does nothing */ + public BrooklynProperties addFromUrlProperty(String urlProperty) { + String url = (String) get(urlProperty); + if (url==null) addFromUrl(url); + return this; + } + + /** + * adds the indicated properties + */ + public BrooklynProperties addFromMap(Map properties) { + putAll(properties); + return this; + } + + /** inserts the value under the given key, if it was not present */ + public boolean putIfAbsent(String key, Object value) { + if (containsKey(key)) return false; + put(key, value); + return true; + } + + /** @deprecated attempts to call get with this syntax are probably mistakes; get(key, defaultValue) is fine but + * Map is unlikely the key, much more likely they meant getFirst(flags, key). + */ + @Deprecated + public String get(Map flags, String key) { + LOG.warn("Discouraged use of 'BrooklynProperties.get(Map,String)' (ambiguous); use getFirst(Map,String) or get(String) -- assuming the former"); + LOG.debug("Trace for discouraged use of 'BrooklynProperties.get(Map,String)'", + new Throwable("Arguments: "+flags+" "+key)); + return getFirst(flags, key); + } + + /** returns the value of the first key which is defined + * <p> + * takes the following flags: + * 'warnIfNone', 'failIfNone' (both taking a boolean (to use default message) or a string (which is the message)); + * and 'defaultIfNone' (a default value to return if there is no such property); defaults to no warning and null response */ + @Override + public String getFirst(String ...keys) { + return getFirst(MutableMap.of(), keys); + } + @Override + public String getFirst(Map flags, String ...keys) { + for (String k: keys) { + if (k!=null && containsKey(k)) return (String) get(k); + } + if (flags.get("warnIfNone")!=null && !Boolean.FALSE.equals(flags.get("warnIfNone"))) { + if (Boolean.TRUE.equals(flags.get("warnIfNone"))) + LOG.warn("Unable to find Brooklyn property "+keys); + else + LOG.warn(""+flags.get("warnIfNone")); + } + if (flags.get("failIfNone")!=null && !Boolean.FALSE.equals(flags.get("failIfNone"))) { + Object f = flags.get("failIfNone"); + if (f instanceof Closure) + ((Closure)f).call((Object[])keys); + if (Boolean.TRUE.equals(f)) + throw new NoSuchElementException("Brooklyn unable to find mandatory property "+keys[0]+ + (keys.length>1 ? " (or "+(keys.length-1)+" other possible names, full list is "+Arrays.asList(keys)+")" : "") ); + else + throw new NoSuchElementException(""+f); + } + if (flags.get("defaultIfNone")!=null) { + return (String) flags.get("defaultIfNone"); + } + return null; + } + + @Override + public String toString() { + return "BrooklynProperties["+size()+"]"; + } + + /** like normal map.put, except config keys are dereferenced on the way in */ + @SuppressWarnings("unchecked") + public Object put(Object key, Object value) { + if (key instanceof HasConfigKey) key = ((HasConfigKey)key).getConfigKey().getName(); + if (key instanceof ConfigKey) key = ((ConfigKey)key).getName(); + return super.put(key, value); + } + + /** like normal map.putAll, except config keys are dereferenced on the way in */ + @Override + public void putAll(Map vals) { + for (Map.Entry<?,?> entry : ((Map<?,?>)vals).entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + + @SuppressWarnings("unchecked") + public <T> Object put(HasConfigKey<T> key, T value) { + return super.put(key.getConfigKey().getName(), value); + } + + @SuppressWarnings("unchecked") + public <T> Object put(ConfigKey<T> key, T value) { + return super.put(key.getName(), value); + } + + public <T> boolean putIfAbsent(ConfigKey<T> key, T value) { + return putIfAbsent(key.getName(), value); + } + + @Override + public <T> T getConfig(ConfigKey<T> key) { + return getConfig(key, null); + } + + @Override + public <T> T getConfig(HasConfigKey<T> key) { + return getConfig(key.getConfigKey(), null); + } + + @Override + public <T> T getConfig(HasConfigKey<T> key, T defaultValue) { + return getConfig(key.getConfigKey(), defaultValue); + } + + @Override + public <T> T getConfig(ConfigKey<T> key, T defaultValue) { + // TODO does not support MapConfigKey etc where entries use subkey notation; for now, access using submap + if (!containsKey(key.getName())) { + if (defaultValue!=null) return defaultValue; + return key.getDefaultValue(); + } + Object value = get(key.getName()); + if (value==null) return null; + // no evaluation / key extraction here + return TypeCoercions.coerce(value, key.getTypeToken()); + } + + @Override + public Object getRawConfig(ConfigKey<?> key) { + return get(key.getName()); + } + + @Override + public Maybe<Object> getConfigRaw(ConfigKey<?> key, boolean includeInherited) { + if (containsKey(key.getName())) return Maybe.of(get(key.getName())); + return Maybe.absent(); + } + + @Override + public Map<ConfigKey<?>, Object> getAllConfig() { + Map<ConfigKey<?>, Object> result = new LinkedHashMap<ConfigKey<?>, Object>(); + for (Object entry: entrySet()) + result.put(new BasicConfigKey<Object>(Object.class, ""+((Map.Entry)entry).getKey()), ((Map.Entry)entry).getValue()); + return result; + } + + @Override + public BrooklynProperties submap(Predicate<ConfigKey<?>> filter) { + BrooklynProperties result = Factory.newEmpty(); + for (Object entry: entrySet()) { + ConfigKey<?> k = new BasicConfigKey<Object>(Object.class, ""+((Map.Entry)entry).getKey()); + if (filter.apply(k)) + result.put(((Map.Entry)entry).getKey(), ((Map.Entry)entry).getValue()); + } + return result; + } + + @SuppressWarnings("unchecked") + @Override + public Map<String, Object> asMapWithStringKeys() { + return this; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/68240194/core/src/main/java/org/apache/brooklyn/core/config/BrooklynServerConfig.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/config/BrooklynServerConfig.java b/core/src/main/java/org/apache/brooklyn/core/config/BrooklynServerConfig.java new file mode 100644 index 0000000..24577d3 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/config/BrooklynServerConfig.java @@ -0,0 +1,192 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.core.config; + +import static brooklyn.entity.basic.ConfigKeys.newStringConfigKey; + +import java.io.File; +import java.net.URI; +import java.util.Map; + +import org.apache.brooklyn.api.management.ManagementContext; +import org.apache.brooklyn.camp.CampPlatform; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.config.StringConfigMap; +import org.apache.brooklyn.core.catalog.internal.CatalogInitialization; +import org.apache.brooklyn.core.config.BrooklynServerConfig; +import org.apache.brooklyn.util.guava.Maybe; +import org.apache.brooklyn.util.os.Os; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.entity.basic.ConfigKeys; + +/** Config keys for the brooklyn server */ +public class BrooklynServerConfig { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(BrooklynServerConfig.class); + + /** + * Provided for setting; consumers should use {@link #getMgmtBaseDir(ManagementContext)} + */ + public static final ConfigKey<String> MGMT_BASE_DIR = newStringConfigKey( + "brooklyn.base.dir", "Directory for reading and writing all brooklyn server data", + Os.fromHome(".brooklyn")); + + @Deprecated /** @deprecated since 0.7.0 use BrooklynServerConfig routines */ + // copied here so we don't have back-ref to BrooklynConfigKeys + public static final ConfigKey<String> BROOKLYN_DATA_DIR = newStringConfigKey( + "brooklyn.datadir", "Directory for writing all brooklyn data"); + + /** + * Provided for setting; consumers should query the management context persistence subsystem + * for the actual target, or use {@link BrooklynServerPaths#newMainPersistencePathResolver(ManagementContext)} + * if trying to resolve the value + */ + public static final ConfigKey<String> PERSISTENCE_DIR = newStringConfigKey( + "brooklyn.persistence.dir", + "Directory or container name for writing persisted state"); + + public static final ConfigKey<String> PERSISTENCE_LOCATION_SPEC = newStringConfigKey( + "brooklyn.persistence.location.spec", + "Optional location spec string for an object store (e.g. jclouds:swift:URL) where persisted state should be kept; " + + "if blank or not supplied, the file system is used"); + + public static final ConfigKey<String> PERSISTENCE_BACKUPS_DIR = newStringConfigKey( + "brooklyn.persistence.backups.dir", + "Directory or container name for writing backups of persisted state; " + + "defaults to 'backups' inside the default persistence directory"); + + public static final ConfigKey<String> PERSISTENCE_BACKUPS_LOCATION_SPEC = newStringConfigKey( + "brooklyn.persistence.backups.location.spec", + "Location spec string for an object store (e.g. jclouds:swift:URL) where backups of persisted state should be kept; " + + "defaults to the local file system"); + + public static final ConfigKey<Boolean> PERSISTENCE_BACKUPS_REQUIRED_ON_PROMOTION = + ConfigKeys.newBooleanConfigKey("brooklyn.persistence.backups.required.promotion", + "Whether a backup should be made of the persisted state from the persistence location to the backup location on node promotion, " + + "before any writes from this node", true); + + public static final ConfigKey<Boolean> PERSISTENCE_BACKUPS_REQUIRED_ON_DEMOTION = + ConfigKeys.newBooleanConfigKey("brooklyn.persistence.backups.required.promotion", + "Whether a backup of in-memory state should be made to the backup persistence location on node demotion, " + + "in case other nodes might write conflicting state", true); + + /** @deprecated since 0.7.0, use {@link #PERSISTENCE_BACKUPS_ON_PROMOTION} and {@link #PERSISTENCE_BACKUPS_ON_DEMOTION}, + * which allow using a different target location and are supported on more environments (and now default to true) */ + @Deprecated + public static final ConfigKey<Boolean> PERSISTENCE_BACKUPS_REQUIRED = + ConfigKeys.newBooleanConfigKey("brooklyn.persistence.backups.required", + "Whether a backup should always be made of the persistence directory; " + + "if true, it will fail if this operation is not permitted (e.g. jclouds-based cloud object stores); " + + "if false, the persistence store will be overwritten with changes (but files not removed if they are unreadable); " + + "if null or not set, the legacy beahviour of creating backups where possible (e.g. file system) is currently used; " + + "this key is DEPRECATED in favor of promotion and demotion specific flags now defaulting to true"); + + public static final ConfigKey<String> BROOKLYN_CATALOG_URL = ConfigKeys.newStringConfigKey("brooklyn.catalog.url", + "The URL of a custom catalog.bom or catalog.xml descriptor to load"); + + /** @deprecated since 0.7.0 replaced by {@link CatalogInitialization}; also note, default removed + * (it was overridden anyway, and in almost all cases the new behaviour is still the default behaviour) */ + @Deprecated + public static final ConfigKey<org.apache.brooklyn.core.catalog.CatalogLoadMode> CATALOG_LOAD_MODE = ConfigKeys.newConfigKey(org.apache.brooklyn.core.catalog.CatalogLoadMode.class, + "brooklyn.catalog.mode", + "The mode the management context should use to load the catalog when first starting"); + + /** string used in places where the management node ID is needed to resolve a path */ + public static final String MANAGEMENT_NODE_ID_PROPERTY = "brooklyn.mgmt.node.id"; + + public static final ConfigKey<Boolean> USE_OSGI = ConfigKeys.newBooleanConfigKey("brooklyn.osgi.enabled", + "Whether OSGi is enabled, defaulting to true", true); + public static final ConfigKey<String> OSGI_CACHE_DIR = ConfigKeys.newStringConfigKey("brooklyn.osgi.cache.dir", + "Directory to use for OSGi cache, potentially including Freemarker template variables " + + "${"+MGMT_BASE_DIR.getName()+"} (which is the default for relative paths), " + + "${"+Os.TmpDirFinder.BROOKLYN_OS_TMPDIR_PROPERTY+"} if it should be in the tmp dir space, " + + "and ${"+MANAGEMENT_NODE_ID_PROPERTY+"} to include the management node ID (recommended if running multiple OSGi paths)", + "osgi/cache/${"+MANAGEMENT_NODE_ID_PROPERTY+"}/"); + public static final ConfigKey<Boolean> OSGI_CACHE_CLEAN = ConfigKeys.newBooleanConfigKey("brooklyn.osgi.cache.clean", + "Whether to delete the OSGi directory before and after use; if unset, it will delete if the node ID forms part of the cache dir path (which by default it does) to avoid file leaks"); + + public static final ConfigKey<CampPlatform> CAMP_PLATFORM = ConfigKeys.newConfigKey(CampPlatform.class, "brooklyn.camp.platform", + "Config set at brooklyn management platform to find the CampPlatform instance (bi-directional)"); + + /** @see BrooklynServerPaths#getMgmtBaseDir(ManagementContext) */ + public static String getMgmtBaseDir(ManagementContext mgmt) { + return BrooklynServerPaths.getMgmtBaseDir(mgmt); + } + /** @see BrooklynServerPaths#getMgmtBaseDir(ManagementContext) */ + public static String getMgmtBaseDir(StringConfigMap brooklynProperties) { + return BrooklynServerPaths.getMgmtBaseDir(brooklynProperties); + } + /** @see BrooklynServerPaths#getMgmtBaseDir(ManagementContext) */ + public static String getMgmtBaseDir(Map<String,?> brooklynProperties) { + return BrooklynServerPaths.getMgmtBaseDir(brooklynProperties); + } + + /** @deprecated since 0.7.0 use {@link BrooklynServerPaths#newMainPersistencePathResolver(ManagementContext)} */ + public static String getPersistenceDir(ManagementContext mgmt) { + return getPersistenceDir(mgmt.getConfig()); + } + /** @deprecated since 0.7.0 use {@link BrooklynServerPaths#newMainPersistencePathResolver(ManagementContext)} */ + public static String getPersistenceDir(StringConfigMap brooklynProperties) { + return resolvePersistencePath(null, brooklynProperties, null); + } + + /** + * @param optionalSuppliedValue + * An optional value which has been supplied explicitly + * @param brooklynProperties + * The properties map where the persistence path should be looked up if not supplied, + * along with finding the brooklyn.base.dir if needed (using file system persistence + * with a relative path) + * @param optionalObjectStoreLocationSpec + * If a location spec is supplied, this will return a container name suitable for use + * with the given object store based on brooklyn.persistence.dir; if null this method + * will return a full file system path, relative to the brooklyn.base.dir if the + * configured brooklyn.persistence.dir is not absolute + * @return The container name or full path for where persist state should be kept + * @deprecated since 0.7.0 use {@link BrooklynServerPaths#newMainPersistencePathResolver(ManagementContext)} */ + public static String resolvePersistencePath(String optionalSuppliedValue, StringConfigMap brooklynProperties, String optionalObjectStoreLocationSpec) { + return BrooklynServerPaths.newMainPersistencePathResolver(brooklynProperties).location(optionalObjectStoreLocationSpec).dir(optionalSuppliedValue).resolve(); + } + + + /** @deprecated since 0.7.0 use {@link BrooklynServerPaths#getBrooklynWebTmpDir(ManagementContext)} */ + public static File getBrooklynWebTmpDir(ManagementContext mgmt) { + return BrooklynServerPaths.getBrooklynWebTmpDir(mgmt); + } + + /** + * @return the CAMP platform associated with a management context, if there is one. + */ + public static Maybe<CampPlatform> getCampPlatform(ManagementContext mgmt) { + CampPlatform result = mgmt.getConfig().getConfig(BrooklynServerConfig.CAMP_PLATFORM); + if (result!=null) return Maybe.of(result); + return Maybe.absent("No CAMP Platform is registered with this Brooklyn management context."); + } + + /** + * @return {@link ManagementContext#getManagementNodeUri()}, located in this utility class for convenience. + */ + public static Maybe<URI> getBrooklynWebUri(ManagementContext mgmt) { + return mgmt.getManagementNodeUri(); + } + +}
