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 40bd3cf74c fix: scope rule batch delete by namespace (#6987)
40bd3cf74c is described below
commit 40bd3cf74c8ef3745c6a00dc856ec71ecc564bc8
Author: Southern <[email protected]>
AuthorDate: Wed Aug 26 13:49:19 2026 +0800
fix: scope rule batch delete by namespace (#6987)
Add namespace-scoped mapper methods and SQL statements using:
`id IN (...) AND namespace_id = #{namespaceId}`.
Update RuleServiceImpl to:
- query rules only within the requested namespace;
- return 0 without side effects when no rules match;
- delete only IDs returned by the scoped query;
- delete rule conditions and publish events only for matched rules.
---
.../org/apache/shenyu/admin/mapper/RuleMapper.java | 18 ++++++++++++++++++
.../shenyu/admin/service/impl/RuleServiceImpl.java | 11 ++++++++---
.../src/main/resources/mappers/rule-sqlmap.xml | 19 +++++++++++++++++++
.../apache/shenyu/admin/mapper/RuleMapperTest.java | 19 +++++++++++++++++++
.../apache/shenyu/admin/service/RuleServiceTest.java | 16 ++++++++++++++--
5 files changed, 78 insertions(+), 5 deletions(-)
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/RuleMapper.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/RuleMapper.java
index 13ef28a98d..a018303773 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/RuleMapper.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/RuleMapper.java
@@ -147,6 +147,24 @@ public interface RuleMapper extends ExistProvider {
*/
int deleteByIds(List<String> ids);
+ /**
+ * Select rules by ids and namespace id.
+ *
+ * @param ids primary keys
+ * @param namespaceId namespace id
+ * @return rule list
+ */
+ List<RuleDO> selectByIdsAndNamespaceId(@Param("ids") List<String> ids,
@Param("namespaceId") String namespaceId);
+
+ /**
+ * Delete rules by ids and namespace id.
+ *
+ * @param ids primary keys
+ * @param namespaceId namespace id
+ * @return rows int
+ */
+ int deleteByIdsAndNamespaceId(@Param("ids") List<String> ids,
@Param("namespaceId") String namespaceId);
+
/**
* list all.
*
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/RuleServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/RuleServiceImpl.java
index 04eca5ccda..49855adc57 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/RuleServiceImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/RuleServiceImpl.java
@@ -422,16 +422,21 @@ public class RuleServiceImpl implements RuleService {
* delete rules by ids and namespaceId.
*
* @param ids primary key.
+ * @param namespaceId namespace id.
* @return rows
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteByIdsAndNamespaceId(final List<String> ids, final String
namespaceId) {
- List<RuleDO> rules = ruleMapper.selectByIds(ids);
- final int deleteCount = ruleMapper.deleteByIds(ids);
+ List<RuleDO> rules = ruleMapper.selectByIdsAndNamespaceId(ids,
namespaceId);
+ if (CollectionUtils.isEmpty(rules)) {
+ return 0;
+ }
+ final List<String> ruleIds = map(rules, RuleDO::getId);
+ final int deleteCount = ruleMapper.deleteByIdsAndNamespaceId(ruleIds,
namespaceId);
if (deleteCount > 0) {
ruleEventPublisher.onDeleted(rules);
- ruleConditionMapper.deleteByRuleIds(ids);
+ ruleConditionMapper.deleteByRuleIds(ruleIds);
}
return deleteCount;
}
diff --git a/shenyu-admin/src/main/resources/mappers/rule-sqlmap.xml
b/shenyu-admin/src/main/resources/mappers/rule-sqlmap.xml
index 3c250a09eb..e9b86b24ec 100644
--- a/shenyu-admin/src/main/resources/mappers/rule-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/rule-sqlmap.xml
@@ -209,6 +209,16 @@
</foreach>
</select>
+ <select id="selectByIdsAndNamespaceId"
resultType="org.apache.shenyu.admin.model.entity.RuleDO">
+ select *
+ from rule
+ where id IN
+ <foreach item="id" collection="ids" open="(" separator="," close=")">
+ #{id, jdbcType=VARCHAR}
+ </foreach>
+ AND namespace_id = #{namespaceId, jdbcType=VARCHAR}
+ </select>
+
<insert id="insert"
parameterType="org.apache.shenyu.admin.model.entity.RuleDO">
INSERT INTO rule (id,
date_created,
@@ -381,4 +391,13 @@
#{id, jdbcType=VARCHAR}
</foreach>
</delete>
+
+ <delete id="deleteByIdsAndNamespaceId">
+ DELETE FROM rule
+ WHERE id IN
+ <foreach item="id" collection="ids" open="(" separator=","
close=")">
+ #{id, jdbcType=VARCHAR}
+ </foreach>
+ AND namespace_id = #{namespaceId, jdbcType=VARCHAR}
+ </delete>
</mapper>
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/RuleMapperTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/RuleMapperTest.java
index 2a2938d359..340a6e8e7f 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/RuleMapperTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/RuleMapperTest.java
@@ -24,6 +24,8 @@ import org.apache.shenyu.common.utils.UUIDUtils;
import org.junit.jupiter.api.Test;
import jakarta.annotation.Resource;
import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Random;
@@ -190,6 +192,23 @@ public final class RuleMapperTest extends
AbstractSpringIntegrationTest {
assertThat(delete, equalTo(1));
}
+ @Test
+ public void deleteByIdsAndNamespaceId() {
+ RuleDO ruleInNamespace = buildRuleDO();
+ RuleDO ruleInAnotherNamespace = buildRuleDO();
+ ruleInAnotherNamespace.setNamespaceId("another-namespace");
+ assertThat(ruleMapper.insert(ruleInNamespace), equalTo(1));
+ assertThat(ruleMapper.insert(ruleInAnotherNamespace), equalTo(1));
+
+ List<String> ids = Arrays.asList(ruleInNamespace.getId(),
ruleInAnotherNamespace.getId());
+ assertThat(ruleMapper.selectByIdsAndNamespaceId(ids,
SYS_DEFAULT_NAMESPACE_ID).size(), equalTo(1));
+
assertThat(ruleMapper.selectByIdsAndNamespaceId(Collections.singletonList(ruleInAnotherNamespace.getId()),
SYS_DEFAULT_NAMESPACE_ID).isEmpty(), equalTo(true));
+ assertThat(ruleMapper.deleteByIdsAndNamespaceId(ids,
SYS_DEFAULT_NAMESPACE_ID), equalTo(1));
+ assertThat(ruleMapper.selectById(ruleInAnotherNamespace.getId()),
equalTo(ruleInAnotherNamespace));
+
+ assertThat(ruleMapper.delete(ruleInAnotherNamespace.getId()),
equalTo(1));
+ }
+
private RuleDO buildRuleDO() {
Timestamp now = new Timestamp(System.currentTimeMillis());
String id = UUIDUtils.getInstance().generateShortUuid();
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/RuleServiceTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/RuleServiceTest.java
index 2725ec84e5..d8fbb27e89 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/RuleServiceTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/RuleServiceTest.java
@@ -79,6 +79,8 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
@@ -133,10 +135,20 @@ public final class RuleServiceTest {
public void testDelete() {
publishEvent();
RuleDO ruleDO = buildRuleDO("123");
- given(this.ruleMapper.selectById("123")).willReturn(ruleDO);
final List<String> ids = Collections.singletonList(ruleDO.getId());
- given(this.ruleMapper.deleteByIds(ids)).willReturn(ids.size());
+ given(this.ruleMapper.selectByIdsAndNamespaceId(ids,
SYS_DEFAULT_NAMESPACE_ID)).willReturn(Collections.singletonList(ruleDO));
+ given(this.ruleMapper.deleteByIdsAndNamespaceId(ids,
SYS_DEFAULT_NAMESPACE_ID)).willReturn(ids.size());
assertEquals(this.ruleService.deleteByIdsAndNamespaceId(ids,
SYS_DEFAULT_NAMESPACE_ID), ids.size());
+ verify(this.ruleConditionMapper).deleteByRuleIds(ids);
+ }
+
+ @Test
+ public void testDeleteWithNoRulesInNamespace() {
+ final List<String> ids = Collections.singletonList("123");
+ given(this.ruleMapper.selectByIdsAndNamespaceId(ids,
SYS_DEFAULT_NAMESPACE_ID)).willReturn(Collections.emptyList());
+
+ assertEquals(this.ruleService.deleteByIdsAndNamespaceId(ids,
SYS_DEFAULT_NAMESPACE_ID), 0);
+ verify(this.ruleMapper, never()).deleteByIdsAndNamespaceId(ids,
SYS_DEFAULT_NAMESPACE_ID);
}
@Test