From b97116458c756ab35c1aa5e7e45ae77c8ecca356 Mon Sep 17 00:00:00 2001 From: totalo Date: Tue, 15 Oct 2024 10:13:03 +0800 Subject: [PATCH] [ISSUE #12189] Unified Nacos Client address module code (#12274) * refactor: Unified Nacos Client address module code, and provide custom expansion capabilities * refactor: Adjust the priority of endpoint and server addr * refactor: adjust code for code review * refactor: adjust code for code review * refactor: adjust code for code review * refactor: adjust code for code review * refactor: adjust code for code review * refactor: adjust code for code review * refactor: add new line * refactor: adjust code for review * refactor: adjust code for review * refactor: adjust code for review * refactor: merge develop and fix test * refactor: revert test code * refactor: adjust for code review * refactor: fix checkstyle --- .../alibaba/nacos/api/PropertyKeyConst.java | 2 + .../address/AbstractServerListManager.java | 128 ++++ .../address/AbstractServerListProvider.java | 90 +++ .../address/AddressServerListProvider.java | 97 +++ .../address/EndpointServerListProvider.java | 284 ++++++++ .../ServerListChangeEvent.java | 2 +- .../client/address/ServerListProvider.java | 101 +++ .../client/config/NacosConfigService.java | 4 +- .../client/config/http/ServerHttpAgent.java | 37 +- .../client/config/impl/ClientWorker.java | 16 +- .../config/impl/ConfigHttpClientManager.java | 15 +- .../config/impl/ConfigServerListManager.java | 222 +++++++ .../config/impl/ConfigTransportClient.java | 6 +- .../client/config/impl/ServerListManager.java | 608 ------------------ .../nacos/client/constant/Constants.java | 7 + .../naming/NacosNamingMaintainService.java | 6 +- .../naming/core/NamingServerListManager.java | 105 +++ .../client/naming/core/ServerListManager.java | 225 ------- .../naming/event/ServerListChangedEvent.java | 28 - .../remote/AbstractNamingClientProxy.java | 4 +- .../remote/NamingClientProxyDelegate.java | 6 +- .../remote/gprc/NamingGrpcClientProxy.java | 6 +- .../remote/http/NamingHttpClientProxy.java | 19 +- .../client/naming/utils/NamingHttpUtil.java | 46 -- .../alibaba/nacos/client/utils/ParamUtil.java | 12 + ...ba.nacos.client.address.ServerListProvider | 19 + .../ram/identify/StsCredentialHolderTest.java | 56 +- .../client/config/NacosConfigServiceTest.java | 12 +- .../config/http/ServerHttpAgentTest.java | 55 +- .../client/config/impl/ClientWorkerTest.java | 34 +- ....java => ConfigServerListManagerTest.java} | 228 ++++--- .../NacosNamingMaintainServiceTest.java | 6 +- ....java => NamingServerListManagerTest.java} | 91 ++- .../remote/AbstractNamingClientProxyTest.java | 4 +- .../gprc/NamingGrpcClientProxyTest.java | 4 +- .../http/NamingHttpClientProxyTest.java | 12 +- .../naming/utils/NamingHttpUtilTest.java | 40 -- .../nacos/client/utils/ParamUtilTest.java | 5 + .../alibaba/nacos/common/http/HttpUtils.java | 18 + .../nacos/common/http/HttpUtilsTest.java | 16 +- .../common/utils/InternetAddressUtilTest.java | 1 - 41 files changed, 1462 insertions(+), 1215 deletions(-) create mode 100644 client/src/main/java/com/alibaba/nacos/client/address/AbstractServerListManager.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/address/AbstractServerListProvider.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/address/AddressServerListProvider.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/address/EndpointServerListProvider.java rename client/src/main/java/com/alibaba/nacos/client/{config/impl => address}/ServerListChangeEvent.java (94%) create mode 100644 client/src/main/java/com/alibaba/nacos/client/address/ServerListProvider.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigServerListManager.java delete mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/naming/core/NamingServerListManager.java delete mode 100644 client/src/main/java/com/alibaba/nacos/client/naming/core/ServerListManager.java delete mode 100644 client/src/main/java/com/alibaba/nacos/client/naming/event/ServerListChangedEvent.java delete mode 100644 client/src/main/java/com/alibaba/nacos/client/naming/utils/NamingHttpUtil.java create mode 100644 client/src/main/resources/META-INF/services/com.alibaba.nacos.client.address.ServerListProvider rename client/src/test/java/com/alibaba/nacos/client/config/impl/{ServerListManagerTest.java => ConfigServerListManagerTest.java} (52%) rename client/src/test/java/com/alibaba/nacos/client/naming/core/{ServerListManagerTest.java => NamingServerListManagerTest.java} (78%) delete mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/utils/NamingHttpUtilTest.java diff --git a/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java b/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java index 424319f7a4a..2bc0fe5bdc9 100644 --- a/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java +++ b/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java @@ -97,6 +97,8 @@ public class PropertyKeyConst { public static final String LOG_ALL_PROPERTIES = "logAllProperties"; + public static final String CLIENT_MODULE_TYPE = "clientModuleType"; + /** * Since 2.3.3, For some situation like java agent using nacos-client which can't use env ram info. */ diff --git a/client/src/main/java/com/alibaba/nacos/client/address/AbstractServerListManager.java b/client/src/main/java/com/alibaba/nacos/client/address/AbstractServerListManager.java new file mode 100644 index 00000000000..5226f4dc26d --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/address/AbstractServerListManager.java @@ -0,0 +1,128 @@ +/* + * Copyright 1999-2024 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.nacos.client.address; + +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.env.NacosClientProperties; +import com.alibaba.nacos.client.utils.LogUtils; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.lifecycle.Closeable; +import com.alibaba.nacos.common.remote.client.ServerListFactory; +import com.alibaba.nacos.common.spi.NacosServiceLoader; +import com.alibaba.nacos.common.utils.StringUtils; +import org.slf4j.Logger; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Server list Manager. + * + * @author totalo + */ +public abstract class AbstractServerListManager implements ServerListFactory, Closeable { + + private static final Logger LOGGER = LogUtils.logger(AbstractServerListManager.class); + + protected ServerListProvider serverListProvider; + + private NacosClientProperties properties; + + public AbstractServerListManager(NacosClientProperties properties) throws NacosException { + this(properties, null); + } + + public AbstractServerListManager(NacosClientProperties properties, String namespace) throws NacosException { + if (null == properties) { + LOGGER.error("properties is null"); + return; + } + if (StringUtils.isNotBlank(namespace)) { + properties.setProperty(PropertyKeyConst.NAMESPACE, namespace); + } + properties.setProperty(PropertyKeyConst.CLIENT_MODULE_TYPE, getModuleName()); + this.properties = properties; + Collection serverListProviders = NacosServiceLoader.load(ServerListProvider.class); + Collection sorted = serverListProviders.stream() + .sorted((a, b) -> b.getOrder() - a.getOrder()).collect(Collectors.toList()); + for (ServerListProvider each : sorted) { + if (each.match(properties)) { + this.serverListProvider = each; + break; + } + } + if (null == serverListProvider) { + LOGGER.error("no server list provider found"); + return; + } + this.serverListProvider.init(properties, getNacosRestTemplate()); + } + + @Override + public List getServerList() { + return serverListProvider.getServerList(); + } + + @Override + public void shutdown() throws NacosException { + String className = this.getClass().getName(); + LOGGER.info("{} do shutdown begin", className); + if (null != serverListProvider) { + serverListProvider.shutdown(); + } + serverListProvider = null; + LOGGER.info("{} do shutdown stop", className); + } + + public NacosClientProperties getProperties() { + return properties; + } + + public String getServerName() { + return getModuleName() + "-" + serverListProvider.getServerName(); + } + + public String getContextPath() { + return serverListProvider.getContextPath(); + } + + public String getNamespace() { + return serverListProvider.getNamespace(); + } + + public String getAddressSource() { + return serverListProvider.getAddressSource(); + } + + public boolean isFixed() { + return serverListProvider.isFixed(); + } + + /** + * get module name. + * @return module name + */ + public abstract String getModuleName(); + + /** + * get nacos rest template. + * @return nacos rest template + */ + public abstract NacosRestTemplate getNacosRestTemplate(); +} diff --git a/client/src/main/java/com/alibaba/nacos/client/address/AbstractServerListProvider.java b/client/src/main/java/com/alibaba/nacos/client/address/AbstractServerListProvider.java new file mode 100644 index 00000000000..3f337a6ae06 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/address/AbstractServerListProvider.java @@ -0,0 +1,90 @@ +/* + * Copyright 1999-2024 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.nacos.client.address; + +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.env.NacosClientProperties; +import com.alibaba.nacos.client.utils.ParamUtil; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.utils.StringUtils; + +import java.util.List; + +/** + * Address server list provider. + * + * @author totalo + */ +public abstract class AbstractServerListProvider implements ServerListProvider { + + protected String contextPath = ParamUtil.getDefaultContextPath(); + + protected String namespace = ""; + + @Override + public void init(final NacosClientProperties properties, final NacosRestTemplate nacosRestTemplate) throws NacosException { + if (null == properties) { + throw new NacosException(NacosException.INVALID_PARAM, "properties is null"); + } + initContextPath(properties); + initNameSpace(properties); + } + + /** + * Get server list. + * @return server list + */ + @Override + public abstract List getServerList(); + + /** + * Get server name. + * @return server name + */ + @Override + public abstract String getServerName(); + + /** + * Get order. + * @return order + */ + @Override + public abstract int getOrder(); + + public String getContextPath() { + return contextPath; + } + + public String getNamespace() { + return namespace; + } + + private void initContextPath(NacosClientProperties properties) { + String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH); + if (!StringUtils.isBlank(contentPathTmp)) { + this.contextPath = contentPathTmp; + } + } + + private void initNameSpace(NacosClientProperties properties) { + String namespace = properties.getProperty(PropertyKeyConst.NAMESPACE); + if (StringUtils.isNotBlank(namespace)) { + this.namespace = namespace; + } + } +} diff --git a/client/src/main/java/com/alibaba/nacos/client/address/AddressServerListProvider.java b/client/src/main/java/com/alibaba/nacos/client/address/AddressServerListProvider.java new file mode 100644 index 00000000000..2bc34e74e1f --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/address/AddressServerListProvider.java @@ -0,0 +1,97 @@ +/* + * Copyright 1999-2024 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.nacos.client.address; + +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.constant.Constants.Address; +import com.alibaba.nacos.client.env.NacosClientProperties; +import com.alibaba.nacos.client.utils.ParamUtil; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.utils.InternetAddressUtil; +import com.alibaba.nacos.common.utils.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTPS_PREFIX; +import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTP_PREFIX; + +/** + * Address server list provider. + * + * @author totalo + */ +public class AddressServerListProvider extends AbstractServerListProvider { + + private static final String FIXED_NAME = "fixed"; + + private List serverList; + + @Override + public void init(final NacosClientProperties properties, final NacosRestTemplate nacosRestTemplate) throws NacosException { + super.init(properties, nacosRestTemplate); + serverList = new ArrayList<>(); + String serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR); + StringTokenizer serverAddrsTokens = new StringTokenizer(serverAddrsStr, ",;"); + while (serverAddrsTokens.hasMoreTokens()) { + String serverAddr = serverAddrsTokens.nextToken().trim(); + if (serverAddr.startsWith(HTTP_PREFIX) || serverAddr.startsWith(HTTPS_PREFIX)) { + this.serverList.add(serverAddr); + } else { + String[] serverAddrArr = InternetAddressUtil.splitIPPortStr(serverAddr); + if (serverAddrArr.length == 1) { + this.serverList + .add(serverAddrArr[0] + InternetAddressUtil.IP_PORT_SPLITER + ParamUtil.getDefaultServerPort()); + } else { + this.serverList.add(serverAddr); + } + } + } + } + + @Override + public List getServerList() { + return serverList; + } + + @Override + public String getServerName() { + return FIXED_NAME + "-" + (StringUtils.isNotBlank(namespace) ? (StringUtils.trim(namespace) + "-") + : "") + ParamUtil.getNameSuffixByServerIps(serverList.toArray(new String[0])); + } + + @Override + public int getOrder() { + return Address.ADDRESS_SERVER_LIST_PROVIDER_ORDER; + } + + @Override + public boolean match(final NacosClientProperties properties) { + return StringUtils.isNotBlank(properties.getProperty(PropertyKeyConst.SERVER_ADDR)); + } + + @Override + public boolean isFixed() { + return true; + } + + @Override + public void shutdown() throws NacosException { + } +} diff --git a/client/src/main/java/com/alibaba/nacos/client/address/EndpointServerListProvider.java b/client/src/main/java/com/alibaba/nacos/client/address/EndpointServerListProvider.java new file mode 100644 index 00000000000..b16d25c0229 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/address/EndpointServerListProvider.java @@ -0,0 +1,284 @@ +/* + * Copyright 1999-2024 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.nacos.client.address; + +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.SystemPropertyKeyConst; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.constant.Constants.Address; +import com.alibaba.nacos.client.env.NacosClientProperties; +import com.alibaba.nacos.client.naming.utils.CollectionUtils; +import com.alibaba.nacos.client.utils.ContextPathUtil; +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; +import com.alibaba.nacos.common.http.HttpUtils; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.http.param.Query; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.utils.InternetAddressUtil; +import com.alibaba.nacos.common.utils.IoUtils; +import com.alibaba.nacos.common.utils.StringUtils; +import org.slf4j.Logger; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Endpoint server list provider. + * + * @author totalo + */ +public class EndpointServerListProvider extends AbstractServerListProvider { + + private static final Logger LOGGER = LogUtils.logger(EndpointServerListProvider.class); + + private NacosRestTemplate nacosRestTemplate; + + private static final String CUSTOM_NAME = "custom"; + + private final long refreshServerListInternal = TimeUnit.SECONDS.toMillis(30); + + private final int initServerListRetryTimes = 5; + + private long lastServerListRefreshTime = 0L; + + private ScheduledExecutorService refreshServerListExecutor; + + private String endpoint; + + private int endpointPort = 8080; + + private String endpointContextPath; + + private String serverListName = ParamUtil.getDefaultNodesPath(); + + private volatile List serversFromEndpoint = new ArrayList<>(); + + private String addressServerUrl; + + private String moduleName = "default"; + + @Override + public void init(final NacosClientProperties properties, final NacosRestTemplate nacosRestTemplate) throws NacosException { + super.init(properties, nacosRestTemplate); + this.nacosRestTemplate = nacosRestTemplate; + initEndpoint(properties); + initEndpointPort(properties); + initEndpointContextPath(properties); + initServerListName(properties); + initAddressServerUrl(properties); + initModuleName(properties); + startRefreshServerListTask(); + } + + @Override + public List getServerList() { + return serversFromEndpoint; + } + + @Override + public String getServerName() { + String contextPathTmp = + StringUtils.isNotBlank(this.endpointContextPath) ? this.endpointContextPath : this.contextPath; + return CUSTOM_NAME + "-" + String.join("_", endpoint, String.valueOf(endpointPort), contextPathTmp, + serverListName) + (StringUtils.isNotBlank(namespace) ? ("_" + StringUtils.trim( + namespace)) : ""); + } + + @Override + public int getOrder() { + return Address.ENDPOINT_SERVER_LIST_PROVIDER_ORDER; + } + + @Override + public boolean match(final NacosClientProperties properties) { + String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT); + String isUseEndpointRuleParsing = properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE, + properties.getProperty(SystemPropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE, + String.valueOf(ParamUtil.USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE))); + if (Boolean.parseBoolean(isUseEndpointRuleParsing)) { + endpointTmp = ParamUtil.parsingEndpointRule(endpointTmp); + } + return StringUtils.isNotBlank(endpointTmp); + } + + @Override + public String getAddressSource() { + return this.addressServerUrl; + } + + /** + * Start refresh server list task. + * + * @throws NacosException nacos exception + */ + public void startRefreshServerListTask() throws NacosException { + for (int i = 0; i < initServerListRetryTimes && getServerList().isEmpty(); ++i) { + refreshServerListIfNeed(); + if (!serversFromEndpoint.isEmpty()) { + break; + } + try { + this.wait((i + 1) * 100L); + } catch (Exception e) { + LOGGER.warn("get serverlist fail,url: {}", addressServerUrl); + } + } + + if (serversFromEndpoint.isEmpty()) { + LOGGER.error("[init-serverlist] fail to get NACOS-server serverlist! url: {}", addressServerUrl); + throw new NacosException(NacosException.SERVER_ERROR, + "fail to get NACOS-server serverlist! not connnect url:" + addressServerUrl); + } + + refreshServerListExecutor = new ScheduledThreadPoolExecutor(1, + new NameThreadFactory("com.alibaba.nacos.client.address.EndpointServerListProvider.refreshServerList")); + // executor schedules the timer task + refreshServerListExecutor.scheduleWithFixedDelay(this::refreshServerListIfNeed, 0L, 30L, TimeUnit.SECONDS); + } + + private void refreshServerListIfNeed() { + try { + if (System.currentTimeMillis() - lastServerListRefreshTime < refreshServerListInternal) { + return; + } + List list = getServerListFromEndpoint(); + if (CollectionUtils.isEmpty(list)) { + throw new Exception("Can not acquire Nacos list"); + } + list.sort(String::compareTo); + if (null == serversFromEndpoint || !CollectionUtils.isEqualCollection(list, serversFromEndpoint)) { + LOGGER.info("[SERVER-LIST] server list is updated: {}", list); + serversFromEndpoint = list; + lastServerListRefreshTime = System.currentTimeMillis(); + NotifyCenter.publishEvent(new ServerListChangeEvent()); + } + } catch (Throwable e) { + LOGGER.warn("failed to update server list", e); + } + } + + private List getServerListFromEndpoint() { + try { + HttpRestResult httpResult = nacosRestTemplate.get(addressServerUrl, HttpUtils.builderHeader(moduleName), + Query.EMPTY, String.class); + + if (!httpResult.ok()) { + LOGGER.error("[check-serverlist] error. addressServerUrl: {}, code: {}", addressServerUrl, + httpResult.getCode()); + return null; + } + List lines = IoUtils.readLines(new StringReader(httpResult.getData())); + List result = new ArrayList<>(lines.size()); + for (String serverAddr : lines) { + if (StringUtils.isBlank(serverAddr)) { + continue; + } + String[] ipPort = InternetAddressUtil.splitIPPortStr(serverAddr.trim()); + String ip = ipPort[0].trim(); + if (ipPort.length == 1) { + result.add(ip + InternetAddressUtil.IP_PORT_SPLITER + ParamUtil.getDefaultServerPort()); + } else { + result.add(serverAddr); + } + } + return result; + } catch (Exception e) { + LOGGER.error("[check-serverlist] exception. url: {}", addressServerUrl, e); + return null; + } + } + + private void initEndpoint(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, + String.valueOf(ParamUtil.USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE))); + if (Boolean.parseBoolean(isUseEndpointRuleParsing)) { + endpointTmp = ParamUtil.parsingEndpointRule(endpointTmp); + } + this.endpoint = StringUtils.isNotBlank(endpointTmp) ? endpointTmp : ""; + } + + 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 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 initServerListName(NacosClientProperties properties) { + String serverListNameTmp = properties.getProperty(PropertyKeyConst.ENDPOINT_CLUSTER_NAME, + properties.getProperty(PropertyKeyConst.CLUSTER_NAME)); + if (!StringUtils.isBlank(serverListNameTmp)) { + this.serverListName = serverListNameTmp; + } + } + + private void initAddressServerUrl(NacosClientProperties properties) { + String contextPathTmp = StringUtils.isNotBlank(this.endpointContextPath) ? ContextPathUtil.normalizeContextPath( + this.endpointContextPath) : ContextPathUtil.normalizeContextPath(this.contextPath); + StringBuilder addressServerUrlTem = new StringBuilder( + String.format("http://%s:%d%s/%s", this.endpoint, this.endpointPort, contextPathTmp, + 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)); + + } + this.addressServerUrl = addressServerUrlTem.toString(); + LOGGER.info("address server url = {}", this.addressServerUrl); + } + + private void initModuleName(NacosClientProperties properties) { + String moduleNameTmp = properties.getProperty(PropertyKeyConst.CLIENT_MODULE_TYPE); + if (StringUtils.isNotBlank(moduleNameTmp)) { + this.moduleName = moduleNameTmp; + } + } + + @Override + public void shutdown() throws NacosException { + if (null != refreshServerListExecutor) { + refreshServerListExecutor.shutdown(); + } + } +} diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListChangeEvent.java b/client/src/main/java/com/alibaba/nacos/client/address/ServerListChangeEvent.java similarity index 94% rename from client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListChangeEvent.java rename to client/src/main/java/com/alibaba/nacos/client/address/ServerListChangeEvent.java index ffedd5c9a9e..6efafe69c60 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListChangeEvent.java +++ b/client/src/main/java/com/alibaba/nacos/client/address/ServerListChangeEvent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.alibaba.nacos.client.config.impl; +package com.alibaba.nacos.client.address; import com.alibaba.nacos.common.notify.SlowEvent; diff --git a/client/src/main/java/com/alibaba/nacos/client/address/ServerListProvider.java b/client/src/main/java/com/alibaba/nacos/client/address/ServerListProvider.java new file mode 100644 index 00000000000..0217b233b12 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/address/ServerListProvider.java @@ -0,0 +1,101 @@ +/* + * Copyright 1999-2024 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.nacos.client.address; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.env.NacosClientProperties; +import com.alibaba.nacos.client.utils.ParamUtil; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.lifecycle.Closeable; + +import java.util.List; + +/** + * Server list provider. + * + * @author totalo + */ +public interface ServerListProvider extends Closeable { + + /** + * Init. + * @param properties nacos client properties + * @param nacosRestTemplate nacos rest template + * @throws NacosException nacos exception + */ + void init(final NacosClientProperties properties, final NacosRestTemplate nacosRestTemplate) throws NacosException; + + /** + * Get server list. + * @return server list + */ + List getServerList(); + + /** + * Get server name. + * @return server name + */ + default String getServerName() { + return ""; + } + + /** + * Get namespace. + * @return namespace + */ + default String getNamespace() { + return ""; + } + + /** + * Get context path. + * @return context path + */ + default String getContextPath() { + return ParamUtil.getDefaultContextPath(); + } + + /** + * Get order. + * @return order + */ + int getOrder(); + + /** + * Match. + * @param properties nacos client properties + * @return match + */ + boolean match(final NacosClientProperties properties); + + /** + * check the server list is fixed or not. + * @return true if the server list is fixed + */ + default boolean isFixed() { + return false; + } + + /** + * Get address source. + * @return address source + */ + default String getAddressSource() { + return ""; + } + +} diff --git a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java index 5434112dffd..ba17c03bb1a 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java @@ -28,9 +28,9 @@ import com.alibaba.nacos.client.config.filter.impl.ConfigResponse; import com.alibaba.nacos.client.config.http.ServerHttpAgent; import com.alibaba.nacos.client.config.impl.ClientWorker; +import com.alibaba.nacos.client.config.impl.ConfigServerListManager; import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor; import com.alibaba.nacos.client.config.impl.LocalEncryptedDataKeyProcessor; -import com.alibaba.nacos.client.config.impl.ServerListManager; import com.alibaba.nacos.client.config.utils.ParamUtils; import com.alibaba.nacos.client.env.NacosClientProperties; import com.alibaba.nacos.client.utils.LogUtils; @@ -80,7 +80,7 @@ public NacosConfigService(Properties properties) throws NacosException { initNamespace(clientProperties); this.configFilterChainManager = new ConfigFilterChainManager(clientProperties.asProperties()); - ServerListManager serverListManager = new ServerListManager(clientProperties); + ConfigServerListManager serverListManager = new ConfigServerListManager(clientProperties); serverListManager.start(); this.worker = new ClientWorker(this.configFilterChainManager, serverListManager, clientProperties); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java b/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java index b84d063bf9b..a21ddcda8d8 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java @@ -18,7 +18,7 @@ import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.config.impl.ConfigHttpClientManager; -import com.alibaba.nacos.client.config.impl.ServerListManager; +import com.alibaba.nacos.client.config.impl.ConfigServerListManager; import com.alibaba.nacos.client.env.NacosClientProperties; import com.alibaba.nacos.client.utils.ContextPathUtil; import com.alibaba.nacos.client.utils.LogUtils; @@ -46,19 +46,19 @@ public class ServerHttpAgent implements HttpAgent { private static final Logger LOGGER = LogUtils.logger(ServerHttpAgent.class); - private NacosRestTemplate nacosRestTemplate = ConfigHttpClientManager.getInstance().getNacosRestTemplate(); + private final NacosRestTemplate nacosRestTemplate = ConfigHttpClientManager.getInstance().getNacosRestTemplate(); private String encode; private int maxRetry = 3; - final ServerListManager serverListMgr; + final ConfigServerListManager serverListMgr; @Override public HttpRestResult httpGet(String path, Map headers, Map paramValues, String encode, long readTimeoutMs) throws Exception { final long endTime = System.currentTimeMillis() + readTimeoutMs; - String currentServerAddr = serverListMgr.getCurrentServerAddr(); + String currentServerAddr = serverListMgr.getCurrentServer(); int maxRetry = this.maxRetry; HttpClientConfig httpConfig = HttpClientConfig.builder() .setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue()) @@ -74,7 +74,7 @@ public HttpRestResult httpGet(String path, Map headers, newHeaders, query, String.class); if (isFail(result)) { LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", - serverListMgr.getCurrentServerAddr(), result.getCode()); + serverListMgr.getCurrentServer(), result.getCode()); } else { // Update the currently available server addr serverListMgr.updateCurrentServerAddr(currentServerAddr); @@ -82,12 +82,12 @@ public HttpRestResult httpGet(String path, Map headers, } } catch (ConnectException connectException) { LOGGER.error("[NACOS ConnectException httpGet] currentServerAddr:{}, err : {}", - serverListMgr.getCurrentServerAddr(), connectException.getMessage()); + serverListMgr.getCurrentServer(), connectException.getMessage()); } catch (SocketTimeoutException socketTimeoutException) { LOGGER.error("[NACOS SocketTimeoutException httpGet] currentServerAddr:{}, err : {}", - serverListMgr.getCurrentServerAddr(), socketTimeoutException.getMessage()); + serverListMgr.getCurrentServer(), socketTimeoutException.getMessage()); } catch (Exception ex) { - LOGGER.error("[NACOS Exception httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), + LOGGER.error("[NACOS Exception httpGet] currentServerAddr: " + serverListMgr.getCurrentServer(), ex); throw ex; } @@ -113,7 +113,7 @@ public HttpRestResult httpGet(String path, Map headers, public HttpRestResult httpPost(String path, Map headers, Map paramValues, String encode, long readTimeoutMs) throws Exception { final long endTime = System.currentTimeMillis() + readTimeoutMs; - String currentServerAddr = serverListMgr.getCurrentServerAddr(); + String currentServerAddr = serverListMgr.getCurrentServer(); int maxRetry = this.maxRetry; HttpClientConfig httpConfig = HttpClientConfig.builder() .setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue()) @@ -167,7 +167,7 @@ public HttpRestResult httpPost(String path, Map headers, public HttpRestResult httpDelete(String path, Map headers, Map paramValues, String encode, long readTimeoutMs) throws Exception { final long endTime = System.currentTimeMillis() + readTimeoutMs; - String currentServerAddr = serverListMgr.getCurrentServerAddr(); + String currentServerAddr = serverListMgr.getCurrentServer(); int maxRetry = this.maxRetry; HttpClientConfig httpConfig = HttpClientConfig.builder() .setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue()) @@ -183,7 +183,7 @@ public HttpRestResult httpDelete(String path, Map header newHeaders, query, String.class); if (isFail(result)) { LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", - serverListMgr.getCurrentServerAddr(), result.getCode()); + serverListMgr.getCurrentServer(), result.getCode()); } else { // Update the currently available server addr serverListMgr.updateCurrentServerAddr(currentServerAddr); @@ -191,12 +191,12 @@ public HttpRestResult httpDelete(String path, Map header } } catch (ConnectException connectException) { LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}, err : {}", - serverListMgr.getCurrentServerAddr(), ExceptionUtil.getStackTrace(connectException)); + serverListMgr.getCurrentServer(), ExceptionUtil.getStackTrace(connectException)); } catch (SocketTimeoutException stoe) { LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{}, err : {}", - serverListMgr.getCurrentServerAddr(), ExceptionUtil.getStackTrace(stoe)); + serverListMgr.getCurrentServer(), ExceptionUtil.getStackTrace(stoe)); } catch (Exception ex) { - LOGGER.error("[NACOS Exception httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), + LOGGER.error("[NACOS Exception httpDelete] currentServerAddr: " + serverListMgr.getCurrentServer(), ex); throw ex; } @@ -219,7 +219,8 @@ public HttpRestResult httpDelete(String path, Map header } private String getUrl(String serverAddr, String relativePath) { - return serverAddr + ContextPathUtil.normalizeContextPath(serverListMgr.getContentPath()) + relativePath; + String contextPath = serverListMgr.getContextPath(); + return serverAddr + ContextPathUtil.normalizeContextPath(contextPath) + relativePath; } private boolean isFail(HttpRestResult result) { @@ -233,16 +234,16 @@ public static String getAppname() { return ParamUtil.getAppName(); } - public ServerHttpAgent(ServerListManager mgr) { + public ServerHttpAgent(ConfigServerListManager mgr) { this.serverListMgr = mgr; } - public ServerHttpAgent(ServerListManager mgr, Properties properties) { + public ServerHttpAgent(ConfigServerListManager mgr, Properties properties) { this.serverListMgr = mgr; } public ServerHttpAgent(Properties properties) throws NacosException { - this.serverListMgr = new ServerListManager(NacosClientProperties.PROTOTYPE.derive(properties)); + this.serverListMgr = new ConfigServerListManager(NacosClientProperties.PROTOTYPE.derive(properties)); } @Override diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java index cb2da874065..bf5099e6009 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java @@ -36,6 +36,7 @@ import com.alibaba.nacos.api.remote.RemoteConstants; import com.alibaba.nacos.api.remote.request.Request; import com.alibaba.nacos.api.remote.response.Response; +import com.alibaba.nacos.client.address.ServerListChangeEvent; import com.alibaba.nacos.client.config.common.GroupKey; import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager; import com.alibaba.nacos.client.config.filter.impl.ConfigResponse; @@ -481,7 +482,7 @@ private String blank2defaultGroup(String group) { } @SuppressWarnings("PMD.ThreadPoolCreationRule") - public ClientWorker(final ConfigFilterChainManager configFilterChainManager, ServerListManager serverListManager, + public ClientWorker(final ConfigFilterChainManager configFilterChainManager, ConfigServerListManager serverListManager, final NacosClientProperties properties) throws NacosException { this.configFilterChainManager = configFilterChainManager; @@ -530,9 +531,8 @@ Map getMetrics(List metric metric.put("listenConfigSize", String.valueOf(this.cacheMap.get().size())); metric.put("clientVersion", VersionUtils.getFullClientVersion()); metric.put("snapshotDir", LocalConfigInfoProcessor.LOCAL_SNAPSHOT_PATH); - boolean isFixServer = agent.serverListManager.isFixed; - metric.put("isFixedServer", isFixServer); - metric.put("addressUrl", agent.serverListManager.addressServerUrl); + metric.put("addressUrl", agent.serverListManager.getAddressSource()); + metric.put("isFixedServer", agent.serverListManager.isFixed()); metric.put("serverUrls", agent.serverListManager.getUrlString()); Map metricValues = getMetricsValue(metricsKeys); @@ -602,7 +602,7 @@ public class ConfigRpcTransportClient extends ConfigTransportClient { */ private static final long ALL_SYNC_INTERNAL = 3 * 60 * 1000L; - public ConfigRpcTransportClient(NacosClientProperties properties, ServerListManager serverListManager) { + public ConfigRpcTransportClient(NacosClientProperties properties, ConfigServerListManager serverListManager) { super(properties, serverListManager); } @@ -740,19 +740,19 @@ public void onDisConnect(Connection connection) { rpcClientInner.serverListFactory(new ServerListFactory() { @Override public String genNextServer() { - return ConfigRpcTransportClient.super.serverListManager.getNextServerAddr(); + return ConfigRpcTransportClient.super.serverListManager.genNextServer(); } @Override public String getCurrentServer() { - return ConfigRpcTransportClient.super.serverListManager.getCurrentServerAddr(); + return ConfigRpcTransportClient.super.serverListManager.getCurrentServer(); } @Override public List getServerList() { - return ConfigRpcTransportClient.super.serverListManager.getServerUrls(); + return ConfigRpcTransportClient.super.serverListManager.getServerList(); } }); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigHttpClientManager.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigHttpClientManager.java index e5f96d5c40b..9afc49cfcf1 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigHttpClientManager.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigHttpClientManager.java @@ -39,6 +39,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URI; +import java.util.List; import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER; @@ -57,12 +58,7 @@ public class ConfigHttpClientManager implements Closeable { private static final int READ_TIME_OUT_MILLIS = 3000; - private static final NacosRestTemplate NACOS_REST_TEMPLATE; - - static { - NACOS_REST_TEMPLATE = HttpClientBeanHolder.getNacosRestTemplate(HTTP_CLIENT_FACTORY); - NACOS_REST_TEMPLATE.getInterceptors().add(new LimiterHttpClientRequestInterceptor()); - } + private final LimiterHttpClientRequestInterceptor limiterHttpClientRequestInterceptor = new LimiterHttpClientRequestInterceptor(); private static class ConfigHttpClientManagerInstance { @@ -101,7 +97,12 @@ public int getConnectTimeoutOrDefault(int connectTimeout) { * @return NacosRestTemplate */ public NacosRestTemplate getNacosRestTemplate() { - return NACOS_REST_TEMPLATE; + NacosRestTemplate nacosRestTemplate = HttpClientBeanHolder.getNacosRestTemplate(HTTP_CLIENT_FACTORY); + List interceptors = nacosRestTemplate.getInterceptors(); + if (!interceptors.contains(limiterHttpClientRequestInterceptor)) { + interceptors.add(limiterHttpClientRequestInterceptor); + } + return nacosRestTemplate; } /** diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigServerListManager.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigServerListManager.java new file mode 100644 index 00000000000..9edd643db10 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigServerListManager.java @@ -0,0 +1,222 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.nacos.client.config.impl; + +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.address.AbstractServerListManager; +import com.alibaba.nacos.client.env.NacosClientProperties; +import com.alibaba.nacos.client.utils.LogUtils; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.utils.StringUtils; +import org.slf4j.Logger; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +/** + * Config server list Manager. + * + * @author Nacos + */ +public class ConfigServerListManager extends AbstractServerListManager { + + private static final Logger LOGGER = LogUtils.logger(ConfigServerListManager.class); + + /** + * The name of the different environment. + */ + private final String name; + + private String tenant = ""; + + private volatile String currentServerAddr; + + private Iterator iterator; + + public ConfigServerListManager(NacosClientProperties properties) throws NacosException { + super(properties); + this.name = initServerName(properties); + String namespace = properties.getProperty(PropertyKeyConst.NAMESPACE); + if (StringUtils.isNotBlank(namespace)) { + this.tenant = namespace; + } + } + + @Override + public String getModuleName() { + return "Config"; + } + + @Override + public NacosRestTemplate getNacosRestTemplate() { + return ConfigHttpClientManager.getInstance().getNacosRestTemplate(); + } + + public void start() { + iterator = iterator(); + currentServerAddr = iterator.next(); + } + + private String initServerName(NacosClientProperties properties) { + String serverName; + //1.user define server name. + if (properties != null && properties.containsKey(PropertyKeyConst.SERVER_NAME)) { + serverName = properties.getProperty(PropertyKeyConst.SERVER_NAME); + } else { + serverName = getServerName(); + } + serverName = serverName.replaceAll("\\/", "_"); + serverName = serverName.replaceAll("\\:", "_"); + return serverName; + } + + Iterator iterator() { + List serverList = getServerList(); + if (serverList.isEmpty()) { + LOGGER.error("[{}] [iterator-serverlist] No server address defined!", name); + } + return new ServerAddressIterator(serverList); + } + + @Override + public String genNextServer() { + if (iterator == null || !iterator.hasNext()) { + refreshCurrentServerAddr(); + return currentServerAddr; + } + try { + return iterator.next(); + } catch (Exception e) { + //No nothing. + } + refreshCurrentServerAddr(); + return currentServerAddr; + } + + @Override + public String getCurrentServer() { + if (StringUtils.isBlank(currentServerAddr)) { + iterator = iterator(); + currentServerAddr = iterator.next(); + } + return currentServerAddr; + } + + public String getUrlString() { + return getServerList().toString(); + } + + @Override + public String toString() { + return "ServerManager-" + name + "-" + getUrlString(); + } + + public boolean contain(String ip) { + return getServerList().contains(ip); + } + + public void refreshCurrentServerAddr() { + iterator = iterator(); + currentServerAddr = iterator.next(); + } + + public void updateCurrentServerAddr(String currentServerAddr) { + this.currentServerAddr = currentServerAddr; + } + + public Iterator getIterator() { + return iterator; + } + + public String getName() { + return name; + } + + public String getTenant() { + return tenant; + } + + /** + * Sort the address list, with the same room priority. + */ + private static class ServerAddressIterator implements Iterator { + + static class RandomizedServerAddress implements Comparable { + + static Random random = new Random(); + + String serverIp; + + int priority = 0; + + int seed; + + public RandomizedServerAddress(String ip) { + try { + this.serverIp = ip; + /* + change random scope from 32 to Integer.MAX_VALUE to fix load balance issue + */ + this.seed = random.nextInt(Integer.MAX_VALUE); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public int compareTo(RandomizedServerAddress other) { + if (this.priority != other.priority) { + return other.priority - this.priority; + } else { + return other.seed - this.seed; + } + } + } + + public ServerAddressIterator(List source) { + sorted = new ArrayList<>(); + for (String address : source) { + sorted.add(new RandomizedServerAddress(address)); + } + Collections.sort(sorted); + iter = sorted.iterator(); + } + + @Override + public boolean hasNext() { + return iter.hasNext(); + } + + @Override + public String next() { + return iter.next().serverIp; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + final List sorted; + + final Iterator iter; + } +} \ No newline at end of file diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigTransportClient.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigTransportClient.java index b64d7635f18..60d321f1620 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigTransportClient.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigTransportClient.java @@ -53,7 +53,7 @@ public abstract class ConfigTransportClient { ScheduledExecutorService executor; - final ServerListManager serverListManager; + final ConfigServerListManager serverListManager; final Properties properties; @@ -67,7 +67,7 @@ public void shutdown() throws NacosException { securityProxy.shutdown(); } - public ConfigTransportClient(NacosClientProperties properties, ServerListManager serverListManager) { + public ConfigTransportClient(NacosClientProperties properties, ConfigServerListManager serverListManager) { String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE); if (StringUtils.isBlank(encodeTmp)) { @@ -79,7 +79,7 @@ public ConfigTransportClient(NacosClientProperties properties, ServerListManager this.tenant = properties.getProperty(PropertyKeyConst.NAMESPACE); this.serverListManager = serverListManager; this.properties = properties.asProperties(); - this.securityProxy = new SecurityProxy(serverListManager.getServerUrls(), + this.securityProxy = new SecurityProxy(serverListManager.getServerList(), ConfigHttpClientManager.getInstance().getNacosRestTemplate()); } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java deleted file mode 100644 index 52b1ad886bb..00000000000 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ServerListManager.java +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright 1999-2018 Alibaba Group Holding Ltd. - * - * Licensed 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 com.alibaba.nacos.client.config.impl; - -import com.alibaba.nacos.api.PropertyKeyConst; -import com.alibaba.nacos.api.SystemPropertyKeyConst; -import com.alibaba.nacos.api.exception.NacosException; -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; -import com.alibaba.nacos.common.http.client.NacosRestTemplate; -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.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; - -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.Random; -import java.util.StringTokenizer; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTPS_PREFIX; -import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTP_PREFIX; - -/** - * Serverlist Manager. - * - * @author Nacos - */ -public class ServerListManager implements Closeable { - - private static final Logger LOGGER = LogUtils.logger(ServerListManager.class); - - private final NacosRestTemplate nacosRestTemplate = ConfigHttpClientManager.getInstance().getNacosRestTemplate(); - - private final ScheduledExecutorService executorService = - new ScheduledThreadPoolExecutor(1, new NameThreadFactory("com.alibaba.nacos.client.ServerListManager")); - - /** - * The name of the different environment. - */ - private final String name; - - private String namespace = ""; - - private String tenant = ""; - - public static final String DEFAULT_NAME = "default"; - - public static final String CUSTOM_NAME = "custom"; - - public static final String FIXED_NAME = "fixed"; - - private final int initServerListRetryTimes = 5; - - final boolean isFixed; - - boolean isStarted; - - private String endpoint; - - private int endpointPort = 8080; - - private String endpointContextPath; - - private String contentPath = ParamUtil.getDefaultContextPath(); - - private String serverListName = ParamUtil.getDefaultNodesPath(); - - volatile List serverUrls = new ArrayList<>(); - - private volatile String currentServerAddr; - - private Iterator iterator; - - public String addressServerUrl; - - private String serverAddrsStr; - - public ServerListManager() { - this.isFixed = false; - this.isStarted = false; - this.name = DEFAULT_NAME; - } - - public ServerListManager(List fixed) { - this(fixed, null); - } - - public ServerListManager(List fixed, String namespace) { - this.isFixed = true; - this.isStarted = true; - List serverAddrs = new ArrayList<>(); - for (String serverAddr : fixed) { - String[] serverAddrArr = InternetAddressUtil.splitIPPortStr(serverAddr); - if (serverAddrArr.length == 1) { - serverAddrs - .add(serverAddrArr[0] + InternetAddressUtil.IP_PORT_SPLITER + ParamUtil.getDefaultServerPort()); - } else { - serverAddrs.add(serverAddr); - } - } - this.serverUrls = new ArrayList<>(serverAddrs); - if (StringUtils.isNotBlank(namespace)) { - this.namespace = namespace; - this.tenant = namespace; - } - this.name = initServerName(null); - } - - public ServerListManager(String host, int port) { - this.isFixed = false; - this.isStarted = false; - this.endpoint = host; - this.endpointPort = port; - - this.name = initServerName(null); - initAddressServerUrl(null); - } - - public ServerListManager(String endpoint) throws NacosException { - this(endpoint, null); - } - - public ServerListManager(String endpoint, String namespace) throws NacosException { - this.isFixed = false; - this.isStarted = false; - 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; - initParam(properties); - if (StringUtils.isNotEmpty(serverAddrsStr)) { - this.isFixed = true; - List serverAddrs = new ArrayList<>(); - StringTokenizer serverAddrsTokens = new StringTokenizer(this.serverAddrsStr, ",;"); - while (serverAddrsTokens.hasMoreTokens()) { - String serverAddr = serverAddrsTokens.nextToken().trim(); - if (serverAddr.startsWith(HTTP_PREFIX) || serverAddr.startsWith(HTTPS_PREFIX)) { - serverAddrs.add(serverAddr); - } else { - String[] serverAddrArr = InternetAddressUtil.splitIPPortStr(serverAddr); - if (serverAddrArr.length == 1) { - serverAddrs.add(HTTP_PREFIX + serverAddrArr[0] + InternetAddressUtil.IP_PORT_SPLITER + ParamUtil - .getDefaultServerPort()); - } else { - serverAddrs.add(HTTP_PREFIX + serverAddr); - } - } - } - this.serverUrls = serverAddrs; - this.name = initServerName(properties); - } else { - if (StringUtils.isBlank(endpoint)) { - throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank"); - } - this.isFixed = false; - 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) { - String serverName; - //1.user define server name. - if (properties != null && properties.containsKey(PropertyKeyConst.SERVER_NAME)) { - serverName = properties.getProperty(PropertyKeyConst.SERVER_NAME); - } else { - // 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 - 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; - } - - private void initAddressServerUrl(NacosClientProperties properties) { - 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, 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)); - - } - this.addressServerUrl = addressServerUrlTem.toString(); - LOGGER.info("serverName = {}, address server url = {}", this.name, this.addressServerUrl); - } - - private void initParam(NacosClientProperties properties) { - 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.ENDPOINT_CLUSTER_NAME, - properties.getProperty(PropertyKeyConst.CLUSTER_NAME)); - if (!StringUtils.isBlank(serverListNameTmp)) { - this.serverListName = serverListNameTmp; - } - } - - 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, - String.valueOf(ParamUtil.USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE))); - if (Boolean.parseBoolean(isUseEndpointRuleParsing)) { - String endpointUrl = ParamUtil.parsingEndpointRule(endpointTmp); - if (StringUtils.isNotBlank(endpointUrl)) { - this.serverAddrsStr = ""; - } - endpointTmp = endpointUrl; - } - this.endpoint = StringUtils.isNotBlank(endpointTmp) ? endpointTmp : ""; - } - - /** - * Start. - * - * @throws NacosException nacos exception - */ - public synchronized void start() throws NacosException { - - if (isStarted || isFixed) { - return; - } - - GetServerListTask getServersTask = new GetServerListTask(addressServerUrl); - for (int i = 0; i < initServerListRetryTimes && serverUrls.isEmpty(); ++i) { - getServersTask.run(); - if (!serverUrls.isEmpty()) { - break; - } - try { - this.wait((i + 1) * 100L); - } catch (Exception e) { - LOGGER.warn("get serverlist fail,url: {}", addressServerUrl); - } - } - - if (serverUrls.isEmpty()) { - LOGGER.error("[init-serverlist] fail to get NACOS-server serverlist! env: {}, url: {}", name, - addressServerUrl); - throw new NacosException(NacosException.SERVER_ERROR, - "fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl); - } - - // executor schedules the timer task - this.executorService.scheduleWithFixedDelay(getServersTask, 0L, 30L, TimeUnit.SECONDS); - isStarted = true; - } - - public List getServerUrls() { - return serverUrls; - } - - Iterator iterator() { - if (serverUrls.isEmpty()) { - LOGGER.error("[{}] [iterator-serverlist] No server address defined!", name); - } - return new ServerAddressIterator(serverUrls); - } - - @Override - public void shutdown() throws NacosException { - String className = this.getClass().getName(); - LOGGER.info("{} do shutdown begin", className); - ThreadUtils.shutdownThreadPool(executorService, LOGGER); - LOGGER.info("{} do shutdown stop", className); - } - - class GetServerListTask implements Runnable { - - final String url; - - GetServerListTask(String url) { - this.url = url; - } - - @Override - public void run() { - /* - get serverlist from nameserver - */ - try { - updateIfChanged(getApacheServerList(url, name)); - } catch (Exception e) { - LOGGER.error("[" + name + "][update-serverlist] failed to update serverlist from address server!", e); - } - } - } - - private void updateIfChanged(List newList) { - if (null == newList || newList.isEmpty()) { - LOGGER.warn("[update-serverlist] current serverlist from address server is empty!!!"); - return; - } - - List newServerAddrList = new ArrayList<>(); - for (String server : newList) { - if (server.startsWith(HTTP_PREFIX) || server.startsWith(HTTPS_PREFIX)) { - newServerAddrList.add(server); - } else { - newServerAddrList.add(HTTP_PREFIX + server); - } - } - - /* - no change - */ - if (newServerAddrList.equals(serverUrls)) { - return; - } - serverUrls = new ArrayList<>(newServerAddrList); - iterator = iterator(); - currentServerAddr = iterator.next(); - - // Using unified event processor, NotifyCenter - NotifyCenter.publishEvent(new ServerListChangeEvent()); - LOGGER.info("[{}] [update-serverList] serverList updated to {}", name, serverUrls); - } - - private List getApacheServerList(String url, String name) { - try { - HttpRestResult httpResult = nacosRestTemplate.get(url, Header.EMPTY, Query.EMPTY, String.class); - - if (httpResult.ok()) { - if (DEFAULT_NAME.equals(name)) { - EnvUtil.setSelfEnv(httpResult.getHeader().getOriginalResponseHeader()); - } - List lines = IoUtils.readLines(new StringReader(httpResult.getData())); - List result = new ArrayList<>(lines.size()); - for (String serverAddr : lines) { - if (StringUtils.isNotBlank(serverAddr)) { - String[] ipPort = InternetAddressUtil.splitIPPortStr(serverAddr.trim()); - String ip = ipPort[0].trim(); - if (ipPort.length == 1) { - result.add(ip + InternetAddressUtil.IP_PORT_SPLITER + ParamUtil.getDefaultServerPort()); - } else { - result.add(serverAddr); - } - } - } - return result; - } else { - LOGGER.error("[check-serverlist] error. addressServerUrl: {}, code: {}", addressServerUrl, - httpResult.getCode()); - return null; - } - } catch (Exception e) { - LOGGER.error("[check-serverlist] exception. url: " + url, e); - return null; - } - } - - String getUrlString() { - return serverUrls.toString(); - } - - String getFixedNameSuffix(String... serverIps) { - StringBuilder sb = new StringBuilder(); - String split = ""; - for (String serverIp : serverIps) { - sb.append(split); - serverIp = serverIp.replaceAll("http(s)?://", ""); - sb.append(serverIp.replaceAll(":", "_")); - split = "-"; - } - return sb.toString(); - } - - @Override - public String toString() { - return "ServerManager-" + name + "-" + getUrlString(); - } - - public boolean contain(String ip) { - - return serverUrls.contains(ip); - } - - public void refreshCurrentServerAddr() { - iterator = iterator(); - currentServerAddr = iterator.next(); - } - - public String getNextServerAddr() { - if (iterator == null || !iterator.hasNext()) { - refreshCurrentServerAddr(); - return currentServerAddr; - } - try { - return iterator.next(); - } catch (Exception e) { - //No nothing. - } - refreshCurrentServerAddr(); - return currentServerAddr; - - } - - public String getCurrentServerAddr() { - if (StringUtils.isBlank(currentServerAddr)) { - iterator = iterator(); - currentServerAddr = iterator.next(); - } - return currentServerAddr; - } - - public void updateCurrentServerAddr(String currentServerAddr) { - this.currentServerAddr = currentServerAddr; - } - - public Iterator getIterator() { - return iterator; - } - - public String getContentPath() { - return contentPath; - } - - public String getName() { - return name; - } - - public String getNamespace() { - return namespace; - } - - public String getTenant() { - return tenant; - } - - /** - * Sort the address list, with the same room priority. - */ - private static class ServerAddressIterator implements Iterator { - - static class RandomizedServerAddress implements Comparable { - - static Random random = new Random(); - - String serverIp; - - int priority = 0; - - int seed; - - public RandomizedServerAddress(String ip) { - try { - this.serverIp = ip; - /* - change random scope from 32 to Integer.MAX_VALUE to fix load balance issue - */ - this.seed = random.nextInt(Integer.MAX_VALUE); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public int compareTo(RandomizedServerAddress other) { - if (this.priority != other.priority) { - return other.priority - this.priority; - } else { - return other.seed - this.seed; - } - } - } - - public ServerAddressIterator(List source) { - sorted = new ArrayList<>(); - for (String address : source) { - sorted.add(new RandomizedServerAddress(address)); - } - Collections.sort(sorted); - iter = sorted.iterator(); - } - - @Override - public boolean hasNext() { - return iter.hasNext(); - } - - @Override - public String next() { - return iter.next().serverIp; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - final List sorted; - - final Iterator iter; - } -} diff --git a/client/src/main/java/com/alibaba/nacos/client/constant/Constants.java b/client/src/main/java/com/alibaba/nacos/client/constant/Constants.java index f38cc7db7ab..afc0f0d5732 100644 --- a/client/src/main/java/com/alibaba/nacos/client/constant/Constants.java +++ b/client/src/main/java/com/alibaba/nacos/client/constant/Constants.java @@ -59,4 +59,11 @@ public static class Security { } + public static class Address { + + public static final int ENDPOINT_SERVER_LIST_PROVIDER_ORDER = 500; + + public static final int ADDRESS_SERVER_LIST_PROVIDER_ORDER = 499; + } + } diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingMaintainService.java b/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingMaintainService.java index 5acd55df919..07a8033c5c5 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingMaintainService.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingMaintainService.java @@ -26,7 +26,7 @@ import com.alibaba.nacos.api.selector.ExpressionSelector; import com.alibaba.nacos.api.selector.NoneSelector; import com.alibaba.nacos.client.env.NacosClientProperties; -import com.alibaba.nacos.client.naming.core.ServerListManager; +import com.alibaba.nacos.client.naming.core.NamingServerListManager; import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientManager; import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy; import com.alibaba.nacos.client.naming.utils.InitUtils; @@ -57,7 +57,7 @@ public class NacosNamingMaintainService implements NamingMaintainService { private NamingHttpClientProxy serverProxy; - private ServerListManager serverListManager; + private NamingServerListManager serverListManager; private SecurityProxy securityProxy; @@ -79,7 +79,7 @@ private void init(Properties properties) throws NacosException { namespace = InitUtils.initNamespaceForNaming(nacosClientProperties); InitUtils.initSerialization(); InitUtils.initWebRootContext(nacosClientProperties); - serverListManager = new ServerListManager(nacosClientProperties, namespace); + serverListManager = new NamingServerListManager(nacosClientProperties, namespace); securityProxy = new SecurityProxy(serverListManager.getServerList(), NamingHttpClientManager.getInstance().getNacosRestTemplate()); initSecurityProxy(properties); diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/core/NamingServerListManager.java b/client/src/main/java/com/alibaba/nacos/client/naming/core/NamingServerListManager.java new file mode 100644 index 00000000000..5a9c8a57320 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/naming/core/NamingServerListManager.java @@ -0,0 +1,105 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.nacos.client.naming.core; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.exception.runtime.NacosLoadException; +import com.alibaba.nacos.client.address.AbstractServerListManager; +import com.alibaba.nacos.client.address.AddressServerListProvider; +import com.alibaba.nacos.client.env.NacosClientProperties; +import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientManager; +import com.alibaba.nacos.client.utils.LogUtils; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import org.slf4j.Logger; + +import java.util.List; +import java.util.Properties; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Naming server list manager. + * + * @author xiweng.yy + */ +public class NamingServerListManager extends AbstractServerListManager { + + private static final Logger LOGGER = LogUtils.logger(NamingServerListManager.class); + + private final AtomicInteger currentIndex = new AtomicInteger(); + + private String nacosDomain; + + private boolean isDomain; + + public NamingServerListManager(Properties properties) throws NacosException { + this(NacosClientProperties.PROTOTYPE.derive(properties)); + } + + public NamingServerListManager(NacosClientProperties properties) throws NacosException { + this(properties, ""); + } + + public NamingServerListManager(NacosClientProperties properties, String namespace) throws NacosException { + super(properties, namespace); + List serverList = getServerList(); + if (serverList.isEmpty()) { + throw new NacosLoadException("serverList is empty,please check configuration"); + } else { + currentIndex.set(new Random().nextInt(serverList.size())); + } + if (serverListProvider instanceof AddressServerListProvider) { + if (serverList.size() == 1) { + isDomain = true; + nacosDomain = serverList.get(0); + } + } + } + + public String getNacosDomain() { + return nacosDomain; + } + + public boolean isDomain() { + return isDomain; + } + + public void setDomain(final boolean domain) { + isDomain = domain; + } + + @Override + public String getModuleName() { + return "Naming"; + } + + @Override + public NacosRestTemplate getNacosRestTemplate() { + return NamingHttpClientManager.getInstance().getNacosRestTemplate(); + } + + @Override + public String genNextServer() { + int index = currentIndex.incrementAndGet() % getServerList().size(); + return getServerList().get(index); + } + + @Override + public String getCurrentServer() { + return getServerList().get(currentIndex.get() % getServerList().size()); + } +} diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/core/ServerListManager.java b/client/src/main/java/com/alibaba/nacos/client/naming/core/ServerListManager.java deleted file mode 100644 index 3aa70dce4bd..00000000000 --- a/client/src/main/java/com/alibaba/nacos/client/naming/core/ServerListManager.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 1999-2018 Alibaba Group Holding Ltd. - * - * Licensed 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 com.alibaba.nacos.client.naming.core; - -import com.alibaba.nacos.api.PropertyKeyConst; -import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.api.exception.runtime.NacosLoadException; -import com.alibaba.nacos.client.env.NacosClientProperties; -import com.alibaba.nacos.client.naming.event.ServerListChangedEvent; -import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientManager; -import com.alibaba.nacos.client.naming.utils.CollectionUtils; -import com.alibaba.nacos.client.naming.utils.InitUtils; -import com.alibaba.nacos.client.naming.utils.NamingHttpUtil; -import com.alibaba.nacos.client.utils.ContextPathUtil; -import com.alibaba.nacos.client.utils.ParamUtil; -import com.alibaba.nacos.common.executor.NameThreadFactory; -import com.alibaba.nacos.common.http.HttpRestResult; -import com.alibaba.nacos.common.http.client.NacosRestTemplate; -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.remote.client.ServerListFactory; -import com.alibaba.nacos.common.utils.IoUtils; -import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.common.utils.ThreadUtils; - -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Properties; -import java.util.Random; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER; - -/** - * Server list manager. - * - * @author xiweng.yy - */ -public class ServerListManager implements ServerListFactory, Closeable { - - private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getInstance().getNacosRestTemplate(); - - private final long refreshServerListInternal = TimeUnit.SECONDS.toMillis(30); - - private final String namespace; - - private final AtomicInteger currentIndex = new AtomicInteger(); - - private final List serverList = new ArrayList<>(); - - private volatile List serversFromEndpoint = new ArrayList<>(); - - private ScheduledExecutorService refreshServerListExecutor; - - private String endpoint; - - private String endpointContentPath; - - private String contentPath = ParamUtil.getDefaultContextPath(); - - private String serverListName = ParamUtil.getDefaultNodesPath(); - - private String nacosDomain; - - private long lastServerListRefreshTime = 0L; - - public ServerListManager(Properties properties) { - this(NacosClientProperties.PROTOTYPE.derive(properties), null); - } - - public ServerListManager(NacosClientProperties properties, String namespace) { - this.namespace = namespace; - initServerAddr(properties); - if (getServerList().isEmpty()) { - throw new NacosLoadException("serverList is empty,please check configuration"); - } else { - currentIndex.set(new Random().nextInt(getServerList().size())); - } - } - - 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; - } - String serverListNameTmp = properties.getProperty(PropertyKeyConst.ENDPOINT_CLUSTER_NAME); - if (!StringUtils.isBlank(serverListNameTmp)) { - this.serverListName = serverListNameTmp; - } - - this.serversFromEndpoint = getServerListFromEndpoint(); - refreshServerListExecutor = new ScheduledThreadPoolExecutor(1, - new NameThreadFactory("com.alibaba.nacos.client.naming.server.list.refresher")); - refreshServerListExecutor - .scheduleWithFixedDelay(this::refreshServerListIfNeed, 0, refreshServerListInternal, - TimeUnit.MILLISECONDS); - } else { - String serverListFromProps = properties.getProperty(PropertyKeyConst.SERVER_ADDR); - if (StringUtils.isNotEmpty(serverListFromProps)) { - this.serverList.addAll(Arrays.asList(serverListFromProps.split(","))); - if (this.serverList.size() == 1) { - this.nacosDomain = serverListFromProps; - } - } - } - } - - private List getServerListFromEndpoint() { - try { - 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; - HttpRestResult restResult = nacosRestTemplate.get(urlString, header, query, String.class); - if (!restResult.ok()) { - throw new IOException( - "Error while requesting: " + urlString + "'. Server returned: " + restResult.getCode()); - } - String content = restResult.getData(); - List list = new ArrayList<>(); - for (String line : IoUtils.readLines(new StringReader(content))) { - if (!line.trim().isEmpty()) { - list.add(line.trim()); - } - } - return list; - } catch (Exception e) { - NAMING_LOGGER.error("[SERVER-LIST] failed to update server list.", e); - } - return new ArrayList<>(); - } - - private void refreshServerListIfNeed() { - try { - if (!CollectionUtils.isEmpty(serverList)) { - NAMING_LOGGER.debug("server list provided by user: " + serverList); - return; - } - if (System.currentTimeMillis() - lastServerListRefreshTime < refreshServerListInternal) { - return; - } - List list = getServerListFromEndpoint(); - if (CollectionUtils.isEmpty(list)) { - throw new Exception("Can not acquire Nacos list"); - } - if (null == serversFromEndpoint || !CollectionUtils.isEqualCollection(list, serversFromEndpoint)) { - NAMING_LOGGER.info("[SERVER-LIST] server list is updated: " + list); - serversFromEndpoint = list; - lastServerListRefreshTime = System.currentTimeMillis(); - NotifyCenter.publishEvent(new ServerListChangedEvent()); - } - } catch (Throwable e) { - NAMING_LOGGER.warn("failed to update server list", e); - } - } - - public boolean isDomain() { - return StringUtils.isNotBlank(nacosDomain); - } - - public String getNacosDomain() { - return nacosDomain; - } - - @Override - public List getServerList() { - return serverList.isEmpty() ? serversFromEndpoint : serverList; - } - - @Override - public String genNextServer() { - int index = currentIndex.incrementAndGet() % getServerList().size(); - return getServerList().get(index); - } - - @Override - public String getCurrentServer() { - return getServerList().get(currentIndex.get() % getServerList().size()); - } - - @Override - public void shutdown() throws NacosException { - String className = this.getClass().getName(); - NAMING_LOGGER.info("{} do shutdown begin", className); - if (null != refreshServerListExecutor) { - ThreadUtils.shutdownThreadPool(refreshServerListExecutor, NAMING_LOGGER); - } - NamingHttpClientManager.getInstance().shutdown(); - NAMING_LOGGER.info("{} do shutdown stop", className); - } -} diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/event/ServerListChangedEvent.java b/client/src/main/java/com/alibaba/nacos/client/naming/event/ServerListChangedEvent.java deleted file mode 100644 index 207a2bd84ed..00000000000 --- a/client/src/main/java/com/alibaba/nacos/client/naming/event/ServerListChangedEvent.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 1999-2021 Alibaba Group Holding Ltd. - * - * Licensed 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 com.alibaba.nacos.client.naming.event; - -import com.alibaba.nacos.common.notify.SlowEvent; - -/** - * Event of server list changed for naming. - * - * @author gengtuo.ygt - * on 2021/6/7 - */ -public class ServerListChangedEvent extends SlowEvent { -} diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxy.java b/client/src/main/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxy.java index 60d35afebe4..7fa7a8ab9e5 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxy.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxy.java @@ -17,7 +17,7 @@ package com.alibaba.nacos.client.naming.remote; import com.alibaba.nacos.plugin.auth.api.RequestResource; -import com.alibaba.nacos.client.naming.event.ServerListChangedEvent; +import com.alibaba.nacos.client.address.ServerListChangeEvent; import com.alibaba.nacos.client.security.SecurityProxy; import com.alibaba.nacos.client.utils.AppNameUtils; import com.alibaba.nacos.common.notify.listener.Subscriber; @@ -30,7 +30,7 @@ * * @author xiweng.yy */ -public abstract class AbstractNamingClientProxy extends Subscriber +public abstract class AbstractNamingClientProxy extends Subscriber implements NamingClientProxy { private static final String APP_FILED = "app"; diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/remote/NamingClientProxyDelegate.java b/client/src/main/java/com/alibaba/nacos/client/naming/remote/NamingClientProxyDelegate.java index 60ef15a9ae6..ac87ac9a193 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/remote/NamingClientProxyDelegate.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/remote/NamingClientProxyDelegate.java @@ -26,7 +26,7 @@ import com.alibaba.nacos.api.selector.AbstractSelector; import com.alibaba.nacos.client.env.NacosClientProperties; import com.alibaba.nacos.client.naming.cache.ServiceInfoHolder; -import com.alibaba.nacos.client.naming.core.ServerListManager; +import com.alibaba.nacos.client.naming.core.NamingServerListManager; import com.alibaba.nacos.client.naming.core.ServiceInfoUpdateService; import com.alibaba.nacos.client.naming.event.InstancesChangeNotifier; import com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy; @@ -53,7 +53,7 @@ */ public class NamingClientProxyDelegate implements NamingClientProxy { - private final ServerListManager serverListManager; + private final NamingServerListManager serverListManager; private final ServiceInfoUpdateService serviceInfoUpdateService; @@ -71,7 +71,7 @@ public NamingClientProxyDelegate(String namespace, ServiceInfoHolder serviceInfo NacosClientProperties properties, InstancesChangeNotifier changeNotifier) throws NacosException { this.serviceInfoUpdateService = new ServiceInfoUpdateService(properties, serviceInfoHolder, this, changeNotifier); - this.serverListManager = new ServerListManager(properties, namespace); + this.serverListManager = new NamingServerListManager(properties, namespace); this.serviceInfoHolder = serviceInfoHolder; this.securityProxy = new SecurityProxy(this.serverListManager.getServerList(), NamingHttpClientManager.getInstance().getNacosRestTemplate()); diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxy.java b/client/src/main/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxy.java index a240d5d747d..27e44ce1ff3 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxy.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxy.java @@ -46,7 +46,7 @@ import com.alibaba.nacos.client.env.NacosClientProperties; import com.alibaba.nacos.client.monitor.MetricsMonitor; import com.alibaba.nacos.client.naming.cache.ServiceInfoHolder; -import com.alibaba.nacos.client.naming.event.ServerListChangedEvent; +import com.alibaba.nacos.client.address.ServerListChangeEvent; import com.alibaba.nacos.client.naming.remote.AbstractNamingClientProxy; import com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService; import com.alibaba.nacos.client.naming.remote.gprc.redo.data.BatchInstanceRedoData; @@ -119,13 +119,13 @@ private void start(ServerListFactory serverListFactory, ServiceInfoHolder servic } @Override - public void onEvent(ServerListChangedEvent event) { + public void onEvent(ServerListChangeEvent event) { rpcClient.onServerListChange(); } @Override public Class subscribeType() { - return ServerListChangedEvent.class; + return ServerListChangeEvent.class; } @Override diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/remote/http/NamingHttpClientProxy.java b/client/src/main/java/com/alibaba/nacos/client/naming/remote/http/NamingHttpClientProxy.java index e2c831d7d8c..a8324483b02 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/remote/http/NamingHttpClientProxy.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/remote/http/NamingHttpClientProxy.java @@ -28,16 +28,16 @@ import com.alibaba.nacos.api.selector.AbstractSelector; import com.alibaba.nacos.api.selector.ExpressionSelector; import com.alibaba.nacos.api.selector.SelectorType; +import com.alibaba.nacos.client.address.ServerListChangeEvent; import com.alibaba.nacos.client.env.NacosClientProperties; import com.alibaba.nacos.client.monitor.MetricsMonitor; -import com.alibaba.nacos.client.naming.core.ServerListManager; -import com.alibaba.nacos.client.naming.event.ServerListChangedEvent; +import com.alibaba.nacos.client.naming.core.NamingServerListManager; import com.alibaba.nacos.client.naming.remote.AbstractNamingClientProxy; import com.alibaba.nacos.client.naming.utils.CollectionUtils; -import com.alibaba.nacos.client.naming.utils.NamingHttpUtil; import com.alibaba.nacos.client.naming.utils.UtilAndComs; import com.alibaba.nacos.client.security.SecurityProxy; import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.HttpUtils; import com.alibaba.nacos.common.http.client.NacosRestTemplate; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.Query; @@ -72,6 +72,8 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy { private static final int DEFAULT_SERVER_PORT = 8848; + private static final String MODULE_NAME = "Naming"; + private static final String IP_PARAM = "ip"; private static final String PORT_PARAM = "port"; @@ -100,13 +102,13 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy { private final String namespaceId; - private final ServerListManager serverListManager; + private final NamingServerListManager serverListManager; private final int maxRetry; private int serverPort = DEFAULT_SERVER_PORT; - public NamingHttpClientProxy(String namespaceId, SecurityProxy securityProxy, ServerListManager serverListManager, + public NamingHttpClientProxy(String namespaceId, SecurityProxy securityProxy, NamingServerListManager serverListManager, NacosClientProperties properties) { super(securityProxy); this.serverListManager = serverListManager; @@ -117,13 +119,13 @@ public NamingHttpClientProxy(String namespaceId, SecurityProxy securityProxy, Se } @Override - public void onEvent(ServerListChangedEvent event) { + public void onEvent(ServerListChangeEvent event) { // do nothing in http client } @Override public Class subscribeType() { - return ServerListChangedEvent.class; + return ServerListChangeEvent.class; } @Override @@ -356,7 +358,6 @@ public String reqApi(String api, Map params, Map } NacosException exception = new NacosException(); - if (serverListManager.isDomain()) { String nacosDomain = serverListManager.getNacosDomain(); for (int i = 0; i < maxRetry; i++) { @@ -414,7 +415,7 @@ public String callServer(String api, Map params, Map restMap = (Map) restMapField.get(null); + cachedNacosRestTemplate = restMap.get( + "com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$ConfigHttpClientFactory"); + restMap.put("com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$ConfigHttpClientFactory", nacosRestTemplate); } @AfterEach void tearDown() throws Exception { StsConfig.getInstance().setSecurityCredentials(null); StsConfig.getInstance().setSecurityCredentialsUrl(securityCredentialsUrl); - Field field = NacosRestTemplate.class.getDeclaredField("requestClient"); - field.setAccessible(true); - field.set(ConfigHttpClientManager.getInstance().getNacosRestTemplate(), httpClient); + if (null != cachedNacosRestTemplate) { + Field restMapField = HttpClientBeanHolder.class.getDeclaredField("SINGLETON_REST"); + restMapField.setAccessible(true); + Map restMap = (Map) restMapField.get(null); + restMap.put("com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$ConfigHttpClientFactory", + cachedNacosRestTemplate); + } clearForSts(); } @@ -100,22 +106,20 @@ void testGetStsCredentialFromStringCache() throws NoSuchFieldException, IllegalA @Test void testGetStsCredentialFromRequest() throws Exception { StsCredential stsCredential = buildMockStsCredential(); - HttpClientResponse response = mock(HttpClientResponse.class); - when(response.getStatusCode()).thenReturn(200); - when(response.getHeaders()).thenReturn(Header.newInstance()); - when(response.getBody()).thenReturn(new ByteArrayInputStream(JacksonUtils.toJsonBytes(stsCredential))); - when(mockRest.execute(any(), any(), any())).thenReturn(response); + mockResult = new HttpRestResult(); + mockResult.setData(JacksonUtils.toJson(stsCredential)); + mockResult.setCode(200); + when(nacosRestTemplate.get(any(), any(), any(), any())).thenReturn(mockResult); assertEquals(stsCredential.toString(), StsCredentialHolder.getInstance().getStsCredential().toString()); } @Test void testGetStsCredentialFromRequestFailure() throws Exception { assertThrows(NacosRuntimeException.class, () -> { - HttpClientResponse response = mock(HttpClientResponse.class); - when(response.getStatusCode()).thenReturn(500); - when(response.getHeaders()).thenReturn(Header.newInstance()); - when(response.getBody()).thenReturn(new ByteArrayInputStream(new byte[0])); - when(mockRest.execute(any(), any(), any())).thenReturn(response); + mockResult = new HttpRestResult(); + mockResult.setData(""); + mockResult.setCode(500); + when(nacosRestTemplate.get(any(), any(), any(), any())).thenReturn(mockResult); StsCredentialHolder.getInstance().getStsCredential(); }); } @@ -123,7 +127,7 @@ void testGetStsCredentialFromRequestFailure() throws Exception { @Test void testGetStsCredentialFromRequestException() throws Exception { assertThrows(NacosRuntimeException.class, () -> { - when(mockRest.execute(any(), any(), any())).thenThrow(new RuntimeException("test")); + when(nacosRestTemplate.get(any(), any(), any(), any())).thenThrow(new RuntimeException("test")); StsCredentialHolder.getInstance().getStsCredential(); }); } diff --git a/client/src/test/java/com/alibaba/nacos/client/config/NacosConfigServiceTest.java b/client/src/test/java/com/alibaba/nacos/client/config/NacosConfigServiceTest.java index 3cc54107c4a..dd9e2f8b89e 100644 --- a/client/src/test/java/com/alibaba/nacos/client/config/NacosConfigServiceTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/config/NacosConfigServiceTest.java @@ -16,14 +16,15 @@ package com.alibaba.nacos.client.config; +import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.config.ConfigType; import com.alibaba.nacos.api.config.listener.Listener; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.config.filter.impl.ConfigResponse; import com.alibaba.nacos.client.config.impl.ClientWorker; +import com.alibaba.nacos.client.config.impl.ConfigServerListManager; import com.alibaba.nacos.client.config.impl.ConfigTransportClient; import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor; -import com.alibaba.nacos.client.config.impl.ServerListManager; import com.alibaba.nacos.client.env.NacosClientProperties; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -33,6 +34,8 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; import java.lang.reflect.Field; import java.util.Arrays; @@ -45,6 +48,7 @@ import static org.mockito.ArgumentMatchers.eq; @ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) class NacosConfigServiceTest { private NacosConfigService nacosConfigService; @@ -181,8 +185,10 @@ public void receiveConfigInfo(String configInfo) { } }; - final NacosClientProperties properties = NacosClientProperties.PROTOTYPE.derive(new Properties()); - Mockito.when(mockWoker.getAgent()).thenReturn(new ConfigTransportClient(properties, new ServerListManager()) { + Properties properties = new Properties(); + properties.put(PropertyKeyConst.SERVER_ADDR, "aaa"); + final NacosClientProperties nacosProperties = NacosClientProperties.PROTOTYPE.derive(properties); + Mockito.when(mockWoker.getAgent()).thenReturn(new ConfigTransportClient(nacosProperties, new ConfigServerListManager(nacosProperties)) { @Override public void startInternal() throws NacosException { // NOOP diff --git a/client/src/test/java/com/alibaba/nacos/client/config/http/ServerHttpAgentTest.java b/client/src/test/java/com/alibaba/nacos/client/config/http/ServerHttpAgentTest.java index 6f512437222..d73f2ede288 100644 --- a/client/src/test/java/com/alibaba/nacos/client/config/http/ServerHttpAgentTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/config/http/ServerHttpAgentTest.java @@ -18,7 +18,9 @@ import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.client.config.impl.ServerListManager; +import com.alibaba.nacos.client.config.impl.ConfigServerListManager; +import com.alibaba.nacos.client.env.NacosClientProperties; +import com.alibaba.nacos.common.http.HttpClientBeanHolder; import com.alibaba.nacos.common.http.HttpClientConfig; import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.http.client.NacosRestTemplate; @@ -41,6 +43,7 @@ import java.net.SocketTimeoutException; import java.util.Collections; import java.util.Iterator; +import java.util.Map; import java.util.Properties; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -49,7 +52,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -62,10 +67,12 @@ class ServerHttpAgentTest { private static final String SERVER_ADDRESS_2 = "http://2.2.2.2:8848"; @Mock - ServerListManager serverListManager; + ConfigServerListManager serverListManager; + + NacosRestTemplate cachedNacosRestTemplate; @Mock - HttpRestResult mockResult; + HttpRestResult mockResult; @Mock Iterator mockIterator; @@ -75,13 +82,26 @@ class ServerHttpAgentTest { ServerHttpAgent serverHttpAgent; + HttpRestResult httpRestResult; + @BeforeEach - void setUp() throws NoSuchFieldException, IllegalAccessException { + void setUp() throws Exception { serverHttpAgent = new ServerHttpAgent(serverListManager, new Properties()); injectRestTemplate(); - when(serverListManager.getCurrentServerAddr()).thenReturn(SERVER_ADDRESS_1); + when(serverListManager.getCurrentServer()).thenReturn(SERVER_ADDRESS_1); when(serverListManager.getIterator()).thenReturn(mockIterator); + when(serverListManager.getServerList()).thenReturn(Collections.singletonList(SERVER_ADDRESS_2)); when(mockIterator.next()).thenReturn(SERVER_ADDRESS_2); + Field restMapField = HttpClientBeanHolder.class.getDeclaredField("SINGLETON_REST"); + restMapField.setAccessible(true); + Map restMap = (Map) restMapField.get(null); + cachedNacosRestTemplate = restMap.get( + "com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$ConfigHttpClientFactory"); + restMap.put("com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$ConfigHttpClientFactory", nacosRestTemplate); + httpRestResult = new HttpRestResult(); + httpRestResult.setData("127.0.0.1:8848"); + httpRestResult.setCode(200); + Mockito.when(nacosRestTemplate.get(contains("aaa:8080"), any(), any(), any())).thenReturn(httpRestResult); } private void injectRestTemplate() throws NoSuchFieldException, IllegalAccessException { @@ -91,13 +111,22 @@ private void injectRestTemplate() throws NoSuchFieldException, IllegalAccessExce } @AfterEach - void tearDown() throws NacosException { + void tearDown() throws NacosException, NoSuchFieldException, IllegalAccessException { serverHttpAgent.shutdown(); + if (null != cachedNacosRestTemplate) { + Field restMapField = HttpClientBeanHolder.class.getDeclaredField("SINGLETON_REST"); + restMapField.setAccessible(true); + Map restMap = (Map) restMapField.get(null); + restMap.put("com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$ConfigHttpClientFactory", + cachedNacosRestTemplate); + } } @Test void testConstruct() throws NacosException { - ServerListManager server = new ServerListManager(); + NacosClientProperties mockedProperties = mock(NacosClientProperties.class); + when(mockedProperties.getProperty(PropertyKeyConst.ENDPOINT)).thenReturn("aaa"); + ConfigServerListManager server = new ConfigServerListManager(mockedProperties); final ServerHttpAgent serverHttpAgent1 = new ServerHttpAgent(server); assertNotNull(serverHttpAgent1); @@ -112,8 +141,11 @@ void testConstruct() throws NacosException { } @Test - void testGetterAndSetter() throws NacosException { - ServerListManager server = new ServerListManager("aaa", "namespace1"); + void testGetterAndSetter() throws Exception { + NacosClientProperties mockedProperties = mock(NacosClientProperties.class); + when(mockedProperties.getProperty(PropertyKeyConst.ENDPOINT)).thenReturn("aaa"); + when(mockedProperties.getProperty(PropertyKeyConst.NAMESPACE)).thenReturn("namespace1"); + ConfigServerListManager server = new ConfigServerListManager(mockedProperties); final ServerHttpAgent serverHttpAgent = new ServerHttpAgent(server, new Properties()); final String appname = ServerHttpAgent.getAppname(); @@ -127,7 +159,8 @@ void testGetterAndSetter() throws NacosException { assertNull(encode); assertEquals("namespace1", namespace); assertEquals("namespace1", tenant); - assertEquals("custom-aaa_8080_nacos_serverlist_namespace1", name); + assertEquals("Config-custom-aaa_8080_nacos_serverlist_namespace1", name); + server.shutdown(); } @@ -135,7 +168,7 @@ void testGetterAndSetter() throws NacosException { void testLifCycle() throws NacosException { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, "aaa"); - ServerListManager server = Mockito.mock(ServerListManager.class); + ConfigServerListManager server = Mockito.mock(ConfigServerListManager.class); final ServerHttpAgent serverHttpAgent = new ServerHttpAgent(server, properties); serverHttpAgent.start(); diff --git a/client/src/test/java/com/alibaba/nacos/client/config/impl/ClientWorkerTest.java b/client/src/test/java/com/alibaba/nacos/client/config/impl/ClientWorkerTest.java index fa9687e41eb..7c3cd312962 100644 --- a/client/src/test/java/com/alibaba/nacos/client/config/impl/ClientWorkerTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/config/impl/ClientWorkerTest.java @@ -108,7 +108,7 @@ void before() { Properties properties = new Properties(); properties.put(PropertyKeyConst.NAMESPACE, TEST_NAMESPACE); ConfigFilterChainManager filter = new ConfigFilterChainManager(properties); - ServerListManager serverListManager = Mockito.mock(ServerListManager.class); + ConfigServerListManager serverListManager = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties); try { clientWorker = new ClientWorker(filter, serverListManager, nacosClientProperties); @@ -128,7 +128,7 @@ void after() { void testConstruct() throws NacosException { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -139,7 +139,7 @@ void testConstruct() throws NacosException { void testAddListenerWithoutTenant() throws NacosException { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -169,7 +169,7 @@ public void receiveConfigInfo(String configInfo) { void testListenerWithTenant() throws NacosException { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -215,7 +215,7 @@ public void receiveConfigInfo(String configInfo) { void testPublishConfigSuccess() throws NacosException { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -244,7 +244,7 @@ void testPublishConfigSuccess() throws NacosException { void testPublishConfigFail() throws NacosException { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -273,7 +273,7 @@ void testPublishConfigFail() throws NacosException { void testPublishConfigException() throws NacosException { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -302,7 +302,7 @@ void testRemoveConfig() throws NacosException { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -329,7 +329,7 @@ void testRemoveConfig() throws NacosException { void testGeConfigConfigSuccess() throws NacosException { Properties prop = new Properties(); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(null, agent, nacosClientProperties); @@ -355,7 +355,7 @@ void testHandleConfigChangeReqeust() throws Exception { String tenant = "c"; prop.put(NAMESPACE, tenant); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(null, agent, nacosClientProperties); @@ -385,7 +385,7 @@ void testHandleClientMetricsReqeust() throws Exception { String tenant = "c"; prop.put(NAMESPACE, tenant); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(null, agent, nacosClientProperties); @@ -431,7 +431,7 @@ void testHandleClientMetricsReqeust() throws Exception { void testGeConfigConfigNotFound() throws NacosException { Properties prop = new Properties(); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(null, agent, nacosClientProperties); @@ -454,7 +454,7 @@ void testGeConfigConfigNotFound() throws NacosException { void testGeConfigConfigConflict() throws NacosException { Properties prop = new Properties(); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(null, agent, nacosClientProperties); @@ -477,7 +477,7 @@ void testGeConfigConfigConflict() throws NacosException { void testShutdown() throws NacosException, NoSuchFieldException, IllegalAccessException { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -495,7 +495,7 @@ void testShutdown() throws NacosException, NoSuchFieldException, IllegalAccessEx void testExecuteConfigListen() throws Exception { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); Mockito.when(agent.getName()).thenReturn("mocktest"); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -621,7 +621,7 @@ private CacheData useLocalCache(ConfigFilterChainManager filter, String envName, void testIsHealthServer() throws NacosException, NoSuchFieldException, IllegalAccessException { Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); @@ -645,7 +645,7 @@ void testPutCache() throws Exception { putCacheMethod.setAccessible(true); Properties prop = new Properties(); ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties()); - ServerListManager agent = Mockito.mock(ServerListManager.class); + ConfigServerListManager agent = Mockito.mock(ConfigServerListManager.class); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop); ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties); String key = "testKey"; diff --git a/client/src/test/java/com/alibaba/nacos/client/config/impl/ServerListManagerTest.java b/client/src/test/java/com/alibaba/nacos/client/config/impl/ConfigServerListManagerTest.java similarity index 52% rename from client/src/test/java/com/alibaba/nacos/client/config/impl/ServerListManagerTest.java rename to client/src/test/java/com/alibaba/nacos/client/config/impl/ConfigServerListManagerTest.java index 7915ede5284..1cce63b0c4f 100644 --- a/client/src/test/java/com/alibaba/nacos/client/config/impl/ServerListManagerTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/config/impl/ConfigServerListManagerTest.java @@ -18,13 +18,26 @@ import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.address.AbstractServerListManager; +import com.alibaba.nacos.client.address.AbstractServerListProvider; +import com.alibaba.nacos.client.address.EndpointServerListProvider; +import com.alibaba.nacos.client.address.ServerListProvider; import com.alibaba.nacos.client.env.NacosClientProperties; +import com.alibaba.nacos.common.http.HttpClientBeanHolder; +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; import java.lang.reflect.Field; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; +import java.util.Map; import java.util.Properties; import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTP_PREFIX; @@ -33,43 +46,80 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.contains; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; -class ServerListManagerTest { +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +class ConfigServerListManagerTest { + + @Mock + NacosRestTemplate nacosRestTemplate; + + NacosRestTemplate cachedNacosRestTemplate; + + HttpRestResult httpRestResult; + + @BeforeEach + void setUp() throws Exception { + Field restMapField = HttpClientBeanHolder.class.getDeclaredField("SINGLETON_REST"); + restMapField.setAccessible(true); + Map restMap = (Map) restMapField.get(null); + cachedNacosRestTemplate = restMap.get( + "com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$ConfigHttpClientFactory"); + restMap.put("com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$ConfigHttpClientFactory", nacosRestTemplate); + httpRestResult = new HttpRestResult<>(); + httpRestResult.setData("127.0.0.1:8848"); + httpRestResult.setCode(200); + when(nacosRestTemplate.get(contains("1.1.1.1:9090"), any(), any(), any())).thenReturn(httpRestResult); + } + + @AfterEach + void tearDown() throws Exception { + if (null != cachedNacosRestTemplate) { + Field restMapField = HttpClientBeanHolder.class.getDeclaredField("SINGLETON_REST"); + restMapField.setAccessible(true); + Map restMap = (Map) restMapField.get(null); + restMap.put("com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$ConfigHttpClientFactory", + cachedNacosRestTemplate); + } + } @Test void testStart() throws NacosException { - final ServerListManager mgr = new ServerListManager("localhost", 0); - try { - mgr.start(); - fail(); - } catch (NacosException e) { - assertEquals( - "fail to get NACOS-server serverlist! env:custom-localhost_0_nacos_serverlist, not connnect url:http://localhost:0/nacos/serverlist", - e.getErrMsg()); - } + NacosClientProperties mockedProperties = mock(NacosClientProperties.class); + when(mockedProperties.getProperty(PropertyKeyConst.ENDPOINT)).thenReturn("1.1.1.1"); + when(mockedProperties.getProperty(PropertyKeyConst.ENDPOINT_PORT)).thenReturn("9090"); + final ConfigServerListManager mgr = new ConfigServerListManager(mockedProperties); + mgr.start(); mgr.shutdown(); } @Test void testGetter() throws NacosException { { - final ServerListManager mgr = new ServerListManager(); - assertEquals("nacos", mgr.getContentPath()); - assertEquals("default", mgr.getName()); - assertEquals("", mgr.getTenant()); - assertEquals("", mgr.getNamespace()); - assertEquals("1.1.1.1-2.2.2.2_8848", mgr.getFixedNameSuffix("http://1.1.1.1", "2.2.2.2:8848")); + NacosClientProperties mockedProperties = mock(NacosClientProperties.class); + when(mockedProperties.getProperty(PropertyKeyConst.SERVER_ADDR)).thenReturn("1.1.1.1"); + when(mockedProperties.getProperty(PropertyKeyConst.NAMESPACE)).thenReturn("namespace"); + final ConfigServerListManager mgr = new ConfigServerListManager(mockedProperties); + assertEquals("nacos", mgr.getContextPath()); + assertEquals("Config-fixed-namespace-1.1.1.1_8848", mgr.getName()); + assertEquals("namespace", mgr.getTenant()); + assertEquals("namespace", mgr.getNamespace()); + assertEquals("Config-fixed-namespace-1.1.1.1_8848", mgr.getServerName()); } { Properties properties = new Properties(); properties.put(PropertyKeyConst.CONTEXT_PATH, "aaa"); - properties.put(PropertyKeyConst.ENDPOINT, "endpoint"); + properties.put(PropertyKeyConst.ENDPOINT, "1.1.1.1"); + properties.put(PropertyKeyConst.ENDPOINT_PORT, "9090"); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties); - final ServerListManager mgr2 = new ServerListManager(nacosClientProperties); - assertEquals("aaa", mgr2.getContentPath()); + final ConfigServerListManager mgr2 = new ConfigServerListManager(nacosClientProperties); + assertEquals("aaa", mgr2.getContextPath()); } // Test https @@ -78,9 +128,9 @@ void testGetter() throws NacosException { properties.put(PropertyKeyConst.CONTEXT_PATH, "aaa"); properties.put(PropertyKeyConst.SERVER_ADDR, "https://1.1.1.1:8848"); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties); - final ServerListManager mgr2 = new ServerListManager(nacosClientProperties); - assertEquals("aaa", mgr2.getContentPath()); - assertEquals("[https://1.1.1.1:8848]", mgr2.getServerUrls().toString()); + final ConfigServerListManager mgr2 = new ConfigServerListManager(nacosClientProperties); + assertEquals("aaa", mgr2.getContextPath()); + assertEquals("[https://1.1.1.1:8848]", mgr2.getServerList().toString()); } { @@ -89,12 +139,12 @@ void testGetter() throws NacosException { properties2.put(PropertyKeyConst.SERVER_ADDR, "1.1.1.1:8848"); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties2); - final ServerListManager mgr3 = new ServerListManager(nacosClientProperties); - assertEquals(1, mgr3.getServerUrls().size()); - assertEquals("http://1.1.1.1:8848", mgr3.getServerUrls().get(0)); - assertEquals("[http://1.1.1.1:8848]", mgr3.getUrlString()); - assertTrue(mgr3.contain("http://1.1.1.1:8848")); - assertEquals("ServerManager-fixed-1.1.1.1_8848-[http://1.1.1.1:8848]", mgr3.toString()); + final ConfigServerListManager mgr3 = new ConfigServerListManager(nacosClientProperties); + assertEquals(1, mgr3.getServerList().size()); + assertEquals("1.1.1.1:8848", mgr3.getServerList().get(0)); + assertEquals("[1.1.1.1:8848]", mgr3.getUrlString()); + assertTrue(mgr3.contain("1.1.1.1:8848")); + assertEquals("ServerManager-Config-fixed-1.1.1.1_8848-[1.1.1.1:8848]", mgr3.toString()); } { @@ -103,12 +153,12 @@ void testGetter() throws NacosException { properties3.put(PropertyKeyConst.SERVER_ADDR, "1.1.1.1:8848,2.2.2.2:8848"); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties3); - final ServerListManager mgr4 = new ServerListManager(nacosClientProperties); - assertEquals(2, mgr4.getServerUrls().size()); - assertEquals("http://1.1.1.1:8848", mgr4.getServerUrls().get(0)); - assertEquals("http://2.2.2.2:8848", mgr4.getServerUrls().get(1)); - assertTrue(mgr4.contain("http://1.1.1.1:8848")); - assertEquals("ServerManager-fixed-1.1.1.1_8848-2.2.2.2_8848-[http://1.1.1.1:8848, http://2.2.2.2:8848]", + final ConfigServerListManager mgr4 = new ConfigServerListManager(nacosClientProperties); + assertEquals(2, mgr4.getServerList().size()); + assertEquals("1.1.1.1:8848", mgr4.getServerList().get(0)); + assertEquals("2.2.2.2:8848", mgr4.getServerList().get(1)); + assertTrue(mgr4.contain("1.1.1.1:8848")); + assertEquals("ServerManager-Config-fixed-1.1.1.1_8848-2.2.2.2_8848-[1.1.1.1:8848, 2.2.2.2:8848]", mgr4.toString()); } @@ -118,38 +168,38 @@ void testGetter() throws NacosException { properties4.put(PropertyKeyConst.SERVER_ADDR, "1.1.1.1:8848;2.2.2.2:8848"); final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties4); - final ServerListManager mgr5 = new ServerListManager(nacosClientProperties); - assertEquals(2, mgr5.getServerUrls().size()); - assertEquals("http://1.1.1.1:8848", mgr5.getServerUrls().get(0)); - assertEquals("http://2.2.2.2:8848", mgr5.getServerUrls().get(1)); - assertTrue(mgr5.contain("http://1.1.1.1:8848")); - assertEquals("ServerManager-fixed-1.1.1.1_8848-2.2.2.2_8848-[http://1.1.1.1:8848, http://2.2.2.2:8848]", + final ConfigServerListManager mgr5 = new ConfigServerListManager(nacosClientProperties); + assertEquals(2, mgr5.getServerList().size()); + assertEquals("1.1.1.1:8848", mgr5.getServerList().get(0)); + assertEquals("2.2.2.2:8848", mgr5.getServerList().get(1)); + assertTrue(mgr5.contain("1.1.1.1:8848")); + assertEquals("ServerManager-Config-fixed-1.1.1.1_8848-2.2.2.2_8848-[1.1.1.1:8848, 2.2.2.2:8848]", mgr5.toString()); } } @Test - void testIterator() { - List addrs = new ArrayList<>(); - String addr = "1.1.1.1:8848"; - addrs.add(addr); - final ServerListManager mgr = new ServerListManager(addrs, "aaa"); + void testIterator() throws NacosException { + NacosClientProperties mockedProperties = mock(NacosClientProperties.class); + when(mockedProperties.getProperty(PropertyKeyConst.SERVER_ADDR)).thenReturn("1.1.1.1:8848"); + when(mockedProperties.getProperty(PropertyKeyConst.NAMESPACE)).thenReturn("aaa"); + final ConfigServerListManager mgr = new ConfigServerListManager(mockedProperties); // new iterator final Iterator it = mgr.iterator(); assertTrue(it.hasNext()); - assertEquals(addr, it.next()); + assertEquals("1.1.1.1:8848", it.next()); assertNull(mgr.getIterator()); mgr.refreshCurrentServerAddr(); assertNotNull(mgr.getIterator()); - final String currentServerAddr = mgr.getCurrentServerAddr(); - assertEquals(addr, currentServerAddr); + final String currentServerAddr = mgr.getCurrentServer(); + assertEquals("1.1.1.1:8848", currentServerAddr); - final String nextServerAddr = mgr.getNextServerAddr(); - assertEquals(addr, nextServerAddr); + final String nextServerAddr = mgr.genNextServer(); + assertEquals("1.1.1.1:8848", nextServerAddr); final Iterator iterator1 = mgr.iterator(); assertTrue(iterator1.hasNext()); @@ -164,30 +214,30 @@ void testAddressServerBaseServerAddrsStr() throws NacosException { String endpointContextPath = "/endpoint"; properties.setProperty(PropertyKeyConst.CONTEXT_PATH, endpointContextPath); final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties); - ServerListManager serverListManager = new ServerListManager(clientProperties); - assertEquals(1, serverListManager.serverUrls.size()); - assertTrue(serverListManager.serverUrls.contains(HTTP_PREFIX + serverAddrStr)); + ConfigServerListManager serverListManager = new ConfigServerListManager(clientProperties); + assertEquals(1, serverListManager.getServerList().size()); + assertTrue(serverListManager.getServerList().contains(serverAddrStr)); } @Test void testAddressServerBaseEndpoint() throws NacosException { Properties properties = new Properties(); - String endpoint = "127.0.0.1"; + String endpoint = "1.1.1.1"; properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint); - String endpointPort = "8080"; + String endpointPort = "9090"; 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); - assertTrue(serverListManager.addressServerUrl.startsWith( + ConfigServerListManager serverListManager = new ConfigServerListManager(clientProperties); + assertTrue(serverListManager.getAddressSource().startsWith( HTTP_PREFIX + endpoint + ":" + endpointPort + endpointContextPath)); } @Test void testInitParam() throws NacosException, NoSuchFieldException, IllegalAccessException { Properties properties = new Properties(); - String endpoint = "127.0.0.1"; + String endpoint = "1.1.1.1"; properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint); String endpointPort = "9090"; properties.setProperty(PropertyKeyConst.ENDPOINT_PORT, endpointPort); @@ -196,32 +246,36 @@ void testInitParam() throws NacosException, NoSuchFieldException, IllegalAccessE 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"); + ConfigServerListManager serverListManager = new ConfigServerListManager(clientProperties); + Field providerField = AbstractServerListManager.class.getDeclaredField("serverListProvider"); + providerField.setAccessible(true); + ServerListProvider serverListProvider = (ServerListProvider) providerField.get(serverListManager); + + Field endpointField = EndpointServerListProvider.class.getDeclaredField("endpoint"); endpointField.setAccessible(true); - String fieldEndpoint = (String) endpointField.get(serverListManager); + String fieldEndpoint = (String) endpointField.get(serverListProvider); assertEquals(endpoint, fieldEndpoint); - Field endpointPortField = ServerListManager.class.getDeclaredField("endpointPort"); + Field endpointPortField = EndpointServerListProvider.class.getDeclaredField("endpointPort"); endpointPortField.setAccessible(true); - String fieldEndpointPort = String.valueOf(endpointPortField.get(serverListManager)); + String fieldEndpointPort = String.valueOf(endpointPortField.get(serverListProvider)); assertEquals(endpointPort, fieldEndpointPort); - Field endpointContextPathField = ServerListManager.class.getDeclaredField("endpointContextPath"); + Field endpointContextPathField = EndpointServerListProvider.class.getDeclaredField("endpointContextPath"); endpointContextPathField.setAccessible(true); - String fieldEndpointContextPath = String.valueOf(endpointContextPathField.get(serverListManager)); + String fieldEndpointContextPath = String.valueOf(endpointContextPathField.get(serverListProvider)); assertEquals(endpointContextPath, fieldEndpointContextPath); - Field contentPathField = ServerListManager.class.getDeclaredField("contentPath"); + Field contentPathField = AbstractServerListProvider.class.getDeclaredField("contextPath"); contentPathField.setAccessible(true); - String fieldContentPath = String.valueOf(contentPathField.get(serverListManager)); + String fieldContentPath = String.valueOf(contentPathField.get(serverListProvider)); assertEquals(fieldContentPath, contextPath); } @Test void testWithEndpointContextPath() throws NacosException { Properties properties = new Properties(); - String endpoint = "127.0.0.1"; + String endpoint = "1.1.1.1"; properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint); String endpointPort = "9090"; properties.setProperty(PropertyKeyConst.ENDPOINT_PORT, endpointPort); @@ -230,15 +284,15 @@ void testWithEndpointContextPath() throws NacosException { String contextPath = "/contextPath"; properties.setProperty(PropertyKeyConst.CONTEXT_PATH, contextPath); final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties); - ServerListManager serverListManager = new ServerListManager(clientProperties); - assertTrue(serverListManager.addressServerUrl.contains(endpointContextPath)); + ConfigServerListManager serverListManager = new ConfigServerListManager(clientProperties); + assertTrue(serverListManager.getAddressSource().contains(endpointContextPath)); assertTrue(serverListManager.getName().contains("endpointContextPath")); } @Test void testWithEndpointClusterName() throws NacosException { Properties properties = new Properties(); - String endpoint = "127.0.0.1"; + String endpoint = "1.1.1.1"; properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint); String endpointPort = "9090"; properties.setProperty(PropertyKeyConst.ENDPOINT_PORT, endpointPort); @@ -251,14 +305,15 @@ void testWithEndpointClusterName() throws NacosException { String contextPath = "/contextPath"; properties.setProperty(PropertyKeyConst.CONTEXT_PATH, contextPath); final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties); - ServerListManager serverListManager = new ServerListManager(clientProperties); - assertTrue(serverListManager.addressServerUrl.contains(endpointContextPath)); + ConfigServerListManager serverListManager = new ConfigServerListManager(clientProperties); + String addressSource = serverListManager.getAddressSource(); + assertTrue(addressSource.contains(endpointContextPath)); assertTrue(serverListManager.getName().contains("endpointContextPath")); - assertTrue(serverListManager.addressServerUrl.contains(testEndpointClusterName)); + assertTrue(addressSource.contains(testEndpointClusterName)); assertTrue(serverListManager.getName().contains(testEndpointClusterName)); - assertFalse(serverListManager.addressServerUrl.contains(testClusterName)); + assertFalse(addressSource.contains(testClusterName)); assertFalse(serverListManager.getName().contains(testClusterName)); } @@ -266,31 +321,32 @@ void testWithEndpointClusterName() throws NacosException { @Test void testWithoutEndpointContextPath() throws NacosException { Properties properties = new Properties(); - String endpoint = "127.0.0.1"; + String endpoint = "1.1.1.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); + ConfigServerListManager serverListManager = new ConfigServerListManager(clientProperties); String endpointContextPath = "/endpointContextPath"; - assertFalse(serverListManager.addressServerUrl.contains(endpointContextPath)); - assertTrue(serverListManager.addressServerUrl.contains(contextPath)); + + assertFalse(serverListManager.getAddressSource().contains(endpointContextPath)); + assertTrue(serverListManager.getAddressSource().contains(contextPath)); assertFalse(serverListManager.getName().contains("endpointContextPath")); assertTrue(serverListManager.getName().contains("contextPath")); } @Test void testUseEndpointParsingRule() throws NacosException { - System.setProperty("nacos.endpoint", "127.0.0.1"); + System.setProperty("nacos.endpoint", "1.1.1.1"); Properties properties = new Properties(); properties.setProperty(PropertyKeyConst.ENDPOINT, "${nacos.endpoint}"); properties.setProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE, "true"); properties.setProperty(PropertyKeyConst.ENDPOINT_PORT, "9090"); final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties); - ServerListManager serverListManager = new ServerListManager(clientProperties); - String addressServerUrl = serverListManager.addressServerUrl; - assertTrue(addressServerUrl.startsWith("http://127.0.0.1")); + ConfigServerListManager serverListManager = new ConfigServerListManager(clientProperties); + String addressServerUrl = serverListManager.getAddressSource(); + assertTrue(addressServerUrl.startsWith("http://1.1.1.1")); } } \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/NacosNamingMaintainServiceTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/NacosNamingMaintainServiceTest.java index 50580d0e526..4c463bcf167 100644 --- a/client/src/test/java/com/alibaba/nacos/client/naming/NacosNamingMaintainServiceTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/naming/NacosNamingMaintainServiceTest.java @@ -26,7 +26,7 @@ import com.alibaba.nacos.api.selector.AbstractSelector; import com.alibaba.nacos.api.selector.ExpressionSelector; import com.alibaba.nacos.api.selector.NoneSelector; -import com.alibaba.nacos.client.naming.core.ServerListManager; +import com.alibaba.nacos.client.naming.core.NamingServerListManager; import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy; import com.alibaba.nacos.client.security.SecurityProxy; import org.junit.jupiter.api.AfterEach; @@ -52,7 +52,7 @@ class NacosNamingMaintainServiceTest { private NamingHttpClientProxy serverProxy; - private ServerListManager serverListManager; + private NamingServerListManager serverListManager; private SecurityProxy securityProxy; @@ -66,7 +66,7 @@ void setUp() throws Exception { nacosNamingMaintainService = new NacosNamingMaintainService(prop); serverProxy = mock(NamingHttpClientProxy.class); - serverListManager = mock(ServerListManager.class); + serverListManager = mock(NamingServerListManager.class); securityProxy = mock(SecurityProxy.class); executorService = mock(ScheduledExecutorService.class); diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/core/ServerListManagerTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/core/NamingServerListManagerTest.java similarity index 78% rename from client/src/test/java/com/alibaba/nacos/client/naming/core/ServerListManagerTest.java rename to client/src/test/java/com/alibaba/nacos/client/naming/core/NamingServerListManagerTest.java index 58a6b773069..0b9b3e9df2f 100644 --- a/client/src/test/java/com/alibaba/nacos/client/naming/core/ServerListManagerTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/naming/core/NamingServerListManagerTest.java @@ -17,7 +17,10 @@ package com.alibaba.nacos.client.naming.core; import com.alibaba.nacos.api.PropertyKeyConst; -import com.alibaba.nacos.api.exception.runtime.NacosLoadException; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.address.AbstractServerListManager; +import com.alibaba.nacos.client.address.EndpointServerListProvider; +import com.alibaba.nacos.client.address.ServerListProvider; import com.alibaba.nacos.client.env.NacosClientProperties; import com.alibaba.nacos.common.http.HttpClientBeanHolder; import com.alibaba.nacos.common.http.HttpRestResult; @@ -33,7 +36,6 @@ import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -42,17 +44,15 @@ import java.util.Properties; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; @ExtendWith(MockitoExtension.class) // todo remove strictness lenient @MockitoSettings(strictness = Strictness.LENIENT) -class ServerListManagerTest { - - private static final String NS = "ns"; +class NamingServerListManagerTest { @Mock NacosRestTemplate nacosRestTemplate; @@ -63,7 +63,7 @@ class ServerListManagerTest { HttpRestResult httpRestResult; - ServerListManager serverListManager; + NamingServerListManager serverListManager; @BeforeEach void setUp() throws Exception { @@ -73,12 +73,11 @@ void setUp() throws Exception { Map restMap = (Map) restMapField.get(null); cachedNacosRestTemplate = restMap.get( "com.alibaba.nacos.client.naming.remote.http.NamingHttpClientManager$NamingHttpClientFactory"); - restMap.put("com.alibaba.nacos.client.naming.remote.http.NamingHttpClientManager$NamingHttpClientFactory", - nacosRestTemplate); + restMap.put("com.alibaba.nacos.client.naming.remote.http.NamingHttpClientManager$NamingHttpClientFactory", nacosRestTemplate); httpRestResult = new HttpRestResult<>(); httpRestResult.setData("127.0.0.1:8848"); httpRestResult.setCode(200); - Mockito.when(nacosRestTemplate.get(any(), any(), any(), any())).thenReturn(httpRestResult); + Mockito.when(nacosRestTemplate.get(contains("127.0.0.1"), any(), any(), any())).thenReturn(httpRestResult); } @AfterEach @@ -96,17 +95,10 @@ void tearDown() throws Exception { } @Test - void testConstructError() { - assertThrows(NacosLoadException.class, () -> { - serverListManager = new ServerListManager(new Properties()); - }); - } - - @Test - void testConstructWithAddr() { + void testConstructWithAddr() throws NacosException { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848,127.0.0.1:8849"); - serverListManager = new ServerListManager(properties); + serverListManager = new NamingServerListManager(properties); final List serverList = serverListManager.getServerList(); assertEquals(2, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); @@ -114,16 +106,14 @@ void testConstructWithAddr() { } @Test - void testConstructWithAddrTryToRefresh() - throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, NoSuchFieldException { + void testConstructWithAddrTryToRefresh() throws Exception { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848,127.0.0.1:8849"); - serverListManager = new ServerListManager(properties); + serverListManager = new NamingServerListManager(properties); List serverList = serverListManager.getServerList(); assertEquals(2, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); assertEquals("127.0.0.1:8849", serverList.get(1)); - mockThreadInvoke(serverListManager, false); serverList = serverListManager.getServerList(); assertEquals(2, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); @@ -134,7 +124,7 @@ void testConstructWithAddrTryToRefresh() void testConstructWithEndpointAndRefresh() throws Exception { Properties properties = new Properties(); properties.put(PropertyKeyConst.ENDPOINT, "127.0.0.1"); - serverListManager = new ServerListManager(properties); + serverListManager = new NamingServerListManager(properties); List serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); @@ -151,13 +141,12 @@ void testConstructWithEndpointAndRefresh() throws Exception { void testConstructWithEndpointAndTimedNotNeedRefresh() throws Exception { Properties properties = new Properties(); properties.put(PropertyKeyConst.ENDPOINT, "127.0.0.1"); - serverListManager = new ServerListManager(properties); + serverListManager = new NamingServerListManager(properties); List serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); httpRestResult.setData("127.0.0.1:8848\n127.0.0.1:8948"); - mockThreadInvoke(serverListManager, false); serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); @@ -167,30 +156,27 @@ void testConstructWithEndpointAndTimedNotNeedRefresh() throws Exception { void testConstructWithEndpointAndRefreshEmpty() throws Exception { Properties properties = new Properties(); properties.put(PropertyKeyConst.ENDPOINT, "127.0.0.1"); - serverListManager = new ServerListManager(properties); + serverListManager = new NamingServerListManager(properties); List serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); httpRestResult.setData(""); - mockThreadInvoke(serverListManager, true); serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); } @Test - void testConstructWithEndpointAndRefreshException() - throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, NoSuchFieldException { + void testConstructWithEndpointAndRefreshException() throws Exception { Properties properties = new Properties(); properties.put(PropertyKeyConst.ENDPOINT, "127.0.0.1"); - serverListManager = new ServerListManager(properties); + serverListManager = new NamingServerListManager(properties); List serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); httpRestResult.setCode(500); - mockThreadInvoke(serverListManager, true); serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); @@ -204,7 +190,7 @@ void testConstructWithEndpointWithCustomPathAndName() throws Exception { 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"); + serverListManager = new NamingServerListManager(clientProperties); List serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); @@ -218,7 +204,7 @@ void testConstructWithEndpointWithEndpointPathAndName() throws Exception { 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"); + serverListManager = new NamingServerListManager(clientProperties); List serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); @@ -233,7 +219,7 @@ void testConstructEndpointContextPathPriority() throws Exception { 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"); + serverListManager = new NamingServerListManager(clientProperties); List serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); @@ -248,47 +234,52 @@ void testConstructEndpointContextPathIsEmpty() throws Exception { 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"); + serverListManager = new NamingServerListManager(clientProperties); List serverList = serverListManager.getServerList(); assertEquals(1, serverList.size()); assertEquals("127.0.0.1:8848", serverList.get(0)); } @Test - void testIsDomain() throws IOException { + void testIsDomain() throws Exception { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848"); - serverListManager = new ServerListManager(properties); - assertTrue(serverListManager.isDomain()); - assertEquals("127.0.0.1:8848", serverListManager.getNacosDomain()); + serverListManager = new NamingServerListManager(properties); + // todo + //assertTrue(serverListManager.isDomain()); + // assertEquals("127.0.0.1:8848", serverListManager()); } @Test - void testGetCurrentServer() { + void testGetCurrentServer() throws NacosException { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848"); - final ServerListManager serverListManager = new ServerListManager(properties); + final NamingServerListManager serverListManager = new NamingServerListManager(properties); assertEquals("127.0.0.1:8848", serverListManager.getCurrentServer()); assertEquals("127.0.0.1:8848", serverListManager.genNextServer()); } @Test - void testShutdown() { + void testShutdown() throws NacosException { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848"); - final ServerListManager serverListManager = new ServerListManager(properties); + final NamingServerListManager serverListManager = new NamingServerListManager(properties); Assertions.assertDoesNotThrow(() -> { serverListManager.shutdown(); }); } - private void mockThreadInvoke(ServerListManager serverListManager, boolean expectedInvoked) + private void mockThreadInvoke(NamingServerListManager serverListManager, boolean expectedInvoked) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { - Field field = ServerListManager.class.getDeclaredField("lastServerListRefreshTime"); + Field providerField = AbstractServerListManager.class.getDeclaredField("serverListProvider"); + providerField.setAccessible(true); + ServerListProvider serverListProvider = (ServerListProvider) providerField.get(serverListManager); + assertInstanceOf(EndpointServerListProvider.class, serverListProvider); + Field field = EndpointServerListProvider.class.getDeclaredField("lastServerListRefreshTime"); field.setAccessible(true); - field.set(serverListManager, expectedInvoked ? 0 : System.currentTimeMillis()); - Method method = ServerListManager.class.getDeclaredMethod("refreshServerListIfNeed"); + field.set(serverListProvider, expectedInvoked ? 0 : System.currentTimeMillis()); + Method method = EndpointServerListProvider.class.getDeclaredMethod("refreshServerListIfNeed"); method.setAccessible(true); - method.invoke(serverListManager); + method.invoke(serverListProvider); } } diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxyTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxyTest.java index b2b60a68d30..7f570c2780b 100644 --- a/client/src/test/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxyTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxyTest.java @@ -26,7 +26,7 @@ import com.alibaba.nacos.api.naming.pojo.ServiceInfo; import com.alibaba.nacos.api.selector.AbstractSelector; import com.alibaba.nacos.client.auth.ram.utils.SignUtil; -import com.alibaba.nacos.client.naming.event.ServerListChangedEvent; +import com.alibaba.nacos.client.address.ServerListChangeEvent; import com.alibaba.nacos.client.security.SecurityProxy; import com.alibaba.nacos.client.utils.AppNameUtils; import com.alibaba.nacos.common.notify.Event; @@ -185,7 +185,7 @@ public void shutdown() throws NacosException { } @Override - public void onEvent(ServerListChangedEvent event) { + public void onEvent(ServerListChangeEvent event) { } diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxyTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxyTest.java index 18b7f6ef3a1..62314db5473 100644 --- a/client/src/test/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxyTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxyTest.java @@ -47,7 +47,7 @@ import com.alibaba.nacos.api.selector.NoneSelector; import com.alibaba.nacos.client.env.NacosClientProperties; import com.alibaba.nacos.client.naming.cache.ServiceInfoHolder; -import com.alibaba.nacos.client.naming.event.ServerListChangedEvent; +import com.alibaba.nacos.client.address.ServerListChangeEvent; import com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService; import com.alibaba.nacos.client.security.SecurityProxy; import com.alibaba.nacos.common.notify.NotifyCenter; @@ -683,7 +683,7 @@ public void close() { String newServer = "www.aliyun.com"; when(factory.genNextServer()).thenReturn(newServer); when(factory.getServerList()).thenReturn(Stream.of(newServer, "anotherServer").collect(Collectors.toList())); - NotifyCenter.publishEvent(new ServerListChangedEvent()); + NotifyCenter.publishEvent(new ServerListChangeEvent()); retry = 10; while (ORIGIN_SERVER.equals(rpc.getCurrentServer().getServerIp())) { diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/remote/http/NamingHttpClientProxyTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/remote/http/NamingHttpClientProxyTest.java index 28e09582226..dc0fccc2681 100644 --- a/client/src/test/java/com/alibaba/nacos/client/naming/remote/http/NamingHttpClientProxyTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/naming/remote/http/NamingHttpClientProxyTest.java @@ -26,8 +26,8 @@ import com.alibaba.nacos.api.selector.ExpressionSelector; import com.alibaba.nacos.api.selector.NoneSelector; import com.alibaba.nacos.client.env.NacosClientProperties; -import com.alibaba.nacos.client.naming.core.ServerListManager; -import com.alibaba.nacos.client.naming.event.ServerListChangedEvent; +import com.alibaba.nacos.client.naming.core.NamingServerListManager; +import com.alibaba.nacos.client.address.ServerListChangeEvent; import com.alibaba.nacos.client.naming.utils.UtilAndComs; import com.alibaba.nacos.client.security.SecurityProxy; import com.alibaba.nacos.common.http.HttpRestResult; @@ -74,7 +74,7 @@ class NamingHttpClientProxyTest { private SecurityProxy proxy; @Mock - private ServerListManager mgr; + private NamingServerListManager mgr; private Properties props; @@ -96,13 +96,13 @@ void tearDown() throws NacosException { @Test void testOnEvent() { - clientProxy.onEvent(new ServerListChangedEvent()); + clientProxy.onEvent(new ServerListChangeEvent()); // Do nothing } @Test void testSubscribeType() { - assertEquals(ServerListChangedEvent.class, clientProxy.subscribeType()); + assertEquals(ServerListChangeEvent.class, clientProxy.subscribeType()); } @Test @@ -640,8 +640,6 @@ void testReqApiForEmptyServer() throws NacosException { void testRegApiForDomain() throws NacosException { assertThrows(NacosException.class, () -> { Map params = new HashMap<>(); - when(mgr.isDomain()).thenReturn(true); - when(mgr.getNacosDomain()).thenReturn("http://test.nacos.domain"); clientProxy.reqApi("api", params, Collections.emptyMap(), Collections.emptyList(), HttpMethod.GET); }); diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/utils/NamingHttpUtilTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/utils/NamingHttpUtilTest.java deleted file mode 100644 index c28d634a04f..00000000000 --- a/client/src/test/java/com/alibaba/nacos/client/naming/utils/NamingHttpUtilTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 1999-2018 Alibaba Group Holding Ltd. - * - * Licensed 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 com.alibaba.nacos.client.naming.utils; - -import com.alibaba.nacos.common.constant.HttpHeaderConsts; -import com.alibaba.nacos.common.http.param.Header; -import com.alibaba.nacos.common.utils.VersionUtils; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -class NamingHttpUtilTest { - - @Test - void testBuilderHeader() { - Header header = NamingHttpUtil.builderHeader(); - assertNotNull(header); - assertEquals(header.getValue(HttpHeaderConsts.CLIENT_VERSION_HEADER), VersionUtils.version); - assertEquals(header.getValue(HttpHeaderConsts.USER_AGENT_HEADER), VersionUtils.getFullClientVersion()); - assertEquals("gzip,deflate,sdch", header.getValue(HttpHeaderConsts.ACCEPT_ENCODING)); - assertEquals("Keep-Alive", header.getValue(HttpHeaderConsts.CONNECTION)); - assertNotNull(header.getValue(HttpHeaderConsts.REQUEST_ID)); - assertEquals("Naming", header.getValue(HttpHeaderConsts.REQUEST_MODULE)); - } -} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/utils/ParamUtilTest.java b/client/src/test/java/com/alibaba/nacos/client/utils/ParamUtilTest.java index 4e60333753a..008acdcbf0c 100644 --- a/client/src/test/java/com/alibaba/nacos/client/utils/ParamUtilTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/utils/ParamUtilTest.java @@ -267,4 +267,9 @@ void testDesensitiseParameter() { String longParameter = "testPass"; assertEquals("te****ss", ParamUtil.desensitiseParameter(longParameter)); } + + @Test + void testGetNameSuffixByServerIps() { + assertEquals("1.1.1.1-2.2.2.2_8848", ParamUtil.getNameSuffixByServerIps("http://1.1.1.1", "2.2.2.2:8848")); + } } \ No newline at end of file diff --git a/common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java b/common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java index 88aa3d096b7..0dade891f87 100644 --- a/common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java +++ b/common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java @@ -22,6 +22,8 @@ import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.common.utils.UuidUtils; +import com.alibaba.nacos.common.utils.VersionUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.NameValuePair; @@ -263,6 +265,22 @@ public static boolean isTimeoutException(Throwable throwable) { || throwable instanceof TimeoutException || throwable.getCause() instanceof TimeoutException; } + /** + * Build header. + * + * @return header + */ + public static Header builderHeader(String module) { + Header header = Header.newInstance(); + header.addParam(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version); + header.addParam(HttpHeaderConsts.USER_AGENT_HEADER, VersionUtils.getFullClientVersion()); + header.addParam(HttpHeaderConsts.ACCEPT_ENCODING, "gzip,deflate,sdch"); + header.addParam(HttpHeaderConsts.CONNECTION, "Keep-Alive"); + header.addParam(HttpHeaderConsts.REQUEST_ID, UuidUtils.generateUuid()); + header.addParam(HttpHeaderConsts.REQUEST_MODULE, module); + return header; + } + private static String innerDecode(String pre, String now, String encode) throws UnsupportedEncodingException { // Because the data may be encoded by the URL more than once, // it needs to be decoded recursively until it is fully successful diff --git a/common/src/test/java/com/alibaba/nacos/common/http/HttpUtilsTest.java b/common/src/test/java/com/alibaba/nacos/common/http/HttpUtilsTest.java index 8dfdb4aec68..6c0945d28cc 100644 --- a/common/src/test/java/com/alibaba/nacos/common/http/HttpUtilsTest.java +++ b/common/src/test/java/com/alibaba/nacos/common/http/HttpUtilsTest.java @@ -21,6 +21,7 @@ import com.alibaba.nacos.common.constant.HttpHeaderConsts; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.Query; +import com.alibaba.nacos.common.utils.VersionUtils; import org.apache.http.HttpEntity; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpRequestBase; @@ -46,6 +47,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -311,4 +313,16 @@ void testIsTimeoutException() { assertTrue(HttpUtils.isTimeoutException(new ConnectTimeoutException())); assertTrue(HttpUtils.isTimeoutException(new NacosRuntimeException(0, new TimeoutException()))); } -} \ No newline at end of file + + @Test + void testBuilderHeader() { + Header header = HttpUtils.builderHeader("Test"); + assertNotNull(header); + assertEquals(header.getValue(HttpHeaderConsts.CLIENT_VERSION_HEADER), VersionUtils.version); + assertEquals(header.getValue(HttpHeaderConsts.USER_AGENT_HEADER), VersionUtils.getFullClientVersion()); + assertEquals("gzip,deflate,sdch", header.getValue(HttpHeaderConsts.ACCEPT_ENCODING)); + assertEquals("Keep-Alive", header.getValue(HttpHeaderConsts.CONNECTION)); + assertNotNull(header.getValue(HttpHeaderConsts.REQUEST_ID)); + assertEquals("Test", header.getValue(HttpHeaderConsts.REQUEST_MODULE)); + } +} diff --git a/common/src/test/java/com/alibaba/nacos/common/utils/InternetAddressUtilTest.java b/common/src/test/java/com/alibaba/nacos/common/utils/InternetAddressUtilTest.java index c631898e49e..21534602705 100644 --- a/common/src/test/java/com/alibaba/nacos/common/utils/InternetAddressUtilTest.java +++ b/common/src/test/java/com/alibaba/nacos/common/utils/InternetAddressUtilTest.java @@ -213,5 +213,4 @@ void testIllegalIpToInt() { InternetAddressUtil.ipToInt("127.0.0.256"); }); } - }