org.apache.kafka.common.Cluster Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kafka-clients Show documentation
Show all versions of kafka-clients Show documentation
Kafka client whose producer requires explicit encoders.
The newest version!
/**
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
* file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
* to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.apache.kafka.common;
import org.apache.kafka.common.utils.Utils;
import java.net.InetSocketAddress;
import java.util.*;
/**
* A representation of a subset of the nodes, topics, and partitions in the Kafka cluster.
*/
public final class Cluster {
private final List nodes;
private final Map partitionsByTopicPartition;
private final Map> partitionsByTopic;
private final Map> availablePartitionsByTopic;
private final Map> partitionsByNode;
/**
* Create a new cluster with the given nodes and partitions
* @param nodes The nodes in the cluster
* @param partitions Information about a subset of the topic-partitions this cluster hosts
*/
public Cluster(Collection nodes, Collection partitions) {
// make a randomized, unmodifiable copy of the nodes
List copy = new ArrayList(nodes);
Collections.shuffle(copy);
this.nodes = Collections.unmodifiableList(copy);
// index the partitions by topic/partition for quick lookup
this.partitionsByTopicPartition = new HashMap(partitions.size());
for (PartitionInfo p : partitions)
this.partitionsByTopicPartition.put(new TopicPartition(p.topic(), p.partition()), p);
// index the partitions by topic and node respectively, and make the lists
// unmodifiable so we can hand them out in user-facing apis without risk
// of the client modifying the contents
HashMap> partsForTopic = new HashMap>();
HashMap> partsForNode = new HashMap>();
for (Node n : this.nodes) {
partsForNode.put(n.id(), new ArrayList());
}
for (PartitionInfo p : partitions) {
if (!partsForTopic.containsKey(p.topic()))
partsForTopic.put(p.topic(), new ArrayList());
List psTopic = partsForTopic.get(p.topic());
psTopic.add(p);
if (p.leader() != null) {
List psNode = Utils.notNull(partsForNode.get(p.leader().id()));
psNode.add(p);
}
}
this.partitionsByTopic = new HashMap>(partsForTopic.size());
this.availablePartitionsByTopic = new HashMap>(partsForTopic.size());
for (Map.Entry> entry : partsForTopic.entrySet()) {
String topic = entry.getKey();
List partitionList = entry.getValue();
this.partitionsByTopic.put(topic, Collections.unmodifiableList(partitionList));
List availablePartitions = new ArrayList();
for (PartitionInfo part : partitionList) {
if (part.leader() != null)
availablePartitions.add(part);
}
this.availablePartitionsByTopic.put(topic, Collections.unmodifiableList(availablePartitions));
}
this.partitionsByNode = new HashMap>(partsForNode.size());
for (Map.Entry> entry : partsForNode.entrySet())
this.partitionsByNode.put(entry.getKey(), Collections.unmodifiableList(entry.getValue()));
}
/**
* Create an empty cluster instance with no nodes and no topic-partitions.
*/
public static Cluster empty() {
return new Cluster(new ArrayList(0), new ArrayList(0));
}
/**
* Create a "bootstrap" cluster using the given list of host/ports
* @param addresses The addresses
* @return A cluster for these hosts/ports
*/
public static Cluster bootstrap(List addresses) {
List nodes = new ArrayList();
int nodeId = -1;
for (InetSocketAddress address : addresses)
nodes.add(new Node(nodeId--, address.getHostName(), address.getPort()));
return new Cluster(nodes, new ArrayList(0));
}
/**
* @return The known set of nodes
*/
public List nodes() {
return this.nodes;
}
/**
* Get the current leader for the given topic-partition
* @param topicPartition The topic and partition we want to know the leader for
* @return The node that is the leader for this topic-partition, or null if there is currently no leader
*/
public Node leaderFor(TopicPartition topicPartition) {
PartitionInfo info = partitionsByTopicPartition.get(topicPartition);
if (info == null)
return null;
else
return info.leader();
}
/**
* Get the metadata for the specified partition
* @param topicPartition The topic and partition to fetch info for
* @return The metadata about the given topic and partition
*/
public PartitionInfo partition(TopicPartition topicPartition) {
return partitionsByTopicPartition.get(topicPartition);
}
/**
* Get the list of partitions for this topic
* @param topic The topic name
* @return A list of partitions
*/
public List partitionsForTopic(String topic) {
return this.partitionsByTopic.get(topic);
}
/**
* Get the list of available partitions for this topic
* @param topic The topic name
* @return A list of partitions
*/
public List availablePartitionsForTopic(String topic) {
return this.availablePartitionsByTopic.get(topic);
}
/**
* Get the list of partitions whose leader is this node
* @param nodeId The node id
* @return A list of partitions
*/
public List partitionsForNode(int nodeId) {
return this.partitionsByNode.get(nodeId);
}
/**
* Get all topics.
* @return a set of all topics
*/
public Set topics() {
return this.partitionsByTopic.keySet();
}
@Override
public String toString() {
return "Cluster(nodes = " + this.nodes + ", partitions = " + this.partitionsByTopicPartition.values() + ")";
}
}