This is an automated email from the ASF dual-hosted git repository.
Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 8a76a026fd fix: register and clean up API runtime resources (#7017)
8a76a026fd is described below
commit 8a76a026fd676b83e692413d2d392ebe1b68c4f6
Author: Southern <[email protected]>
AuthorDate: Wed Sep 2 06:56:21 2026 +0800
fix: register and clean up API runtime resources (#7017)
- After the API is created successfully, call the 'register' function to
publish the associated selector/rule/metadata.
- After the API is deleted successfully, call the 'removeRegister'
function to clean up the associated runtime data.
- When deleting by API path, the cleanup is executed synchronously.
- Add protection for cases where extension data or context path is
missing.
- Add tests for API deletion cleanup and scenarios where the API does not
exist.
Co-authored-by: aias00 <[email protected]>
---
.../shenyu/admin/service/impl/ApiServiceImpl.java | 6 ++++
.../shenyu/admin/service/ApiServiceTest.java | 41 ++++++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ApiServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ApiServiceImpl.java
index ad05dbc788..6386166fe2 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ApiServiceImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ApiServiceImpl.java
@@ -152,6 +152,7 @@ public class ApiServiceImpl implements ApiService {
.build()).collect(Collectors.toList());
tagRelationMapper.batchInsert(tags);
}
+ register(apiDO);
}
return ShenyuResultMessage.CREATE_SUCCESS;
}
@@ -191,6 +192,9 @@ public class ApiServiceImpl implements ApiService {
private void register(final ApiDO apiDO) {
//register selector/rule/metadata if necessary
final ApiDocRegisterDTO.ApiExt ext =
GsonUtils.getInstance().fromJson(apiDO.getExt(),
ApiDocRegisterDTO.ApiExt.class);
+ if (Objects.isNull(ext) ||
StringUtils.isBlank(apiDO.getContextPath())) {
+ return;
+ }
RegisterClientServerDisruptorPublisher publisher =
RegisterClientServerDisruptorPublisher.getInstance();
final String contextPath = apiDO.getContextPath();
final String path = apiDO.getApiPath();
@@ -228,6 +232,7 @@ public class ApiServiceImpl implements ApiService {
final int deleteRows = this.apiMapper.deleteByIds(apiIds);
if (deleteRows > 0) {
tagRelationMapper.deleteByApiIds(apiIds);
+ apis.forEach(this::removeRegister);
}
return StringUtils.EMPTY;
}
@@ -281,6 +286,7 @@ public class ApiServiceImpl implements ApiService {
final int deleteRows = this.apiMapper.deleteByIds(apiIds);
if (deleteRows > 0) {
tagRelationMapper.deleteByApiIds(apiIds);
+ apiDOs.forEach(this::removeRegister);
}
return deleteRows;
}
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ApiServiceTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ApiServiceTest.java
index 7ffc2c87b0..5c789f5482 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ApiServiceTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ApiServiceTest.java
@@ -23,12 +23,16 @@ import org.apache.shenyu.admin.mapper.TagMapper;
import org.apache.shenyu.admin.mapper.TagRelationMapper;
import org.apache.shenyu.admin.model.dto.ApiDTO;
import org.apache.shenyu.admin.model.entity.ApiDO;
+import org.apache.shenyu.admin.model.entity.MetaDataDO;
+import org.apache.shenyu.admin.model.entity.SelectorDO;
import org.apache.shenyu.admin.model.page.CommonPager;
import org.apache.shenyu.admin.model.page.PageParameter;
import org.apache.shenyu.admin.model.query.ApiQuery;
import org.apache.shenyu.admin.model.vo.ApiVO;
+import org.apache.shenyu.admin.model.vo.RuleVO;
import org.apache.shenyu.admin.service.impl.ApiServiceImpl;
import org.apache.shenyu.admin.utils.ShenyuResultMessage;
+import org.apache.shenyu.common.constant.AdminConstants;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -47,8 +51,14 @@ import java.util.stream.IntStream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static
org.apache.shenyu.common.constant.Constants.SYS_DEFAULT_NAMESPACE_ID;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
@@ -99,6 +109,37 @@ public final class ApiServiceTest {
assertEquals(StringUtils.EMPTY,
apiService.delete(Collections.singletonList("123")));
}
+ @Test
+ public void testDeleteCleansRegisteredResources() {
+ RuleVO rule = new RuleVO();
+ rule.setId("rule-1");
+ SelectorDO selector = new SelectorDO();
+ selector.setId("selector-1");
+ MetaDataDO metadata = new MetaDataDO();
+ metadata.setId("metadata-1");
+ ApiDO apiDO = buildApiDO("123");
+
when(apiMapper.selectByIds(Collections.singletonList("123"))).thenReturn(Collections.singletonList(apiDO));
+
when(apiMapper.deleteByIds(Collections.singletonList("123"))).thenReturn(1);
+
when(ruleService.searchByCondition(any())).thenReturn(Collections.singletonList(rule));
+
when(selectorService.findByNameAndPluginNamesAndNamespaceId(anyString(),
anyList(), anyString()))
+ .thenReturn(Collections.singletonList(selector));
+
when(ruleService.findBySelectorId("selector-1")).thenReturn(Collections.emptyList());
+ when(metaDataService.findByPathAndNamespaceId(apiDO.getApiPath(),
SYS_DEFAULT_NAMESPACE_ID)).thenReturn(metadata);
+
+ apiService.delete(Collections.singletonList("123"));
+
+ verify(ruleService,
times(1)).deleteByIdsAndNamespaceId(Collections.singletonList("rule-1"),
SYS_DEFAULT_NAMESPACE_ID);
+ verify(selectorService,
times(1)).deleteByNamespaceId(Collections.singletonList("selector-1"),
SYS_DEFAULT_NAMESPACE_ID);
+ verify(metaDataService,
times(1)).deleteByIdsAndNamespaceId(Collections.singletonList("metadata-1"),
SYS_DEFAULT_NAMESPACE_ID);
+ }
+
+ @Test
+ public void testDeleteWhenApiDoesNotExist() {
+
when(apiMapper.selectByIds(Collections.singletonList("missing"))).thenReturn(Collections.emptyList());
+
+ assertEquals(AdminConstants.SYS_API_ID_NOT_EXIST,
apiService.delete(Collections.singletonList("missing")));
+ }
+
@Test
public void testFindById() {
String id = "123";