zjncs opened a new pull request, #11074:
URL: https://github.com/apache/rocketmq/pull/11074

   ## Motivation
   
   `ConsumerRunningInfo.analyzeSubscription`, `isPushType` and 
`analyzeProcessQueue` run on data reported by **each consumer over the wire** 
(`DefaultMQAdminExtImpl.getConsumerRunningInfo` just forwards the broker 
response), so the well-known properties cannot be assumed to exist. Two latent 
crashes exist today when a client does not report them:
   
   1. `analyzeSubscription` falls back to 
`String.valueOf(properties.get(PROP_CONSUMER_START_TIMESTAMP))` when 
`getProperty` returns null. For a genuinely **absent** property this produces 
the literal string `"null"`, and `Long.parseLong("null")` throws:
   
   ```
   java.lang.NumberFormatException: For input string: "null"
       at java.base/java.lang.Long.parseLong(Long.java:XXX)
       at 
...ConsumerRunningInfo.analyzeSubscription(ConsumerRunningInfo.java:64)
   ```
   
   This aborts `mqadmin consumerStatus` / `consumerSubCommand` / the consumer 
monitor midway through the report.
   
   2. `isPushType` (and the identical block inlined in `analyzeProcessQueue`) 
cast the raw `properties.get(PROP_CONSUME_TYPE)` value to `ConsumeType` and 
call `.name()` on it, throwing NPE when the property is absent:
   
   ```
   java.lang.NullPointerException: Cannot invoke "ConsumeType.name()" because 
the return value of "java.util.Properties.get(Object)" is null
   ```
   
   `isPushType` is also called from 
`QueryMsgByIdSubCommand`/`QueryMsgByUniqueKeySubCommand` on the same wire data.
   
   The existing `if (property == null)` fallbacks were introduced to handle 
**non-String** values after deserialization, but they fail to handle the 
**missing** value. No Java client omits these properties today, but the wire 
protocol is implemented by other clients/versions, and one misbehaving client 
should not take down the whole admin command.
   
   ## Modification
   
   - `analyzeSubscription`: read the start timestamp once via 
`properties.get(...)`; when it is unknown, keep the startup grace 
(`startForAWhile = false`) instead of crashing — the 2-minute window exists to 
tolerate freshly started consumers, and an unknown start time deserves the same 
grace rather than a false "different subscription" alarm.
   - `isPushType`: return `false` when `PROP_CONSUME_TYPE` is unknown instead 
of NPE-ing; a single code path now handles both String values and in-memory 
`ConsumeType` values (the case covered by the existing test).
   - `analyzeProcessQueue`: reuse `isPushType` and drop the duplicated block.
   
   ## Verification
   
   `mvn -pl remoting test -Dtest=ConsumerRunningInfoTest`
   
   fail-before (fix stashed, new tests kept):
   
   ```
   Tests run: 3, Failures: 0, Errors: 1, Skipped: 1
   testAnalyzeSubscriptionWithMissingStartTimestamp  <<< ERROR!
   java.lang.NumberFormatException: For input string: "null"
   
   testAnalyzeMethodsTolerateMissingProperties  <<< ERROR!
   java.lang.NullPointerException: Cannot invoke "ConsumeType.name()" because 
the return value of "java.util.Properties.get(Object)" is null
   ```
   
   pass-after:
   
   ```
   Tests run: 7, Failures: 0, Errors: 0, Skipped: 0 - in ConsumerRunningInfoTest
   BUILD SUCCESS
   ```
   
   No associated issue; found by code inspection.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to