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 ae0b3c4ec3 [type:fix] scope the meta_data path check on update by 
namespace (#6689) (#7210)
ae0b3c4ec3 is described below

commit ae0b3c4ec3c1ea98bc196a7d9906948e1f377e13
Author: HY-love-sleep <[email protected]>
AuthorDate: Sat Sep 26 11:54:38 2026 +0800

    [type:fix] scope the meta_data path check on update by namespace (#6689) 
(#7210)
---
 .../apache/shenyu/admin/mapper/MetaDataMapper.java |  8 +++++---
 .../admin/service/impl/MetaDataServiceImpl.java    |  3 ++-
 .../main/resources/mappers/meta-data-sqlmap.xml    |  1 +
 .../shenyu/admin/mapper/MetaDataMapperTest.java    | 24 ++++++++++++++++++++++
 .../shenyu/admin/service/MetaDataServiceTest.java  |  2 +-
 5 files changed, 33 insertions(+), 5 deletions(-)

diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/MetaDataMapper.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/MetaDataMapper.java
index f5b63d4fbf..bcb4464213 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/MetaDataMapper.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/MetaDataMapper.java
@@ -185,9 +185,11 @@ public interface MetaDataMapper extends ExistProvider {
     /**
      * the path is existed.
      *
-     * @param path    path
-     * @param exclude exclude
+     * @param path        path
+     * @param namespaceId namespaceId
+     * @param exclude     exclude
      * @return existed
      */
-    Boolean pathExistedExclude(@Param("path") Serializable path, 
@Param("exclude") List<String> exclude);
+    Boolean pathExistedExclude(@Param("path") Serializable path, 
@Param("namespaceId") String namespaceId,
+                               @Param("exclude") List<String> exclude);
 }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java
index d8dce3f59f..150c8a9c7c 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java
@@ -298,7 +298,8 @@ public class MetaDataServiceImpl implements MetaDataService 
{
     }
 
     private String update(final MetaDataDTO metaDataDTO) {
-        Assert.isNull(metaDataMapper.pathExistedExclude(metaDataDTO.getPath(), 
Collections.singletonList(metaDataDTO.getId())), 
AdminConstants.DATA_PATH_IS_EXIST);
+        Assert.isNull(metaDataMapper.pathExistedExclude(metaDataDTO.getPath(), 
metaDataDTO.getNamespaceId(),
+                Collections.singletonList(metaDataDTO.getId())), 
AdminConstants.DATA_PATH_IS_EXIST);
         MetaDataDO metaDataDO = 
MetaDataTransfer.INSTANCE.mapToEntity(metaDataDTO);
         Optional.ofNullable(metaDataMapper.selectById(metaDataDTO.getId()))
                 .ifPresent(e -> metaDataDTO.setEnabled(e.getEnabled()));
diff --git a/shenyu-admin/src/main/resources/mappers/meta-data-sqlmap.xml 
b/shenyu-admin/src/main/resources/mappers/meta-data-sqlmap.xml
index ae8b6465e5..280347000a 100644
--- a/shenyu-admin/src/main/resources/mappers/meta-data-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/meta-data-sqlmap.xml
@@ -155,6 +155,7 @@
         SElECT true
         FROM meta_data
         WHERE path = #{path}
+        AND namespace_id = #{namespaceId}
         AND id NOT IN
         <foreach collection="exclude" item="id" index="index" open="(" 
separator="," close=")">
             #{id}
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/MetaDataMapperTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/MetaDataMapperTest.java
index 584dd4e21c..21bcee8013 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/MetaDataMapperTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/MetaDataMapperTest.java
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test;
 
 import jakarta.annotation.Resource;
 import java.sql.Timestamp;
+import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -35,6 +36,7 @@ import static 
org.apache.shenyu.common.constant.Constants.SYS_DEFAULT_NAMESPACE_
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.comparesEqualTo;
 import static org.hamcrest.Matchers.hasItems;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
@@ -246,6 +248,28 @@ public final class MetaDataMapperTest extends 
AbstractSpringIntegrationTest {
         assertThat(result, comparesEqualTo(idList.size()));
     }
 
+    /**
+     * The path uniqueness check on update must be scoped to the namespace,
+     * otherwise a path that only exists in another namespace blocks the 
update.
+     */
+    @Test
+    public void pathExistedExcludeIsScopedByNamespace() {
+        MetaDataDO metaDataDO = getMetaDataDO();
+        metaDataDO.setPath("/namespace-scoped-path");
+        metaDataDO.setNamespaceId("namespace-a");
+        assertThat(metaDataMapper.insert(metaDataDO), comparesEqualTo(1));
+
+        // the same path inside the same namespace still collides (the row 
itself excluded)
+        assertThat(metaDataMapper.pathExistedExclude("/namespace-scoped-path", 
"namespace-a",
+                Collections.singletonList("another-id")), 
comparesEqualTo(Boolean.TRUE));
+        // while the path merely existing in another namespace must not
+        assertNull(metaDataMapper.pathExistedExclude("/namespace-scoped-path", 
"namespace-b",
+                Collections.singletonList("another-id")));
+        // and the row being updated is excluded from its own check
+        assertNull(metaDataMapper.pathExistedExclude("/namespace-scoped-path", 
"namespace-a",
+                Collections.singletonList(metaDataDO.getId())));
+    }
+
     private MetaDataDO getMetaDataDO() {
         Timestamp now = new Timestamp(System.currentTimeMillis());
         return MetaDataDO.builder()
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/MetaDataServiceTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/MetaDataServiceTest.java
index 1378c15c94..87d213980d 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/MetaDataServiceTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/MetaDataServiceTest.java
@@ -354,7 +354,7 @@ public final class MetaDataServiceTest {
         when(metaDataDTO.getId()).thenReturn("id");
         when(metaDataDTO.getPath()).thenReturn("path");
         
when(metaDataDTO.getNamespaceId()).thenReturn(SYS_DEFAULT_NAMESPACE_ID);
-        when(metaDataMapper.pathExistedExclude("path", 
Collections.singletonList("id"))).thenReturn(null);
+        when(metaDataMapper.pathExistedExclude("path", 
SYS_DEFAULT_NAMESPACE_ID, Collections.singletonList("id"))).thenReturn(null);
         when(metaDataMapper.selectById("id")).thenReturn(metaDataDO);
         when(metaDataMapper.update(any())).thenReturn(1);
 

Reply via email to