use of org.apache.kafka.controller.BrokersToIsrs.TopicIdPartition in project kafka by apache.
the class ReplicationControlManagerTest method testPreferredElectionDoesNotTriggerUncleanElection.
@Test
public void testPreferredElectionDoesNotTriggerUncleanElection() throws Exception {
ReplicationControlTestContext ctx = new ReplicationControlTestContext();
ReplicationControlManager replication = ctx.replicationControl;
ctx.registerBrokers(1, 2, 3, 4);
ctx.unfenceBrokers(1, 2, 3, 4);
Uuid fooId = ctx.createTestTopic("foo", new int[][] { new int[] { 1, 2, 3 } }).topicId();
TopicIdPartition partition = new TopicIdPartition(fooId, 0);
ctx.fenceBrokers(Utils.mkSet(2, 3));
ctx.fenceBrokers(Utils.mkSet(1, 2, 3));
ctx.unfenceBrokers(Utils.mkSet(2));
assertLeaderAndIsr(replication, partition, NO_LEADER, new int[] { 1 });
ctx.alterTopicConfig("foo", "unclean.leader.election.enable", "true");
ElectLeadersRequestData request = buildElectLeadersRequest(ElectionType.PREFERRED, singletonMap("foo", singletonList(0)));
// No election should be done even though unclean election is available
ControllerResult<ElectLeadersResponseData> result = replication.electLeaders(request);
assertEquals(Collections.emptyList(), result.records());
ElectLeadersResponseData expectedResponse = buildElectLeadersResponse(NONE, false, singletonMap(new TopicPartition("foo", 0), new ApiError(PREFERRED_LEADER_NOT_AVAILABLE)));
assertEquals(expectedResponse, result.response());
}
use of org.apache.kafka.controller.BrokersToIsrs.TopicIdPartition in project kafka by apache.
the class ReplicationControlManagerTest method testElectUncleanLeaders.
@ParameterizedTest
@ValueSource(booleans = { true, false })
public void testElectUncleanLeaders(boolean electAllPartitions) throws Exception {
ReplicationControlTestContext ctx = new ReplicationControlTestContext();
ReplicationControlManager replication = ctx.replicationControl;
ctx.registerBrokers(0, 1, 2, 3, 4);
ctx.unfenceBrokers(0, 1, 2, 3, 4);
Uuid fooId = ctx.createTestTopic("foo", new int[][] { new int[] { 1, 2, 3 }, new int[] { 2, 3, 4 }, new int[] { 0, 2, 1 } }).topicId();
TopicIdPartition partition0 = new TopicIdPartition(fooId, 0);
TopicIdPartition partition1 = new TopicIdPartition(fooId, 1);
TopicIdPartition partition2 = new TopicIdPartition(fooId, 2);
ctx.fenceBrokers(Utils.mkSet(2, 3));
ctx.fenceBrokers(Utils.mkSet(1, 2, 3));
assertLeaderAndIsr(replication, partition0, NO_LEADER, new int[] { 1 });
assertLeaderAndIsr(replication, partition1, 4, new int[] { 4 });
assertLeaderAndIsr(replication, partition2, 0, new int[] { 0 });
ElectLeadersRequestData request = buildElectLeadersRequest(ElectionType.UNCLEAN, electAllPartitions ? null : singletonMap("foo", asList(0, 1, 2)));
// No election can be done yet because no replicas are available for partition 0
ControllerResult<ElectLeadersResponseData> result1 = replication.electLeaders(request);
assertEquals(Collections.emptyList(), result1.records());
ElectLeadersResponseData expectedResponse1 = buildElectLeadersResponse(NONE, electAllPartitions, Utils.mkMap(Utils.mkEntry(new TopicPartition("foo", 0), new ApiError(ELIGIBLE_LEADERS_NOT_AVAILABLE)), Utils.mkEntry(new TopicPartition("foo", 1), new ApiError(ELECTION_NOT_NEEDED)), Utils.mkEntry(new TopicPartition("foo", 2), new ApiError(ELECTION_NOT_NEEDED))));
assertElectLeadersResponse(expectedResponse1, result1.response());
// Now we bring 2 back online which should allow the unclean election of partition 0
ctx.unfenceBrokers(Utils.mkSet(2));
// Bring 2 back into the ISR for partition 1. This allows us to verify that
// preferred election does not occur as a result of the unclean election request.
ctx.alterIsr(partition1, 4, asList(2, 4));
ControllerResult<ElectLeadersResponseData> result = replication.electLeaders(request);
assertEquals(1, result.records().size());
ApiMessageAndVersion record = result.records().get(0);
assertTrue(record.message() instanceof PartitionChangeRecord);
PartitionChangeRecord partitionChangeRecord = (PartitionChangeRecord) record.message();
assertEquals(0, partitionChangeRecord.partitionId());
assertEquals(2, partitionChangeRecord.leader());
assertEquals(singletonList(2), partitionChangeRecord.isr());
ctx.replay(result.records());
assertLeaderAndIsr(replication, partition0, 2, new int[] { 2 });
assertLeaderAndIsr(replication, partition1, 4, new int[] { 2, 4 });
assertLeaderAndIsr(replication, partition2, 0, new int[] { 0 });
ElectLeadersResponseData expectedResponse = buildElectLeadersResponse(NONE, electAllPartitions, Utils.mkMap(Utils.mkEntry(new TopicPartition("foo", 0), ApiError.NONE), Utils.mkEntry(new TopicPartition("foo", 1), new ApiError(ELECTION_NOT_NEEDED)), Utils.mkEntry(new TopicPartition("foo", 2), new ApiError(ELECTION_NOT_NEEDED))));
assertElectLeadersResponse(expectedResponse, result.response());
}
use of org.apache.kafka.controller.BrokersToIsrs.TopicIdPartition in project kafka by apache.
the class ReplicationControlManagerTest method testShrinkAndExpandIsr.
@Test
public void testShrinkAndExpandIsr() throws Exception {
ReplicationControlTestContext ctx = new ReplicationControlTestContext();
ReplicationControlManager replicationControl = ctx.replicationControl;
ctx.registerBrokers(0, 1, 2);
ctx.unfenceBrokers(0, 1, 2);
CreatableTopicResult createTopicResult = ctx.createTestTopic("foo", new int[][] { new int[] { 0, 1, 2 } });
TopicIdPartition topicIdPartition = new TopicIdPartition(createTopicResult.topicId(), 0);
TopicPartition topicPartition = new TopicPartition("foo", 0);
assertEquals(OptionalInt.of(0), ctx.currentLeader(topicIdPartition));
long brokerEpoch = ctx.currentBrokerEpoch(0);
PartitionData shrinkIsrRequest = newAlterIsrPartition(replicationControl, topicIdPartition, asList(0, 1));
ControllerResult<AlterIsrResponseData> shrinkIsrResult = sendAlterIsr(replicationControl, 0, brokerEpoch, "foo", shrinkIsrRequest);
AlterIsrResponseData.PartitionData shrinkIsrResponse = assertAlterIsrResponse(shrinkIsrResult, topicPartition, NONE);
assertConsistentAlterIsrResponse(replicationControl, topicIdPartition, shrinkIsrResponse);
PartitionData expandIsrRequest = newAlterIsrPartition(replicationControl, topicIdPartition, asList(0, 1, 2));
ControllerResult<AlterIsrResponseData> expandIsrResult = sendAlterIsr(replicationControl, 0, brokerEpoch, "foo", expandIsrRequest);
AlterIsrResponseData.PartitionData expandIsrResponse = assertAlterIsrResponse(expandIsrResult, topicPartition, NONE);
assertConsistentAlterIsrResponse(replicationControl, topicIdPartition, expandIsrResponse);
}
use of org.apache.kafka.controller.BrokersToIsrs.TopicIdPartition in project kafka by apache.
the class ReplicationControlManagerTest method testInvalidAlterIsrRequests.
@Test
public void testInvalidAlterIsrRequests() throws Exception {
ReplicationControlTestContext ctx = new ReplicationControlTestContext();
ReplicationControlManager replicationControl = ctx.replicationControl;
ctx.registerBrokers(0, 1, 2);
ctx.unfenceBrokers(0, 1, 2);
CreatableTopicResult createTopicResult = ctx.createTestTopic("foo", new int[][] { new int[] { 0, 1, 2 } });
TopicIdPartition topicIdPartition = new TopicIdPartition(createTopicResult.topicId(), 0);
TopicPartition topicPartition = new TopicPartition("foo", 0);
assertEquals(OptionalInt.of(0), ctx.currentLeader(topicIdPartition));
long brokerEpoch = ctx.currentBrokerEpoch(0);
// Invalid leader
PartitionData invalidLeaderRequest = newAlterIsrPartition(replicationControl, topicIdPartition, asList(0, 1));
ControllerResult<AlterIsrResponseData> invalidLeaderResult = sendAlterIsr(replicationControl, 1, ctx.currentBrokerEpoch(1), "foo", invalidLeaderRequest);
assertAlterIsrResponse(invalidLeaderResult, topicPartition, Errors.INVALID_REQUEST);
// Stale broker epoch
PartitionData invalidBrokerEpochRequest = newAlterIsrPartition(replicationControl, topicIdPartition, asList(0, 1));
assertThrows(StaleBrokerEpochException.class, () -> sendAlterIsr(replicationControl, 0, brokerEpoch - 1, "foo", invalidBrokerEpochRequest));
// Invalid leader epoch
PartitionData invalidLeaderEpochRequest = newAlterIsrPartition(replicationControl, topicIdPartition, asList(0, 1));
invalidLeaderEpochRequest.setLeaderEpoch(500);
ControllerResult<AlterIsrResponseData> invalidLeaderEpochResult = sendAlterIsr(replicationControl, 1, ctx.currentBrokerEpoch(1), "foo", invalidLeaderEpochRequest);
assertAlterIsrResponse(invalidLeaderEpochResult, topicPartition, FENCED_LEADER_EPOCH);
// Invalid ISR (3 is not a valid replica)
PartitionData invalidIsrRequest1 = newAlterIsrPartition(replicationControl, topicIdPartition, asList(0, 1));
invalidIsrRequest1.setNewIsr(asList(0, 1, 3));
ControllerResult<AlterIsrResponseData> invalidIsrResult1 = sendAlterIsr(replicationControl, 1, ctx.currentBrokerEpoch(1), "foo", invalidIsrRequest1);
assertAlterIsrResponse(invalidIsrResult1, topicPartition, Errors.INVALID_REQUEST);
// Invalid ISR (does not include leader 0)
PartitionData invalidIsrRequest2 = newAlterIsrPartition(replicationControl, topicIdPartition, asList(0, 1));
invalidIsrRequest2.setNewIsr(asList(1, 2));
ControllerResult<AlterIsrResponseData> invalidIsrResult2 = sendAlterIsr(replicationControl, 1, ctx.currentBrokerEpoch(1), "foo", invalidIsrRequest2);
assertAlterIsrResponse(invalidIsrResult2, topicPartition, Errors.INVALID_REQUEST);
}
use of org.apache.kafka.controller.BrokersToIsrs.TopicIdPartition in project kafka by apache.
the class BrokersToIsrsTest method testLeadersOnlyIterator.
@Test
public void testLeadersOnlyIterator() {
SnapshotRegistry snapshotRegistry = new SnapshotRegistry(new LogContext());
BrokersToIsrs brokersToIsrs = new BrokersToIsrs(snapshotRegistry);
brokersToIsrs.update(UUIDS[0], 0, null, new int[] { 1, 2, 3 }, -1, 1);
brokersToIsrs.update(UUIDS[1], 1, null, new int[] { 2, 3, 4 }, -1, 4);
assertEquals(toSet(new TopicIdPartition(UUIDS[0], 0)), toSet(brokersToIsrs.iterator(1, true)));
assertEquals(toSet(), toSet(brokersToIsrs.iterator(2, true)));
assertEquals(toSet(new TopicIdPartition(UUIDS[1], 1)), toSet(brokersToIsrs.iterator(4, true)));
brokersToIsrs.update(UUIDS[0], 0, new int[] { 1, 2, 3 }, new int[] { 1, 2, 3 }, 1, 2);
assertEquals(toSet(), toSet(brokersToIsrs.iterator(1, true)));
assertEquals(toSet(new TopicIdPartition(UUIDS[0], 0)), toSet(brokersToIsrs.iterator(2, true)));
}
Aggregations