-
Notifications
You must be signed in to change notification settings - Fork 14.2k
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-17648: AsyncKafkaConsumer#unsubscribe swallow TopicAuthorizationException and GroupAuthorizationException #17516
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ import org.apache.kafka.metadata.authorizer.StandardAuthorizer | |
import org.apache.kafka.security.authorizer.AclEntry.WILDCARD_HOST | ||
import org.apache.kafka.server.config.ServerConfigs | ||
import org.junit.jupiter.api.Assertions._ | ||
import org.junit.jupiter.api.function.Executable | ||
import org.junit.jupiter.api.{BeforeEach, TestInfo} | ||
import org.junit.jupiter.params.ParameterizedTest | ||
import org.junit.jupiter.params.provider.MethodSource | ||
|
@@ -132,6 +133,84 @@ class GroupAuthorizerIntegrationTest extends BaseRequestTest { | |
assertEquals(Set(topic), consumeException.unauthorizedTopics.asScala) | ||
} | ||
|
||
@ParameterizedTest(name = TestInfoUtils.TestWithParameterizedQuorumAndGroupProtocolNames) | ||
@MethodSource(Array("getTestQuorumAndGroupProtocolParametersAll")) | ||
def testConsumeUnsubscribeWithoutGroupPermission(quorum: String, groupProtocol: String): Unit = { | ||
val topic = "topic" | ||
|
||
createTopic(topic, listenerName = interBrokerListenerName) | ||
|
||
// allow topic read/write permission to poll/send record | ||
addAndVerifyAcls( | ||
Set(createAcl(AclOperation.WRITE, AclPermissionType.ALLOW), createAcl(AclOperation.READ, AclPermissionType.ALLOW)), | ||
new ResourcePattern(ResourceType.TOPIC, topic, PatternType.LITERAL) | ||
) | ||
val producer = createProducer() | ||
producer.send(new ProducerRecord[Array[Byte], Array[Byte]](topic, "message".getBytes)).get() | ||
producer.close() | ||
|
||
// allow group read permission to join group | ||
val group = "group" | ||
addAndVerifyAcls( | ||
Set(createAcl(AclOperation.READ, AclPermissionType.ALLOW)), | ||
new ResourcePattern(ResourceType.GROUP, group, PatternType.LITERAL) | ||
) | ||
|
||
val props = new Properties() | ||
props.put(ConsumerConfig.GROUP_ID_CONFIG, group) | ||
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false") | ||
val consumer = createConsumer(configOverrides = props) | ||
consumer.subscribe(List(topic).asJava) | ||
TestUtils.pollUntilAtLeastNumRecords(consumer, numRecords = 1) | ||
|
||
removeAndVerifyAcls( | ||
Set(createAcl(AclOperation.READ, AclPermissionType.ALLOW)), | ||
new ResourcePattern(ResourceType.GROUP, group, PatternType.LITERAL) | ||
) | ||
|
||
assertDoesNotThrow(new Executable { | ||
override def execute(): Unit = consumer.unsubscribe() | ||
}) | ||
} | ||
|
||
@ParameterizedTest(name = TestInfoUtils.TestWithParameterizedQuorumAndGroupProtocolNames) | ||
@MethodSource(Array("getTestQuorumAndGroupProtocolParametersAll")) | ||
def testConsumeCloseWithoutGroupPermission(quorum: String, groupProtocol: String): Unit = { | ||
val topic = "topic" | ||
createTopic(topic, listenerName = interBrokerListenerName) | ||
|
||
// allow topic read/write permission to poll/send record | ||
addAndVerifyAcls( | ||
Set(createAcl(AclOperation.WRITE, AclPermissionType.ALLOW), createAcl(AclOperation.READ, AclPermissionType.ALLOW)), | ||
new ResourcePattern(ResourceType.TOPIC, topic, PatternType.LITERAL) | ||
) | ||
val producer = createProducer() | ||
producer.send(new ProducerRecord[Array[Byte], Array[Byte]](topic, "message".getBytes)).get() | ||
|
||
// allow group read permission to join group | ||
val group = "group" | ||
addAndVerifyAcls( | ||
Set(createAcl(AclOperation.READ, AclPermissionType.ALLOW)), | ||
new ResourcePattern(ResourceType.GROUP, group, PatternType.LITERAL) | ||
) | ||
|
||
val props = new Properties() | ||
props.put(ConsumerConfig.GROUP_ID_CONFIG, group) | ||
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false") | ||
val consumer = createConsumer(configOverrides = props) | ||
consumer.subscribe(List(topic).asJava) | ||
TestUtils.pollUntilAtLeastNumRecords(consumer, numRecords = 1) | ||
|
||
removeAndVerifyAcls( | ||
Set(createAcl(AclOperation.READ, AclPermissionType.ALLOW)), | ||
new ResourcePattern(ResourceType.GROUP, group, PatternType.LITERAL) | ||
) | ||
|
||
assertDoesNotThrow(new Executable { | ||
override def execute(): Unit = consumer.close() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similar situation with close. I don't believe that the consumer swallows the exceptions, I believe they just don't come out here because there is no known coordinator (so no group request or client poll on close). If my understanding is right, we shouldn't swallow them either on the new consumer |
||
}) | ||
} | ||
|
||
@ParameterizedTest(name = TestInfoUtils.TestWithParameterizedQuorumAndGroupProtocolNames) | ||
@MethodSource(Array("getTestQuorumAndGroupProtocolParametersAll")) | ||
def testAuthorizedProduceAndConsume(quorum: String, groupProtocol: String): Unit = { | ||
|
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 test is valuable, but if we agree on leaving this PR for the unsubscribe to leverage the close/callbacks changes in #16686 we should probably bring this test back in a separate PR, after that one goes in. What do you think?
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.
Hi @lianetm, I would like to confirm again: do you mean that we disable
close
test cases currently, revert change inAsyncKafkaConsumer#releaseAssignmentAndLeaveGroup
function, and then we will enable this test after #16686 is merged? Thanks.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.
Hi @lianetm, thanks for your review. I add test cases for
TopicAuthorizationException
and disable test cases forclose
function. Could you help me review again when you have time? Thanks.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.
It looks like #16686 is almost ready. I will remove
@Disabled
after it's merged.