KAFKA-19305 Make ClientQuotaImage and TopicImage immutable (#19847)

- Updated `ClientQuotaImage` and `TopicImage` by using
`Collections.unmodifiableMap` or `ImmutableMap` to prevent accidental or
intentional mutations after construction.

Reviewers: Alyssa Huang <ahuang@confluent.io>, Chia-Ping Tsai
 <chia7712@gmail.com>
This commit is contained in:
Chang-Chi Hsu 2025-07-16 11:50:18 +08:00 committed by GitHub
parent daece61a50
commit 2658f25238
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 9 additions and 66 deletions

View File

@ -31,7 +31,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
/**
@ -39,21 +38,11 @@ import java.util.Objects;
*
* This class is thread-safe.
*/
public final class ClientQuotaImage {
public record ClientQuotaImage(Map<String, Double> quotas) {
public static final ClientQuotaImage EMPTY = new ClientQuotaImage(Map.of());
private final Map<String, Double> quotas;
public ClientQuotaImage(Map<String, Double> quotas) {
this.quotas = quotas;
}
Map<String, Double> quotas() {
return quotas;
}
public Map<String, Double> quotaMap() {
return Collections.unmodifiableMap(quotas);
public ClientQuotaImage {
quotas = Collections.unmodifiableMap(quotas);
}
public void write(
@ -100,17 +89,6 @@ public final class ClientQuotaImage {
return quotas.isEmpty();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof ClientQuotaImage other)) return false;
return quotas.equals(other.quotas);
}
@Override
public int hashCode() {
return Objects.hash(quotas);
}
@Override
public String toString() {
return new ClientQuotaImageNode(this).stringify();

View File

@ -24,9 +24,9 @@ import org.apache.kafka.image.writer.ImageWriter;
import org.apache.kafka.image.writer.ImageWriterOptions;
import org.apache.kafka.metadata.PartitionRegistration;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
/**
@ -34,31 +34,9 @@ import java.util.Objects;
*
* This class is thread-safe.
*/
public final class TopicImage {
private final String name;
private final Uuid id;
private final Map<Integer, PartitionRegistration> partitions;
public TopicImage(String name,
Uuid id,
Map<Integer, PartitionRegistration> partitions) {
this.name = name;
this.id = id;
this.partitions = partitions;
}
public String name() {
return name;
}
public Uuid id() {
return id;
}
public Map<Integer, PartitionRegistration> partitions() {
return partitions;
public record TopicImage(String name, Uuid id, Map<Integer, PartitionRegistration> partitions) {
public TopicImage {
partitions = Collections.unmodifiableMap(partitions);
}
public void write(ImageWriter writer, ImageWriterOptions options) {
@ -72,19 +50,6 @@ public final class TopicImage {
}
}
@Override
public boolean equals(Object o) {
if (!(o instanceof TopicImage other)) return false;
return name.equals(other.name) &&
id.equals(other.id) &&
partitions.equals(other.partitions);
}
@Override
public int hashCode() {
return Objects.hash(name, id, partitions);
}
@Override
public String toString() {
return new TopicImageNode(this).stringify();

View File

@ -34,12 +34,12 @@ public class ClientQuotaImageNode implements MetadataNode {
@Override
public Collection<String> childNames() {
return image.quotaMap().keySet();
return image.quotas().keySet();
}
@Override
public MetadataNode child(String name) {
Double result = image.quotaMap().get(name);
Double result = image.quotas().get(name);
if (result == null) return null;
return new MetadataLeafNode(result + "");
}