[BROOKLYN-162] Refactor package in ./core/policy
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/6eacb3c3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/6eacb3c3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/6eacb3c3 Branch: refs/heads/master Commit: 6eacb3c38337d3c8733221b89b42fea3cdd93a23 Parents: a4c0e5f Author: Hadrian Zbarcea <[email protected]> Authored: Mon Aug 17 02:03:16 2015 -0400 Committer: Hadrian Zbarcea <[email protected]> Committed: Mon Aug 17 14:52:04 2015 -0400 ---------------------------------------------------------------------- .../main/java/brooklyn/basic/BrooklynTypes.java | 2 +- .../enricher/basic/AbstractEnricher.java | 2 +- .../brooklyn/entity/basic/AbstractEntity.java | 6 +- .../group/AbstractMembershipTrackingPolicy.java | 2 +- .../entity/proxying/InternalEntityFactory.java | 2 +- .../entity/proxying/InternalPolicyFactory.java | 2 +- .../AbstractBrooklynObjectRebindSupport.java | 2 +- .../entity/rebind/BasicEntityRebindSupport.java | 2 +- .../entity/rebind/BasicPolicyRebindSupport.java | 3 +- .../brooklyn/entity/rebind/RebindIteration.java | 2 +- .../entity/rebind/dto/MementosGenerators.java | 2 +- .../java/brooklyn/event/feed/AbstractFeed.java | 2 +- .../policy/basic/AbstractEntityAdjunct.java | 510 ------------------- .../brooklyn/policy/basic/AbstractPolicy.java | 119 ----- .../java/brooklyn/policy/basic/AdjunctType.java | 174 ------- .../brooklyn/policy/basic/ConfigMapImpl.java | 140 ----- .../policy/basic/GeneralPurposePolicy.java | 36 -- .../java/brooklyn/policy/basic/Policies.java | 73 --- .../policy/basic/PolicyDynamicType.java | 44 -- .../policy/basic/PolicyTypeSnapshot.java | 40 -- .../policy/basic/AbstractEntityAdjunct.java | 510 +++++++++++++++++++ .../core/policy/basic/AbstractPolicy.java | 119 +++++ .../brooklyn/core/policy/basic/AdjunctType.java | 174 +++++++ .../core/policy/basic/ConfigMapImpl.java | 140 +++++ .../core/policy/basic/GeneralPurposePolicy.java | 36 ++ .../brooklyn/core/policy/basic/Policies.java | 73 +++ .../core/policy/basic/PolicyDynamicType.java | 44 ++ .../core/policy/basic/PolicyTypeSnapshot.java | 40 ++ .../entity/EntityPreManagementTest.java | 2 +- .../brooklyn/entity/basic/EntitySpecTest.java | 2 +- .../entity/basic/PolicyRegistrationTest.java | 2 +- .../entity/group/GroupPickUpEntitiesTest.java | 2 +- .../entity/rebind/RebindCatalogItemTest.java | 3 +- .../entity/rebind/RebindFailuresTest.java | 2 +- .../entity/rebind/RebindPolicyTest.java | 2 +- .../brooklyn/policy/basic/BasicPolicyTest.java | 89 ---- .../brooklyn/policy/basic/EnricherTypeTest.java | 59 --- .../brooklyn/policy/basic/PolicyConfigTest.java | 202 -------- .../policy/basic/PolicySubscriptionTest.java | 125 ----- .../brooklyn/policy/basic/PolicyTypeTest.java | 58 --- .../java/brooklyn/test/policy/TestPolicy.java | 2 +- .../core/policy/basic/BasicPolicyTest.java | 90 ++++ .../core/policy/basic/EnricherTypeTest.java | 59 +++ .../core/policy/basic/PolicyConfigTest.java | 202 ++++++++ .../policy/basic/PolicySubscriptionTest.java | 128 +++++ .../core/policy/basic/PolicyTypeTest.java | 59 +++ .../policy/os/AdvertiseWinrmLoginPolicy.java | 3 +- .../brooklyn/policy/os/CreateUserPolicy.java | 2 +- .../policy/autoscaling/AutoScalerPolicy.java | 2 +- .../policy/followthesun/FollowTheSunPolicy.java | 2 +- .../policy/ha/AbstractFailureDetector.java | 2 +- .../policy/ha/ConditionalSuspendPolicy.java | 2 +- .../brooklyn/policy/ha/ServiceReplacer.java | 2 +- .../brooklyn/policy/ha/ServiceRestarter.java | 2 +- .../loadbalancing/LoadBalancingPolicy.java | 2 +- .../camp/brooklyn/TestReferencingPolicy.java | 2 +- .../apache/brooklyn/cli/lister/ClassFinder.java | 2 +- .../brooklyn/rest/resources/PolicyResource.java | 4 +- .../rest/transform/PolicyTransformer.java | 2 +- .../rest/util/BrooklynRestResourceUtils.java | 2 +- .../rest/testing/mocks/CapitalizePolicy.java | 3 +- .../testing/mocks/RestMockSimplePolicy.java | 2 +- .../util/BrooklynRestResourceUtilsTest.java | 2 +- .../java/brooklyn/osgi/tests/SimplePolicy.java | 2 +- .../brooklyn/osgi/tests/more/MorePolicy.java | 3 +- .../brooklyn/osgi/tests/more/MorePolicy.java | 2 +- 66 files changed, 1716 insertions(+), 1718 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/basic/BrooklynTypes.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/basic/BrooklynTypes.java b/core/src/main/java/brooklyn/basic/BrooklynTypes.java index 64dbcd0..780349f 100644 --- a/core/src/main/java/brooklyn/basic/BrooklynTypes.java +++ b/core/src/main/java/brooklyn/basic/BrooklynTypes.java @@ -26,11 +26,11 @@ import org.apache.brooklyn.api.event.Sensor; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.policy.Enricher; import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.core.policy.basic.PolicyDynamicType; import brooklyn.config.ConfigKey; import brooklyn.enricher.basic.EnricherDynamicType; import brooklyn.entity.basic.EntityDynamicType; -import brooklyn.policy.basic.PolicyDynamicType; import brooklyn.util.exceptions.Exceptions; import com.google.common.collect.Maps; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java b/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java index 5bca143..651ea56 100644 --- a/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java +++ b/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java @@ -29,6 +29,7 @@ import org.apache.brooklyn.api.event.Sensor; import org.apache.brooklyn.api.mementos.EnricherMemento; import org.apache.brooklyn.api.policy.Enricher; import org.apache.brooklyn.api.policy.EnricherType; +import org.apache.brooklyn.core.policy.basic.AbstractEntityAdjunct; import org.apache.brooklyn.core.util.flags.TypeCoercions; import brooklyn.config.ConfigKey; @@ -36,7 +37,6 @@ import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.basic.Entities; import brooklyn.entity.basic.EntityInternal; import brooklyn.entity.rebind.BasicEnricherRebindSupport; -import brooklyn.policy.basic.AbstractEntityAdjunct; import com.google.common.base.Objects; import com.google.common.collect.Maps; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/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 4bdae46..b004754 100644 --- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java +++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java @@ -60,6 +60,9 @@ import org.apache.brooklyn.core.management.internal.EffectorUtils; import org.apache.brooklyn.core.management.internal.EntityManagementSupport; import org.apache.brooklyn.core.management.internal.ManagementContextInternal; import org.apache.brooklyn.core.management.internal.SubscriptionTracker; +import org.apache.brooklyn.core.policy.basic.AbstractEntityAdjunct; +import org.apache.brooklyn.core.policy.basic.AbstractPolicy; +import org.apache.brooklyn.core.policy.basic.AbstractEntityAdjunct.AdjunctTagSupport; import org.apache.brooklyn.core.util.config.ConfigBag; import org.apache.brooklyn.core.util.flags.FlagUtils; import org.apache.brooklyn.core.util.flags.TypeCoercions; @@ -88,9 +91,6 @@ import brooklyn.internal.storage.impl.BasicReference; import org.apache.brooklyn.location.basic.Locations; -import brooklyn.policy.basic.AbstractEntityAdjunct; -import brooklyn.policy.basic.AbstractEntityAdjunct.AdjunctTagSupport; -import brooklyn.policy.basic.AbstractPolicy; import brooklyn.util.collections.MutableList; import brooklyn.util.collections.MutableMap; import brooklyn.util.collections.MutableSet; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/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 5647975..400506f 100644 --- a/core/src/main/java/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java +++ b/core/src/main/java/brooklyn/entity/group/AbstractMembershipTrackingPolicy.java @@ -29,6 +29,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal; 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.policy.basic.AbstractPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,7 +38,6 @@ import brooklyn.config.ConfigKey; import brooklyn.entity.basic.Attributes; import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.basic.DynamicGroup; -import brooklyn.policy.basic.AbstractPolicy; import brooklyn.util.collections.MutableMap; import brooklyn.util.javalang.JavaClassNames; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java b/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java index 1c1a920..eb601ed 100644 --- a/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java +++ b/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java @@ -37,6 +37,7 @@ import org.apache.brooklyn.api.policy.EnricherSpec; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.core.management.internal.ManagementContextInternal; +import org.apache.brooklyn.core.policy.basic.AbstractPolicy; import org.apache.brooklyn.core.util.flags.FlagUtils; import org.apache.brooklyn.core.util.task.Tasks; import org.slf4j.Logger; @@ -48,7 +49,6 @@ import brooklyn.entity.basic.AbstractEntity; import brooklyn.entity.basic.BrooklynTaskTags; import brooklyn.entity.basic.Entities; import brooklyn.entity.basic.EntityInternal; -import brooklyn.policy.basic.AbstractPolicy; import brooklyn.util.collections.MutableMap; import brooklyn.util.collections.MutableSet; import brooklyn.util.exceptions.Exceptions; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java b/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java index 7c53404..c174dcb 100644 --- a/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java +++ b/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java @@ -27,12 +27,12 @@ import org.apache.brooklyn.api.policy.EnricherSpec; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.core.management.internal.ManagementContextInternal; +import org.apache.brooklyn.core.policy.basic.AbstractPolicy; import org.apache.brooklyn.core.util.config.ConfigBag; import brooklyn.config.ConfigKey; import brooklyn.enricher.basic.AbstractEnricher; import brooklyn.entity.basic.AbstractEntity; -import brooklyn.policy.basic.AbstractPolicy; import brooklyn.util.collections.MutableMap; import brooklyn.util.exceptions.Exceptions; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java index 19a6cd6..000a651 100644 --- a/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java +++ b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java @@ -22,12 +22,12 @@ import org.apache.brooklyn.api.entity.rebind.RebindContext; import org.apache.brooklyn.api.entity.rebind.RebindSupport; import org.apache.brooklyn.api.mementos.Memento; import org.apache.brooklyn.api.policy.EntityAdjunct; +import org.apache.brooklyn.core.policy.basic.AbstractEntityAdjunct.AdjunctTagSupport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import brooklyn.basic.AbstractBrooklynObject; import brooklyn.entity.rebind.dto.MementosGenerators; -import brooklyn.policy.basic.AbstractEntityAdjunct.AdjunctTagSupport; import brooklyn.util.text.Strings; public abstract class AbstractBrooklynObjectRebindSupport<T extends Memento> implements RebindSupport<T> { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java index 3a29595..f059a83 100644 --- a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java +++ b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java @@ -31,6 +31,7 @@ import org.apache.brooklyn.api.entity.rebind.RebindContext; import org.apache.brooklyn.api.event.AttributeSensor; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.mementos.EntityMemento; +import org.apache.brooklyn.core.policy.basic.AbstractPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,7 +42,6 @@ import brooklyn.entity.basic.AbstractGroupImpl; import brooklyn.entity.basic.EntityInternal; import brooklyn.entity.rebind.dto.MementosGenerators; import brooklyn.event.feed.AbstractFeed; -import brooklyn.policy.basic.AbstractPolicy; import brooklyn.util.exceptions.Exceptions; import com.google.common.base.Throwables; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java index 4623225..e511ce2 100644 --- a/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java +++ b/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java @@ -20,11 +20,10 @@ package brooklyn.entity.rebind; import org.apache.brooklyn.api.entity.rebind.RebindContext; import org.apache.brooklyn.api.mementos.PolicyMemento; +import org.apache.brooklyn.core.policy.basic.AbstractPolicy; import org.apache.brooklyn.core.util.config.ConfigBag; import org.apache.brooklyn.core.util.flags.FlagUtils; -import brooklyn.policy.basic.AbstractPolicy; - public class BasicPolicyRebindSupport extends AbstractBrooklynObjectRebindSupport<PolicyMemento> { private final AbstractPolicy policy; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/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 67d20ae..eb1a461 100644 --- a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java +++ b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java @@ -73,6 +73,7 @@ import org.apache.brooklyn.core.management.internal.EntityManagerInternal; import org.apache.brooklyn.core.management.internal.LocationManagerInternal; import org.apache.brooklyn.core.management.internal.ManagementContextInternal; 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; @@ -92,7 +93,6 @@ import brooklyn.event.feed.AbstractFeed; import org.apache.brooklyn.location.basic.AbstractLocation; import org.apache.brooklyn.location.basic.LocationInternal; -import brooklyn.policy.basic.AbstractPolicy; import brooklyn.util.collections.MutableList; import brooklyn.util.collections.MutableMap; import brooklyn.util.exceptions.Exceptions; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java index 5c52788..301211d 100644 --- a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java +++ b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java @@ -50,6 +50,7 @@ import org.apache.brooklyn.api.policy.Enricher; import org.apache.brooklyn.api.policy.EntityAdjunct; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.core.catalog.internal.CatalogItemDo; +import org.apache.brooklyn.core.policy.basic.AbstractPolicy; import org.apache.brooklyn.core.util.config.ConfigBag; import org.apache.brooklyn.core.util.flags.FlagUtils; @@ -64,7 +65,6 @@ import brooklyn.event.feed.AbstractFeed; import org.apache.brooklyn.location.basic.LocationInternal; -import brooklyn.policy.basic.AbstractPolicy; import brooklyn.util.collections.MutableMap; import com.google.common.annotations.Beta; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/event/feed/AbstractFeed.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/event/feed/AbstractFeed.java b/core/src/main/java/brooklyn/event/feed/AbstractFeed.java index 23037a7..59ed4f7 100644 --- a/core/src/main/java/brooklyn/event/feed/AbstractFeed.java +++ b/core/src/main/java/brooklyn/event/feed/AbstractFeed.java @@ -27,6 +27,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal; import org.apache.brooklyn.api.entity.rebind.RebindSupport; import org.apache.brooklyn.api.mementos.FeedMemento; import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement; +import org.apache.brooklyn.core.policy.basic.AbstractEntityAdjunct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,7 +35,6 @@ import brooklyn.config.ConfigKey; import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.basic.EntityInternal; import brooklyn.entity.rebind.BasicFeedRebindSupport; -import brooklyn.policy.basic.AbstractEntityAdjunct; import brooklyn.util.javalang.JavaClassNames; import brooklyn.util.text.Strings; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java deleted file mode 100644 index afa015f..0000000 --- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package brooklyn.policy.basic; - -import static brooklyn.util.GroovyJavaMethods.truth; -import static com.google.common.base.Preconditions.checkState; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.entity.Group; -import org.apache.brooklyn.api.entity.basic.EntityLocal; -import org.apache.brooklyn.api.entity.trait.Configurable; -import org.apache.brooklyn.api.event.AttributeSensor; -import org.apache.brooklyn.api.event.Sensor; -import org.apache.brooklyn.api.event.SensorEventListener; -import org.apache.brooklyn.api.management.ExecutionContext; -import org.apache.brooklyn.api.management.SubscriptionContext; -import org.apache.brooklyn.api.management.SubscriptionHandle; -import org.apache.brooklyn.api.management.Task; -import org.apache.brooklyn.api.policy.EntityAdjunct; -import org.apache.brooklyn.core.management.internal.SubscriptionTracker; -import org.apache.brooklyn.core.util.config.ConfigBag; -import org.apache.brooklyn.core.util.flags.FlagUtils; -import org.apache.brooklyn.core.util.flags.SetFromFlag; -import org.apache.brooklyn.core.util.flags.TypeCoercions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.basic.AbstractBrooklynObject; -import brooklyn.basic.BrooklynObjectInternal; -import brooklyn.config.ConfigKey; -import brooklyn.config.ConfigKey.HasConfigKey; -import brooklyn.config.ConfigMap; -import brooklyn.enricher.basic.AbstractEnricher; -import brooklyn.entity.basic.ConfigKeys; -import brooklyn.entity.basic.Entities; -import brooklyn.entity.basic.EntityInternal; -import brooklyn.util.guava.Maybe; -import brooklyn.util.text.Strings; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; - - -/** - * Common functionality for policies and enrichers - */ -public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject implements BrooklynObjectInternal, EntityAdjunct, Configurable { - private static final Logger log = LoggerFactory.getLogger(AbstractEntityAdjunct.class); - - private boolean _legacyNoConstructionInit; - - /** - * @deprecated since 0.7.0; leftover properties are put into config, since when coming from yaml this is normal. - */ - @Deprecated - protected Map<String,Object> leftoverProperties = Maps.newLinkedHashMap(); - - protected transient ExecutionContext execution; - - private final BasicConfigurationSupport config = new BasicConfigurationSupport(); - - /** - * The config values of this entity. Updating this map should be done - * via {@link #config()}. - * - * @deprecated since 0.7.0; use {@link #config()} instead; this field may be made private or deleted in a future release. - */ - @Deprecated - protected final ConfigMapImpl configsInternal = new ConfigMapImpl(this); - - /** - * @deprecated since 0.7.0; use {@link #getAdjunctType()} instead; this field may be made private or deleted in a future release. - */ - @Deprecated - protected final AdjunctType adjunctType = new AdjunctType(this); - - @SetFromFlag - protected String name; - - protected transient EntityLocal entity; - - /** not for direct access; refer to as 'subscriptionTracker' via getter so that it is initialized */ - protected transient SubscriptionTracker _subscriptionTracker; - - private AtomicBoolean destroyed = new AtomicBoolean(false); - - @SetFromFlag(value="uniqueTag") - protected String uniqueTag; - - public AbstractEntityAdjunct() { - this(Collections.emptyMap()); - } - - public AbstractEntityAdjunct(@SuppressWarnings("rawtypes") Map properties) { - super(properties); - _legacyNoConstructionInit = (properties != null) && Boolean.TRUE.equals(properties.get("noConstructionInit")); - - if (isLegacyConstruction()) { - AbstractBrooklynObject checkWeGetThis = configure(properties); - assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this; - - boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class)); - if (!deferConstructionChecks) { - FlagUtils.checkRequiredFields(this); - } - } - } - - /** - * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly - */ - @Override - @Deprecated - @SuppressWarnings({ "unchecked", "rawtypes" }) - public AbstractEntityAdjunct configure(Map flags) { - // TODO only set on first time through - boolean isFirstTime = true; - - // allow config keys, and fields, to be set from these flags if they have a SetFromFlag annotation - // or if the value is a config key - for (Iterator<Map.Entry> iter = flags.entrySet().iterator(); iter.hasNext();) { - Map.Entry entry = iter.next(); - if (entry.getKey() instanceof ConfigKey) { - ConfigKey key = (ConfigKey)entry.getKey(); - if (adjunctType.getConfigKeys().contains(key)) { - setConfig(key, entry.getValue()); - } else { - log.warn("Unknown configuration key {} for policy {}; ignoring", key, this); - iter.remove(); - } - } - } - - ConfigBag bag = new ConfigBag().putAll(flags); - FlagUtils.setFieldsFromFlags(this, bag, isFirstTime); - FlagUtils.setAllConfigKeys(this, bag, false); - leftoverProperties.putAll(bag.getUnusedConfig()); - - //replace properties _contents_ with leftovers so subclasses see leftovers only - flags.clear(); - flags.putAll(leftoverProperties); - leftoverProperties = flags; - - if (!truth(name) && flags.containsKey("displayName")) { - //TODO inconsistent with entity and location, where name is legacy and displayName is encouraged! - //'displayName' is a legacy way to refer to a policy's name - Preconditions.checkArgument(flags.get("displayName") instanceof CharSequence, "'displayName' property should be a string"); - setDisplayName(flags.remove("displayName").toString()); - } - - // set leftover flags should as config items; particularly useful when these have come from a brooklyn.config map - for (Object flag: flags.keySet()) { - ConfigKey<Object> key = ConfigKeys.newConfigKey(Object.class, Strings.toString(flag)); - if (config().getRaw(key).isPresent()) { - log.warn("Config '"+flag+"' on "+this+" conflicts with key already set; ignoring"); - } else { - config().set(key, flags.get(flag)); - } - } - - return this; - } - - /** - * Used for legacy-style policies/enrichers on rebind, to indicate that init() should not be called. - * Will likely be deleted in a future release; should not be called apart from by framework code. - */ - @Beta - protected boolean isLegacyNoConstructionInit() { - return _legacyNoConstructionInit; - } - - @Override - public ConfigurationSupportInternal config() { - return config; - } - - private class BasicConfigurationSupport implements ConfigurationSupportInternal { - - @Override - public <T> T get(ConfigKey<T> key) { - return configsInternal.getConfig(key); - } - - @Override - public <T> T get(HasConfigKey<T> key) { - return get(key.getConfigKey()); - } - - @SuppressWarnings("unchecked") - @Override - public <T> T set(ConfigKey<T> key, T val) { - if (entity != null && isRunning()) { - doReconfigureConfig(key, val); - } - T result = (T) configsInternal.setConfig(key, val); - onChanged(); - return result; - } - - @Override - public <T> T set(HasConfigKey<T> key, T val) { - return setConfig(key.getConfigKey(), val); - } - - @SuppressWarnings("unchecked") - @Override - public <T> T set(ConfigKey<T> key, Task<T> val) { - if (entity != null && isRunning()) { - // TODO Support for AbstractEntityAdjunct - throw new UnsupportedOperationException(); - } - T result = (T) configsInternal.setConfig(key, val); - onChanged(); - return result; - } - - @Override - public <T> T set(HasConfigKey<T> key, Task<T> val) { - return set(key.getConfigKey(), val); - } - - @Override - public ConfigBag getBag() { - return getLocalBag(); - } - - @Override - public ConfigBag getLocalBag() { - return ConfigBag.newInstance(configsInternal.getAllConfig()); - } - - @Override - public Maybe<Object> getRaw(ConfigKey<?> key) { - return configsInternal.getConfigRaw(key, true); - } - - @Override - public Maybe<Object> getRaw(HasConfigKey<?> key) { - return getRaw(key.getConfigKey()); - } - - @Override - public Maybe<Object> getLocalRaw(ConfigKey<?> key) { - return configsInternal.getConfigRaw(key, false); - } - - @Override - public Maybe<Object> getLocalRaw(HasConfigKey<?> key) { - return getLocalRaw(key.getConfigKey()); - } - - @Override - public void addToLocalBag(Map<String, ?> vals) { - configsInternal.addToLocalBag(vals); - } - - @Override - public void removeFromLocalBag(String key) { - configsInternal.removeFromLocalBag(key); - } - - @Override - public void refreshInheritedConfig() { - // no-op for location - } - - @Override - public void refreshInheritedConfigOfChildren() { - // no-op for location - } - } - - public <T> T getConfig(ConfigKey<T> key) { - return config().get(key); - } - - protected <K> K getRequiredConfig(ConfigKey<K> key) { - K result = config().get(key); - if (result==null) - throw new NullPointerException("Value required for '"+key.getName()+"' in "+this); - return result; - } - - @Override - @Deprecated - public <T> T setConfig(ConfigKey<T> key, T val) { - return config().set(key, val); - } - - // TODO make immutable - /** for inspection only */ - @Beta - @Deprecated - public ConfigMap getConfigMap() { - return configsInternal; - } - - /** - * Invoked whenever a config change is applied after management is started. - * Default implementation throws an exception to disallow the change. - * Can be overridden to return (allowing the change) or to make other changes - * (if necessary), and of course it can do this selectively and call the super to disallow any others. */ - protected <T> void doReconfigureConfig(ConfigKey<T> key, T val) { - throw new UnsupportedOperationException("reconfiguring "+key+" unsupported for "+this); - } - - @Override - protected void onTagsChanged() { - onChanged(); - } - - protected abstract void onChanged(); - - protected AdjunctType getAdjunctType() { - return adjunctType; - } - - @Override - public String getDisplayName() { - if (name!=null && name.length()>0) return name; - return getClass().getCanonicalName(); - } - - public void setDisplayName(String name) { - this.name = name; - } - - public void setEntity(EntityLocal entity) { - if (destroyed.get()) throw new IllegalStateException("Cannot set entity on a destroyed entity adjunct"); - this.entity = entity; - if (entity!=null && getCatalogItemId() == null) { - setCatalogItemId(entity.getCatalogItemId()); - } - } - - /** @deprecated since 0.7.0 only {@link AbstractEnricher} has emit convenience */ - protected <T> void emit(Sensor<T> sensor, Object val) { - checkState(entity != null, "entity must first be set"); - if (val == Entities.UNCHANGED) { - return; - } - if (val == Entities.REMOVE) { - ((EntityInternal)entity).removeAttribute((AttributeSensor<T>) sensor); - return; - } - - T newVal = TypeCoercions.coerce(val, sensor.getTypeToken()); - if (sensor instanceof AttributeSensor) { - entity.setAttribute((AttributeSensor<T>)sensor, newVal); - } else { - entity.emit(sensor, newVal); - } - } - - protected synchronized SubscriptionTracker getSubscriptionTracker() { - if (_subscriptionTracker!=null) return _subscriptionTracker; - if (entity==null) return null; - _subscriptionTracker = new SubscriptionTracker(((EntityInternal)entity).getManagementSupport().getSubscriptionContext()); - return _subscriptionTracker; - } - - /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */ - protected <T> SubscriptionHandle subscribe(Entity producer, Sensor<T> sensor, SensorEventListener<? super T> listener) { - if (!checkCanSubscribe()) return null; - return getSubscriptionTracker().subscribe(producer, sensor, listener); - } - - /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */ - protected <T> SubscriptionHandle subscribeToMembers(Group producerGroup, Sensor<T> sensor, SensorEventListener<? super T> listener) { - if (!checkCanSubscribe(producerGroup)) return null; - return getSubscriptionTracker().subscribeToMembers(producerGroup, sensor, listener); - } - - /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */ - protected <T> SubscriptionHandle subscribeToChildren(Entity producerParent, Sensor<T> sensor, SensorEventListener<? super T> listener) { - if (!checkCanSubscribe(producerParent)) return null; - return getSubscriptionTracker().subscribeToChildren(producerParent, sensor, listener); - } - - /** @deprecated since 0.7.0 use {@link #checkCanSubscribe(Entity)} */ - @Deprecated - protected boolean check(Entity requiredEntity) { - return checkCanSubscribe(requiredEntity); - } - /** returns false if deleted, throws exception if invalid state, otherwise true. - * okay if entity is not yet managed (but not if entity is no longer managed). */ - protected boolean checkCanSubscribe(Entity producer) { - if (destroyed.get()) return false; - if (producer==null) throw new IllegalStateException(this+" given a null target for subscription"); - if (entity==null) throw new IllegalStateException(this+" cannot subscribe to "+producer+" because it is not associated to an entity"); - if (((EntityInternal)entity).getManagementSupport().isNoLongerManaged()) throw new IllegalStateException(this+" cannot subscribe to "+producer+" because the associated entity "+entity+" is no longer managed"); - return true; - } - protected boolean checkCanSubscribe() { - if (destroyed.get()) return false; - if (entity==null) throw new IllegalStateException(this+" cannot subscribe because it is not associated to an entity"); - if (((EntityInternal)entity).getManagementSupport().isNoLongerManaged()) throw new IllegalStateException(this+" cannot subscribe because the associated entity "+entity+" is no longer managed"); - return true; - } - - /** - * Unsubscribes the given producer. - * - * @see SubscriptionContext#unsubscribe(SubscriptionHandle) - */ - protected boolean unsubscribe(Entity producer) { - if (destroyed.get()) return false; - return getSubscriptionTracker().unsubscribe(producer); - } - - /** - * Unsubscribes the given producer. - * - * @see SubscriptionContext#unsubscribe(SubscriptionHandle) - */ - protected boolean unsubscribe(Entity producer, SubscriptionHandle handle) { - if (destroyed.get()) return false; - return getSubscriptionTracker().unsubscribe(producer, handle); - } - - /** - * @return a list of all subscription handles - */ - protected Collection<SubscriptionHandle> getAllSubscriptions() { - SubscriptionTracker tracker = getSubscriptionTracker(); - return (tracker != null) ? tracker.getAllSubscriptions() : Collections.<SubscriptionHandle>emptyList(); - } - - /** - * Unsubscribes and clears all managed subscriptions; is called by the owning entity when a policy is removed - * and should always be called by any subclasses overriding this method - */ - public void destroy() { - destroyed.set(true); - SubscriptionTracker tracker = getSubscriptionTracker(); - if (tracker != null) tracker.unsubscribeAll(); - } - - @Override - public boolean isDestroyed() { - return destroyed.get(); - } - - @Override - public boolean isRunning() { - return !isDestroyed(); - } - - @Override - public String getUniqueTag() { - return uniqueTag; - } - - public TagSupport tags() { - return new AdjunctTagSupport(); - } - - public class AdjunctTagSupport extends BasicTagSupport { - @Override - public Set<Object> getTags() { - ImmutableSet.Builder<Object> rb = ImmutableSet.builder().addAll(super.getTags()); - if (getUniqueTag()!=null) rb.add(getUniqueTag()); - return rb.build(); - } - public String getUniqueTag() { - return AbstractEntityAdjunct.this.getUniqueTag(); - } - public void setUniqueTag(String uniqueTag) { - AbstractEntityAdjunct.this.uniqueTag = uniqueTag; - } - } - - @Override - public String toString() { - return Objects.toStringHelper(getClass()).omitNullValues() - .add("name", name) - .add("uniqueTag", uniqueTag) - .add("running", isRunning()) - .add("entity", entity) - .add("id", getId()) - .toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java b/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java deleted file mode 100644 index e935e4b..0000000 --- a/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package brooklyn.policy.basic; - -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.brooklyn.api.entity.rebind.RebindSupport; -import org.apache.brooklyn.api.entity.trait.Configurable; -import org.apache.brooklyn.api.mementos.PolicyMemento; -import org.apache.brooklyn.api.policy.Policy; -import org.apache.brooklyn.api.policy.PolicyType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.entity.rebind.BasicPolicyRebindSupport; - -import com.google.common.base.Objects; - -/** - * Base {@link Policy} implementation; all policies should extend this or its children - */ -public abstract class AbstractPolicy extends AbstractEntityAdjunct implements Policy, Configurable { - @SuppressWarnings("unused") - private static final Logger log = LoggerFactory.getLogger(AbstractPolicy.class); - - protected String policyStatus; - protected AtomicBoolean suspended = new AtomicBoolean(false); - - private final PolicyDynamicType policyType; - - public AbstractPolicy() { - this(Collections.emptyMap()); - } - - public AbstractPolicy(Map<?,?> flags) { - super(flags); - - // TODO Don't let `this` reference escape during construction - policyType = new PolicyDynamicType(this); - - if (isLegacyConstruction() && !isLegacyNoConstructionInit()) { - init(); - } - } - - @Override - public PolicyType getPolicyType() { - return policyType.getSnapshot(); - } - - @Override - public void suspend() { - suspended.set(true); - } - - @Override - public void resume() { - suspended.set(false); - } - - @Override - public boolean isSuspended() { - if (suspended==null) { - // only if accessed during construction in super, e.g. by a call to toString in configure - return true; - } - return suspended.get(); - } - - @Override - public void destroy(){ - suspend(); - super.destroy(); - } - - @Override - public boolean isRunning() { - return !isSuspended() && !isDestroyed(); - } - - @Override - protected void onChanged() { - // currently changes simply trigger re-persistence; there is no intermediate listener as we do for EntityChangeListener - if (getManagementContext() != null) { - getManagementContext().getRebindManager().getChangeListener().onChanged(this); - } - } - - @Override - public RebindSupport<PolicyMemento> getRebindSupport() { - return new BasicPolicyRebindSupport(this); - } - - @Override - public String toString() { - return Objects.toStringHelper(getClass()) - .add("name", name) - .add("running", isRunning()) - .toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/policy/basic/AdjunctType.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/policy/basic/AdjunctType.java b/core/src/main/java/brooklyn/policy/basic/AdjunctType.java deleted file mode 100644 index f53f822..0000000 --- a/core/src/main/java/brooklyn/policy/basic/AdjunctType.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package brooklyn.policy.basic; - -import java.io.Serializable; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -import org.apache.brooklyn.api.policy.EntityAdjunct; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.config.ConfigKey; -import brooklyn.config.ConfigKey.HasConfigKey; - -import com.google.common.base.Joiner; -import com.google.common.base.Objects; -import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; - -/** - * This is the actual type of a policy instance at runtime. - */ -public class AdjunctType implements Serializable { - private static final long serialVersionUID = -662979234559595903L; - - private static final Logger LOG = LoggerFactory.getLogger(AdjunctType.class); - - private final String name; - private final Map<String, ConfigKey<?>> configKeys; - private final Set<ConfigKey<?>> configKeysSet; - - public AdjunctType(AbstractEntityAdjunct adjunct) { - this(adjunct.getClass(), adjunct); - } - - protected AdjunctType(Class<? extends EntityAdjunct> clazz) { - this(clazz, null); - } - - private AdjunctType(Class<? extends EntityAdjunct> clazz, AbstractEntityAdjunct adjunct) { - name = clazz.getCanonicalName(); - configKeys = Collections.unmodifiableMap(findConfigKeys(clazz, null)); - configKeysSet = ImmutableSet.copyOf(this.configKeys.values()); - if (LOG.isTraceEnabled()) - LOG.trace("Policy {} config keys: {}", name, Joiner.on(", ").join(configKeys.keySet())); - } - - AdjunctType(String name, Map<String, ConfigKey<?>> configKeys) { - this.name = name; - this.configKeys = ImmutableMap.copyOf(configKeys); - this.configKeysSet = ImmutableSet.copyOf(this.configKeys.values()); - } - - public String getName() { - return name; - } - - public Set<ConfigKey<?>> getConfigKeys() { - return configKeysSet; - } - - public ConfigKey<?> getConfigKey(String name) { - return configKeys.get(name); - } - - @Override - public int hashCode() { - return Objects.hashCode(name, configKeys); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (getClass() != obj.getClass()) return false; - AdjunctType o = (AdjunctType) obj; - if (!Objects.equal(name, o.getName())) return false; - if (!Objects.equal(getConfigKeys(), o.getConfigKeys())) return false; - return true; - } - - @Override - public String toString() { - return Objects.toStringHelper(name) - .add("configKeys", configKeys) - .toString(); - } - - /** - * Finds the config keys defined on the entity's class, statics and optionally any non-static (discouraged). - */ - // TODO Remove duplication from EntityDynamicType - protected static Map<String,ConfigKey<?>> findConfigKeys(Class<? extends EntityAdjunct> clazz, EntityAdjunct optionalInstance) { - try { - Map<String,ConfigKey<?>> result = Maps.newLinkedHashMap(); - Map<String,Field> configFields = Maps.newLinkedHashMap(); - for (Field f : clazz.getFields()) { - boolean isConfigKey = ConfigKey.class.isAssignableFrom(f.getType()); - if (!isConfigKey) { - if (!HasConfigKey.class.isAssignableFrom(f.getType())) { - // neither ConfigKey nor HasConfigKey - continue; - } - } - if (!Modifier.isStatic(f.getModifiers())) { - // require it to be static or we have an instance - LOG.warn("Discouraged use of non-static config key "+f+" defined in " + (optionalInstance!=null ? optionalInstance : clazz)); - if (optionalInstance==null) continue; - } - ConfigKey<?> k = isConfigKey ? (ConfigKey<?>) f.get(optionalInstance) : - ((HasConfigKey<?>)f.get(optionalInstance)).getConfigKey(); - - Field alternativeField = configFields.get(k.getName()); - // Allow overriding config keys (e.g. to set default values) when there is an assignable-from relationship between classes - Field definitiveField = alternativeField != null ? inferSubbestField(alternativeField, f) : f; - boolean skip = false; - if (definitiveField != f) { - // If they refer to the _same_ instance, just keep the one we already have - if (alternativeField.get(optionalInstance) == f.get(optionalInstance)) skip = true; - } - if (skip) { - //nothing - } else if (definitiveField == f) { - result.put(k.getName(), k); - configFields.put(k.getName(), f); - } else if (definitiveField != null) { - if (LOG.isDebugEnabled()) LOG.debug("multiple definitions for config key {} on {}; preferring that in sub-class: {} to {}", new Object[] { - k.getName(), optionalInstance!=null ? optionalInstance : clazz, alternativeField, f}); - } else if (definitiveField == null) { - LOG.warn("multiple definitions for config key {} on {}; preferring {} to {}", new Object[] { - k.getName(), optionalInstance!=null ? optionalInstance : clazz, alternativeField, f}); - } - } - - return result; - } catch (IllegalAccessException e) { - throw Throwables.propagate(e); - } - } - - /** - * Gets the field that is in the sub-class; or null if one field does not come from a sub-class of the other field's class - */ - // TODO Remove duplication from EntityDynamicType - private static Field inferSubbestField(Field f1, Field f2) { - Class<?> c1 = f1.getDeclaringClass(); - Class<?> c2 = f2.getDeclaringClass(); - boolean isSuper1 = c1.isAssignableFrom(c2); - boolean isSuper2 = c2.isAssignableFrom(c1); - return (isSuper1) ? (isSuper2 ? null : f2) : (isSuper2 ? f1 : null); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/policy/basic/ConfigMapImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/policy/basic/ConfigMapImpl.java b/core/src/main/java/brooklyn/policy/basic/ConfigMapImpl.java deleted file mode 100644 index 467eb05..0000000 --- a/core/src/main/java/brooklyn/policy/basic/ConfigMapImpl.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package brooklyn.policy.basic; - -import static brooklyn.util.GroovyJavaMethods.elvis; - -import java.util.Collections; -import java.util.Map; - -import org.apache.brooklyn.api.entity.basic.EntityLocal; -import org.apache.brooklyn.api.management.ExecutionContext; -import org.apache.brooklyn.core.util.flags.TypeCoercions; -import org.apache.brooklyn.core.util.internal.ConfigKeySelfExtracting; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.collect.Maps; - -import brooklyn.config.ConfigKey; -import brooklyn.config.internal.AbstractConfigMapImpl; -import brooklyn.entity.basic.ConfigKeys; -import brooklyn.entity.basic.EntityInternal; -import brooklyn.entity.basic.Sanitizer; -import brooklyn.event.basic.StructuredConfigKey; -import brooklyn.util.guava.Maybe; - -public class ConfigMapImpl extends AbstractConfigMapImpl { - - private static final Logger LOG = LoggerFactory.getLogger(ConfigMapImpl.class); - - /** policy against which config resolution / task execution will occur */ - private final AbstractEntityAdjunct adjunct; - - /* - * TODO An alternative implementation approach would be to have: - * setParent(Entity o, Map<ConfigKey,Object> inheritedConfig=[:]) - * The idea is that the parent could in theory decide explicitly what in its config - * would be shared. - * I (Aled) am undecided as to whether that would be better... - * - * (Alex) i lean toward the config key getting to make the decision - */ - - public ConfigMapImpl(AbstractEntityAdjunct adjunct) { - this.adjunct = Preconditions.checkNotNull(adjunct, "AbstractEntityAdjunct must be specified"); - } - - @SuppressWarnings("unchecked") - @Override - public <T> T getConfig(ConfigKey<T> key, T defaultValue) { - // FIXME What about inherited task in config?! - // alex says: think that should work, no? - // FIXME What if someone calls getConfig on a task, before setting parent app? - // alex says: not supported (throw exception, or return the task) - - // In case this entity class has overridden the given key (e.g. to set default), then retrieve this entity's key - // TODO If ask for a config value that's not in our configKeys, should we really continue with rest of method and return key.getDefaultValue? - // e.g. SshBasedJavaAppSetup calls setAttribute(JMX_USER), which calls getConfig(JMX_USER) - // but that example doesn't have a default... - ConfigKey<T> ownKey = adjunct!=null ? (ConfigKey<T>)elvis(adjunct.getAdjunctType().getConfigKey(key.getName()), key) : key; - - // Don't use groovy truth: if the set value is e.g. 0, then would ignore set value and return default! - if (ownKey instanceof ConfigKeySelfExtracting) { - if (((ConfigKeySelfExtracting<T>)ownKey).isSet(ownConfig)) { - // FIXME Should we support config from futures? How to get execution context before setEntity? - EntityLocal entity = adjunct.entity; - ExecutionContext exec = (entity != null) ? ((EntityInternal)entity).getExecutionContext() : null; - return ((ConfigKeySelfExtracting<T>)ownKey).extractValue(ownConfig, exec); - } - } else { - LOG.warn("Config key {} of {} is not a ConfigKeySelfExtracting; cannot retrieve value; returning default", ownKey, this); - } - return TypeCoercions.coerce((defaultValue != null) ? defaultValue : ownKey.getDefaultValue(), key.getTypeToken()); - } - - @Override - public Maybe<Object> getConfigRaw(ConfigKey<?> key, boolean includeInherited) { - if (ownConfig.containsKey(key)) return Maybe.of(ownConfig.get(key)); - return Maybe.absent(); - } - - /** returns the config of this policy */ - @Override - public Map<ConfigKey<?>,Object> getAllConfig() { - // Don't use ImmutableMap because valide for values to be null - return Collections.unmodifiableMap(Maps.newLinkedHashMap(ownConfig)); - } - - public Object setConfig(ConfigKey<?> key, Object v) { - Object val = coerceConfigVal(key, v); - if (key instanceof StructuredConfigKey) { - return ((StructuredConfigKey)key).applyValueToMap(val, ownConfig); - } else { - return ownConfig.put(key, val); - } - } - - public void addToLocalBag(Map<String, ?> vals) { - for (Map.Entry<String, ?> entry : vals.entrySet()) { - setConfig(ConfigKeys.newConfigKey(Object.class, entry.getKey()), entry.getValue()); - } - } - - public void removeFromLocalBag(String key) { - ownConfig.remove(key); - } - - @Override - public ConfigMapImpl submap(Predicate<ConfigKey<?>> filter) { - ConfigMapImpl m = new ConfigMapImpl(adjunct); - for (Map.Entry<ConfigKey<?>,Object> entry: ownConfig.entrySet()) - if (filter.apply(entry.getKey())) - m.ownConfig.put(entry.getKey(), entry.getValue()); - return m; - } - - @Override - public String toString() { - return super.toString()+"[own="+Sanitizer.sanitize(ownConfig)+"]"; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/policy/basic/GeneralPurposePolicy.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/policy/basic/GeneralPurposePolicy.java b/core/src/main/java/brooklyn/policy/basic/GeneralPurposePolicy.java deleted file mode 100644 index 0600006..0000000 --- a/core/src/main/java/brooklyn/policy/basic/GeneralPurposePolicy.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package brooklyn.policy.basic; - -import java.util.Collections; -import java.util.Map; - -/** - * @deprecated since 0.7.0; will be either deleted or moved to tests - */ -@Deprecated -public class GeneralPurposePolicy extends AbstractPolicy { - public GeneralPurposePolicy() { - this(Collections.emptyMap()); - } - public GeneralPurposePolicy(Map properties) { - super(properties); - } -} - http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/policy/basic/Policies.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/policy/basic/Policies.java b/core/src/main/java/brooklyn/policy/basic/Policies.java deleted file mode 100644 index 887546a..0000000 --- a/core/src/main/java/brooklyn/policy/basic/Policies.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 brooklyn.policy.basic; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.entity.basic.EntityLocal; -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.policy.Policy; - -import groovy.lang.Closure; -import brooklyn.entity.basic.Lifecycle; -import brooklyn.policy.basic.AbstractPolicy; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class Policies { - - public static SensorEventListener listenerFromValueClosure(final Closure code) { - return new SensorEventListener() { - @Override - public void onEvent(SensorEvent event) { - code.call(event.getValue()); - } - }; - } - - public static <T> Policy newSingleSensorValuePolicy(final Sensor<T> sensor, final Closure code) { - return new AbstractPolicy() { - @Override - public void setEntity(EntityLocal entity) { - super.setEntity(entity); - entity.subscribe(entity, sensor, listenerFromValueClosure(code)); - } - }; - } - - public static <S,T> Policy newSingleSensorValuePolicy(final Entity remoteEntity, final Sensor<T> remoteSensor, - final Closure code) { - return new AbstractPolicy() { - @Override - public void setEntity(EntityLocal entity) { - super.setEntity(entity); - entity.subscribe(remoteEntity, remoteSensor, listenerFromValueClosure(code)); - } - }; - } - - public static Lifecycle getPolicyStatus(Policy p) { - if (p.isRunning()) return Lifecycle.RUNNING; - if (p.isDestroyed()) return Lifecycle.DESTROYED; - if (p.isSuspended()) return Lifecycle.STOPPED; - // TODO could policy be in an error state? - return Lifecycle.CREATED; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java b/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java deleted file mode 100644 index b6d3c6d..0000000 --- a/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.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 brooklyn.policy.basic; - -import org.apache.brooklyn.api.policy.Policy; -import org.apache.brooklyn.api.policy.PolicyType; - -import brooklyn.basic.BrooklynDynamicType; - -public class PolicyDynamicType extends BrooklynDynamicType<Policy, AbstractPolicy> { - - public PolicyDynamicType(Class<? extends Policy> type) { - super(type); - } - - public PolicyDynamicType(AbstractPolicy policy) { - super(policy); - } - - public PolicyType getSnapshot() { - return (PolicyType) super.getSnapshot(); - } - - @Override - protected PolicyTypeSnapshot newSnapshot() { - return new PolicyTypeSnapshot(name, value(configKeys)); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java b/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java deleted file mode 100644 index b6d2f33..0000000 --- a/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package brooklyn.policy.basic; - -import java.util.Map; - -import org.apache.brooklyn.api.policy.PolicyType; - -import brooklyn.basic.BrooklynTypeSnapshot; -import brooklyn.config.ConfigKey; - -public class PolicyTypeSnapshot extends BrooklynTypeSnapshot implements PolicyType { - private static final long serialVersionUID = 4670930188951106009L; - - PolicyTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) { - super(name, configKeys); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - return (obj instanceof PolicyTypeSnapshot) && super.equals(obj); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6eacb3c3/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java b/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java new file mode 100644 index 0000000..eda106f --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java @@ -0,0 +1,510 @@ +/* + * 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.policy.basic; + +import static brooklyn.util.GroovyJavaMethods.truth; +import static com.google.common.base.Preconditions.checkState; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.Group; +import org.apache.brooklyn.api.entity.basic.EntityLocal; +import org.apache.brooklyn.api.entity.trait.Configurable; +import org.apache.brooklyn.api.event.AttributeSensor; +import org.apache.brooklyn.api.event.Sensor; +import org.apache.brooklyn.api.event.SensorEventListener; +import org.apache.brooklyn.api.management.ExecutionContext; +import org.apache.brooklyn.api.management.SubscriptionContext; +import org.apache.brooklyn.api.management.SubscriptionHandle; +import org.apache.brooklyn.api.management.Task; +import org.apache.brooklyn.api.policy.EntityAdjunct; +import org.apache.brooklyn.core.management.internal.SubscriptionTracker; +import org.apache.brooklyn.core.util.config.ConfigBag; +import org.apache.brooklyn.core.util.flags.FlagUtils; +import org.apache.brooklyn.core.util.flags.SetFromFlag; +import org.apache.brooklyn.core.util.flags.TypeCoercions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.basic.AbstractBrooklynObject; +import brooklyn.basic.BrooklynObjectInternal; +import brooklyn.config.ConfigKey; +import brooklyn.config.ConfigKey.HasConfigKey; +import brooklyn.config.ConfigMap; +import brooklyn.enricher.basic.AbstractEnricher; +import brooklyn.entity.basic.ConfigKeys; +import brooklyn.entity.basic.Entities; +import brooklyn.entity.basic.EntityInternal; +import brooklyn.util.guava.Maybe; +import brooklyn.util.text.Strings; + +import com.google.common.annotations.Beta; +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; + + +/** + * Common functionality for policies and enrichers + */ +public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject implements BrooklynObjectInternal, EntityAdjunct, Configurable { + private static final Logger log = LoggerFactory.getLogger(AbstractEntityAdjunct.class); + + private boolean _legacyNoConstructionInit; + + /** + * @deprecated since 0.7.0; leftover properties are put into config, since when coming from yaml this is normal. + */ + @Deprecated + protected Map<String,Object> leftoverProperties = Maps.newLinkedHashMap(); + + protected transient ExecutionContext execution; + + private final BasicConfigurationSupport config = new BasicConfigurationSupport(); + + /** + * The config values of this entity. Updating this map should be done + * via {@link #config()}. + * + * @deprecated since 0.7.0; use {@link #config()} instead; this field may be made private or deleted in a future release. + */ + @Deprecated + protected final ConfigMapImpl configsInternal = new ConfigMapImpl(this); + + /** + * @deprecated since 0.7.0; use {@link #getAdjunctType()} instead; this field may be made private or deleted in a future release. + */ + @Deprecated + protected final AdjunctType adjunctType = new AdjunctType(this); + + @SetFromFlag + protected String name; + + protected transient EntityLocal entity; + + /** not for direct access; refer to as 'subscriptionTracker' via getter so that it is initialized */ + protected transient SubscriptionTracker _subscriptionTracker; + + private AtomicBoolean destroyed = new AtomicBoolean(false); + + @SetFromFlag(value="uniqueTag") + protected String uniqueTag; + + public AbstractEntityAdjunct() { + this(Collections.emptyMap()); + } + + public AbstractEntityAdjunct(@SuppressWarnings("rawtypes") Map properties) { + super(properties); + _legacyNoConstructionInit = (properties != null) && Boolean.TRUE.equals(properties.get("noConstructionInit")); + + if (isLegacyConstruction()) { + AbstractBrooklynObject checkWeGetThis = configure(properties); + assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this; + + boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class)); + if (!deferConstructionChecks) { + FlagUtils.checkRequiredFields(this); + } + } + } + + /** + * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly + */ + @Override + @Deprecated + @SuppressWarnings({ "unchecked", "rawtypes" }) + public AbstractEntityAdjunct configure(Map flags) { + // TODO only set on first time through + boolean isFirstTime = true; + + // allow config keys, and fields, to be set from these flags if they have a SetFromFlag annotation + // or if the value is a config key + for (Iterator<Map.Entry> iter = flags.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry = iter.next(); + if (entry.getKey() instanceof ConfigKey) { + ConfigKey key = (ConfigKey)entry.getKey(); + if (adjunctType.getConfigKeys().contains(key)) { + setConfig(key, entry.getValue()); + } else { + log.warn("Unknown configuration key {} for policy {}; ignoring", key, this); + iter.remove(); + } + } + } + + ConfigBag bag = new ConfigBag().putAll(flags); + FlagUtils.setFieldsFromFlags(this, bag, isFirstTime); + FlagUtils.setAllConfigKeys(this, bag, false); + leftoverProperties.putAll(bag.getUnusedConfig()); + + //replace properties _contents_ with leftovers so subclasses see leftovers only + flags.clear(); + flags.putAll(leftoverProperties); + leftoverProperties = flags; + + if (!truth(name) && flags.containsKey("displayName")) { + //TODO inconsistent with entity and location, where name is legacy and displayName is encouraged! + //'displayName' is a legacy way to refer to a policy's name + Preconditions.checkArgument(flags.get("displayName") instanceof CharSequence, "'displayName' property should be a string"); + setDisplayName(flags.remove("displayName").toString()); + } + + // set leftover flags should as config items; particularly useful when these have come from a brooklyn.config map + for (Object flag: flags.keySet()) { + ConfigKey<Object> key = ConfigKeys.newConfigKey(Object.class, Strings.toString(flag)); + if (config().getRaw(key).isPresent()) { + log.warn("Config '"+flag+"' on "+this+" conflicts with key already set; ignoring"); + } else { + config().set(key, flags.get(flag)); + } + } + + return this; + } + + /** + * Used for legacy-style policies/enrichers on rebind, to indicate that init() should not be called. + * Will likely be deleted in a future release; should not be called apart from by framework code. + */ + @Beta + protected boolean isLegacyNoConstructionInit() { + return _legacyNoConstructionInit; + } + + @Override + public ConfigurationSupportInternal config() { + return config; + } + + private class BasicConfigurationSupport implements ConfigurationSupportInternal { + + @Override + public <T> T get(ConfigKey<T> key) { + return configsInternal.getConfig(key); + } + + @Override + public <T> T get(HasConfigKey<T> key) { + return get(key.getConfigKey()); + } + + @SuppressWarnings("unchecked") + @Override + public <T> T set(ConfigKey<T> key, T val) { + if (entity != null && isRunning()) { + doReconfigureConfig(key, val); + } + T result = (T) configsInternal.setConfig(key, val); + onChanged(); + return result; + } + + @Override + public <T> T set(HasConfigKey<T> key, T val) { + return setConfig(key.getConfigKey(), val); + } + + @SuppressWarnings("unchecked") + @Override + public <T> T set(ConfigKey<T> key, Task<T> val) { + if (entity != null && isRunning()) { + // TODO Support for AbstractEntityAdjunct + throw new UnsupportedOperationException(); + } + T result = (T) configsInternal.setConfig(key, val); + onChanged(); + return result; + } + + @Override + public <T> T set(HasConfigKey<T> key, Task<T> val) { + return set(key.getConfigKey(), val); + } + + @Override + public ConfigBag getBag() { + return getLocalBag(); + } + + @Override + public ConfigBag getLocalBag() { + return ConfigBag.newInstance(configsInternal.getAllConfig()); + } + + @Override + public Maybe<Object> getRaw(ConfigKey<?> key) { + return configsInternal.getConfigRaw(key, true); + } + + @Override + public Maybe<Object> getRaw(HasConfigKey<?> key) { + return getRaw(key.getConfigKey()); + } + + @Override + public Maybe<Object> getLocalRaw(ConfigKey<?> key) { + return configsInternal.getConfigRaw(key, false); + } + + @Override + public Maybe<Object> getLocalRaw(HasConfigKey<?> key) { + return getLocalRaw(key.getConfigKey()); + } + + @Override + public void addToLocalBag(Map<String, ?> vals) { + configsInternal.addToLocalBag(vals); + } + + @Override + public void removeFromLocalBag(String key) { + configsInternal.removeFromLocalBag(key); + } + + @Override + public void refreshInheritedConfig() { + // no-op for location + } + + @Override + public void refreshInheritedConfigOfChildren() { + // no-op for location + } + } + + public <T> T getConfig(ConfigKey<T> key) { + return config().get(key); + } + + protected <K> K getRequiredConfig(ConfigKey<K> key) { + K result = config().get(key); + if (result==null) + throw new NullPointerException("Value required for '"+key.getName()+"' in "+this); + return result; + } + + @Override + @Deprecated + public <T> T setConfig(ConfigKey<T> key, T val) { + return config().set(key, val); + } + + // TODO make immutable + /** for inspection only */ + @Beta + @Deprecated + public ConfigMap getConfigMap() { + return configsInternal; + } + + /** + * Invoked whenever a config change is applied after management is started. + * Default implementation throws an exception to disallow the change. + * Can be overridden to return (allowing the change) or to make other changes + * (if necessary), and of course it can do this selectively and call the super to disallow any others. */ + protected <T> void doReconfigureConfig(ConfigKey<T> key, T val) { + throw new UnsupportedOperationException("reconfiguring "+key+" unsupported for "+this); + } + + @Override + protected void onTagsChanged() { + onChanged(); + } + + protected abstract void onChanged(); + + protected AdjunctType getAdjunctType() { + return adjunctType; + } + + @Override + public String getDisplayName() { + if (name!=null && name.length()>0) return name; + return getClass().getCanonicalName(); + } + + public void setDisplayName(String name) { + this.name = name; + } + + public void setEntity(EntityLocal entity) { + if (destroyed.get()) throw new IllegalStateException("Cannot set entity on a destroyed entity adjunct"); + this.entity = entity; + if (entity!=null && getCatalogItemId() == null) { + setCatalogItemId(entity.getCatalogItemId()); + } + } + + /** @deprecated since 0.7.0 only {@link AbstractEnricher} has emit convenience */ + protected <T> void emit(Sensor<T> sensor, Object val) { + checkState(entity != null, "entity must first be set"); + if (val == Entities.UNCHANGED) { + return; + } + if (val == Entities.REMOVE) { + ((EntityInternal)entity).removeAttribute((AttributeSensor<T>) sensor); + return; + } + + T newVal = TypeCoercions.coerce(val, sensor.getTypeToken()); + if (sensor instanceof AttributeSensor) { + entity.setAttribute((AttributeSensor<T>)sensor, newVal); + } else { + entity.emit(sensor, newVal); + } + } + + protected synchronized SubscriptionTracker getSubscriptionTracker() { + if (_subscriptionTracker!=null) return _subscriptionTracker; + if (entity==null) return null; + _subscriptionTracker = new SubscriptionTracker(((EntityInternal)entity).getManagementSupport().getSubscriptionContext()); + return _subscriptionTracker; + } + + /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */ + protected <T> SubscriptionHandle subscribe(Entity producer, Sensor<T> sensor, SensorEventListener<? super T> listener) { + if (!checkCanSubscribe()) return null; + return getSubscriptionTracker().subscribe(producer, sensor, listener); + } + + /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */ + protected <T> SubscriptionHandle subscribeToMembers(Group producerGroup, Sensor<T> sensor, SensorEventListener<? super T> listener) { + if (!checkCanSubscribe(producerGroup)) return null; + return getSubscriptionTracker().subscribeToMembers(producerGroup, sensor, listener); + } + + /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */ + protected <T> SubscriptionHandle subscribeToChildren(Entity producerParent, Sensor<T> sensor, SensorEventListener<? super T> listener) { + if (!checkCanSubscribe(producerParent)) return null; + return getSubscriptionTracker().subscribeToChildren(producerParent, sensor, listener); + } + + /** @deprecated since 0.7.0 use {@link #checkCanSubscribe(Entity)} */ + @Deprecated + protected boolean check(Entity requiredEntity) { + return checkCanSubscribe(requiredEntity); + } + /** returns false if deleted, throws exception if invalid state, otherwise true. + * okay if entity is not yet managed (but not if entity is no longer managed). */ + protected boolean checkCanSubscribe(Entity producer) { + if (destroyed.get()) return false; + if (producer==null) throw new IllegalStateException(this+" given a null target for subscription"); + if (entity==null) throw new IllegalStateException(this+" cannot subscribe to "+producer+" because it is not associated to an entity"); + if (((EntityInternal)entity).getManagementSupport().isNoLongerManaged()) throw new IllegalStateException(this+" cannot subscribe to "+producer+" because the associated entity "+entity+" is no longer managed"); + return true; + } + protected boolean checkCanSubscribe() { + if (destroyed.get()) return false; + if (entity==null) throw new IllegalStateException(this+" cannot subscribe because it is not associated to an entity"); + if (((EntityInternal)entity).getManagementSupport().isNoLongerManaged()) throw new IllegalStateException(this+" cannot subscribe because the associated entity "+entity+" is no longer managed"); + return true; + } + + /** + * Unsubscribes the given producer. + * + * @see SubscriptionContext#unsubscribe(SubscriptionHandle) + */ + protected boolean unsubscribe(Entity producer) { + if (destroyed.get()) return false; + return getSubscriptionTracker().unsubscribe(producer); + } + + /** + * Unsubscribes the given producer. + * + * @see SubscriptionContext#unsubscribe(SubscriptionHandle) + */ + protected boolean unsubscribe(Entity producer, SubscriptionHandle handle) { + if (destroyed.get()) return false; + return getSubscriptionTracker().unsubscribe(producer, handle); + } + + /** + * @return a list of all subscription handles + */ + protected Collection<SubscriptionHandle> getAllSubscriptions() { + SubscriptionTracker tracker = getSubscriptionTracker(); + return (tracker != null) ? tracker.getAllSubscriptions() : Collections.<SubscriptionHandle>emptyList(); + } + + /** + * Unsubscribes and clears all managed subscriptions; is called by the owning entity when a policy is removed + * and should always be called by any subclasses overriding this method + */ + public void destroy() { + destroyed.set(true); + SubscriptionTracker tracker = getSubscriptionTracker(); + if (tracker != null) tracker.unsubscribeAll(); + } + + @Override + public boolean isDestroyed() { + return destroyed.get(); + } + + @Override + public boolean isRunning() { + return !isDestroyed(); + } + + @Override + public String getUniqueTag() { + return uniqueTag; + } + + public TagSupport tags() { + return new AdjunctTagSupport(); + } + + public class AdjunctTagSupport extends BasicTagSupport { + @Override + public Set<Object> getTags() { + ImmutableSet.Builder<Object> rb = ImmutableSet.builder().addAll(super.getTags()); + if (getUniqueTag()!=null) rb.add(getUniqueTag()); + return rb.build(); + } + public String getUniqueTag() { + return AbstractEntityAdjunct.this.getUniqueTag(); + } + public void setUniqueTag(String uniqueTag) { + AbstractEntityAdjunct.this.uniqueTag = uniqueTag; + } + } + + @Override + public String toString() { + return Objects.toStringHelper(getClass()).omitNullValues() + .add("name", name) + .add("uniqueTag", uniqueTag) + .add("running", isRunning()) + .add("entity", entity) + .add("id", getId()) + .toString(); + } +}
