use of org.apache.kafka.common.message.EndQuorumEpochResponseData in project kafka by apache.
the class RaftClientTestContext method assertSentEndQuorumEpochResponse.
void assertSentEndQuorumEpochResponse(Errors partitionError, int epoch, OptionalInt leaderId) {
List<RaftResponse.Outbound> sentMessages = drainSentResponses(ApiKeys.END_QUORUM_EPOCH);
assertEquals(1, sentMessages.size());
RaftMessage raftMessage = sentMessages.get(0);
assertTrue(raftMessage.data() instanceof EndQuorumEpochResponseData);
EndQuorumEpochResponseData response = (EndQuorumEpochResponseData) raftMessage.data();
assertEquals(Errors.NONE, Errors.forCode(response.errorCode()));
EndQuorumEpochResponseData.PartitionData partitionResponse = response.topics().get(0).partitions().get(0);
assertEquals(epoch, partitionResponse.leaderEpoch());
assertEquals(leaderId.orElse(-1), partitionResponse.leaderId());
assertEquals(partitionError, Errors.forCode(partitionResponse.errorCode()));
}
use of org.apache.kafka.common.message.EndQuorumEpochResponseData in project kafka by apache.
the class KafkaRaftClientTest method testElectionTimeoutAfterUserInitiatedResign.
@Test
public void testElectionTimeoutAfterUserInitiatedResign() throws Exception {
int localId = 0;
int otherNodeId = 1;
Set<Integer> voters = Utils.mkSet(localId, otherNodeId);
RaftClientTestContext context = new RaftClientTestContext.Builder(localId, voters).build();
context.becomeLeader();
assertEquals(OptionalInt.of(localId), context.currentLeader());
int resignedEpoch = context.currentEpoch();
context.client.resign(resignedEpoch);
context.pollUntil(context.client.quorum()::isResigned);
context.pollUntilRequest();
int correlationId = context.assertSentEndQuorumEpochRequest(resignedEpoch, otherNodeId);
EndQuorumEpochResponseData response = EndQuorumEpochResponse.singletonResponse(Errors.NONE, context.metadataPartition, Errors.NONE, resignedEpoch, localId);
context.deliverResponse(correlationId, otherNodeId, response);
context.client.poll();
// We do not resend `EndQuorumRequest` once the other voter has acknowledged it.
context.time.sleep(context.retryBackoffMs);
context.client.poll();
assertFalse(context.channel.hasSentRequests());
// Any `Fetch` received in the resigned state should result in a NOT_LEADER error.
context.deliverRequest(context.fetchRequest(1, -1, 0, 0, 0));
context.pollUntilResponse();
context.assertSentFetchPartitionResponse(Errors.NOT_LEADER_OR_FOLLOWER, resignedEpoch, OptionalInt.of(localId));
// After the election timer, we should become a candidate.
context.time.sleep(2 * context.electionTimeoutMs());
context.pollUntil(context.client.quorum()::isCandidate);
assertEquals(resignedEpoch + 1, context.currentEpoch());
assertEquals(new LeaderAndEpoch(OptionalInt.empty(), resignedEpoch + 1), context.listener.currentLeaderAndEpoch());
}
use of org.apache.kafka.common.message.EndQuorumEpochResponseData in project kafka by apache.
the class KafkaRaftClientTest method testClusterAuthorizationFailedInEndQuorumEpoch.
@Test
public void testClusterAuthorizationFailedInEndQuorumEpoch() throws Exception {
int localId = 0;
int otherNodeId = 1;
int epoch = 2;
Set<Integer> voters = Utils.mkSet(localId, otherNodeId);
RaftClientTestContext context = RaftClientTestContext.initializeAsLeader(localId, voters, epoch);
context.client.shutdown(5000);
context.pollUntilRequest();
int correlationId = context.assertSentEndQuorumEpochRequest(epoch, otherNodeId);
EndQuorumEpochResponseData response = new EndQuorumEpochResponseData().setErrorCode(Errors.CLUSTER_AUTHORIZATION_FAILED.code());
context.deliverResponse(correlationId, otherNodeId, response);
assertThrows(ClusterAuthorizationException.class, context.client::poll);
}
use of org.apache.kafka.common.message.EndQuorumEpochResponseData in project kafka by apache.
the class RaftClientTestContext method assertSentEndQuorumEpochResponse.
void assertSentEndQuorumEpochResponse(Errors responseError) {
List<RaftResponse.Outbound> sentMessages = drainSentResponses(ApiKeys.END_QUORUM_EPOCH);
assertEquals(1, sentMessages.size());
RaftMessage raftMessage = sentMessages.get(0);
assertTrue(raftMessage.data() instanceof EndQuorumEpochResponseData);
EndQuorumEpochResponseData response = (EndQuorumEpochResponseData) raftMessage.data();
assertEquals(responseError, Errors.forCode(response.errorCode()));
}
use of org.apache.kafka.common.message.EndQuorumEpochResponseData in project kafka by apache.
the class KafkaRaftClient method handleEndQuorumEpochResponse.
private boolean handleEndQuorumEpochResponse(RaftResponse.Inbound responseMetadata, long currentTimeMs) {
EndQuorumEpochResponseData response = (EndQuorumEpochResponseData) responseMetadata.data;
Errors topLevelError = Errors.forCode(response.errorCode());
if (topLevelError != Errors.NONE) {
return handleTopLevelError(topLevelError, responseMetadata);
}
if (!hasValidTopicPartition(response, log.topicPartition())) {
return false;
}
EndQuorumEpochResponseData.PartitionData partitionResponse = response.topics().get(0).partitions().get(0);
Errors partitionError = Errors.forCode(partitionResponse.errorCode());
OptionalInt responseLeaderId = optionalLeaderId(partitionResponse.leaderId());
int responseEpoch = partitionResponse.leaderEpoch();
Optional<Boolean> handled = maybeHandleCommonResponse(partitionError, responseLeaderId, responseEpoch, currentTimeMs);
if (handled.isPresent()) {
return handled.get();
} else if (partitionError == Errors.NONE) {
ResignedState resignedState = quorum.resignedStateOrThrow();
resignedState.acknowledgeResignation(responseMetadata.sourceId());
return true;
} else {
return handleUnexpectedError(partitionError, responseMetadata);
}
}
Aggregations