package org.radargun.stages.topology; import java.lang.reflect.Type; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.radargun.DistStageAck; import org.radargun.config.DefaultConverter; import org.radargun.config.Property; import org.radargun.config.Stage; import org.radargun.stages.AbstractDistStage; import org.radargun.traits.InjectTrait; import org.radargun.traits.Partitionable; /** * Stage that partitions the cluster into several parts that cannot communicate * * @author Radim Vansa <rvansa@redhat.com> */ @Stage(doc = "Partitions the cluster into several parts that cannot communicate.") public class SetPartitionsStage extends AbstractDistStage { @Property(optional = false, converter = UniqueCheckerConverter.class, doc = "Set of sets of partitions, " + "e.g. [0,1],[2] makes two partitions, one with slaves 0 and 1 and second with slave 2 alone.") private List<Set<Integer>> partitions; @InjectTrait(dependency = InjectTrait.Dependency.SKIP) private Partitionable partitionable; public DistStageAck executeOnSlave() { if (!shouldExecute() || !isServiceRunning()) { return successfulResponse(); } if (partitions == null) { return errorResponse("No partitions configured!", null); } int myPartitionIndex = -1; for (int i = 0; i < partitions.size(); ++i) { if (partitions.get(i).contains(slaveState.getSlaveIndex())) { myPartitionIndex = i; break; } } if (myPartitionIndex < 0) { return errorResponse("Slave " + slaveState.getSlaveIndex() + " is not contained in any partition!", null); } try { partitionable.setMembersInPartition(slaveState.getSlaveIndex(), partitions.get(myPartitionIndex)); } catch (Exception e) { return errorResponse("Error setting members in partition", e); } return successfulResponse(); } private static class UniqueCheckerConverter extends DefaultConverter { @Override public Object convert(String string, Type type) { Collection setOfSets = (Collection) super.convert(string, type); Set<Object> all = new HashSet<Object>(); for (Object set : setOfSets) { for (Object slave : (Collection) set) { if (all.contains(slave)) { throw new IllegalArgumentException("Each slave can be only in one part! Error found for slave " + slave); } all.add(slave); } } return setOfSets; } } }