use of org.apache.kafka.common.requests.MetadataResponse in project kafka by apache.
the class MetadataTest method testTopicAuthorizationError.
@Test
public void testTopicAuthorizationError() {
Time time = new MockTime();
String invalidTopic = "foo";
MetadataResponse unauthorizedTopicResponse = RequestTestUtils.metadataUpdateWith("clusterId", 1, Collections.singletonMap(invalidTopic, Errors.TOPIC_AUTHORIZATION_FAILED), Collections.emptyMap());
metadata.updateWithCurrentRequestVersion(unauthorizedTopicResponse, false, time.milliseconds());
TopicAuthorizationException e = assertThrows(TopicAuthorizationException.class, () -> metadata.maybeThrowAnyException());
assertEquals(Collections.singleton(invalidTopic), e.unauthorizedTopics());
// We clear the exception once it has been raised to the user
metadata.maybeThrowAnyException();
// Reset the unauthorized topic error
metadata.updateWithCurrentRequestVersion(unauthorizedTopicResponse, false, time.milliseconds());
// If we get a good update, the error should clear even if we haven't had a chance to raise it to the user
metadata.updateWithCurrentRequestVersion(emptyMetadataResponse(), false, time.milliseconds());
metadata.maybeThrowAnyException();
}
use of org.apache.kafka.common.requests.MetadataResponse in project kafka by apache.
the class MetadataTest method testUpdateLastEpoch.
@Test
public void testUpdateLastEpoch() {
TopicPartition tp = new TopicPartition("topic-1", 0);
MetadataResponse metadataResponse = emptyMetadataResponse();
metadata.updateWithCurrentRequestVersion(metadataResponse, false, 0L);
// if we have no leader epoch, this call shouldn't do anything
assertFalse(metadata.updateLastSeenEpochIfNewer(tp, 0));
assertFalse(metadata.updateLastSeenEpochIfNewer(tp, 1));
assertFalse(metadata.updateLastSeenEpochIfNewer(tp, 2));
assertFalse(metadata.lastSeenLeaderEpoch(tp).isPresent());
// Metadata with newer epoch is handled
metadataResponse = RequestTestUtils.metadataUpdateWith("dummy", 1, Collections.emptyMap(), Collections.singletonMap("topic-1", 1), _tp -> 10);
metadata.updateWithCurrentRequestVersion(metadataResponse, false, 1L);
assertOptional(metadata.lastSeenLeaderEpoch(tp), leaderAndEpoch -> assertEquals(leaderAndEpoch.intValue(), 10));
// Don't update to an older one
assertFalse(metadata.updateLastSeenEpochIfNewer(tp, 1));
assertOptional(metadata.lastSeenLeaderEpoch(tp), leaderAndEpoch -> assertEquals(leaderAndEpoch.intValue(), 10));
// Don't cause update if it's the same one
assertFalse(metadata.updateLastSeenEpochIfNewer(tp, 10));
assertOptional(metadata.lastSeenLeaderEpoch(tp), leaderAndEpoch -> assertEquals(leaderAndEpoch.intValue(), 10));
// Update if we see newer epoch
assertTrue(metadata.updateLastSeenEpochIfNewer(tp, 12));
assertOptional(metadata.lastSeenLeaderEpoch(tp), leaderAndEpoch -> assertEquals(leaderAndEpoch.intValue(), 12));
metadataResponse = RequestTestUtils.metadataUpdateWith("dummy", 1, Collections.emptyMap(), Collections.singletonMap("topic-1", 1), _tp -> 12);
metadata.updateWithCurrentRequestVersion(metadataResponse, false, 2L);
assertOptional(metadata.lastSeenLeaderEpoch(tp), leaderAndEpoch -> assertEquals(leaderAndEpoch.intValue(), 12));
// Don't overwrite metadata with older epoch
metadataResponse = RequestTestUtils.metadataUpdateWith("dummy", 1, Collections.emptyMap(), Collections.singletonMap("topic-1", 1), _tp -> 11);
metadata.updateWithCurrentRequestVersion(metadataResponse, false, 3L);
assertOptional(metadata.lastSeenLeaderEpoch(tp), leaderAndEpoch -> assertEquals(leaderAndEpoch.intValue(), 12));
}
use of org.apache.kafka.common.requests.MetadataResponse in project kafka by apache.
the class MetadataTest method testIgnoreLeaderEpochInOlderMetadataResponse.
/**
* Prior to Kafka version 2.4 (which coincides with Metadata version 9), the broker does not propagate leader epoch
* information accurately while a reassignment is in progress, so we cannot rely on it. This is explained in more
* detail in MetadataResponse's constructor.
*/
@Test
public void testIgnoreLeaderEpochInOlderMetadataResponse() {
TopicPartition tp = new TopicPartition("topic", 0);
MetadataResponsePartition partitionMetadata = new MetadataResponsePartition().setPartitionIndex(tp.partition()).setLeaderId(5).setLeaderEpoch(10).setReplicaNodes(Arrays.asList(1, 2, 3)).setIsrNodes(Arrays.asList(1, 2, 3)).setOfflineReplicas(Collections.emptyList()).setErrorCode(Errors.NONE.code());
MetadataResponseTopic topicMetadata = new MetadataResponseTopic().setName(tp.topic()).setErrorCode(Errors.NONE.code()).setPartitions(Collections.singletonList(partitionMetadata)).setIsInternal(false);
MetadataResponseTopicCollection topics = new MetadataResponseTopicCollection();
topics.add(topicMetadata);
MetadataResponseData data = new MetadataResponseData().setClusterId("clusterId").setControllerId(0).setTopics(topics).setBrokers(new MetadataResponseBrokerCollection());
for (short version = ApiKeys.METADATA.oldestVersion(); version < 9; version++) {
ByteBuffer buffer = MessageUtil.toByteBuffer(data, version);
MetadataResponse response = MetadataResponse.parse(buffer, version);
assertFalse(response.hasReliableLeaderEpochs());
metadata.updateWithCurrentRequestVersion(response, false, 100);
assertTrue(metadata.partitionMetadataIfCurrent(tp).isPresent());
MetadataResponse.PartitionMetadata responseMetadata = this.metadata.partitionMetadataIfCurrent(tp).get();
assertEquals(Optional.empty(), responseMetadata.leaderEpoch);
}
for (short version = 9; version <= ApiKeys.METADATA.latestVersion(); version++) {
ByteBuffer buffer = MessageUtil.toByteBuffer(data, version);
MetadataResponse response = MetadataResponse.parse(buffer, version);
assertTrue(response.hasReliableLeaderEpochs());
metadata.updateWithCurrentRequestVersion(response, false, 100);
assertTrue(metadata.partitionMetadataIfCurrent(tp).isPresent());
MetadataResponse.PartitionMetadata responseMetadata = metadata.partitionMetadataIfCurrent(tp).get();
assertEquals(Optional.of(10), responseMetadata.leaderEpoch);
}
}
use of org.apache.kafka.common.requests.MetadataResponse in project kafka by apache.
the class MetadataTest method testClusterListenerGetsNotifiedOfUpdate.
@Test
public void testClusterListenerGetsNotifiedOfUpdate() {
MockClusterResourceListener mockClusterListener = new MockClusterResourceListener();
ClusterResourceListeners listeners = new ClusterResourceListeners();
listeners.maybeAdd(mockClusterListener);
metadata = new Metadata(refreshBackoffMs, metadataExpireMs, new LogContext(), listeners);
String hostName = "www.example.com";
metadata.bootstrap(Collections.singletonList(new InetSocketAddress(hostName, 9002)));
assertFalse(MockClusterResourceListener.IS_ON_UPDATE_CALLED.get(), "ClusterResourceListener should not called when metadata is updated with bootstrap Cluster");
Map<String, Integer> partitionCounts = new HashMap<>();
partitionCounts.put("topic", 1);
partitionCounts.put("topic1", 1);
MetadataResponse metadataResponse = RequestTestUtils.metadataUpdateWith("dummy", 1, partitionCounts);
metadata.updateWithCurrentRequestVersion(metadataResponse, false, 100);
assertEquals("dummy", mockClusterListener.clusterResource().clusterId(), "MockClusterResourceListener did not get cluster metadata correctly");
assertTrue(MockClusterResourceListener.IS_ON_UPDATE_CALLED.get(), "MockClusterResourceListener should be called when metadata is updated with non-bootstrap Cluster");
}
use of org.apache.kafka.common.requests.MetadataResponse in project kafka by apache.
the class MetadataTest method testMetadataMergeOnIdDowngrade.
@Test
public void testMetadataMergeOnIdDowngrade() {
Time time = new MockTime();
Map<String, Uuid> topicIds = new HashMap<>();
final AtomicReference<Set<String>> retainTopics = new AtomicReference<>(new HashSet<>());
metadata = new Metadata(refreshBackoffMs, metadataExpireMs, new LogContext(), new ClusterResourceListeners()) {
@Override
protected boolean retainTopic(String topic, boolean isInternal, long nowMs) {
return retainTopics.get().contains(topic);
}
};
// Initialize a metadata instance with two topics. Both will be retained.
String clusterId = "clusterId";
int nodes = 2;
Map<String, Integer> topicPartitionCounts = new HashMap<>();
topicPartitionCounts.put("validTopic1", 2);
topicPartitionCounts.put("validTopic2", 3);
retainTopics.set(Utils.mkSet("validTopic1", "validTopic2"));
topicIds.put("validTopic1", Uuid.randomUuid());
topicIds.put("validTopic2", Uuid.randomUuid());
MetadataResponse metadataResponse = RequestTestUtils.metadataUpdateWithIds(clusterId, nodes, Collections.emptyMap(), topicPartitionCounts, _tp -> 100, topicIds);
metadata.updateWithCurrentRequestVersion(metadataResponse, true, time.milliseconds());
Map<String, Uuid> metadataTopicIds1 = metadata.topicIds();
retainTopics.get().forEach(topic -> assertEquals(metadataTopicIds1.get(topic), topicIds.get(topic)));
// Try removing the topic ID from keepValidTopic (simulating receiving a request from a controller with an older IBP)
topicIds.remove("validTopic1");
metadataResponse = RequestTestUtils.metadataUpdateWithIds(clusterId, nodes, Collections.emptyMap(), topicPartitionCounts, _tp -> 200, topicIds);
metadata.updateWithCurrentRequestVersion(metadataResponse, true, time.milliseconds());
Map<String, Uuid> metadataTopicIds2 = metadata.topicIds();
retainTopics.get().forEach(topic -> assertEquals(metadataTopicIds2.get(topic), topicIds.get(topic)));
Cluster cluster = metadata.fetch();
// We still have the topic, but it just doesn't have an ID.
assertEquals(Utils.mkSet("validTopic1", "validTopic2"), cluster.topics());
assertEquals(2, cluster.partitionsForTopic("validTopic1").size());
assertEquals(new HashSet<>(topicIds.values()), new HashSet<>(cluster.topicIds()));
assertEquals(Uuid.ZERO_UUID, cluster.topicId("validTopic1"));
}
Aggregations