assign provider namespace https://github.com/apache/dubbo/issues/10637 (#10686)

Co-authored-by: niejian <niejian@bluemoon.com.cn>
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java
index 622780a..398ab32 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java
@@ -110,6 +110,13 @@
     String PROVIDER_PORT = "provider-port";
 
     /**
+     * provider namespace
+     *
+     * @since 3.1.1
+     */
+    String PROVIDER_NAMESPACE = "provider-namespace";
+
+    /**
      * The request size of service instances
      *
      * @since 2.7.5
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java
index f557f93..6ac7a43 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java
@@ -27,6 +27,7 @@
 import static org.apache.dubbo.common.constants.CommonConstants.ROUTER_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.STUB_EVENT_KEY;
 import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDED_BY;
+import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDER_NAMESPACE;
 import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDER_PORT;
 
 /**
@@ -90,6 +91,12 @@
      */
     protected Integer providerPort;
 
+    /**
+     * assign the namespace that provider belong to
+     * @since 3.1.1
+     */
+    protected String providerNamespace;
+
     protected String router;
 
     /**
@@ -275,6 +282,15 @@
         this.providerPort = providerPort;
     }
 
+    @Parameter(key = PROVIDER_NAMESPACE)
+    public String getProviderNamespace() {
+        return providerNamespace;
+    }
+
+    public void setProviderNamespace(String providerNamespace) {
+        this.providerNamespace = providerNamespace;
+    }
+
     @Parameter(key = ROUTER_KEY, append = true)
     public String getRouter() {
         return router;
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java
index 10afb4f..bcf4869 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java
@@ -357,6 +357,13 @@
     int providerPort() default -1;
 
     /**
+     * assign the namespace that provider belong to
+     * @see AbstractReferenceConfig#providerNamespace
+     * @since 3.1.1
+     */
+    String providerNamespace() default "";
+
+    /**
      * the scope for referring/exporting a service, if it's local, it means searching in current JVM only.
      *
      * @see org.apache.dubbo.rpc.Constants#SCOPE_LOCAL
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index 4f81b5d..478a50a 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -478,16 +478,21 @@
             }
             return;
         }
-        // get pod namespace
-        String podNamespace;
-        if (StringUtils.isEmpty(System.getenv("POD_NAMESPACE"))) {
-            if (logger.isWarnEnabled()) {
-                logger.warn(CONFIG_FAILED_LOAD_ENV_VARIABLE, "", "", "Can not get env variable: POD_NAMESPACE, it may not be running in the K8S environment , " +
-                    "finally use 'default' replace.");
+
+        // get provider namespace if (@DubboReference, <reference provider-namespace="xx"/>) present
+        String podNamespace = referenceParameters.get(RegistryConstants.PROVIDER_NAMESPACE);
+
+        // get pod namespace from env if annotation not present the provider namespace
+        if (StringUtils.isEmpty(podNamespace)) {
+            if (StringUtils.isEmpty(System.getenv("POD_NAMESPACE"))) {
+                if (logger.isWarnEnabled()) {
+                    logger.warn(CONFIG_FAILED_LOAD_ENV_VARIABLE, "", "", "Can not get env variable: POD_NAMESPACE, it may not be running in the K8S environment , " +
+                            "finally use 'default' replace.");
+                }
+                podNamespace = "default";
+            } else {
+                podNamespace = System.getenv("POD_NAMESPACE");
             }
-            podNamespace = "default";
-        } else {
-            podNamespace = System.getenv("POD_NAMESPACE");
         }
 
         // In mesh mode, providedBy equals K8S Service name.
diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd
index 99b34ee..eb92b4b 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd
@@ -245,6 +245,12 @@
                             <![CDATA[ declares provider service port. ]]></xsd:documentation>
                     </xsd:annotation>
                 </xsd:attribute>
+                <xsd:attribute name="provider-namespace" type="xsd:string">
+                    <xsd:annotation>
+                        <xsd:documentation>
+                            <![CDATA[ assign namespace that the provider belong to when mesh enable. ]]></xsd:documentation>
+                    </xsd:annotation>
+                </xsd:attribute>
                 <xsd:attribute name="router" type="xsd:string">
                     <xsd:annotation>
                         <xsd:documentation>
diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
index 10bc5c6..b475c79 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
@@ -245,6 +245,12 @@
                             <![CDATA[ declares provider service port. ]]></xsd:documentation>
                     </xsd:annotation>
                 </xsd:attribute>
+                <xsd:attribute name="provider-namespace" type="xsd:string">
+                    <xsd:annotation>
+                        <xsd:documentation>
+                            <![CDATA[ assign namespace that the provider belong to when mesh enable. ]]></xsd:documentation>
+                    </xsd:annotation>
+                </xsd:attribute>
                 <xsd:attribute name="router" type="xsd:string">
                     <xsd:annotation>
                         <xsd:documentation>