tju-yxq opened a new issue, #2210:
URL: https://github.com/apache/rocketmq-dashboard/issues/2210

   ## Problem
   
   Studio refuses to delete an instance registration until it can confirm 
through the selected vendor provider that the instance has no managed Topics or 
Consumer Groups:
   
   ```java
   int topicCount = provider.countTopics(id);
   int consumerGroupCount = provider.countGroups(id);
   ```
   
   That guard is necessary when the remote system is reachable, but it also 
makes a stale registration impossible to remove when the preflight cannot run. 
Examples include a decommissioned NameServer or Proxy endpoint, expired cloud 
credentials, a deleted cloud instance, DNS/network failure, or a provider API 
outage. In those cases `countTopics` or `countGroups` throws before 
`instanceRepository.deleteById` is reached.
   
   This conflicts with the UI's cloud-instance wording that deletion only 
removes the Studio registration and does not release the cloud RocketMQ 
instance. A registration whose remote instance is already gone can remain 
permanently stuck in Studio.
   
   ## Reproduction
   
   A deterministic service test against the current `rocketmq-studio` head 
(`eb44e159`) stubs an existing instance and makes `countTopics` throw 
`IllegalStateException("broker unavailable")`.
   
   Observed behavior:
   
   - the provider exception escapes;
   - `instanceRepository.deleteById` is never called;
   - no existing request option permits removal of the stale registration.
   
   This is a unit-level reproduction; it does not claim a live Broker or 
cloud-provider test.
   
   ## Required safety contract
   
   A force option must not turn the existing managed-resource guard into an 
unconditional bypass.
   
   1. A normal delete continues to run the authoritative provider preflight.
   2. If the preflight succeeds and finds any Topic or Consumer Group, deletion 
returns a conflict. Supplying `force=true` must not override this known result.
   3. If the preflight succeeds and both counts are zero, deletion proceeds 
normally.
   4. If the preflight cannot determine the counts, the normal request returns 
a stable machine-readable error distinct from the managed-resource conflict.
   5. Only after that specific failure may the UI offer a second, explicit 
warning that removes the Studio registration without claiming to delete or 
validate remote resources.
   6. A force request must still attempt the preflight. It may proceed only 
when that attempt is unavailable; it must still reject known managed resources.
   7. A forced removal must be visible in the operation audit, including 
`forced=true`, an unavailable-preflight marker, and a bounded/sanitized failure 
summary that cannot copy credentials or unbounded provider text into the audit 
record.
   8. Existing concurrent-delete behavior, Apache AdminClient release rules, 
and the 404 result for an already removed registration must remain intact.
   
   ## API and UI contract
   
   Use an instance-specific delete request instead of adding `force` to the 
common delete DTO used by unrelated resources.
   
   The backend response for an unavailable preflight needs a stable error 
identifier, so the frontend does not inspect an English message substring. The 
instance page should:
   
   - send the ordinary delete request after the existing confirmation;
   - show the second destructive confirmation only for the 
unavailable-preflight identifier;
   - never offer force removal for the managed-resources conflict;
   - resend the request with `force=true` only after explicit confirmation;
   - report a failure if the forced request itself does not complete.
   
   ## Tests
   
   Backend coverage should include:
   
   - empty-instance normal deletion;
   - Topics and Consumer Groups blocking both normal and force requests;
   - unavailable preflight rejecting a normal request without repository/audit 
side effects;
   - unavailable preflight allowing an explicit force removal;
   - sanitized and bounded forced-audit detail;
   - Apache endpoint release after a successful forced removal;
   - concurrent deletion still returning 404;
   - controller request binding and the machine-readable unavailable-preflight 
response.
   
   Frontend coverage should include:
   
   - force serialized in the instance API request;
   - the second confirmation appears only for the exact error identifier;
   - confirming it sends `force=true`;
   - ordinary conflicts and unrelated failures never expose the force path;
   - successful deletion still reloads the latest active filters.
   
   ## Related work
   
   - #1235 introduced the authoritative live-count preflight; this issue 
preserves that protection.
   - #1726 concerned converting one unsupported Tencent count path into an HTTP 
501 response. It was closed because `UnsupportedOperationException` already had 
a handler. A structured failure alone does not provide an explicit, safe way to 
remove a stale registration.
   - #2000 covers the separate concurrent-delete zero-row result.
   - #1592 implements Tencent group counting and does not address 
unreachable/decommissioned providers.
   
   The expected implementation spans the instance-specific backend 
request/error/preflight/audit contract and the frontend API/confirmation flow. 
The production change is expected to exceed 100 lines because both boundaries 
must change together; tests are not counted toward that estimate.
   
   


-- 
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