brooklyn.entity.group.AbstractMembershipTrackingPolicy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of brooklyn-core Show documentation
Show all versions of brooklyn-core Show documentation
Entity implementation classes, events, and other core elements
package brooklyn.entity.group;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import brooklyn.entity.Entity;
import brooklyn.entity.Group;
import brooklyn.entity.basic.DynamicGroup;
import brooklyn.entity.trait.Startable;
import brooklyn.event.Sensor;
import brooklyn.event.SensorEvent;
import brooklyn.event.SensorEventListener;
import brooklyn.policy.basic.AbstractPolicy;
import brooklyn.util.flags.SetFromFlag;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
/** abstract class which helps track membership of a group, invoking (empty) methods in this class on MEMBER{ADDED,REMOVED} events, as well as SERVICE_UP {true,false} for those members. */
public abstract class AbstractMembershipTrackingPolicy extends AbstractPolicy {
private static final Logger LOG = LoggerFactory.getLogger(AbstractMembershipTrackingPolicy.class);
private Group group;
@SetFromFlag
private Set> sensorsToTrack;
public AbstractMembershipTrackingPolicy(Map flags) {
super(flags);
if (sensorsToTrack == null) sensorsToTrack = Sets.newLinkedHashSet();
}
public AbstractMembershipTrackingPolicy() {
this(Collections.emptyMap());
}
/**
* Sets the group to be tracked; unsubscribes from any previous group, and subscribes to this group.
*
* Note this must be called *after* adding the policy to the entity.
*
* @param group
*/
public void setGroup(Group group) {
Preconditions.checkNotNull(group, "The group cannot be null");
unsubscribeFromGroup();
this.group = group;
subscribeToGroup();
}
/**
* Unsubscribes from the group.
*/
public void reset() {
unsubscribeFromGroup();
}
@Override
public void suspend() {
unsubscribeFromGroup();
super.suspend();
}
@Override
public void resume() {
super.resume();
if (group != null) {
subscribeToGroup();
}
}
// TODO having "subscribe to changes only" semantics as part of subscription would be much cleaner
// than this lightweight map
Map lastKnownServiceUpCache = new ConcurrentHashMap();
protected void subscribeToGroup() {
Preconditions.checkNotNull(group, "The group cannot be null");
LOG.debug("Subscribing to group "+group+", for memberAdded, memberRemoved, serviceUp, and {}", sensorsToTrack);
subscribe(group, DynamicGroup.MEMBER_ADDED, new SensorEventListener() {
@Override public void onEvent(SensorEvent event) {
onEntityAdded(event.getValue());
}
});
subscribe(group, DynamicGroup.MEMBER_REMOVED, new SensorEventListener() {
@Override public void onEvent(SensorEvent event) {
lastKnownServiceUpCache.remove(event.getSource());
onEntityRemoved(event.getValue());
}
});
subscribeToMembers(group, Startable.SERVICE_UP, new SensorEventListener() {
@Override public void onEvent(SensorEvent event) {
if (event.getValue() == lastKnownServiceUpCache.put(event.getSource().getId(), event.getValue()))
// ignore if value has not changed
return;
onEntityChange(event.getSource());
}
});
for (Sensor> sensor : sensorsToTrack) {
subscribeToMembers(group, sensor, new SensorEventListener
© 2015 - 2025 Weber Informatics LLC | Privacy Policy