Skip to content
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

Merged
merged 9 commits into from Jul 1, 2021
Merged

Conversation

jolshan
Copy link
Contributor

@jolshan jolshan commented Jun 17, 2021

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)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

@jolshan jolshan marked this pull request as draft June 17, 2021 02:46
@jolshan
Copy link
Contributor Author

jolshan commented Jun 17, 2021

@hachikuji I originally wanted the constructor for DeleteTopicsResult to be private, but InternalTopicManagerTest required creating a subclass.

*/
DeleteTopicsWithIdsResult deleteTopicsWithIds(Collection<Uuid> topics, DeleteTopicsOptions options);
DeleteTopicsResult deleteTopics(TopicCollection topics, DeleteTopicsOptions options);
Copy link
Contributor

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?

Copy link
Contributor Author

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

…ting to get the type that doesn't match the request
* 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 {
Copy link
Contributor

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);

Copy link
Contributor Author

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?

Copy link
Contributor

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 ?

Copy link
Contributor Author

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.

@jolshan jolshan marked this pull request as ready for review June 29, 2021 17:32
@jolshan jolshan changed the title [WIP] New Admin API for deleteTopics KAFKA-13011: Update deleteTopics Admin API Jun 29, 2021
final DeleteTopicsOptions options) {
DeleteTopicsResult result;
if (topics instanceof TopicIdCollection)
result = DeleteTopicsResult.ofTopicIds(new HashMap<>(handleDeleteTopicsUsingIds(((TopicIdCollection) topics).topicIds(), options)));
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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>>)'

Copy link
Contributor Author

@jolshan jolshan Jun 30, 2021

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

Copy link
Contributor Author

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.

}

protected static DeleteTopicsResult ofTopicIds(Map<Uuid, KafkaFuture<Void>> topicIdFutures) {
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

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."));
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

@hachikuji hachikuji left a 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

@hachikuji hachikuji merged commit cee2e97 into apache:trunk Jul 1, 2021
* 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.
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xdgrulez pushed a commit to xdgrulez/kafka that referenced this pull request Dec 22, 2021
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants