This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new f89e1a0e fix: prevent instance metadata from being orphaned (#1125)
f89e1a0e is described below

commit f89e1a0ef206ad6196b9d4b05920b79fd579f862
Author: aias00 <[email protected]>
AuthorDate: Thu Aug 6 23:47:21 2026 -0700

    fix: prevent instance metadata from being orphaned (#1125)
---
 .../rocketmq/studio/instance/InstanceService.java  |  8 ++++-
 .../studio/instance/InstanceControllerTest.java    | 19 ++++++++++++
 .../studio/instance/InstanceServiceTest.java       | 34 ++++++++++++++++++++++
 3 files changed, 60 insertions(+), 1 deletion(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/instance/InstanceService.java 
b/server/src/main/java/org/apache/rocketmq/studio/instance/InstanceService.java
index 95014da8..bb24a94a 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/instance/InstanceService.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/instance/InstanceService.java
@@ -204,8 +204,14 @@ public class InstanceService {
             throw new BusinessException(400, "InstanceVO ID is required");
         }
 
-        instanceRepository.findById(id)
+        InstanceVO existing = instanceRepository.findById(id)
                 .orElseThrow(() -> new BusinessException(404, "InstanceVO not 
found: " + id));
+
+        if (existing.getTopicCount() > 0 || existing.getConsumerGroupCount() > 
0) {
+            throw new BusinessException(409, String.format(
+                    "Cannot delete instance with managed resources: topics=%d, 
consumerGroups=%d",
+                    existing.getTopicCount(), 
existing.getConsumerGroupCount()));
+        }
         instanceRepository.deleteById(id);
     }
 
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/instance/InstanceControllerTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/instance/InstanceControllerTest.java
index 8f3ff7e9..3d04b220 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/instance/InstanceControllerTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/instance/InstanceControllerTest.java
@@ -19,6 +19,7 @@ package org.apache.rocketmq.studio.instance;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.rocketmq.studio.common.domain.enums.InstanceType;
+import org.apache.rocketmq.studio.common.exception.BusinessException;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import 
org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
@@ -35,6 +36,7 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
@@ -200,6 +202,23 @@ class InstanceControllerTest {
         verify(instanceService).deleteInstance("inst-1");
     }
 
+    @Test
+    void deleteInstanceShouldReturnConflictWhenManagedResourcesExist() throws 
Exception {
+        doThrow(new BusinessException(409,
+                "Cannot delete instance with managed resources: topics=2, 
consumerGroups=1"))
+                .when(instanceService).deleteInstance("inst-1");
+
+        mockMvc.perform(post("/api/instances/delete")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content(objectMapper.writeValueAsString(Map.of("id", 
"inst-1"))))
+                .andExpect(status().isConflict())
+                .andExpect(jsonPath("$.code").value(409))
+                .andExpect(jsonPath("$.message")
+                        .value("Cannot delete instance with managed resources: 
topics=2, consumerGroups=1"));
+
+        verify(instanceService).deleteInstance("inst-1");
+    }
+
     @Test
     void deleteInstanceShouldRejectBlankId() throws Exception {
         mockMvc.perform(post("/api/instances/delete")
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/instance/InstanceServiceTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/instance/InstanceServiceTest.java
index b998643e..afc67482 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/instance/InstanceServiceTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/instance/InstanceServiceTest.java
@@ -457,6 +457,40 @@ class InstanceServiceTest {
         verify(instanceRepository).deleteById("inst-1");
     }
 
+    @Test
+    void deleteInstanceShouldRejectInstanceWithTopics() {
+        InstanceVO existing = InstanceVO.builder()
+                .name("with-topics")
+                .topicCount(2)
+                .build();
+        existing.setId("inst-1");
+        
when(instanceRepository.findById("inst-1")).thenReturn(Optional.of(existing));
+
+        assertThatThrownBy(() -> instanceService.deleteInstance("inst-1"))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("Cannot delete instance with managed resources: 
topics=2, consumerGroups=0")
+                .satisfies(ex -> assertThat(((BusinessException) 
ex).getCode()).isEqualTo(409));
+
+        verify(instanceRepository, never()).deleteById("inst-1");
+    }
+
+    @Test
+    void deleteInstanceShouldRejectInstanceWithConsumerGroups() {
+        InstanceVO existing = InstanceVO.builder()
+                .name("with-consumer-groups")
+                .consumerGroupCount(3)
+                .build();
+        existing.setId("inst-1");
+        
when(instanceRepository.findById("inst-1")).thenReturn(Optional.of(existing));
+
+        assertThatThrownBy(() -> instanceService.deleteInstance("inst-1"))
+                .isInstanceOf(BusinessException.class)
+                .hasMessage("Cannot delete instance with managed resources: 
topics=0, consumerGroups=3")
+                .satisfies(ex -> assertThat(((BusinessException) 
ex).getCode()).isEqualTo(409));
+
+        verify(instanceRepository, never()).deleteById("inst-1");
+    }
+
     @Test
     void deleteInstanceShouldThrowWhenIdIsNull() {
         assertThatThrownBy(() -> instanceService.deleteInstance(null))

Reply via email to