Merge pull request #1359 from alibaba/develop

Develop
This commit is contained in:
Fury Zhu 2019-06-12 16:40:33 +08:00 committed by GitHub
commit 3af86ae6a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
121 changed files with 5169 additions and 2229 deletions

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -20,6 +20,8 @@ import java.util.Properties;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingMaintainFactory;
import com.alibaba.nacos.api.naming.NamingMaintainService;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
@ -74,4 +76,26 @@ public class NacosFactory {
return NamingFactory.createNamingService(properties);
}
/**
* Create maintain service
*
* @param serverAddr
* @return NamingMaintainService
* @throws NacosException Exception
*/
public static NamingMaintainService createMaintainService(String serverAddr) throws NacosException {
return NamingMaintainFactory.createMaintainService(serverAddr);
}
/**
* Create maintain service
*
* @param properties
* @return NamingMaintainService
* @throws NacosException Exception
*/
public static NamingMaintainService createMaintainService(Properties properties) throws NacosException {
return NamingMaintainFactory.createMaintainService(properties);
}
}

View File

@ -22,6 +22,8 @@ package com.alibaba.nacos.api;
*/
public class PropertyKeyConst {
public final static String IS_USE_CLOUD_NAMESPACE_PARSING = "isUseCloudNamespaceParsing";
public final static String IS_USE_ENDPOINT_PARSING_RULE = "isUseEndpointParsingRule";
public final static String ENDPOINT = "endpoint";
@ -44,12 +46,21 @@ public class PropertyKeyConst {
public final static String ENCODE = "encode";
public final static String CONFIG_LONG_POLL_TIMEOUT = "config.long-poll.timeout";
public final static String CONFIG_RETRY_TIME = "config.retry.time";
public final static String MAX_RETRY = "maxRetry";
public final static String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart";
public final static String NAMING_CLIENT_BEAT_THREAD_COUNT = "namingClientBeatThreadCount";
public final static String NAMING_POLLING_THREAD_COUNT = "namingPollingThreadCount";
/**
* Get the key value of some variable value from the system property
*/
public static class SystemEnv {
public static final String ALIBABA_ALIWARE_ENDPOINT_PORT = "ALIBABA_ALIWARE_ENDPOINT_PORT";
@ -58,4 +69,5 @@ public class PropertyKeyConst {
public static final String ALIBABA_ALIWARE_ENDPOINT_URL = "ALIBABA_ALIWARE_ENDPOINT_URL";
}
}

View File

@ -16,6 +16,9 @@
package com.alibaba.nacos.api;
/**
* <p>
* Support for reading the value of the specified variable from the -D parameter
* </P>
* Properties that are preferred to which in {@link PropertyKeyConst}
*
* @author pbting
@ -27,5 +30,23 @@ public interface SystemPropertyKeyConst {
String NAMING_WEB_CONTEXT = "nacos.naming.web.context";
String NACOS_NAMING_REQUEST_MODULE = "nacos.naming.request.module";
/**
* In the cloud (Alibaba Cloud or other cloud vendors) environment,
* whether to enable namespace resolution in the cloud environment.
* <p>
* The default is on.
* </p>
*/
String IS_USE_CLOUD_NAMESPACE_PARSING = "nacos.use.cloud.namespace.parsing";
/**
* In the cloud environment, if the process level requires a globally uniform namespace,
* it can be specified with the -D parameter.
*/
String ANS_NAMESPACE = "ans.namespace";
/**
* It is also supported by the -D parameter.
*/
String IS_USE_ENDPOINT_PARSING_RULE = "nacos.use.endpoint.parsing.rule";
}

View File

@ -88,6 +88,26 @@ public class Constants {
*/
public static final int SO_TIMEOUT = 60000;
/**
* millisecond
*/
public static final int CONFIG_LONG_POLL_TIMEOUT = 30000;
/**
* millisecond
*/
public static final int MIN_CONFIG_LONG_POLL_TIMEOUT = 10000;
/**
* millisecond
*/
public static final int CONFIG_RETRY_TIME = 2000;
/**
* Maximum number of retries
*/
public static final int MAX_RETRY = 3;
/**
* millisecond
*/
@ -103,6 +123,8 @@ public class Constants {
public static final int FLOW_CONTROL_INTERVAL = 1000;
public static final float DEFAULT_PROTECT_THRESHOLD = 0.0F;
public static final String LINE_SEPARATOR = Character.toString((char) 1);
public static final String WORD_SEPARATOR = Character.toString((char) 2);
@ -123,6 +145,8 @@ public class Constants {
public static final String DEFAULT_NAMESPACE_ID = "public";
public static final boolean DEFAULT_USE_CLOUD_NAMESPACE_PARSING = true;
public static final int WRITE_REDIRECT_CODE = 307;
public static final String SERVICE_INFO_SPLITER = "@@";

View File

@ -49,6 +49,13 @@ public @interface NacosConfigurationProperties {
*/
String dataId();
/**
* if the config style is yaml
*
* @return default value is <code>false</code>
*/
boolean yaml() default false;
/**
* It indicates the properties of current doBind bean is auto-refreshed when Nacos configuration is changed.
*

View File

@ -0,0 +1,52 @@
/*
* 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.api.naming;
import com.alibaba.nacos.api.exception.NacosException;
import java.lang.reflect.Constructor;
import java.util.Properties;
/**
* @author liaochuntao
* @since 1.0.1
*/
public class NamingMaintainFactory {
public static NamingMaintainService createMaintainService(String serverList) throws NacosException {
try {
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingMaintainService");
Constructor constructor = driverImplClass.getConstructor(String.class);
NamingMaintainService vendorImpl = (NamingMaintainService)constructor.newInstance(serverList);
return vendorImpl;
} catch (Throwable e) {
throw new NacosException(-400, e.getMessage());
}
}
public static NamingMaintainService createMaintainService(Properties properties) throws NacosException {
try {
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingMaintainService");
Constructor constructor = driverImplClass.getConstructor(Properties.class);
NamingMaintainService vendorImpl = (NamingMaintainService)constructor.newInstance(properties);
return vendorImpl;
} catch (Throwable e) {
throw new NacosException(-400, e.getMessage());
}
}
}

View File

@ -0,0 +1,168 @@
/*
* 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.api.naming;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.Service;
import com.alibaba.nacos.api.selector.AbstractSelector;
import java.util.Map;
/**
* Operations related to Nacos
*
* @author liaochuntao
* @since 1.0.1
*/
public interface NamingMaintainService {
/**
* update instance info
*
* @param serviceName
* @param instance
* @throws NacosException
*/
void updateInstance(String serviceName, Instance instance) throws NacosException;
/**
* update instance info
*
* @param serviceName
* @param groupName
* @param instance
* @throws NacosException
*/
void updateInstance(String serviceName, String groupName, Instance instance) throws NacosException;
/**
* query service
*
* @param serviceName
* @return
* @throws NacosException
*/
Service queryService(String serviceName) throws NacosException;
/**
* query service
*
* @param serviceName
* @param groupName
* @return
* @throws NacosException
*/
Service queryService(String serviceName, String groupName) throws NacosException;
/**
* create service to Nacos
*
* @param serviceName name of service
* @throws NacosException
*/
void createService(String serviceName) throws NacosException;
/**
* create service to Nacos
*
* @param serviceName name of service
* @param groupName group of service
* @throws NacosException
*/
void createService(String serviceName, String groupName) throws NacosException;
/**
* create service to Nacos
*
* @param serviceName name of service
* @param groupName group of service
* @param protectThreshold protectThreshold of service
* @throws NacosException
*/
void createService(String serviceName, String groupName, float protectThreshold) throws NacosException;
/**
* create service to Nacos
*
* @param serviceName name of service
* @param groupName group of service
* @param protectThreshold protectThreshold of service
* @param expression expression of selector
* @throws NacosException
*/
void createService(String serviceName, String groupName, float protectThreshold, String expression) throws NacosException;
/**
* create service to Nacos
*
* @param service name of service
* @param selector selector
* @throws NacosException
*/
void createService(Service service, AbstractSelector selector) throws NacosException;
/**
* delete service from Nacos
*
* @param serviceName name of service
* @return if delete service success return true
* @throws NacosException
*/
boolean deleteService(String serviceName) throws NacosException;
/**
* delete service from Nacos
*
* @param serviceName name of service
* @param groupName group of service
* @return if delete service success return true
* @throws NacosException
*/
boolean deleteService(String serviceName, String groupName) throws NacosException;
/**
* update service to Nacos
*
* @param serviceName name of service
* @param groupName group of service
* @param protectThreshold protectThreshold of service
* @throws NacosException
*/
void updateService(String serviceName, String groupName, float protectThreshold) throws NacosException;
/**
* update service to Nacos
*
* @param serviceName name of service
* @param groupName group of service
* @param protectThreshold protectThreshold of service
* @param metadata metadata of service
* @throws NacosException
*/
void updateService(String serviceName, String groupName, float protectThreshold, Map<String, String> metadata) throws NacosException;
/**
* update service to Nacos with selector
*
* @param service {@link Service} pojo of service
* @param selector {@link AbstractSelector} pojo of selector
* @throws NacosException
*/
void updateService(Service service, AbstractSelector selector) throws NacosException;
}

View File

@ -19,10 +19,12 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.Service;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.selector.AbstractSelector;
import java.util.List;
import java.util.Map;
/**
* Naming Service

View File

@ -28,6 +28,10 @@ public class NamingEvent implements Event {
private String serviceName;
private String groupName;
private String clusters;
private List<Instance> instances;
public NamingEvent(String serviceName, List<Instance> instances) {
@ -35,6 +39,13 @@ public class NamingEvent implements Event {
this.instances = instances;
}
public NamingEvent(String serviceName, String groupName, String clusters, List<Instance> instances) {
this.serviceName = serviceName;
this.groupName = groupName;
this.clusters = clusters;
this.instances = instances;
}
public String getServiceName() {
return serviceName;
}
@ -50,4 +61,20 @@ public class NamingEvent implements Event {
public void setInstances(List<Instance> instances) {
this.instances = instances;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public String getClusters() {
return clusters;
}
public void setClusters(String clusters) {
this.clusters = clusters;
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.api.naming.pojo;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.nacos.api.common.Constants;
import org.apache.commons.lang3.StringUtils;
@ -45,8 +46,16 @@ public abstract class AbstractHealthChecker implements Cloneable {
* @return Another instance with exactly the same fields.
* @throws CloneNotSupportedException
*/
@Override
public abstract AbstractHealthChecker clone() throws CloneNotSupportedException;
/**
* used to JsonAdapter
*/
public void jsonAdapterCallback(SerializeWriter writer){
// do nothing
}
public static class None extends AbstractHealthChecker {
public static final String TYPE = "NONE";
@ -116,6 +125,17 @@ public abstract class AbstractHealthChecker implements Cloneable {
return headerMap;
}
/**
* used to JsonAdapter
*
* @param writer
*/
@Override
public void jsonAdapterCallback(SerializeWriter writer) {
writer.writeFieldValue(',', "path", getPath());
writer.writeFieldValue(',', "headers", getHeaders());
}
@Override
public int hashCode() {
return Objects.hash(path, headers, expectedResponseCode);
@ -215,6 +235,18 @@ public abstract class AbstractHealthChecker implements Cloneable {
this.pwd = pwd;
}
/**
* used to JsonAdapter
*
* @param writer
*/
@Override
public void jsonAdapterCallback(SerializeWriter writer) {
writer.writeFieldValue(',', "user", getUser());
writer.writeFieldValue(',', "pwd", getPwd());
writer.writeFieldValue(',', "cmd", getCmd());
}
@Override
public int hashCode() {
return Objects.hash(user, pwd, cmd);

View File

@ -101,4 +101,15 @@ public class Service {
public void addMetadata(String key, String value) {
this.metadata.put(key, value);
}
@Override
public String toString() {
return "Service{" +
"name='" + name + '\'' +
", protectThreshold=" + protectThreshold +
", appName='" + appName + '\'' +
", groupName='" + groupName + '\'' +
", metadata=" + metadata +
'}';
}
}

View File

@ -13,31 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.utils;
import com.alibaba.nacos.client.utils.StringUtils;
package com.alibaba.nacos.api.selector;
/**
* Tenant Util
*
* @author Nacos
* @author liaochuntao
* @since 1.0.1
*/
public class TenantUtil {
public class NoneSelector extends AbstractSelector {
private static String userTenant = "";
static {
userTenant = System.getProperty("tenant.id", "");
if (StringUtils.isBlank(userTenant)) {
userTenant = System.getProperty("acm.namespace", "");
}
}
public static String getUserTenant() {
return userTenant;
}
public static void setUserTenant(String userTenant) {
TenantUtil.userTenant = userTenant;
public NoneSelector() {
this.setType(SelectorType.none.name());
}
}

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.client.config;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
@ -31,10 +32,10 @@ import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
import com.alibaba.nacos.client.config.utils.ContentUtils;
import com.alibaba.nacos.client.config.utils.ParamUtils;
import com.alibaba.nacos.client.config.utils.TenantUtil;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.client.utils.TenantUtil;
import org.slf4j.Logger;
import java.io.IOException;
@ -81,16 +82,22 @@ public class NacosConfigService implements ConfigService {
initNamespace(properties);
agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
agent.start();
worker = new ClientWorker(agent, configFilterChainManager);
worker = new ClientWorker(agent, configFilterChainManager, properties);
}
private void initNamespace(Properties properties) {
String namespaceTmp = null;
String isUseCloudNamespaceParsing =
properties.getProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
System.getProperty(SystemPropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
String.valueOf(Constants.DEFAULT_USE_CLOUD_NAMESPACE_PARSING)));
if (Boolean.valueOf(isUseCloudNamespaceParsing)) {
namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, new Callable<String>() {
@Override
public String call() {
return TenantUtil.getUserTenant();
return TenantUtil.getUserTenantForAcm();
}
});
@ -101,6 +108,7 @@ public class NacosConfigService implements ConfigService {
return StringUtils.isNotBlank(namespace) ? namespace : EMPTY;
}
});
}
if (StringUtils.isBlank(namespaceTmp)) {
namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE);

View File

@ -31,6 +31,7 @@ import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.StringUtils;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import java.io.IOException;
import java.net.ConnectException;
@ -65,8 +66,10 @@ public class ServerHttpAgent implements HttpAgent {
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
final boolean isSSL = false;
boolean isSSL = false;
String currentServerAddr = serverListMgr.getCurrentServerAddr();
int maxRetry = this.maxRetry;
do {
try {
@ -75,7 +78,7 @@ public class ServerHttpAgent implements HttpAgent {
newHeaders.addAll(headers);
}
HttpResult result = HttpSimpleClient.httpGet(
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
getUrl(currentServerAddr, path, isSSL), newHeaders, paramValues, encoding,
readTimeoutMs, isSSL);
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
@ -83,18 +86,29 @@ public class ServerHttpAgent implements HttpAgent {
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
serverListMgr.getCurrentServerAddr(), result.code);
} else {
// Update the currently available server addr
serverListMgr.updateCurrentServerAddr(currentServerAddr);
return result;
}
} catch (ConnectException ce) {
LOGGER.error("[NACOS ConnectException] currentServerAddr:{}", serverListMgr.getCurrentServerAddr());
serverListMgr.refreshCurrentServerAddr();
LOGGER.error("[NACOS ConnectException httpGet] currentServerAddr:{}", serverListMgr.getCurrentServerAddr());
} catch (SocketTimeoutException stoe) {
LOGGER.error("[NACOS SocketTimeoutException] currentServerAddr:{}", serverListMgr.getCurrentServerAddr());
serverListMgr.refreshCurrentServerAddr();
LOGGER.error("[NACOS SocketTimeoutException httpGet] currentServerAddr:{}", serverListMgr.getCurrentServerAddr());
} catch (IOException ioe) {
LOGGER.error("[NACOS IOException] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);
LOGGER.error("[NACOS IOException httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);
throw ioe;
}
if (serverListMgr.getIterator().hasNext()) {
currentServerAddr = serverListMgr.getIterator().next();
} else {
maxRetry --;
if (maxRetry < 0) {
throw new ConnectException("[NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached");
}
serverListMgr.refreshCurrentServerAddr();
}
} while (System.currentTimeMillis() <= endTime);
LOGGER.error("no available server");
@ -106,39 +120,55 @@ public class ServerHttpAgent implements HttpAgent {
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
boolean isSSL = false;
String currentServerAddr = serverListMgr.getCurrentServerAddr();
int maxRetry = this.maxRetry;
do {
try {
List<String> newHeaders = getSpasHeaders(paramValues);
if (headers != null) {
newHeaders.addAll(headers);
}
HttpResult result = HttpSimpleClient.httpPost(
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
getUrl(currentServerAddr, path, isSSL), newHeaders, paramValues, encoding,
readTimeoutMs, isSSL);
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
serverListMgr.getCurrentServerAddr(), result.code);
LOGGER.error("[NACOS ConnectException httpPost] currentServerAddr: {}, httpCode: {}",
currentServerAddr, result.code);
} else {
// Update the currently available server addr
serverListMgr.updateCurrentServerAddr(currentServerAddr);
return result;
}
} catch (ConnectException ce) {
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}", serverListMgr.getCurrentServerAddr());
serverListMgr.refreshCurrentServerAddr();
LOGGER.error("[NACOS ConnectException httpPost] currentServerAddr: {}", currentServerAddr);
} catch (SocketTimeoutException stoe) {
LOGGER.error("[NACOS SocketTimeoutException]", "currentServerAddr: {}",
serverListMgr.getCurrentServerAddr());
serverListMgr.refreshCurrentServerAddr();
LOGGER.error("[NACOS SocketTimeoutException httpPost] currentServerAddr: {} err : {}",
currentServerAddr, stoe.getMessage());
} catch (IOException ioe) {
LOGGER.error("[NACOS IOException] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);
LOGGER.error("[NACOS IOException httpPost] currentServerAddr: " + currentServerAddr, ioe);
throw ioe;
}
if (serverListMgr.getIterator().hasNext()) {
currentServerAddr = serverListMgr.getIterator().next();
} else {
maxRetry --;
if (maxRetry < 0) {
throw new ConnectException("[NACOS HTTP-POST] The maximum number of tolerable server reconnection errors has been reached");
}
serverListMgr.refreshCurrentServerAddr();
}
} while (System.currentTimeMillis() <= endTime);
LOGGER.error("no available server");
throw new ConnectException("no available server");
LOGGER.error("no available server, currentServerAddr : {}", currentServerAddr);
throw new ConnectException("no available server, currentServerAddr : " + currentServerAddr);
}
@Override
@ -146,6 +176,10 @@ public class ServerHttpAgent implements HttpAgent {
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
boolean isSSL = false;
String currentServerAddr = serverListMgr.getCurrentServerAddr();
int maxRetry = this.maxRetry;
do {
try {
List<String> newHeaders = getSpasHeaders(paramValues);
@ -153,7 +187,7 @@ public class ServerHttpAgent implements HttpAgent {
newHeaders.addAll(headers);
}
HttpResult result = HttpSimpleClient.httpDelete(
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
getUrl(currentServerAddr, path, isSSL), newHeaders, paramValues, encoding,
readTimeoutMs, isSSL);
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
@ -161,19 +195,29 @@ public class ServerHttpAgent implements HttpAgent {
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
serverListMgr.getCurrentServerAddr(), result.code);
} else {
// Update the currently available server addr
serverListMgr.updateCurrentServerAddr(currentServerAddr);
return result;
}
} catch (ConnectException ce) {
LOGGER.error("[NACOS ConnectException] currentServerAddr:{}", serverListMgr.getCurrentServerAddr());
serverListMgr.refreshCurrentServerAddr();
LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}", serverListMgr.getCurrentServerAddr());
} catch (SocketTimeoutException stoe) {
LOGGER.error("[NACOS SocketTimeoutException] currentServerAddr:{}", serverListMgr.getCurrentServerAddr());
serverListMgr.refreshCurrentServerAddr();
LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{}", serverListMgr.getCurrentServerAddr());
} catch (IOException ioe) {
LOGGER.error("[NACOS IOException] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);
LOGGER.error("[NACOS IOException httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);
throw ioe;
}
if (serverListMgr.getIterator().hasNext()) {
currentServerAddr = serverListMgr.getIterator().next();
} else {
maxRetry --;
if (maxRetry < 0) {
throw new ConnectException("[NACOS HTTP-DELETE] The maximum number of tolerable server reconnection errors has been reached");
}
serverListMgr.refreshCurrentServerAddr();
}
} while (System.currentTimeMillis() <= endTime);
LOGGER.error("no available server");
@ -209,6 +253,7 @@ public class ServerHttpAgent implements HttpAgent {
private void init(Properties properties) {
initEncode(properties);
initAkSk(properties);
initMaxRetry(properties);
}
private void initEncode(Properties properties) {
@ -241,6 +286,10 @@ public class ServerHttpAgent implements HttpAgent {
}
}
private void initMaxRetry(Properties properties) {
maxRetry = NumberUtils.toInt(String.valueOf(properties.get(PropertyKeyConst.MAX_RETRY)), Constants.MAX_RETRY);
}
@Override
public synchronized void start() throws NacosException {
serverListMgr.start();
@ -392,6 +441,7 @@ public class ServerHttpAgent implements HttpAgent {
private String accessKey;
private String secretKey;
private String encode;
private int maxRetry = 3;
private volatile STSCredential sTSCredential;
final ServerListManager serverListMgr;

View File

@ -22,8 +22,8 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
import com.alibaba.nacos.client.config.filter.impl.ConfigResponse;
import com.alibaba.nacos.client.config.utils.MD5;
import com.alibaba.nacos.client.config.utils.TenantUtil;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.TenantUtil;
import org.slf4j.Logger;
import java.util.ArrayList;
@ -236,7 +236,7 @@ public class CacheData {
this.configFilterChainManager = configFilterChainManager;
this.dataId = dataId;
this.group = group;
this.tenant = TenantUtil.getUserTenant();
this.tenant = TenantUtil.getUserTenantForAcm();
listeners = new CopyOnWriteArrayList<ManagerListenerWrap>();
this.isInitializing = true;
this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
@ -274,7 +274,7 @@ public class CacheData {
*/
private volatile boolean isUseLocalConfig = false;
/**
* last motify time
* last modify time
*/
private volatile long localConfigLastModified;
private volatile String content;

View File

@ -15,6 +15,7 @@
*/
package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
@ -24,11 +25,12 @@ import com.alibaba.nacos.client.config.http.HttpAgent;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.utils.ContentUtils;
import com.alibaba.nacos.client.config.utils.MD5;
import com.alibaba.nacos.client.config.utils.TenantUtil;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import com.alibaba.nacos.client.utils.TenantUtil;
import org.slf4j.Logger;
import java.io.File;
@ -42,7 +44,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
@ -189,7 +191,7 @@ public class ClientWorker {
}
public CacheData getCache(String dataId, String group) {
return getCache(dataId, group, TenantUtil.getUserTenant());
return getCache(dataId, group, TenantUtil.getUserTenantForAcm());
}
public CacheData getCache(String dataId, String group, String tenant) {
@ -312,7 +314,7 @@ public class ClientWorker {
/**
* 从Server获取值变化了的DataID列表返回的对象里只有dataId和group是有效的 保证不返回NULL
*/
List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> inInitializingCacheList) {
List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> inInitializingCacheList) throws IOException {
StringBuilder sb = new StringBuilder();
for (CacheData cacheData : cacheDatas) {
if (!cacheData.isUseLocalConfigInfo()) {
@ -338,10 +340,9 @@ public class ClientWorker {
/**
* 从Server获取值变化了的DataID列表返回的对象里只有dataId和group是有效的 保证不返回NULL
*/
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) {
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException {
List<String> params = Arrays.asList(Constants.PROBE_MODIFY_REQUEST, probeUpdateString);
long timeout = TimeUnit.SECONDS.toMillis(30L);
List<String> headers = new ArrayList<String>(2);
headers.add("Long-Pulling-Timeout");
@ -371,6 +372,7 @@ public class ClientWorker {
} catch (IOException e) {
setHealthServer(false);
LOGGER.error("[" + agent.getName() + "] [check-update] get changed dataId exception", e);
throw e;
}
return Collections.emptyList();
}
@ -413,10 +415,14 @@ public class ClientWorker {
}
@SuppressWarnings("PMD.ThreadPoolCreationRule")
public ClientWorker(final HttpAgent agent, final ConfigFilterChainManager configFilterChainManager) {
public ClientWorker(final HttpAgent agent, final ConfigFilterChainManager configFilterChainManager, final Properties properties) {
this.agent = agent;
this.configFilterChainManager = configFilterChainManager;
// Initialize the timeout parameter
init(properties);
executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
@ -427,17 +433,18 @@ public class ClientWorker {
}
});
executorService = Executors.newCachedThreadPool(new ThreadFactory() {
executorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker.longPolling" + agent.getName());
t.setName("com.alibaba.nacos.client.Worker.longPolling." + agent.getName());
t.setDaemon(true);
return t;
}
});
executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
checkConfigInfo();
@ -448,6 +455,14 @@ public class ClientWorker {
}, 1L, 10L, TimeUnit.MILLISECONDS);
}
private void init(Properties properties) {
timeout = Math.max(NumberUtils.toInt(String.valueOf(properties.get(PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT)),
Constants.CONFIG_LONG_POLL_TIMEOUT), Constants.MIN_CONFIG_LONG_POLL_TIMEOUT);
taskPenaltyTime = NumberUtils.toInt(String.valueOf(properties.get(PropertyKeyConst.CONFIG_RETRY_TIME)), Constants.CONFIG_RETRY_TIME);
}
class LongPollingRunnable implements Runnable {
private int taskId;
@ -455,9 +470,12 @@ public class ClientWorker {
this.taskId = taskId;
}
@Override
public void run() {
try {
List<CacheData> cacheDatas = new ArrayList<CacheData>();
List<String> inInitializingCacheList = new ArrayList<String>();
try {
// check failover config
for (CacheData cacheData : cacheMap.get().values()) {
if (cacheData.getTaskId() == taskId) {
@ -473,7 +491,6 @@ public class ClientWorker {
}
}
List<String> inInitializingCacheList = new ArrayList<String>();
// check server config
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
@ -507,15 +524,17 @@ public class ClientWorker {
}
}
inInitializingCacheList.clear();
} catch (Throwable e) {
LOGGER.error("longPolling error", e);
} finally {
executorService.execute(this);
}
}
}
// =================
executorService.execute(this);
} catch (Throwable e) {
// If the rotation training task is abnormal, the next execution time of the task will be punished
LOGGER.error("longPolling error : ", e);
executorService.schedule(this, taskPenaltyTime, TimeUnit.MILLISECONDS);
}
}
}
public boolean isHealthServer() {
return isHealthServer;
@ -526,15 +545,18 @@ public class ClientWorker {
}
final ScheduledExecutorService executor;
final ExecutorService executorService;
final ScheduledExecutorService executorService;
/**
* groupKey -> cacheData
*/
AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
new HashMap<String, CacheData>());
HttpAgent agent;
ConfigFilterChainManager configFilterChainManager;
private final HttpAgent agent;
private final ConfigFilterChainManager configFilterChainManager;
private boolean isHealthServer = true;
private long timeout;
private double currentLongingTaskCount = 0;
private int taskPenaltyTime;
}

View File

@ -16,6 +16,7 @@
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.config.impl.EventDispatcher.ServerlistChangeEvent;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
@ -151,6 +152,7 @@ public class ServerListManager {
contentPath, serverListName, namespace);
}
}
}
private void initParam(Properties properties) {
@ -180,7 +182,13 @@ public class ServerListManager {
}
String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT);
if (Boolean.valueOf(properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE, ParamUtil.USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE))) {
// Whether to enable domain name resolution rules
String isUseEndpointRuleParsing =
properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
System.getProperty(SystemPropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
String.valueOf(ParamUtil.USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE)));
if (Boolean.valueOf(isUseEndpointRuleParsing)) {
String endpointUrl = ParamUtil.parsingEndpointRule(endpointTmp);
if (StringUtils.isNotBlank(endpointUrl)) {
serverAddrsStr = "";
@ -258,7 +266,8 @@ public class ServerListManager {
return;
}
serverUrls = new ArrayList<String>(newList);
currentServerAddr = iterator().next();
iterator = iterator();
currentServerAddr = iterator.next();
EventDispatcher.fireEvent(new ServerlistChangeEvent());
LOGGER.info("[{}] [update-serverlist] serverlist updated to {}", name, serverUrls);
@ -325,16 +334,26 @@ public class ServerListManager {
}
public void refreshCurrentServerAddr() {
currentServerAddr = iterator().next();
iterator = iterator();
currentServerAddr = iterator.next();
}
public String getCurrentServerAddr() {
if (StringUtils.isBlank(currentServerAddr)) {
currentServerAddr = iterator().next();
iterator = iterator();
currentServerAddr = iterator.next();
}
return currentServerAddr;
}
public void updateCurrentServerAddr(String currentServerAddr) {
this.currentServerAddr = currentServerAddr;
}
public Iterator<String> getIterator() {
return iterator;
}
public String getContentPath() {
return contentPath;
}
@ -352,7 +371,7 @@ public class ServerListManager {
}
/**
* 不同环境的名称
* The name of the different environment
*/
private String name;
private String namespace = "";
@ -362,7 +381,7 @@ public class ServerListManager {
static public final String FIXED_NAME = "fixed";
private int initServerlistRetryTimes = 5;
/**
* 和其他server的连接超时和socket超时
* Connection timeout and socket timeout with other servers
*/
static final int TIMEOUT = 5000;
@ -376,15 +395,17 @@ public class ServerListManager {
private volatile String currentServerAddr;
private Iterator<String> iterator;
public String serverPort = ParamUtil.getDefaultServerPort();
public String addressServerUrl;
private String serverAddrsStr;
}
/**
* 对地址列表排序同机房优先
* Sort the address list, with the same room priority.
*/
class ServerAddressIterator implements Iterator<String> {
@ -426,14 +447,17 @@ class ServerAddressIterator implements Iterator<String> {
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();
}

View File

@ -16,31 +16,19 @@
package com.alibaba.nacos.client.logging.log4j2;
import com.alibaba.nacos.client.logging.AbstractNacosLogging;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.common.util.ClassUtils;
import com.alibaba.nacos.common.util.ResourceUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
import org.apache.logging.log4j.core.lookup.Interpolator;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.apache.logging.log4j.core.config.LoggerConfig;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.apache.logging.log4j.core.config.ConfigurationFactory.CONFIGURATION_FILE_PROPERTY;
import java.util.Map;
/**
* Support for Log4j version 2.7 or higher
@ -54,50 +42,32 @@ public class Log4J2NacosLogging extends AbstractNacosLogging {
private static final String FILE_PROTOCOL = "file";
private static final String YAML_PARSER_CLASS_NAME = "com.fasterxml.jackson.dataformat.yaml.YAMLParser";
private static final String NACOS_LOGGER_PREFIX = "com.alibaba.nacos";
private static final String JSON_PARSER_CLASS_NAME = "com.fasterxml.jackson.databind.ObjectMapper";
private final StrSubstitutor strSubstitutor = new StrSubstitutor(new Interpolator());
private Set<String> locationList = new HashSet<String>();
public Log4J2NacosLogging() {
String location = getLocation(NACOS_LOG4J2_LOCATION);
if (!StringUtils.isBlank(location)) {
locationList.add(location);
}
}
private String location = getLocation(NACOS_LOG4J2_LOCATION);
@Override
public void loadConfiguration() {
if (locationList.isEmpty()) {
return;
}
final LoggerContext loggerContext = (LoggerContext)LogManager.getContext(false);
final Configuration contextConfiguration = loggerContext.getConfiguration();
List<String> configList = findConfig(getCurrentlySupportedConfigLocations());
if (configList != null) {
locationList.addAll(configList);
}
final List<AbstractConfiguration> configurations = new ArrayList<AbstractConfiguration>();
LoggerContext loggerContext = (LoggerContext)LogManager.getContext(false);
for (String location : locationList) {
try {
// load and start nacos configuration
Configuration configuration = loadConfiguration(loggerContext, location);
if (configuration instanceof AbstractConfiguration) {
configurations.add((AbstractConfiguration)configuration);
configuration.start();
// append loggers and appenders to contextConfiguration
Map<String, Appender> appenders = configuration.getAppenders();
for (Appender appender: appenders.values()) {
contextConfiguration.addAppender(appender);
}
} catch (Exception e) {
throw new IllegalStateException(
"Could not initialize Log4J2 Nacos logging from " + location, e);
Map<String, LoggerConfig> loggers = configuration.getLoggers();
for (String name : loggers.keySet()) {
if (name.startsWith(NACOS_LOGGER_PREFIX)) {
contextConfiguration.addLogger(name, loggers.get(name));
}
}
// since log4j 2.6
CompositeConfiguration compositeConfiguration = new CompositeConfiguration(configurations);
loggerContext.start(compositeConfiguration);
loggerContext.updateLoggers();
}
private Configuration loadConfiguration(LoggerContext loggerContext, String location) {
@ -119,43 +89,4 @@ public class Log4J2NacosLogging extends AbstractNacosLogging {
}
return new ConfigurationSource(stream, url);
}
private String[] getCurrentlySupportedConfigLocations() {
List<String> supportedConfigLocations = new ArrayList<String>();
if (ClassUtils.isPresent(YAML_PARSER_CLASS_NAME)) {
Collections.addAll(supportedConfigLocations, "log4j2.yaml", "log4j2.yml", "log4j2-test.yaml",
"log4j2-test.yml");
}
if (ClassUtils.isPresent(JSON_PARSER_CLASS_NAME)) {
Collections.addAll(supportedConfigLocations, "log4j2.json", "log4j2.jsn", "log4j2-test.json",
"log4j2-test.jsn");
}
supportedConfigLocations.add("log4j2.xml");
supportedConfigLocations.add("log4j2-test.xml");
return supportedConfigLocations.toArray(new String[supportedConfigLocations.size()]);
}
private List<String> findConfig(String[] locations) {
final String configLocationStr = this.strSubstitutor.replace(PropertiesUtil.getProperties()
.getStringProperty(CONFIGURATION_FILE_PROPERTY));
if (configLocationStr != null) {
return Arrays.asList(configLocationStr.split(","));
}
for (String location : locations) {
ClassLoader defaultClassLoader = ClassUtils.getDefaultClassLoader();
if (defaultClassLoader != null && defaultClassLoader.getResource(location) != null) {
List<String> list = new ArrayList<String>();
list.add("classpath:" + location);
return list;
}
}
return null;
}
}

View File

@ -0,0 +1,174 @@
/*
* 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;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingMaintainService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.Service;
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.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.InitUtils;
import com.alibaba.nacos.client.utils.StringUtils;
import java.util.Map;
import java.util.Properties;
/**
* @author liaochuntao
* @since 1.0.1
*/
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
public class NacosNamingMaintainService implements NamingMaintainService {
private String namespace;
private String endpoint;
private String serverList;
private NamingProxy serverProxy;
public NacosNamingMaintainService(String serverList) {
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverList);
init(properties);
}
public NacosNamingMaintainService(Properties properties) {
init(properties);
}
private void init(Properties properties) {
namespace = InitUtils.initNamespaceForNaming(properties);
initServerAddr(properties);
InitUtils.initWebRootContext();
serverProxy = new NamingProxy(namespace, endpoint, serverList);
serverProxy.setProperties(properties);
}
private void initServerAddr(Properties properties) {
serverList = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
endpoint = InitUtils.initEndpoint(properties);
if (StringUtils.isNotEmpty(endpoint)) {
serverList = "";
}
}
@Override
public void updateInstance(String serviceName, Instance instance) throws NacosException {
updateInstance(serviceName, Constants.DEFAULT_GROUP, instance);
}
@Override
public void updateInstance(String serviceName, String groupName, Instance instance) throws NacosException {
serverProxy.updateInstance(serviceName, groupName, instance);
}
@Override
public Service queryService(String serviceName) throws NacosException {
return queryService(serviceName, Constants.DEFAULT_GROUP);
}
@Override
public Service queryService(String serviceName, String groupName) throws NacosException {
return serverProxy.queryService(serviceName, groupName);
}
@Override
public void createService(String serviceName) throws NacosException {
createService(serviceName, Constants.DEFAULT_GROUP);
}
@Override
public void createService(String serviceName, String groupName) throws NacosException {
createService(serviceName, groupName, Constants.DEFAULT_PROTECT_THRESHOLD);
}
@Override
public void createService(String serviceName, String groupName, float protectThreshold) throws NacosException {
NoneSelector selector = new NoneSelector();
Service service = new Service();
service.setName(serviceName);
service.setGroupName(groupName);
service.setProtectThreshold(protectThreshold);
createService(service, selector);
}
@Override
public void createService(String serviceName, String groupName, float protectThreshold, String expression) throws NacosException {
Service service = new Service();
service.setName(serviceName);
service.setGroupName(groupName);
service.setProtectThreshold(protectThreshold);
ExpressionSelector selector = new ExpressionSelector();
selector.setExpression(expression);
createService(service, selector);
}
@Override
public void createService(Service service, AbstractSelector selector) throws NacosException {
serverProxy.createService(service, selector);
}
@Override
public boolean deleteService(String serviceName) throws NacosException {
return deleteService(serviceName, Constants.DEFAULT_GROUP);
}
@Override
public boolean deleteService(String serviceName, String groupName) throws NacosException {
return serverProxy.deleteService(serviceName, groupName);
}
@Override
public void updateService(String serviceName, String groupName, float protectThreshold) throws NacosException {
Service service = new Service();
service.setName(serviceName);
service.setGroupName(groupName);
service.setProtectThreshold(protectThreshold);
updateService(service, new NoneSelector());
}
@Override
public void updateService(String serviceName, String groupName, float protectThreshold, Map<String, String> metadata) throws NacosException {
Service service = new Service();
service.setName(serviceName);
service.setGroupName(groupName);
service.setProtectThreshold(protectThreshold);
service.setMetadata(metadata);
updateService(service, new NoneSelector());
}
@Override
public void updateService(Service service, AbstractSelector selector) throws NacosException {
serverProxy.updateService(service, selector);
}
}

View File

@ -16,7 +16,6 @@
package com.alibaba.nacos.client.naming;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
@ -26,7 +25,6 @@ import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.client.identify.CredentialService;
import com.alibaba.nacos.client.naming.beat.BeatInfo;
import com.alibaba.nacos.client.naming.beat.BeatReactor;
import com.alibaba.nacos.client.naming.core.Balancer;
@ -34,25 +32,21 @@ import com.alibaba.nacos.client.naming.core.EventDispatcher;
import com.alibaba.nacos.client.naming.core.HostReactor;
import com.alibaba.nacos.client.naming.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.InitUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.client.utils.*;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.math.NumberUtils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.*;
/**
* @author nkorange
*/
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
public class NacosNamingService implements NamingService {
private static final String DEFAULT_PORT = "8080";
/**
* Each Naming instance should have different namespace.
*/
@ -82,15 +76,13 @@ public class NacosNamingService implements NamingService {
}
public NacosNamingService(Properties properties) {
init(properties);
}
private void init(Properties properties) {
serverList = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
initNamespace(properties);
initEndpoint(properties);
initWebRootContext();
namespace = InitUtils.initNamespaceForNaming(properties);
initServerAddr(properties);
InitUtils.initWebRootContext();
initCacheDir();
initLogName(properties);
@ -130,6 +122,14 @@ public class NacosNamingService implements NamingService {
return loadCacheAtStart;
}
private void initServerAddr(Properties properties) {
serverList = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
endpoint = InitUtils.initEndpoint(properties);
if (StringUtils.isNotEmpty(endpoint)) {
serverList = "";
}
}
private void initLogName(Properties properties) {
logName = System.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME);
if (StringUtils.isEmpty(logName)) {
@ -149,104 +149,6 @@ public class NacosNamingService implements NamingService {
}
}
private void initEndpoint(final Properties properties) {
if (properties == null) {
return;
}
//这里通过 dubbo/sca 侧来初始化默认传入的是 true
boolean isUseEndpointParsingRule = Boolean.valueOf(properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE, ParamUtil.USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE));
String endpointUrl;
if (isUseEndpointParsingRule) {
endpointUrl = ParamUtil.parsingEndpointRule(properties.getProperty(PropertyKeyConst.ENDPOINT));
if (com.alibaba.nacos.client.utils.StringUtils.isNotBlank(endpointUrl)) {
serverList = "";
}
} else {
endpointUrl = properties.getProperty(PropertyKeyConst.ENDPOINT);
}
if (StringUtils.isBlank(endpointUrl)) {
return;
}
String endpointPort = TemplateUtils.stringEmptyAndThenExecute(System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT), new Callable<String>() {
@Override
public String call() {
return properties.getProperty(PropertyKeyConst.ENDPOINT_PORT);
}
});
endpointPort = TemplateUtils.stringEmptyAndThenExecute(endpointPort, new Callable<String>() {
@Override
public String call() {
return "8080";
}
});
endpoint = endpointUrl + ":" + endpointPort;
}
private void initNamespace(Properties properties) {
String tmpNamespace = null;
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = System.getProperty(PropertyKeyConst.NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Property :" + namespace);
return namespace;
}
});
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Environment :" + namespace);
return namespace;
}
});
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = CredentialService.getInstance().getCredential().getTenantId();
LogUtils.NAMING_LOGGER.info("initializer namespace from Credential Module " + namespace);
return namespace;
}
});
if (StringUtils.isEmpty(tmpNamespace) && properties != null) {
tmpNamespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
}
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
return UtilAndComs.DEFAULT_NAMESPACE_ID;
}
});
namespace = tmpNamespace;
}
private void initWebRootContext() {
// support the web context with ali-yun if the app deploy by EDAS
final String webContext = System.getProperty(SystemPropertyKeyConst.NAMING_WEB_CONTEXT);
TemplateUtils.stringNotEmptyAndThenExecute(webContext, new Runnable() {
@Override
public void run() {
UtilAndComs.WEB_CONTEXT = webContext.indexOf("/") > -1 ? webContext
: "/" + webContext;
UtilAndComs.NACOS_URL_BASE = UtilAndComs.WEB_CONTEXT + "/v1/ns";
UtilAndComs.NACOS_URL_INSTANCE = UtilAndComs.NACOS_URL_BASE + "/instance";
}
});
}
@Override
public void registerInstance(String serviceName, String ip, int port) throws NacosException {
registerInstance(serviceName, ip, port, Constants.DEFAULT_CLUSTER_NAME);

View File

@ -21,8 +21,8 @@ import com.alibaba.nacos.client.naming.cache.ConcurrentDiskUtil;
import com.alibaba.nacos.client.naming.cache.DiskCache;
import com.alibaba.nacos.client.naming.core.HostReactor;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.client.utils.StringUtils;
import java.io.BufferedReader;
import java.io.File;

View File

@ -211,6 +211,6 @@ public class ConcurrentDiskUtil {
}
}
static final int RETRY_COUNT = 10;
static final int SLEEP_BASETIME = 10;
private static final int RETRY_COUNT = 10;
private static final int SLEEP_BASETIME = 10;
}

View File

@ -20,7 +20,7 @@ import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.alibaba.nacos.client.utils.StringUtils;
import java.io.BufferedReader;
import java.io.File;

View File

@ -125,7 +125,7 @@ public class EventDispatcher {
if (!CollectionUtils.isEmpty(listeners)) {
for (EventListener listener : listeners) {
List<Instance> hosts = Collections.unmodifiableList(serviceInfo.getHosts());
listener.onEvent(new NamingEvent(serviceInfo.getName(), hosts));
listener.onEvent(new NamingEvent(serviceInfo.getName(), serviceInfo.getGroupName(), serviceInfo.getClusters(), hosts));
}
}

View File

@ -23,8 +23,8 @@ import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.backups.FailoverReactor;
import com.alibaba.nacos.client.naming.cache.DiskCache;
import com.alibaba.nacos.client.naming.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.client.utils.StringUtils;
import java.util.*;
import java.util.concurrent.*;
@ -36,9 +36,9 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
*/
public class HostReactor {
public static final long DEFAULT_DELAY = 1000L;
private static final long DEFAULT_DELAY = 1000L;
public long updateHoldInterval = 5000L;
private static final long UPDATE_HOLD_INTERVAL = 5000L;
private final Map<String, ScheduledFuture<?>> futureMap = new HashMap<String, ScheduledFuture<?>>();
@ -234,11 +234,11 @@ public class HostReactor {
} else if (updatingMap.containsKey(serviceName)) {
if (updateHoldInterval > 0) {
if (UPDATE_HOLD_INTERVAL > 0) {
// hold a moment waiting for update finish
synchronized (serviceObj) {
try {
serviceObj.wait(updateHoldInterval);
serviceObj.wait(UPDATE_HOLD_INTERVAL);
} catch (InterruptedException e) {
NAMING_LOGGER.error("[getServiceInfo] serviceName:" + serviceName + ", clusters:" + clusters, e);
}

View File

@ -17,7 +17,7 @@ package com.alibaba.nacos.client.naming.core;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.naming.utils.IoUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.alibaba.nacos.client.utils.StringUtils;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

View File

@ -17,7 +17,7 @@ package com.alibaba.nacos.client.naming.net;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.naming.utils.IoUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.alibaba.nacos.client.utils.StringUtils;
import com.google.common.net.HttpHeaders;
import java.io.IOException;

View File

@ -24,6 +24,7 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.Service;
import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.api.selector.ExpressionSelector;
import com.alibaba.nacos.api.selector.SelectorType;
@ -31,6 +32,7 @@ import com.alibaba.nacos.client.config.impl.SpasAdapter;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.beat.BeatInfo;
import com.alibaba.nacos.client.naming.utils.*;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.common.util.HttpMethod;
import com.alibaba.nacos.common.util.UuidUtils;
@ -170,7 +172,7 @@ public class NamingProxy {
NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}",
namespaceId, serviceName, instance);
final Map<String, String> params = new HashMap<String, String>(8);
final Map<String, String> params = new HashMap<String, String>(9);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
@ -203,6 +205,83 @@ public class NamingProxy {
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.DELETE);
}
public void updateInstance(String serviceName, String groupName, Instance instance) throws NacosException {
NAMING_LOGGER.info("[UPDATE-SERVICE] {} update service {} with instance: {}",
namespaceId, serviceName, instance);
final Map<String, String> params = new HashMap<String, String>(8);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
params.put("ip", instance.getIp());
params.put("port", String.valueOf(instance.getPort()));
params.put("weight", String.valueOf(instance.getWeight()));
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
params.put("metadata", JSON.toJSONString(instance.getMetadata()));
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.PUT);
}
public Service queryService(String serviceName, String groupName) throws NacosException {
NAMING_LOGGER.info("[QUERY-SERVICE] {} query service : {}, {}",
namespaceId, serviceName, groupName);
final Map<String, String> params = new HashMap<String, String>(3);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
String result = reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.GET);
JSONObject jsonObject = JSON.parseObject(result);
return jsonObject.toJavaObject(Service.class);
}
public void createService(Service service, AbstractSelector selector) throws NacosException {
NAMING_LOGGER.info("[CREATE-SERVICE] {} creating service : {}",
namespaceId, service);
final Map<String, String> params = new HashMap<String, String>(6);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, service.getName());
params.put(CommonParams.GROUP_NAME, service.getGroupName());
params.put("protectThreshold", String.valueOf(service.getProtectThreshold()));
params.put("metadata", JSON.toJSONString(service.getMetadata()));
params.put("selector", JSON.toJSONString(selector));
reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.POST);
}
public boolean deleteService(String serviceName, String groupName) throws NacosException {
NAMING_LOGGER.info("[DELETE-SERVICE] {} deleting service : {} with groupName : {}",
namespaceId, serviceName, groupName);
final Map<String, String> params = new HashMap<String, String>(6);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
String result = reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.DELETE);
return "ok".equals(result);
}
public void updateService(Service service, AbstractSelector selector) throws NacosException {
NAMING_LOGGER.info("[UPDATE-SERVICE] {} updating service : {}",
namespaceId, service);
final Map<String, String> params = new HashMap<String, String>(6);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, service.getName());
params.put(CommonParams.GROUP_NAME, service.getGroupName());
params.put("protectThreshold", String.valueOf(service.getProtectThreshold()));
params.put("metadata", JSON.toJSONString(service.getMetadata()));
params.put("selector", JSON.toJSONString(selector));
reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.PUT);
}
public String queryList(String serviceName, String clusters, int udpPort, boolean healthyOnly)
throws NacosException {
@ -219,7 +298,9 @@ public class NamingProxy {
public long sendBeat(BeatInfo beatInfo) {
try {
NAMING_LOGGER.info("[BEAT] {} sending beat to server: {}", namespaceId, beatInfo.toString());
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER.debug("[BEAT] {} sending beat to server: {}", namespaceId, beatInfo.toString());
}
Map<String, String> params = new HashMap<String, String>(4);
params.put("beat", JSON.toJSONString(beatInfo));
params.put(CommonParams.NAMESPACE_ID, namespaceId);

View File

@ -0,0 +1,153 @@
/*
* 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.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.utils.*;
import java.util.Properties;
import java.util.concurrent.Callable;
/**
* @author liaochuntao
* @author deshao
*/
public class InitUtils {
/**
* Add a difference to the name naming. This method simply initializes the namespace for Naming.
* Config initialization is not the same, so it cannot be reused directly.
*
* @param properties
* @return
*/
public static final String initNamespaceForNaming(Properties properties) {
String tmpNamespace = null;
String isUseCloudNamespaceParsing =
properties.getProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
System.getProperty(SystemPropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
String.valueOf(Constants.DEFAULT_USE_CLOUD_NAMESPACE_PARSING)));
if (Boolean.valueOf(isUseCloudNamespaceParsing)) {
tmpNamespace = TenantUtil.getUserTenantForAns();
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = System.getProperty(SystemPropertyKeyConst.ANS_NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Property :" + namespace);
return namespace;
}
});
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Environment :" + namespace);
return namespace;
}
});
}
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = System.getProperty(PropertyKeyConst.NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Property :" + namespace);
return namespace;
}
});
if (StringUtils.isEmpty(tmpNamespace) && properties != null) {
tmpNamespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
}
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
return UtilAndComs.DEFAULT_NAMESPACE_ID;
}
});
return tmpNamespace;
}
public static final void initWebRootContext() {
// support the web context with ali-yun if the app deploy by EDAS
final String webContext = System.getProperty(SystemPropertyKeyConst.NAMING_WEB_CONTEXT);
TemplateUtils.stringNotEmptyAndThenExecute(webContext, new Runnable() {
@Override
public void run() {
UtilAndComs.WEB_CONTEXT = webContext.indexOf("/") > -1 ? webContext
: "/" + webContext;
UtilAndComs.NACOS_URL_BASE = UtilAndComs.WEB_CONTEXT + "/v1/ns";
UtilAndComs.NACOS_URL_INSTANCE = UtilAndComs.NACOS_URL_BASE + "/instance";
}
});
}
public static final String initEndpoint(final Properties properties) {
if (properties == null) {
return "";
}
// Whether to enable domain name resolution rules
String isUseEndpointRuleParsing =
properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
System.getProperty(SystemPropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
String.valueOf(ParamUtil.USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE)));
boolean isUseEndpointParsingRule = Boolean.valueOf(isUseEndpointRuleParsing);
String endpointUrl;
if (isUseEndpointParsingRule) {
// Get the set domain name information
endpointUrl = ParamUtil.parsingEndpointRule(properties.getProperty(PropertyKeyConst.ENDPOINT));
if (StringUtils.isBlank(endpointUrl)) {
return "";
}
} else {
endpointUrl = properties.getProperty(PropertyKeyConst.ENDPOINT);
}
if (StringUtils.isBlank(endpointUrl)) {
return "";
}
String endpointPort = TemplateUtils.stringEmptyAndThenExecute(System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT), new Callable<String>() {
@Override
public String call() {
return properties.getProperty(PropertyKeyConst.ENDPOINT_PORT);
}
});
endpointPort = TemplateUtils.stringEmptyAndThenExecute(endpointPort, new Callable<String>() {
@Override
public String call() {
return "8080";
}
});
return endpointUrl + ":" + endpointPort;
}
}

View File

@ -16,6 +16,8 @@
package com.alibaba.nacos.client.naming.utils;
import com.alibaba.nacos.client.utils.StringUtils;
import java.io.*;
import java.nio.channels.FileChannel;
import java.util.ArrayList;

View File

@ -15,6 +15,8 @@
*/
package com.alibaba.nacos.client.naming.utils;
import com.alibaba.nacos.client.utils.StringUtils;
import java.net.InetAddress;
import java.net.UnknownHostException;

View File

@ -1,163 +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 java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collection;
import java.util.Locale;
/**
* @author nkorange
*/
public class StringUtils {
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
public static final String EMPTY = "";
public static boolean equals(String str1, String str2) {
return str1 == null ? str2 == null : str1.equals(str2);
}
public static String join(Collection collection, String separator) {
if (collection == null) {
return null;
}
StringBuilder stringBuilder = new StringBuilder();
Object[] objects = collection.toArray();
for (int i = 0; i < collection.size() - 1; i++) {
stringBuilder.append(objects[i].toString()).append(separator);
}
if (collection.size() > 0) {
stringBuilder.append(objects[collection.size() - 1]);
}
return stringBuilder.toString();
}
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
public static String escapeJavaScript(String str) {
return escapeJavaStyleString(str, true, true);
}
private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes, boolean escapeForwardSlash) {
if (str == null) {
return null;
}
try {
StringWriter writer = new StringWriter(str.length() * 2);
escapeJavaStyleString(writer, str, escapeSingleQuotes, escapeForwardSlash);
return writer.toString();
} catch (IOException ioe) {
// this should never ever happen while writing to a StringWriter
return null;
}
}
private static String hex(char ch) {
return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
}
private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote,
boolean escapeForwardSlash) throws IOException {
if (out == null) {
throw new IllegalArgumentException("The Writer must not be null");
}
if (str == null) {
return;
}
int sz;
sz = str.length();
for (int i = 0; i < sz; i++) {
char ch = str.charAt(i);
// handle unicode
if (ch > 0xfff) {
out.write("\\u" + hex(ch));
} else if (ch > 0xff) {
out.write("\\u0" + hex(ch));
} else if (ch > 0x7f) {
out.write("\\u00" + hex(ch));
} else if (ch < 32) {
switch (ch) {
case '\b':
out.write('\\');
out.write('b');
break;
case '\n':
out.write('\\');
out.write('n');
break;
case '\t':
out.write('\\');
out.write('t');
break;
case '\f':
out.write('\\');
out.write('f');
break;
case '\r':
out.write('\\');
out.write('r');
break;
default:
if (ch > 0xf) {
out.write("\\u00" + hex(ch));
} else {
out.write("\\u000" + hex(ch));
}
break;
}
} else {
switch (ch) {
case '\'':
if (escapeSingleQuote) {
out.write('\\');
}
out.write('\'');
break;
case '"':
out.write('\\');
out.write('"');
break;
case '\\':
out.write('\\');
out.write('\\');
break;
case '/':
if (escapeForwardSlash) {
out.write('\\');
}
out.write('/');
break;
default:
out.write(ch);
break;
}
}
}
}
}

