@Override public SubscriptionContext getSubscriptionContext() { // Rely on synchronization in EntityManagementSupport; synchronizing on AbstractEntity.this // is dangerous because user's entity code might synchronize on that and call getAttribute. // Given that getSubscriptionContext is called by AttributeMap.update (via emitInternal), // that risks deadlock! return getManagementSupport().getSubscriptionContext(); }
@Override public ManagementContext getManagementContext() { // NB Sept 2014 - removed synch keyword above due to deadlock; // it also synchs in ManagementSupport.getManagementContext(); // no apparent reason why it was here also return getManagementSupport().getManagementContext(); }
@Override public ExecutionContext getExecutionContext() { // NB May 2016 - removed synch keyword above due to deadlock (see https://issues.apache.org/jira/browse/BROOKLYN-284). // As with getManagementContext(), it also synchs in ManagementSupport.getExecutionContext(); // no apparent reason why it was here also. return getManagementSupport().getExecutionContext(); }
@Override protected <T> void onConfigChanging(ConfigKey<T> key, Object val) { if (!inConstruction && getManagementSupport().isDeployed()) { // previously we threw, then warned, but it is still quite common; // so long as callers don't expect miracles, it should be fine. // i (Alex) think the way to be stricter about this (if that becomes needed) // would be to introduce a 'mutable' field on config keys LOG.debug("configuration being made to {} after deployment: {} = {}; change may not be visible in other contexts", new Object[] { getContainer(), key, val }); } }
@Override public void requestPersist() { getManagementSupport().getEntityChangeListener().onChanged(); }
@Override protected <T> void onConfigChanged(ConfigKey<T> key, Object val) { getManagementSupport().getEntityChangeListener().onConfigChanged(key); }
@Override public boolean remove(Enricher enricher) { ((AbstractEnricher)enricher).destroy(); boolean changed = enrichersInternal.remove(enricher); if (changed) { getManagementSupport().getEntityChangeListener().onEnricherRemoved(enricher); } return changed; }
@Override public void clearLocations() { synchronized (locations) { locations.set(ImmutableList.<Location>of()); } getManagementSupport().getEntityChangeListener().onLocationsChanged(); }
@Override public <T> T setWithoutPublishing(AttributeSensor<T> attribute, T val) { if (LOG.isTraceEnabled()) LOG.trace(""+AbstractEntity.this+" setAttributeWithoutPublishing "+attribute+" "+val); T result = attributesInternal.updateWithoutPublishing(attribute, val); if (result == null) { // could be this is a new sensor entityType.addSensorIfAbsentWithoutPublishing(attribute); } getManagementSupport().getEntityChangeListener().onAttributeChanged(attribute); return result; }
@Override public void setDisplayName(String newDisplayName) { displayName.set(newDisplayName); displayNameAutoGenerated = false; getManagementSupport().getEntityChangeListener().onChanged(); }
@Override protected void onTagsChanged() { super.onTagsChanged(); getManagementSupport().getEntityChangeListener().onTagsChanged(); }
@Override public void add(Enricher enricher) { Enricher old = findApparentlyEqualAndWarnIfNotSameUniqueTag(enrichersInternal, enricher); if (old!=null) { LOG.debug("Removing "+old+" when adding "+enricher+" to "+AbstractEntity.this); remove(old); } CatalogUtils.setCatalogItemIdOnAddition(AbstractEntity.this, enricher); enrichersInternal.add((AbstractEnricher) enricher); ((AbstractEnricher)enricher).setEntity(AbstractEntity.this); ConfigConstraints.assertValid(enricher); getManagementSupport().getEntityChangeListener().onEnricherAdded(enricher); // TODO Could add equivalent of AbstractEntity.POLICY_ADDED for enrichers; no use-case for that yet }
public <T> void emitInternal(Sensor<T> sensor, T val) { if (getManagementSupport().isNoLongerManaged()) throw new IllegalStateException("Entity "+AbstractEntity.this+" is no longer managed, when trying to publish "+sensor+" "+val); SubscriptionContext subsContext = subscriptions().getSubscriptionContext(); if (subsContext != null) subsContext.publish(sensor.newEvent(getProxyIfAvailable(), val)); } }
@Override public boolean remove(Policy policy) { ((AbstractPolicy)policy).destroy(); boolean changed = policiesInternal.remove(policy); if (changed) { getManagementSupport().getEntityChangeListener().onPolicyRemoved(policy); sensors().emit(AbstractEntity.POLICY_REMOVED, new PolicyDescriptor(policy)); } return changed; }
/** * Returns the application, looking it up if not yet known (registering if necessary) */ @Override public Application getApplication() { if (application != null) return application; Entity parent = getParent(); Application app = (parent != null) ? parent.getApplication() : null; if (app != null) { if (getManagementSupport().isFullyManaged()) // only do this once fully managed, in case root app becomes parented setApplication(app); } return app; }
@Override public boolean removeFeed(Feed feed) { feed.stop(); boolean changed = feedsInternal.remove(feed); if (changed) { getManagementContext().getRebindManager().getChangeListener().onUnmanaged(feed); getManagementSupport().getEntityChangeListener().onFeedRemoved(feed); } return changed; }
@Override public boolean removeChild(Entity child) { synchronized (getAttributesSynchObjectInternal()) { synchronized (children) { boolean changed = children.remove(child); child.clearParent(); if (changed) { getManagementSupport().getEntityChangeListener().onChildrenChanged(); } if (changed) { sensors().emit(AbstractEntity.CHILD_REMOVED, child); } return changed; } } }
@Override public void add(Policy policy) { Policy old = findApparentlyEqualAndWarnIfNotSameUniqueTag(policiesInternal, policy); if (old!=null) { LOG.debug("Removing "+old+" when adding "+policy+" to "+AbstractEntity.this); remove(old); } CatalogUtils.setCatalogItemIdOnAddition(AbstractEntity.this, policy); policiesInternal.add((AbstractPolicy)policy); ((AbstractPolicy)policy).setEntity(AbstractEntity.this); ConfigConstraints.assertValid(policy); getManagementSupport().getEntityChangeListener().onPolicyAdded(policy); sensors().emit(AbstractEntity.POLICY_ADDED, new PolicyDescriptor(policy)); }
@Override public void removeLocations(Collection<? extends Location> removedLocations) { synchronized (locations) { List<Location> oldLocations = locations.get(); Set<Location> trulyRemovedLocations = Sets.intersection(ImmutableSet.copyOf(removedLocations), ImmutableSet.copyOf(oldLocations)); locations.set(MutableList.<Location>builder().addAll(oldLocations).removeAll(removedLocations).buildImmutable()); for (Location loc : trulyRemovedLocations) { sensors().emit(AbstractEntity.LOCATION_REMOVED, loc); } } // TODO Not calling `Entities.unmanage(removedLocation)` because this location might be shared with other entities. // Relying on abstractLocation.removeChildLocation unmanaging it, but not ideal as top-level locations will stick // around forever, even if not referenced. // Same goes for AbstractEntity#clearLocations(). getManagementSupport().getEntityChangeListener().onLocationsChanged(); }
@Override public void setManagementContext(ManagementContextInternal managementContext) { super.setManagementContext(managementContext); getManagementSupport().setManagementContext(managementContext); entityType.setName(getEntityTypeName()); if (displayNameAutoGenerated) displayName.set(getEntityType().getSimpleName()+":"+Strings.maxlen(getId(), 4)); }