package org.radargun.stages.topology; import java.util.EnumSet; import java.util.List; import org.radargun.DistStageAck; import org.radargun.config.Property; import org.radargun.config.Stage; import org.radargun.stages.AbstractDistStage; import org.radargun.traits.InjectTrait; import org.radargun.traits.TopologyHistory; import org.radargun.traits.TopologyHistory.Event; import org.radargun.utils.TimeConverter; import org.radargun.utils.TimeService; import static org.radargun.traits.TopologyHistory.HistoryType; /** * Controls which topology events have (not) happened recently * * @author Radim Vansa <rvansa@redhat.com> */ @Stage(doc = "Controls which topology events have (not) happened recently") public class CheckTopologyStage extends AbstractDistStage { @Property(doc = "Name of the cache. Default is the default cache.") public String cacheName; @Property(doc = "Type of events to check in this stage. Default are TOPOLOGY, REHASH, CACHE_STATUS (see org.radargun.traits.TopologyHistory.HistoryType).") public EnumSet<TopologyHistory.HistoryType> checkEvents = EnumSet.allOf(TopologyHistory.HistoryType.class); @Property(converter = TimeConverter.class, doc = "The period in milliseconds which is checked. Default is infinite.") public long period = Long.MAX_VALUE; @Property(doc = "The check controls if this event has happened (true) or not happened (false). Defaults to true.") public boolean changed = true; @InjectTrait(dependency = InjectTrait.Dependency.MANDATORY) private TopologyHistory topologyHistory; @Override public DistStageAck executeOnSlave() { if (!shouldExecute()) { log.debug("Ignoring this slave"); return successfulResponse(); } if (checkEvents.contains(HistoryType.TOPOLOGY)) { List<Event> history = topologyHistory.getTopologyChangeHistory(cacheName); if (!check(history)) { return errorResponse("Topology check failed, " + (history.isEmpty() ? "no change in history" : "last change " + history.get(history.size() - 1))); } else { log.debug("Topology check passed."); } } if (checkEvents.contains(HistoryType.REHASH)) { List<Event> history = topologyHistory.getRehashHistory(cacheName); if (!check(history)) { return errorResponse("Hash check failed, " + (history.isEmpty() ? "no change in history" : "last change " + history.get(history.size() - 1))); } else { log.debug("Hash check passed."); } } if (checkEvents.contains(HistoryType.CACHE_STATUS)) { List<Event> history = topologyHistory.getCacheStatusChangeHistory(cacheName); if (!check(history)) { return errorResponse("Cache status check failed, " + (history.isEmpty() ? "no change in history" : "last change " + history.get(history.size() - 1))); } else { log.debug("Cache status check passed."); } } return successfulResponse(); } private boolean check(List<Event> history) { if (history.isEmpty()) return !changed; long lastChange = history.get(history.size() - 1).getTime().getTime(); long current = TimeService.currentTimeMillis(); boolean hasChanged = lastChange + period > current; return hasChanged == changed; } }