public override Void Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse) { Channel.putLong(appendResponse.Term()); Channel.put(( sbyte )(appendResponse.Success() ? 1 : 0)); Channel.putLong(appendResponse.MatchIndex()); Channel.putLong(appendResponse.AppendIndex()); return(null); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request req) throws java.io.IOException public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request req) { if (req.LeaderTerm() < Ctx.term()) { Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(Ctx.myself(), Ctx.term(), false, req.PrevLogIndex(), Ctx.entryLog().appendIndex()); Outcome.addOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(req.From(), appendResponse)); return(Outcome); } Outcome.NextRole = FOLLOWER; Log.info("Moving to FOLLOWER state after receiving append entries request from %s at term %d (I am at %d)n", req.From(), req.LeaderTerm(), Ctx.term()); Appending.HandleAppendEntriesRequest(Ctx, Outcome, req, Log); return(Outcome); }
public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response) { return(Outcome); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldStepDownIfAppendEntriesRequestFromLaterTerm() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldStepDownIfAppendEntriesRequestFromLaterTerm() { // given long leaderTerm = 1; long leaderCommitIndex = 10; long rivalTerm = leaderTerm + 1; long logIndex = 20; RaftLogEntry[] entries = new RaftLogEntry[] { new RaftLogEntry(rivalTerm, ReplicatedInteger.valueOf(99)) }; Leader leader = new Leader(); RaftState state = raftState().term(leaderTerm).commitIndex(leaderCommitIndex).build(); // when Outcome outcome = leader.Handle(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request(_member1, rivalTerm, logIndex, leaderTerm, entries, leaderCommitIndex), state, Log()); // then assertThat(outcome.Role, equalTo(FOLLOWER)); assertThat(outcome.Leader, equalTo(_member1)); assertThat(outcome.Term, equalTo(rivalTerm)); Org.Neo4j.causalclustering.core.consensus.RaftMessages_RaftMessage response = messageFor(outcome, _member1); assertThat(response, instanceOf(typeof(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response))); Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response typedResponse = (Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response)response; assertThat(typedResponse.Term(), equalTo(rivalTerm)); // Not checking success or failure of append }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldRespondNegativelyToAppendEntriesRequestFromEarlierTerm() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldRespondNegativelyToAppendEntriesRequestFromEarlierTerm() { // given long leaderTerm = 5; long leaderCommitIndex = 10; long rivalTerm = leaderTerm - 1; long logIndex = 20; RaftLogEntry[] entries = new RaftLogEntry[] { new RaftLogEntry(rivalTerm, ReplicatedInteger.valueOf(99)) }; Leader leader = new Leader(); RaftState state = raftState().term(leaderTerm).commitIndex(leaderCommitIndex).build(); // when Outcome outcome = leader.Handle(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request(_member1, rivalTerm, logIndex, leaderTerm, entries, leaderCommitIndex), state, Log()); // then assertThat(outcome.Role, equalTo(LEADER)); assertThat(outcome.Term, equalTo(leaderTerm)); Org.Neo4j.causalclustering.core.consensus.RaftMessages_RaftMessage response = messageFor(outcome, _member1); assertThat(response, instanceOf(typeof(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response))); Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response typedResponse = (Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response)response; assertThat(typedResponse.Term(), equalTo(leaderTerm)); assertThat(typedResponse.Success(), equalTo(false)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void leaderShouldRejectAppendEntriesResponseWithNewerTermAndBecomeAFollower() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void LeaderShouldRejectAppendEntriesResponseWithNewerTermAndBecomeAFollower() { // given RaftState state = raftState().myself(_myself).build(); Leader leader = new Leader(); // when Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response message = appendEntriesResponse().from(_member1).term(state.Term() + 1).build(); Outcome outcome = leader.Handle(message, state, Log()); // then assertEquals(0, count(outcome.OutgoingMessages)); assertEquals(FOLLOWER, outcome.Role); assertEquals(0, count(outcome.LogCommands)); assertEquals(state.Term() + 1, outcome.Term); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldIgnoreAppendResponsesFromOldTerms() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldIgnoreAppendResponsesFromOldTerms() { // given Leader leader = new Leader(); long leaderTerm = 5; long followerTerm = 3; RaftState state = raftState().term(leaderTerm).build(); Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response incomingResponse = appendEntriesResponse().failure().term(followerTerm).from(_member1).build(); // when Outcome outcome = leader.Handle(incomingResponse, state, Log()); // then assertThat(outcome.Term, equalTo(leaderTerm)); assertThat(outcome.Role, equalTo(LEADER)); assertThat(outcome.OutgoingMessages, empty()); assertThat(outcome.ShipCommands, empty()); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: public void decode(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf buffer, java.util.List<Object> list) throws Exception public override void Decode(ChannelHandlerContext ctx, ByteBuf buffer, IList <object> list) { ReadableChannel channel = new NetworkReadableClosableChannelNetty4(buffer); ClusterId clusterId = ClusterId.Marshal.INSTANCE.unmarshal(channel); int messageTypeWire = channel.Int; Org.Neo4j.causalclustering.core.consensus.RaftMessages_Type[] values = Enum.GetValues(typeof(Org.Neo4j.causalclustering.core.consensus.RaftMessages_Type)); Org.Neo4j.causalclustering.core.consensus.RaftMessages_Type messageType = values[messageTypeWire]; MemberId from = RetrieveMember(channel); Org.Neo4j.causalclustering.core.consensus.RaftMessages_RaftMessage result; if (messageType.Equals(VOTE_REQUEST)) { MemberId candidate = RetrieveMember(channel); long term = channel.Long; long lastLogIndex = channel.Long; long lastLogTerm = channel.Long; result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Vote_Request(from, term, candidate, lastLogIndex, lastLogTerm); } else if (messageType.Equals(VOTE_RESPONSE)) { long term = channel.Long; bool voteGranted = channel.Get() == 1; result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Vote_Response(from, term, voteGranted); } else if (messageType.Equals(PRE_VOTE_REQUEST)) { MemberId candidate = RetrieveMember(channel); long term = channel.Long; long lastLogIndex = channel.Long; long lastLogTerm = channel.Long; result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_PreVote_Request(from, term, candidate, lastLogIndex, lastLogTerm); } else if (messageType.Equals(PRE_VOTE_RESPONSE)) { long term = channel.Long; bool voteGranted = channel.Get() == 1; result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_PreVote_Response(from, term, voteGranted); } else if (messageType.Equals(APPEND_ENTRIES_REQUEST)) { // how many long term = channel.Long; long prevLogIndex = channel.Long; long prevLogTerm = channel.Long; long leaderCommit = channel.Long; long count = channel.Long; RaftLogEntry[] entries = new RaftLogEntry[( int )count]; for (int i = 0; i < count; i++) { long entryTerm = channel.Long; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final org.neo4j.causalclustering.core.replication.ReplicatedContent content = marshal.unmarshal(channel); ReplicatedContent content = _marshal.unmarshal(channel); entries[i] = new RaftLogEntry(entryTerm, content); } result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request(from, term, prevLogIndex, prevLogTerm, entries, leaderCommit); } else if (messageType.Equals(APPEND_ENTRIES_RESPONSE)) { long term = channel.Long; bool success = channel.Get() == 1; long matchIndex = channel.Long; long appendIndex = channel.Long; result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(from, term, success, matchIndex, appendIndex); } else if (messageType.Equals(NEW_ENTRY_REQUEST)) { ReplicatedContent content = _marshal.unmarshal(channel); result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_NewEntry_Request(from, content); } else if (messageType.Equals(HEARTBEAT)) { long leaderTerm = channel.Long; long commitIndexTerm = channel.Long; long commitIndex = channel.Long; result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Heartbeat(from, leaderTerm, commitIndex, commitIndexTerm); } else if (messageType.Equals(HEARTBEAT_RESPONSE)) { result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_HeartbeatResponse(from); } else if (messageType.Equals(LOG_COMPACTION_INFO)) { long leaderTerm = channel.Long; long prevIndex = channel.Long; result = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_LogCompactionInfo(from, leaderTerm, prevIndex); } else { throw new System.ArgumentException("Unknown message type"); } list.Add(Org.Neo4j.causalclustering.core.consensus.RaftMessages_ReceivedInstantClusterIdAwareMessage.of(_clock.instant(), clusterId, result)); }
// TODO: rethink this test, it does too much //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void leaderShouldSpawnMismatchCommandOnFailure() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void LeaderShouldSpawnMismatchCommandOnFailure() { // given /* * A leader who * - has an append index of 100 * - knows about instance 2 * - assumes that instance 2 is fully caught up */ Leader leader = new Leader(); MemberId instance2 = member(2); FollowerState instance2State = CreateArtificialFollowerState(100); ReadableRaftState state = mock(typeof(ReadableRaftState)); FollowerStates <MemberId> followerState = new FollowerStates <MemberId>(); followerState = new FollowerStates <MemberId>(followerState, instance2, instance2State); RaftLog log = new InMemoryRaftLog(); for (int i = 0; i <= 100; i++) { log.Append(new RaftLogEntry(0, valueOf(i))); } when(state.CommitIndex()).thenReturn(-1L); when(state.EntryLog()).thenReturn(log); when(state.FollowerStates()).thenReturn(followerState); when(state.Term()).thenReturn(4L); // both leader and follower are in the same term // when // that leader is asked to handle a response from that follower that says that the follower is still missing // things Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response = appendEntriesResponse().failure().appendIndex(0).matchIndex(-1).term(4).from(instance2).build(); Outcome outcome = leader.Handle(response, state, mock(typeof(Log))); // then int mismatchCount = 0; foreach (ShipCommand shipCommand in outcome.ShipCommands) { if (shipCommand is ShipCommand.Mismatch) { mismatchCount++; } } assertThat(mismatchCount, greaterThan(0)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void leaderShouldIgnoreSuccessResponseThatIndicatesLaggingWhileLocalStateIndicatesFollowerIsCaughtUp() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void LeaderShouldIgnoreSuccessResponseThatIndicatesLaggingWhileLocalStateIndicatesFollowerIsCaughtUp() { // given /* * A leader who * - has an append index of 100 * - knows about instance 2 * - assumes that instance 2 is fully caught up */ Leader leader = new Leader(); MemberId instance2 = member(2); int j = 100; FollowerState instance2State = CreateArtificialFollowerState(j); ReadableRaftState state = mock(typeof(ReadableRaftState)); FollowerStates <MemberId> followerState = new FollowerStates <MemberId>(); followerState = new FollowerStates <MemberId>(followerState, instance2, instance2State); ReadableRaftLog logMock = mock(typeof(ReadableRaftLog)); when(logMock.AppendIndex()).thenReturn(100L); // with commit requests in this test when(state.CommitIndex()).thenReturn(-1L); when(state.EntryLog()).thenReturn(logMock); when(state.FollowerStates()).thenReturn(followerState); when(state.Term()).thenReturn(4L); // both leader and follower are in the same term // when that leader is asked to handle a response from that follower that says that the follower is still // missing things Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response = appendEntriesResponse().success().matchIndex(80).term(4).from(instance2).build(); Outcome outcome = leader.Handle(response, state, mock(typeof(Log))); // then the leader should not send anything, since this is a delayed, out of order response to a previous append // request assertTrue(outcome.OutgoingMessages.Count == 0); // The follower state should not be touched FollowerStates <MemberId> updatedFollowerStates = outcome.FollowerStates; assertEquals(100, updatedFollowerStates.Get(instance2).MatchIndex); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void leaderShouldRespondToSuccessResponseThatIndicatesLaggingFollowerWithJustWhatItsMissing() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void LeaderShouldRespondToSuccessResponseThatIndicatesLaggingFollowerWithJustWhatItsMissing() { // given /* * A leader who * - has an append index of 100 * - knows about instance 2 * - assumes that instance 2 is at an index less than 100 -say 50 */ Leader leader = new Leader(); MemberId instance2 = member(2); FollowerState instance2State = CreateArtificialFollowerState(50); ReadableRaftState state = mock(typeof(ReadableRaftState)); FollowerStates <MemberId> followerState = new FollowerStates <MemberId>(); followerState = new FollowerStates <MemberId>(followerState, instance2, instance2State); ReadableRaftLog logMock = mock(typeof(ReadableRaftLog)); when(logMock.AppendIndex()).thenReturn(100L); // with commit requests in this test when(state.CommitIndex()).thenReturn(-1L); when(state.EntryLog()).thenReturn(logMock); when(state.FollowerStates()).thenReturn(followerState); when(state.Term()).thenReturn(231L); // both leader and follower are in the same term // when that leader is asked to handle a response from that follower that says that the follower is still // missing things Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response = appendEntriesResponse().success().matchIndex(89).term(231).from(instance2).build(); Outcome outcome = leader.Handle(response, state, mock(typeof(Log))); // then int matchCount = 0; foreach (ShipCommand shipCommand in outcome.ShipCommands) { if (shipCommand is ShipCommand.Match) { matchCount++; } } assertThat(matchCount, greaterThan(0)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void leaderShouldNotRespondToSuccessResponseThatIndicatesUpToDateFollower() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void LeaderShouldNotRespondToSuccessResponseThatIndicatesUpToDateFollower() { // given /* * A leader who * - has an append index of 100 * - knows about instance 2 * - assumes that instance 2 is at an index less than 100 -say 84 */ Leader leader = new Leader(); MemberId instance2 = member(2); FollowerState instance2State = CreateArtificialFollowerState(84); ReadableRaftState state = mock(typeof(ReadableRaftState)); FollowerStates <MemberId> followerState = new FollowerStates <MemberId>(); followerState = new FollowerStates <MemberId>(followerState, instance2, instance2State); ReadableRaftLog logMock = mock(typeof(ReadableRaftLog)); when(logMock.AppendIndex()).thenReturn(100L); when(state.CommitIndex()).thenReturn(-1L); when(state.EntryLog()).thenReturn(logMock); when(state.FollowerStates()).thenReturn(followerState); when(state.Term()).thenReturn(4L); // both leader and follower are in the same term // when // that leader is asked to handle a response from that follower that says that the follower is up to date Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response = appendEntriesResponse().success().matchIndex(100).term(4).from(instance2).build(); Outcome outcome = leader.Handle(response, state, mock(typeof(Log))); // then // The leader should not be trying to send any messages to that instance assertTrue(outcome.OutgoingMessages.Count == 0); // And the follower state should be updated FollowerStates <MemberId> updatedFollowerStates = outcome.FollowerStates; assertEquals(100, updatedFollowerStates.Get(instance2).MatchIndex); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response) throws java.io.IOException public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response) { if (response.Term() < Ctx.term()) { /* Ignore responses from old terms! */ return(Outcome); } else if (response.Term() > Ctx.term()) { Outcome.NextTerm = response.Term(); StepDownToFollower(Outcome, Ctx); Log.info("Moving to FOLLOWER state after receiving append response at term %d (my term is " + "%d) from %s", response.Term(), Ctx.term(), response.From()); Outcome.replaceFollowerStates(new FollowerStates <MemberId>()); return(Outcome); } FollowerState follower = Ctx.followerStates().get(response.From()); if (response.Success()) { Debug.Assert(response.MatchIndex() <= Ctx.entryLog().appendIndex()); bool followerProgressed = response.MatchIndex() > follower.MatchIndex; Outcome.replaceFollowerStates(Outcome.FollowerStates.onSuccessResponse(response.From(), max(response.MatchIndex(), follower.MatchIndex))); Outcome.addShipCommand(new ShipCommand.Match(response.MatchIndex(), response.From())); /* * Matches from older terms can in complicated leadership change / log truncation scenarios * be overwritten, even if they were replicated to a majority of instances. Thus we must only * consider matches from this leader's term when figuring out which have been safely replicated * and are ready for commit. * This is explained nicely in Figure 3.7 of the thesis */ bool matchInCurrentTerm = Ctx.entryLog().readEntryTerm(response.MatchIndex()) == Ctx.term(); /* * The quorum situation may have changed only if the follower actually progressed. */ if (followerProgressed && matchInCurrentTerm) { // TODO: Test that mismatch between voting and participating members affects commit outcome long quorumAppendIndex = Followers.quorumAppendIndex(Ctx.votingMembers(), Outcome.FollowerStates); if (quorumAppendIndex > Ctx.commitIndex()) { Outcome.LeaderCommit = quorumAppendIndex; Outcome.CommitIndex = quorumAppendIndex; Outcome.addShipCommand(new ShipCommand.CommitUpdate()); } } } else // Response indicated failure. { if (response.AppendIndex() > -1 && response.AppendIndex() >= Ctx.entryLog().prevIndex()) { // Signal a mismatch to the log shipper, which will serve an earlier entry. Outcome.addShipCommand(new ShipCommand.Mismatch(response.AppendIndex(), response.From())); } else { // There are no earlier entries, message the follower that we have compacted so that // it can take appropriate action. RaftMessages_LogCompactionInfo compactionInfo = new RaftMessages_LogCompactionInfo(Ctx.myself(), Ctx.term(), Ctx.entryLog().prevIndex()); Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed directedCompactionInfo = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(response.From(), compactionInfo); Outcome.addOutgoingMessage(directedCompactionInfo); } } return(Outcome); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request req) throws java.io.IOException public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request req) { if (req.LeaderTerm() < Ctx.term()) { Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(Ctx.myself(), Ctx.term(), false, -1, Ctx.entryLog().appendIndex()); Outcome.addOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(req.From(), appendResponse)); return(Outcome); } else if (req.LeaderTerm() == Ctx.term()) { throw new System.InvalidOperationException("Two leaders in the same term."); } else { // There is a new leader in a later term, we should revert to follower. (§5.1) StepDownToFollower(Outcome, Ctx); Log.info("Moving to FOLLOWER state after receiving append request at term %d (my term is " + "%d) from %s", req.LeaderTerm(), Ctx.term(), req.From()); Appending.HandleAppendEntriesRequest(Ctx, Outcome, req, Log); return(Outcome); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldSerializeAppendResponse() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldSerializeAppendResponse() { MemberId sender = new MemberId(System.Guid.randomUUID()); Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response request = (new AppendEntriesResponseBuilder()).from(sender).success().matchIndex(12).build(); SerializeReadBackAndVerifyMessage(request); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldSendCompactionInfoIfFailureWithNoEarlierEntries() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldSendCompactionInfoIfFailureWithNoEarlierEntries() { // given Leader leader = new Leader(); long term = 1; long leaderPrevIndex = 3; long followerIndex = leaderPrevIndex - 1; InMemoryRaftLog raftLog = new InMemoryRaftLog(); raftLog.Skip(leaderPrevIndex, term); RaftState state = raftState().term(term).entryLog(raftLog).build(); Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response incomingResponse = appendEntriesResponse().failure().term(term).appendIndex(followerIndex).from(_member1).build(); // when Outcome outcome = leader.Handle(incomingResponse, state, Log()); // then Org.Neo4j.causalclustering.core.consensus.RaftMessages_RaftMessage outgoingMessage = messageFor(outcome, _member1); assertThat(outgoingMessage, instanceOf(typeof(Org.Neo4j.causalclustering.core.consensus.RaftMessages_LogCompactionInfo))); Org.Neo4j.causalclustering.core.consensus.RaftMessages_LogCompactionInfo typedOutgoingMessage = (Org.Neo4j.causalclustering.core.consensus.RaftMessages_LogCompactionInfo)outgoingMessage; assertThat(typedOutgoingMessage.PrevIndex(), equalTo(leaderPrevIndex)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldEncodeAndDecodeAppendEntriesResponse() public virtual void ShouldEncodeAndDecodeAppendEntriesResponse() { // given MemberId member = new MemberId(System.Guid.randomUUID()); Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(member, 1, false, -1, 0); // when _channel.writeOutbound(response); object message = _channel.readOutbound(); _channel.writeInbound(message); // then assertEquals(response, _channel.readInbound()); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: static void handleAppendEntriesRequest(org.neo4j.causalclustering.core.consensus.state.ReadableRaftState state, org.neo4j.causalclustering.core.consensus.outcome.Outcome outcome, org.neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request request, org.neo4j.logging.Log log) throws java.io.IOException internal static void HandleAppendEntriesRequest(ReadableRaftState state, Outcome outcome, Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request request, Log log) { if (request.LeaderTerm() < state.Term()) { Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(state.Myself(), state.Term(), false, -1, state.EntryLog().appendIndex()); outcome.AddOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(request.From(), appendResponse)); return; } outcome.PreElection = false; outcome.NextTerm = request.LeaderTerm(); outcome.Leader = request.From(); outcome.LeaderCommit = request.LeaderCommit(); if (!Follower.LogHistoryMatches(state, request.PrevLogIndex(), request.PrevLogTerm())) { Debug.Assert(request.PrevLogIndex() > -1 && request.PrevLogTerm() > -1); Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(state.Myself(), request.LeaderTerm(), false, -1, state.EntryLog().appendIndex()); outcome.AddOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(request.From(), appendResponse)); return; } long baseIndex = request.PrevLogIndex() + 1; int offset; /* Find possible truncation point. */ for (offset = 0; offset < request.Entries().Length; offset++) { long logIndex = baseIndex + offset; long logTerm = state.EntryLog().readEntryTerm(logIndex); if (logIndex > state.EntryLog().appendIndex()) { // entry doesn't exist because it's beyond the current log end, so we can go ahead and append break; } else if (logIndex < state.EntryLog().prevIndex()) { // entry doesn't exist because it's before the earliest known entry, so continue with the next one continue; } else if (logTerm != request.Entries()[offset].term()) { /* * the entry's index falls within our current range and the term doesn't match what we know. We must * truncate. */ if (logIndex <= state.CommitIndex()) // first, assert that we haven't committed what we are about to truncate { throw new System.InvalidOperationException(format("Cannot truncate entry at index %d with term %d when commit index is at %d", logIndex, logTerm, state.CommitIndex())); } outcome.AddLogCommand(new TruncateLogCommand(logIndex)); break; } } if (offset < request.Entries().Length) { outcome.AddLogCommand(new BatchAppendLogEntries(baseIndex, offset, request.Entries())); } Follower.CommitToLogOnUpdate(state, request.PrevLogIndex() + request.Entries().Length, request.LeaderCommit(), outcome); long endMatchIndex = request.PrevLogIndex() + request.Entries().Length; // this is the index of the last incoming entry Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(state.Myself(), request.LeaderTerm(), true, endMatchIndex, endMatchIndex); outcome.AddOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(request.From(), appendResponse)); }