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

hefengen 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 e38f4eac29 [type:feat]The sync-data-http method adapts to the 
namespace transformation (#5598)
e38f4eac29 is described below

commit e38f4eac29fc796e41bc057ed95d3abc4d4ac54a
Author: xcsnx <1192709...@qq.com>
AuthorDate: Wed Oct 16 22:04:31 2024 +0800

    [type:feat]The sync-data-http method adapts to the namespace transformation 
(#5598)
    
    * sync frontend
    
    * commit
    
    * commit
    
    * fix e2e
    
    * fix test
    
    * fix
    
    * fix cr
    
    * fix cr
    
    * fix cr
    
    * final
    
    * fix
    
    * fix
    
    * fix
    
    * fix
    
    * fix uni test
    
    * fix
    
    * fix
    
    * fix
    
    * fix
    
    * fix
    
    * fix
    
    * fix
    
    * fix
    
    ---------
    
    Co-authored-by: ‘xcsnx’ <‘1192709...@qq.com’>
    Co-authored-by: aias00 <rok...@163.com>
---
 .../config/HttpLongPollingSyncConfiguration.java   |   1 -
 .../shenyu/admin/controller/ConfigController.java  |  41 +++++--
 .../admin/discovery/LocalDiscoveryProcessor.java   |   2 +
 .../listener/AbstractDataChangedListener.java      | 136 ++++++++++++---------
 .../shenyu/admin/listener/ConfigDataCache.java     |  14 ++-
 .../shenyu/admin/listener/DataChangedEvent.java    |   6 +-
 .../http/HttpLongPollingDataChangedListener.java   | 107 +++++++++++-----
 .../shenyu/admin/mapper/NamespaceMapper.java       |   9 +-
 .../apache/shenyu/admin/model/entity/RuleDO.java   |   1 +
 .../shenyu/admin/service/NamespaceService.java     |   7 ++
 .../admin/service/impl/DiscoveryServiceImpl.java   |   1 +
 .../admin/service/impl/NamespaceServiceImpl.java   |   9 +-
 .../admin/service/impl/SelectorServiceImpl.java    |   3 +-
 .../admin/service/impl/UpstreamCheckService.java   |   1 +
 .../shenyu/admin/transfer/DiscoveryTransfer.java   |   1 +
 .../shenyu/admin/transfer/MetaDataTransfer.java    |   1 +
 .../main/resources/mappers/namespace-sqlmap.xml    |   8 +-
 .../admin/controller/ConfigControllerTest.java     |  19 ++-
 .../listener/AbstractDataChangedListenerTest.java  |  77 +++++++-----
 .../shenyu/admin/listener/ConfigDataCacheTest.java |   3 +-
 .../apache/shenyu/common/config/ShenyuConfig.java  |   8 +-
 .../shenyu/common/dto/ProxySelectorData.java       |  20 +++
 .../sync/data/http/HttpSyncDataConfiguration.java  |   8 +-
 .../http/HttpClientPluginConfigurationTest.java    |   3 +-
 .../shenyu/sync/data/http/HttpSyncDataService.java |  29 +++--
 .../sync/data/http/HttpSyncDataServiceTest.java    |   6 +-
 26 files changed, 358 insertions(+), 163 deletions(-)

diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/HttpLongPollingSyncConfiguration.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/HttpLongPollingSyncConfiguration.java
index 190c938bc8..0b06a529e0 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/HttpLongPollingSyncConfiguration.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/HttpLongPollingSyncConfiguration.java
@@ -42,5 +42,4 @@ public class HttpLongPollingSyncConfiguration {
     public HttpLongPollingDataChangedListener 
httpLongPollingDataChangedListener(final HttpSyncProperties httpSyncProperties) 
{
         return new HttpLongPollingDataChangedListener(httpSyncProperties);
     }
-
 }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigController.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigController.java
index 5d8c67e156..6a77afae7e 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigController.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigController.java
@@ -18,8 +18,16 @@
 package org.apache.shenyu.admin.controller;
 
 import com.google.common.collect.Maps;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotNull;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.exception.ShenyuAdminException;
 import 
org.apache.shenyu.admin.listener.http.HttpLongPollingDataChangedListener;
 import org.apache.shenyu.admin.model.result.ShenyuAdminResult;
+import org.apache.shenyu.admin.model.vo.NamespaceVO;
+import org.apache.shenyu.admin.service.NamespaceService;
 import org.apache.shenyu.admin.utils.ShenyuResultMessage;
 import org.apache.shenyu.common.dto.ConfigData;
 import org.apache.shenyu.common.enums.ConfigGroupEnum;
@@ -27,10 +35,6 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.NotNull;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.Map;
@@ -42,29 +46,40 @@ import java.util.Map;
 @RequestMapping("/configs")
 @RestController
 public class ConfigController {
-    
+
     private final HttpLongPollingDataChangedListener longPollingListener;
-    
-    public ConfigController(final HttpLongPollingDataChangedListener 
longPollingListener) {
+
+    private final NamespaceService namespaceService;
+
+    public ConfigController(final HttpLongPollingDataChangedListener 
longPollingListener, final NamespaceService namespaceService) {
         this.longPollingListener = longPollingListener;
+        this.namespaceService = namespaceService;
     }
-    
+
     /**
      * Fetch configs shenyu result.
      *
-     * @param groupKeys the group keys
+     * @param groupKeys   the group keys
+     * @param namespaceId namespaceId
      * @return the shenyu result
      */
     @GetMapping("/fetch")
-    public ShenyuAdminResult fetchConfigs(@NotNull final String[] groupKeys) {
+    public ShenyuAdminResult fetchConfigs(@NotNull final String[] groupKeys, 
final String namespaceId) {
+        if (StringUtils.isEmpty(namespaceId)) {
+            throw new ShenyuAdminException("namespaceId is null");
+        }
+        NamespaceVO existNamespace = namespaceService.findById(namespaceId);
+        if (StringUtils.isNotEmpty(namespaceId) && 
ObjectUtils.isEmpty(existNamespace)) {
+            throw new ShenyuAdminException("namespace is not exist");
+        }
         Map<String, ConfigData<?>> result = Maps.newHashMap();
         for (String groupKey : groupKeys) {
-            ConfigData<?> data = 
longPollingListener.fetchConfig(ConfigGroupEnum.valueOf(groupKey));
+            ConfigData<?> data = 
longPollingListener.fetchConfig(ConfigGroupEnum.valueOf(groupKey), namespaceId);
             result.put(groupKey, data);
         }
         return ShenyuAdminResult.success(ShenyuResultMessage.SUCCESS, result);
     }
-    
+
     /**
      * Listener.
      *
@@ -75,5 +90,5 @@ public class ConfigController {
     public void listener(final HttpServletRequest request, final 
HttpServletResponse response) {
         longPollingListener.doLongPolling(request, response);
     }
-    
+
 }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/discovery/LocalDiscoveryProcessor.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/discovery/LocalDiscoveryProcessor.java
index 223e0873bc..08be2f5a6d 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/discovery/LocalDiscoveryProcessor.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/discovery/LocalDiscoveryProcessor.java
@@ -88,6 +88,7 @@ public class LocalDiscoveryProcessor implements 
DiscoveryProcessor, ApplicationE
         discoverySyncData.setSelectorName(proxySelectorDTO.getName());
         List<DiscoveryUpstreamData> upstreamDataList = 
upstreamDTOS.stream().map(DiscoveryTransfer.INSTANCE::mapToData).collect(Collectors.toList());
         discoverySyncData.setUpstreamDataList(upstreamDataList);
+        discoverySyncData.setNamespaceId(proxySelectorDTO.getNamespaceId());
         DataChangedEvent dataChangedEvent = new 
DataChangedEvent(ConfigGroupEnum.DISCOVER_UPSTREAM, DataEventTypeEnum.UPDATE, 
Collections.singletonList(discoverySyncData));
         eventPublisher.publishEvent(dataChangedEvent);
         DiscoveryStreamUpdatedEvent discoveryStreamUpdatedEvent = new 
DiscoveryStreamUpdatedEvent(discoverySyncData, LOCAL_DISCOVERY_UPSTREAM_UPDATE);
@@ -108,6 +109,7 @@ public class LocalDiscoveryProcessor implements 
DiscoveryProcessor, ApplicationE
         discoverySyncData.setSelectorName(proxySelectorDTO.getName());
         List<DiscoveryUpstreamData> upstreamDataList = 
discoveryUpstreamDOS.stream().map(DiscoveryTransfer.INSTANCE::mapToData).collect(Collectors.toList());
         discoverySyncData.setUpstreamDataList(upstreamDataList);
+        discoverySyncData.setNamespaceId(proxySelectorDTO.getNamespaceId());
         DataChangedEvent dataChangedEvent = new 
DataChangedEvent(ConfigGroupEnum.DISCOVER_UPSTREAM, DataEventTypeEnum.UPDATE, 
Collections.singletonList(discoverySyncData));
         eventPublisher.publishEvent(dataChangedEvent);
     }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/AbstractDataChangedListener.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/AbstractDataChangedListener.java
index 2084a9086d..6547b2fa6d 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/AbstractDataChangedListener.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/AbstractDataChangedListener.java
@@ -17,23 +17,28 @@
 
 package org.apache.shenyu.admin.listener;
 
+import jakarta.annotation.Resource;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import 
org.apache.shenyu.admin.listener.http.HttpLongPollingDataChangedListener;
+import org.apache.shenyu.admin.model.vo.NamespaceVO;
 import org.apache.shenyu.admin.service.AppAuthService;
 import org.apache.shenyu.admin.service.DiscoveryUpstreamService;
 import org.apache.shenyu.admin.service.MetaDataService;
 import org.apache.shenyu.admin.service.NamespacePluginService;
+import org.apache.shenyu.admin.service.NamespaceService;
 import org.apache.shenyu.admin.service.ProxySelectorService;
 import org.apache.shenyu.admin.service.RuleService;
 import org.apache.shenyu.admin.service.SelectorService;
 import org.apache.shenyu.common.dto.AppAuthData;
 import org.apache.shenyu.common.dto.ConfigData;
+import org.apache.shenyu.common.dto.DiscoverySyncData;
 import org.apache.shenyu.common.dto.MetaData;
 import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.common.dto.ProxySelectorData;
 import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
-import org.apache.shenyu.common.dto.DiscoverySyncData;
-import org.apache.shenyu.common.dto.ProxySelectorData;
 import org.apache.shenyu.common.enums.ConfigGroupEnum;
 import org.apache.shenyu.common.enums.DataEventTypeEnum;
 import org.apache.shenyu.common.utils.GsonUtils;
@@ -42,11 +47,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
 
-import jakarta.annotation.Resource;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import static 
org.apache.shenyu.common.constant.Constants.SYS_DEFAULT_NAMESPACE_ID;
+
 
 /**
  * Abstract class for ConfigEventListener.
@@ -98,14 +104,18 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
     @Resource
     private DiscoveryUpstreamService discoveryUpstreamService;
 
+    @Resource
+    private NamespaceService namespaceService;
+
     /**
      * fetch configuration from cache.
      *
-     * @param groupKey the group key
+     * @param groupKey    the group key
+     * @param namespaceId the namespaceId
      * @return the configuration data
      */
-    public ConfigData<?> fetchConfig(final ConfigGroupEnum groupKey) {
-        ConfigDataCache config = CACHE.get(groupKey.name());
+    public ConfigData<?> fetchConfig(final ConfigGroupEnum groupKey, final 
String namespaceId) {
+        ConfigDataCache config = 
CACHE.get(HttpLongPollingDataChangedListener.buildCacheKey(namespaceId, 
groupKey.name()));
         switch (groupKey) {
             case APP_AUTH:
                 return buildConfigData(config, AppAuthData.class);
@@ -131,8 +141,9 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
         if (CollectionUtils.isEmpty(changed)) {
             return;
         }
-        this.updateAppAuthCache();
-        this.afterAppAuthChanged(changed, eventType);
+        String namespaceId = changed.stream().map(value -> 
StringUtils.defaultString(value.getNamespaceId(), 
SYS_DEFAULT_NAMESPACE_ID)).findFirst().get();
+        this.updateAppAuthCache(namespaceId);
+        this.afterAppAuthChanged(changed, eventType, namespaceId);
     }
 
     /**
@@ -141,7 +152,7 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
      * @param changed   the changed
      * @param eventType the event type
      */
-    protected void afterAppAuthChanged(final List<AppAuthData> changed, final 
DataEventTypeEnum eventType) {
+    protected void afterAppAuthChanged(final List<AppAuthData> changed, final 
DataEventTypeEnum eventType, final String namespaceId) {
     }
 
     @Override
@@ -149,8 +160,9 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
         if (CollectionUtils.isEmpty(changed)) {
             return;
         }
-        this.updateMetaDataCache();
-        this.afterMetaDataChanged(changed, eventType);
+        String namespaceId = changed.stream().map(value -> 
StringUtils.defaultString(value.getNamespaceId(), 
SYS_DEFAULT_NAMESPACE_ID)).findFirst().get();
+        this.updateMetaDataCache(namespaceId);
+        this.afterMetaDataChanged(changed, eventType, namespaceId);
     }
 
     /**
@@ -159,7 +171,7 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
      * @param changed   the changed
      * @param eventType the event type
      */
-    protected void afterMetaDataChanged(final List<MetaData> changed, final 
DataEventTypeEnum eventType) {
+    protected void afterMetaDataChanged(final List<MetaData> changed, final 
DataEventTypeEnum eventType, final String namespaceId) {
     }
 
     @Override
@@ -167,45 +179,48 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
         if (CollectionUtils.isEmpty(changed)) {
             return;
         }
-        this.updatePluginCache();
-        this.afterPluginChanged(changed, eventType);
+        String namespaceId = changed.stream().map(value -> 
StringUtils.defaultString(value.getNamespaceId(), 
SYS_DEFAULT_NAMESPACE_ID)).findFirst().get();
+        this.updatePluginCache(namespaceId);
+        this.afterPluginChanged(changed, eventType, namespaceId);
     }
-    
+
     /**
      * After plugin changed.
      *
      * @param changed   the changed
      * @param eventType the event type
      */
-    protected void afterPluginChanged(final List<PluginData> changed, final 
DataEventTypeEnum eventType) {
+    protected void afterPluginChanged(final List<PluginData> changed, final 
DataEventTypeEnum eventType, final String namespaceId) {
     }
-    
+
     @Override
     public void onRuleChanged(final List<RuleData> changed, final 
DataEventTypeEnum eventType) {
         if (CollectionUtils.isEmpty(changed)) {
             return;
         }
         LOG.info("onRuleChanged, changed:{}, eventType:{}", 
JsonUtils.toJson(changed), JsonUtils.toJson(eventType));
-        this.updateRuleCache();
-        this.afterRuleChanged(changed, eventType);
+        String namespaceId = changed.stream().map(value -> 
StringUtils.defaultString(value.getNamespaceId(), 
SYS_DEFAULT_NAMESPACE_ID)).findFirst().get();
+        this.updateRuleCache(namespaceId);
+        this.afterRuleChanged(changed, eventType, namespaceId);
     }
-    
+
     /**
      * After rule changed.
      *
      * @param changed   the changed
      * @param eventType the event type
      */
-    protected void afterRuleChanged(final List<RuleData> changed, final 
DataEventTypeEnum eventType) {
+    protected void afterRuleChanged(final List<RuleData> changed, final 
DataEventTypeEnum eventType, final String namespaceId) {
     }
-    
+
     @Override
     public void onSelectorChanged(final List<SelectorData> changed, final 
DataEventTypeEnum eventType) {
         if (CollectionUtils.isEmpty(changed)) {
             return;
         }
-        this.updateSelectorCache();
-        this.afterSelectorChanged(changed, eventType);
+        String namespaceId = changed.stream().map(value -> 
StringUtils.defaultString(value.getNamespaceId(), 
SYS_DEFAULT_NAMESPACE_ID)).findFirst().get();
+        this.updateSelectorCache(namespaceId);
+        this.afterSelectorChanged(changed, eventType, namespaceId);
     }
 
     /**
@@ -218,8 +233,9 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
         if (CollectionUtils.isEmpty(changed)) {
             return;
         }
-        this.updateProxySelectorDataCache();
-        this.afterProxySelectorChanged(changed, eventType);
+        String namespaceId = changed.stream().map(value -> 
StringUtils.defaultString(value.getNamespaceId(), 
SYS_DEFAULT_NAMESPACE_ID)).findFirst().get();
+        this.updateProxySelectorDataCache(namespaceId);
+        this.afterProxySelectorChanged(changed, eventType, namespaceId);
     }
 
     /**
@@ -228,7 +244,7 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
      * @param changed   the changed
      * @param eventType the event type
      */
-    protected void afterProxySelectorChanged(final List<ProxySelectorData> 
changed, final DataEventTypeEnum eventType) {
+    protected void afterProxySelectorChanged(final List<ProxySelectorData> 
changed, final DataEventTypeEnum eventType, final String namespaceId) {
     }
 
     /**
@@ -241,8 +257,9 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
         if (CollectionUtils.isEmpty(changed)) {
             return;
         }
-        this.updateDiscoveryUpstreamDataCache();
-        this.afterDiscoveryUpstreamDataChanged(changed, eventType);
+        String namespaceId = changed.stream().map(value -> 
StringUtils.defaultString(value.getNamespaceId(), 
SYS_DEFAULT_NAMESPACE_ID)).findFirst().get();
+        this.updateDiscoveryUpstreamDataCache(namespaceId);
+        this.afterDiscoveryUpstreamDataChanged(changed, eventType, 
namespaceId);
     }
 
     /**
@@ -251,7 +268,7 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
      * @param changed   the changed
      * @param eventType the event type
      */
-    protected void afterDiscoveryUpstreamDataChanged(final 
List<DiscoverySyncData> changed, final DataEventTypeEnum eventType) {
+    protected void afterDiscoveryUpstreamDataChanged(final 
List<DiscoverySyncData> changed, final DataEventTypeEnum eventType, final 
String namespaceId) {
     }
 
     /**
@@ -260,7 +277,7 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
      * @param changed   the changed
      * @param eventType the event type
      */
-    protected void afterSelectorChanged(final List<SelectorData> changed, 
final DataEventTypeEnum eventType) {
+    protected void afterSelectorChanged(final List<SelectorData> changed, 
final DataEventTypeEnum eventType, final String namespaceId) {
     }
 
     @Override
@@ -278,68 +295,73 @@ public abstract class AbstractDataChangedListener 
implements DataChangedListener
      * @param <T>   the type of class
      * @param data  the new config data
      */
-    protected <T> void updateCache(final ConfigGroupEnum group, final List<T> 
data) {
+    protected <T> void updateCache(final ConfigGroupEnum group, final List<T> 
data, final String namespaceId) {
         String json = GsonUtils.getInstance().toJson(data);
-        ConfigDataCache newVal = new ConfigDataCache(group.name(), json, 
DigestUtils.md5Hex(json), System.currentTimeMillis());
+        String configDataCacheKey = 
HttpLongPollingDataChangedListener.buildCacheKey(namespaceId, group.name());
+        ConfigDataCache newVal = new ConfigDataCache(configDataCacheKey, json, 
DigestUtils.md5Hex(json), System.currentTimeMillis(), namespaceId);
         ConfigDataCache oldVal = CACHE.put(newVal.getGroup(), newVal);
         LOG.info("update config cache[{}], old: {}, updated: {}", group, 
oldVal, newVal);
         LOG.info("update config json: {}", json);
     }
-    
+
     /**
      * refresh local cache.
      */
     protected void refreshLocalCache() {
-        this.updateAppAuthCache();
-        this.updatePluginCache();
-        this.updateRuleCache();
-        this.updateSelectorCache();
-        this.updateMetaDataCache();
-        this.updateProxySelectorDataCache();
-        this.updateDiscoveryUpstreamDataCache();
+        List<NamespaceVO> namespaceList = namespaceService.listAll();
+        for (NamespaceVO namespace : namespaceList) {
+            String namespaceId = namespace.getNamespaceId();
+            this.updatePluginCache(namespaceId);
+            this.updateAppAuthCache(namespaceId);
+            this.updateRuleCache(namespaceId);
+            this.updateSelectorCache(namespaceId);
+            this.updateMetaDataCache(namespaceId);
+            this.updateProxySelectorDataCache(namespaceId);
+            this.updateDiscoveryUpstreamDataCache(namespaceId);
+        }
     }
 
     /**
      * Update selector cache.
      */
-    protected void updateSelectorCache() {
-        this.updateCache(ConfigGroupEnum.SELECTOR, selectorService.listAll());
+    protected void updateSelectorCache(final String namespaceId) {
+        this.updateCache(ConfigGroupEnum.SELECTOR, selectorService.listAll(), 
namespaceId);
     }
 
     /**
      * Update rule cache.
      */
-    protected void updateRuleCache() {
-        this.updateCache(ConfigGroupEnum.RULE, ruleService.listAll());
+    protected void updateRuleCache(final String namespaceId) {
+        this.updateCache(ConfigGroupEnum.RULE, ruleService.listAll(), 
namespaceId);
     }
 
     /**
      * Update plugin cache.
      */
-    protected void updatePluginCache() {
-        this.updateCache(ConfigGroupEnum.PLUGIN, 
namespacePluginService.listAll());
+    protected void updatePluginCache(final String namespaceId) {
+        this.updateCache(ConfigGroupEnum.PLUGIN, 
namespacePluginService.listAll(namespaceId), namespaceId);
     }
-    
+
     /**
      * Update app auth cache.
      */
-    protected void updateAppAuthCache() {
-        this.updateCache(ConfigGroupEnum.APP_AUTH, appAuthService.listAll());
+    protected void updateAppAuthCache(final String namespaceId) {
+        this.updateCache(ConfigGroupEnum.APP_AUTH, appAuthService.listAll(), 
namespaceId);
     }
-    
+
     /**
      * Update meta data cache.
      */
-    protected void updateMetaDataCache() {
-        this.updateCache(ConfigGroupEnum.META_DATA, metaDataService.listAll());
+    protected void updateMetaDataCache(final String namespaceId) {
+        this.updateCache(ConfigGroupEnum.META_DATA, metaDataService.listAll(), 
namespaceId);
     }
 
-    protected void updateProxySelectorDataCache() {
-        this.updateCache(ConfigGroupEnum.PROXY_SELECTOR, 
proxySelectorService.listAll());
+    protected void updateProxySelectorDataCache(final String namespaceId) {
+        this.updateCache(ConfigGroupEnum.PROXY_SELECTOR, 
proxySelectorService.listAll(), namespaceId);
     }
 
-    protected void updateDiscoveryUpstreamDataCache() {
-        this.updateCache(ConfigGroupEnum.DISCOVER_UPSTREAM, 
discoveryUpstreamService.listAll());
+    protected void updateDiscoveryUpstreamDataCache(final String namespaceId) {
+        this.updateCache(ConfigGroupEnum.DISCOVER_UPSTREAM, 
discoveryUpstreamService.listAll(), namespaceId);
     }
 
     private <T> ConfigData<T> buildConfigData(final ConfigDataCache config, 
final Class<T> dataType) {
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/ConfigDataCache.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/ConfigDataCache.java
index c399851b99..973839f1fd 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/ConfigDataCache.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/ConfigDataCache.java
@@ -31,6 +31,8 @@ public class ConfigDataCache {
     private final String json;
 
     private volatile long lastModifyTime;
+
+    private final String namespaceId;
     
     /**
      * Instantiates a new Config data cache.
@@ -40,11 +42,12 @@ public class ConfigDataCache {
      * @param md5            the md5
      * @param lastModifyTime the last modify time
      */
-    public ConfigDataCache(final String group, final String json, final String 
md5, final long lastModifyTime) {
+    public ConfigDataCache(final String group, final String json, final String 
md5, final long lastModifyTime, final String namespaceId) {
         this.group = group;
         this.json = json;
         this.md5 = md5;
         this.lastModifyTime = lastModifyTime;
+        this.namespaceId = namespaceId;
     }
     
     /**
@@ -94,6 +97,15 @@ public class ConfigDataCache {
         return json;
     }
 
+    /**
+     * Gets namespaceId.
+     *
+     * @return the namespaceId
+     */
+    public String getNamespaceId() {
+        return namespaceId;
+    }
+
     @Override
     public String toString() {
         return "{"
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEvent.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEvent.java
index 728668992c..e89105528e 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEvent.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/DataChangedEvent.java
@@ -42,9 +42,9 @@ public class DataChangedEvent extends ApplicationEvent {
     /**
      * Instantiates a new Data changed event.
      *
-     * @param groupKey the group key
-     * @param type     the type
-     * @param source   the source
+     * @param groupKey    the group key
+     * @param type        the type
+     * @param source      the source
      */
     public DataChangedEvent(final ConfigGroupEnum groupKey, final 
DataEventTypeEnum type, final List<?> source) {
         
super(source.stream().filter(Objects::nonNull).collect(Collectors.toList()));
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/http/HttpLongPollingDataChangedListener.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/http/HttpLongPollingDataChangedListener.java
index e9baa1c1f2..3a409f6763 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/http/HttpLongPollingDataChangedListener.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/http/HttpLongPollingDataChangedListener.java
@@ -46,20 +46,25 @@ import org.springframework.http.MediaType;
 import jakarta.servlet.AsyncContext;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
+import static 
org.apache.shenyu.common.constant.Constants.SYS_DEFAULT_NAMESPACE_ID;
+
 /**
  * HTTP long polling, which blocks the client's request thread
  * and informs the client of group information about data changes
@@ -82,7 +87,7 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
     /**
      * Blocked client.
      */
-    private final BlockingQueue<LongPollingClient> clients;
+    private final Map<String, BlockingQueue<LongPollingClient>> clientsMap;
 
     private final ScheduledExecutorService scheduler;
 
@@ -94,7 +99,7 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
      * @param httpSyncProperties the HttpSyncProperties
      */
     public HttpLongPollingDataChangedListener(final HttpSyncProperties 
httpSyncProperties) {
-        this.clients = new ArrayBlockingQueue<>(1024);
+        this.clientsMap = new ConcurrentHashMap<>();
         this.scheduler = new ScheduledThreadPoolExecutor(1,
                 ShenyuThreadFactory.create("long-polling", true));
         this.httpSyncProperties = httpSyncProperties;
@@ -126,7 +131,8 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
     public void doLongPolling(final HttpServletRequest request, final 
HttpServletResponse response) {
         // compare group md5
         List<ConfigGroupEnum> changedGroup = compareChangedGroup(request);
-        String clientIp = getRemoteIp(request);
+        final String clientIp = getRemoteIp(request);
+        final String namespaceId = getNamespaceId(request);
         // response immediately.
         if (CollectionUtils.isNotEmpty(changedGroup)) {
             this.generateResponse(response, changedGroup);
@@ -139,46 +145,47 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
         // AsyncContext.settimeout() does not timeout properly, so you have to 
control it yourself
         asyncContext.setTimeout(0L);
         // block client's thread.
-        scheduler.execute(new LongPollingClient(asyncContext, clientIp, 
HttpConstants.SERVER_MAX_HOLD_TIMEOUT));
+        scheduler.execute(new LongPollingClient(asyncContext, clientIp, 
HttpConstants.SERVER_MAX_HOLD_TIMEOUT, namespaceId));
     }
 
     @Override
-    protected void afterAppAuthChanged(final List<AppAuthData> changed, final 
DataEventTypeEnum eventType) {
-        scheduler.execute(new DataChangeTask(ConfigGroupEnum.APP_AUTH));
+    protected void afterAppAuthChanged(final List<AppAuthData> changed, final 
DataEventTypeEnum eventType, final String namespaceId) {
+        scheduler.execute(new DataChangeTask(ConfigGroupEnum.APP_AUTH, 
namespaceId));
     }
 
     @Override
-    protected void afterMetaDataChanged(final List<MetaData> changed, final 
DataEventTypeEnum eventType) {
-        scheduler.execute(new DataChangeTask(ConfigGroupEnum.META_DATA));
+    protected void afterMetaDataChanged(final List<MetaData> changed, final 
DataEventTypeEnum eventType, final String namespaceId) {
+        scheduler.execute(new DataChangeTask(ConfigGroupEnum.META_DATA, 
namespaceId));
     }
 
     @Override
-    protected void afterPluginChanged(final List<PluginData> changed, final 
DataEventTypeEnum eventType) {
-        scheduler.execute(new DataChangeTask(ConfigGroupEnum.PLUGIN));
+    protected void afterPluginChanged(final List<PluginData> changed, final 
DataEventTypeEnum eventType, final String namespaceId) {
+        scheduler.execute(new DataChangeTask(ConfigGroupEnum.PLUGIN, 
namespaceId));
     }
 
     @Override
-    protected void afterRuleChanged(final List<RuleData> changed, final 
DataEventTypeEnum eventType) {
-        scheduler.execute(new DataChangeTask(ConfigGroupEnum.RULE));
+    protected void afterRuleChanged(final List<RuleData> changed, final 
DataEventTypeEnum eventType, final String namespaceId) {
+        scheduler.execute(new DataChangeTask(ConfigGroupEnum.RULE, 
namespaceId));
     }
 
     @Override
-    protected void afterSelectorChanged(final List<SelectorData> changed, 
final DataEventTypeEnum eventType) {
-        scheduler.execute(new DataChangeTask(ConfigGroupEnum.SELECTOR));
+    protected void afterSelectorChanged(final List<SelectorData> changed, 
final DataEventTypeEnum eventType, final String namespaceId) {
+        scheduler.execute(new DataChangeTask(ConfigGroupEnum.SELECTOR, 
namespaceId));
     }
 
     @Override
-    protected void afterProxySelectorChanged(final List<ProxySelectorData> 
changed, final DataEventTypeEnum eventType) {
-        scheduler.execute(new DataChangeTask(ConfigGroupEnum.PROXY_SELECTOR));
+    protected void afterProxySelectorChanged(final List<ProxySelectorData> 
changed, final DataEventTypeEnum eventType, final String namespaceId) {
+        scheduler.execute(new DataChangeTask(ConfigGroupEnum.PROXY_SELECTOR, 
namespaceId));
     }
 
     @Override
-    protected void afterDiscoveryUpstreamDataChanged(final 
List<DiscoverySyncData> changed, final DataEventTypeEnum eventType) {
-        scheduler.execute(new 
DataChangeTask(ConfigGroupEnum.DISCOVER_UPSTREAM));
+    protected void afterDiscoveryUpstreamDataChanged(final 
List<DiscoverySyncData> changed, final DataEventTypeEnum eventType, final 
String namespaceId) {
+        scheduler.execute(new 
DataChangeTask(ConfigGroupEnum.DISCOVER_UPSTREAM, namespaceId));
     }
 
     private List<ConfigGroupEnum> compareChangedGroup(final HttpServletRequest 
request) {
         List<ConfigGroupEnum> changedGroup = new 
ArrayList<>(ConfigGroupEnum.values().length);
+        String namespaceId = getNamespaceId(request);
         for (ConfigGroupEnum group : ConfigGroupEnum.values()) {
             // md5,lastModifyTime
             String[] params = 
StringUtils.split(request.getParameter(group.name()), ',');
@@ -187,7 +194,8 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
             }
             String clientMd5 = params[0];
             long clientModifyTime = NumberUtils.toLong(params[1]);
-            ConfigDataCache serverCache = CACHE.get(group.name());
+
+            ConfigDataCache serverCache = CACHE.get(buildCacheKey(namespaceId, 
group.name()));
             // do check.
             if (this.checkCacheDelayAndUpdate(serverCache, clientMd5, 
clientModifyTime)) {
                 changedGroup.add(group);
@@ -196,6 +204,10 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
         return changedGroup;
     }
 
+    public static String buildCacheKey(final String namespaceId, final String 
group) {
+        return namespaceId + "_" + group;
+    }
+
     /**
      * check whether the client needs to update the cache.
      *
@@ -218,17 +230,20 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
         // the lastModifyTime before client, then the local cache needs to be 
updated.
         // Considering the concurrency problem, admin must lock,
         // otherwise it may cause the request from shenyu-web to update the 
cache concurrently, causing excessive db pressure
-        ConfigDataCache latest = CACHE.get(serverCache.getGroup());
+
+        String configDataCacheKey = 
buildCacheKey(serverCache.getNamespaceId(), serverCache.getGroup());
+
+        ConfigDataCache latest = CACHE.get(configDataCacheKey);
         if (latest != serverCache) {
             return !StringUtils.equals(clientMd5, latest.getMd5());
         }
         synchronized (this) {
-            latest = CACHE.get(serverCache.getGroup());
+            latest = CACHE.get(configDataCacheKey);
             if (latest != serverCache) {
                 return !StringUtils.equals(clientMd5, latest.getMd5());
             }
             super.refreshLocalCache();
-            latest = CACHE.get(serverCache.getGroup());
+            latest = CACHE.get(configDataCacheKey);
             return !StringUtils.equals(clientMd5, latest.getMd5());
         }
     }
@@ -267,6 +282,20 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
         return StringUtils.isBlank(header) ? request.getRemoteAddr() : header;
     }
 
+    /**
+     * get namespaceId.
+     *
+     * @param request the request
+     * @return the namespaceId
+     */
+    private static String getNamespaceId(final HttpServletRequest request) {
+        String namespaceId = SYS_DEFAULT_NAMESPACE_ID;
+        if (StringUtils.isNotEmpty(request.getParameter("namespaceId"))) {
+            namespaceId = request.getParameter("namespaceId");
+        }
+        return namespaceId;
+    }
+
     /**
      * When a group's data changes, the thread is created to notify the client 
asynchronously.
      */
@@ -282,24 +311,34 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
          */
         private final long changeTime = System.currentTimeMillis();
 
+        /**
+         * The namespaceId.
+         */
+        private final String namespaceId;
+
         /**
          * Instantiates a new Data change task.
          *
          * @param groupKey the group key
          */
-        DataChangeTask(final ConfigGroupEnum groupKey) {
+        DataChangeTask(final ConfigGroupEnum groupKey, final String 
namespaceId) {
             this.groupKey = groupKey;
+            this.namespaceId = namespaceId;
         }
 
         @Override
         public void run() {
-            if (clients.size() > httpSyncProperties.getNotifyBatchSize()) {
-                List<LongPollingClient> targetClients = new 
ArrayList<>(clients.size());
-                clients.drainTo(targetClients);
+            BlockingQueue<LongPollingClient> namespaceClients = 
clientsMap.get(namespaceId);
+            if (CollectionUtils.isEmpty(namespaceClients)) {
+                return;
+            }
+            if (namespaceClients.size() > 
httpSyncProperties.getNotifyBatchSize()) {
+                List<LongPollingClient> targetClients = new 
ArrayList<>(namespaceClients.size());
+                namespaceClients.drainTo(targetClients);
                 List<List<LongPollingClient>> partitionClients = 
Lists.partition(targetClients, httpSyncProperties.getNotifyBatchSize());
                 partitionClients.forEach(item -> scheduler.execute(() -> 
doRun(item)));
             } else {
-                doRun(clients);
+                doRun(namespaceClients);
             }
         }
 
@@ -337,6 +376,11 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
          */
         private final long timeoutTime;
 
+        /**
+         * The namespaceId.
+         */
+        private final String namespaceId;
+
         /**
          * The Async timeout future.
          */
@@ -349,22 +393,25 @@ public class HttpLongPollingDataChangedListener extends 
AbstractDataChangedListe
          * @param ip          the ip
          * @param timeoutTime the timeout time
          */
-        LongPollingClient(final AsyncContext ac, final String ip, final long 
timeoutTime) {
+        LongPollingClient(final AsyncContext ac, final String ip, final long 
timeoutTime, final String namespaceId) {
             this.asyncContext = ac;
             this.ip = ip;
             this.timeoutTime = timeoutTime;
+            this.namespaceId = namespaceId;
         }
 
         @Override
         public void run() {
             try {
+                BlockingQueue<LongPollingClient> namespaceClients = 
clientsMap.getOrDefault(namespaceId, new ArrayBlockingQueue<>(1024));
                 this.asyncTimeoutFuture = scheduler.schedule(() -> {
-                    clients.remove(LongPollingClient.this);
+                    namespaceClients.remove(LongPollingClient.this);
                     List<ConfigGroupEnum> changedGroups = 
compareChangedGroup((HttpServletRequest) asyncContext.getRequest());
                     sendResponse(changedGroups);
                     log.debug("LongPollingClient {} ", 
GsonUtils.getInstance().toJson(changedGroups));
                 }, timeoutTime, TimeUnit.MILLISECONDS);
-                clients.add(this);
+                namespaceClients.add(this);
+                clientsMap.put(namespaceId, namespaceClients);
             } catch (Exception ex) {
                 log.error("add long polling client error", ex);
             }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/NamespaceMapper.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/NamespaceMapper.java
index 06b16e6c9d..f9612d855f 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/NamespaceMapper.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/NamespaceMapper.java
@@ -64,7 +64,14 @@ public interface NamespaceMapper extends ExistProvider {
      * @param name name.
      * @return namespaceDOList
      */
-    List<NamespaceDO> selectAll(String name);
+    List<NamespaceDO> selectAllByName(String name);
+
+    /**
+     * selectAll.
+     *
+     * @return namespaceDOList
+     */
+    List<NamespaceDO> selectAll();
 
     /**
      * insert namespace.
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/RuleDO.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/RuleDO.java
index 4d0a102927..bddf298ece 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/RuleDO.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/RuleDO.java
@@ -329,6 +329,7 @@ public final class RuleDO extends BaseDO {
                 .matchRestful(ruleDO.getMatchRestful())
                 .conditionDataList(conditionDataList)
                 .beforeConditionDataList(beforeConditionDataList)
+                .namespaceId(ruleDO.getNamespaceId())
                 .build();
     }
 
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/NamespaceService.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/NamespaceService.java
index 9cc581d5b2..a5236284c4 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/NamespaceService.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/NamespaceService.java
@@ -65,4 +65,11 @@ public interface NamespaceService {
      * @return {@linkplain List}
      */
     List<NamespaceVO> list(String name);
+
+    /**
+     * find list of namespace.
+     *
+     * @return {@linkplain List}
+     */
+    List<NamespaceVO> listAll();
 }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryServiceImpl.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryServiceImpl.java
index ab4bcf7331..83a20e2b63 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryServiceImpl.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryServiceImpl.java
@@ -262,6 +262,7 @@ public class DiscoveryServiceImpl implements 
DiscoveryService {
                 proxySelectorDTO.setPluginName(d.getPluginName());
                 proxySelectorDTO.setName(selectorDO.getName());
                 proxySelectorDTO.setId(selectorDO.getId());
+                proxySelectorDTO.setNamespaceId(selectorDO.getNamespaceId());
                 DiscoveryHandlerDO discoveryHandlerDO = 
discoveryHandlerMapper.selectBySelectorId(selectorDO.getId());
                 
discoveryProcessor.createProxySelector(DiscoveryTransfer.INSTANCE.mapToDTO(discoveryHandlerDO),
 proxySelectorDTO);
                 
discoveryProcessor.fetchAll(DiscoveryTransfer.INSTANCE.mapToDTO(discoveryHandlerDO),
 proxySelectorDTO);
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/NamespaceServiceImpl.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/NamespaceServiceImpl.java
index 7adc399f4b..c647bf1eca 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/NamespaceServiceImpl.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/NamespaceServiceImpl.java
@@ -99,10 +99,17 @@ public class NamespaceServiceImpl implements 
NamespaceService {
 
     @Override
     public List<NamespaceVO> list(final String name) {
-        List<NamespaceDO> namespaceDOS = namespaceMapper.selectAll(name);
+        List<NamespaceDO> namespaceDOS = namespaceMapper.selectAllByName(name);
         return 
namespaceDOS.stream().map(NamespaceTransfer.INSTANCE::mapToVo).collect(Collectors.toList());
     }
 
+    @Override
+    public List<NamespaceVO> listAll() {
+        List<NamespaceDO> namespaceDOS = namespaceMapper.selectAll();
+        return 
namespaceDOS.stream().map(NamespaceTransfer.INSTANCE::mapToVo).collect(Collectors.toList());
+
+    }
+
     private NamespaceVO create(final NamespaceDTO namespaceDTO) {
         Timestamp currentTime = new Timestamp(System.currentTimeMillis());
         String id = UUIDUtils.getInstance().generateShortUuid();
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SelectorServiceImpl.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SelectorServiceImpl.java
index 9e7be95214..79f8974d50 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SelectorServiceImpl.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SelectorServiceImpl.java
@@ -295,10 +295,11 @@ public class SelectorServiceImpl implements 
SelectorService {
             
discoveryUpstreamMapper.deleteByDiscoveryHandlerId(discoveryHandlerDO.getId());
             DiscoveryDO discoveryDO = 
discoveryMapper.selectById(discoveryHandlerDO.getDiscoveryId());
             if (Objects.nonNull(discoveryDO)) {
-                DiscoveryProcessor discoveryProcessor = 
discoveryProcessorHolder.chooseProcessor(discoveryDO.getType());
+                final DiscoveryProcessor discoveryProcessor = 
discoveryProcessorHolder.chooseProcessor(discoveryDO.getType());
                 ProxySelectorDTO proxySelectorDTO = new ProxySelectorDTO();
                 proxySelectorDTO.setName(selector.getName());
                 
proxySelectorDTO.setPluginName(pluginMap.getOrDefault(selector.getId(), ""));
+                proxySelectorDTO.setNamespaceId(selector.getNamespaceId());
                 
discoveryProcessor.removeProxySelector(DiscoveryTransfer.INSTANCE.mapToDTO(discoveryHandlerDO),
 proxySelectorDTO);
                 if 
(DiscoveryLevel.SELECTOR.getCode().equals(discoveryDO.getLevel())) {
                     discoveryProcessor.removeDiscovery(discoveryDO);
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/UpstreamCheckService.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/UpstreamCheckService.java
index 0cd3e6573f..ac39f46d1c 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/UpstreamCheckService.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/UpstreamCheckService.java
@@ -432,6 +432,7 @@ public class UpstreamCheckService {
         discoverySyncData.setPluginName(pluginName);
         discoverySyncData.setSelectorId(selectorId);
         discoverySyncData.setSelectorName(selectorDO.getName());
+        discoverySyncData.setNamespaceId(selectorDO.getNamespaceId());
         LOG.debug("UpstreamCacheManager update selectorId={}|json={}", 
selectorId, GsonUtils.getGson().toJson(discoverySyncData));
         eventPublisher.publishEvent(new 
DataChangedEvent(ConfigGroupEnum.DISCOVER_UPSTREAM, DataEventTypeEnum.UPDATE, 
Collections.singletonList(discoverySyncData)));
     }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/transfer/DiscoveryTransfer.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/transfer/DiscoveryTransfer.java
index cec29e0c88..9209248e2d 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/transfer/DiscoveryTransfer.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/transfer/DiscoveryTransfer.java
@@ -229,6 +229,7 @@ public enum DiscoveryTransfer {
             proxySelectorData.setPluginName(data.getPluginName());
             proxySelectorData.setType(data.getType());
             proxySelectorData.setForwardPort(data.getForwardPort());
+            proxySelectorData.setNamespaceId(data.getNamespaceId());
             String props = data.getProps();
             Properties properties = GsonUtils.getInstance().fromJson(props, 
Properties.class);
             proxySelectorData.setProps(properties);
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/transfer/MetaDataTransfer.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/transfer/MetaDataTransfer.java
index 6f8dbaaaad..427ade08b6 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/transfer/MetaDataTransfer.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/transfer/MetaDataTransfer.java
@@ -149,6 +149,7 @@ public enum MetaDataTransfer {
                         .parameterTypes(v.getParameterTypes())
                         .rpcExt(v.getRpcExt())
                         .enabled(v.getEnabled())
+                        .namespaceId(v.getNamespaceId())
                         .build())
                 .orElse(null);
     }
diff --git a/shenyu-admin/src/main/resources/mappers/namespace-sqlmap.xml 
b/shenyu-admin/src/main/resources/mappers/namespace-sqlmap.xml
index b7802ce67a..6271aab533 100644
--- a/shenyu-admin/src/main/resources/mappers/namespace-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/namespace-sqlmap.xml
@@ -56,7 +56,7 @@
         WHERE namespace_id = #{namespaceId, jdbcType=VARCHAR}
     </select>
 
-    <select id="selectAll" 
resultType="org.apache.shenyu.admin.model.entity.NamespaceDO">
+    <select id="selectAllByName" 
resultType="org.apache.shenyu.admin.model.entity.NamespaceDO">
         SELECT
         <include refid="Base_Column_List"/>
         FROM namespace
@@ -67,6 +67,12 @@
         </where>
     </select>
 
+    <select id="selectAll" 
resultType="org.apache.shenyu.admin.model.entity.NamespaceDO">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM namespace
+    </select>
+
     <insert id="insert" keyColumn="id" keyProperty="id" useGeneratedKeys="true"
             parameterType="org.apache.shenyu.admin.model.entity.NamespaceDO">
         INSERT INTO namespace
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ConfigControllerTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ConfigControllerTest.java
index 5ff5c2c473..70a098994c 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ConfigControllerTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ConfigControllerTest.java
@@ -18,6 +18,8 @@
 package org.apache.shenyu.admin.controller;
 
 import 
org.apache.shenyu.admin.listener.http.HttpLongPollingDataChangedListener;
+import org.apache.shenyu.admin.model.vo.NamespaceVO;
+import org.apache.shenyu.admin.service.NamespaceService;
 import org.apache.shenyu.admin.utils.ShenyuResultMessage;
 import org.apache.shenyu.common.dto.ConfigData;
 import org.apache.shenyu.common.enums.ConfigGroupEnum;
@@ -36,8 +38,10 @@ import 
org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+
 import java.util.Collections;
 
+import static 
org.apache.shenyu.common.constant.Constants.SYS_DEFAULT_NAMESPACE_ID;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.core.Is.is;
 import static org.mockito.ArgumentMatchers.any;
@@ -62,6 +66,9 @@ public final class ConfigControllerTest {
     @Mock
     private HttpLongPollingDataChangedListener mockLongPollingListener;
 
+    @Mock
+    private NamespaceService namespaceService;
+
     @BeforeEach
     public void setUp() {
         this.mockMvc = 
MockMvcBuilders.standaloneSetup(configController).build();
@@ -71,12 +78,14 @@ public final class ConfigControllerTest {
     public void testFetchConfigs() throws Exception {
         // Configure HttpLongPollingDataChangedListener.fetchConfig(...).
         final ConfigData<?> configData = new ConfigData<>("md5-value1", 0L, 
Collections.emptyList());
-        
doReturn(configData).when(mockLongPollingListener).fetchConfig(ConfigGroupEnum.APP_AUTH);
-
+        final NamespaceVO namespaceVO = new NamespaceVO();
+        
doReturn(configData).when(mockLongPollingListener).fetchConfig(ConfigGroupEnum.APP_AUTH,
 SYS_DEFAULT_NAMESPACE_ID);
+        
doReturn(namespaceVO).when(namespaceService).findById(SYS_DEFAULT_NAMESPACE_ID);
         // Run the test
         final MockHttpServletResponse response = 
mockMvc.perform(get("/configs/fetch")
-                .param("groupKeys", new 
String[]{ConfigGroupEnum.APP_AUTH.toString()})
-                .accept(MediaType.APPLICATION_JSON))
+                        .param("groupKeys", new 
String[]{ConfigGroupEnum.APP_AUTH.toString()})
+                        .param("namespaceId", SYS_DEFAULT_NAMESPACE_ID)
+                        .accept(MediaType.APPLICATION_JSON))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$.message", 
is(ShenyuResultMessage.SUCCESS)))
                 .andExpect(jsonPath("$.data['APP_AUTH'].md5", 
is("md5-value1")))
@@ -90,7 +99,7 @@ public final class ConfigControllerTest {
     public void testListener() throws Exception {
         // Run the test
         final MockHttpServletResponse response = 
mockMvc.perform(post("/configs/listener")
-                .accept(MediaType.APPLICATION_JSON))
+                        .accept(MediaType.APPLICATION_JSON))
                 .andReturn().getResponse();
 
         // Verify the results
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/AbstractDataChangedListenerTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/AbstractDataChangedListenerTest.java
index 9c3f492331..abcf5d1424 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/AbstractDataChangedListenerTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/AbstractDataChangedListenerTest.java
@@ -18,10 +18,13 @@
 package org.apache.shenyu.admin.listener;
 
 import com.google.common.collect.Lists;
+import 
org.apache.shenyu.admin.listener.http.HttpLongPollingDataChangedListener;
+import org.apache.shenyu.admin.model.vo.NamespaceVO;
 import org.apache.shenyu.admin.service.AppAuthService;
 import org.apache.shenyu.admin.service.DiscoveryUpstreamService;
 import org.apache.shenyu.admin.service.MetaDataService;
 import org.apache.shenyu.admin.service.NamespacePluginService;
+import org.apache.shenyu.admin.service.NamespaceService;
 import org.apache.shenyu.admin.service.ProxySelectorService;
 import org.apache.shenyu.admin.service.RuleService;
 import org.apache.shenyu.admin.service.SelectorService;
@@ -40,9 +43,11 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import java.lang.reflect.Field;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ConcurrentMap;
 
+import static 
org.apache.shenyu.common.constant.Constants.SYS_DEFAULT_NAMESPACE_ID;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -70,6 +75,8 @@ public final class AbstractDataChangedListenerTest {
 
     private DiscoveryUpstreamService discoveryUpstreamService;
 
+    private NamespaceService namespaceService;
+
     @BeforeEach
     public void setUp() throws Exception {
         listener = new MockAbstractDataChangedListener();
@@ -80,6 +87,7 @@ public final class AbstractDataChangedListenerTest {
         metaDataService = mock(MetaDataService.class);
         proxySelectorService = mock(ProxySelectorService.class);
         discoveryUpstreamService = mock(DiscoveryUpstreamService.class);
+        namespaceService = mock(NamespaceService.class);
 
         Class clazz = MockAbstractDataChangedListener.class.getSuperclass();
         Field appAuthServiceField = clazz.getDeclaredField("appAuthService");
@@ -103,11 +111,14 @@ public final class AbstractDataChangedListenerTest {
         Field discoveryUpstreamServiceField = 
clazz.getDeclaredField("discoveryUpstreamService");
         discoveryUpstreamServiceField.setAccessible(true);
         discoveryUpstreamServiceField.set(listener, discoveryUpstreamService);
+        Field namespaceServiceField = 
clazz.getDeclaredField("namespaceService");
+        namespaceServiceField.setAccessible(true);
+        namespaceServiceField.set(listener, namespaceService);
 
         List<AppAuthData> appAuthDatas = 
Lists.newArrayList(mock(AppAuthData.class));
         when(appAuthService.listAll()).thenReturn(appAuthDatas);
         List<PluginData> pluginDatas = 
Lists.newArrayList(mock(PluginData.class));
-        when(namespacePluginService.listAll()).thenReturn(pluginDatas);
+        
when(namespacePluginService.listAll(SYS_DEFAULT_NAMESPACE_ID)).thenReturn(pluginDatas);
         List<RuleData> ruleDatas = Lists.newArrayList(mock(RuleData.class));
         when(ruleService.listAll()).thenReturn(ruleDatas);
         List<SelectorData> selectorDatas = 
Lists.newArrayList(mock(SelectorData.class));
@@ -118,7 +129,12 @@ public final class AbstractDataChangedListenerTest {
         when(proxySelectorService.listAll()).thenReturn(proxySelectorDatas);
         List<DiscoverySyncData> discoverySyncDatas = 
Lists.newArrayList(mock(DiscoverySyncData.class));
         
when(discoveryUpstreamService.listAll()).thenReturn(discoverySyncDatas);
-        
+        List<NamespaceVO> list = new ArrayList<>();
+        NamespaceVO namespaceVO = new NamespaceVO();
+        namespaceVO.setNamespaceId(SYS_DEFAULT_NAMESPACE_ID);
+        list.add(namespaceVO);
+        when(namespaceService.listAll()).thenReturn(list);
+
         // clear first
         listener.getCache().clear();
     }
@@ -131,28 +147,28 @@ public final class AbstractDataChangedListenerTest {
     @Test
     public void testFetchConfig() {
         List<AppAuthData> appAuthDatas = 
Lists.newArrayList(mock(AppAuthData.class));
-        listener.updateCache(ConfigGroupEnum.APP_AUTH, appAuthDatas);
-        ConfigData<?> result1 = listener.fetchConfig(ConfigGroupEnum.APP_AUTH);
+        listener.updateCache(ConfigGroupEnum.APP_AUTH, appAuthDatas, 
SYS_DEFAULT_NAMESPACE_ID);
+        ConfigData<?> result1 = listener.fetchConfig(ConfigGroupEnum.APP_AUTH, 
SYS_DEFAULT_NAMESPACE_ID);
         assertNotNull(result1);
 
         List<PluginData> pluginDatas = 
Lists.newArrayList(mock(PluginData.class));
-        listener.updateCache(ConfigGroupEnum.PLUGIN, pluginDatas);
-        ConfigData<?> result2 = listener.fetchConfig(ConfigGroupEnum.PLUGIN);
+        listener.updateCache(ConfigGroupEnum.PLUGIN, pluginDatas, 
SYS_DEFAULT_NAMESPACE_ID);
+        ConfigData<?> result2 = listener.fetchConfig(ConfigGroupEnum.PLUGIN, 
SYS_DEFAULT_NAMESPACE_ID);
         assertNotNull(result2);
 
         List<RuleData> ruleDatas = Lists.newArrayList(mock(RuleData.class));
-        listener.updateCache(ConfigGroupEnum.RULE, ruleDatas);
-        ConfigData<?> result3 = listener.fetchConfig(ConfigGroupEnum.RULE);
+        listener.updateCache(ConfigGroupEnum.RULE, ruleDatas, 
SYS_DEFAULT_NAMESPACE_ID);
+        ConfigData<?> result3 = listener.fetchConfig(ConfigGroupEnum.RULE, 
SYS_DEFAULT_NAMESPACE_ID);
         assertNotNull(result3);
 
         List<SelectorData> selectorDatas = 
Lists.newArrayList(mock(SelectorData.class));
-        listener.updateCache(ConfigGroupEnum.SELECTOR, selectorDatas);
-        ConfigData<?> result4 = listener.fetchConfig(ConfigGroupEnum.SELECTOR);
+        listener.updateCache(ConfigGroupEnum.SELECTOR, selectorDatas, 
SYS_DEFAULT_NAMESPACE_ID);
+        ConfigData<?> result4 = listener.fetchConfig(ConfigGroupEnum.SELECTOR, 
SYS_DEFAULT_NAMESPACE_ID);
         assertNotNull(result4);
 
         List<MetaData> metaDatas = Lists.newArrayList(mock(MetaData.class));
-        listener.updateCache(ConfigGroupEnum.META_DATA, metaDatas);
-        ConfigData<?> result5 = 
listener.fetchConfig(ConfigGroupEnum.META_DATA);
+        listener.updateCache(ConfigGroupEnum.META_DATA, metaDatas, 
SYS_DEFAULT_NAMESPACE_ID);
+        ConfigData<?> result5 = 
listener.fetchConfig(ConfigGroupEnum.META_DATA, SYS_DEFAULT_NAMESPACE_ID);
         assertNotNull(result5);
     }
 
@@ -161,10 +177,10 @@ public final class AbstractDataChangedListenerTest {
         List<AppAuthData> empty = Lists.newArrayList();
         DataEventTypeEnum eventType = mock(DataEventTypeEnum.class);
         listener.onAppAuthChanged(empty, eventType);
-        
assertFalse(listener.getCache().containsKey(ConfigGroupEnum.APP_AUTH.name()));
+        
assertFalse(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.APP_AUTH.name())));
         List<AppAuthData> appAuthDatas = 
Lists.newArrayList(mock(AppAuthData.class));
         listener.onAppAuthChanged(appAuthDatas, eventType);
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.APP_AUTH.name()));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.APP_AUTH.name())));
     }
 
     @Test
@@ -172,10 +188,10 @@ public final class AbstractDataChangedListenerTest {
         List<MetaData> empty = Lists.newArrayList();
         DataEventTypeEnum eventType = mock(DataEventTypeEnum.class);
         listener.onMetaDataChanged(empty, eventType);
-        
assertFalse(listener.getCache().containsKey(ConfigGroupEnum.META_DATA.name()));
+        
assertFalse(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.META_DATA.name())));
         List<MetaData> metaDatas = Lists.newArrayList(mock(MetaData.class));
         listener.onMetaDataChanged(metaDatas, eventType);
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.META_DATA.name()));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.META_DATA.name())));
     }
 
     @Test
@@ -183,10 +199,13 @@ public final class AbstractDataChangedListenerTest {
         List<PluginData> empty = Lists.newArrayList();
         DataEventTypeEnum eventType = mock(DataEventTypeEnum.class);
         listener.onPluginChanged(empty, eventType);
-        
assertFalse(listener.getCache().containsKey(ConfigGroupEnum.PLUGIN.name()));
+        
assertFalse(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.PLUGIN.name())));
         List<PluginData> pluginDatas = 
Lists.newArrayList(mock(PluginData.class));
+        PluginData pluginData = new PluginData();
+        pluginData.setNamespaceId(SYS_DEFAULT_NAMESPACE_ID);
+        pluginDatas.set(0, pluginData);
         listener.onPluginChanged(pluginDatas, eventType);
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.PLUGIN.name()));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.PLUGIN.name())));
     }
 
     @Test
@@ -194,10 +213,10 @@ public final class AbstractDataChangedListenerTest {
         List<RuleData> empty = Lists.newArrayList();
         DataEventTypeEnum eventType = mock(DataEventTypeEnum.class);
         listener.onRuleChanged(empty, eventType);
-        
assertFalse(listener.getCache().containsKey(ConfigGroupEnum.RULE.name()));
+        
assertFalse(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.RULE.name())));
         List<RuleData> ruleDatas = Lists.newArrayList(mock(RuleData.class));
         listener.onRuleChanged(ruleDatas, eventType);
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.RULE.name()));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.RULE.name())));
     }
 
     @Test
@@ -205,27 +224,27 @@ public final class AbstractDataChangedListenerTest {
         List<SelectorData> empty = Lists.newArrayList();
         DataEventTypeEnum eventType = mock(DataEventTypeEnum.class);
         listener.onSelectorChanged(empty, eventType);
-        
assertFalse(listener.getCache().containsKey(ConfigGroupEnum.SELECTOR.name()));
+        
assertFalse(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.SELECTOR.name())));
         List<SelectorData> selectorDatas = 
Lists.newArrayList(mock(SelectorData.class));
         listener.onSelectorChanged(selectorDatas, eventType);
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.SELECTOR.name()));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.SELECTOR.name())));
     }
 
     @Test
     public void testAfterPropertiesSet() {
         listener.afterPropertiesSet();
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.APP_AUTH.name()));
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.PLUGIN.name()));
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.RULE.name()));
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.SELECTOR.name()));
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.META_DATA.name()));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.APP_AUTH.name())));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.PLUGIN.name())));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.RULE.name())));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.SELECTOR.name())));
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.META_DATA.name())));
     }
 
     @Test
     public void testUpdateCache() {
         List<AppAuthData> appAuthDatas = 
Lists.newArrayList(mock(AppAuthData.class));
-        listener.updateCache(ConfigGroupEnum.APP_AUTH, appAuthDatas);
-        
assertTrue(listener.getCache().containsKey(ConfigGroupEnum.APP_AUTH.name()));
+        listener.updateCache(ConfigGroupEnum.APP_AUTH, appAuthDatas, 
SYS_DEFAULT_NAMESPACE_ID);
+        
assertTrue(listener.getCache().containsKey(HttpLongPollingDataChangedListener.buildCacheKey(SYS_DEFAULT_NAMESPACE_ID,
 ConfigGroupEnum.APP_AUTH.name())));
     }
 
     static class MockAbstractDataChangedListener extends 
