Before Creating the Bug Report
Runtime platform environment
Not platform-specific.
RocketMQ version
develop
JDK Version
JDK17
Describe the Bug
When the gRPC proxy builds QueryRouteResponse, the permission of each MessageQueue can be incorrect if readQueueNums and writeQueueNums are different.
The problem is in RouteActivity#genMessageQueueFromQueueData.
QueueData uses queue ids as ranges:
- readable queues:
0 .. readQueueNums - 1
- writable queues:
0 .. writeQueueNums - 1
So when a topic has both read and write permission, the overlapping queue ids should be marked as READ_WRITE.
However, the current implementation calculates the number of read-only, write-only, and read-write queues first, then appends them in groups while increasing the queue id. This preserves the count of each permission type, but may assign the permission to the wrong queue id.
For example, with:
readQueueNums = 4
writeQueueNums = 8
perm = PERM_READ | PERM_WRITE
The expected result is:
- queue ids
0..3: READ_WRITE
- queue ids
4..7: WRITE
But the current implementation returns:
- queue ids
0..3: WRITE
- queue ids
4..7: READ_WRITE
So the route response exposes incorrect per-queue permissions to gRPC clients.
Steps to Reproduce
- Create a
QueueData with:
readQueueNums = 4
writeQueueNums = 8
perm = PERM_READ | PERM_WRITE
- Call
RouteActivity#genMessageQueueFromQueueData.
- Check the generated
MessageQueue list in the returned route response.
A similar issue can also be reproduced with:
readQueueNums = 8
writeQueueNums = 4
perm = PERM_READ | PERM_WRITE
What Did You Expect to See?
The permission should be calculated by queue id.
For readQueueNums = 4, writeQueueNums = 8, and PERM_READ | PERM_WRITE:
- queue id
0: READ_WRITE
- queue id
1: READ_WRITE
- queue id
2: READ_WRITE
- queue id
3: READ_WRITE
- queue id
4: WRITE
- queue id
5: WRITE
- queue id
6: WRITE
- queue id
7: WRITE
In general:
id < readQueueNums means the queue is readable
id < writeQueueNums means the queue is writable
- if both conditions are true, the permission should be
READ_WRITE
What Did You See Instead?
The current implementation returns the correct number of queues for each permission type, but assigns those permissions to the wrong queue ids.
For readQueueNums = 4, writeQueueNums = 8, and PERM_READ | PERM_WRITE, it returns:
- queue id
0: WRITE
- queue id
1: WRITE
- queue id
2: WRITE
- queue id
3: WRITE
- queue id
4: READ_WRITE
- queue id
5: READ_WRITE
- queue id
6: READ_WRITE
- queue id
7: READ_WRITE
This is inconsistent with how RocketMQ builds readable and writable queues from QueueData.
Additional Context
The issue is not about the total number of queues. The total count is correct.
The problem is that MessageQueue.id is part of the queue identity, so permission needs to match the actual queue id. Grouping permissions first and assigning ids afterwards can produce a route response where clients see a readable/writable status that belongs to a different queue id.
The internal route selection logic also builds read/write queues by iterating queue ids from 0 to readQueueNums - 1 or writeQueueNums - 1, which confirms that the permission should be derived per queue id rather than by grouped counts.
Before Creating the Bug Report
I found a bug, not just asking a question, which should be created in GitHub Discussions.
I have searched the GitHub Issues and GitHub Discussions of this repository and believe that this is not a duplicate.
I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.
Runtime platform environment
Not platform-specific.
RocketMQ version
develop
JDK Version
JDK17
Describe the Bug
When the gRPC proxy builds
QueryRouteResponse, the permission of eachMessageQueuecan be incorrect ifreadQueueNumsandwriteQueueNumsare different.The problem is in
RouteActivity#genMessageQueueFromQueueData.QueueDatauses queue ids as ranges:0 .. readQueueNums - 10 .. writeQueueNums - 1So when a topic has both read and write permission, the overlapping queue ids should be marked as
READ_WRITE.However, the current implementation calculates the number of read-only, write-only, and read-write queues first, then appends them in groups while increasing the queue id. This preserves the count of each permission type, but may assign the permission to the wrong queue id.
For example, with:
readQueueNums = 4writeQueueNums = 8perm = PERM_READ | PERM_WRITEThe expected result is:
0..3:READ_WRITE4..7:WRITEBut the current implementation returns:
0..3:WRITE4..7:READ_WRITESo the route response exposes incorrect per-queue permissions to gRPC clients.
Steps to Reproduce
QueueDatawith:readQueueNums = 4writeQueueNums = 8perm = PERM_READ | PERM_WRITERouteActivity#genMessageQueueFromQueueData.MessageQueuelist in the returned route response.A similar issue can also be reproduced with:
readQueueNums = 8writeQueueNums = 4perm = PERM_READ | PERM_WRITEWhat Did You Expect to See?
The permission should be calculated by queue id.
For
readQueueNums = 4,writeQueueNums = 8, andPERM_READ | PERM_WRITE:0:READ_WRITE1:READ_WRITE2:READ_WRITE3:READ_WRITE4:WRITE5:WRITE6:WRITE7:WRITEIn general:
id < readQueueNumsmeans the queue is readableid < writeQueueNumsmeans the queue is writableREAD_WRITEWhat Did You See Instead?
The current implementation returns the correct number of queues for each permission type, but assigns those permissions to the wrong queue ids.
For
readQueueNums = 4,writeQueueNums = 8, andPERM_READ | PERM_WRITE, it returns:0:WRITE1:WRITE2:WRITE3:WRITE4:READ_WRITE5:READ_WRITE6:READ_WRITE7:READ_WRITEThis is inconsistent with how RocketMQ builds readable and writable queues from
QueueData.Additional Context
The issue is not about the total number of queues. The total count is correct.
The problem is that
MessageQueue.idis part of the queue identity, so permission needs to match the actual queue id. Grouping permissions first and assigning ids afterwards can produce a route response where clients see a readable/writable status that belongs to a different queue id.The internal route selection logic also builds read/write queues by iterating queue ids from
0toreadQueueNums - 1orwriteQueueNums - 1, which confirms that the permission should be derived per queue id rather than by grouped counts.