[Branch 2.7][Fix][broker] Fix NPE when ledger id not found in OpReadEntry
(#15837)
#16966
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
(cherry picked from commit 7a3ad61)
Motivation
In current implementation, We have more than one potential NPE relate
ManagedLedgerImpl#startReadOperationOnLedger
method.1. Unbox NPE
pulsar/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/ManagedLedgerImpl.java
Lines 2230 to 2244 in b13d15c
According to this code, we can know that when the ledger id is null, we will fail
OpReadEntry
. However, there is no direct return here after failure. NPE will be thrown on line 2238. Because we want to unboxnull
.2. null
OpReadEntry
contextAccording to the code above, we can see when we fail
OpReadEntry
, we pass a null value as context(line 2235). there is an NPE when the dispatcher gets the callback.pulsar/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherSingleActiveConsumer.java
Lines 478 to 484 in 0975cdc
3.
OpReadEntry#create
pulsar/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/OpReadEntry.java
Lines 48 to 63 in 9376128
When we create
OpReadEntry
and then callManagedCursor#startReadOperationOnLedger
, assuming the ledger id is equal to null. At this point, we will fail thisOpReadEntry
. But at the current time, other parameters are not initialized. When we callOpReadEntry#readEntriesFailed
. The cursor will be null and the NPE will be thrown.pulsar/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/OpReadEntry.java
Lines 90 to 94 in 9376128
Modifications
OpReadEntry
logic inManagedCursor#startReadOperationOnLedger
, when ledger id equals null, we can return the original value. theManagedLedger
will validate if this operation is legal.From the perspective of the overall design, the
OpReadEntry
is just a middle state object, that may have illegal value, we have to check thisOpReadEntry
is valid inManagedLedger#asyncReadEntries
(Current we already do that).Verifying this change
Documentation
doc-not-needed
(Please explain why)