diff --git a/dubbo-config/dubbo-config-api/pom.xml b/dubbo-config/dubbo-config-api/pom.xml
index ef57efb4d9c3..0147c42c3ffc 100644
--- a/dubbo-config/dubbo-config-api/pom.xml
+++ b/dubbo-config/dubbo-config-api/pom.xml
@@ -239,6 +239,10 @@
test
+
+ commons-net
+ commons-net
+
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 98aab862d288..d372f542189b 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -37,6 +37,7 @@
import org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker;
import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
+import org.apache.dubbo.config.utils.SubnetUtil;
import org.apache.dubbo.metadata.ServiceNameMapping;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
@@ -713,9 +714,20 @@ private URL buildUrl(ProtocolConfig protocolConfig, Map params)
params.put(CommonConstants.IPV6_KEY, ipv6Host);
}
+ if (StringUtils.isBlank(getTag())) {
+ if (SubnetUtil.isEmpty()) {
+ String content = ConfigurationUtils.getCachedDynamicProperty(getScopeModel(), SubnetUtil.TAG_SUBNETS_KEY, null);
+ SubnetUtil.init(content);
+ }
+ if (!SubnetUtil.isEmpty()) {
+ String tagLevel = SubnetUtil.getTagLevelByHost(params.get(BIND_IP_KEY));
+ setTag(tagLevel);
+ params.put(CommonConstants.TAG_KEY, tagLevel);
+ }
+ }
+
Integer port = findConfiguredPort(protocolConfig, provider, this.getExtensionLoader(Protocol.class), name, params);
URL url = new ServiceConfigURL(name, null, null, host, port, getContextPath(protocolConfig).map(p -> p + "/" + path).orElse(path), params);
-
// You can customize Configurator to append extra parameters
if (this.getExtensionLoader(ConfiguratorFactory.class)
.hasExtension(url.getProtocol())) {
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/SubnetUtil.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/SubnetUtil.java
new file mode 100644
index 000000000000..85025bf729e3
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/SubnetUtil.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.utils;
+
+import org.apache.dubbo.common.utils.StringUtils;
+
+import org.apache.commons.net.util.SubnetUtils;
+import org.yaml.snakeyaml.LoaderOptions;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.SafeConstructor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+
+public class SubnetUtil {
+ public static final String TAG_SUBNETS_KEY = "tag.subnets";
+
+ private static Map> cellSubnets = new ConcurrentHashMap<>();
+ protected static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+ protected static final ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
+ protected static final ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
+
+ public static boolean isEmpty() {
+ try {
+ readLock.lock();
+ return cellSubnets.isEmpty();
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ public static void init(String content) {
+ if (StringUtils.isBlank(content)) {
+ return;
+ }
+ try {
+ writeLock.lock();
+ Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
+ cellSubnets = new HashMap<>();
+ Map> tmpPathSubnet = (Map>) yaml.load(content);
+ for (Map.Entry> entry : tmpPathSubnet.entrySet()) {
+ String path = entry.getKey();
+ List subnetInfos = cellSubnets.computeIfAbsent(path, f -> new ArrayList());
+ entry.getValue().forEach(e -> subnetInfos.add(new SubnetUtils(e.trim()).getInfo()));
+ }
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ public static String getTagLevelByHost(String host) {
+ try {
+ readLock.lock();
+ for (Map.Entry> entry : cellSubnets.entrySet()) {
+ for (SubnetUtils.SubnetInfo subnetInfo : entry.getValue()) {
+ if (subnetInfo.isInRange(host)) {
+ return entry.getKey();
+ }
+ }
+ }
+ return null;
+ } finally {
+ readLock.unlock();
+ }
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/SubnetUtilTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/SubnetUtilTest.java
new file mode 100644
index 000000000000..acdd798dc84f
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/SubnetUtilTest.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.utils;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class SubnetUtilTest {
+ @Test
+ public void testLoadContent() {
+ String content = "" +//
+ "cn|cn-northwest|cell-1: \n" +
+ "- 172.37.66.0/24 #cn-northwest-1a\n" +
+ "cn|cn-north|cell-2: \n" +
+ "- 172.37.67.0/24 #cn-northwest-1b\n" +
+ "\"\": \n" +
+ "- 172.37.33.0/24 #cn-north-1a\n";
+ SubnetUtil.init(content);
+ Assert.assertEquals(SubnetUtil.getTagLevelByHost("172.37.66.1"),"cn|cn-northwest|cell-1");
+ Assert.assertEquals(SubnetUtil.getTagLevelByHost("172.37.33.1"),"");
+ }
+}
diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index 21a83cddc3d9..fbfa053a5a45 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -131,6 +131,7 @@
2.1.0
2.0
3.12.0
+ 3.9.0
1.8.0
0.1.35
1.11.2
@@ -653,6 +654,11 @@
commons-lang3
${commons_lang3_version}
+
+ commons-net
+ commons-net
+ ${commons_net_version}
+
io.envoyproxy.controlplane
api