X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2FMockRaftActorContext.java;h=05b1d34a0f8b921cffbd192c0b9bb9cfefc6c494;hp=adf7778fe7daa068d5f6e1bfab0110f6665bc62c;hb=8049fd4d06da0f4616180e46fbbe95f98cf698ea;hpb=254cfb302af490110740ebef111ae28783018a02 diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java index adf7778fe7..05b1d34a0f 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActorContext.java @@ -13,37 +13,34 @@ import akka.actor.ActorSelection; import akka.actor.ActorSystem; import akka.actor.Props; import akka.japi.Procedure; -import com.google.common.base.Preconditions; -import com.google.common.base.Supplier; -import com.google.protobuf.GeneratedMessage; +import com.google.common.base.Throwables; +import com.google.common.io.ByteSource; +import java.io.IOException; +import java.io.OutputStream; import java.io.Serializable; import java.util.HashMap; import java.util.Map; -import org.opendaylight.controller.cluster.DataPersistenceProvider; +import java.util.Optional; +import java.util.function.Consumer; import org.opendaylight.controller.cluster.NonPersistentDataProvider; +import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior; +import org.opendaylight.controller.cluster.raft.persisted.ByteState; +import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry; +import org.opendaylight.controller.cluster.raft.persisted.Snapshot.State; +import org.opendaylight.controller.cluster.raft.policy.RaftPolicy; import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload; -import org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages; -import org.opendaylight.controller.protobuff.messages.cluster.raft.test.MockPayloadMessages; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class MockRaftActorContext implements RaftActorContext { +public class MockRaftActorContext extends RaftActorContextImpl { + private static final Logger LOG = LoggerFactory.getLogger(MockRaftActorContext.class); - private String id; private ActorSystem system; - private ActorRef actor; - private long index = 0; - private long lastApplied = 0; - private final ElectionTerm electionTerm; - private ReplicatedLog replicatedLog; - private Map peerAddresses = new HashMap<>(); - private ConfigParams configParams; - private boolean snapshotCaptureInitiated; - private SnapshotManager snapshotManager; - private DataPersistenceProvider persistenceProvider = new NonPersistentDataProvider(); - - public MockRaftActorContext(){ - electionTerm = new ElectionTerm() { + private RaftPolicy raftPolicy; + private Consumer> createSnapshotProcedure = out -> { }; + + private static ElectionTerm newElectionTerm() { + return new ElectionTerm() { private long currentTerm = 1; private String votedFor = ""; @@ -58,37 +55,44 @@ public class MockRaftActorContext implements RaftActorContext { } @Override - public void update(long currentTerm, String votedFor){ - this.currentTerm = currentTerm; - this.votedFor = votedFor; + public void update(long newTerm, String newVotedFor) { + this.currentTerm = newTerm; + this.votedFor = newVotedFor; // TODO : Write to some persistent state } - @Override public void updateAndPersist(long currentTerm, - String votedFor) { - update(currentTerm, votedFor); + @Override public void updateAndPersist(long newTerm, String newVotedFor) { + update(newTerm, newVotedFor); } }; + } - configParams = new DefaultConfigParamsImpl(); + public MockRaftActorContext() { + super(null, null, "test", newElectionTerm(), -1, -1, new HashMap<>(), + new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), applyState -> { }, LOG); + setReplicatedLog(new MockReplicatedLogBuilder().build()); } - public MockRaftActorContext(String id, ActorSystem system, ActorRef actor){ - this(); - this.id = id; + public MockRaftActorContext(String id, ActorSystem system, ActorRef actor) { + super(actor, null, id, newElectionTerm(), -1, -1, new HashMap<>(), + new DefaultConfigParamsImpl(), new NonPersistentDataProvider(), + applyState -> actor.tell(applyState, actor), LOG); + this.system = system; - this.actor = actor; initReplicatedLog(); } - public void initReplicatedLog(){ - this.replicatedLog = new SimpleReplicatedLog(); + public void initReplicatedLog() { + SimpleReplicatedLog replicatedLog = new SimpleReplicatedLog(); long term = getTermInformation().getCurrentTerm(); - this.replicatedLog.append(new MockReplicatedLogEntry(term, 0, new MockPayload("1"))); - this.replicatedLog.append(new MockReplicatedLogEntry(term, 1, new MockPayload("2"))); + replicatedLog.append(new SimpleReplicatedLogEntry(0, term, new MockPayload("1"))); + replicatedLog.append(new SimpleReplicatedLogEntry(1, term, new MockPayload("2"))); + setReplicatedLog(replicatedLog); + setCommitIndex(replicatedLog.lastIndex()); + setLastApplied(replicatedLog.lastIndex()); } @Override public ActorRef actorOf(Props props) { @@ -99,164 +103,99 @@ public class MockRaftActorContext implements RaftActorContext { return system.actorSelection(path); } - @Override public String getId() { - return id; - } - - @Override public ActorRef getActor() { - return actor; - } - - @Override public ElectionTerm getTermInformation() { - return electionTerm; - } - - public void setIndex(long index){ - this.index = index; - } - - @Override public long getCommitIndex() { - return index; - } - - @Override public void setCommitIndex(long commitIndex) { - this.index = commitIndex; - } - - @Override public void setLastApplied(long lastApplied){ - this.lastApplied = lastApplied; - } - - @Override public long getLastApplied() { - return lastApplied; - } - - @Override - // FIXME : A lot of tests try to manipulate the replicated log by setting it using this method - // This is OK to do if the underlyingActor is not RafActor or a derived class. If not then you should not - // used this way to manipulate the log because the RaftActor actually has a field replicatedLog - // which it creates internally and sets on the RaftActorContext - // The only right way to manipulate the replicated log therefore is to get it from either the RaftActor - // or the RaftActorContext and modify the entries in there instead of trying to replace it by using this setter - // Simple assertion that will fail if you do so - // ReplicatedLog log = new ReplicatedLogImpl(); - // raftActor.underlyingActor().getRaftActorContext().setReplicatedLog(log); - // assertEquals(log, raftActor.underlyingActor().getReplicatedLog()) - public void setReplicatedLog(ReplicatedLog replicatedLog) { - this.replicatedLog = replicatedLog; - } - - @Override public ReplicatedLog getReplicatedLog() { - return replicatedLog; - } - @Override public ActorSystem getActorSystem() { return this.system; } - @Override public Logger getLogger() { - return LoggerFactory.getLogger(getClass()); - } - - @Override public Map getPeerAddresses() { - return peerAddresses; - } - - @Override public String getPeerAddress(String peerId) { - return peerAddresses.get(peerId); - } - - @Override public void addToPeers(String name, String address) { - peerAddresses.put(name, address); - } - - @Override public void removePeer(String name) { - peerAddresses.remove(name); - } - @Override public ActorSelection getPeerActorSelection(String peerId) { String peerAddress = getPeerAddress(peerId); - if(peerAddress != null){ + if (peerAddress != null) { return actorSelection(peerAddress); } return null; } - @Override public void setPeerAddress(String peerId, String peerAddress) { - Preconditions.checkState(peerAddresses.containsKey(peerId)); - peerAddresses.put(peerId, peerAddress); - } - public void setPeerAddresses(Map peerAddresses) { - this.peerAddresses = peerAddresses; - } + for (String id: getPeerIds()) { + removePeer(id); + } - @Override - public ConfigParams getConfigParams() { - return configParams; + for (Map.Entry e: peerAddresses.entrySet()) { + addToPeers(e.getKey(), e.getValue(), VotingState.VOTING); + } } @Override public SnapshotManager getSnapshotManager() { - if(this.snapshotManager == null){ - this.snapshotManager = new SnapshotManager(this, getLogger()); - } - return this.snapshotManager; - } + SnapshotManager snapshotManager = super.getSnapshotManager(); + snapshotManager.setCreateSnapshotConsumer(createSnapshotProcedure); - public void setConfigParams(ConfigParams configParams) { - this.configParams = configParams; - } + snapshotManager.setSnapshotCohort(new RaftActorSnapshotCohort() { + @Override + public State deserializeSnapshot(ByteSource snapshotBytes) throws IOException { + return ByteState.of(snapshotBytes.read()); + } - @Override - public long getTotalMemory() { - return Runtime.getRuntime().totalMemory(); - } + @Override + public void createSnapshot(ActorRef actorRef, java.util.Optional installSnapshotStream) { + } - @Override - public void setTotalMemoryRetriever(Supplier retriever) { + @Override + public void applySnapshot(State snapshotState) { + } + }); + + return snapshotManager; } - @Override - public boolean hasFollowers() { - return getPeerAddresses().keySet().size() > 0; + public void setCreateSnapshotProcedure(Consumer> createSnapshotProcedure) { + this.createSnapshotProcedure = createSnapshotProcedure; } @Override - public DataPersistenceProvider getPersistenceProvider() { - return persistenceProvider; + public RaftPolicy getRaftPolicy() { + return raftPolicy != null ? raftPolicy : super.getRaftPolicy(); } - public void setPersistenceProvider(DataPersistenceProvider persistenceProvider) { - this.persistenceProvider = persistenceProvider; + public void setRaftPolicy(RaftPolicy raftPolicy) { + this.raftPolicy = raftPolicy; } public static class SimpleReplicatedLog extends AbstractReplicatedLogImpl { - @Override public void appendAndPersist( - ReplicatedLogEntry replicatedLogEntry) { - append(replicatedLogEntry); - } - @Override public int dataSize() { return -1; } - @Override public void removeFromAndPersist(long index) { - removeFrom(index); + @Override + public void captureSnapshotIfReady(ReplicatedLogEntry replicatedLogEntry) { } @Override - public void appendAndPersist(ReplicatedLogEntry replicatedLogEntry, Procedure callback) { + public boolean shouldCaptureSnapshot(long logIndex) { + return false; + } + + @Override + public boolean removeFromAndPersist(long index) { + return removeFrom(index) >= 0; + } + + @Override + @SuppressWarnings("checkstyle:IllegalCatch") + public boolean appendAndPersist(ReplicatedLogEntry replicatedLogEntry, Procedure callback, + boolean doAsync) { append(replicatedLogEntry); - if(callback != null) { + if (callback != null) { try { callback.apply(replicatedLogEntry); } catch (Exception e) { - e.printStackTrace(); + Throwables.propagate(e); } } + + return true; } } @@ -268,38 +207,21 @@ public class MockRaftActorContext implements RaftActorContext { public MockPayload() { } - public MockPayload(String s) { - this.value = s; + public MockPayload(String data) { + this.value = data; size = value.length(); } - public MockPayload(String s, int size) { - this(s); + public MockPayload(String data, int size) { + this(data); this.size = size; } - @Override public Map, String> encode() { - Map, String> map = new HashMap<>(); - map.put(MockPayloadMessages.value, value); - return map; - } - - @Override public Payload decode( - AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload payloadProtoBuff) { - String value = payloadProtoBuff.getExtension(MockPayloadMessages.value); - this.value = value; - return this; - } - @Override public int size() { return size; } - @Override public String getClientPayloadClassName() { - return MockPayload.class.getName(); - } - @Override public String toString() { return value; @@ -309,7 +231,7 @@ public class MockRaftActorContext implements RaftActorContext { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((value == null) ? 0 : value.hashCode()); + result = prime * result + (value == null ? 0 : value.hashCode()); return result; } @@ -336,96 +258,19 @@ public class MockRaftActorContext implements RaftActorContext { } } - public static class MockReplicatedLogEntry implements ReplicatedLogEntry, Serializable { - private static final long serialVersionUID = 1L; - - private final long term; - private final long index; - private final Payload data; - - public MockReplicatedLogEntry(long term, long index, Payload data){ - - this.term = term; - this.index = index; - this.data = data; - } - - @Override public Payload getData() { - return data; - } - - @Override public long getTerm() { - return term; - } - - @Override public long getIndex() { - return index; - } - - @Override - public int size() { - return getData().size(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((data == null) ? 0 : data.hashCode()); - result = prime * result + (int) (index ^ (index >>> 32)); - result = prime * result + (int) (term ^ (term >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - MockReplicatedLogEntry other = (MockReplicatedLogEntry) obj; - if (data == null) { - if (other.data != null) { - return false; - } - } else if (!data.equals(other.data)) { - return false; - } - if (index != other.index) { - return false; - } - if (term != other.term) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("MockReplicatedLogEntry [term=").append(term).append(", index=").append(index) - .append(", data=").append(data).append("]"); - return builder.toString(); - } - } - public static class MockReplicatedLogBuilder { private final ReplicatedLog mockLog = new SimpleReplicatedLog(); public MockReplicatedLogBuilder createEntries(int start, int end, int term) { - for (int i=start; i