This is an automated email from the ASF dual-hosted git repository.
RongtongJin pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/rocketmq.git
The following commit(s) were added to refs/heads/develop by this push:
new 37808b38c1 fix(auth): tolerate blank subscription topics in heartbeats
(#11082)
37808b38c1 is described below
commit 37808b38c1405c9bb433df04f0b88ea063dfd6e1
Author: dingshuangxi888 <[email protected]>
AuthorDate: Wed Sep 9 10:26:04 2026 +0800
fix(auth): tolerate blank subscription topics in heartbeats (#11082)
* fix(auth): tolerate empty topics in consumer heartbeats
* fix(auth): skip blank heartbeat subscription topics
---------
Co-authored-by: shuangxi.dsx <[email protected]>
---
.../DefaultAuthorizationContextBuilder.java | 3 ++
.../DefaultAuthorizationContextBuilderTest.java | 51 ++++++++++++++++++++--
2 files changed, 51 insertions(+), 3 deletions(-)
diff --git
a/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java
b/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java
index 54625ca527..00920de9a7 100644
---
a/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java
+++
b/auth/src/main/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilder.java
@@ -350,6 +350,9 @@ public class DefaultAuthorizationContextBuilder implements
AuthorizationContextB
if (subscriptionData == null) {
throw new AuthorizationException("subscription
is null.");
}
+ if
(StringUtils.isBlank(subscriptionData.getTopic())) {
+ continue;
+ }
String subscriptionTopic =
requireResource(subscriptionData.getTopic(),
"topic");
if (NamespaceUtil.isRetryTopic(subscriptionTopic))
{
diff --git
a/auth/src/test/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilderTest.java
b/auth/src/test/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilderTest.java
index 8be1f126d9..f1591c86ea 100644
---
a/auth/src/test/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilderTest.java
+++
b/auth/src/test/java/org/apache/rocketmq/auth/authorization/builder/DefaultAuthorizationContextBuilderTest.java
@@ -1097,9 +1097,7 @@ public class DefaultAuthorizationContextBuilderTest {
HeartbeatData heartbeatData = new HeartbeatData();
ConsumerData consumerData = new ConsumerData();
consumerData.setGroupName("group");
- SubscriptionData subscriptionData = new SubscriptionData();
- subscriptionData.setTopic(" ");
-
consumerData.setSubscriptionDataSet(Collections.singleton(subscriptionData));
+ consumerData.setSubscriptionDataSet(Collections.singleton(null));
heartbeatData.setConsumerDataSet(Collections.singleton(consumerData));
Assert.assertThrows(AuthorizationException.class, () ->
builder.build(channelHandlerContext,
remotingRequest(RequestCode.HEART_BEAT, new
HeartbeatRequestHeader(),
@@ -1446,6 +1444,53 @@ public class DefaultAuthorizationContextBuilderTest {
remotingRequest(RequestCode.DELETE_SUBSCRIPTION_GROUP_LIST, null,
invalidGroupList.encode())));
}
+ @Test
+ public void buildHeartbeatSkipsBlankTopics() {
+ mockRemotingChannel();
+ ConsumerData consumerData = new ConsumerData();
+ consumerData.setGroupName("group");
+ consumerData.setSubscriptionDataSet(new LinkedHashSet<>(Arrays.asList(
+ new SubscriptionData(null, "*"),
+ new SubscriptionData("", "*"),
+ new SubscriptionData(" ", "*"),
+ new SubscriptionData("\t\r\n", "*"),
+ new SubscriptionData("topic", "*"),
+ new SubscriptionData("%RETRY%group", "*"))));
+ HeartbeatData heartbeatData = new HeartbeatData();
+ heartbeatData.setConsumerDataSet(Collections.singleton(consumerData));
+
+ List<DefaultAuthorizationContext> result =
builder.build(channelHandlerContext,
+ remotingRequest(RequestCode.HEART_BEAT, new
HeartbeatRequestHeader(), heartbeatData.encode()));
+
+ assertResourceOrder(result, "Group:group", "Topic:topic");
+ assertActions(result, "Group:group", Action.SUB);
+ assertActions(result, "Topic:topic", Action.SUB);
+ }
+
+ @Test
+ public void buildHeartbeatWithOnlyBlankTopicsStillChecksGroup() {
+ mockRemotingChannel();
+ ConsumerData consumerData = new ConsumerData();
+ consumerData.setGroupName("group");
+ consumerData.setSubscriptionDataSet(new LinkedHashSet<>(Arrays.asList(
+ new SubscriptionData(null, "*"),
+ new SubscriptionData("", "*"),
+ new SubscriptionData(" ", "*"),
+ new SubscriptionData("\t\r\n", "*"))));
+ HeartbeatData heartbeatData = new HeartbeatData();
+ heartbeatData.setConsumerDataSet(Collections.singleton(consumerData));
+
+ List<DefaultAuthorizationContext> result =
builder.build(channelHandlerContext,
+ remotingRequest(RequestCode.HEART_BEAT, new
HeartbeatRequestHeader(), heartbeatData.encode()));
+
+ assertResourceOrder(result, "Group:group");
+ assertActions(result, "Group:group", Action.SUB);
+
+ consumerData.setGroupName("");
+ Assert.assertThrows(AuthorizationException.class, () ->
builder.build(channelHandlerContext,
+ remotingRequest(RequestCode.HEART_BEAT, new
HeartbeatRequestHeader(), heartbeatData.encode())));
+ }
+
@Test
public void buildGrpcHeartbeatByClientShape() {
Metadata metadata = new Metadata();