[ISSUE #8714] Prevent receive message NPE when client settings are missing#10585
[ISSUE #8714] Prevent receive message NPE when client settings are missing#10585Aias00 wants to merge 1 commit into
Conversation
203e34b to
272e93f
Compare
There was a problem hiding this comment.
Pull request overview
This PR addresses issue #8714 by preventing a NullPointerException in the gRPC proxy’s ReceiveMessageActivity when client Settings are not yet cached, and adds a regression test covering the missing-settings scenario.
Changes:
- Add a null-guard in
ReceiveMessageActivity#receiveMessageto handleGrpcClientSettingsManager#getClientSettingsreturningnull. - Add a unit test verifying receive-message returns a structured response when client settings are missing.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| proxy/src/main/java/org/apache/rocketmq/proxy/grpc/v2/consumer/ReceiveMessageActivity.java | Adds a fallback path when client settings are missing to avoid NPE during receive-message handling. |
| proxy/src/test/java/org/apache/rocketmq/proxy/grpc/v2/consumer/ReceiveMessageActivityTest.java | Adds a regression test ensuring missing client settings don’t cause an internal error response. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Settings settings = this.grpcClientSettingsManager.getClientSettings(ctx); | ||
| if (settings == null) { | ||
| settings = Settings.getDefaultInstance(); | ||
| } | ||
| final boolean isLite = ClientType.LITE_PUSH_CONSUMER.equals(settings.getClientType()); |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #10585 +/- ##
=============================================
- Coverage 48.26% 48.17% -0.10%
+ Complexity 13433 13413 -20
=============================================
Files 1378 1378
Lines 100817 100823 +6
Branches 13040 13042 +2
=============================================
- Hits 48660 48569 -91
- Misses 46211 46293 +82
- Partials 5946 5961 +15 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Adds a null-guard for getClientSettings() in ReceiveMessageActivity.receiveMessage() to prevent NPE when client settings have not yet been cached, returning a structured receive response instead of an internal error.
Findings
- [Info]
proxy/.../ReceiveMessageActivity.java:68— UsingSettings.getDefaultInstance()as the fallback is reasonable and consistent with how other activities handle missing settings. The downstreamClientType.LITE_PUSH_CONSUMER.equals(...)will safely returnfalsefor the default instance, andgetSubscription()on a defaultSettingsreturns an empty subscription — so the flow degrades gracefully. - [Info]
proxy/.../ReceiveMessageActivityTest.java— Test coverage is solid: mocksgetClientSettingsto returnnulland verifies the response code. Good practice.
Suggestions
- Consider whether
sendMessageActivityor other gRPC v2 activities have the same gap. A quick audit of allgetClientSettings(ctx)call sites without null checks would be a useful follow-up.
Automated review by github-manager-bot
ReceiveMessageActivity can be invoked before cached gRPC client settings are available. When settings are missing, fall back to the real default consumer settings (maxAttempts = retryMaxTimes + 1) instead of Settings.getDefaultInstance(), whose backoffPolicy.maxAttempts is 0. With maxAttempts == 0, PopMessageResultFilterImpl routes fresh messages (reconsumeTimes == 0) straight to the DLQ via reconsumeTimes >= maxAttempts. The real default avoids both the NullPointerException and the DLQ regression. Constraint: Related to apache#8714 Confidence: high Scope-risk: narrow Directive: Keep missing client settings on the default consumer path unless the protocol starts requiring an explicit settings handshake before receive. Tested: mvn -pl proxy -Dtest=ReceiveMessageActivityTest,PopMessageResultFilterImplTest,GrpcClientSettingsManagerTest test Not-tested: Full repository test suite
272e93f to
8f6a9c9
Compare
|
Re: the suggestion to audit other
The producer activities ( So |
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Review by github-manager-bot (Re-review)
Summary
New commit e5f7c3a improves the null-settings fallback by replacing Settings.getDefaultInstance() with a proper getDefaultConsumerSettings() that carries a real maxAttempts value, preventing fresh messages from being routed to the DLQ when client settings are not yet cached.
Changes Since Last Review
GrpcClientSettingsManager.java— AddedgetDefaultConsumerSettings()that delegates tocreateDefaultConsumerSettingsBuilder().build(), ensuringmaxAttempts = retryMaxTimes + 1instead of the protobuf empty default of 0.ReceiveMessageActivity.java:68— Fallback now callsgetDefaultConsumerSettings()instead ofSettings.getDefaultInstance().PopMessageResultFilterImplTest.java— New test class with 3 test cases covering the DLQ regression path (fresh message, retry exhaustion, null settings).GrpcClientSettingsManagerTest.java— New test verifyingmaxAttempts > 0on the default consumer settings.ReceiveMessageActivityTest.java— New test verifying the fallback path does not DLQ fresh messages.
Findings
- [Positive] The fix correctly addresses the subtle DLQ risk: with protobuf's empty default,
backoffPolicy.maxAttempts == 0causesPopMessageResultFilterImplto treatreconsumeTimes == 0as exhausted. The new default prevents this. - [Positive] Test coverage is thorough — covers both the settings layer and the filter layer, with clear test names explaining the regression scenario.
- [Info]
proxy/.../ReceiveMessageActivity.java:68— The fallbackgetDefaultConsumerSettings()creates a newSettingsobject on every call when settings are null. If this path is hot, consider caching the default. However, this is a minor concern since the null-settings case should be rare (only before first client registration).
Verdict
The improvement is well-executed. The previous review's suggestion about auditing other getClientSettings() call sites remains a useful follow-up.
Automated review by github-manager-bot
Which Issue(s) This PR Fixes
Fixes #8714
Brief Description
ReceiveMessageActivitycurrently assumesGrpcClientSettingsManager#getClientSettingsalways returns a non-nullSettingsinstance. When receive-message is called before client settings are cached, the proxy dereferencessettings.getClientType()/settings.getSubscription()and returns an internal NPE instead of a structured receive response.This PR treats missing client settings the same as the existing default-settings path used by tests, allowing receive validation and pop handling to continue without throwing a
NullPointerException.How Did You Test This Change?
mvn -pl proxy -Dtest=ReceiveMessageActivityTest testResult:
BUILD SUCCESS,Tests run: 10, Failures: 0, Errors: 0, Skipped: 0