AbstractDataChangedListener {
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/ConfigDataCacheTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/ConfigDataCacheTest.java
index de4601058e..eb5f160f42 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/ConfigDataCacheTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/listener/ConfigDataCacheTest.java
@@ -31,7 +31,8 @@ public final class ConfigDataCacheTest {
         String group = "default";
         String json = "{\"name\":\"shenyu\"}";
         String md51 = "8e8a3a2fdbd4368f169aa88c5fdce5a1";
-        ConfigDataCache cache = new ConfigDataCache(group, json, md51, 0);
+        String namespaceId = "649330b6-c2d7-4edc-be8e-8a54df9eb385";
+        ConfigDataCache cache = new ConfigDataCache(group, json, md51, 0, 
namespaceId);
         assertEquals(cache.getMd5(), md51);
         assertEquals(cache.getJson(), json);
         assertEquals(cache.getGroup(), group);
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
index d39379bd82..13dc09c8c3 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
@@ -70,9 +70,9 @@ public class ShenyuConfig {
     private SpringCloudCacheConfig springCloudCache = new 
SpringCloudCacheConfig();
     
     private AlertConfig alert = new AlertConfig();
-    
+
     private String namespace = Constants.SYS_DEFAULT_NAMESPACE_ID;
-    
+
     /**
      * shenyu bootstrap namespace.
      *
@@ -81,7 +81,7 @@ public class ShenyuConfig {
     public String getNamespace() {
         return namespace;
     }
-    
+
     /**
      * Set shenyu bootstrap namespace, default value is {@link 
org.apache.shenyu.common.constant.Constants#SYS_DEFAULT_NAMESPACE_ID}.
      *
@@ -90,7 +90,7 @@ public class ShenyuConfig {
     public void setNamespace(final String namespace) {
         this.namespace = namespace;
     }
-    
+
     /**
      * Gets health.
      *
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/ProxySelectorData.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/ProxySelectorData.java
index 0f28eedbb2..1ab2bc6759 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/ProxySelectorData.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/ProxySelectorData.java
@@ -36,6 +36,8 @@ public class ProxySelectorData {
 
     private Properties props = new Properties();
 
+    private String namespaceId;
+
     /**
      * getId.
      *
@@ -144,4 +146,22 @@ public class ProxySelectorData {
         this.props = props;
     }
 
+    /**
+     * get namespaceId.
+     *
+     * @return namespaceId
+     */
+    public String getNamespaceId() {
+        return namespaceId;
+    }
+
+    /**
+     * set namespaceId.
+     *
+     * @param namespaceId namespaceId
+     */
+    public void setNamespaceId(final String namespaceId) {
+        this.namespaceId = namespaceId;
+    }
+
 }
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-http/src/main/java/org/apache/shenyu/springboot/starter/sync/data/http/HttpSyncDataConfiguration.java
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-http/src/main/java/org/apache/shenyu/springboot/starter/sync/data/http/HttpSyncDataConfiguration.java
index 8bc3059848..624bb7e5b6 100644
--- 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-http/src/main/java/org/apache/shenyu/springboot/starter/sync/data/http/HttpSyncDataConfiguration.java
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-http/src/main/java/org/apache/shenyu/springboot/starter/sync/data/http/HttpSyncDataConfiguration.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.springboot.starter.sync.data.http;
 
+import org.apache.shenyu.common.config.ShenyuConfig;
 import org.apache.shenyu.common.constant.HttpConstants;
 import org.apache.shenyu.sync.data.api.AuthDataSubscriber;
 import org.apache.shenyu.sync.data.api.MetaDataSubscriber;
@@ -103,6 +104,7 @@ public class HttpSyncDataConfiguration {
      * @param accessTokenManager the access token manager
      * @param proxySelectorDataSubscribers the proxySelectorData subscribers
      * @param discoveryUpstreamDataSubscribers the discoveryUpstreamData 
subscribers
+     * @param shenyuConfig       the shenyuConfig
      * @return the sync data service
      */
     @Bean
@@ -113,7 +115,8 @@ public class HttpSyncDataConfiguration {
                                                final 
ObjectProvider<List<AuthDataSubscriber>> authSubscribers,
                                                final 
ObjectProvider<AccessTokenManager> accessTokenManager,
                                                final 
ObjectProvider<List<ProxySelectorDataSubscriber>> proxySelectorDataSubscribers,
-                                               final 
ObjectProvider<List<DiscoveryUpstreamDataSubscriber>> 
discoveryUpstreamDataSubscribers) {
+                                               final 
ObjectProvider<List<DiscoveryUpstreamDataSubscriber>> 
discoveryUpstreamDataSubscribers,
+                                               final 
ObjectProvider<ShenyuConfig> shenyuConfig) {
         LOGGER.info("you use http long pull sync shenyu data");
         return new HttpSyncDataService(
                 Objects.requireNonNull(httpConfig.getIfAvailable()),
@@ -123,7 +126,8 @@ public class HttpSyncDataConfiguration {
                 authSubscribers.getIfAvailable(Collections::emptyList),
                 
proxySelectorDataSubscribers.getIfAvailable(Collections::emptyList),
                 
discoveryUpstreamDataSubscribers.getIfAvailable(Collections::emptyList),
-                Objects.requireNonNull(accessTokenManager.getIfAvailable())
+                Objects.requireNonNull(accessTokenManager.getIfAvailable()),
+                Objects.requireNonNull(shenyuConfig.getIfAvailable())
         );
     }
 }
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-http/src/test/java/org/apache/shenyu/springboot/starter/sync/data/http/HttpClientPluginConfigurationTest.java
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-http/src/test/java/org/apache/shenyu/springboot/starter/sync/data/http/HttpClientPluginConfigurationTest.java
index 2a6240b7fb..d99298f6e9 100644
--- 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-http/src/test/java/org/apache/shenyu/springboot/starter/sync/data/http/HttpClientPluginConfigurationTest.java
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-http/src/test/java/org/apache/shenyu/springboot/starter/sync/data/http/HttpClientPluginConfigurationTest.java
@@ -18,6 +18,7 @@
 package org.apache.shenyu.springboot.starter.sync.data.http;
 
 import com.github.tomakehurst.wiremock.WireMockServer;
+import org.apache.shenyu.common.config.ShenyuConfig;
 import org.apache.shenyu.common.exception.CommonErrorCode;
 import org.apache.shenyu.common.utils.GsonUtils;
 import org.apache.shenyu.sync.data.api.PluginDataSubscriber;
@@ -68,7 +69,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
                 "spring.main.web-application-type=none"
         })
 @EnableAutoConfiguration
-@MockBean({PluginDataSubscriber.class, ServletWebServerFactory.class})
+@MockBean({PluginDataSubscriber.class, ServletWebServerFactory.class, 
ShenyuConfig.class})
 public final class HttpClientPluginConfigurationTest {
 
     @Autowired
diff --git 
a/shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java
 
b/shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java
index 509bd12b51..1c268e90c0 100644
--- 
a/shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java
+++ 
b/shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java
@@ -21,8 +21,15 @@ import com.google.common.base.Splitter;
 import com.google.common.collect.Lists;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
+import okhttp3.Headers;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.config.ShenyuConfig;
 import org.apache.shenyu.common.constant.Constants;
 import org.apache.shenyu.common.dto.ConfigData;
 import org.apache.shenyu.common.enums.ConfigGroupEnum;
@@ -30,11 +37,11 @@ import org.apache.shenyu.common.exception.ShenyuException;
 import org.apache.shenyu.common.utils.GsonUtils;
 import org.apache.shenyu.common.utils.ThreadUtils;
 import org.apache.shenyu.sync.data.api.AuthDataSubscriber;
+import org.apache.shenyu.sync.data.api.DiscoveryUpstreamDataSubscriber;
 import org.apache.shenyu.sync.data.api.MetaDataSubscriber;
 import org.apache.shenyu.sync.data.api.PluginDataSubscriber;
-import org.apache.shenyu.sync.data.api.SyncDataService;
 import org.apache.shenyu.sync.data.api.ProxySelectorDataSubscriber;
-import org.apache.shenyu.sync.data.api.DiscoveryUpstreamDataSubscriber;
+import org.apache.shenyu.sync.data.api.SyncDataService;
 import org.apache.shenyu.sync.data.http.config.HttpConfig;
 import org.apache.shenyu.sync.data.http.refresh.DataRefreshFactory;
 import org.slf4j.Logger;
@@ -53,12 +60,6 @@ import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
-import okhttp3.Headers;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.RequestBody;
-import okhttp3.Response;
-import okhttp3.ResponseBody;
 
 /**
  * HTTP long polling implementation.
@@ -79,9 +80,11 @@ public class HttpSyncDataService implements SyncDataService {
     private final DataRefreshFactory factory;
 
     private final AccessTokenManager accessTokenManager;
-    
+
     private final OkHttpClient okHttpClient;
 
+    private final ShenyuConfig shenyuConfig;
+
     public HttpSyncDataService(final HttpConfig httpConfig,
                                final PluginDataSubscriber pluginDataSubscriber,
                                final OkHttpClient okHttpClient,
@@ -89,11 +92,13 @@ public class HttpSyncDataService implements SyncDataService 
{
                                final List<AuthDataSubscriber> 
authDataSubscribers,
                                final List<ProxySelectorDataSubscriber> 
proxySelectorDataSubscribers,
                                final List<DiscoveryUpstreamDataSubscriber> 
discoveryUpstreamDataSubscribers,
-                               final AccessTokenManager accessTokenManager) {
+                               final AccessTokenManager accessTokenManager,
+                               final ShenyuConfig shenyuConfig) {
         this.accessTokenManager = accessTokenManager;
         this.factory = new DataRefreshFactory(pluginDataSubscriber, 
metaDataSubscribers, authDataSubscribers, proxySelectorDataSubscribers, 
discoveryUpstreamDataSubscribers);
         this.serverList = 
Lists.newArrayList(Splitter.on(",").split(httpConfig.getUrl()));
         this.okHttpClient = okHttpClient;
+        this.shenyuConfig = shenyuConfig;
         this.start();
     }
 
@@ -134,6 +139,7 @@ public class HttpSyncDataService implements SyncDataService 
{
         for (ConfigGroupEnum groupKey : groups) {
             
params.append("groupKeys").append("=").append(groupKey.name()).append("&");
         }
+        
params.append("namespaceId").append("=").append(shenyuConfig.getNamespace());
         String url = server + Constants.SHENYU_ADMIN_PATH_CONFIGS_FETCH + "?" 
+ StringUtils.removeEnd(params.toString(), "&");
         LOG.info("request configs: [{}]", url);
         String json;
@@ -188,6 +194,7 @@ public class HttpSyncDataService implements SyncDataService 
{
                 params.put(group.name(), Lists.newArrayList(value));
             }
         }
+        params.put("namespaceId", 
Lists.newArrayList(shenyuConfig.getNamespace()));
         LOG.debug("listener params: [{}]", params);
         Headers headers = new Headers.Builder()
                 .add(Constants.X_ACCESS_TOKEN, 
this.accessTokenManager.getAccessToken())
@@ -217,7 +224,7 @@ public class HttpSyncDataService implements SyncDataService 
{
             String message = String.format("listener configs fail, 
server:[%s], %s", server, e.getMessage());
             throw new ShenyuException(message, e);
         }
-        
+
         if (Objects.nonNull(groupJson) && !groupJson.isEmpty()) {
             // fetch group configuration async.
             ConfigGroupEnum[] changedGroups = 
GsonUtils.getGson().fromJson(groupJson, ConfigGroupEnum[].class);
diff --git 
a/shenyu-sync-data-center/shenyu-sync-data-http/src/test/java/org/apache/shenyu/sync/data/http/HttpSyncDataServiceTest.java
 
b/shenyu-sync-data-center/shenyu-sync-data-http/src/test/java/org/apache/shenyu/sync/data/http/HttpSyncDataServiceTest.java
index 6a9ae130c5..545369b6d5 100644
--- 
a/shenyu-sync-data-center/shenyu-sync-data-http/src/test/java/org/apache/shenyu/sync/data/http/HttpSyncDataServiceTest.java
+++ 
b/shenyu-sync-data-center/shenyu-sync-data-http/src/test/java/org/apache/shenyu/sync/data/http/HttpSyncDataServiceTest.java
@@ -19,6 +19,7 @@ package org.apache.shenyu.sync.data.http;
 
 import com.github.tomakehurst.wiremock.WireMockServer;
 import 
com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
+import org.apache.shenyu.common.config.ShenyuConfig;
 import org.apache.shenyu.common.constant.HttpConstants;
 import org.apache.shenyu.common.dto.ConfigData;
 import org.apache.shenyu.common.dto.PluginData;
@@ -84,6 +85,8 @@ public final class HttpSyncDataServiceTest {
 
     private HttpSyncDataService httpSyncDataService;
 
+    private ShenyuConfig shenyuConfig;
+
     @BeforeEach
     public void before() {
         this.wireMockServer = new WireMockServer(
@@ -123,6 +126,7 @@ public final class HttpSyncDataServiceTest {
         this.authDataSubscriber = mock(AuthDataSubscriber.class);
         this.proxySelectorDataSubscriber = 
mock(ProxySelectorDataSubscriber.class);
         this.discoveryUpstreamDataSubscriber = 
mock(DiscoveryUpstreamDataSubscriber.class);
+        this.shenyuConfig = mock(ShenyuConfig.class);
 
         OkHttpClient okHttpClient = new OkHttpClient.Builder()
                 
.readTimeout(Duration.ofMillis(Objects.isNull(httpConfig.getReadTimeout()) ? 
(int) HttpConstants.CLIENT_POLLING_READ_TIMEOUT : httpConfig.getReadTimeout()))
@@ -133,7 +137,7 @@ public final class HttpSyncDataServiceTest {
         AccessTokenManager accessTokenManager = new 
AccessTokenManager(okHttpClient, httpConfig);
         this.httpSyncDataService = new HttpSyncDataService(httpConfig, 
pluginDataSubscriber, new OkHttpClient(),
                 Collections.singletonList(metaDataSubscriber), 
Collections.singletonList(authDataSubscriber), 
Collections.singletonList(proxySelectorDataSubscriber),
-                Collections.singletonList(discoveryUpstreamDataSubscriber), 
accessTokenManager);
+                Collections.singletonList(discoveryUpstreamDataSubscriber), 
accessTokenManager, shenyuConfig);
     }
 
     @AfterEach

Reply via email to