commit
3af86ae6a1
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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 = "@@";
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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";
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -45,5 +45,8 @@
|
||||
additivity="false">
|
||||
<AppenderRef ref="NAMING_LOG_FILE"/>
|
||||
</Logger>
|
||||
<Root level="INFO">
|
||||
<AppenderRef ref="CONFIG_LOG_FILE"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
@ -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, ","));
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -406,6 +406,7 @@ public class LongPollingService extends AbstractEventListener {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}, timeoutTime, TimeUnit.MILLISECONDS);
|
||||
|
||||
allSubs.add(this);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
0
console/src/main/resources/nacos-version.txt
Executable file → Normal file
@ -38,6 +38,9 @@ module.exports = {
|
||||
components: resolve('src/components'),
|
||||
},
|
||||
},
|
||||
node: {
|
||||
fs: 'empty'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
0
console/src/main/resources/static/console-fe/public/js/vs/editor/contrib/suggest/browser/media/String_16x.svg
Executable file → Normal file
0
console/src/main/resources/static/console-fe/public/js/vs/editor/contrib/suggest/browser/media/String_16x.svg
Executable file → Normal file
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
0
console/src/main/resources/static/console-fe/public/js/vs/editor/contrib/suggest/browser/media/String_inverse_16x.svg
Executable file → Normal file
0
console/src/main/resources/static/console-fe/public/js/vs/editor/contrib/suggest/browser/media/String_inverse_16x.svg
Executable file → Normal file
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
@ -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;
|
@ -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(
|
||||
|
@ -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() {
|
||||
|
@ -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',
|
||||
|
@ -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: '检查类型',
|
||||
|
@ -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',
|
||||
|
@ -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;
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
@ -468,7 +468,7 @@ class NewConfig extends React.Component {
|
||||
message: locale.moreAdvanced,
|
||||
},
|
||||
{
|
||||
max: 127,
|
||||
maxLength: 127,
|
||||
message: locale.groupNotEmpty,
|
||||
},
|
||||
{ validator: this.validateChart.bind(this) },
|
||||
|
@ -67,7 +67,7 @@ class EditInstanceDialog extends React.Component {
|
||||
port,
|
||||
ephemeral,
|
||||
weight,
|
||||
enable: enabled,
|
||||
enabled,
|
||||
metadata: replaceEnter(METADATA_SEPARATOR)(metadataText),
|
||||
},
|
||||
dataType: 'text',
|
||||
|
@ -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',
|
||||
|
@ -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>
|
||||
|
@ -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()}
|
||||
|
@ -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
@ -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>
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
BIN
distribution/plugins/health/nacos-health-plugin-example-1.0.jar
Normal file
BIN
distribution/plugins/health/nacos-health-plugin-example-1.0.jar
Normal file
Binary file not shown.
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.",
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user