New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KAFKA-13011: Update deleteTopics Admin API #10892
Conversation
@hachikuji I originally wanted the constructor for DeleteTopicsResult to be private, but InternalTopicManagerTest required creating a subclass. |
clients/src/main/java/org/apache/kafka/clients/admin/TopicCollection.java
Outdated
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/TopicCollection.java
Outdated
Show resolved
Hide resolved
*/ | ||
DeleteTopicsWithIdsResult deleteTopicsWithIds(Collection<Uuid> topics, DeleteTopicsOptions options); | ||
DeleteTopicsResult deleteTopics(TopicCollection topics, DeleteTopicsOptions options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since TopicCollection
can handle both "by name" and "by ID" deletion, is the intent to eventually deprecate the old deletion api or will we keep it around for convenience?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eventually we want to deprecate the old api yes
clients/src/main/java/org/apache/kafka/common/TopicCollection.java
Outdated
Show resolved
Hide resolved
…ting to get the type that doesn't match the request
clients/src/main/java/org/apache/kafka/clients/admin/DeleteTopicsResult.java
Outdated
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/DeleteTopicsResult.java
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/DeleteTopicsResult.java
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/KafkaAdminClient.java
Outdated
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/common/TopicCollection.java
Outdated
Show resolved
Hide resolved
* A class used to represent a collection of topics. This collection may define topics by topic name | ||
* or topic ID. Subclassing this class beyond the classes provided here is not supported. | ||
*/ | ||
public abstract class TopicCollection { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be helpful to have a couple static factories? For example:
public static TopicIdCollection ofTopicIds(Collection<Uuid> uuids);
public static TopicNameCollection ofTopicNames(Collection<String> names);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Static factories in addition to a public constructor? Or make the constructor private?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No strong opinion, but I'd probably vote to keep the constructors private. Might be worth getting a second opinion. @ijuma ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's simpler with just the factories, so I like this idea.
clients/src/main/java/org/apache/kafka/common/TopicCollection.java
Outdated
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/common/TopicCollection.java
Outdated
Show resolved
Hide resolved
final DeleteTopicsOptions options) { | ||
DeleteTopicsResult result; | ||
if (topics instanceof TopicIdCollection) | ||
result = DeleteTopicsResult.ofTopicIds(new HashMap<>(handleDeleteTopicsUsingIds(((TopicIdCollection) topics).topicIds(), options))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we copy the result of handleDeleteTopicsUsingIds
? Seems like that method is already returning a fresh map.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was an artifact of the old version of the code. We would create a copy of the map
return new DeleteTopicsResult(new HashMap<>(topicFutures));
I can remove though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm. When I try to remove I get
'ofTopicIds(java.util.Map<org.apache.kafka.common.Uuid,org.apache.kafka.common.KafkaFuture<java.lang.Void>>)' in 'org.apache.kafka.clients.admin.DeleteTopicsResult' cannot be applied to '(java.util.Map<org.apache.kafka.common.Uuid,org.apache.kafka.common.internals.KafkaFutureImpl<java.lang.Void>>)'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many other admin client calls also follow this pattern with using KafkaFutureImpl and copying the result to get KafkaFutures
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can move this cast to the handle...
call and return a KafkaFuture if it makes things cleaner.
clients/src/test/java/org/apache/kafka/clients/admin/DeleteTopicsResultTest.java
Outdated
Show resolved
Hide resolved
clients/src/test/java/org/apache/kafka/clients/admin/TopicCollectionTest.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
protected static DeleteTopicsResult ofTopicIds(Map<Uuid, KafkaFuture<Void>> topicIdFutures) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these methods need to be protected or could they be package access?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgive my ignorance but is that not the same thing? Is package private just that we can't use in subclasses outside the package? If that's the case then sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's right. The less exposed it is, the better.
clients/src/main/java/org/apache/kafka/clients/admin/DeleteTopicsResult.java
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/DeleteTopicsResult.java
Outdated
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/DeleteTopicsResult.java
Outdated
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/DeleteTopicsResult.java
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/KafkaAdminClient.java
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/KafkaAdminClient.java
Outdated
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/common/TopicCollection.java
Outdated
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/KafkaAdminClient.java
Outdated
Show resolved
Hide resolved
...ams/src/test/java/org/apache/kafka/streams/processor/internals/InternalTopicManagerTest.java
Outdated
Show resolved
Hide resolved
clients/src/main/java/org/apache/kafka/clients/admin/KafkaAdminClient.java
Outdated
Show resolved
Hide resolved
final Map<Uuid, KafkaFutureImpl<Void>> topicFutures = new HashMap<>(topicIds.size()); | ||
final List<Uuid> validTopicIds = new ArrayList<>(topicIds.size()); | ||
for (Uuid topicId : topicIds) { | ||
if (topicId.equals(Uuid.ZERO_UUID)) { | ||
KafkaFutureImpl<Void> future = new KafkaFutureImpl<>(); | ||
future.completeExceptionally(new UnknownTopicIdException("The given topic ID '" + | ||
topicId + "' cannot be represented in a request.")); | ||
topicId + "' cannot be represented in a request.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message is a little strange. We can certainly represent the topic id, but it is invalid. I wonder if it would make sense to raise IllegalArgumentException
directly instead of through the result since this is likely a logical error of some kind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah. The name equivalent is InvalidTopicException
so maybe we could just use that (or IllegalArugmentException
is probably better) so the cases are similar? I think that we should keep it as through the result so it is consistent with the name equivalent, but that's just me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I like InvalidTopicException
over IllegalArgumentException
if we are raising it through the future. Typically IllegalArgumentException
is raised directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. We can change to that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the patch! LGTM
* with default options. See the overload for more details. | ||
* <p> | ||
* This operation is supported by brokers with version 2.8.0 or higher. | ||
* When using topic IDs, this operation is supported by brokers with version 3.0.0 or higher. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does require a specific inter-broker protocol version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, it will need the controller to use topic IDs (IBP 2.8) to get a successful deletion. The 3.0.0 part was for the code to handle the request itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah actually, now that I think of it, the broker code was added in 2.8, so maybe this should just say 2.8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I suggest submitting a follow-up PR with the improvements. If a particular IBP is required, we should state that too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I'm thinking the change is to make the comment clearer about the version and IBP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This patch adds two new apis to support topic deletion using topic IDs or names. It uses a new class `TopicCollection` to keep a collection of topics defined either by names or IDs. Finally, it modifies `DeleteTopicsResult` to support both names and IDs and deprecates the old methods which have become ambiguous. Eventually we will want to deprecate the old `deleteTopics` apis as well, but this patch does not do so. Reviewers: Jason Gustafson <jason@confluent.io>
Added two new apis to support deleteTopics using topic IDs or names. Added a new class TopicCollection to keep a collection of topics defined either by names or IDs. Modified DeleteTopicsResult to support both names and IDs and deprecated the old methods. Eventually we will want to deprecate the old deleteTopics apis as well.
Tested using the existing deleteTopics tests. Also created unit tests for new/updated classes.
Committer Checklist (excluded from commit message)