feat(11752): The contentPath of AddressServerUrl is not flexible. (#11754)

This commit is contained in:
blake.qiu 2024-03-07 11:39:52 +08:00 committed by GitHub
parent c2aa515f1e
commit 4397e8d275
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 233 additions and 61 deletions

View File

@ -33,6 +33,8 @@ public class PropertyKeyConst {
public static final String ENDPOINT_PORT = "endpointPort";
public static final String ENDPOINT_CONTEXT_PATH = "endpointContextPath";
public static final String SERVER_NAME = "serverName";
public static final String NAMESPACE = "namespace";
@ -94,6 +96,8 @@ public class PropertyKeyConst {
public static final String ALIBABA_ALIWARE_ENDPOINT_PORT = "ALIBABA_ALIWARE_ENDPOINT_PORT";
public static final String ALIBABA_ALIWARE_ENDPOINT_CONTEXT_PATH = "ALIBABA_ALIWARE_ENDPOINT_CONTEXT_PATH";
public static final String ALIBABA_ALIWARE_NAMESPACE = "ALIBABA_ALIWARE_NAMESPACE";
public static final String ALIBABA_ALIWARE_ENDPOINT_URL = "ALIBABA_ALIWARE_ENDPOINT_URL";

View File

@ -23,6 +23,7 @@ import com.alibaba.nacos.client.env.NacosClientProperties;
import com.alibaba.nacos.client.utils.ContextPathUtil;
import com.alibaba.nacos.client.utils.EnvUtil;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.common.executor.NameThreadFactory;
import com.alibaba.nacos.common.http.HttpRestResult;
@ -31,8 +32,8 @@ import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.Query;
import com.alibaba.nacos.common.lifecycle.Closeable;
import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.InternetAddressUtil;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.common.utils.ThreadUtils;
import org.slf4j.Logger;
@ -48,7 +49,6 @@ import java.util.StringTokenizer;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.alibaba.nacos.client.utils.ParamUtil;
import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTPS_PREFIX;
import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTP_PREFIX;
@ -82,21 +82,18 @@ public class ServerListManager implements Closeable {
public static final String FIXED_NAME = "fixed";
private final int initServerlistRetryTimes = 5;
/**
* Connection timeout and socket timeout with other servers.
*/
static final int TIMEOUT = 5000;
private final int initServerListRetryTimes = 5;
final boolean isFixed;
boolean isStarted = false;
boolean isStarted;
private String endpoint;
private int endpointPort = 8080;
private String endpointContextPath;
private String contentPath = ParamUtil.getDefaultContextPath();
private String serverListName = ParamUtil.getDefaultNodesPath();
@ -107,8 +104,6 @@ public class ServerListManager implements Closeable {
private Iterator<String> iterator;
public String serverPort = ParamUtil.getDefaultServerPort();
public String addressServerUrl;
private String serverAddrsStr;
@ -161,34 +156,24 @@ public class ServerListManager implements Closeable {
public ServerListManager(String endpoint, String namespace) throws NacosException {
this.isFixed = false;
this.isStarted = false;
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint);
final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
this.endpoint = initEndpoint(clientProperties);
if (StringUtils.isBlank(endpoint)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
}
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint);
final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
initParam(clientProperties);
if (StringUtils.isNotBlank(namespace)) {
this.namespace = namespace;
this.tenant = namespace;
}
this.name = initServerName(null);
initAddressServerUrl(clientProperties);
}
public ServerListManager(NacosClientProperties properties) throws NacosException {
this.isStarted = false;
this.serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
String namespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
initParam(properties);
if (StringUtils.isNotBlank(namespace)) {
this.namespace = namespace;
this.tenant = namespace;
}
if (StringUtils.isNotEmpty(serverAddrsStr)) {
this.isFixed = true;
List<String> serverAddrs = new ArrayList<>();
@ -209,7 +194,6 @@ public class ServerListManager implements Closeable {
}
this.serverUrls = serverAddrs;
this.name = initServerName(properties);
} else {
if (StringUtils.isBlank(endpoint)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
@ -218,7 +202,18 @@ public class ServerListManager implements Closeable {
this.name = initServerName(properties);
initAddressServerUrl(properties);
}
}
private void initNameSpace(NacosClientProperties properties) {
String namespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
if (StringUtils.isNotBlank(namespace)) {
this.namespace = namespace;
this.tenant = namespace;
}
}
private void initServerAddr(NacosClientProperties properties) {
this.serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
}
private String initServerName(NacosClientProperties properties) {
@ -227,20 +222,22 @@ public class ServerListManager implements Closeable {
if (properties != null && properties.containsKey(PropertyKeyConst.SERVER_NAME)) {
serverName = properties.getProperty(PropertyKeyConst.SERVER_NAME);
} else {
// if fix url,use fix url join string.
// if fix url, use fix url join string.
if (isFixed) {
serverName = FIXED_NAME + "-" + (StringUtils.isNotBlank(namespace) ? (StringUtils.trim(namespace) + "-")
: "") + getFixedNameSuffix(serverUrls.toArray(new String[0]));
} else {
//if use endpoint , use endpoint ,content path ,serverlist name
serverName = CUSTOM_NAME + "-" + String
.join("_", endpoint, String.valueOf(endpointPort), contentPath, serverListName) + (
StringUtils.isNotBlank(namespace) ? ("_" + StringUtils.trim(namespace)) : "");
//if use endpoint, use endpoint, content path, serverList name
String contextPathTmp =
StringUtils.isNotBlank(this.endpointContextPath) ? this.endpointContextPath : this.contentPath;
serverName =
CUSTOM_NAME + "-" + String.join("_", endpoint, String.valueOf(endpointPort), contextPathTmp,
serverListName) + (StringUtils.isNotBlank(namespace) ? ("_" + StringUtils.trim(
namespace)) : "");
}
}
serverName = serverName.replaceAll("\\/", "_");
serverName = serverName.replaceAll("\\:", "_");
return serverName;
}
@ -248,49 +245,69 @@ public class ServerListManager implements Closeable {
if (isFixed) {
return;
}
String contextPathTem = StringUtils.isNotBlank(this.endpointContextPath) ? ContextPathUtil.normalizeContextPath(
this.endpointContextPath) : ContextPathUtil.normalizeContextPath(this.contentPath);
StringBuilder addressServerUrlTem = new StringBuilder(
String.format("http://%s:%d%s/%s", this.endpoint, this.endpointPort,
ContextPathUtil.normalizeContextPath(this.contentPath), this.serverListName));
String.format("http://%s:%d%s/%s", this.endpoint, this.endpointPort, contextPathTem,
this.serverListName));
boolean hasQueryString = false;
if (StringUtils.isNotBlank(namespace)) {
addressServerUrlTem.append("?namespace=").append(namespace);
hasQueryString = true;
}
if (properties != null && properties.containsKey(PropertyKeyConst.ENDPOINT_QUERY_PARAMS)) {
addressServerUrlTem
.append(hasQueryString ? "&" : "?" + properties.getProperty(PropertyKeyConst.ENDPOINT_QUERY_PARAMS));
addressServerUrlTem.append(
hasQueryString ? "&" : "?" + properties.getProperty(PropertyKeyConst.ENDPOINT_QUERY_PARAMS));
}
this.addressServerUrl = addressServerUrlTem.toString();
LOGGER.info("serverName = {}, address server url = {}", this.name, this.addressServerUrl);
}
private void initParam(NacosClientProperties properties) {
this.endpoint = initEndpoint(properties);
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
if (!StringUtils.isBlank(contentPathTmp)) {
this.contentPath = contentPathTmp;
initServerAddr(properties);
initNameSpace(properties);
initEndpoint(properties);
initEndpointPort(properties);
initEndpointContextPath(properties);
initContextPath(properties);
initServerListName(properties);
}
private void initEndpointContextPath(NacosClientProperties properties) {
String endpointContextPathTmp = TemplateUtils.stringEmptyAndThenExecute(
properties.getProperty(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_CONTEXT_PATH),
() -> properties.getProperty(PropertyKeyConst.ENDPOINT_CONTEXT_PATH));
if (StringUtils.isNotBlank(endpointContextPathTmp)) {
this.endpointContextPath = endpointContextPathTmp;
}
}
private void initEndpointPort(NacosClientProperties properties) {
String endpointPortTmp = TemplateUtils.stringEmptyAndThenExecute(
properties.getProperty(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT),
() -> properties.getProperty(PropertyKeyConst.ENDPOINT_PORT));
if (StringUtils.isNotBlank(endpointPortTmp)) {
this.endpointPort = Integer.parseInt(endpointPortTmp);
}
}
private void initServerListName(NacosClientProperties properties) {
String serverListNameTmp = properties.getProperty(PropertyKeyConst.CLUSTER_NAME);
if (!StringUtils.isBlank(serverListNameTmp)) {
this.serverListName = serverListNameTmp;
}
}
private String initEndpoint(final NacosClientProperties properties) {
String endpointPortTmp = TemplateUtils
.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT),
() -> properties.getProperty(PropertyKeyConst.ENDPOINT_PORT));
if (StringUtils.isNotBlank(endpointPortTmp)) {
this.endpointPort = Integer.parseInt(endpointPortTmp);
private void initContextPath(NacosClientProperties properties) {
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
if (!StringUtils.isBlank(contentPathTmp)) {
this.contentPath = contentPathTmp;
}
}
private void initEndpoint(final NacosClientProperties properties) {
String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT);
// Whether to enable domain name resolution rules
String isUseEndpointRuleParsing = properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
properties.getProperty(SystemPropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
@ -300,10 +317,9 @@ public class ServerListManager implements Closeable {
if (StringUtils.isNotBlank(endpointUrl)) {
this.serverAddrsStr = "";
}
return endpointUrl;
this.endpoint = endpointUrl;
}
return StringUtils.isNotBlank(endpointTmp) ? endpointTmp : "";
this.endpoint = StringUtils.isNotBlank(endpointTmp) ? endpointTmp : "";
}
/**
@ -318,7 +334,7 @@ public class ServerListManager implements Closeable {
}
GetServerListTask getServersTask = new GetServerListTask(addressServerUrl);
for (int i = 0; i < initServerlistRetryTimes && serverUrls.isEmpty(); ++i) {
for (int i = 0; i < initServerListRetryTimes && serverUrls.isEmpty(); ++i) {
getServersTask.run();
if (!serverUrls.isEmpty()) {
break;

View File

@ -76,6 +76,8 @@ public class ServerListManager implements ServerListFactory, Closeable {
private String endpoint;
private String endpointContentPath;
private String contentPath = ParamUtil.getDefaultContextPath();
private String serverListName = ParamUtil.getDefaultNodesPath();
@ -101,7 +103,10 @@ public class ServerListManager implements ServerListFactory, Closeable {
private void initServerAddr(NacosClientProperties properties) {
this.endpoint = InitUtils.initEndpoint(properties);
if (StringUtils.isNotEmpty(endpoint)) {
String endpointContentPathTmp = properties.getProperty(PropertyKeyConst.ENDPOINT_CONTEXT_PATH);
if (!StringUtils.isBlank(endpointContentPathTmp)) {
this.endpointContentPath = endpointContentPathTmp;
}
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
if (!StringUtils.isBlank(contentPathTmp)) {
this.contentPath = contentPathTmp;
@ -130,9 +135,13 @@ public class ServerListManager implements ServerListFactory, Closeable {
private List<String> getServerListFromEndpoint() {
try {
StringBuilder addressServerUrlTem = new StringBuilder(String.format("http://%s%s/%s", this.endpoint,
ContextPathUtil.normalizeContextPath(this.contentPath), this.serverListName));
String urlString = addressServerUrlTem.toString();
String contentPathTmp;
if (StringUtils.isNotBlank(this.endpointContentPath)) {
contentPathTmp = ContextPathUtil.normalizeContextPath(this.endpointContentPath);
} else {
contentPathTmp = ContextPathUtil.normalizeContextPath(this.contentPath);
}
String urlString = String.format("http://%s%s/%s", this.endpoint, contentPathTmp, this.serverListName);
Header header = NamingHttpUtil.builderHeader();
Query query = StringUtils.isNotBlank(namespace) ? Query.newInstance().addParam("namespace", namespace)
: Query.EMPTY;

View File

@ -22,11 +22,14 @@ import com.alibaba.nacos.client.env.NacosClientProperties;
import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTP_PREFIX;
public class ServerListManagerTest {
@Test
@ -146,4 +149,100 @@ public class ServerListManagerTest {
}
@Test
public void testAddressServerBaseServerAddrsStr() throws NacosException {
Properties properties = new Properties();
String serverAddrStr = "nacos.test.com:8080";
properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverAddrStr);
String endpointContextPath = "/endpoint";
properties.setProperty(PropertyKeyConst.CONTEXT_PATH, endpointContextPath);
final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
ServerListManager serverListManager = new ServerListManager(clientProperties);
Assert.assertEquals(1, serverListManager.serverUrls.size());
Assert.assertTrue(serverListManager.serverUrls.contains(HTTP_PREFIX + serverAddrStr));
}
@Test
public void testAddressServerBaseEndpoint() throws NacosException {
Properties properties = new Properties();
String endpoint = "127.0.0.1";
properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint);
String endpointPort = "8080";
properties.setProperty(PropertyKeyConst.ENDPOINT_PORT, endpointPort);
String endpointContextPath = "/endpoint";
properties.setProperty(PropertyKeyConst.ENDPOINT_CONTEXT_PATH, endpointContextPath);
final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
ServerListManager serverListManager = new ServerListManager(clientProperties);
Assert.assertTrue(serverListManager.addressServerUrl.startsWith(
HTTP_PREFIX + endpoint + ":" + endpointPort + endpointContextPath));
}
@Test
public void testInitParam() throws NacosException, NoSuchFieldException, IllegalAccessException {
Properties properties = new Properties();
String endpoint = "127.0.0.1";
properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint);
String endpointPort = "9090";
properties.setProperty(PropertyKeyConst.ENDPOINT_PORT, endpointPort);
String endpointContextPath = "/endpointContextPath";
properties.setProperty(PropertyKeyConst.ENDPOINT_CONTEXT_PATH, endpointContextPath);
String contextPath = "/contextPath";
properties.setProperty(PropertyKeyConst.CONTEXT_PATH, contextPath);
final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
ServerListManager serverListManager = new ServerListManager(clientProperties);
Field endpointField = ServerListManager.class.getDeclaredField("endpoint");
endpointField.setAccessible(true);
String fieldEndpoint = (String) endpointField.get(serverListManager);
Assert.assertEquals(endpoint, fieldEndpoint);
Field endpointPortField = ServerListManager.class.getDeclaredField("endpointPort");
endpointPortField.setAccessible(true);
String fieldEndpointPort = String.valueOf(endpointPortField.get(serverListManager));
Assert.assertEquals(endpointPort, fieldEndpointPort);
Field endpointContextPathField = ServerListManager.class.getDeclaredField("endpointContextPath");
endpointContextPathField.setAccessible(true);
String fieldEndpointContextPath = String.valueOf(endpointContextPathField.get(serverListManager));
Assert.assertEquals(endpointContextPath, fieldEndpointContextPath);
Field contentPathField = ServerListManager.class.getDeclaredField("contentPath");
contentPathField.setAccessible(true);
String fieldContentPath = String.valueOf(contentPathField.get(serverListManager));
Assert.assertEquals(fieldContentPath, contextPath);
}
@Test
public void testWithEndpointContextPath() throws NacosException {
Properties properties = new Properties();
String endpoint = "127.0.0.1";
properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint);
String endpointPort = "9090";
properties.setProperty(PropertyKeyConst.ENDPOINT_PORT, endpointPort);
String endpointContextPath = "/endpointContextPath";
properties.setProperty(PropertyKeyConst.ENDPOINT_CONTEXT_PATH, endpointContextPath);
String contextPath = "/contextPath";
properties.setProperty(PropertyKeyConst.CONTEXT_PATH, contextPath);
final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
ServerListManager serverListManager = new ServerListManager(clientProperties);
Assert.assertTrue(serverListManager.addressServerUrl.contains(endpointContextPath));
Assert.assertTrue(serverListManager.getName().contains("endpointContextPath"));
}
@Test
public void testWithoutEndpointContextPath() throws NacosException {
Properties properties = new Properties();
String endpoint = "127.0.0.1";
properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint);
String endpointPort = "9090";
properties.setProperty(PropertyKeyConst.ENDPOINT_PORT, endpointPort);
String contextPath = "/contextPath";
properties.setProperty(PropertyKeyConst.CONTEXT_PATH, contextPath);
final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
ServerListManager serverListManager = new ServerListManager(clientProperties);
String endpointContextPath = "/endpointContextPath";
Assert.assertFalse(serverListManager.addressServerUrl.contains(endpointContextPath));
Assert.assertTrue(serverListManager.addressServerUrl.contains(contextPath));
Assert.assertFalse(serverListManager.getName().contains("endpointContextPath"));
Assert.assertTrue(serverListManager.getName().contains("contextPath"));
}
}

View File

@ -201,6 +201,50 @@ public class ServerListManagerTest {
Assert.assertEquals("127.0.0.1:8848", serverList.get(0));
}
@Test
public void testConstructWithEndpointWithEndpointPathAndName() throws Exception {
clientProperties.setProperty(PropertyKeyConst.ENDPOINT_CONTEXT_PATH, "aaa");
clientProperties.setProperty(PropertyKeyConst.CLUSTER_NAME, "bbb");
clientProperties.setProperty(PropertyKeyConst.ENDPOINT, "127.0.0.1");
Mockito.reset(nacosRestTemplate);
Mockito.when(nacosRestTemplate.get(eq("http://127.0.0.1:8080/aaa/bbb"), any(), any(), any()))
.thenReturn(httpRestResult);
serverListManager = new ServerListManager(clientProperties, "test");
List<String> serverList = serverListManager.getServerList();
Assert.assertEquals(1, serverList.size());
Assert.assertEquals("127.0.0.1:8848", serverList.get(0));
}
@Test
public void testConstructEndpointContextPathPriority() throws Exception {
clientProperties.setProperty(PropertyKeyConst.ENDPOINT_CONTEXT_PATH, "aaa");
clientProperties.setProperty(PropertyKeyConst.CONTEXT_PATH, "bbb");
clientProperties.setProperty(PropertyKeyConst.CLUSTER_NAME, "ccc");
clientProperties.setProperty(PropertyKeyConst.ENDPOINT, "127.0.0.1");
Mockito.reset(nacosRestTemplate);
Mockito.when(nacosRestTemplate.get(eq("http://127.0.0.1:8080/aaa/ccc"), any(), any(), any()))
.thenReturn(httpRestResult);
serverListManager = new ServerListManager(clientProperties, "test");
List<String> serverList = serverListManager.getServerList();
Assert.assertEquals(1, serverList.size());
Assert.assertEquals("127.0.0.1:8848", serverList.get(0));
}
@Test
public void testConstructEndpointContextPathIsEmpty() throws Exception {
clientProperties.setProperty(PropertyKeyConst.ENDPOINT_CONTEXT_PATH, "");
clientProperties.setProperty(PropertyKeyConst.CONTEXT_PATH, "bbb");
clientProperties.setProperty(PropertyKeyConst.CLUSTER_NAME, "ccc");
clientProperties.setProperty(PropertyKeyConst.ENDPOINT, "127.0.0.1");
Mockito.reset(nacosRestTemplate);
Mockito.when(nacosRestTemplate.get(eq("http://127.0.0.1:8080/bbb/ccc"), any(), any(), any()))
.thenReturn(httpRestResult);
serverListManager = new ServerListManager(clientProperties, "test");
List<String> serverList = serverListManager.getServerList();
Assert.assertEquals(1, serverList.size());
Assert.assertEquals("127.0.0.1:8848", serverList.get(0));
}
@Test
public void testIsDomain() throws IOException {
Properties properties = new Properties();