Search in sources :

Example 1 with EndQuorumEpochResponseData

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()));
}
Also used : EndQuorumEpochResponseData(org.apache.kafka.common.message.EndQuorumEpochResponseData)

Example 2 with EndQuorumEpochResponseData

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());
}
Also used : EndQuorumEpochResponseData(org.apache.kafka.common.message.EndQuorumEpochResponseData) Test(org.junit.jupiter.api.Test)

Example 3 with EndQuorumEpochResponseData

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);
}
Also used : EndQuorumEpochResponseData(org.apache.kafka.common.message.EndQuorumEpochResponseData) Test(org.junit.jupiter.api.Test)

Example 4 with EndQuorumEpochResponseData

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()));
}
Also used : EndQuorumEpochResponseData(org.apache.kafka.common.message.EndQuorumEpochResponseData)

Example 5 with EndQuorumEpochResponseData

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);
    }
}
Also used : Errors(org.apache.kafka.common.protocol.Errors) EndQuorumEpochResponseData(org.apache.kafka.common.message.EndQuorumEpochResponseData) OptionalInt(java.util.OptionalInt)

Aggregations

EndQuorumEpochResponseData (org.apache.kafka.common.message.EndQuorumEpochResponseData)6 Errors (org.apache.kafka.common.protocol.Errors)2 Test (org.junit.jupiter.api.Test)2 OptionalInt (java.util.OptionalInt)1 EndQuorumEpochRequestData (org.apache.kafka.common.message.EndQuorumEpochRequestData)1