View File

@ -20,7 +20,7 @@ package com.alibaba.nacos.client.naming.utils;
*/
public class UtilAndComs {
public static final String VERSION = "Nacos-Java-Client:v1.0.0";
public static final String VERSION = "Nacos-Java-Client:v1.0.1";
public static String WEB_CONTEXT = "/nacos";
@ -28,6 +28,8 @@ public class UtilAndComs {
public static String NACOS_URL_INSTANCE = NACOS_URL_BASE + "/instance";
public static String NACOS_URL_SERVICE = NACOS_URL_BASE + "/service";
public static final String ENCODING = "UTF-8";
public static final String ENV_LIST_KEY = "envList";

View File

@ -86,28 +86,22 @@ public class EnvUtil {
return selfLocationTag;
}
public static String listToString(List<String> list) {
if (list == null) {
private static String listToString(List<String> list) {
if (list == null || list.isEmpty()) {
return null;
}
StringBuilder result = new StringBuilder();
boolean first = true;
// 第一个前面不拼接","
for (String string : list) {
if (first) {
first = false;
} else {
result.append(string);
result.append(",");
}
result.append(string);
}
return result.toString();
return result.toString().substring(0, result.length() - 1);
}
private static String selfAmorayTag;
private static String selfVipserverTag;
private static String selfLocationTag;
public final static String AMORY_TAG = "Amory-Tag";
public final static String VIPSERVER_TAG = "Vipserver-Tag";
public final static String LOCATION_TAG = "Location-Tag";
private final static String AMORY_TAG = "Amory-Tag";
private final static String VIPSERVER_TAG = "Vipserver-Tag";
private final static String LOCATION_TAG = "Location-Tag";
}

View File

@ -33,7 +33,7 @@ public class ParamUtil {
private final static Logger LOGGER = LogUtils.logger(ParamUtil.class);
public final static String USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE = "true";
public final static boolean USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE = true;
private static final Pattern PATTERN = Pattern.compile("\\$\\{[^}]+\\}");
private static String defaultContextPath = "nacos";

View File

@ -15,7 +15,11 @@
*/
package com.alibaba.nacos.client.utils;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collection;
import java.util.Locale;
/**
* string util
@ -26,13 +30,15 @@ public class StringUtils {
public static final int INDEX_NOT_FOUND = -1;
public static final String EMPTY = "";
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
if (!Character.isWhitespace(str.charAt(i))) {
return false;
}
}
@ -40,7 +46,6 @@ public class StringUtils {
}
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
@ -92,4 +97,106 @@ public class StringUtils {
return stringBuilder.toString();
}
public static String escapeJavaScript(String str) {
return escapeJavaStyleString(str, true, true);
}
private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes, boolean escapeForwardSlash) {
if (str == null) {
return null;
}
try {
StringWriter writer = new StringWriter(str.length() * 2);
escapeJavaStyleString(writer, str, escapeSingleQuotes, escapeForwardSlash);
return writer.toString();
} catch (IOException ioe) {
// this should never ever happen while writing to a StringWriter
return null;
}
}
private static String hex(char ch) {
return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
}
private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote,
boolean escapeForwardSlash) throws IOException {
if (out == null) {
throw new IllegalArgumentException("The Writer must not be null");
}
if (str == null) {
return;
}
int sz;
sz = str.length();
for (int i = 0; i < sz; i++) {
char ch = str.charAt(i);
// handle unicode
if (ch > 0xfff) {
out.write("\\u" + hex(ch));
} else if (ch > 0xff) {
out.write("\\u0" + hex(ch));
} else if (ch > 0x7f) {
out.write("\\u00" + hex(ch));
} else if (ch < 32) {
switch (ch) {
case '\b':
out.write('\\');
out.write('b');
break;
case '\n':
out.write('\\');
out.write('n');
break;
case '\t':
out.write('\\');
out.write('t');
break;
case '\f':
out.write('\\');
out.write('f');
break;
case '\r':
out.write('\\');
out.write('r');
break;
default:
if (ch > 0xf) {
out.write("\\u00" + hex(ch));
} else {
out.write("\\u000" + hex(ch));
}
break;
}
} else {
switch (ch) {
case '\'':
if (escapeSingleQuote) {
out.write('\\');
}
out.write('\'');
break;
case '"':
out.write('\\');
out.write('"');
break;
case '\\':
out.write('\\');
out.write('\\');
break;
case '/':
if (escapeForwardSlash) {
out.write('\\');
}
out.write('/');
break;
default:
out.write(ch);
break;
}
}
}
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.utils;
/**
* Tenant Util
*
* @author Nacos
*/
public class TenantUtil {
private static String userTenant;
static {
userTenant = System.getProperty("tenant.id", "");
}
/**
* Adapt the way ACM gets tenant on the cloud.
* <p>
* Note the difference between getting and getting ANS.
* Since the processing logic on the server side is different, the default value returns differently.
* </p>
*
* @return
*/
public static String getUserTenantForAcm() {
String tmp = userTenant;
if (StringUtils.isBlank(userTenant)) {
tmp = System.getProperty("acm.namespace", "");
}
return tmp;
}
/**
* Adapt the way ANS gets tenant on the cloud.
*
* @return
*/
public static String getUserTenantForAns() {
String tmp = userTenant;
if (StringUtils.isBlank(userTenant)) {
tmp = System.getProperty("ans.namespace");
}
return tmp;
}
}

View File

@ -45,5 +45,8 @@
additivity="false">
<AppenderRef ref="NAMING_LOG_FILE"/>
</Logger>
<Root level="INFO">
<AppenderRef ref="CONFIG_LOG_FILE"/>
</Root>
</Loggers>
</Configuration>

View File

@ -0,0 +1,62 @@
package com.alibaba.nacos.client;
import com.alibaba.nacos.client.utils.StringUtils;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import static org.junit.Assert.*;
import static com.alibaba.nacos.client.utils.StringUtils.*;
public class StringUtilsTest {
@Test
public void testisNotBlank() {
assertTrue(isNotBlank("foo"));
assertFalse(isNotBlank(" "));
assertFalse(isNotBlank(null));
}
@Test
public void testIsNotEmpty() {
assertFalse(isNotEmpty(""));
assertTrue(isNotEmpty("foo"));
}
@Test
public void testDefaultIfEmpty() {
assertEquals("foo", defaultIfEmpty("", "foo"));
assertEquals("bar", defaultIfEmpty("bar", "foo"));
}
@Test
public void testEquals() {
assertTrue(StringUtils.equals("foo", "foo"));
assertFalse(StringUtils.equals("bar", "foo"));
assertFalse(StringUtils.equals(" ", "foo"));
assertFalse(StringUtils.equals("foo", null));
}
@Test
public void testSubstringBetween() {
assertNull(substringBetween(null, null, null));
assertNull(substringBetween("", "foo", ""));
assertNull(substringBetween("foo", "bar", "baz"));
assertEquals("", substringBetween("foo", "foo", ""));
}
@Test
public void testJoin() {
assertNull(join(null, ""));
Collection collection = new ArrayList();
collection.add("foo");
collection.add("bar");
assertEquals("foo,bar", join(collection, ","));
}
}

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId>
<version>1.0.0</version>
<version>1.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -1,60 +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.common.util;
/**
* @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
* @since 0.9.0
*/
public class ClassUtils {
public static ClassLoader getDefaultClassLoader() {
try {
return Thread.currentThread().getContextClassLoader();
} catch (Throwable t) {
// ignore
}
ClassLoader classLoader = ClassUtils.class.getClassLoader();
if (classLoader != null) {
return classLoader;
}
try {
return ClassLoader.getSystemClassLoader();
} catch (Throwable t) {
// ignore
}
return null;
}
public static boolean isPresent(String className) {
ClassLoader defaultClassLoader = getDefaultClassLoader();
try {
if (defaultClassLoader != null) {
defaultClassLoader.loadClass(className);
} else {
Class.forName(className);
}
return true;
} catch (Throwable t) {
return false;
}
}
}

View File

@ -17,7 +17,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -406,6 +406,7 @@ public class LongPollingService extends AbstractEventListener {
}
}
}, timeoutTime, TimeUnit.MILLISECONDS);
allSubs.add(this);

View File

@ -100,7 +100,7 @@ public class DumpService {
log.warn("clearConfigHistory start");
if (ServerListService.isFirstIp()) {
try {
Timestamp startTime = getBeforeStamp(TimeUtils.getCurrentTime(), 24 * 30);
Timestamp startTime = getBeforeStamp(TimeUtils.getCurrentTime(), 24 * getRetentionDays());
int totalCount = persistService.findConfigHistoryCountByTime(startTime);
if (totalCount > 0) {
int pageSize = 1000;
@ -278,6 +278,25 @@ public class DumpService {
return isQuickStart;
}
private int getRetentionDays() {
String val = env.getProperty("nacos.config.retention.days");
if (null == val) {
return retentionDays;
}
int tmp = 0;
try {
tmp = Integer.parseInt(val);
if (tmp > 0) {
retentionDays = tmp;
}
} catch (NumberFormatException nfe) {
fatalLog.error("read nacos.config.retention.days wrong", nfe);
}
return retentionDays;
}
public void dump(String dataId, String group, String tenant, String tag, long lastModified, String handleIp) {
dump(dataId, group, tenant, tag, lastModified, handleIp, false);
}
@ -400,4 +419,5 @@ public class DumpService {
Boolean isQuickStart = false;
private int retentionDays = 30;
}

View File

@ -0,0 +1,24 @@
package com.alibaba.nacos.config.server.service.dump;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class DumpServiceTest {
@Autowired
DumpService service;
@Test
public void init() {
service.init();
}
}

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<artifactId>nacos-console</artifactId>
<!--<packaging>war</packaging>-->
@ -104,6 +104,7 @@
<version>2.1.1.RELEASE</version>
<configuration>
<mainClass>com.alibaba.nacos.Nacos</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>

0
console/src/main/resources/nacos-version.txt Executable file → Normal file
View File

View File

@ -38,6 +38,9 @@ module.exports = {
components: resolve('src/components'),
},
},
node: {
fs: 'empty'
},
module: {
rules: [
{

View File

@ -75,6 +75,7 @@
"react-router-dom": "^4.3.1",
"react-router-redux": "^4.0.8",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0"
"redux-thunk": "^2.3.0",
"yamljs": "^0.3.0"
}
}

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1,491 @@
/*
* 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.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { getParams } from '../../globalLib';
import { ConfigProvider, Dialog, Loading, Tab } from '@alifd/next';
import './index.scss';
const TabPane = Tab.Item;
/**
*
* Service Registration Sample Code Show Window
* @author yongchao9 #2019年05月18日 下午4:26:19
*
*/
@ConfigProvider.config
class ShowServiceCodeing extends React.Component {
static displayName = 'ShowServiceCodeing';
static propTypes = {
locale: PropTypes.object,
};
constructor(props) {
super(props);
this.state = {
dialogvisible: false,
loading: false,
};
this.defaultCode = '';
this.nodejsCode = 'TODO';
this.cppCode = 'TODO';
this.shellCode = 'TODO';
this.pythonCode = 'TODO';
this.record = {};
this.springCode = 'TODO';
this.sprigbootCode = 'TODO';
this.sprigcloudCode = 'TODO';
}
componentDidMount() {
}
openLoading() {
this.setState({
loading: true,
});
}
closeLoading() {
this.setState({
loading: false,
});
}
getData() {
const namespace = getParams('namespace'); // 获取ak,sk
const obj = {
group: this.record.group || '',
dataId: this.record.dataId || '',
namespace,
inEdas: window.globalConfig.isParentEdas(),
};
this.defaultCode = this.getJavaCode(obj);
this.createCodeMirror('text/x-java', this.defaultCode);
this.springCode = this.getSpringCode(obj);
this.sprigbootCode = this.getSpringBootCode(obj);
this.sprigcloudCode = this.getSpringCloudCode(obj);
this.nodejsCode = this.getNodejsCode(obj);
this.cppCode = this.getCppCode(obj);
this.shellCode = this.getShellCode(obj);
this.pythonCode = this.getPythonCode(obj);
this.forceUpdate();
}
getJavaCode(data) {
return `/* Refer to document: https://github.com/alibaba/nacos/blob/master/example/src/main/java/com/alibaba/nacos/example
* pom.xml
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>$\{latest.version}</version>
</dependency>
*/
package com.alibaba.nacos.example;
import java.util.Properties;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.Event;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
/**
* @author nkorange
*/
public class NamingExample {
public static void main(String[] args) throws NacosException {
Properties properties = new Properties();
properties.setProperty("serverAddr", System.getProperty("serverAddr"));
properties.setProperty("namespace", System.getProperty("namespace"));
NamingService naming = NamingFactory.createNamingService(properties);
naming.registerInstance("${this.record.name}", "11.11.11.11", 8888, "TEST1");
naming.registerInstance("${this.record.name}", "2.2.2.2", 9999, "DEFAULT");
System.out.println(naming.getAllInstances("${this.record.name}"));
naming.deregisterInstance("${this.record.name}", "2.2.2.2", 9999, "DEFAULT");
System.out.println(naming.getAllInstances("${this.record.name}"));
naming.subscribe("${this.record.name}", new EventListener() {
@Override
public void onEvent(Event event) {
System.out.println(((NamingEvent)event).getServiceName());
System.out.println(((NamingEvent)event).getInstances());
}
});
}
}`;
}
getSpringCode(data) {
return `/* Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-example/nacos-spring-discovery-example
* pom.xml
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<version>\${latest.version}</version>
</dependency>
*/
// Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-example/nacos-spring-discovery-example/src/main/java/com/alibaba/nacos/example/spring
package com.alibaba.nacos.example.spring;
import com.alibaba.nacos.api.annotation.NacosProperties;
import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableNacosDiscovery(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))
public class NacosConfiguration {
}
// Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-example/nacos-spring-discovery-example/src/main/java/com/alibaba/nacos/example/spring/controller
package com.alibaba.nacos.example.spring.controller;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
@Controller
@RequestMapping("discovery")
public class DiscoveryController {
@NacosInjected
private NamingService namingService;
@RequestMapping(value = "/get", method = GET)
@ResponseBody
public List<Instance> get(@RequestParam String serviceName) throws NacosException {
return namingService.getAllInstances(serviceName);
}
}`;
}
getSpringBootCode(data) {
return `/* Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-boot-example/nacos-spring-boot-discovery-example
* pom.xml
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>\${latest.version}</version>
</dependency>
*/
/* Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-boot-example/nacos-spring-boot-discovery-example/src/main/resources
* application.properties
nacos.discovery.server-addr=127.0.0.1:8848
*/
// Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-boot-example/nacos-spring-boot-discovery-example/src/main/java/com/alibaba/nacos/example/spring/boot/controller
package com.alibaba.nacos.example.spring.boot.controller;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
@Controller
@RequestMapping("discovery")
public class DiscoveryController {
@NacosInjected
private NamingService namingService;
@RequestMapping(value = "/get", method = GET)
@ResponseBody
public List<Instance> get(@RequestParam String serviceName) throws NacosException {
return namingService.getAllInstances(serviceName);
}
}`;
}
getSpringCloudCode(data) {
return `/* Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/
* pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>\${latest.version}</version>
</dependency>
*/
// nacos-spring-cloud-provider-example
/* Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/nacos-spring-cloud-provider-example/src/main/resources
* application.properties
server.port=18080
spring.application.name=${this.record.name}
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
*/
// Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/nacos-spring-cloud-provider-example/src/main/java/com/alibaba/nacos/example/spring/cloud
package com.alibaba.nacos.example.spring.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* @author xiaojing
*/
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NacosProviderApplication.class, args);
}
@RestController
class EchoController {
@RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
public String echo(@PathVariable String string) {
return "Hello Nacos Discovery " + string;
}
}
}
// nacos-spring-cloud-consumer-example
/* Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/nacos-spring-cloud-consumer-example/src/main/resources
* application.properties
spring.application.name=micro-service-oauth2
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
*/
// Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/nacos-spring-cloud-consumer-example/src/main/java/com/alibaba/nacos/example/spring/cloud
package com.alibaba.nacos.example.spring.cloud;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @author xiaojing
*/
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApplication {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(NacosConsumerApplication.class, args);
}
@RestController
public class TestController {
private final RestTemplate restTemplate;
@Autowired
public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
public String echo(@PathVariable String str) {
return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
}
}
}`;
}
getNodejsCode(data) {
return 'TODO';
}
getCppCode(data) {
return 'TODO';
}
getShellCode(data) {
return 'TODO';
}
getPythonCode(data) {
return 'TODO';
}
openDialog(record) {
this.setState({
dialogvisible: true,
});
this.record = record;
setTimeout(() => {
this.getData(); // 获取数据
});
}
closeDialog() {
this.setState({
dialogvisible: false,
});
}
createCodeMirror(mode, value) {
const commontarget = this.refs.codepreview;
if (commontarget) {
commontarget.innerHTML = '';
this.cm = window.CodeMirror(commontarget, {
value,
mode,
height: 400,
width: 500,
lineNumbers: true,
theme: 'xq-light',
lint: true,
tabMode: 'indent',
autoMatchParens: true,
textWrapping: true,
gutters: ['CodeMirror-lint-markers'],
extraKeys: {
F1(cm) {
cm.setOption('fullScreen', !cm.getOption('fullScreen'));
},
Esc(cm) {
if (cm.getOption('fullScreen')) cm.setOption('fullScreen', false);
},
},
});
// this.cm.setSize('300px',height:'222px');
this.cm.setSize('auto', '490px');
}
// this.cm.setSize(window.innerWidth*0.8-10,400);//设置宽高
}
changeTab(key, code) {
setTimeout(() => {
this[key] = true;
this.createCodeMirror('text/javascript', code);
});
}
render() {
const { locale = {} } = this.props;
const footer = <div />;
return (
<div>
<Dialog
title={locale.sampleCode}
style={{ width: '80%' }}
visible={this.state.dialogvisible}
footer={footer}
onClose={this.closeDialog.bind(this)}
>
<div style={{ height: 500 }}>
<Loading tip={locale.loading} style={{ width: '100%' }} visible={this.state.loading}>
<Tab shape={'text'} style={{ height: 40, paddingBottom: 10 }}>
<TabPane
title={'Java'}
key={0}
onClick={this.changeTab.bind(this, 'commoneditor1', this.defaultCode)}
/>
<TabPane
title={'Spring'}
key={1}
onClick={this.changeTab.bind(this, 'commoneditor1', this.springCode)}
/>
<TabPane
title={'Spring Boot'}
key={2}
onClick={this.changeTab.bind(this, 'commoneditor2', this.sprigbootCode)}
/>
<TabPane
title={'Spring Cloud'}
key={21}
onClick={this.changeTab.bind(this, 'commoneditor21', this.sprigcloudCode)}
/>
<TabPane
title={'Node.js'}
key={3}
onClick={this.changeTab.bind(this, 'commoneditor3', this.nodejsCode)}
/>
<TabPane
title={'C++'}
key={4}
onClick={this.changeTab.bind(this, 'commoneditor4', this.cppCode)}
/>
<TabPane
title={'Shell'}
key={5}
onClick={this.changeTab.bind(this, 'commoneditor5', this.shellCode)}
/>
<TabPane
title={'Python'}
key={6}
onClick={this.changeTab.bind(this, 'commoneditor6', this.pythonCode)}
/>
{}
</Tab>
<div ref={'codepreview'} />
</Loading>
</div>
</Dialog>
</div>
);
}
}
export default ShowServiceCodeing;

View File

@ -41,6 +41,7 @@ import ListeningToQuery from './pages/ConfigurationManagement/ListeningToQuery';
import ConfigurationManagement from './pages/ConfigurationManagement/ConfigurationManagement';
import ServiceList from './pages/ServiceManagement/ServiceList';
import ServiceDetail from './pages/ServiceManagement/ServiceDetail';
import ClusterNodeList from './pages/ClusterManagement/ClusterNodeList';
import reducers from './reducers';
import { changeLanguage } from './reducers/locale';
@ -81,6 +82,7 @@ const MENU = [
{ path: '/configurationManagement', component: ConfigurationManagement },
{ path: '/serviceManagement', component: ServiceList },
{ path: '/serviceDetail', component: ServiceDetail },
{ path: '/clusterManagement', component: ClusterNodeList },
];
@connect(

View File

@ -391,7 +391,7 @@ class MainLayout extends React.Component {
refreshNav() {
const { navList } = this.state;
const { location, history, functionMode } = this.props;
const [configUrl, serviceUrl] = ['/configurationManagement', '/serviceManagement'];
const [configUrl, serviceUrl, clusterUrl] = ['/configurationManagement', '/serviceManagement', '/clusterManagement'];
this.setState(
{
navList: navList.map(item => {
@ -407,6 +407,12 @@ class MainLayout extends React.Component {
) {
item.enable = true;
}
if (
item.serviceName === 'clusterManagementVirtual' &&
(functionMode === null || functionMode === 'cluster')
) {
item.enable = true;
}
return item;
}),
},
@ -418,6 +424,9 @@ class MainLayout extends React.Component {
if (functionMode === 'naming' && location.pathname === configUrl) {
history.push(serviceUrl);
}
if (functionMode === 'cluster' && location.pathname === clusterUrl) {
history.push(clusterUrl);
}
}
componentWillReceiveProps() {

View File

@ -46,6 +46,8 @@ const I18N_CONF = {
serviceManagement: 'Service List',
serviceDetail: 'Service Details',
namespace: 'Namespace',
clusterManagementVirtual: 'ClusterManagement',
clusterManagement: 'Cluster Node List',
},
NameSpace: {
namespace: 'Namespaces',
@ -84,11 +86,24 @@ const I18N_CONF = {
columnHealthyInstanceCount: 'Healthy Instance Count',
operation: 'Operation',
detail: 'Details',
sampleCode: 'Code Example',
deleteAction: 'Delete',
prompt: 'Confirm',
promptDelete: 'Do you want to delete the service?',
create: 'Create Service',
},
ClusterNodeList: {
clusterNodeList: 'Node List',
nodeIp: 'NodeIp',
nodeIpPlaceholder: 'Please enter node Ip',
query: 'Search',
pubNoData: 'No results found.',
nodeState: 'NodeState',
clusterTerm: 'ClusterTerm',
leaderDueMs: 'LeaderDue(ms)',
heartbeatDueMs: 'HeartbeatDue(ms)',
voteFor: 'VoteFor',
},
EditClusterDialog: {
updateCluster: 'Update Cluster',
checkType: 'Check Type',

View File

@ -46,6 +46,8 @@ const I18N_CONF = {
serviceManagement: '服务列表',
serviceDetail: '服务详情',
namespace: '命名空间',
clusterManagementVirtual: '集群管理',
clusterManagement: '节点列表',
},
NameSpace: {
namespace: '命名空间',
@ -84,11 +86,24 @@ const I18N_CONF = {
columnHealthyInstanceCount: '健康实例数',
operation: '操作',
detail: '详情',
sampleCode: '示例代码',
deleteAction: '删除',
prompt: '提示',
promptDelete: '确定要删除当前服务吗',
create: '创建服务',
},
ClusterNodeList: {
clusterNodeList: '节点列表',
nodeIp: '节点Ip',
nodeIpPlaceholder: '请输入节点Ip',
query: '查询',
pubNoData: '没有数据',
nodeState: '节点状态',
clusterTerm: '集群任期',
leaderDueMs: 'Leader止时(ms)',
heartbeatDueMs: '心跳止时(ms)',
voteFor: '投票对象',
},
EditClusterDialog: {
updateCluster: '更新集群',
checkType: '检查类型',

View File

@ -227,6 +227,37 @@ module.exports = {
useRouter: false,
id: 'namespace',
},
{
enable: false,
isExtend: true,
name: '集群管理',
title: '集群管理',
isVirtual: true,
projectName: 'nacos',
serviceName: 'clusterManagementVirtual',
link: 'clusterManagementVirtual',
hasFusion: true,
template: '',
registerName: 'com.alibaba.nacos.page.clusterManagementVirtual',
useRouter: false,
id: 'com.alibaba.nacos.page.clusterManagementVirtual',
children: [
{
isExtend: false,
name: '节点状态',
title: '节点状态',
isVirtual: false,
projectName: 'nacos',
serviceName: 'clusterManagement',
link: 'clusterManagement',
hasFusion: true,
template: '',
registerName: 'com.alibaba.nacos.page.clusterManagement',
useRouter: false,
id: 'clusterManagement',
},
],
},
],
defaultKey: 'configurationManagement',
projectName: 'nacos',

View File

@ -0,0 +1,204 @@
/*
* 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.
*/
import React from 'react';
import PropTypes from 'prop-types';
import {
Button,
Field,
Form,
Grid,
Input,
Loading,
Pagination,
Table,
ConfigProvider,
} from '@alifd/next';
import { request } from '../../../globalLib';
import RegionGroup from '../../../components/RegionGroup';
import './ClusterNodeList.scss';
const FormItem = Form.Item;
const { Row, Col } = Grid;
const { Column } = Table;
@ConfigProvider.config
class ClusterNodeList extends React.Component {
static displayName = 'ClusterNodeList';
static propTypes = {
locale: PropTypes.object,
};
constructor(props) {
super(props);
this.state = {
loading: false,
total: 0,
pageSize: 10,
currentPage: 1,
keyword: '',
dataSource: [],
};
this.field = new Field(this);
}
openLoading() {
this.setState({ loading: true });
}
closeLoading() {
this.setState({ loading: false });
}
openEditServiceDialog() {
try {
this.editServiceDialog.current.getInstance().show(this.state.service);
} catch (error) {}
}
queryClusterStateList() {
const { currentPage, pageSize, keyword, withInstances = false } = this.state;
const parameter = [
`withInstances=${withInstances}`,
`pageNo=${currentPage}`,
`pageSize=${pageSize}`,
`keyword=${keyword}`,
];
request({
url: `v1/ns/operator/cluster/states?${parameter.join('&')}`,
beforeSend: () => this.openLoading(),
success: ({ count = 0, clusterStateList = [] } = {}) => {
this.setState({
dataSource: clusterStateList,
total: count,
});
},
error: () =>
this.setState({
dataSource: [],
total: 0,
currentPage: 0,
}),
complete: () => this.closeLoading(),
});
}
getQueryLater = () => {
setTimeout(() => this.queryClusterStateList());
};
setNowNameSpace = (nowNamespaceName, nowNamespaceId) =>
this.setState({
nowNamespaceName,
nowNamespaceId,
});
rowColor = row => ({ className: !row.voteFor ? '' : '' });
render() {
const { locale = {} } = this.props;
const {
pubNoData,
clusterNodeList,
nodeIp,
nodeIpPlaceholder,
query,
} = locale;
const { keyword, nowNamespaceName, nowNamespaceId } = this.state;
const { init, getValue } = this.field;
this.init = init;
this.getValue = getValue;
return (
<div className="main-container cluster-management">
<Loading
shape="flower"
style={{ position: 'relative', width: '100%' }}
visible={this.state.loading}
tip="Loading..."
color="#333"
>
<div style={{ marginTop: -15 }}>
<RegionGroup
setNowNameSpace={this.setNowNameSpace}
namespaceCallBack={this.getQueryLater}
/>
</div>
<h3 className="page-title">
<span className="title-item">{clusterNodeList}</span>
<span className="title-item">|</span>
<span className="title-item">{nowNamespaceName}</span>
<span className="title-item">{nowNamespaceId}</span>
</h3>
<Row className="demo-row" style={{ marginBottom: 10, padding: 0 }}>
<Col span="24">
<Form inline field={this.field}>
<FormItem label={nodeIp}>
<Input
placeholder={nodeIpPlaceholder}
style={{ width: 200 }}
value={keyword}
onChange={keyword => this.setState({ keyword })}
onPressEnter={() =>
this.setState({ currentPage: 1 }, () => this.queryClusterStateList())
}
/>
</FormItem>
<FormItem label="">
<Button
type="primary"
onClick={() => this.setState({ currentPage: 1 }, () => this.queryClusterStateList())}
style={{ marginRight: 10 }}
>
{query}
</Button>
</FormItem>
</Form>
</Col>
</Row>
<Row style={{ padding: 0 }}>
<Col span="24" style={{ padding: 0 }}>
<Table
dataSource={this.state.dataSource}
locale={{ empty: pubNoData }}
getRowProps={row => this.rowColor(row)}
>
<Column title={locale.nodeIp} dataIndex="nodeIp" />
<Column title={locale.nodeState} dataIndex="nodeState" />
<Column title={locale.clusterTerm} dataIndex="clusterTerm" />
<Column title={locale.leaderDueMs} dataIndex="leaderDueMs" />
<Column title={locale.heartbeatDueMs} dataIndex="heartbeatDueMs" />
</Table>
</Col>
</Row>
{this.state.total > this.state.pageSize && (
<div style={{ marginTop: 10, textAlign: 'right' }}>
<Pagination
current={this.state.currentPage}
total={this.state.total}
pageSize={this.state.pageSize}
onChange={currentPage =>
this.setState({ currentPage }, () => this.queryClusterStateList())
}
/>
</div>
)}
</Loading>
</div>
);
}
}
export default ClusterNodeList;

View File

@ -0,0 +1,29 @@
/*
* 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.
*/
.cluster-management {
.page-title {
height: 30px;
width: 100%;
line-height: 30px;
margin: 0 0 20px;
padding: 0 0 0 10px;
border-left: 3px solid #09c;
color: #ccc;
}
.title-item {
font-size: 14px;
color: #000;
margin-right: 8px;
}
}

View File

@ -0,0 +1,16 @@
/*
* 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.
*/
import ClusterNodeList from './ClusterNodeList';
export default ClusterNodeList;

View File

@ -468,7 +468,7 @@ class NewConfig extends React.Component {
message: locale.moreAdvanced,
},
{
max: 127,
maxLength: 127,
message: locale.groupNotEmpty,
},
{ validator: this.validateChart.bind(this) },

View File

@ -67,7 +67,7 @@ class EditInstanceDialog extends React.Component {
port,
ephemeral,
weight,
enable: enabled,
enabled,
metadata: replaceEnter(METADATA_SEPARATOR)(metadataText),
},
dataType: 'text',

View File

@ -26,6 +26,7 @@ class InstanceTable extends React.Component {
locale: PropTypes.object,
clusterName: PropTypes.string,
serviceName: PropTypes.string,
groupName: PropTypes.string,
};
constructor(props) {
@ -52,7 +53,7 @@ class InstanceTable extends React.Component {
}
getInstanceList() {
const { clusterName, serviceName } = this.props;
const { clusterName, serviceName, groupName } = this.props;
if (!clusterName) return;
const { pageSize, pageNum } = this.state;
request({
@ -60,6 +61,7 @@ class InstanceTable extends React.Component {
data: {
serviceName,
clusterName,
groupName,
pageSize,
pageNo: pageNum,
},
@ -87,7 +89,7 @@ class InstanceTable extends React.Component {
port,
ephemeral,
weight,
enable: !enabled,
enabled: !enabled,
metadata: JSON.stringify(metadata),
},
dataType: 'text',

View File

@ -93,7 +93,7 @@ class ServiceDetail extends React.Component {
render() {
const { locale = {} } = this.props;
const { serviceName, loading, service = {}, clusters } = this.state;
const { serviceName, groupName, loading, service = {}, clusters } = this.state;
const { metadata = {}, selector = {} } = service;
const metadataText = processMetaData(METADATA_ENTER)(metadata);
return (
@ -169,7 +169,11 @@ class ServiceDetail extends React.Component {
</Button>
}
>
<InstanceTable clusterName={cluster.name} serviceName={serviceName} />
<InstanceTable
clusterName={cluster.name}
serviceName={serviceName}
groupName={groupName}
/>
</Card>
))}
</Loading>

View File

@ -29,6 +29,7 @@ import {
import { request } from '../../../globalLib';
import RegionGroup from '../../../components/RegionGroup';
import EditServiceDialog from '../ServiceDetail/EditServiceDialog';
import ShowServiceCodeing from 'components/ShowCodeing/ShowServiceCodeing';
import './ServiceList.scss';
@ -48,6 +49,7 @@ class ServiceList extends React.Component {
constructor(props) {
super(props);
this.editServiceDialog = React.createRef();
this.showcode = React.createRef();
this.state = {
loading: false,
total: 0,
@ -69,8 +71,10 @@ class ServiceList extends React.Component {
openEditServiceDialog() {
try {
this.editServiceDialog.current.getInstance().show(this.state.service);
} catch (error) {}
this.editServiceDialog.current.getInstance()
.show(this.state.service);
} catch (error) {
}
}
queryServiceList() {
@ -104,6 +108,21 @@ class ServiceList extends React.Component {
setTimeout(() => this.queryServiceList());
};
showcode = () => {
setTimeout(() => this.queryServiceList());
};
/**
*
* Added method to open sample code window
* @author yongchao9 #2019年05月18日 下午5:46:28
*
*/
showSampleCode(record) {
this.showcode.current.getInstance()
.openDialog(record);
}
deleteService(service) {
const { locale = {} } = this.props;
const { prompt, promptDelete } = locale;
@ -138,6 +157,7 @@ class ServiceList extends React.Component {
rowColor = row => ({ className: !row.healthyInstanceCount ? 'row-bg-red' : '' });
render() {
const { locale = {} } = this.props;
const {
@ -149,6 +169,7 @@ class ServiceList extends React.Component {
create,
operation,
detail,
sampleCode,
deleteAction,
} = locale;
const { keyword, nowNamespaceName, nowNamespaceId } = this.state;
@ -160,7 +181,10 @@ class ServiceList extends React.Component {
<div className="main-container service-management">
<Loading
shape="flower"
style={{ position: 'relative', width: '100%' }}
style={{
position: 'relative',
width: '100%',
}}
visible={this.state.loading}
tip="Loading..."
color="#333"
@ -177,7 +201,13 @@ class ServiceList extends React.Component {
<span className="title-item">{nowNamespaceName}</span>
<span className="title-item">{nowNamespaceId}</span>
</h3>
<Row className="demo-row" style={{ marginBottom: 10, padding: 0 }}>
<Row
className="demo-row"
style={{
marginBottom: 10,
padding: 0,
}}
>
<Col span="24">
<Form inline field={this.field}>
<FormItem label={serviceName}>
@ -227,24 +257,32 @@ class ServiceList extends React.Component {
title={operation}
align="center"
cell={(value, index, record) => (
// @author yongchao9 #2019年05月18日 下午5:46:28
/* Add a link to view "sample code"
replace the original button with a label,
which is consistent with the operation style in configuration management.
*/
<div>
<Button
type="normal"
<a
onClick={() =>
this.props.history.push(
`/serviceDetail?name=${record.name}&groupName=${record.groupName}`
)
}
`/serviceDetail?name=${record.name}&groupName=${record.groupName}`,
)}
style={{ marginRight: 5 }}
>
{detail}
</Button>
<Button
style={{ marginLeft: 12 }}
type="normal"
</a>
<span style={{ marginRight: 5 }}>|</span>
<a style={{ marginRight: 5 }} onClick={() => this.showSampleCode(record)}>
{sampleCode}
</a>
<span style={{ marginRight: 5 }}>|</span>
<a
onClick={() => this.deleteService(record)}
style={{ marginRight: 5 }}
>
{deleteAction}
</Button>
</a>
</div>
)}
/>
@ -252,7 +290,11 @@ class ServiceList extends React.Component {
</Col>
</Row>
{this.state.total > this.state.pageSize && (
<div style={{ marginTop: 10, textAlign: 'right' }}>
<div style={{
marginTop: 10,
textAlign: 'right',
}}
>
<Pagination
current={this.state.currentPage}
total={this.state.total}
@ -264,6 +306,7 @@ class ServiceList extends React.Component {
</div>
)}
</Loading>
<ShowServiceCodeing ref={this.showcode} />
<EditServiceDialog
ref={this.editServiceDialog}
openLoading={() => this.openLoading()}

View File

@ -1,3 +1,5 @@
import * as yamljs from 'yamljs';
export default {
/**
* 检测json是否合法
@ -35,21 +37,19 @@ export default {
/**
* 检测yaml是否合法
*/
// validateYaml(str) {
// try {
// console.log('yaml: ', yaml, yaml.safeLoadAll(str));
// return !!yaml.safeLoadAll(str);
// } catch (e) {
// console.log('e: ', e);
// return false;
// }
// },
validateYaml(str) {
try {
return yamljs.parse(str);
} catch (e) {
return false;
}
},
/**
* 检测属性是否正确
*/
validateProperties(str = '') {
const reg = /^[^=]+=[^=]+$/;
const reg = /^[^=]+=.+$/;
return str
.replace('\n\r', '\n')
.split('\n')
@ -66,6 +66,7 @@ export default {
'text/html': this.validateXml,
html: this.validateXml,
properties: this.validateProperties,
yaml: this.validateYaml,
};
if (!validateObj[type]) {

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -14,7 +14,7 @@ rem limitations under the License.
if not exist "%JAVA_HOME%\bin\java.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! & EXIT /B 1
set "JAVA=%JAVA_HOME%\bin\java.exe"
setlocal
setlocal enabledelayedexpansion
set BASE_DIR=%~dp0
rem added double quotation marks to avoid the issue caused by the folder names containing spaces.
@ -24,9 +24,26 @@ set BASE_DIR="%BASE_DIR:~0,-5%"
set DEFAULT_SEARCH_LOCATIONS="classpath:/,classpath:/config/,file:./,file:./config/"
set CUSTOM_SEARCH_LOCATIONS=%DEFAULT_SEARCH_LOCATIONS%,file:%BASE_DIR%/conf/
set MODE="standalone"
set FUNCTION_MODE="all"
set MODE_INDEX=-1
set FUNCTION_MODE_INDEX=-1
set i=0
for %%a in (%*) do (
if "%%a" == "-m" ( set /a MODE_INDEX=!i!+1 )
if "%%a" == "-f" ( set /a FUNCTION_MODE_INDEX=!i!+1 )
set /a i+=1
)
if not "%2" == "cluster" (
set i=0
for %%a in (%*) do (
if %MODE_INDEX% == !i! ( set MODE="%%a" )
if %FUNCTION_MODE_INDEX% == !i! ( set FUNCTION_MODE="%%a" )
set /a i+=1
)
if %MODE% == "standalone" (
set "JAVA_OPT=%JAVA_OPT% -Xms512m -Xmx512m -Xmn256m"
set "JAVA_OPT=%JAVA_OPT% -Dnacos.standalone=true"
) else (
@ -35,9 +52,17 @@ if not "%2" == "cluster" (
set "JAVA_OPT=%JAVA_OPT% -XX:-UseLargePages"
)
if %FUNCTION_MODE% == "config" (
set "JAVA_OPT=%JAVA_OPT% -Dnacos.functionMode=config"
)
if %FUNCTION_MODE% == "naming" (
set "JAVA_OPT=%JAVA_OPT% -Dnacos.functionMode=naming"
)
set "JAVA_OPT=%JAVA_OPT% -Xbootclasspath/a:%BASE_DIR%\plugins\cmdb:%BASE_DIR%\plugins\mysql"
set "JAVA_OPT=%JAVA_OPT% -Dnacos.home=%BASE_DIR%"
set "JAVA_OPT=%JAVA_OPT% -jar %BASE_DIR%\target\nacos-server.jar"
set "JAVA_OPT=%JAVA_OPT% -Dloader.path=%BASE_DIR%/plugins/health -jar %BASE_DIR%\target\nacos-server.jar"
set "JAVA_OPT=%JAVA_OPT% --spring.config.location=%CUSTOM_SEARCH_LOCATIONS%"
set "JAVA_OPT=%JAVA_OPT% --logging.config=%BASE_DIR%/conf/nacos-logback.xml"

View File

@ -102,7 +102,7 @@ else
fi
JAVA_OPT="${JAVA_OPT} -Dnacos.home=${BASE_DIR}"
JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/target/nacos-server.jar"
JAVA_OPT="${JAVA_OPT} -Dloader.path=${BASE_DIR}/plugins/health -jar ${BASE_DIR}/target/nacos-server.jar"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
JAVA_OPT="${JAVA_OPT} --spring.config.location=${CUSTOM_SEARCH_LOCATIONS}"
JAVA_OPT="${JAVA_OPT} --logging.config=${BASE_DIR}/conf/nacos-logback.xml"

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -41,7 +41,7 @@ import static com.alibaba.nacos.core.utils.SystemUtils.*;
@Component("serverListManager")
public class ServerListManager {
public static final int STABLE_PERIOD = 60 * 1000;
private static final int STABLE_PERIOD = 60 * 1000;
@Autowired
private SwitchDomain switchDomain;
@ -74,7 +74,7 @@ public class ServerListManager {
GlobalExecutor.registerServerStatusReporter(new ServerStatusReporter(), 5000);
}
public List<Server> refreshServerList() {
private List<Server> refreshServerList() {
List<Server> result = new ArrayList<>();
@ -111,12 +111,12 @@ public class ServerListManager {
String ip;
int port;
if (serverList.get(0).contains(UtilsAndCommons.IP_PORT_SPLITER)) {
ip = serverList.get(i).split(UtilsAndCommons.IP_PORT_SPLITER)[0];
port = Integer.parseInt(serverList.get(i).split(UtilsAndCommons.IP_PORT_SPLITER)[1]);
String server = serverList.get(i);
if (server.contains(UtilsAndCommons.IP_PORT_SPLITER)) {
ip = server.split(UtilsAndCommons.IP_PORT_SPLITER)[0];
port = Integer.parseInt(server.split(UtilsAndCommons.IP_PORT_SPLITER)[1]);
} else {
ip = serverList.get(i);
ip = server;
port = RunningConfig.getServerPort();
}

View File

@ -58,13 +58,12 @@ public class CatalogController {
@RequestMapping(value = "/service")
public JSONObject serviceDetail(HttpServletRequest request) throws Exception {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID,
Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
com.alibaba.nacos.naming.core.Service detailedService = serviceManager.getService(namespaceId, serviceName);
Service detailedService = serviceManager.getService(namespaceId, serviceName);
if (detailedService == null) {
throw new NacosException(NacosException.NOT_FOUND, "serivce " + serviceName + " is not found!");
throw new NacosException(NacosException.NOT_FOUND, "service " + serviceName + " is not found!");
}
JSONObject detailView = new JSONObject();
@ -80,7 +79,7 @@ public class CatalogController {
List<Cluster> clusters = new ArrayList<>();
for (Cluster cluster : detailedService.getClusterMap().values()) {
for (com.alibaba.nacos.naming.core.Cluster cluster : detailedService.getClusterMap().values()) {
Cluster clusterView = new Cluster();
clusterView.setName(cluster.getName());
clusterView.setHealthChecker(cluster.getHealthChecker());
@ -88,7 +87,7 @@ public class CatalogController {
clusterView.setUseIPPort4Check(cluster.isUseIPPort4Check());
clusterView.setDefaultPort(cluster.getDefaultPort());
clusterView.setDefaultCheckPort(cluster.getDefaultCheckPort());
clusterView.setServiceName(serviceName);
clusterView.setServiceName(cluster.getService().getName());
clusters.add(clusterView);
}
@ -141,7 +140,7 @@ public class CatalogController {
}
@RequestMapping(value = "/services", method = RequestMethod.GET)
public Object listDetail(HttpServletRequest request) throws Exception {
public Object listDetail(HttpServletRequest request) {
boolean withInstances = Boolean.parseBoolean(WebUtils.optional(request, "withInstances", "true"));
@ -149,22 +148,24 @@ public class CatalogController {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID,
Constants.DEFAULT_NAMESPACE_ID);
List<ServiceDetailInfo> serviceDetailInfoList = new ArrayList<>();
int pageNo = Integer.parseInt(WebUtils.required(request, "pageNo"));
int pageSize = Integer.parseInt(WebUtils.required(request, "pageSize"));
String keyword = WebUtils.optional(request, "keyword", StringUtils.EMPTY);
serviceManager
.getServiceMap(namespaceId)
.forEach(
(serviceName, service) -> {
List<Service> serviceList = new ArrayList<>(8);
serviceManager.getPagedService(namespaceId, pageNo, pageSize, keyword, StringUtils.EMPTY, serviceList);
for (Service service : serviceList) {
ServiceDetailInfo serviceDetailInfo = new ServiceDetailInfo();
serviceDetailInfo.setServiceName(NamingUtils.getServiceName(serviceName));
serviceDetailInfo.setGroupName(NamingUtils.getGroupName(serviceName));
serviceDetailInfo.setServiceName(NamingUtils.getServiceName(service.getName()));
serviceDetailInfo.setGroupName(NamingUtils.getGroupName(service.getName()));
serviceDetailInfo.setMetadata(service.getMetadata());
Map<String, ClusterInfo> clusterInfoMap = getStringClusterInfoMap(service);
serviceDetailInfo.setClusterMap(clusterInfoMap);
serviceDetailInfoList.add(serviceDetailInfo);
});
}
return serviceDetailInfoList;
} else {
@ -248,7 +249,7 @@ public class CatalogController {
return ipAddressInfos;
}
private JSONObject serviceList(HttpServletRequest request) throws Exception {
private JSONObject serviceList(HttpServletRequest request) {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID,
Constants.DEFAULT_NAMESPACE_ID);

View File

@ -16,17 +16,23 @@
package com.alibaba.nacos.naming.controllers;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.CommonParams;
import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeerSet;
import com.alibaba.nacos.naming.core.Cluster;
import com.alibaba.nacos.naming.core.Service;
import com.alibaba.nacos.naming.core.ServiceManager;
import com.alibaba.nacos.naming.exception.NacosException;
import com.alibaba.nacos.naming.healthcheck.HealthCheckType;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.pojo.ClusterStateView;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
@ -36,6 +42,9 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author nkorange
@ -67,9 +76,7 @@ public class ClusterController {
Cluster cluster = service.getClusterMap().get(clusterName);
if (cluster == null) {
Loggers.SRV_LOG.warn("[UPDATE-CLUSTER] cluster not exist, will create it: {}, service: {}", clusterName, serviceName);
cluster = new Cluster();
cluster.setName(clusterName);
cluster.setService(service);
cluster = new Cluster(clusterName, service);
}
cluster.setDefCkport(NumberUtils.toInt(checkPort));
@ -77,23 +84,12 @@ public class ClusterController {
JSONObject healthCheckObj = JSON.parseObject(healthChecker);
AbstractHealthChecker abstractHealthChecker;
switch (healthCheckObj.getString("type")) {
case AbstractHealthChecker.Tcp.TYPE:
abstractHealthChecker = JSON.parseObject(healthChecker, AbstractHealthChecker.Tcp.class);
break;
case AbstractHealthChecker.Http.TYPE:
abstractHealthChecker = JSON.parseObject(healthChecker, AbstractHealthChecker.Http.class);
break;
case AbstractHealthChecker.Mysql.TYPE:
abstractHealthChecker = JSON.parseObject(healthChecker, AbstractHealthChecker.Mysql.class);
break;
case AbstractHealthChecker.None.TYPE:
abstractHealthChecker = JSON.parseObject(healthChecker, AbstractHealthChecker.None.class);
break;
default:
String type = healthCheckObj.getString("type");
Class<AbstractHealthChecker> healthCheckClass = HealthCheckType.ofHealthCheckerClass(type);
if(healthCheckClass == null){
throw new NacosException(NacosException.INVALID_PARAM, "unknown health check type:" + healthChecker);
}
abstractHealthChecker = JSON.parseObject(healthChecker, healthCheckClass);
cluster.setHealthChecker(abstractHealthChecker);
cluster.setMetadata(UtilsAndCommons.parseMetadata(metadata));
@ -107,4 +103,5 @@ public class ClusterController {
return "ok";
}
}

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.naming.controllers;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.CommonParams;
import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.boot.RunningConfig;
import com.alibaba.nacos.naming.core.DistroMapper;
@ -30,13 +31,19 @@ import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.push.PushService;
import com.alibaba.nacos.naming.web.CanDistro;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Health status related operation controller
@ -90,6 +97,7 @@ public class HealthController {
throw new IllegalArgumentException("Param 'healthy' is required.");
}
valid = BooleanUtils.toBoolean(healthyString);
Service service = serviceManager.getService(namespaceId, serviceName);
// Only health check "none" need update health status with api
@ -110,4 +118,20 @@ public class HealthController {
return "ok";
}
@ResponseBody
@RequestMapping(value = "checkers", method = RequestMethod.GET)
public ResponseEntity checkers() {
List<Class> classes = HealthCheckType.getLoadedHealthCheckerClasses();
Map<String, AbstractHealthChecker> checkerMap = new HashMap<>(8);
for (Class clazz : classes) {
try {
AbstractHealthChecker checker = (AbstractHealthChecker) clazz.newInstance();
checkerMap.put(checker.getType(), checker);
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
return ResponseEntity.ok(checkerMap);
}
}

View File

@ -235,10 +235,6 @@ public class InstanceController {
String clusterName = clientBeat.getCluster();
if (StringUtils.isBlank(clusterName)) {
clusterName = UtilsAndCommons.DEFAULT_CLUSTER_NAME;
}
if (Loggers.DEBUG_LOG.isDebugEnabled()) {
Loggers.DEBUG_LOG.debug("[CLIENT-BEAT] full arguments: beat: {}, serviceName: {}", clientBeat, serviceName);
}
@ -339,7 +335,15 @@ public class InstanceController {
cluster = WebUtils.optional(request, "cluster", UtilsAndCommons.DEFAULT_CLUSTER_NAME);
}
boolean healthy = BooleanUtils.toBoolean(WebUtils.optional(request, "healthy", "true"));
boolean enabled = BooleanUtils.toBoolean(WebUtils.optional(request, "enable", "true"));
String enabledString = WebUtils.optional(request, "enabled", StringUtils.EMPTY);
boolean enabled;
if (StringUtils.isBlank(enabledString)) {
enabled = BooleanUtils.toBoolean(WebUtils.optional(request, "enable", "true"));
} else {
enabled = BooleanUtils.toBoolean(enabledString);
}
boolean ephemeral = BooleanUtils.toBoolean(WebUtils.optional(request, "ephemeral",
String.valueOf(switchDomain.isDefaultInstanceEphemeral())));
@ -469,6 +473,12 @@ public class InstanceController {
}
for (Instance instance : ips) {
// remove disabled instance:
if (!instance.isEnabled()) {
continue;
}
JSONObject ipObj = new JSONObject();
ipObj.put("ip", instance.getIp());

View File

@ -24,6 +24,8 @@ import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.cluster.ServerListManager;
import com.alibaba.nacos.naming.cluster.ServerStatusManager;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftCore;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeerSet;
import com.alibaba.nacos.naming.core.DistroMapper;
import com.alibaba.nacos.naming.core.Service;
import com.alibaba.nacos.naming.core.ServiceManager;
@ -31,8 +33,10 @@ import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.naming.misc.SwitchEntry;
import com.alibaba.nacos.naming.misc.SwitchManager;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.pojo.ClusterStateView;
import com.alibaba.nacos.naming.push.PushService;
import com.alibaba.nacos.naming.web.NeedAuth;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
@ -42,6 +46,8 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@ -77,6 +83,9 @@ public class OperatorController {
@Autowired
private RaftCore raftCore;
@Autowired
private RaftPeerSet raftPeerSet;
@RequestMapping("/push/state")
public JSONObject pushState(HttpServletRequest request) {
@ -215,4 +224,41 @@ public class OperatorController {
serverListManager.onReceiveServerStatus(serverStatus);
return "ok";
}
@RequestMapping(value = "/cluster/states", method = RequestMethod.GET)
public Object listStates(HttpServletRequest request) {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID,
Constants.DEFAULT_NAMESPACE_ID);
JSONObject result = new JSONObject();
int page = Integer.parseInt(WebUtils.required(request, "pageNo"));
int pageSize = Integer.parseInt(WebUtils.required(request, "pageSize"));
String keyword = WebUtils.optional(request, "keyword", StringUtils.EMPTY);
String containedInstance = WebUtils.optional(request, "instance", StringUtils.EMPTY);
List<RaftPeer> raftPeerLists = new ArrayList<>();
int total = serviceManager.getPagedClusterState(namespaceId, page - 1, pageSize, keyword, containedInstance, raftPeerLists, raftPeerSet);
if (CollectionUtils.isEmpty(raftPeerLists)) {
result.put("clusterStateList", Collections.emptyList());
result.put("count", 0);
return result;
}
JSONArray clusterStateJsonArray = new JSONArray();
for(RaftPeer raftPeer: raftPeerLists) {
ClusterStateView clusterStateView = new ClusterStateView();
clusterStateView.setClusterTerm(raftPeer.term.intValue());
clusterStateView.setNodeIp(raftPeer.ip);
clusterStateView.setNodeState(raftPeer.state.name());
clusterStateView.setVoteFor(raftPeer.voteFor);
clusterStateView.setHeartbeatDueMs(raftPeer.heartbeatDueMs);
clusterStateView.setLeaderDueMs(raftPeer.leaderDueMs);
clusterStateJsonArray.add(clusterStateView);
}
result.put("clusterStateList", clusterStateJsonArray);
result.put("count", total);
return result;
}
}

View File

@ -20,15 +20,18 @@ import com.alibaba.nacos.naming.healthcheck.HealthCheckReactor;
import com.alibaba.nacos.naming.healthcheck.HealthCheckStatus;
import com.alibaba.nacos.naming.healthcheck.HealthCheckTask;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.springframework.util.Assert;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author nkorange
* @author jifengnan 2019-04-26
*/
public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implements Cloneable {
@ -62,8 +65,19 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
public Cluster() {
}
public Cluster(String clusterName) {
/**
* Create a cluster.
* <p>the cluster name cannot be null, and only the arabic numerals, letters and endashes are allowed.
*
* @param clusterName the cluster name
* @param service the service to which the current cluster belongs
* @throws IllegalArgumentException the service is null, or the cluster name is null, or the cluster name is illegal
* @author jifengnan 2019-04-26
* @since 1.0.1
*/
public Cluster(String clusterName, Service service) {
this.setName(clusterName);
this.service = service;
validate();
}
@ -113,19 +127,54 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
return service;
}
/**
* Replace the service for the current cluster.
* <p>Deprecated because the service shouldn't be replaced.
* (the service fields can be changed, but the service A shouldn't be replaced to service B).
* If the service of a cluster is required to replace, actually, a new cluster is required.
*
* @param service the new service
*/
@Deprecated
public void setService(Service service) {
this.service = service;
this.setServiceName(service.getName());
}
/**
* this method has been deprecated, the service name shouldn't be changed.
*
* @param serviceName the service name
* @author jifengnan 2019-04-26
* @since 1.0.1
*/
@Deprecated
@Override
public void setServiceName(String serviceName) {
super.setServiceName(serviceName);
}
/**
* Get the service name of the current cluster.
* <p>Note that the returned service name is not the name which set by {@link #setServiceName(String)},
* but the name of the service to which the current cluster belongs.
*
* @return the service name of the current cluster.
*/
@Override
public String getServiceName() {
if (service != null) {
return service.getName();
} else {
return super.getServiceName();
}
}
@Override
public Cluster clone() throws CloneNotSupportedException {
super.clone();
Cluster cluster = new Cluster();
Cluster cluster = new Cluster(this.getName(), service);
cluster.setHealthChecker(getHealthChecker().clone());
cluster.setService(getService());
cluster.persistentInstances = new HashSet<Instance>();
cluster.persistentInstances = new HashSet<>();
cluster.checkTask = null;
cluster.metadata = new HashMap<>(metadata);
return cluster;
@ -263,16 +312,28 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
@Override
public int hashCode() {
return Objects.hash(getName());
return new HashCodeBuilder(17, 37)
.append(getName())
.append(service)
.toHashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Cluster)) {
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
return getName().equals(((Cluster) obj).getName());
Cluster cluster = (Cluster) o;
return new EqualsBuilder()
.append(getName(), cluster.getName())
.append(service, cluster.service)
.isEquals();
}
public int getDefCkport() {
@ -330,7 +391,15 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
return persistentInstances.contains(ip) || ephemeralInstances.contains(ip);
}
/**
* validate the current cluster.
* <p>the cluster name cannot be null, and only the arabic numerals, letters and endashes are allowed.
*
* @throws IllegalArgumentException the service is null, or the cluster name is null, or the cluster name is illegal
*/
public void validate() {
Assert.notNull(getName(), "cluster name cannot be null");
Assert.notNull(service, "service cannot be null");
if (!getName().matches(CLUSTER_NAME_SYNTAX)) {
throw new IllegalArgumentException("cluster name can only have these characters: 0-9a-zA-Z-, current: " + getName());
}

View File

@ -51,6 +51,9 @@ public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance impleme
public static final Pattern IP_PATTERN
= Pattern.compile("(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}):?(\\d{1,5})?");
public static final Pattern ONLY_DIGIT_AND_DOT
= Pattern.compile("(\\d|\\.)+");
public static final String SPLITER = "_";
public Instance() {
@ -296,11 +299,12 @@ public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance impleme
}
public boolean validate() {
if (onlyContainsDigitAndDot()) {
Matcher matcher = IP_PATTERN.matcher(getIp() + ":" + getPort());
if (!matcher.matches()) {
return false;
}
}
if (getWeight() > MAX_WEIGHT_VALUE || getWeight() < MIN_WEIGHT_VALUE) {
return false;
@ -309,6 +313,11 @@ public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance impleme
return true;
}
private boolean onlyContainsDigitAndDot() {
Matcher matcher = ONLY_DIGIT_AND_DOT.matcher(getIp());
return matcher.matches();
}
@Override
public int compareTo(Object o) {
if (!(o instanceof Instance)) {

View File

@ -215,8 +215,7 @@ public class Service extends com.alibaba.nacos.api.naming.pojo.Service implement
if (!clusterMap.containsKey(instance.getClusterName())) {
Loggers.SRV_LOG.warn("cluster: {} not found, ip: {}, will create new cluster with default configuration.",
instance.getClusterName(), instance.toJSON());
Cluster cluster = new Cluster(instance.getClusterName());
cluster.setService(this);
Cluster cluster = new Cluster(instance.getClusterName(), this);
cluster.init();
getClusterMap().put(instance.getClusterName(), cluster);
}

View File

@ -20,12 +20,15 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.naming.cluster.ServerListManager;
import com.alibaba.nacos.naming.cluster.servers.Server;
import com.alibaba.nacos.naming.consistency.ConsistencyService;
import com.alibaba.nacos.naming.consistency.Datum;
import com.alibaba.nacos.naming.consistency.KeyBuilder;
import com.alibaba.nacos.naming.consistency.RecordListener;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeerSet;
import com.alibaba.nacos.naming.misc.*;
import com.alibaba.nacos.naming.push.PushService;
import org.apache.commons.lang3.ArrayUtils;
@ -226,6 +229,41 @@ public class ServiceManager implements RecordListener<Service> {
}
}
public int getPagedClusterState(String namespaceId, int startPage, int pageSize, String keyword, String containedInstance, List<RaftPeer> raftPeerList, RaftPeerSet raftPeerSet) {
List<RaftPeer> matchList = new ArrayList<>(raftPeerSet.allPeers());
List<RaftPeer> tempList = new ArrayList<>();
if(StringUtils.isNotBlank(keyword)) {
for(RaftPeer raftPeer: matchList) {
String ip = raftPeer.ip.split(":")[0];
if(keyword.equals(ip)) {
tempList.add(raftPeer);
}
}
matchList = tempList;
}
if (pageSize >= matchList.size()) {
raftPeerList.addAll(matchList);
return matchList.size();
}
for (int i = 0; i < matchList.size(); i++) {
if (i < startPage * pageSize) {
continue;
}
raftPeerList.add(matchList.get(i));
if (raftPeerList.size() >= pageSize) {
break;
}
}
return matchList.size();
}
public void updatedHealthStatus(String namespaceId, String serviceName, String serverIP) {
Message msg = synchronizer.get(serverIP, UtilsAndCommons.assembleFullServiceName(namespaceId, serviceName));
JSONObject serviceJson = JSON.parseObject(msg.getData());
@ -357,7 +395,7 @@ public class ServiceManager implements RecordListener<Service> {
service = new Service();
service.setName(serviceName);
service.setNamespaceId(namespaceId);
service.setGroupName(Constants.DEFAULT_GROUP);
service.setGroupName(NamingUtils.getGroupName(serviceName));
// now validate the service. if failed, exception will be thrown
service.setLastModifiedMillis(System.currentTimeMillis());
service.recalculateChecksum();
@ -485,8 +523,7 @@ public class ServiceManager implements RecordListener<Service> {
for (Instance instance : ips) {
if (!service.getClusterMap().containsKey(instance.getClusterName())) {
Cluster cluster = new Cluster(instance.getClusterName());
cluster.setService(service);
Cluster cluster = new Cluster(instance.getClusterName(), service);
cluster.init();
service.getClusterMap().put(instance.getClusterName(), cluster);
Loggers.SRV_LOG.warn("cluster: {} not found, ip: {}, will create new cluster with default configuration.",

View File

@ -15,48 +15,45 @@
*/
package com.alibaba.nacos.naming.healthcheck;
import com.alibaba.nacos.naming.healthcheck.extend.HealthCheckExtendProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author nacos
*/
@Component("healthCheckDelegate")
public class HealthCheckProcessorDelegate implements HealthCheckProcessor {
@Autowired
private HttpHealthCheckProcessor httpProcessor;
private Map<String, HealthCheckProcessor> healthCheckProcessorMap
= new HashMap<>();
public HealthCheckProcessorDelegate(HealthCheckExtendProvider provider) {
provider.init();
}
@Autowired
private TcpSuperSenseProcessor tcpProcessor;
@Autowired
private MysqlHealthCheckProcessor mysqlProcessor;
@Autowired
private NoneHealthCheckProcessor noneProcessor;
public void addProcessor(Collection<HealthCheckProcessor> processors){
healthCheckProcessorMap.putAll(processors.stream()
.filter(processor -> processor.getType() != null)
.collect(Collectors.toMap(HealthCheckProcessor::getType, processor -> processor)));
}
@Override
public void process(HealthCheckTask task) {
String type = task.getCluster().getHealthChecker().getType();
if (type.equals(httpProcessor.getType())) {
httpProcessor.process(task);
return;
HealthCheckProcessor processor = healthCheckProcessorMap.get(type);
if(processor == null){
processor = healthCheckProcessorMap.get("none");
}
if (type.equals(tcpProcessor.getType())) {
tcpProcessor.process(task);
return;
}
if (type.equals(mysqlProcessor.getType())) {
mysqlProcessor.process(task);
return;
}
noneProcessor.process(task);
processor.process(task);
}
@Override

View File

@ -15,6 +15,13 @@
*/
package com.alibaba.nacos.naming.healthcheck;
import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author nkorange
*/
@ -22,17 +29,54 @@ public enum HealthCheckType {
/**
* TCP type
*/
TCP,
TCP("tcp", AbstractHealthChecker.Tcp.class),
/**
* HTTP type
*/
HTTP,
HTTP("http", AbstractHealthChecker.Http.class),
/**
* MySQL type
*/
MYSQL,
MYSQL("mysql", AbstractHealthChecker.Mysql.class),
/**
* No check
*/
NONE
NONE("none", AbstractHealthChecker.None.class);
private String name;
private Class healthCheckerClass;
private static Map<String, Class> EXTEND =
new ConcurrentHashMap<>();
HealthCheckType(String name, Class healthCheckerClass) {
this.name = name;
this.healthCheckerClass = healthCheckerClass;
}
public static void registerHealthChecker(String type, Class healthCheckerClass){
EXTEND.putIfAbsent(type, healthCheckerClass);
}
public static Class ofHealthCheckerClass(String type){
HealthCheckType enumType;
try {
enumType = valueOf(type);
}catch (Exception e){
return EXTEND.get(type);
}
return enumType.healthCheckerClass;
}
public static List<Class> getLoadedHealthCheckerClasses(){
List<Class> all = new ArrayList<>();
for(HealthCheckType type : values()){
all.add(type.healthCheckerClass);
}
for(Map.Entry<String, Class> entry : EXTEND.entrySet()){
all.add(entry.getValue());
}
return all;
}
}

View File

@ -42,25 +42,16 @@ public class JsonAdapter implements ObjectDeserializer, ObjectSerializer {
return INSTANCE;
}
@SuppressWarnings("unchecked")
@Override
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
JSONObject jsonObj = (JSONObject) parser.parse();
String checkType = jsonObj.getString("type");
if (StringUtils.equals(checkType, AbstractHealthChecker.Http.TYPE)) {
return (T) JSON.parseObject(jsonObj.toJSONString(), AbstractHealthChecker.Http.class);
}
Class target = HealthCheckType.ofHealthCheckerClass(checkType);
if (StringUtils.equals(checkType, AbstractHealthChecker.Tcp.TYPE)) {
return (T) JSON.parseObject(jsonObj.toJSONString(), AbstractHealthChecker.Tcp.class);
}
if (StringUtils.equals(checkType, AbstractHealthChecker.None.TYPE)) {
return (T) JSON.parseObject(jsonObj.toJSONString(), AbstractHealthChecker.None.class);
}
if (StringUtils.equals(checkType, AbstractHealthChecker.Mysql.TYPE)) {
return (T) JSON.parseObject(jsonObj.toJSONString(), AbstractHealthChecker.Mysql.class);
if(target != null){
return (T) JSON.parseObject(jsonObj.toJSONString(), target);
}
return null;
@ -83,21 +74,6 @@ public class JsonAdapter implements ObjectDeserializer, ObjectSerializer {
writer.writeFieldValue(',', "type", config.getType());
if (StringUtils.equals(config.getType(), HealthCheckType.HTTP.name())) {
AbstractHealthChecker.Http httpCheckConfig = (AbstractHealthChecker.Http) config;
writer.writeFieldValue(',', "path", httpCheckConfig.getPath());
writer.writeFieldValue(',', "headers", httpCheckConfig.getHeaders());
}
if (StringUtils.equals(config.getType(), HealthCheckType.TCP.name())) {
// nothing sepcial to handle
}
if (StringUtils.equals(config.getType(), HealthCheckType.MYSQL.name())) {
AbstractHealthChecker.Mysql mysqlCheckConfig = (AbstractHealthChecker.Mysql) config;
writer.writeFieldValue(',', "user", mysqlCheckConfig.getUser());
writer.writeFieldValue(',', "pwd", mysqlCheckConfig.getPwd());
writer.writeFieldValue(',', "cmd", mysqlCheckConfig.getCmd());
}
config.jsonAdapterCallback(writer);
}
}

View File

@ -0,0 +1,109 @@
/*
* 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.naming.healthcheck.extend;
import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
import com.alibaba.nacos.naming.healthcheck.HealthCheckProcessor;
import com.alibaba.nacos.naming.healthcheck.HealthCheckType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.SingletonBeanRegistry;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.Set;
/**
* @author XCXCXCXCX
*/
@Component
public class HealthCheckExtendProvider implements BeanFactoryAware {
private static final Logger LOGGER = LoggerFactory.getLogger(HealthCheckExtendProvider.class);
private ServiceLoader<HealthCheckProcessor> processorLoader
= ServiceLoader.load(HealthCheckProcessor.class);
private ServiceLoader<AbstractHealthChecker> checkerLoader
= ServiceLoader.load(AbstractHealthChecker.class);
private SingletonBeanRegistry registry;
public void init(){
loadExtend();
}
private void loadExtend() {
Iterator<HealthCheckProcessor> processorIt = processorLoader.iterator();
Iterator<AbstractHealthChecker> healthCheckerIt = checkerLoader.iterator();
Set<String> origin = new HashSet<>();
for(HealthCheckType type : HealthCheckType.values()){
origin.add(type.name());
}
Set<String> processorType = new HashSet<>();
Set<String> healthCheckerType = new HashSet<>();
processorType.addAll(origin);
healthCheckerType.addAll(origin);
while(processorIt.hasNext()){
HealthCheckProcessor processor = processorIt.next();
String type = processor.getType();
if(processorType.contains(type)){
throw new RuntimeException("More than one processor of the same type was found : [type=\"" + type + "\"]");
}
processorType.add(type);
registry.registerSingleton(lowerFirstChar(processor.getClass().getSimpleName()), processor);
}
while(healthCheckerIt.hasNext()){
AbstractHealthChecker checker = healthCheckerIt.next();
String type = checker.getType();
if(healthCheckerType.contains(type)){
throw new RuntimeException("More than one healthChecker of the same type was found : [type=\"" + type + "\"]");
}
healthCheckerType.add(type);
HealthCheckType.registerHealthChecker(checker.getType(), checker.getClass());
}
if(!processorType.equals(healthCheckerType)){
throw new RuntimeException("An unmatched processor and healthChecker are detected in the extension package.");
}
if(processorType.size() > origin.size()){
processorType.removeAll(origin);
LOGGER.debug("init health plugin : types=" + processorType);
}
}
private String lowerFirstChar(String simpleName) {
if(StringUtils.isBlank(simpleName)){
throw new IllegalArgumentException("can't find extend processor class name");
}
return String.valueOf(simpleName.charAt(0)).toLowerCase() + simpleName.substring(1);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if(beanFactory instanceof SingletonBeanRegistry){
this.registry = (SingletonBeanRegistry) beanFactory;
}
}
}

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.naming.misc;
import com.alibaba.nacos.naming.boot.RunningConfig;
import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.Response;
import org.springframework.util.StringUtils;
import java.net.HttpURLConnection;
import java.util.HashMap;
@ -31,7 +32,7 @@ import java.util.Map;
public class ServerStatusSynchronizer implements Synchronizer {
@Override
public void send(final String serverIP, Message msg) {
if (serverIP == null) {
if (StringUtils.isEmpty(serverIP)) {
return;
}

View File

@ -36,6 +36,7 @@ import static com.alibaba.nacos.core.utils.SystemUtils.NACOS_HOME;
/**
* @author nacos
* @author jifengnan
*/
public class UtilsAndCommons {
@ -69,7 +70,7 @@ public class UtilsAndCommons {
public static final String NACOS_SERVER_HEADER = "Nacos-Server";
public static final String NACOS_VERSION = "1.0.0";
public static final String NACOS_VERSION = "1.0.1";
public static final String SUPER_TOKEN = "xy";
@ -239,23 +240,25 @@ public class UtilsAndCommons {
}
/**
* 根据指定的字符串计算出一个0{@code upperLimit}不含之间的数字本方法会试图让不同的字符串较均匀的分布在0到{@code upperLimit}之间
* (Provide a number between 0(include) and {@code upperLimit}(exclude) for the given {@code string}, the number will be nearly uniform distribution.)
* Provide a number between 0(inclusive) and {@code upperLimit}(exclusive) for the given {@code string},
* the number will be nearly uniform distribution.
* <p>
* <p>
* 举个例子假设有N个提供相同服务的服务器地址被存在一个数组中为了实现负载均衡可以根据调用者的名字决定使用哪个服务器
* (e.g. Assume there's an array which contains some IP of the servers provide the same service, the caller name can be used to choose the server to achieve load balance.)
*
* e.g. Assume there's an array which contains some IP of the servers provide the same service,
* the caller name can be used to choose the server to achieve load balance.
* <blockquote><pre>
* String[] serverIps = new String[10];
* int index = shakeUp("callerName", serverIps.length);
* String targetServerIp = serverIps[index];
* </pre></blockquote>
*
* @param string 字符串如果为null会固定返回0 (a string. the number 0 will be returned if it's null)
* @param upperLimit 返回值的上限必须为正整数(>0) (the upper limit of the returned number, must be a positive integer, which means > 0)
* @return 0到upperLimit不含之间的一个数字 (a number between 0(include) and upperLimit(exclude))
* @param string a string. the number 0 will be returned if it's null
* @param upperLimit the upper limit of the returned number, must be a positive integer, which means > 0
* @return a number between 0(inclusive) and upperLimit(exclusive)
* @throws IllegalArgumentException if the upper limit equals or less than 0
* @since 1.0.0
* @author jifengnan
*/
public static int shakeUp(String string, int upperLimit) {
if (upperLimit < 1) {

View File

@ -0,0 +1,94 @@
/*
* 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.naming.pojo;
import com.alibaba.fastjson.JSON;
/**
* @author: universefeeler
* @Date: 2019/05/19 15:51
* @Description:
*/
public class ClusterStateView{
private String nodeIp;
private String nodeState;
private long clusterTerm;
private long leaderDueMs;
private String voteFor;
private long heartbeatDueMs;
public long getLeaderDueMs() {
return leaderDueMs;
}
public void setLeaderDueMs(long leaderDueMs) {
this.leaderDueMs = leaderDueMs;
}
public long getHeartbeatDueMs() {
return heartbeatDueMs;
}
public void setHeartbeatDueMs(long heartbeatDueMs) {
this.heartbeatDueMs = heartbeatDueMs;
}
public String getVoteFor() {
return voteFor;
}
public void setVoteFor(String voteFor) {
this.voteFor = voteFor;
}
public String getNodeIp() {
return nodeIp;
}
public void setNodeIp(String nodeIp) {
this.nodeIp = nodeIp;
}
public String getNodeState() {
return nodeState;
}
public void setNodeState(String nodeState) {
this.nodeState = nodeState;
}
public long getClusterTerm() {
return clusterTerm;
}
public void setClusterTerm(long clusterTerm) {
this.clusterTerm = clusterTerm;
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -93,13 +93,9 @@ public class PushService {
try {
udpSocket = new DatagramSocket();
Receiver receiver;
Receiver receiver = new Receiver();
Thread inThread;
receiver = new Receiver();
inThread = new Thread(receiver);
Thread inThread = new Thread(receiver);
inThread.setDaemon(true);
inThread.setName("com.alibaba.nacos.naming.push.receiver");
inThread.start();

View File

@ -15,8 +15,6 @@
*/
package com.alibaba.nacos.naming.selector;
import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.api.selector.SelectorType;
import com.alibaba.nacos.naming.core.Instance;
import java.util.List;
@ -27,11 +25,7 @@ import java.util.List;
* @author nkorange
* @since 0.7.0
*/
public class NoneSelector extends AbstractSelector implements Selector {
public NoneSelector() {
this.setType(SelectorType.none.name());
}
public class NoneSelector extends com.alibaba.nacos.api.selector.NoneSelector implements Selector {
@Override
public List<Instance> select(String consumer, List<Instance> providers) {

View File

@ -15,15 +15,26 @@
*/
package com.alibaba.nacos.naming;
import com.alibaba.nacos.naming.boot.SpringContext;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftCore;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeerSet;
import com.alibaba.nacos.naming.core.DistroMapper;
import com.alibaba.nacos.naming.core.ServiceManager;
import com.alibaba.nacos.naming.healthcheck.HealthCheckProcessorDelegate;
import com.alibaba.nacos.naming.misc.NetUtils;
import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.naming.push.PushService;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.ExpectedException;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.springframework.context.ApplicationContext;
import static org.mockito.Mockito.doReturn;
/**
* @author nkorange
@ -39,6 +50,9 @@ public class BaseTest {
@Mock
public RaftCore raftCore;
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Before
public void before() {
MockitoAnnotations.initMocks(this);
@ -49,5 +63,27 @@ public class BaseTest {
Mockito.when(peerSet.local()).thenReturn(peer);
Mockito.when(peerSet.getLeader()).thenReturn(peer);
Mockito.when(peerSet.isLeader(NetUtils.localServer())).thenReturn(true);
new SpringContext().setApplicationContext(context);
doReturn(distroMapper).when(context).getBean(DistroMapper.class);
doReturn(switchDomain).when(context).getBean(SwitchDomain.class);
doReturn(delegate).when(context).getBean(HealthCheckProcessorDelegate.class);
doReturn(pushService).when(context).getBean(PushService.class);
}
protected static final String TEST_CLUSTER_NAME = "test-cluster";
protected static final String TEST_SERVICE_NAME = "test-service";
protected static final String TEST_GROUP_NAME = "test-group-name";
protected static final String TEST_NAMESPACE = "test-namespace";
@Spy
protected ApplicationContext context;
@Mock
protected DistroMapper distroMapper;
@Spy
protected SwitchDomain switchDomain;
@Mock
protected HealthCheckProcessorDelegate delegate;
@Mock
protected PushService pushService;
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.naming.consistency.ephemeral.distro;
import com.alibaba.nacos.naming.misc.GlobalConfig;
import com.alibaba.nacos.naming.misc.Loggers;
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.util.ReflectionTestUtils;

Some files were not shown because too many files have changed in this diff Show More