btlqql opened a new pull request, #5319:
URL: https://github.com/apache/rocketmq-dashboard/pull/5319
### Which Issue(s) This PR Fixes
- Fixes #5049
### Brief Description
`AliyunClientFactory.client`
(server/src/main/java/org/apache/rocketmq/studio/provider/alibaba/AliyunClientFactory.java:62-65)
published a new client with a bare `clients.computeIfAbsent(key, ignored ->
createClient(...))`, while `invalidateCredential` (same file, line 70) evicted
the matching entries with `clients.entrySet().removeIf(...)`. The two
operations were not mutually exclusive: a lookup that had already started
building its client while `CloudCredentialService.update` rotated the secret
removed nothing (the entry did not exist yet), so the client built from the
*old* secret was published into the cache right after the invalidation
returned. The next lookup for that credential/region returned that stale client
— the rotation reported success but subsequent Aliyun calls kept signing with
the previous access key until another rotation or a restart.
The fix makes creation and invalidation share the factory's monitor, exactly
like the sibling `TencentClientFactory` already does: `client()` takes a lock
for the `computeIfAbsent` publish (with a lock-free fast path for the hits) and
`invalidateCredential` is `synchronized`, so a client that is still being
created is always published *before* the eviction runs and is therefore evicted
by it. A lookup that starts after invalidation completes builds a client from
the updated credential.
### How Did You Test This Change?
New deterministic regression
`AliyunClientFactoryTest#invalidateCredentialShouldEvictClientCreatedDuringRotationTest`:
a subclassed factory publishes a first client only after a latch is released,
`createClient` signals when it is in flight, and a second thread calls the real
`invalidateCredential` while that creation is still running; the test then
asserts that the next `client(CREDENTIAL_ID, REGION)` is the replacement
client, that the first client was closed and that exactly two clients were
created.
Red run on the unmodified tree:
```
$ cd server && mvn -B -ntp test -Dtest=AliyunClientFactoryTest
[ERROR] Tests run: 11, Failures: 1, Errors: 0, Skipped: 0, Time elapsed:
4.393 s <<< FAILURE! -- in
org.apache.rocketmq.studio.provider.alibaba.AliyunClientFactoryTest
[ERROR]
org.apache.rocketmq.studio.provider.alibaba.AliyunClientFactoryTest.invalidateCredentialShouldEvictClientCreatedDuringRotationTest
-- Time elapsed: 0.032 s <<< FAILURE!
[ERROR]
AliyunClientFactoryTest.invalidateCredentialShouldEvictClientCreatedDuringRotationTest:162
java.lang.AssertionError:
Expecting actual:
Mock for AsyncClient, hashCode: 59930654
and:
Mock for AsyncClient, hashCode: 1070319462
to refer to the same object
[ERROR] Tests run: 11, Failures: 1, Errors: 0, Skipped: 0
[INFO] BUILD FAILURE
```
Green run after the fix (same command, same test class):
```
$ cd server && mvn -B -ntp test -Dtest=AliyunClientFactoryTest
[INFO] You have 0 Checkstyle violations.
[INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:
4.497 s -- in
org.apache.rocketmq.studio.provider.alibaba.AliyunClientFactoryTest
[INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
### Checklist
- [x] One coherent change; unrelated modifications are not bundled in
- [x] Commit subject follows Conventional Commits
- [x] Tests added or updated for non-trivial changes
- [x] New UI text has both Chinese and English entries under `web/src/i18n/`
— not applicable, no UI text changed
- [x] Architecture constraints stay green (`mvn test` runs the ArchUnit
checks) — only the locking discipline inside one existing class changed; no new
type, package or dependency, and the ArchUnit rules run in the same reactor
- [x] New source files carry the ASF license header — no new source file,
the change is inside an existing file
- [x] Documentation touched where behaviour changed (README / `docs/` /
in-app help) — not applicable: cache internals only, the endpoint contracts and
API shapes are unchanged
--
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]