Updated the OTPListner: replaced synchronizedMap with ConcurrentHashMapp for better concurrency#1891
Updated the OTPListner: replaced synchronizedMap with ConcurrentHashMapp for better concurrency#1891BhuvanaShreeBS wants to merge 1 commit intomosip:developfrom
Conversation
…p for better concurrency Signed-off-by: Bhuvanashree B S <bhuvanashree.b@cyberpwn.com>
WalkthroughOTPListener.java refactored to replace Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@apitest-commons/src/main/java/io/mosip/testrig/apirig/testrunner/OTPListener.java`:
- Around line 189-193: The code in OTPListener uses
allNotificationMapS.get(emailId) followed by
allNotificationMapS.remove(emailId), creating a TOCTOU race; replace the
two-step pattern with a single atomic call: call
allNotificationMapS.remove(emailId) directly, store its result in a local
variable, check that result for null and return it if non-null (remove the
redundant get and null-check on the first call) so the retrieval-and-delete is
atomic with respect to other threads.
🧹 Nitpick comments (1)
apitest-commons/src/main/java/io/mosip/testrig/apirig/testrunner/OTPListener.java (1)
30-33: Inconsistency:emailNotificationMapSstill usessynchronizedMapwith rawObjecttypes.
allNotificationMapSwas improved toConcurrentHashMap<String, String>, butemailNotificationMapSon lines 30–31 still usesCollections.synchronizedMap(new HashMap<Object, Object>()). Consider applying the same treatment for consistency and to avoid the unnecessary(String)cast on line 153/220.
| if (allNotificationMapS.get(emailId) != null) { | ||
| String message = (String) allNotificationMapS.remove(emailId); | ||
| logger.info("Found notification for " + emailId); | ||
| return message; | ||
| String message = allNotificationMapS.remove(emailId); | ||
| if (message != null) { | ||
| return message; | ||
| } |
There was a problem hiding this comment.
TOCTOU race: get followed by remove is not atomic.
Even with ConcurrentHashMap, a concurrent thread can remove the entry between your get check (line 189) and your remove call (line 190). The null-check on line 191 prevents returning null, which is good, but the initial get is now redundant — just call remove directly.
Proposed fix
- if (allNotificationMapS.get(emailId) != null) {
- String message = allNotificationMapS.remove(emailId);
- if (message != null) {
- return message;
- }
+ String message = allNotificationMapS.remove(emailId);
+ if (message != null) {
+ return message;
}🤖 Prompt for AI Agents
In
`@apitest-commons/src/main/java/io/mosip/testrig/apirig/testrunner/OTPListener.java`
around lines 189 - 193, The code in OTPListener uses
allNotificationMapS.get(emailId) followed by
allNotificationMapS.remove(emailId), creating a TOCTOU race; replace the
two-step pattern with a single atomic call: call
allNotificationMapS.remove(emailId) directly, store its result in a local
variable, check that result for null and return it if non-null (remove the
redundant get and null-check on the first call) so the retrieval-and-delete is
atomic with respect to other threads.
Updated the OTPListner - replaced synchronizedMap with ConcurrentHashMapp for better concurrency
Summary by CodeRabbit
Bug Fixes
Refactor