Merge remote-tracking branch 'origin/develop' into asoc2022_issue#8458

# Conflicts:
#	client/src/test/java/com/alibaba/nacos/client/naming/remote/gprc/redo/NamingGrpcRedoServiceTest.java
#	common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java
This commit is contained in:
Daydreamer-ia 2023-09-24 15:18:17 +08:00
commit fc8549dc8f
430 changed files with 12302 additions and 5710 deletions

View File

@ -171,9 +171,9 @@ jobs:
ask-config: "${{ secrets.ASK_CONFIG_VIRGINA }}"
test-version: "${{ matrix.version }}"
test-code-git: "https://github.com/nacos-group/nacos-e2e.git"
test-code-branch: "master"
test-code-branch: "main"
test-code-path: "java/nacos-2X"
test-cmd: 'mvn clean test -B -Dnacos.client.version=2.2.3'
test-cmd: 'mvn clean test -B'
job-id: ${{ strategy.job-index }}
- name: Publish Test Report
uses: mikepenz/action-junit-report@v3

View File

@ -184,7 +184,7 @@ jobs:
test-code-git: "https://github.com/nacos-group/nacos-e2e.git"
test-code-branch: "main"
test-code-path: "java/nacos-2X"
test-cmd: 'mvn clean test -B -Dnacos.client.version=2.2.3'
test-cmd: 'mvn clean test -B'
job-id: ${{ strategy.job-index }}
- name: Publish Test Report
uses: mikepenz/action-junit-report@v3

View File

@ -82,7 +82,7 @@ For more details, see [quick-start.](https://nacos.io/en-us/docs/quick-start.htm
## Documentation
You can view the full documentation from the [Nacos website](https://nacos.io/en-us/docs/what-is-nacos.html).
You can view the full documentation from the [Nacos website](https://nacos.io/en-us/docs/v2/what-is-nacos.html).
You can also read this online eBook from the [NACOS ARCHITECTURE & PRINCIPLES](https://www.yuque.com/nacos/ebook/kbyo6n).

View File

@ -77,6 +77,10 @@ public class PropertyKeyConst {
public static final String NAMING_ASYNC_QUERY_SUBSCRIBE_SERVICE = "namingAsyncQuerySubscribeService";
public static final String REDO_DELAY_TIME = "redoDelayTime";
public static final String REDO_DELAY_THREAD_COUNT = "redoDelayThreadCount";
/**
* Get the key value of some variable value from the system property.
*/

View File

@ -138,7 +138,7 @@ public @interface NacosProperties {
String SERVER_ADDR_PLACEHOLDER = "${" + PREFIX + SERVER_ADDR + ":}";
/**
* The placeholder of endpoint, the value is ${nacos.context-path:}".
* The placeholder of endpoint, the value is ${nacos.context-path:}.
*/
String CONTEXT_PATH_PLACEHOLDER = "${" + PREFIX + CONTEXT_PATH + ":}";

View File

@ -19,7 +19,7 @@ package com.alibaba.nacos.api.cmdb.pojo;
import java.util.Set;
/**
* CMDB lable.
* CMDB label.
*
* @author nkorange
* @since 0.7.0

View File

@ -17,7 +17,7 @@
package com.alibaba.nacos.api.cmdb.pojo;
/**
* CMDB preserverd entity type.
* CMDB preserved entity type.
*
* @author nkorange
* @since 0.7.0

View File

@ -86,9 +86,9 @@ public class Constants {
public static final String USERNAME = "username";
public static final String TOKEN_REFRESH_WINDOW = "tokenRefreshWindow";
public static final Integer SDK_GRPC_PORT_DEFAULT_OFFSET = 1000;
public static final Integer CLUSTER_GRPC_PORT_DEFAULT_OFFSET = 1001;
/**
@ -216,13 +216,20 @@ public class Constants {
public static final String CLUSTER_NAME_PATTERN_STRING = "^[0-9a-zA-Z-]+$";
/**
* millisecond.
*/
public static final long DEFAULT_REDO_DELAY_TIME = 3000L;
public static final int DEFAULT_REDO_THREAD_COUNT = 1;
/**
* The constants in config directory.
*/
public static class Config {
public static final String CONFIG_MODULE = "config";
public static final String NOTIFY_HEADER = "notify";
}

View File

@ -58,6 +58,11 @@ public enum ConfigType {
*/
YAML("yaml"),
/**
* config type is "toml".
*/
TOML("toml"),
/**
* not a real type.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2023 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.
@ -21,11 +21,42 @@ import com.alibaba.nacos.api.remote.request.Request;
/**
* abstract request of config module request,all config module request should extends this class.
*
* @author liuzunfei
* @version $Id: ConfigCommonRequest.java, v 0.1 2020年07月13日 9:05 PM liuzunfei Exp $
*/
public abstract class AbstractConfigRequest extends Request {
private String dataId;
private String group;
private String tenant;
public String getDataId() {
return dataId;
}
public void setDataId(String dataId) {
this.dataId = dataId;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getTenant() {
return tenant;
}
public void setTenant(String tenant) {
this.tenant = tenant;
}
@Override
public String getModule() {
return Constants.Config.CONFIG_MODULE;

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2020 Alibaba Group Holding Ltd.
* Copyright 1999-2023 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2020 Alibaba Group Holding Ltd.
* Copyright 1999-2023 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.
@ -27,12 +27,6 @@ import java.util.Map;
*/
public class ConfigPublishRequest extends AbstractConfigRequest {
String dataId;
String group;
String tenant;
String content;
String casMd5;
@ -43,6 +37,13 @@ public class ConfigPublishRequest extends AbstractConfigRequest {
}
public ConfigPublishRequest(String dataId, String group, String tenant, String content) {
this.content = content;
super.setGroup(group);
super.setTenant(tenant);
super.setDataId(dataId);
}
/**
* get additional param.
*
@ -66,49 +67,6 @@ public class ConfigPublishRequest extends AbstractConfigRequest {
additionMap.put(key, value);
}
public ConfigPublishRequest(String dataId, String group, String tenant, String content) {
this.content = content;
this.dataId = dataId;
this.group = group;
this.tenant = tenant;
}
/**
* Getter method for property <tt>dataId</tt>.
*
* @return property value of dataId
*/
public String getDataId() {
return dataId;
}
/**
* Setter method for property <tt>dataId</tt>.
*
* @param dataId value to be assigned to property dataId
*/
public void setDataId(String dataId) {
this.dataId = dataId;
}
/**
* Getter method for property <tt>group</tt>.
*
* @return property value of group
*/
public String getGroup() {
return group;
}
/**
* Setter method for property <tt>group</tt>.
*
* @param group value to be assigned to property group
*/
public void setGroup(String group) {
this.group = group;
}
/**
* Getter method for property <tt>content</tt>.
*
@ -163,21 +121,4 @@ public class ConfigPublishRequest extends AbstractConfigRequest {
this.additionMap = additionMap;
}
/**
* Getter method for property <tt>tenant</tt>.
*
* @return property value of tenant
*/
public String getTenant() {
return tenant;
}
/**
* Setter method for property <tt>tenant</tt>.
*
* @param tenant value to be assigned to property tenant
*/
public void setTenant(String tenant) {
this.tenant = tenant;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2023 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.
@ -26,12 +26,6 @@ import com.alibaba.nacos.api.common.Constants;
*/
public class ConfigQueryRequest extends AbstractConfigRequest {
private String dataId;
private String group;
private String tenant;
private String tag;
/**
@ -50,60 +44,6 @@ public class ConfigQueryRequest extends AbstractConfigRequest {
return request;
}
/**
* Getter method for property <tt>dataId</tt>.
*
* @return property value of dataId
*/
public String getDataId() {
return dataId;
}
/**
* Setter method for property <tt>dataId</tt>.
*
* @param dataId value to be assigned to property dataId
*/
public void setDataId(String dataId) {
this.dataId = dataId;
}
/**
* Getter method for property <tt>group</tt>.
*
* @return property value of group
*/
public String getGroup() {
return group;
}
/**
* Setter method for property <tt>group</tt>.
*
* @param group value to be assigned to property group
*/
public void setGroup(String group) {
this.group = group;
}
/**
* Getter method for property <tt>tenant</tt>.
*
* @return property value of tenant
*/
public String getTenant() {
return tenant;
}
/**
* Setter method for property <tt>tenant</tt>.
*
* @param tenant value to be assigned to property tenant
*/
public void setTenant(String tenant) {
this.tenant = tenant;
}
/**
* Getter method for property <tt>tag</tt>.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2020 Alibaba Group Holding Ltd.
* Copyright 1999-2023 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.
@ -24,12 +24,6 @@ package com.alibaba.nacos.api.config.remote.request;
*/
public class ConfigRemoveRequest extends AbstractConfigRequest {
String dataId;
String group;
String tenant;
String tag;
public ConfigRemoveRequest() {
@ -37,19 +31,10 @@ public class ConfigRemoveRequest extends AbstractConfigRequest {
}
public ConfigRemoveRequest(String dataId, String group, String tenant, String tag) {
this.dataId = dataId;
this.group = group;
super.setDataId(dataId);
super.setGroup(group);
super.setTenant(tenant);
this.tag = tag;
this.tenant = tenant;
}
/**
* Getter method for property <tt>dataId</tt>.
*
* @return property value of dataId
*/
public String getDataId() {
return dataId;
}
/**
@ -70,48 +55,4 @@ public class ConfigRemoveRequest extends AbstractConfigRequest {
this.tag = tag;
}
/**
* Setter method for property <tt>dataId</tt>.
*
* @param dataId value to be assigned to property dataId
*/
public void setDataId(String dataId) {
this.dataId = dataId;
}
/**
* Getter method for property <tt>group</tt>.
*
* @return property value of group
*/
public String getGroup() {
return group;
}
/**
* Setter method for property <tt>group</tt>.
*
* @param group value to be assigned to property group
*/
public void setGroup(String group) {
this.group = group;
}
/**
* Getter method for property <tt>tenant</tt>.
*
* @return property value of tenant
*/
public String getTenant() {
return tenant;
}
/**
* Setter method for property <tt>tenant</tt>.
*
* @param tenant value to be assigned to property tenant
*/
public void setTenant(String tenant) {
this.tenant = tenant;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2020 Alibaba Group Holding Ltd.
* Copyright 1999-2023 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.
@ -26,12 +26,6 @@ import com.alibaba.nacos.api.config.remote.request.AbstractConfigRequest;
*/
public class ConfigChangeClusterSyncRequest extends AbstractConfigRequest {
String dataId;
String group;
String tenant;
String tag;
long lastModified;
@ -56,60 +50,6 @@ public class ConfigChangeClusterSyncRequest extends AbstractConfigRequest {
isBatch = batch;
}
/**
* Getter method for property <tt>dataId</tt>.
*
* @return property value of dataId
*/
public String getDataId() {
return dataId;
}
/**
* Setter method for property <tt>dataId</tt>.
*
* @param dataId value to be assigned to property dataId
*/
public void setDataId(String dataId) {
this.dataId = dataId;
}
/**
* Getter method for property <tt>group</tt>.
*
* @return property value of group
*/
public String getGroup() {
return group;
}
/**
* Setter method for property <tt>group</tt>.
*
* @param group value to be assigned to property group
*/
public void setGroup(String group) {
this.group = group;
}
/**
* Getter method for property <tt>tenant</tt>.
*
* @return property value of tenant
*/
public String getTenant() {
return tenant;
}
/**
* Setter method for property <tt>tenant</tt>.
*
* @param tenant value to be assigned to property tenant
*/
public void setTenant(String tenant) {
this.tenant = tenant;
}
/**
* Getter method for property <tt>tag</tt>.
*

View File

@ -181,7 +181,7 @@ public class NacosException extends Exception {
public static final int RESOURCE_NOT_FOUND = -404;
/**
* http client error code, ome exceptions that occurred when the use the Nacos RestTemplate and Nacos
* http client error code, ome exceptions that occurred when there use the Nacos RestTemplate and Nacos
* AsyncRestTemplate.
*/
public static final int HTTP_CLIENT_ERROR_CODE = -500;

View File

@ -260,7 +260,7 @@ private static final long serialVersionUID = 0L;
if (key == null) { throw new NullPointerException(); }
java.util.Map<String, String> map =
internalGetHeaders().getMap();
return map.containsKey(key) ? map.get(key) : defaultValue;
return map.getOrDefault(key, defaultValue);
}
/**
* <code>map&lt;string, string&gt; headers = 7;</code>
@ -797,7 +797,7 @@ private static final long serialVersionUID = 0L;
}
private com.google.protobuf.MapField<String, String>
internalGetMutableHeaders() {
onChanged();;
onChanged();
if (headers_ == null) {
headers_ = com.google.protobuf.MapField.newMapField(
HeadersDefaultEntryHolder.defaultEntry);

View File

@ -17,21 +17,14 @@
package com.alibaba.nacos.api.grpc.auto;
import static io.grpc.MethodDescriptor.generateFullMethodName;
import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
import static io.grpc.stub.ClientCalls.asyncUnaryCall;
import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
import static io.grpc.stub.ClientCalls.blockingUnaryCall;
import static io.grpc.stub.ClientCalls.futureUnaryCall;
import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
import static io.grpc.stub.ServerCalls.asyncUnaryCall;
import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
/**
*
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler (version 1.14.0)",

View File

@ -21,7 +21,7 @@ import com.alibaba.nacos.api.common.ResponseCode;
/**
* Business response code of naming module
*
* <p>Every code stays between 20001 to 29999.
* <p>Every code stays between 20001 and 29999.
*
* @author nkorange
* @author 1.2.0

View File

@ -31,12 +31,15 @@ public class RpcScheduledExecutor extends ScheduledThreadPoolExecutor {
public static final RpcScheduledExecutor TIMEOUT_SCHEDULER = new RpcScheduledExecutor(1,
"com.alibaba.nacos.remote.TimerScheduler");
public static final RpcScheduledExecutor CONTROL_SCHEDULER = new RpcScheduledExecutor(1,
"com.alibaba.nacos.control.DelayScheduler");
public static final RpcScheduledExecutor COMMON_SERVER_EXECUTOR = new RpcScheduledExecutor(1,
"com.alibaba.nacos.remote.ServerCommonScheduler");
public RpcScheduledExecutor(int corePoolSize, final String threadName) {
super(corePoolSize, new ThreadFactory() {
private AtomicLong index = new AtomicLong();
private final AtomicLong index = new AtomicLong();
@Override
public Thread newThread(Runnable r) {

View File

@ -64,7 +64,7 @@ public interface Selector<R, C, E> extends Serializable {
String getType();
/**
* Get the select context which usede by {@link #select(Object)}.
* Get the select context which used by {@link #select(Object)}.
*
* @return selector context type.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
* Copyright 1999-2023 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.
@ -16,6 +16,7 @@
package com.alibaba.nacos.auth.parser.grpc;
import com.alibaba.nacos.api.config.remote.request.AbstractConfigRequest;
import com.alibaba.nacos.api.config.remote.request.ConfigBatchListenRequest;
import com.alibaba.nacos.api.remote.request.Request;
import com.alibaba.nacos.common.utils.ReflectUtils;
@ -39,23 +40,35 @@ public class ConfigGrpcResourceParser extends AbstractGrpcResourceParser {
if (!configListenContexts.isEmpty()) {
namespaceId = ((ConfigBatchListenRequest) request).getConfigListenContexts().get(0).getTenant();
}
} else if (request instanceof AbstractConfigRequest) {
namespaceId = ((AbstractConfigRequest) request).getTenant();
} else {
namespaceId = (String) ReflectUtils.getFieldValue(request, "tenant", StringUtils.EMPTY);
}
return namespaceId;
return StringUtils.isBlank(namespaceId) ? StringUtils.EMPTY : namespaceId;
}
@Override
protected String getGroup(Request request) {
String groupName = (String) ReflectUtils
.getFieldValue(request, com.alibaba.nacos.api.common.Constants.GROUP, StringUtils.EMPTY);
String groupName;
if (request instanceof AbstractConfigRequest) {
groupName = ((AbstractConfigRequest) request).getGroup();
} else {
groupName = (String) ReflectUtils
.getFieldValue(request, com.alibaba.nacos.api.common.Constants.GROUP, StringUtils.EMPTY);
}
return StringUtils.isBlank(groupName) ? StringUtils.EMPTY : groupName;
}
@Override
protected String getResourceName(Request request) {
String dataId = (String) ReflectUtils
.getFieldValue(request, com.alibaba.nacos.api.common.Constants.DATAID, StringUtils.EMPTY);
String dataId;
if (request instanceof AbstractConfigRequest) {
dataId = ((AbstractConfigRequest) request).getDataId();
} else {
dataId = (String) ReflectUtils
.getFieldValue(request, com.alibaba.nacos.api.common.Constants.DATAID, StringUtils.EMPTY);
}
return StringUtils.isBlank(dataId) ? StringUtils.EMPTY : dataId;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
* Copyright 1999-2023 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.

View File

@ -36,11 +36,12 @@ import com.alibaba.nacos.client.config.utils.ParamUtils;
import com.alibaba.nacos.client.env.NacosClientProperties;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.PreInitUtils;
import com.alibaba.nacos.client.utils.ValidatorUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import org.slf4j.Logger;
import java.util.Arrays;
import java.util.Collections;
import java.util.Properties;
/**
@ -73,6 +74,7 @@ public class NacosConfigService implements ConfigService {
private final ConfigFilterChainManager configFilterChainManager;
public NacosConfigService(Properties properties) throws NacosException {
PreInitUtils.asyncPreLoadCostComponent();
final NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
ValidatorUtils.checkInitParam(clientProperties);
@ -105,7 +107,8 @@ public class NacosConfigService implements ConfigService {
.queryConfig(dataId, group, worker.getAgent().getTenant(), timeoutMs, false);
String content = configResponse.getContent();
String encryptedDataKey = configResponse.getEncryptedDataKey();
worker.addTenantListenersWithContent(dataId, group, content, encryptedDataKey, Arrays.asList(listener));
worker.addTenantListenersWithContent(dataId, group, content, encryptedDataKey,
Collections.singletonList(listener));
// get a decryptContent, fix https://github.com/alibaba/nacos/issues/7039
ConfigResponse cr = new ConfigResponse();
@ -119,7 +122,7 @@ public class NacosConfigService implements ConfigService {
@Override
public void addListener(String dataId, String group, Listener listener) throws NacosException {
worker.addTenantListeners(dataId, group, Arrays.asList(listener));
worker.addTenantListeners(dataId, group, Collections.singletonList(listener));
}
@Override

View File

@ -411,17 +411,13 @@ public class ClientWorker implements Closeable {
private int calculateTaskId() {
int perTaskSize = (int) ParamUtil.getPerTaskConfigSize();
int taskId = -1;
for (int index = 0; index < taskIdCacheCountList.size(); index++) {
if (taskIdCacheCountList.get(index).get() < perTaskSize) {
return index;
}
}
if (taskId < 0) {
taskIdCacheCountList.add(new AtomicInteger(0));
taskId = taskIdCacheCountList.size() - 1;
}
return taskId;
taskIdCacheCountList.add(new AtomicInteger(0));
return taskIdCacheCountList.size() - 1;
}
public CacheData getCache(String dataId, String group) {
@ -733,7 +729,7 @@ public class ClientWorker implements Closeable {
@Override
public Class<? extends Event> subscribeType() {
return ServerlistChangeEvent.class;
return ServerListChangeEvent.class;
}
};
NotifyCenter.registerSubscriber(subscriber);

View File

@ -23,5 +23,5 @@ import com.alibaba.nacos.common.notify.SlowEvent;
*
* @author zongtanghu
*/
public class ServerlistChangeEvent extends SlowEvent {
public class ServerListChangeEvent extends SlowEvent {
}

View File

@ -323,6 +323,9 @@ public class ServerListManager implements Closeable {
GetServerListTask getServersTask = new GetServerListTask(addressServerUrl);
for (int i = 0; i < initServerlistRetryTimes && serverUrls.isEmpty(); ++i) {
getServersTask.run();
if (!serverUrls.isEmpty()) {
break;
}
try {
this.wait((i + 1) * 100L);
} catch (Exception e) {
@ -408,8 +411,8 @@ public class ServerListManager implements Closeable {
currentServerAddr = iterator.next();
// Using unified event processor, NotifyCenter
NotifyCenter.publishEvent(new ServerlistChangeEvent());
LOGGER.info("[{}] [update-serverlist] serverlist updated to {}", name, serverUrls);
NotifyCenter.publishEvent(new ServerListChangeEvent());
LOGGER.info("[{}] [update-serverList] serverList updated to {}", name, serverUrls);
}
private List<String> getApacheServerList(String url, String name) {

View File

@ -36,6 +36,7 @@ import com.alibaba.nacos.client.naming.remote.NamingClientProxyDelegate;
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.PreInitUtils;
import com.alibaba.nacos.client.utils.ValidatorUtils;
import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.utils.StringUtils;
@ -54,7 +55,7 @@ import java.util.UUID;
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
public class NacosNamingService implements NamingService {
private static final String DEFAULT_NAMING_LOG_FILE_PATH = "naming.log";
private static final String DEFAULT_NAMING_LOG_FILE_PATH = "naming.log";
private static final String UP = "UP";
@ -86,20 +87,21 @@ public class NacosNamingService implements NamingService {
}
private void init(Properties properties) throws NacosException {
PreInitUtils.asyncPreLoadCostComponent();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
ValidatorUtils.checkInitParam(nacosClientProperties);
this.namespace = InitUtils.initNamespaceForNaming(nacosClientProperties);
InitUtils.initSerialization();
InitUtils.initWebRootContext(nacosClientProperties);
initLogName(nacosClientProperties);
this.notifierEventScope = UUID.randomUUID().toString();
this.changeNotifier = new InstancesChangeNotifier(this.notifierEventScope);
NotifyCenter.registerToPublisher(InstancesChangeEvent.class, 16384);
NotifyCenter.registerSubscriber(changeNotifier);
this.serviceInfoHolder = new ServiceInfoHolder(namespace, this.notifierEventScope, nacosClientProperties);
this.clientProxy = new NamingClientProxyDelegate(this.namespace, serviceInfoHolder, nacosClientProperties, changeNotifier);
this.clientProxy = new NamingClientProxyDelegate(this.namespace, serviceInfoHolder, nacosClientProperties,
changeNotifier);
}
private void initLogName(NacosClientProperties properties) {
@ -241,7 +243,7 @@ public class NacosNamingService implements NamingService {
serviceInfo = clientProxy.subscribe(serviceName, groupName, clusterString);
}
} else {
serviceInfo = clientProxy.queryInstancesOfService(serviceName, groupName, clusterString, 0, false);
serviceInfo = clientProxy.queryInstancesOfService(serviceName, groupName, clusterString, false);
}
List<Instance> list;
if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
@ -298,11 +300,11 @@ public class NacosNamingService implements NamingService {
String clusterString = StringUtils.join(clusters, ",");
if (subscribe) {
serviceInfo = serviceInfoHolder.getServiceInfo(serviceName, groupName, clusterString);
if (null == serviceInfo) {
if (null == serviceInfo || !clientProxy.isSubscribed(serviceName, groupName, clusterString)) {
serviceInfo = clientProxy.subscribe(serviceName, groupName, clusterString);
}
} else {
serviceInfo = clientProxy.queryInstancesOfService(serviceName, groupName, clusterString, 0, false);
serviceInfo = clientProxy.queryInstancesOfService(serviceName, groupName, clusterString, false);
}
return selectInstances(serviceInfo, healthy);
}
@ -368,13 +370,12 @@ public class NacosNamingService implements NamingService {
String clusterString = StringUtils.join(clusters, ",");
if (subscribe) {
ServiceInfo serviceInfo = serviceInfoHolder.getServiceInfo(serviceName, groupName, clusterString);
if (null == serviceInfo) {
if (null == serviceInfo || !clientProxy.isSubscribed(serviceName, groupName, clusterString)) {
serviceInfo = clientProxy.subscribe(serviceName, groupName, clusterString);
}
return Balancer.RandomByWeight.selectHost(serviceInfo);
} else {
ServiceInfo serviceInfo = clientProxy
.queryInstancesOfService(serviceName, groupName, clusterString, 0, false);
ServiceInfo serviceInfo = clientProxy.queryInstancesOfService(serviceName, groupName, clusterString, false);
return Balancer.RandomByWeight.selectHost(serviceInfo);
}
}
@ -467,6 +468,6 @@ public class NacosNamingService implements NamingService {
serviceInfoHolder.shutdown();
clientProxy.shutdown();
NotifyCenter.deregisterSubscriber(changeNotifier);
}
}

View File

@ -25,6 +25,8 @@ import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientManager;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.InitUtils;
import com.alibaba.nacos.client.naming.utils.NamingHttpUtil;
import com.alibaba.nacos.client.utils.ContextPathUtil;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.common.executor.NameThreadFactory;
import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
@ -50,7 +52,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTP_PREFIX;
/**
* Server list manager.
@ -74,6 +75,10 @@ public class ServerListManager implements ServerListFactory, Closeable {
private ScheduledExecutorService refreshServerListExecutor;
private String endpoint;
private String contentPath = ParamUtil.getDefaultContextPath();
private String serverListName = ParamUtil.getDefaultNodesPath();
private String nacosDomain;
@ -96,6 +101,16 @@ public class ServerListManager implements ServerListFactory, Closeable {
private void initServerAddr(NacosClientProperties properties) {
this.endpoint = InitUtils.initEndpoint(properties);
if (StringUtils.isNotEmpty(endpoint)) {
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
if (!StringUtils.isBlank(contentPathTmp)) {
this.contentPath = contentPathTmp;
}
String serverListNameTmp = properties.getProperty(PropertyKeyConst.CLUSTER_NAME);
if (!StringUtils.isBlank(serverListNameTmp)) {
this.serverListName = serverListNameTmp;
}
this.serversFromEndpoint = getServerListFromEndpoint();
refreshServerListExecutor = new ScheduledThreadPoolExecutor(1,
new NameThreadFactory("com.alibaba.nacos.client.naming.server.list.refresher"));
@ -115,7 +130,10 @@ public class ServerListManager implements ServerListFactory, Closeable {
private List<String> getServerListFromEndpoint() {
try {
String urlString = HTTP_PREFIX + endpoint + "/nacos/serverlist";
StringBuilder addressServerUrlTem = new StringBuilder(
String.format("http://%s%s/%s", this.endpoint,
ContextPathUtil.normalizeContextPath(this.contentPath), this.serverListName));
String urlString = addressServerUrlTem.toString();
Header header = NamingHttpUtil.builderHeader();
Query query = StringUtils.isNotBlank(namespace)
? Query.newInstance().addParam("namespace", namespace)

View File

@ -77,7 +77,8 @@ public class ServiceInfoUpdateService implements Closeable {
if (properties == null || !properties.containsKey(PropertyKeyConst.NAMING_ASYNC_QUERY_SUBSCRIBE_SERVICE)) {
return false;
}
return ConvertUtils.toBoolean(properties.getProperty(PropertyKeyConst.NAMING_ASYNC_QUERY_SUBSCRIBE_SERVICE), false);
return ConvertUtils.toBoolean(properties.getProperty(PropertyKeyConst.NAMING_ASYNC_QUERY_SUBSCRIBE_SERVICE),
false);
}
private int initPollingThreadCount(NacosClientProperties properties) {
@ -188,14 +189,14 @@ public class ServiceInfoUpdateService implements Closeable {
ServiceInfo serviceObj = serviceInfoHolder.getServiceInfoMap().get(serviceKey);
if (serviceObj == null) {
serviceObj = namingClientProxy.queryInstancesOfService(serviceName, groupName, clusters, 0, false);
serviceObj = namingClientProxy.queryInstancesOfService(serviceName, groupName, clusters, false);
serviceInfoHolder.processServiceInfo(serviceObj);
lastRefTime = serviceObj.getLastRefTime();
return;
}
if (serviceObj.getLastRefTime() <= lastRefTime) {
serviceObj = namingClientProxy.queryInstancesOfService(serviceName, groupName, clusters, 0, false);
serviceObj = namingClientProxy.queryInstancesOfService(serviceName, groupName, clusters, false);
serviceInfoHolder.processServiceInfo(serviceObj);
}
lastRefTime = serviceObj.getLastRefTime();

View File

@ -91,13 +91,12 @@ public interface NamingClientProxy extends Closeable {
* @param serviceName service name
* @param groupName group name
* @param clusters clusters
* @param udpPort udp port
* @param healthyOnly healthy only
* @return service info
* @throws NacosException nacos exception
*/
ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters, int udpPort,
boolean healthyOnly) throws NacosException;
ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters, boolean healthyOnly)
throws NacosException;
/**
* Query Service.

View File

@ -65,8 +65,8 @@ public class NamingClientProxyDelegate implements NamingClientProxy {
private ScheduledExecutorService executorService;
public NamingClientProxyDelegate(String namespace, ServiceInfoHolder serviceInfoHolder, NacosClientProperties properties,
InstancesChangeNotifier changeNotifier) throws NacosException {
public NamingClientProxyDelegate(String namespace, ServiceInfoHolder serviceInfoHolder,
NacosClientProperties properties, InstancesChangeNotifier changeNotifier) throws NacosException {
this.serviceInfoUpdateService = new ServiceInfoUpdateService(properties, serviceInfoHolder, this,
changeNotifier);
this.serverListManager = new ServerListManager(properties, namespace);
@ -88,9 +88,8 @@ public class NamingClientProxyDelegate implements NamingClientProxy {
});
final Properties nacosClientPropertiesView = properties.asProperties();
this.securityProxy.login(nacosClientPropertiesView);
this.executorService
.scheduleWithFixedDelay(() -> securityProxy.login(nacosClientPropertiesView), 0, SECURITY_INFO_REFRESH_INTERVAL_MILLS,
TimeUnit.MILLISECONDS);
this.executorService.scheduleWithFixedDelay(() -> securityProxy.login(nacosClientPropertiesView), 0,
SECURITY_INFO_REFRESH_INTERVAL_MILLS, TimeUnit.MILLISECONDS);
}
@Override
@ -131,9 +130,9 @@ public class NamingClientProxyDelegate implements NamingClientProxy {
}
@Override
public ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters, int udpPort,
public ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters,
boolean healthyOnly) throws NacosException {
return grpcClientProxy.queryInstancesOfService(serviceName, groupName, clusters, udpPort, healthyOnly);
return grpcClientProxy.queryInstancesOfService(serviceName, groupName, clusters, healthyOnly);
}
@Override
@ -178,8 +177,8 @@ public class NamingClientProxyDelegate implements NamingClientProxy {
@Override
public void unsubscribe(String serviceName, String groupName, String clusters) throws NacosException {
NAMING_LOGGER
.debug("[UNSUBSCRIBE-SERVICE] service:{}, group:{}, cluster:{} ", serviceName, groupName, clusters);
NAMING_LOGGER.debug("[UNSUBSCRIBE-SERVICE] service:{}, group:{}, cluster:{} ", serviceName, groupName,
clusters);
serviceInfoUpdateService.stopUpdateIfContain(serviceName, groupName, clusters);
grpcClientProxy.unsubscribe(serviceName, groupName, clusters);
}

View File

@ -54,8 +54,8 @@ import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.remote.client.RpcClient;
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
import com.alibaba.nacos.common.remote.client.ServerListFactory;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import com.alibaba.nacos.common.remote.client.ServerListFactory;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.JacksonUtils;
@ -98,7 +98,7 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
labels.put(Constants.APPNAME, AppNameUtils.getAppName());
this.rpcClient = RpcClientFactory.createClient(uuid, ConnectionType.GRPC, labels,
RpcClientTlsConfig.properties(properties.asProperties()));
this.redoService = new NamingGrpcRedoService(this);
this.redoService = new NamingGrpcRedoService(this, properties);
NAMING_LOGGER.info("Create naming rpc client for uuid->{}", uuid);
start(serverListFactory, serviceInfoHolder);
}
@ -139,8 +139,10 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
@Override
public void batchDeregisterService(String serviceName, String groupName, List<Instance> instances)
throws NacosException {
List<Instance> retainInstance = getRetainInstance(serviceName, groupName, instances);
batchRegisterService(serviceName, groupName, retainInstance);
synchronized (redoService.getRegisteredInstances()) {
List<Instance> retainInstance = getRetainInstance(serviceName, groupName, instances);
batchRegisterService(serviceName, groupName, retainInstance);
}
}
/**
@ -218,11 +220,20 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
@Override
public void deregisterService(String serviceName, String groupName, Instance instance) throws NacosException {
NAMING_LOGGER
.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}", namespaceId, serviceName,
instance);
redoService.instanceDeregister(serviceName, groupName);
doDeregisterService(serviceName, groupName, instance);
NAMING_LOGGER.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}", namespaceId,
serviceName, instance);
String key = NamingUtils.getGroupedName(serviceName, groupName);
InstanceRedoData instanceRedoData = redoService.getRegisteredInstancesByKey(key);
if (instanceRedoData instanceof BatchInstanceRedoData) {
List<Instance> instances = new ArrayList<>();
if (null != instance) {
instances.add(instance);
}
batchDeregisterService(serviceName, groupName, instances);
} else {
redoService.instanceDeregister(serviceName, groupName);
doDeregisterService(serviceName, groupName, instance);
}
}
/**
@ -246,12 +257,11 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
}
@Override
public ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters, int udpPort,
public ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters,
boolean healthyOnly) throws NacosException {
ServiceQueryRequest request = new ServiceQueryRequest(namespaceId, serviceName, groupName);
request.setCluster(clusters);
request.setHealthyOnly(healthyOnly);
request.setUdpPort(udpPort);
QueryServiceResponse response = requestToServer(request, QueryServiceResponse.class);
return response.getServiceInfo();
}
@ -321,8 +331,8 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
@Override
public void unsubscribe(String serviceName, String groupName, String clusters) throws NacosException {
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER
.debug("[GRPC-UNSUBSCRIBE] service:{}, group:{}, cluster:{} ", serviceName, groupName, clusters);
NAMING_LOGGER.debug("[GRPC-UNSUBSCRIBE] service:{}, group:{}, cluster:{} ", serviceName, groupName,
clusters);
}
redoService.subscriberDeregister(serviceName, groupName, clusters);
doUnsubscribe(serviceName, groupName, clusters);

View File

@ -16,9 +16,12 @@
package com.alibaba.nacos.client.naming.remote.gprc.redo;
import com.alibaba.nacos.api.PropertyKeyConst;
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.api.naming.utils.NamingUtils;
import com.alibaba.nacos.client.env.NacosClientProperties;
import com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy;
import com.alibaba.nacos.client.naming.remote.gprc.redo.data.BatchInstanceRedoData;
import com.alibaba.nacos.client.naming.remote.gprc.redo.data.InstanceRedoData;
@ -48,12 +51,9 @@ public class NamingGrpcRedoService implements ConnectionEventListener {
private static final String REDO_THREAD_NAME = "com.alibaba.nacos.client.naming.grpc.redo";
private static final int REDO_THREAD = 1;
private int redoThreadCount;
/**
* TODO get redo delay from config.
*/
private static final long DEFAULT_REDO_DELAY = 3000L;
private long redoDelayTime;
private final ConcurrentMap<String, InstanceRedoData> registeredInstances = new ConcurrentHashMap<>();
@ -63,10 +63,21 @@ public class NamingGrpcRedoService implements ConnectionEventListener {
private volatile boolean connected = false;
public NamingGrpcRedoService(NamingGrpcClientProxy clientProxy) {
this.redoExecutor = new ScheduledThreadPoolExecutor(REDO_THREAD, new NameThreadFactory(REDO_THREAD_NAME));
this.redoExecutor.scheduleWithFixedDelay(new RedoScheduledTask(clientProxy, this), DEFAULT_REDO_DELAY,
DEFAULT_REDO_DELAY, TimeUnit.MILLISECONDS);
public NamingGrpcRedoService(NamingGrpcClientProxy clientProxy, NacosClientProperties properties) {
setProperties(properties);
this.redoExecutor = new ScheduledThreadPoolExecutor(redoThreadCount, new NameThreadFactory(REDO_THREAD_NAME));
this.redoExecutor.scheduleWithFixedDelay(new RedoScheduledTask(clientProxy, this), redoDelayTime, redoDelayTime,
TimeUnit.MILLISECONDS);
}
private void setProperties(NacosClientProperties properties) {
redoDelayTime = properties.getLong(PropertyKeyConst.REDO_DELAY_TIME, Constants.DEFAULT_REDO_DELAY_TIME);
redoThreadCount = properties.getInteger(PropertyKeyConst.REDO_DELAY_THREAD_COUNT,
Constants.DEFAULT_REDO_THREAD_COUNT);
}
public ConcurrentMap<String, InstanceRedoData> getRegisteredInstances() {
return registeredInstances;
}
public boolean isConnected() {
@ -112,7 +123,7 @@ public class NamingGrpcRedoService implements ConnectionEventListener {
*
* @param serviceName service name
* @param groupName group name
* @param instances batch registered instance
* @param instances batch registered instance
*/
public void cacheInstanceForRedo(String serviceName, String groupName, List<Instance> instances) {
String key = NamingUtils.getGroupedName(serviceName, groupName);
@ -306,6 +317,7 @@ public class NamingGrpcRedoService implements ConnectionEventListener {
/**
* get Cache service.
*
* @return cache service
*/
public InstanceRedoData getRegisteredInstancesByKey(String combinedServiceName) {

View File

@ -28,7 +28,6 @@ import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.api.selector.ExpressionSelector;
import com.alibaba.nacos.api.selector.SelectorType;
import com.alibaba.nacos.api.utils.NetUtils;
import com.alibaba.nacos.client.env.NacosClientProperties;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.core.ServerListManager;
@ -93,8 +92,6 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
private static final String CLUSTERS_PARAM = "clusters";
private static final String UDP_PORT_PARAM = "udpPort";
private static final String CLIENT_IP_PARAM = "clientIP";
private static final String HEALTHY_ONLY_PARAM = "healthyOnly";
@ -160,17 +157,15 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
}
@Override
public void batchDeregisterService(String serviceName, String groupName, List<Instance> instances)
throws NacosException {
public void batchDeregisterService(String serviceName, String groupName, List<Instance> instances) {
throw new UnsupportedOperationException(
"Do not support persistent instances to perform batch de registration methods.");
}
@Override
public void deregisterService(String serviceName, String groupName, Instance instance) throws NacosException {
NAMING_LOGGER
.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}", namespaceId, serviceName,
instance);
NAMING_LOGGER.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}", namespaceId,
serviceName, instance);
if (instance.isEphemeral()) {
return;
}
@ -187,8 +182,8 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
@Override
public void updateInstance(String serviceName, String groupName, Instance instance) throws NacosException {
NAMING_LOGGER
.info("[UPDATE-SERVICE] {} update service {} with instance: {}", namespaceId, serviceName, instance);
NAMING_LOGGER.info("[UPDATE-SERVICE] {} update service {} with instance: {}", namespaceId, serviceName,
instance);
final Map<String, String> params = new HashMap<>(32);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
@ -206,20 +201,10 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
}
@Override
public ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters, int udpPort,
boolean healthyOnly) throws NacosException {
final Map<String, String> params = new HashMap<>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, NamingUtils.getGroupedName(serviceName, groupName));
params.put(CLUSTERS_PARAM, clusters);
params.put(UDP_PORT_PARAM, String.valueOf(udpPort));
params.put(CLIENT_IP_PARAM, NetUtils.localIP());
params.put(HEALTHY_ONLY_PARAM, String.valueOf(healthyOnly));
String result = reqApi(UtilAndComs.nacosUrlBase + "/instance/list", params, HttpMethod.GET);
if (StringUtils.isNotEmpty(result)) {
return JacksonUtils.toObj(result, ServiceInfo.class);
}
return new ServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), clusters);
public ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters,
boolean healthyOnly) {
throw new UnsupportedOperationException(
"Do not support query instance by http client,please use gRPC replaced.");
}
@Override
@ -442,8 +427,8 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
url = NamingHttpClientManager.getInstance().getPrefix() + curServer + api;
}
try {
HttpRestResult<String> restResult = nacosRestTemplate
.exchangeForm(url, header, Query.newInstance().initParams(params), body, method, String.class);
HttpRestResult<String> restResult = nacosRestTemplate.exchangeForm(url, header,
Query.newInstance().initParams(params), body, method, String.class);
end = System.currentTimeMillis();
MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(restResult.getCode()))

View File

@ -0,0 +1,47 @@
/*
* Copyright 1999-2023 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;
import com.alibaba.nacos.client.auth.ram.utils.SpasAdapter;
import com.alibaba.nacos.common.utils.JacksonUtils;
/**
* Async do pre init to load some cost component.
*
* <ul>
* <li>JacksonUtil</li>
* <li>SpasAdapter</li>
* </ul>
*
* @author xiweng.yy
*/
public class PreInitUtils {
/**
* Async pre load cost component.
*/
@SuppressWarnings("PMD.AvoidManuallyCreateThreadRule")
public static void asyncPreLoadCostComponent() {
Thread preLoadThread = new Thread(() -> {
// Jackson util will init static {@code ObjectMapper}, which will cost hundreds milliseconds.
JacksonUtils.createEmptyJsonNode();
// Ram auth plugin will try to get credential from env and system when leak input identity by properties.
SpasAdapter.getAk();
});
preLoadThread.start();
}
}

View File

@ -301,6 +301,7 @@
{"name":"setEnabled","parameterTypes":["boolean"] },
{"name":"setEphemeral","parameterTypes":["boolean"] },
{"name":"setHealthy","parameterTypes":["boolean"] },
{"name":"setInstanceId","parameterTypes":["java.lang.String"] },
{"name":"setIp","parameterTypes":["java.lang.String"] },
{"name":"setMetadata","parameterTypes":["java.util.Map"] },
{"name":"setPort","parameterTypes":["int"] },

View File

@ -43,7 +43,6 @@ import java.util.List;
import java.util.Properties;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
@ -344,7 +343,7 @@ public class NacosNamingServiceTest {
//when
client.getAllInstances(serviceName, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "", 0, false);
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "", false);
}
@Test
@ -355,7 +354,7 @@ public class NacosNamingServiceTest {
//when
client.getAllInstances(serviceName, groupName, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "", 0, false);
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "", false);
}
@ -391,7 +390,7 @@ public class NacosNamingServiceTest {
//when
client.getAllInstances(serviceName, clusterList, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "cluster1,cluster2", 0,
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "cluster1,cluster2",
false);
}
@ -404,7 +403,7 @@ public class NacosNamingServiceTest {
//when
client.getAllInstances(serviceName, groupName, clusterList, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "cluster1,cluster2", 0, false);
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "cluster1,cluster2", false);
}
@Test
@ -435,7 +434,7 @@ public class NacosNamingServiceTest {
//when
client.selectInstances(serviceName, true, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "", 0, false);
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "", false);
}
@Test
@ -446,7 +445,7 @@ public class NacosNamingServiceTest {
//when
client.selectInstances(serviceName, groupName, true, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "", 0, false);
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "", false);
}
@ -482,7 +481,7 @@ public class NacosNamingServiceTest {
//when
client.selectInstances(serviceName, clusterList, true, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "cluster1,cluster2", 0,
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "cluster1,cluster2",
false);
}
@ -495,7 +494,7 @@ public class NacosNamingServiceTest {
//when
client.selectInstances(serviceName, groupName, clusterList, true, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "cluster1,cluster2", 0, false);
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "cluster1,cluster2", false);
}
@Test
@ -525,7 +524,7 @@ public class NacosNamingServiceTest {
String serviceName = "service1";
String groupName = "group1";
List<String> clusterList = Arrays.asList("cluster1", "cluster2");
when(proxy.queryInstancesOfService(serviceName, groupName, "cluster1,cluster2", 0, false)).thenReturn(info);
when(proxy.queryInstancesOfService(serviceName, groupName, "cluster1,cluster2", false)).thenReturn(info);
//when
List<Instance> instances = client.selectInstances(serviceName, groupName, clusterList, true, false);
@ -583,14 +582,14 @@ public class NacosNamingServiceTest {
hosts.add(healthyInstance);
ServiceInfo infoWithHealthyInstance = new ServiceInfo();
infoWithHealthyInstance.setHosts(hosts);
when(proxy.queryInstancesOfService(anyString(), anyString(), anyString(), anyInt(), anyBoolean())).thenReturn(
when(proxy.queryInstancesOfService(anyString(), anyString(), anyString(), anyBoolean())).thenReturn(
infoWithHealthyInstance);
String serviceName = "service1";
//when
client.selectOneHealthyInstance(serviceName, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "", 0, false);
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "", false);
}
@Test
@ -603,7 +602,7 @@ public class NacosNamingServiceTest {
hosts.add(healthyInstance);
ServiceInfo infoWithHealthyInstance = new ServiceInfo();
infoWithHealthyInstance.setHosts(hosts);
when(proxy.queryInstancesOfService(anyString(), anyString(), anyString(), anyInt(), anyBoolean())).thenReturn(
when(proxy.queryInstancesOfService(anyString(), anyString(), anyString(), anyBoolean())).thenReturn(
infoWithHealthyInstance);
String serviceName = "service1";
@ -611,7 +610,7 @@ public class NacosNamingServiceTest {
//when
client.selectOneHealthyInstance(serviceName, groupName, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "", 0, false);
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "", false);
}
@ -667,7 +666,7 @@ public class NacosNamingServiceTest {
hosts.add(healthyInstance);
ServiceInfo infoWithHealthyInstance = new ServiceInfo();
infoWithHealthyInstance.setHosts(hosts);
when(proxy.queryInstancesOfService(anyString(), anyString(), anyString(), anyInt(), anyBoolean())).thenReturn(
when(proxy.queryInstancesOfService(anyString(), anyString(), anyString(), anyBoolean())).thenReturn(
infoWithHealthyInstance);
String serviceName = "service1";
@ -675,7 +674,7 @@ public class NacosNamingServiceTest {
//when
client.selectOneHealthyInstance(serviceName, clusterList, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "cluster1,cluster2", 0,
verify(proxy, times(1)).queryInstancesOfService(serviceName, Constants.DEFAULT_GROUP, "cluster1,cluster2",
false);
}
@ -689,7 +688,7 @@ public class NacosNamingServiceTest {
hosts.add(healthyInstance);
ServiceInfo infoWithHealthyInstance = new ServiceInfo();
infoWithHealthyInstance.setHosts(hosts);
when(proxy.queryInstancesOfService(anyString(), anyString(), anyString(), anyInt(), anyBoolean())).thenReturn(
when(proxy.queryInstancesOfService(anyString(), anyString(), anyString(), anyBoolean())).thenReturn(
infoWithHealthyInstance);
String serviceName = "service1";
@ -698,7 +697,7 @@ public class NacosNamingServiceTest {
//when
client.selectOneHealthyInstance(serviceName, groupName, clusterList, false);
//then
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "cluster1,cluster2", 0, false);
verify(proxy, times(1)).queryInstancesOfService(serviceName, groupName, "cluster1,cluster2", false);
}
@Test

View File

@ -43,19 +43,19 @@ public class ServiceInfoUpdateServiceTest {
info.setCacheMillis(10000L);
ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class);
NamingClientProxy proxy = Mockito.mock(NamingClientProxy.class);
Mockito.when(proxy.queryInstancesOfService(serviceName, group, clusters, 0, false)).thenReturn(info);
Mockito.when(proxy.queryInstancesOfService(serviceName, group, clusters, false)).thenReturn(info);
InstancesChangeNotifier notifyer = Mockito.mock(InstancesChangeNotifier.class);
Properties prop = new Properties();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
nacosClientProperties.setProperty("namingAsyncQuerySubscribeService", "true");
final ServiceInfoUpdateService serviceInfoUpdateService = new ServiceInfoUpdateService(nacosClientProperties, holder, proxy,
notifyer);
final ServiceInfoUpdateService serviceInfoUpdateService = new ServiceInfoUpdateService(nacosClientProperties,
holder, proxy, notifyer);
serviceInfoUpdateService.scheduleUpdateIfAbsent("aa", "bb", "cc");
TimeUnit.SECONDS.sleep(2);
Mockito.verify(proxy).queryInstancesOfService(serviceName, group, clusters, 0, false);
TimeUnit.MILLISECONDS.sleep(1500);
Mockito.verify(proxy).queryInstancesOfService(serviceName, group, clusters, false);
}
@Test
@ -69,17 +69,17 @@ public class ServiceInfoUpdateServiceTest {
info.setClusters(clusters);
info.setLastRefTime(System.currentTimeMillis());
NamingClientProxy proxy = Mockito.mock(NamingClientProxy.class);
Mockito.when(proxy.queryInstancesOfService(serviceName, group, clusters, 0, false)).thenReturn(info);
Mockito.when(proxy.queryInstancesOfService(serviceName, group, clusters, false)).thenReturn(info);
InstancesChangeNotifier notifyer = Mockito.mock(InstancesChangeNotifier.class);
Properties prop = new Properties();
ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class);
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
final ServiceInfoUpdateService serviceInfoUpdateService = new ServiceInfoUpdateService(nacosClientProperties, holder, proxy,
notifyer);
final ServiceInfoUpdateService serviceInfoUpdateService = new ServiceInfoUpdateService(nacosClientProperties,
holder, proxy, notifyer);
serviceInfoUpdateService.scheduleUpdateIfAbsent(serviceName, group, clusters);
serviceInfoUpdateService.stopUpdateIfContain(serviceName, group, clusters);
serviceInfoUpdateService.shutdown();
}

View File

@ -127,7 +127,7 @@ public class AbstractNamingClientProxyTest {
}
@Override
public ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters, int udpPort,
public ServiceInfo queryInstancesOfService(String serviceName, String groupName, String clusters,
boolean healthyOnly) throws NacosException {
return null;
}

View File

@ -78,7 +78,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);
@ -106,7 +106,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingHttpClientProxy mockHttpClient = Mockito.mock(NamingHttpClientProxy.class);
@ -134,7 +134,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);
@ -162,7 +162,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingHttpClientProxy mockHttpClient = Mockito.mock(NamingHttpClientProxy.class);
@ -190,7 +190,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
String serviceName = "service1";
@ -210,7 +210,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);
@ -221,8 +221,8 @@ public class NamingClientProxyDelegateTest {
String serviceName = "service1";
String groupName = "group1";
String clusters = "cluster1";
delegate.queryInstancesOfService(serviceName, groupName, clusters, 0, false);
verify(mockGrpcClient, times(1)).queryInstancesOfService(serviceName, groupName, clusters, 0, false);
delegate.queryInstancesOfService(serviceName, groupName, clusters, false);
verify(mockGrpcClient, times(1)).queryInstancesOfService(serviceName, groupName, clusters, false);
}
@Test
@ -232,7 +232,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
Service service = delegate.queryService("a", "b");
@ -246,7 +246,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
Service service = new Service();
@ -264,7 +264,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
Assert.assertFalse(delegate.deleteService("service", "group1"));
@ -277,7 +277,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
Service service = new Service();
@ -295,7 +295,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);
@ -319,7 +319,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);
@ -350,7 +350,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);
@ -373,7 +373,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);
@ -392,7 +392,7 @@ public class NamingClientProxyDelegateTest {
Properties props = new Properties();
props.setProperty("serverAddr", "localhost");
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);

View File

@ -221,6 +221,33 @@ public class NamingGrpcClientProxyTest {
}));
}
@Test
public void testDeregisterServiceForBatchRegistered() throws NacosException {
try {
List<Instance> instanceList = new ArrayList<>();
instance.setHealthy(true);
instanceList.add(instance);
instanceList.add(new Instance());
client.batchRegisterService(SERVICE_NAME, GROUP_NAME, instanceList);
} catch (Exception ignored) {
}
response = new BatchInstanceResponse();
when(this.rpcClient.request(any())).thenReturn(response);
List<Instance> instanceList = new ArrayList<>();
instance.setHealthy(true);
instanceList.add(instance);
client.deregisterService(SERVICE_NAME, GROUP_NAME, instance);
verify(this.rpcClient, times(1)).request(argThat(request -> {
if (request instanceof BatchInstanceRequest) {
BatchInstanceRequest request1 = (BatchInstanceRequest) request;
request1.setRequestId("1");
return request1.getInstances().size() == 1 && request1.getType()
.equals(NamingRemoteConstants.BATCH_REGISTER_INSTANCE);
}
return false;
}));
}
@Test
public void testBatchRegisterService() throws NacosException {
List<Instance> instanceList = new ArrayList<>();
@ -312,7 +339,7 @@ public class NamingGrpcClientProxyTest {
ServiceInfo info = new ServiceInfo(GROUP_NAME + "@@" + SERVICE_NAME + "@@" + CLUSTERS);
res.setServiceInfo(info);
when(this.rpcClient.request(any())).thenReturn(res);
ServiceInfo actual = client.queryInstancesOfService(SERVICE_NAME, GROUP_NAME, CLUSTERS, 0, false);
ServiceInfo actual = client.queryInstancesOfService(SERVICE_NAME, GROUP_NAME, CLUSTERS, false);
Assert.assertEquals(info, actual);
}

View File

@ -16,8 +16,10 @@
package com.alibaba.nacos.client.naming.remote.gprc.redo;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.remote.TestConnection;
import com.alibaba.nacos.client.env.NacosClientProperties;
import com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy;
import com.alibaba.nacos.client.naming.remote.gprc.redo.data.BatchInstanceRedoData;
import com.alibaba.nacos.client.naming.remote.gprc.redo.data.InstanceRedoData;
@ -31,8 +33,10 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledExecutorService;
@ -56,9 +60,11 @@ public class NamingGrpcRedoServiceTest {
@Before
public void setUp() throws Exception {
redoService = new NamingGrpcRedoService(clientProxy);
ScheduledExecutorService redoExecutor = (ScheduledExecutorService) ReflectUtils
.getFieldValue(redoService, "redoExecutor");
Properties prop = new Properties();
NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
redoService = new NamingGrpcRedoService(clientProxy, nacosClientProperties);
ScheduledExecutorService redoExecutor = (ScheduledExecutorService) ReflectUtils.getFieldValue(redoService,
"redoExecutor");
redoExecutor.shutdownNow();
}
@ -67,6 +73,42 @@ public class NamingGrpcRedoServiceTest {
redoService.shutdown();
}
@Test
public void testDefaultProperties() throws Exception {
Field redoThreadCountField = NamingGrpcRedoService.class.getDeclaredField("redoThreadCount");
redoThreadCountField.setAccessible(true);
Field redoDelayTimeField = NamingGrpcRedoService.class.getDeclaredField("redoDelayTime");
redoDelayTimeField.setAccessible(true);
Long redoDelayTimeValue = (Long) redoDelayTimeField.get(redoService);
Integer redoThreadCountValue = (Integer) redoThreadCountField.get(redoService);
assertEquals(Long.valueOf(3000L), redoDelayTimeValue);
assertEquals(Integer.valueOf(1), redoThreadCountValue);
}
@Test
public void testCustomProperties() throws Exception {
Properties prop = new Properties();
prop.setProperty(PropertyKeyConst.REDO_DELAY_TIME, "4000");
prop.setProperty(PropertyKeyConst.REDO_DELAY_THREAD_COUNT, "2");
NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
NamingGrpcRedoService redoService = new NamingGrpcRedoService(clientProxy, nacosClientProperties);
Field redoThreadCountField = NamingGrpcRedoService.class.getDeclaredField("redoThreadCount");
redoThreadCountField.setAccessible(true);
Field redoDelayTimeField = NamingGrpcRedoService.class.getDeclaredField("redoDelayTime");
redoDelayTimeField.setAccessible(true);
Long redoDelayTimeValue = (Long) redoDelayTimeField.get(redoService);
Integer redoThreadCountValue = (Integer) redoThreadCountField.get(redoService);
assertEquals(Long.valueOf(4000L), redoDelayTimeValue);
assertEquals(Integer.valueOf(2), redoThreadCountValue);
}
@Test
public void testOnConnected() {
assertFalse(redoService.isConnected());
@ -115,7 +157,8 @@ public class NamingGrpcRedoServiceTest {
instanceList.add(instance);
redoService.cacheInstanceForRedo(SERVICE, GROUP, instanceList);
assertFalse(registeredInstances.isEmpty());
BatchInstanceRedoData actual = (BatchInstanceRedoData) registeredInstances.entrySet().iterator().next().getValue();
BatchInstanceRedoData actual = (BatchInstanceRedoData) registeredInstances.entrySet().iterator().next()
.getValue();
assertEquals(SERVICE, actual.getServiceName());
assertEquals(GROUP, actual.getGroupName());
assertEquals(instanceList, actual.getInstances());

View File

@ -212,27 +212,13 @@ public class NamingHttpClientProxyTest {
}
@Test
public void testQueryInstancesOfService() throws Exception {
//given
NacosRestTemplate nacosRestTemplate = mock(NacosRestTemplate.class);
HttpRestResult<Object> a = new HttpRestResult<Object>();
a.setData("");
a.setCode(200);
when(nacosRestTemplate.exchangeForm(any(), any(), any(), any(), any(), any())).thenReturn(a);
final Field nacosRestTemplateField = NamingHttpClientProxy.class.getDeclaredField("nacosRestTemplate");
nacosRestTemplateField.setAccessible(true);
nacosRestTemplateField.set(clientProxy, nacosRestTemplate);
public void testQueryInstancesOfServiceThrowsException() {
//assert exception
String serviceName = "service1";
String groupName = "group1";
String clusters = "cluster1";
//when
ServiceInfo serviceInfo = clientProxy.queryInstancesOfService(serviceName, groupName, clusters, 0, false);
//then
verify(nacosRestTemplate, times(1)).exchangeForm(any(), any(), any(), any(), eq(HttpMethod.GET), any());
Assert.assertEquals(groupName + "@@" + serviceName, serviceInfo.getName());
Assert.assertEquals(clusters, serviceInfo.getClusters());
Assert.assertThrows(UnsupportedOperationException.class,
() -> clientProxy.queryInstancesOfService(serviceName, groupName, clusters, false));
}
@Test
@ -254,8 +240,8 @@ public class NamingHttpClientProxyTest {
//when
Service service = clientProxy.queryService(serviceName, groupName);
//then
verify(nacosRestTemplate, times(1))
.exchangeForm(endsWith(UtilAndComs.nacosUrlService), any(), any(), any(), eq(HttpMethod.GET), any());
verify(nacosRestTemplate, times(1)).exchangeForm(endsWith(UtilAndComs.nacosUrlService), any(), any(), any(),
eq(HttpMethod.GET), any());
Assert.assertEquals(serviceName, service.getName());
Assert.assertEquals(groupName, service.getGroupName());
}
@ -276,8 +262,8 @@ public class NamingHttpClientProxyTest {
//when
clientProxy.createService(new Service(), new NoneSelector());
//then
verify(nacosRestTemplate, times(1))
.exchangeForm(endsWith(UtilAndComs.nacosUrlService), any(), any(), any(), eq(HttpMethod.POST), any());
verify(nacosRestTemplate, times(1)).exchangeForm(endsWith(UtilAndComs.nacosUrlService), any(), any(), any(),
eq(HttpMethod.POST), any());
}
@Test
@ -298,8 +284,8 @@ public class NamingHttpClientProxyTest {
//when
clientProxy.deleteService(serviceName, groupName);
//then
verify(nacosRestTemplate, times(1))
.exchangeForm(endsWith(UtilAndComs.nacosUrlService), any(), any(), any(), eq(HttpMethod.DELETE), any());
verify(nacosRestTemplate, times(1)).exchangeForm(endsWith(UtilAndComs.nacosUrlService), any(), any(), any(),
eq(HttpMethod.DELETE), any());
}
@Test
@ -320,8 +306,8 @@ public class NamingHttpClientProxyTest {
//when
clientProxy.updateService(new Service(), new NoneSelector());
//then
verify(nacosRestTemplate, times(1))
.exchangeForm(endsWith(UtilAndComs.nacosUrlService), any(), any(), any(), eq(HttpMethod.PUT), any());
verify(nacosRestTemplate, times(1)).exchangeForm(endsWith(UtilAndComs.nacosUrlService), any(), any(), any(),
eq(HttpMethod.PUT), any());
}
@ -343,8 +329,8 @@ public class NamingHttpClientProxyTest {
//when
boolean serverHealthy = clientProxy.serverHealthy();
//then
verify(nacosRestTemplate, times(1))
.exchangeForm(endsWith("/operator/metrics"), any(), any(), any(), eq(HttpMethod.GET), any());
verify(nacosRestTemplate, times(1)).exchangeForm(endsWith("/operator/metrics"), any(), any(), any(),
eq(HttpMethod.GET), any());
Assert.assertTrue(serverHealthy);
}
@ -365,8 +351,8 @@ public class NamingHttpClientProxyTest {
//when
ListView<String> serviceList = clientProxy.getServiceList(1, 10, groupName, new NoneSelector());
//then
verify(nacosRestTemplate, times(1))
.exchangeForm(endsWith("/service/list"), any(), any(), any(), eq(HttpMethod.GET), any());
verify(nacosRestTemplate, times(1)).exchangeForm(endsWith("/service/list"), any(), any(), any(),
eq(HttpMethod.GET), any());
Assert.assertEquals(2, serviceList.getCount());
Assert.assertEquals("aaa", serviceList.getData().get(0));
Assert.assertEquals("bbb", serviceList.getData().get(1));

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 1999-2018 Alibaba Group Holding Ltd.
~ Copyright 1999-2023 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.
@ -61,7 +61,7 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
<build>
<resources>

View File

@ -96,7 +96,7 @@ public class JdkHttpClientRequest implements HttpClientRequest {
conn.setRequestMethod(httpMethod);
if (body != null && !"".equals(body)) {
String contentType = headers.getValue(HttpHeaderConsts.CONTENT_TYPE);
String bodyStr = JacksonUtils.toJson(body);
String bodyStr = body instanceof String ? (String) body : JacksonUtils.toJson(body);
if (MediaType.APPLICATION_FORM_URLENCODED.equals(contentType)) {
Map<String, String> map = JacksonUtils.toObj(bodyStr, HashMap.class);
bodyStr = HttpUtils.encodingParams(map, headers.getCharset());

View File

@ -27,7 +27,7 @@ import java.util.List;
* @author zongtanghu
*/
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class SmartSubscriber extends Subscriber {
public abstract class SmartSubscriber extends Subscriber<Event> {
/**
* Returns which event type are smart subscriber interested in.

View File

@ -0,0 +1,53 @@
/*
* Copyright 1999-2023 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.paramcheck;
import java.util.List;
/**
* The type Abstract param checker.
*
* @author zhuoguang
*/
public abstract class AbstractParamChecker {
protected ParamCheckRule paramCheckRule;
public AbstractParamChecker() {
initParamCheckRule();
}
/**
* Gets checker type.
*
* @return the checker type
*/
public abstract String getCheckerType();
/**
* Check param info list param check response.
*
* @param paramInfos the param infos
* @return the param check response
*/
public abstract ParamCheckResponse checkParamInfoList(List<ParamInfo> paramInfos);
/**
* Init param check rule.
*/
public abstract void initParamCheckRule();
}

View File

@ -0,0 +1,416 @@
/*
* Copyright 1999-2023 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.paramcheck;
import com.alibaba.nacos.common.utils.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
/**
* The type Default param checker.
*
* @author zhuoguang
*/
public class DefaultParamChecker extends AbstractParamChecker {
private Pattern namespaceShowNamePattern;
private Pattern namespaceIdPattern;
private Pattern dataIdPattern;
private Pattern serviceNamePattern;
private Pattern groupPattern;
private Pattern clusterPattern;
private Pattern ipPattern;
private static final String CHECKER_TYPE = "default";
@Override
public String getCheckerType() {
return CHECKER_TYPE;
}
@Override
public ParamCheckResponse checkParamInfoList(List<ParamInfo> paramInfos) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (paramInfos == null) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
for (ParamInfo paramInfo : paramInfos) {
paramCheckResponse = checkParamInfoFormat(paramInfo);
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
@Override
public void initParamCheckRule() {
this.paramCheckRule = new ParamCheckRule();
initFormatPattern();
}
private void initFormatPattern() {
this.namespaceShowNamePattern = Pattern.compile(this.paramCheckRule.namespaceShowNamePatternString);
this.namespaceIdPattern = Pattern.compile(this.paramCheckRule.namespaceIdPatternString);
this.dataIdPattern = Pattern.compile(this.paramCheckRule.dataIdPatternString);
this.serviceNamePattern = Pattern.compile(this.paramCheckRule.serviceNamePatternString);
this.groupPattern = Pattern.compile(this.paramCheckRule.groupPatternString);
this.clusterPattern = Pattern.compile(this.paramCheckRule.clusterPatternString);
this.ipPattern = Pattern.compile(this.paramCheckRule.ipPatternString);
}
/**
* Check param info format.
*
* @param paramInfo the param info
* @return the param check response
*/
public ParamCheckResponse checkParamInfoFormat(ParamInfo paramInfo) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (paramInfo == null) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
paramCheckResponse = checkNamespaceShowNameFormat(paramInfo.getNamespaceShowName());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse = checkNamespaceIdFormat(paramInfo.getNamespaceId());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse = checkDataIdFormat(paramInfo.getDataId());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse = checkServiceNameFormat(paramInfo.getServiceName());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse = checkGroupFormat(paramInfo.getGroup());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse = checkClusterFormat(paramInfo.getClusters());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse = checkSingleClusterFormat(paramInfo.getCluster());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse = checkIpFormat(paramInfo.getIp());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse = checkPortFormat(paramInfo.getPort());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse = checkMetadataFormat(paramInfo.getMetadata());
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check namespace show name format.
*
* @param namespaceShowName the namespace show name
* @return the param check response
*/
public ParamCheckResponse checkNamespaceShowNameFormat(String namespaceShowName) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (StringUtils.isBlank(namespaceShowName)) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
if (namespaceShowName.length() > paramCheckRule.maxNamespaceShowNameLength) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'namespaceShowName' is illegal, the param length should not exceed %d.",
paramCheckRule.maxNamespaceShowNameLength));
return paramCheckResponse;
}
if (!namespaceShowNamePattern.matcher(namespaceShowName).matches()) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage("Param 'namespaceShowName' is illegal, illegal characters should not appear in the param.");
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check namespace id format.
*
* @param namespaceId the namespace id
* @return the param check response
*/
public ParamCheckResponse checkNamespaceIdFormat(String namespaceId) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (StringUtils.isBlank(namespaceId)) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
if (namespaceId.length() > paramCheckRule.maxNamespaceIdLength) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'namespaceId/tenant' is illegal, the param length should not exceed %d.",
paramCheckRule.maxNamespaceIdLength));
return paramCheckResponse;
}
if (!namespaceIdPattern.matcher(namespaceId).matches()) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage("Param 'namespaceId/tenant' is illegal, illegal characters should not appear in the param.");
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check data id format.
*
* @param dataId the data id
* @return the param check response
*/
public ParamCheckResponse checkDataIdFormat(String dataId) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (StringUtils.isBlank(dataId)) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
if (dataId.length() > paramCheckRule.maxDataIdLength) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'dataId' is illegal, the param length should not exceed %d.",
paramCheckRule.maxNamespaceIdLength));
return paramCheckResponse;
}
if (!dataIdPattern.matcher(dataId).matches()) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage("Param 'dataId' is illegal, illegal characters should not appear in the param.");
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check service name format.
*
* @param serviceName the service name
* @return the param check response
*/
public ParamCheckResponse checkServiceNameFormat(String serviceName) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (StringUtils.isBlank(serviceName)) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
if (serviceName.length() > paramCheckRule.maxServiceNameLength) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'serviceName' is illegal, the param length should not exceed %d.",
paramCheckRule.maxServiceNameLength));
return paramCheckResponse;
}
if (!serviceNamePattern.matcher(serviceName).matches()) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage("Param 'serviceName' is illegal, illegal characters should not appear in the param.");
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check group format.
*
* @param group the group
* @return the param check response
*/
public ParamCheckResponse checkGroupFormat(String group) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (StringUtils.isBlank(group)) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
if (group.length() > paramCheckRule.maxGroupLength) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'group' is illegal, the param length should not exceed %d.",
paramCheckRule.maxGroupLength));
return paramCheckResponse;
}
if (!groupPattern.matcher(group).matches()) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage("Param 'group' is illegal, illegal characters should not appear in the param.");
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check cluster format.
*
* @param clusterString the cluster string
* @return the param check response
*/
public ParamCheckResponse checkClusterFormat(String clusterString) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (StringUtils.isBlank(clusterString)) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
String[] clusters = clusterString.split(",");
for (String cluster : clusters) {
paramCheckResponse = checkSingleClusterFormat(cluster);
if (!paramCheckResponse.isSuccess()) {
return paramCheckResponse;
}
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check single cluster format.
*
* @param cluster the cluster
* @return the param check response
*/
public ParamCheckResponse checkSingleClusterFormat(String cluster) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (StringUtils.isBlank(cluster)) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
if (cluster.length() > paramCheckRule.maxClusterLength) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'cluster' is illegal, the param length should not exceed %d.",
paramCheckRule.maxClusterLength));
return paramCheckResponse;
}
if (!clusterPattern.matcher(cluster).matches()) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage("Param 'cluster' is illegal, illegal characters should not appear in the param.");
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check ip format.
*
* @param ip the ip
* @return the param check response
*/
public ParamCheckResponse checkIpFormat(String ip) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (StringUtils.isBlank(ip)) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
if (ip.length() > paramCheckRule.maxIpLength) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'ip' is illegal, the param length should not exceed %d.",
paramCheckRule.maxIpLength));
return paramCheckResponse;
}
if (!ipPattern.matcher(ip).matches()) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage("Param 'ip' is illegal, illegal characters should not appear in the param.");
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check port format.
*
* @param port the port
* @return the param check response
*/
public ParamCheckResponse checkPortFormat(String port) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (StringUtils.isBlank(port)) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
int portInt = 0;
try {
portInt = Integer.parseInt(port);
} catch (Exception e) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'port' is illegal, the value should be between %d and %d",
paramCheckRule.minPort, paramCheckRule.maxPort));
return paramCheckResponse;
}
if (portInt > paramCheckRule.maxPort || portInt < paramCheckRule.minPort) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'port' is illegal, the value should be between %d and %d",
paramCheckRule.minPort, paramCheckRule.maxPort));
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
/**
* Check metadata format.
*
* @param metadata the metadata
* @return the param check response
*/
public ParamCheckResponse checkMetadataFormat(Map<String, String> metadata) {
ParamCheckResponse paramCheckResponse = new ParamCheckResponse();
if (metadata == null || metadata.isEmpty()) {
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
int totalLength = 0;
for (Map.Entry<String, String> entry : metadata.entrySet()) {
if (StringUtils.isNotBlank(entry.getKey())) {
totalLength = totalLength + entry.getKey().length();
}
if (StringUtils.isNotBlank(entry.getValue())) {
totalLength = totalLength + entry.getValue().length();
}
}
if (totalLength > paramCheckRule.maxMetadataLength) {
paramCheckResponse.setSuccess(false);
paramCheckResponse.setMessage(String.format("Param 'Metadata' is illegal, the param length should not exceed %d.",
paramCheckRule.maxMetadataLength));
return paramCheckResponse;
}
paramCheckResponse.setSuccess(true);
return paramCheckResponse;
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 1999-2023 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.paramcheck;
/**
* The type Param check response.
*
* @author zhuoguang
*/
public class ParamCheckResponse {
private boolean success;
private String message;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 1999-2023 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.paramcheck;
/**
* Param check rules.
*
* @author zhuoguang
*/
public class ParamCheckRule {
public int maxNamespaceShowNameLength = 256;
public String namespaceShowNamePatternString = "^[^@#$%^&*]+$";
public int maxNamespaceIdLength = 64;
public String namespaceIdPatternString = "^[\\w-]+";
public int maxDataIdLength = 256;
public String dataIdPatternString = "^[a-zA-Z0-9-_:\\.]*$";
public int maxServiceNameLength = 512;
public String serviceNamePatternString = "^(?!@).((?!@@)[^\\u4E00-\\u9FA5\\s])*$";
public int maxGroupLength = 128;
public String groupPatternString = "^[a-zA-Z0-9-_:\\.]*$";
public int maxClusterLength = 64;
public String clusterPatternString = "^[0-9a-zA-Z-_]+$";
public int maxIpLength = 128;
public String ipPatternString = "^[^\\u4E00-\\u9FA5\\s]*$";
public int maxPort = 65535;
public int minPort = 0;
public int maxMetadataLength = 1024;
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 1999-2023 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.paramcheck;
import com.alibaba.nacos.common.spi.NacosServiceLoader;
import com.alibaba.nacos.common.utils.StringUtils;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* The type Param checker manager.
*
* @author zhuoguang
*/
public class ParamCheckerManager {
private static final ParamCheckerManager INSTANCE = new ParamCheckerManager();
private static final AbstractParamChecker DEFAULT_PARAM_CHECKER = new DefaultParamChecker();
private final Map<String, AbstractParamChecker> paramCheckerMap = new ConcurrentHashMap<>();
private ParamCheckerManager() {
Collection<AbstractParamChecker> paramCheckers = NacosServiceLoader.load(AbstractParamChecker.class);
for (AbstractParamChecker paramChecker : paramCheckers) {
String checkerType = paramChecker.getCheckerType();
paramCheckerMap.put(checkerType, paramChecker);
}
}
public static ParamCheckerManager getInstance() {
return INSTANCE;
}
public AbstractParamChecker getParamChecker(String checkerType) {
if (StringUtils.isBlank(checkerType)) {
return DEFAULT_PARAM_CHECKER;
}
AbstractParamChecker paramChecker = paramCheckerMap.get(checkerType);
if (paramChecker == null) {
paramChecker = DEFAULT_PARAM_CHECKER;
}
return paramChecker;
}
}

View File

@ -0,0 +1,126 @@
/*
* Copyright 1999-2023 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.paramcheck;
import java.util.Map;
/**
* Param info.
*
* @author zhuoguang
*/
public class ParamInfo {
private String namespaceShowName;
private String namespaceId;
private String dataId;
private String serviceName;
private String group;
private String cluster;
private String clusters;
private String ip;
private String port;
private Map<String, String> metadata;
public String getNamespaceShowName() {
return namespaceShowName;
}
public void setNamespaceShowName(String namespaceShowName) {
this.namespaceShowName = namespaceShowName;
}
public String getNamespaceId() {
return namespaceId;
}
public void setNamespaceId(String namespaceId) {
this.namespaceId = namespaceId;
}
public String getDataId() {
return dataId;
}
public void setDataId(String dataId) {
this.dataId = dataId;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getCluster() {
return cluster;
}
public void setCluster(String cluster) {
this.cluster = cluster;
}
public String getClusters() {
return clusters;
}
public void setClusters(String clusters) {
this.clusters = clusters;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public Map<String, String> getMetadata() {
return metadata;
}
public void setMetadata(Map<String, String> metadata) {
this.metadata = metadata;
}
}

View File

@ -346,7 +346,7 @@ public abstract class RpcClient implements Closeable {
rpcClientStatus.set(RpcClientStatus.STARTING);
int startUpRetryTimes = rpcClientConfig.retryTimes();
while (startUpRetryTimes > 0 && connectToServer == null) {
while (startUpRetryTimes >= 0 && connectToServer == null) {
try {
startUpRetryTimes--;
ServerInfo serverInfo = nextRpcServer();
@ -639,7 +639,8 @@ public abstract class RpcClient implements Closeable {
Response response;
Throwable exceptionThrow = null;
long start = System.currentTimeMillis();
while (retryTimes < rpcClientConfig.retryTimes() && (timeoutMills <= 0 || System.currentTimeMillis() < timeoutMills + start)) {
while (retryTimes <= rpcClientConfig.retryTimes() && (timeoutMills <= 0
|| System.currentTimeMillis() < timeoutMills + start)) {
boolean waitReconnect = false;
try {
if (this.currentConnection == null || !isRunning()) {
@ -710,16 +711,15 @@ public abstract class RpcClient implements Closeable {
*/
public void asyncRequest(Request request, RequestCallBack callback) throws NacosException {
int retryTimes = 0;
Throwable exceptionToThrow = null;
long start = System.currentTimeMillis();
while (retryTimes < rpcClientConfig.retryTimes()
while (retryTimes <= rpcClientConfig.retryTimes()
&& System.currentTimeMillis() < start + callback.getTimeout()) {
boolean waitReconnect = false;
try {
if (this.currentConnection == null || !isRunning()) {
waitReconnect = true;
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "Client not connected.");
throw new NacosException(NacosException.CLIENT_DISCONNECT, "Client not connected.");
}
this.currentConnection.asyncRequest(request, callback);
return;
@ -763,13 +763,13 @@ public abstract class RpcClient implements Closeable {
int retryTimes = 0;
long start = System.currentTimeMillis();
Exception exceptionToThrow = null;
while (retryTimes < rpcClientConfig.retryTimes()
while (retryTimes <= rpcClientConfig.retryTimes()
&& System.currentTimeMillis() < start + rpcClientConfig.timeOutMills()) {
boolean waitReconnect = false;
try {
if (this.currentConnection == null || !isRunning()) {
waitReconnect = true;
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "Client not connected.");
throw new NacosException(NacosException.CLIENT_DISCONNECT, "Client not connected.");
}
return this.currentConnection.requestFuture(request);
} catch (Exception e) {
@ -835,6 +835,7 @@ public abstract class RpcClient implements Closeable {
} catch (Exception e) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] HandleServerRequest:{}, errorMessage = {}",
rpcClientConfig.name(), serverRequestHandler.getClass().getName(), e.getMessage());
throw e;
}
}

View File

@ -49,7 +49,7 @@ public class RpcClientTlsConfig extends TlsConfig {
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_PROTOCOLS)) {
tlsConfig.setProtocols(RpcConstants.RPC_CLIENT_TLS_PROTOCOLS);
tlsConfig.setProtocols(properties.getProperty(RpcConstants.RPC_CLIENT_TLS_PROTOCOLS));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_CIPHERS)) {

View File

@ -20,6 +20,7 @@ import com.alibaba.nacos.common.trace.DeregisterInstanceReason;
/**
* Naming deregister instance trace event.
*
* @author yanda
*/
public class DeregisterInstanceTraceEvent extends NamingTraceEvent {
@ -30,9 +31,9 @@ public class DeregisterInstanceTraceEvent extends NamingTraceEvent {
private final boolean rpc;
private String instanceIp;
private final String instanceIp;
private int instancePort;
private final int instancePort;
public final DeregisterInstanceReason reason;

View File

@ -18,14 +18,15 @@ package com.alibaba.nacos.common.trace.event.naming;
/**
* Naming deregister service trace event.
*
* @author yanda
*/
public class DeregisterServiceTraceEvent extends NamingTraceEvent {
private static final long serialVersionUID = 7358195336881398548L;
public DeregisterServiceTraceEvent(long eventTime, String serviceNamespace,
String serviceGroup, String serviceName) {
public DeregisterServiceTraceEvent(long eventTime, String serviceNamespace, String serviceGroup,
String serviceName) {
super("DEREGISTER_SERVICE_TRACE_EVENT", eventTime, serviceNamespace, serviceGroup, serviceName);
}
}

View File

@ -20,21 +20,22 @@ import com.alibaba.nacos.common.trace.HealthCheckType;
/**
* Naming instance health state change trace event.
*
* @author yanda
*/
public class HealthStateChangeTraceEvent extends NamingTraceEvent {
private static final long serialVersionUID = 6966396191118694597L;
private String instanceIp;
private final String instanceIp;
private int instancePort;
private final int instancePort;
private boolean isHealthy;
private final boolean isHealthy;
private HealthCheckType healthCheckType;
private final HealthCheckType healthCheckType;
private String healthStateChangeReason;
private final String healthStateChangeReason;
public String getInstanceIp() {
return instanceIp;
@ -60,8 +61,8 @@ public class HealthStateChangeTraceEvent extends NamingTraceEvent {
return healthStateChangeReason;
}
public HealthStateChangeTraceEvent(long eventTime, String serviceNamespace, String serviceGroup,
String serviceName, String instanceIp, int instancePort, boolean isHealthy, String healthStateChangeReason) {
public HealthStateChangeTraceEvent(long eventTime, String serviceNamespace, String serviceGroup, String serviceName,
String instanceIp, int instancePort, boolean isHealthy, String healthStateChangeReason) {
super("HEALTH_STATE_CHANGE_TRACE_EVENT", eventTime, serviceNamespace, serviceGroup, serviceName);
this.instanceIp = instanceIp;
this.instancePort = instancePort;

View File

@ -24,11 +24,11 @@ import com.alibaba.nacos.common.trace.event.TraceEvent;
* @author yanda
*/
public class NamingTraceEvent extends TraceEvent {
private static final long serialVersionUID = 2923077640400851816L;
public NamingTraceEvent(String eventType, long eventTime,
String serviceNamespace, String serviceGroup, String name) {
public NamingTraceEvent(String eventType, long eventTime, String serviceNamespace, String serviceGroup,
String name) {
super(eventType, eventTime, serviceNamespace, serviceGroup, name);
}

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.common.trace.event.naming;
/**
* Naming push service trace event.
*
* @author yanda
*/
public class PushServiceTraceEvent extends NamingTraceEvent {
@ -55,8 +56,8 @@ public class PushServiceTraceEvent extends NamingTraceEvent {
}
public PushServiceTraceEvent(long eventTime, long pushCostTimeForNetWork, long pushCostTimeForAll,
long serviceLevelAgreementTime, String clientIp, String serviceNamespace,
String serviceGroup, String serviceName, int instanceSize) {
long serviceLevelAgreementTime, String clientIp, String serviceNamespace, String serviceGroup,
String serviceName, int instanceSize) {
super("PUSH_SERVICE_TRACE_EVENT", eventTime, serviceNamespace, serviceGroup, serviceName);
this.clientIp = clientIp;
this.instanceSize = instanceSize;

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.common.trace.event.naming;
/**
* Naming register instance trace event.
*
* @author yanda
*/
public class RegisterInstanceTraceEvent extends NamingTraceEvent {
@ -28,9 +29,9 @@ public class RegisterInstanceTraceEvent extends NamingTraceEvent {
private final boolean rpc;
private String instanceIp;
private final String instanceIp;
private int instancePort;
private final int instancePort;
public String getClientIp() {
return clientIp;

View File

@ -18,14 +18,14 @@ package com.alibaba.nacos.common.trace.event.naming;
/**
* Naming deregister service trace event.
*
* @author yanda
*/
public class RegisterServiceTraceEvent extends NamingTraceEvent {
private static final long serialVersionUID = -8568231862586636388L;
public RegisterServiceTraceEvent(long eventTime, String serviceNamespace,
String serviceGroup, String serviceName) {
public RegisterServiceTraceEvent(long eventTime, String serviceNamespace, String serviceGroup, String serviceName) {
super("REGISTER_SERVICE_TRACE_EVENT", eventTime, serviceNamespace, serviceGroup, serviceName);
}
}

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.common.trace.event.naming;
/**
* Naming subscribe service trace event.
*
* @author yanda
*/
public class SubscribeServiceTraceEvent extends NamingTraceEvent {
@ -30,8 +31,8 @@ public class SubscribeServiceTraceEvent extends NamingTraceEvent {
return clientIp;
}
public SubscribeServiceTraceEvent(long eventTime, String clientIp, String serviceNamespace,
String serviceGroup, String serviceName) {
public SubscribeServiceTraceEvent(long eventTime, String clientIp, String serviceNamespace, String serviceGroup,
String serviceName) {
super("SUBSCRIBE_SERVICE_TRACE_EVENT", eventTime, serviceNamespace, serviceGroup, serviceName);
this.clientIp = clientIp;
}

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.common.trace.event.naming;
/**
* Naming unsubscribe service trace event.
*
* @author yanda
*/
public class UnsubscribeServiceTraceEvent extends NamingTraceEvent {
@ -30,8 +31,8 @@ public class UnsubscribeServiceTraceEvent extends NamingTraceEvent {
return clientIp;
}
public UnsubscribeServiceTraceEvent(long eventTime, String clientIp, String serviceNamespace,
String serviceGroup, String serviceName) {
public UnsubscribeServiceTraceEvent(long eventTime, String clientIp, String serviceNamespace, String serviceGroup,
String serviceName) {
super("UNSUBSCRIBE_SERVICE_TRACE_EVENT", eventTime, serviceNamespace, serviceGroup, serviceName);
this.clientIp = clientIp;
}

View File

@ -0,0 +1,68 @@
/*
* 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.trace.event.naming;
import java.util.Map;
/**
* Naming update instance trace event.
*
* @author stone-98
* @date 2023/8/31
*/
public class UpdateInstanceTraceEvent extends NamingTraceEvent {
private static final long serialVersionUID = -6995370254824508523L;
private final Map<String, String> metadata;
private final String clientIp;
private final String instanceIp;
private final int instancePort;
public Map<String, String> getMetadata() {
return metadata;
}
public String getClientIp() {
return clientIp;
}
public String getInstanceIp() {
return instanceIp;
}
public int getInstancePort() {
return instancePort;
}
public String toInetAddr() {
return instanceIp + ":" + instancePort;
}
public UpdateInstanceTraceEvent(long eventTime, String clientIp, String serviceNamespace, String serviceGroup,
String serviceName, String instanceIp, int instancePort, Map<String, String> metadata) {
super("UPDATE_INSTANCE_TRACE_EVENT", eventTime, serviceNamespace, serviceGroup, serviceName);
this.clientIp = clientIp;
this.instanceIp = instanceIp;
this.instancePort = instancePort;
this.metadata = metadata;
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.trace.event.naming;
import java.util.Map;
/**
* Naming update service trace event.
*
* @author stone-98
* @date 2023/8/31
*/
public class UpdateServiceTraceEvent extends NamingTraceEvent {
private static final long serialVersionUID = -6792054530665003857L;
private final Map<String, String> metadata;
public Map<String, String> getMetadata() {
return metadata;
}
public UpdateServiceTraceEvent(long eventTime, String serviceNamespace, String serviceGroup, String serviceName,
Map<String, String> metadata) {
super("UPDATE_SERVICE_TRACE_EVENT", eventTime, serviceNamespace, serviceGroup, serviceName);
this.metadata = metadata;
}
}

View File

@ -129,6 +129,29 @@ public class StringUtils {
return isEmpty(str) ? defaultStr : str;
}
/**
* <p>Returns either the passed in CharSequence, or if the CharSequence is
* empty or {@code null} or whitespace only, the value of {@code defaultStr}.</p>
*
* @param str the CharSequence to check, may be null, may be whitespace only
* @param defaultStr the default CharSequence to return if the input is empty ("") or {@code null}, may be null
* @return the passed in CharSequence, or the default
*/
public static String defaultIfBlank(String str, String defaultStr) {
return isBlank(str) ? defaultStr : str;
}
/**
* <p>Returns either the passed in CharSequence, or if the CharSequence is
* empty or {@code null} or whitespace only, the value of {@code EmptyString}.</p>
*
* @param str the CharSequence to check, may be null, may be whitespace only
* @return the passed in CharSequence, or the empty string
*/
public static String defaultEmptyIfBlank(String str) {
return defaultIfBlank(str, EMPTY);
}
/**
* <p>Compares two CharSequences, returning {@code true} if they represent
* equal sequences of characters.</p>
@ -400,7 +423,7 @@ public class StringUtils {
}
if (ignoreCase) {
String lowerCaseStr = str.toString().toLowerCase();
String lowerCasePrefix = str.toString().toLowerCase();
String lowerCasePrefix = prefix.toString().toLowerCase();
return lowerCaseStr.startsWith(lowerCasePrefix);
} else {
return str.toString().startsWith(prefix.toString());
@ -542,7 +565,7 @@ public class StringUtils {
* {@code String} is not {@code null}, its length is greater than 0, and it contains at least one non-whitespace
* character.
*
* @param str the {@code String} to check (may be {@code null})
* @param str the {@code String} to check (maybe {@code null})
* @return {@code true} if the {@code String} is not {@code null}, its length is greater than 0, and it does not
* contain whitespace only
* @see Character#isWhitespace
@ -698,7 +721,7 @@ public class StringUtils {
* <p>Note: this method returns {@code true} for a {@code String} that
* purely consists of whitespace.
*
* @param str the {@code String} to check (may be {@code null})
* @param str the {@code String} to check (maybe {@code null})
* @return {@code true} if the {@code String} is not {@code null} and has length
* @see #hasText(String)
*/
@ -710,7 +733,7 @@ public class StringUtils {
* Take a {@code String} that is a delimited list and convert it into a {@code String} array.
*
* <p>A single {@code delimiter} may consist of more than one character,
* but it will still be considered as a single delimiter string, rather than as bunch of potential delimiter
* but it will still be considered as a single delimiter string, rather than as a bunch of potential delimiter
* characters, in contrast to {@link #tokenizeToStringArray}.
*
* @param str the input {@code String} (potentially {@code null} or empty)
@ -727,7 +750,7 @@ public class StringUtils {
* Take a {@code String} that is a delimited list and convert it into a {@code String} array.
*
* <p>A single {@code delimiter} may consist of more than one character,
* but it will still be considered as a single delimiter string, rather than as bunch of potential delimiter
* but it will still be considered as a single delimiter string, rather than as a bunch of potential delimiter
* characters, in contrast to {@link #tokenizeToStringArray}.
*
* @param str the input {@code String} (potentially {@code null} or empty)
@ -853,9 +876,9 @@ public class StringUtils {
}
/**
* Extract the filename from the given Java resource path, e.g. {@code "mypath/myfile.txt" &rarr; "myfile.txt"}.
* Extract the filename from the given Java resource path, e.g. {@code "myPath/myFile.txt" &rarr; "myFile.txt"}.
*
* @param path the file path (may be {@code null})
* @param path the file path (maybe {@code null})
* @return the extracted filename, or {@code null} if none
*/

View File

@ -0,0 +1,17 @@
#
# Copyright 1999-2023 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.
#
com.alibaba.nacos.common.paramcheck.DefaultParamChecker

View File

@ -0,0 +1,41 @@
/*
* Copyright 1999-2023 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.paramcheck;
import org.junit.Test;
import java.util.ArrayList;
/**
* The type Default param checker test.
*
* @author zhuoguang
*/
public class DefaultParamCheckerTest {
/**
* Check param info list.
*/
@Test
public void checkParamInfoList() {
AbstractParamChecker paramChecker = new DefaultParamChecker();
ParamInfo paramInfo = new ParamInfo();
ArrayList<ParamInfo> paramInfos = new ArrayList<>();
paramInfos.add(paramInfo);
paramChecker.checkParamInfoList(paramInfos);
}
}

View File

@ -319,17 +319,14 @@ public class RpcClientTest {
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "10.10.10.10::8848")).getAddress());
assertEquals("10.10.10.10:8848",
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "10.10.10.10:8848")).getAddress());
assertEquals("10.10.10.10:8848",
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "http://10.10.10.10:8848"))
.getAddress());
assertEquals("10.10.10.10:8848",
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "http://10.10.10.10::8848"))
.getAddress());
assertEquals("10.10.10.10:8848", ((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient,
"http://10.10.10.10:8848")).getAddress());
assertEquals("10.10.10.10:8848", ((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient,
"http://10.10.10.10::8848")).getAddress());
assertEquals("10.10.10.10:8848",
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "http://10.10.10.10")).getAddress());
assertEquals("10.10.10.10:8848",
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "https://10.10.10.10::8848"))
.getAddress());
assertEquals("10.10.10.10:8848", ((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient,
"https://10.10.10.10::8848")).getAddress());
}
@Test
@ -437,7 +434,7 @@ public class RpcClientTest {
exception = e;
}
verify(connection, times(3)).requestFuture(any());
verify(connection, times(4)).requestFuture(any());
verify(rpcClient).switchServerAsyncOnRequestFail();
Assert.assertNotNull(exception);
assertEquals(RpcClientStatus.UNHEALTHY, rpcClient.rpcClientStatus.get());
@ -635,4 +632,19 @@ public class RpcClientTest {
}
};
}
@Test(expected = RuntimeException.class)
public void testHandleServerRequestWhenExceptionThenThrowException() throws RuntimeException {
RpcClient rpcClient = buildTestNextRpcServerClient();
Request request = new Request() {
@Override
public String getModule() {
return null;
}
};
rpcClient.serverRequestHandlers.add(req -> {
throw new RuntimeException();
});
rpcClient.handleServerRequest(request);
}
}

View File

@ -112,7 +112,7 @@
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-contrl-plugin</artifactId>
<artifactId>nacos-control-plugin</artifactId>
<version>${revision}</version>
</dependency>
<dependency>

View File

@ -28,7 +28,6 @@ import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -54,12 +53,15 @@ public class CapacityManagementAspect {
private static final String DELETE_CONFIG =
"execution(* com.alibaba.nacos.config.server.controller.ConfigController.deleteConfig(..)) && args"
+ "(request,response,dataId,group,tenant,..)";
@Autowired
private CapacityService capacityService;
@Autowired
private ConfigInfoPersistService configInfoPersistService;
private final CapacityService capacityService;
private final ConfigInfoPersistService configInfoPersistService;
public CapacityManagementAspect(ConfigInfoPersistService configInfoPersistService, CapacityService capacityService) {
this.configInfoPersistService = configInfoPersistService;
this.capacityService = capacityService;
}
/**
* Need to judge the size of content whether to exceed the limitation.

View File

@ -0,0 +1,70 @@
/*
* Copyright 1999-2022 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.config.server.aspect;
import com.alibaba.nacos.config.server.utils.LogUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
/**
* The pointcut for configuration change operations, it will log when the configuration change fails.
*
* @author blake.qiu
*/
@Aspect
@Component
public class ConfigOpFailureAspect {
private static final Logger LOGGER = LogUtil.DEFAULT_LOG;
/**
* Pointcut for all methods from 'configRepositoryInterface'.
*/
@Pointcut("within(com.alibaba.nacos.config.server.service.repository..*)")
public void configRepositoryInterfaceMethods() {
}
/**
* Log message when a method from 'configRepositoryInterface' throws an exception.
*/
@AfterThrowing(pointcut = "configRepositoryInterfaceMethods()", throwing = "exception")
public void logException(JoinPoint joinPoint, Throwable exception) {
try {
Object[] args = joinPoint.getArgs();
StringBuilder params = new StringBuilder();
if (args != null) {
for (int i = 0; i < args.length; i++) {
if (i < args.length - 1) {
params.append(args[i]).append(", ");
} else {
params.append(args[i]);
}
}
}
String methodName = joinPoint.getSignature().getName();
LOGGER.error("An error occurred while executing method [{}].\n Parameters: [{}].", methodName, params,
exception);
} catch (Exception e) {
LOGGER.error("An error occurred while logging the original exception. method [{}]",
joinPoint.getSignature().getName(), e);
}
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.config.server.configuration;
import com.alibaba.nacos.core.config.AbstractDynamicConfig;
import com.alibaba.nacos.sys.env.EnvUtil;
/**
* Nacos config common configs.
*
* @author blake.qiu
*/
public class ConfigCommonConfig extends AbstractDynamicConfig {
private static final String CONFIG_COMMON = "ConfigCommon";
private static final ConfigCommonConfig INSTANCE = new ConfigCommonConfig();
private int maxPushRetryTimes = 50;
private ConfigCommonConfig() {
super(CONFIG_COMMON);
resetConfig();
}
public static ConfigCommonConfig getInstance() {
return INSTANCE;
}
public int getMaxPushRetryTimes() {
return maxPushRetryTimes;
}
public void setMaxPushRetryTimes(int maxPushRetryTimes) {
this.maxPushRetryTimes = maxPushRetryTimes;
}
@Override
protected void getConfigFromEnv() {
maxPushRetryTimes = EnvUtil.getProperty("nacos.config.push.maxRetryTime", Integer.class, 50);
}
@Override
protected String printConfig() {
return "ConfigCommonConfigs{" + "maxPushRetryTimes=" + maxPushRetryTimes + '}';
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2023 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.
@ -16,8 +16,9 @@
package com.alibaba.nacos.config.server.configuration;
import com.alibaba.nacos.config.server.filter.NacosWebFilter;
import com.alibaba.nacos.config.server.filter.CircuitFilter;
import com.alibaba.nacos.config.server.filter.ConfigParamCheckFilter;
import com.alibaba.nacos.config.server.filter.NacosWebFilter;
import com.alibaba.nacos.persistence.configuration.condition.ConditionDistributedEmbedStorage;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
@ -65,4 +66,19 @@ public class NacosConfigConfiguration {
return new CircuitFilter();
}
@Bean
public FilterRegistrationBean<ConfigParamCheckFilter> configParamCheckFilterRegistration() {
FilterRegistrationBean<ConfigParamCheckFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(configParamCheckFilter());
registration.addUrlPatterns("/v1/cs/*");
registration.addUrlPatterns("/v2/cs/*");
registration.setName("configparamcheckfilter");
registration.setOrder(8);
return registration;
}
@Bean
public ConfigParamCheckFilter configParamCheckFilter() {
return new ConfigParamCheckFilter();
}
}

View File

@ -299,8 +299,9 @@ public class ConfigController {
@Secured(action = ActionTypes.WRITE, signType = SignType.CONFIG)
public RestResult<Boolean> deleteConfigs(HttpServletRequest request, @RequestParam(value = "ids") List<Long> ids) {
String clientIp = RequestUtil.getRemoteIp(request);
String srcUser = RequestUtil.getSrcUserName(request);
final Timestamp time = TimeUtils.getCurrentTime();
List<ConfigInfo> configInfoList = configInfoPersistService.removeConfigInfoByIds(ids, clientIp, null);
List<ConfigInfo> configInfoList = configInfoPersistService.removeConfigInfoByIds(ids, clientIp, srcUser);
if (CollectionUtils.isEmpty(configInfoList)) {
return RestResultUtils.success(true);
}

View File

@ -21,7 +21,6 @@ import com.alibaba.nacos.api.model.v2.Result;
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
import com.alibaba.nacos.common.http.param.MediaType;
import com.alibaba.nacos.common.utils.InternetAddressUtil;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.Pair;
import com.alibaba.nacos.common.utils.StringUtils;
@ -52,7 +51,6 @@ import org.springframework.stereotype.Service;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
@ -79,11 +77,11 @@ public class ConfigServletInner {
private final LongPollingService longPollingService;
private ConfigInfoPersistService configInfoPersistService;
private final ConfigInfoPersistService configInfoPersistService;
private ConfigInfoBetaPersistService configInfoBetaPersistService;
private final ConfigInfoBetaPersistService configInfoBetaPersistService;
private ConfigInfoTagPersistService configInfoTagPersistService;
private final ConfigInfoTagPersistService configInfoTagPersistService;
public ConfigServletInner(LongPollingService longPollingService, ConfigInfoPersistService configInfoPersistService,
ConfigInfoBetaPersistService configInfoBetaPersistService,
@ -172,7 +170,6 @@ public class ConfigServletInner {
boolean isSli = false;
if (lockResult > 0) {
// LockResult > 0 means cacheItem is not null and other thread can`t delete this cacheItem
FileInputStream fis = null;
try {
String md5 = Constants.NULL;
long lastModified = 0L;
@ -212,7 +209,7 @@ public class ConfigServletInner {
} else {
if (StringUtils.isBlank(tag)) {
if (isUseTag(cacheItem, autoTag)) {
if (cacheItem != null && cacheItem.getConfigCacheTags() != null) {
if (cacheItem.getConfigCacheTags() != null) {
ConfigCache configCacheTag = cacheItem.getConfigCacheTags().get(autoTag);
if (configCacheTag != null) {
md5 = configCacheTag.getMd5(acceptCharset);
@ -254,10 +251,8 @@ public class ConfigServletInner {
isSli = true;
}
} else {
if (cacheItem != null) {
md5 = cacheItem.getTagMd5(tag, acceptCharset);
lastModified = cacheItem.getTagLastModified(tag);
}
md5 = cacheItem.getTagMd5(tag, acceptCharset);
lastModified = cacheItem.getTagLastModified(tag);
if (PropertyUtil.isDirectRead()) {
configInfoBase = configInfoTagPersistService.findConfigInfo4Tag(dataId, group, tenant, tag);
} else {
@ -298,8 +293,6 @@ public class ConfigServletInner {
} else {
out.print(pair.getSecond());
}
out.flush();
out.close();
} else {
String encryptedDataKey = response.getHeader("Encrypted-Data-Key");
Pair<String, String> pair = EncryptionHandler.decryptHandler(dataId, encryptedDataKey, content);
@ -310,9 +303,9 @@ public class ConfigServletInner {
} else {
out.print(decryptContent);
}
out.flush();
out.close();
}
out.flush();
out.close();
LogUtil.PULL_CHECK_LOG.warn("{}|{}|{}|{}", groupKey, requestIp, md5, TimeUtils.getCurrentTimeStr());
@ -329,7 +322,6 @@ public class ConfigServletInner {
} finally {
releaseConfigReadLock(groupKey);
IoUtils.closeQuietly(fis);
}
} else if (lockResult == 0) {

View File

@ -0,0 +1,95 @@
/*
* Copyright 1999-2023 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.config.server.filter;
import com.alibaba.nacos.common.paramcheck.AbstractParamChecker;
import com.alibaba.nacos.common.paramcheck.ParamCheckResponse;
import com.alibaba.nacos.common.paramcheck.ParamCheckerManager;
import com.alibaba.nacos.common.paramcheck.ParamInfo;
import com.alibaba.nacos.core.paramcheck.AbstractHttpParamExtractor;
import com.alibaba.nacos.core.paramcheck.HttpParamExtractorManager;
import com.alibaba.nacos.core.paramcheck.ServerParamCheckConfig;
import com.alibaba.nacos.plugin.control.Loggers;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* Config param check filter.
*
* @author zhuoguang
*/
public class ConfigParamCheckFilter implements Filter {
private static final String MODULE = "config";
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
boolean paramCheckEnabled = ServerParamCheckConfig.getInstance().isParamCheckEnabled();
if (!paramCheckEnabled) {
chain.doFilter(request, response);
return;
}
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
try {
String uri = req.getRequestURI();
String method = req.getMethod();
HttpParamExtractorManager extractorManager = HttpParamExtractorManager.getInstance();
AbstractHttpParamExtractor paramExtractor = extractorManager.getExtractor(uri, method, MODULE);
List<ParamInfo> paramInfoList = paramExtractor.extractParam(req);
ParamCheckerManager paramCheckerManager = ParamCheckerManager.getInstance();
AbstractParamChecker paramChecker = paramCheckerManager.getParamChecker(ServerParamCheckConfig.getInstance().getActiveParamChecker());
ParamCheckResponse paramCheckResponse = paramChecker.checkParamInfoList(paramInfoList);
if (paramCheckResponse.isSuccess()) {
chain.doFilter(req, resp);
} else {
Loggers.CONTROL.info("Param check invalid,{},url:{}", paramCheckResponse.getMessage(), uri);
generate400Response(resp, paramCheckResponse.getMessage());
}
} catch (Exception e) {
generate400Response(resp, e.getMessage());
}
}
/**
* Generate 400 response.
*
* @param response the response
* @param message the message
*/
public void generate400Response(HttpServletResponse response, String message) {
try {
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache,no-store");
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getOutputStream().println(message);
} catch (Exception ex) {
Loggers.CONTROL.error("Error to generate tps 400 response", ex);
}
}
}

View File

@ -60,7 +60,7 @@ public class CacheItem {
*/
private volatile Map<String, ConfigCache> configCacheTags = null;
public SimpleReadWriteLock rwLock = new SimpleReadWriteLock();
private final SimpleReadWriteLock rwLock = new SimpleReadWriteLock();
public CacheItem(String groupKey, String encryptedDataKey) {
this.groupKey = StringPool.get(groupKey);
@ -104,10 +104,6 @@ public class CacheItem {
return rwLock;
}
public void setRwLock(SimpleReadWriteLock rwLock) {
this.rwLock = rwLock;
}
public String getType() {
return type;
}

View File

@ -0,0 +1,58 @@
/*
* Copyright 1999-2023 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.config.server.paramcheck;
import com.alibaba.nacos.common.paramcheck.ParamInfo;
import com.alibaba.nacos.common.utils.HttpMethod;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.core.paramcheck.AbstractHttpParamExtractor;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
/**
* The type Config blur search http param extractor.
*
* @author zhuoguang
*/
public class ConfigBlurSearchHttpParamExtractor extends AbstractHttpParamExtractor {
private static final String BLUR_SEARCH_MODE = "blur";
@Override
public void init() {
addTargetRequest(Constants.CONFIG_CONTROLLER_PATH, HttpMethod.GET);
addTargetRequest(Constants.CONFIG_CONTROLLER_PATH + "/", HttpMethod.GET);
}
@Override
public List<ParamInfo> extractParam(HttpServletRequest request) throws Exception {
String searchMode = request.getParameter("search");
ArrayList<ParamInfo> paramInfos = new ArrayList<>();
if (StringUtils.equals(searchMode, BLUR_SEARCH_MODE)) {
return paramInfos;
}
ParamInfo paramInfo = new ParamInfo();
paramInfo.setNamespaceId(request.getParameter("tenant"));
paramInfo.setDataId(request.getParameter("dataId"));
paramInfo.setGroup(request.getParameter("group"));
paramInfos.add(paramInfo);
return paramInfos;
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 1999-2023 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.config.server.paramcheck;
import com.alibaba.nacos.common.paramcheck.ParamInfo;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.core.paramcheck.AbstractHttpParamExtractor;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
/**
* Config default http param extractor.
*
* @author zhuoguang
*/
public class ConfigDefaultHttpParamExtractor extends AbstractHttpParamExtractor {
@Override
public void init() {
addDefaultTargetRequest("config");
}
@Override
public List<ParamInfo> extractParam(HttpServletRequest request) {
ParamInfo paramInfo = new ParamInfo();
paramInfo.setNamespaceId(getAliasNamespaceId(request));
paramInfo.setDataId(getAliasDataId(request));
paramInfo.setGroup(getAliasGroup(request));
paramInfo.setIp(getAliasIp(request));
ArrayList<ParamInfo> paramInfos = new ArrayList<>();
paramInfos.add(paramInfo);
return paramInfos;
}
private String getAliasNamespaceId(HttpServletRequest request) {
String namespaceid = request.getParameter("namespaceId");
if (StringUtils.isBlank(namespaceid)) {
namespaceid = request.getParameter("tenant");
}
if (StringUtils.isBlank(namespaceid)) {
namespaceid = request.getParameter("namespace");
}
return namespaceid;
}
private String getAliasDataId(HttpServletRequest request) {
String dataid = request.getParameter("dataId");
return dataid;
}
private String getAliasGroup(HttpServletRequest request) {
String group = request.getParameter("group");
return group;
}
private String getAliasIp(HttpServletRequest request) {
String ip = request.getParameter("ip");
return ip;
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 1999-2023 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.config.server.paramcheck;
import com.alibaba.nacos.common.paramcheck.ParamInfo;
import com.alibaba.nacos.common.utils.HttpMethod;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.core.paramcheck.AbstractHttpParamExtractor;
import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
/**
* ConfigListener http param extractor.
*
* @author zhuoguang
*/
public class ConfigListenerHttpParamExtractor extends AbstractHttpParamExtractor {
static final char WORD_SEPARATOR_CHAR = (char) 2;
static final char LINE_SEPARATOR_CHAR = (char) 1;
@Override
public void init() {
addTargetRequest(Constants.CONFIG_CONTROLLER_PATH + "/listener", HttpMethod.POST);
}
@Override
public List<ParamInfo> extractParam(HttpServletRequest request) throws Exception {
ArrayList<ParamInfo> paramInfos = new ArrayList<>();
String listenConfigs = request.getParameter("Listening-Configs");
if (StringUtils.isBlank(listenConfigs)) {
return paramInfos;
}
listenConfigs = URLDecoder.decode(listenConfigs, Constants.ENCODE);
if (StringUtils.isBlank(listenConfigs)) {
return paramInfos;
}
String[] lines = listenConfigs.split(Character.toString(LINE_SEPARATOR_CHAR));
for (String line : lines) {
ParamInfo paramInfo = new ParamInfo();
String[] words = line.split(Character.toString(WORD_SEPARATOR_CHAR));
if (words.length < 3 || words.length > 4) {
throw new IllegalArgumentException("invalid probeModify");
}
paramInfo.setDataId(words[0]);
paramInfo.setGroup(words[1]);
if (words.length == 4) {
paramInfo.setNamespaceId(words[3]);
}
paramInfos.add(paramInfo);
}
return paramInfos;
}
}

View File

@ -143,6 +143,9 @@ public class ConfigChangeListenContext {
Set<String> connectionIds = groupKeyContext.get(groupKey.getKey());
if (CollectionUtils.isNotEmpty(connectionIds)) {
connectionIds.remove(connectionId);
if (connectionIds.isEmpty()) {
groupKeyContext.remove(groupKey.getKey());
}
} else {
groupKeyContext.remove(groupKey.getKey());
}

View File

@ -23,6 +23,7 @@ import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.notify.listener.Subscriber;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.config.server.configuration.ConfigCommonConfig;
import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent;
import com.alibaba.nacos.config.server.utils.ConfigExecutor;
import com.alibaba.nacos.config.server.utils.GroupKey;
@ -113,7 +114,8 @@ public class RpcConfigChangeNotifier extends Subscriber<LocalDataChangeEvent> {
ConfigChangeNotifyRequest notifyRequest = ConfigChangeNotifyRequest.build(dataId, group, tenant);
RpcPushTask rpcPushRetryTask = new RpcPushTask(notifyRequest, 50, client, clientIp, metaInfo.getAppName());
RpcPushTask rpcPushRetryTask = new RpcPushTask(notifyRequest,
ConfigCommonConfig.getInstance().getMaxPushRetryTimes(), client, clientIp, metaInfo.getAppName());
push(rpcPushRetryTask);
notifyClientCount++;
}

View File

@ -67,7 +67,7 @@ public class AggrWhitelist {
*/
public static void load(String content) {
if (StringUtils.isBlank(content)) {
FATAL_LOG.error("aggr dataId whitelist is blank.");
FATAL_LOG.warn("aggr dataId whitelist is blank.");
return;
}
DEFAULT_LOG.warn("[aggr-dataIds] {}", content);

View File

@ -32,10 +32,8 @@ import com.alibaba.nacos.config.server.utils.DiskUtil;
import com.alibaba.nacos.config.server.utils.GroupKey2;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import com.alibaba.nacos.persistence.configuration.DatasourceConfiguration;
import com.alibaba.nacos.sys.utils.ApplicationUtils;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.ArrayList;
@ -44,8 +42,6 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import static com.alibaba.nacos.config.server.constant.Constants.ENCODE;
import static com.alibaba.nacos.config.server.constant.Constants.ENCODE_GBK;
import static com.alibaba.nacos.config.server.constant.Constants.ENCODE_UTF8;
import static com.alibaba.nacos.config.server.utils.LogUtil.DEFAULT_LOG;
import static com.alibaba.nacos.config.server.utils.LogUtil.DUMP_LOG;
@ -58,24 +54,28 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.FATAL_LOG;
*/
public class ConfigCacheService {
static final Logger LOGGER = LoggerFactory.getLogger(ConfigCacheService.class);
private static final String NO_SPACE_CN = "设备上没有空间";
private static final String NO_SPACE_EN = "No space left on device";
private static final String DISK_QUATA_CN = "超出磁盘限额";
private static final String DISK_QUOTA_CN = "超出磁盘限额";
private static final String DISK_QUATA_EN = "Disk quota exceeded";
private static final String DISK_QUOTA_EN = "Disk quota exceeded";
/**
* groupKey -> cacheItem.
*/
private static final ConcurrentHashMap<String, CacheItem> CACHE = new ConcurrentHashMap<>();
@Autowired
private static ConfigInfoPersistService configInfoPersistService;
public static ConfigInfoPersistService getConfigInfoPersistService() {
if (configInfoPersistService == null) {
configInfoPersistService = ApplicationUtils.getBean(ConfigInfoPersistService.class);
}
return configInfoPersistService;
}
public static int groupCount() {
return CACHE.size();
}
@ -120,7 +120,7 @@ public class ConfigCacheService {
boolean newLastModified = lastModifiedTs > ConfigCacheService.getLastModifiedTs(groupKey);
if (md5 == null) {
md5 = MD5Utils.md5Hex(content, ENCODE);
md5 = MD5Utils.md5Hex(content, ENCODE_UTF8);
}
//check md5 & update local disk cache.
@ -161,8 +161,8 @@ public class ConfigCacheService {
DUMP_LOG.error("[dump-exception] save disk error. " + groupKey + ", " + ioe);
if (ioe.getMessage() != null) {
String errMsg = ioe.getMessage();
if (NO_SPACE_CN.equals(errMsg) || NO_SPACE_EN.equals(errMsg) || errMsg.contains(DISK_QUATA_CN)
|| errMsg.contains(DISK_QUATA_EN)) {
if (NO_SPACE_CN.equals(errMsg) || NO_SPACE_EN.equals(errMsg) || errMsg.contains(DISK_QUOTA_CN)
|| errMsg.contains(DISK_QUOTA_EN)) {
// Protect from disk full.
FATAL_LOG.error("Local Disk Full,Exit", ioe);
System.exit(0);
@ -238,7 +238,7 @@ public class ConfigCacheService {
if (!PropertyUtil.isDirectRead()) {
DUMP_LOG.info(
"[dump-beta] md5 changed, update md5 in local disk cache. groupKey={}, newMd5={}, oldMd5={}",
new Object[] {groupKey, md5, localContentBetaMd5});
groupKey, md5, localContentBetaMd5);
ConfigDiskServiceFactory.getInstance().saveBetaToDisk(dataId, group, tenant, content);
} else {
@ -250,23 +250,23 @@ public class ConfigCacheService {
boolean ipListChanged = !betaIpList.equals(ConfigCacheService.getBetaIps(groupKey));
if (md5Changed) {
DUMP_LOG.info(
"[dump-beta] md5 changed, update md5 & iplist & timestamp in jvm cache. groupKey={}, newMd5={}, oldMd5={}lastModifiedTs={}",
new Object[] {groupKey, md5, localContentBetaMd5, lastModifiedTs});
"[dump-beta] md5 changed, update md5 & ip list & timestamp in jvm cache. groupKey={}, newMd5={}, oldMd5={}lastModifiedTs={}",
groupKey, md5, localContentBetaMd5, lastModifiedTs);
updateBetaMd5(groupKey, md5, betaIpList, lastModifiedTs, encryptedDataKey);
} else if (ipListChanged) {
DUMP_LOG.warn("[dump-beta] ip list changed, update ip list & timestamp in jvm cache. groupKey={},"
+ " newIpList={}, oldIpList={}lastModifiedTs={}",
new Object[] {groupKey, betaIpList, ConfigCacheService.getBetaIps(groupKey), lastModifiedTs});
+ " newIpList={}, oldIpList={}lastModifiedTs={}", groupKey, betaIpList,
ConfigCacheService.getBetaIps(groupKey), lastModifiedTs);
updateBetaIpList(groupKey, betaIpList, lastModifiedTs);
} else if (timestampUpdated) {
DUMP_LOG.warn(
"[dump-beta] timestamp changed, update timestamp in jvm cache. groupKey={}, newLastModifiedTs={}, oldLastModifiedTs={}",
new Object[] {groupKey, lastModifiedTs, ConfigCacheService.getBetaLastModifiedTs(groupKey)});
groupKey, lastModifiedTs, ConfigCacheService.getBetaLastModifiedTs(groupKey));
updateBetaTimeStamp(groupKey, lastModifiedTs);
} else {
DUMP_LOG.warn(
"[dump-beta-ignore] ignore to save jvm cache, md5 & ip list & timestamp no changed. groupKey={}",
new Object[] {groupKey});
groupKey);
}
return true;
} catch (IOException ioe) {
@ -314,7 +314,7 @@ public class ConfigCacheService {
boolean timestampChanged = lastModifiedTs > localTagLastModifiedTs;
final String md5 = MD5Utils.md5Hex(content, ENCODE_GBK);
final String md5 = MD5Utils.md5Hex(content, ENCODE_UTF8);
String localContentTagMd5 = ConfigCacheService.getContentTagMd5(groupKey, tag);
boolean md5Changed = !md5.equals(localContentTagMd5);
@ -328,16 +328,15 @@ public class ConfigCacheService {
}
if (md5Changed) {
String md5Utf8 = MD5Utils.md5Hex(content, ENCODE_UTF8);
DUMP_LOG.warn(
"[dump-tag] md5 changed, update local jvm cache, groupKey={},tag={}, md5UTF8={},oldMd5={},lastModifiedTs={}",
new Object[] {groupKey, tag, md5Utf8, localContentTagMd5, lastModifiedTs});
updateTagMd5(groupKey, tag, md5Utf8, lastModifiedTs, encryptedDataKey4Tag);
"[dump-tag] md5 changed, update local jvm cache, groupKey={},tag={}, newMd5={},oldMd5={},lastModifiedTs={}",
groupKey, tag, md5, localContentTagMd5, lastModifiedTs);
updateTagMd5(groupKey, tag, md5, lastModifiedTs, encryptedDataKey4Tag);
} else if (timestampChanged) {
DUMP_LOG.warn(
"[dump-tag] timestamp changed, update last modified in local jvm cache, groupKey={},tag={},"
+ "tagLastModifiedTs={},oldTagLastModifiedTs={}",
new Object[] {groupKey, tag, lastModifiedTs, localTagLastModifiedTs});
+ "tagLastModifiedTs={},oldTagLastModifiedTs={}", groupKey, tag, lastModifiedTs,
localTagLastModifiedTs);
updateTagTimeStamp(groupKey, tag, lastModifiedTs);
} else {
@ -379,35 +378,33 @@ public class ConfigCacheService {
boolean newLastModified = lastModifiedTs > ConfigCacheService.getLastModifiedTs(groupKey);
String md5Gbk = MD5Utils.md5Hex(content, ENCODE_GBK);
String md5Utf8 = MD5Utils.md5Hex(content, ENCODE_UTF8);
String md5 = MD5Utils.md5Hex(content, ENCODE_UTF8);
//check md5 & update local disk cache.
String localContentMd5 = ConfigCacheService.getContentMd5(groupKey);
boolean md5Changed = !md5Gbk.equals(localContentMd5);
boolean md5Changed = !md5.equals(localContentMd5);
if (md5Changed) {
if (!PropertyUtil.isDirectRead()) {
DUMP_LOG.info("[dump-change] md5 changed, save to disk cache ,groupKey={}, md5={}", groupKey,
md5Gbk);
DUMP_LOG.info("[dump-change] md5 changed, save to disk cache ,groupKey={}, md5={}", groupKey, md5);
ConfigDiskServiceFactory.getInstance().saveToDisk(dataId, group, tenant, content);
} else {
//ignore to save disk cache in direct model
}
} else {
DUMP_LOG.warn("[dump-change-ignore] ignore to save to disk cache. md5 consistent,groupKey={}, md5={}",
groupKey, md5Gbk);
groupKey, md5);
}
//check md5 and timestamp & update local jvm cache.
if (md5Changed) {
DUMP_LOG.info(
"[dump-change] md5 changed, update md5 and timestamp in jvm cache ,groupKey={},newMd5UTF8={},oldMd5={},lastModifiedTs={}",
groupKey, md5Utf8, localContentMd5, lastModifiedTs);
updateMd5(groupKey, md5Utf8, lastModifiedTs, encryptedDataKey);
"[dump-change] md5 changed, update md5 and timestamp in jvm cache ,groupKey={},newMd5={},oldMd5={},lastModifiedTs={}",
groupKey, md5, localContentMd5, lastModifiedTs);
updateMd5(groupKey, md5, lastModifiedTs, encryptedDataKey);
} else if (newLastModified) {
DUMP_LOG.info(
"[dump-change] md5 consistent ,timestamp changed, update timestamp only in jvm cache ,groupKey={}, md5={},lastModifiedTs={}",
groupKey, md5Utf8, lastModifiedTs);
groupKey, md5, lastModifiedTs);
updateTimeStamp(groupKey, lastModifiedTs, encryptedDataKey);
} else {
DUMP_LOG.warn(
@ -431,7 +428,7 @@ public class ConfigCacheService {
String aggreds = null;
try {
if (DatasourceConfiguration.isEmbeddedStorage()) {
ConfigInfoBase config = configInfoPersistService.findConfigInfoBase(AggrWhitelist.AGGRIDS_METADATA,
ConfigInfoBase config = getConfigInfoPersistService().findConfigInfoBase(AggrWhitelist.AGGRIDS_METADATA,
"DEFAULT_GROUP");
if (config != null) {
aggreds = config.getContent();
@ -449,7 +446,7 @@ public class ConfigCacheService {
String clientIpWhitelist = null;
try {
if (DatasourceConfiguration.isEmbeddedStorage()) {
ConfigInfoBase config = configInfoPersistService.findConfigInfoBase(
ConfigInfoBase config = getConfigInfoPersistService().findConfigInfoBase(
ClientIpWhiteList.CLIENT_IP_WHITELIST_METADATA, "DEFAULT_GROUP");
if (config != null) {
clientIpWhitelist = config.getContent();
@ -468,20 +465,20 @@ public class ConfigCacheService {
String switchContent = null;
try {
if (DatasourceConfiguration.isEmbeddedStorage()) {
ConfigInfoBase config = configInfoPersistService.findConfigInfoBase(SwitchService.SWITCH_META_DATAID,
ConfigInfoBase config = getConfigInfoPersistService().findConfigInfoBase(SwitchService.SWITCH_META_DATA_ID,
"DEFAULT_GROUP");
if (config != null) {
switchContent = config.getContent();
}
} else {
switchContent = DiskUtil.getConfig(SwitchService.SWITCH_META_DATAID, "DEFAULT_GROUP",
switchContent = DiskUtil.getConfig(SwitchService.SWITCH_META_DATA_ID, "DEFAULT_GROUP",
StringUtils.EMPTY);
}
if (switchContent != null) {
SwitchService.load(switchContent);
}
} catch (IOException e) {
DUMP_LOG.error("reload fail:" + SwitchService.SWITCH_META_DATAID, e);
DUMP_LOG.error("reload fail:" + SwitchService.SWITCH_META_DATA_ID, e);
}
}
@ -491,7 +488,7 @@ public class ConfigCacheService {
* @return return diff result list.
*/
public static List<String> checkMd5() {
List<String> diffList = new ArrayList<String>();
List<String> diffList = new ArrayList<>();
long startTime = System.currentTimeMillis();
for (Entry<String/* groupKey */, CacheItem> entry : CACHE.entrySet()) {
String groupKey = entry.getKey();
@ -764,7 +761,7 @@ public class ConfigCacheService {
*/
public static List<String> getBetaIps(String groupKey) {
CacheItem item = CACHE.get(groupKey);
return (null != item) ? item.getIps4Beta() : Collections.<String>emptyList();
return (null != item) ? item.getIps4Beta() : Collections.emptyList();
}
public static long getBetaLastModifiedTs(String groupKey) {
@ -836,7 +833,7 @@ public class ConfigCacheService {
*/
public static int tryReadLock(String groupKey) {
CacheItem groupItem = CACHE.get(groupKey);
int result = (null == groupItem) ? 0 : (groupItem.rwLock.tryReadLock() ? 1 : -1);
int result = (null == groupItem) ? 0 : (groupItem.getRwLock().tryReadLock() ? 1 : -1);
if (result < 0) {
DEFAULT_LOG.warn("[read-lock] failed, {}, {}", result, groupKey);
}
@ -851,7 +848,7 @@ public class ConfigCacheService {
public static void releaseReadLock(String groupKey) {
CacheItem item = CACHE.get(groupKey);
if (null != item) {
item.rwLock.releaseReadLock();
item.getRwLock().releaseReadLock();
}
}
@ -864,7 +861,7 @@ public class ConfigCacheService {
*/
static int tryWriteLock(String groupKey) {
CacheItem groupItem = CACHE.get(groupKey);
int result = (null == groupItem) ? 0 : (groupItem.rwLock.tryWriteLock() ? 1 : -1);
int result = (null == groupItem) ? 0 : (groupItem.getRwLock().tryWriteLock() ? 1 : -1);
if (result < 0) {
DEFAULT_LOG.warn("[write-lock] failed, {}, {}", result, groupKey);
}
@ -874,7 +871,7 @@ public class ConfigCacheService {
static void releaseWriteLock(String groupKey) {
CacheItem groupItem = CACHE.get(groupKey);
if (null != groupItem) {
groupItem.rwLock.releaseWriteLock();
groupItem.getRwLock().releaseWriteLock();
}
}

View File

@ -39,7 +39,6 @@ import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@ -345,7 +344,6 @@ public class LongPollingService {
@Override
public void run() {
try {
ConfigCacheService.getContentBetaMd5(groupKey);
for (Iterator<ClientLongPolling> iter = allSubs.iterator(); iter.hasNext(); ) {
ClientLongPolling clientSub = iter.next();
if (clientSub.clientMd5Map.containsKey(groupKey)) {
@ -366,7 +364,7 @@ public class LongPollingService {
RequestUtil
.getRemoteIp((HttpServletRequest) clientSub.asyncContext.getRequest()),
"polling", clientSub.clientMd5Map.size(), clientSub.probeRequestSize, groupKey);
clientSub.sendResponse(Arrays.asList(groupKey));
clientSub.sendResponse(Collections.singletonList(groupKey));
}
}

View File

@ -37,7 +37,7 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.FATAL_LOG;
@Service
public class SwitchService {
public static final String SWITCH_META_DATAID = "com.alibaba.nacos.meta.switch";
public static final String SWITCH_META_DATA_ID = "com.alibaba.nacos.meta.switch";
public static final String FIXED_POLLING = "isFixedPolling";
@ -85,7 +85,7 @@ public class SwitchService {
*/
public static void load(String config) {
if (StringUtils.isBlank(config)) {
FATAL_LOG.error("switch config is blank.");
FATAL_LOG.warn("switch config is blank.");
return;
}
FATAL_LOG.warn("[switch-config] {}", config);
@ -96,7 +96,7 @@ public class SwitchService {
if (!StringUtils.isBlank(line) && !line.startsWith("#")) {
String[] array = line.split("=");
if (array == null || array.length != 2) {
if (array.length != 2) {
LogUtil.FATAL_LOG.error("corrupt switch record {}", line);
continue;
}

View File

@ -43,6 +43,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static com.alibaba.nacos.config.server.utils.LogUtil.FATAL_LOG;
@ -99,7 +100,7 @@ public class GroupCapacityPersistService {
TableConstant.GROUP_CAPACITY);
String sql = groupCapacityMapper.select(
Arrays.asList("id", "quota", "`usage`", "`max_size`", "max_aggr_count", "max_aggr_size", "group_id"),
Arrays.asList("group_id"));
Collections.singletonList("group_id"));
List<GroupCapacity> list = jdbcTemplate.query(sql, new Object[] {groupId}, GROUP_CAPACITY_ROW_MAPPER);
if (list.isEmpty()) {
return null;
@ -374,7 +375,7 @@ public class GroupCapacityPersistService {
TableConstant.GROUP_CAPACITY);
PreparedStatementCreator preparedStatementCreator = connection -> {
PreparedStatement ps = connection.prepareStatement(
groupCapacityMapper.delete(Arrays.asList("group_id")));
groupCapacityMapper.delete(Collections.singletonList("group_id")));
ps.setString(1, group);
return ps;
};

View File

@ -0,0 +1,123 @@
/*
* 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.config.server.service.dump;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.model.ConfigInfo;
import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
import com.alibaba.nacos.config.server.service.ConfigCacheService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService;
import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService;
import com.alibaba.nacos.config.server.utils.GroupKey2;
import com.alibaba.nacos.config.server.utils.LogUtil;
import java.sql.Timestamp;
import java.util.List;
/**
* Dump change processor.
*
* @author Nacos
* @date 2020/7/5 12:19 PM
*/
public class DumpChangeConfigWorker implements Runnable {
private ConfigInfoPersistService configInfoPersistService;
private HistoryConfigInfoPersistService historyConfigInfoPersistService;
Timestamp startTime;
public DumpChangeConfigWorker(DumpService dumpService, Timestamp startTime) {
this.configInfoPersistService = dumpService.getConfigInfoPersistService();
this.historyConfigInfoPersistService = dumpService.getHistoryConfigInfoPersistService();
this.startTime = startTime;
}
/**
* do check change.
*/
public void run() {
try {
Timestamp currentTime = new Timestamp(System.currentTimeMillis());
LogUtil.DEFAULT_LOG.info("DumpChange start ,from time {},current time {}", startTime, currentTime);
LogUtil.DEFAULT_LOG.info("Start to check delete configs from time {}", startTime);
int pageSize = 100;
long startDeletedConfigTime = System.currentTimeMillis();
LogUtil.DEFAULT_LOG.info("Check delete configs from time {}", startTime);
long deleteCursorId = 0L;
while (true) {
List<ConfigInfoWrapper> configDeleted = historyConfigInfoPersistService.findDeletedConfig(startTime,
deleteCursorId, pageSize);
for (ConfigInfo configInfo : configDeleted) {
if (configInfoPersistService.findConfigInfo(configInfo.getDataId(), configInfo.getGroup(),
configInfo.getTenant()) == null) {
ConfigCacheService.remove(configInfo.getDataId(), configInfo.getGroup(),
configInfo.getTenant());
LogUtil.DEFAULT_LOG.info("[dump-delete-ok] {}",
new Object[] {GroupKey2.getKey(configInfo.getDataId(), configInfo.getGroup())});
}
}
if (configDeleted.size() < pageSize) {
break;
}
deleteCursorId = configDeleted.get(configDeleted.size() - 1).getId();
}
LogUtil.DEFAULT_LOG.info("Check delete configs finished,cost:{}",
System.currentTimeMillis() - startDeletedConfigTime);
LogUtil.DEFAULT_LOG.info("Check changeConfig start");
long startChangeConfigTime = System.currentTimeMillis();
long changeCursorId = 0L;
while (true) {
LogUtil.DEFAULT_LOG.info("Check changed configs from time {},lastMaxId={}", startTime, changeCursorId);
List<ConfigInfoWrapper> changeConfigs = configInfoPersistService.findChangeConfig(startTime,
changeCursorId, pageSize);
for (ConfigInfoWrapper cf : changeConfigs) {
ConfigCacheService.dumpChange(cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getContent(),
cf.getLastModified(), cf.getEncryptedDataKey());
final String content = cf.getContent();
final String md5 = MD5Utils.md5Hex(content, Constants.ENCODE_UTF8);
LogUtil.DEFAULT_LOG.info("[dump-change-check-ok] {}, {}, length={}, md5={}",
new Object[] {GroupKey2.getKey(cf.getDataId(), cf.getGroup()), cf.getLastModified(),
content.length(), md5});
}
if (changeConfigs.size() < pageSize) {
break;
}
changeCursorId = changeConfigs.get(changeConfigs.size() - 1).getId();
}
ConfigCacheService.reloadConfig();
long endChangeConfigTime = System.currentTimeMillis();
LogUtil.DEFAULT_LOG.info("Check changed configs finished,cost:{},set next start time to {}",
endChangeConfigTime - startChangeConfigTime, currentTime);
startTime = currentTime;
} catch (Throwable e) {
LogUtil.DEFAULT_LOG.error("Check changed configs error", e);
}
}
}

View File

@ -102,7 +102,7 @@ public class DumpConfigHandler extends Subscriber<ConfigDumpEvent> {
ClientIpWhiteList.load(content);
}
if (dataId.equals(SwitchService.SWITCH_META_DATAID)) {
if (dataId.equals(SwitchService.SWITCH_META_DATA_ID)) {
SwitchService.load(content);
}

View File

@ -17,7 +17,6 @@
package com.alibaba.nacos.config.server.service.dump;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.config.server.constant.Constants;
@ -25,20 +24,14 @@ import com.alibaba.nacos.config.server.manager.TaskManager;
import com.alibaba.nacos.config.server.model.ConfigInfo;
import com.alibaba.nacos.config.server.model.ConfigInfoAggr;
import com.alibaba.nacos.config.server.model.ConfigInfoChanged;
import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
import com.alibaba.nacos.core.namespace.repository.NamespacePersistService;
import com.alibaba.nacos.persistence.model.Page;
import com.alibaba.nacos.config.server.service.ConfigCacheService;
import com.alibaba.nacos.persistence.datasource.DynamicDataSource;
import com.alibaba.nacos.config.server.service.dump.processor.DumpAllBetaProcessor;
import com.alibaba.nacos.config.server.service.dump.processor.DumpAllProcessor;
import com.alibaba.nacos.config.server.service.dump.processor.DumpAllTagProcessor;
import com.alibaba.nacos.config.server.service.dump.processor.DumpChangeProcessor;
import com.alibaba.nacos.config.server.service.dump.processor.DumpProcessor;
import com.alibaba.nacos.config.server.service.dump.task.DumpAllBetaTask;
import com.alibaba.nacos.config.server.service.dump.task.DumpAllTagTask;
import com.alibaba.nacos.config.server.service.dump.task.DumpAllTask;
import com.alibaba.nacos.config.server.service.dump.task.DumpChangeTask;
import com.alibaba.nacos.config.server.service.dump.task.DumpTask;
import com.alibaba.nacos.config.server.service.merge.MergeTaskProcessor;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService;
@ -54,14 +47,15 @@ import com.alibaba.nacos.config.server.utils.GroupKey2;
import com.alibaba.nacos.config.server.utils.LogUtil;
import com.alibaba.nacos.config.server.utils.TimeUtils;
import com.alibaba.nacos.core.cluster.ServerMemberManager;
import com.alibaba.nacos.core.namespace.repository.NamespacePersistService;
import com.alibaba.nacos.persistence.datasource.DynamicDataSource;
import com.alibaba.nacos.persistence.model.Page;
import com.alibaba.nacos.sys.env.EnvUtil;
import com.alibaba.nacos.sys.utils.InetUtils;
import com.alibaba.nacos.sys.utils.TimerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
@ -112,6 +106,11 @@ public abstract class DumpService {
*/
static final int DUMP_ALL_INTERVAL_IN_MINUTE = 6 * 60;
/**
* full dump interval.
*/
static final int DUMP_CHANGE_INTERVAL_IN_SECONDS = 15;
/**
* full dump delay.
*/
@ -227,6 +226,8 @@ public abstract class DumpService {
}
};
Timestamp currentTime = new Timestamp(System.currentTimeMillis());
try {
dumpConfigInfo(dumpAllProcessor);
@ -284,6 +285,9 @@ public abstract class DumpService {
ConfigExecutor.scheduleConfigTask(dumpAllTag, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE,
TimeUnit.MINUTES);
ConfigExecutor.scheduleConfigTask(new DumpChangeConfigWorker(this, currentTime), 0,
DUMP_CHANGE_INTERVAL_IN_SECONDS, TimeUnit.SECONDS);
}
ConfigExecutor.scheduleConfigTask(clearConfigHistory, 10, 10, TimeUnit.MINUTES);
@ -294,60 +298,14 @@ public abstract class DumpService {
}
private void dumpConfigInfo(DumpAllProcessor dumpAllProcessor) throws IOException {
int timeStep = 6;
boolean isAllDump = true;
// initial dump all
FileInputStream fis = null;
Timestamp heartheatLastStamp = null;
try {
if (isQuickStart()) {
File heartbeatFile = DiskUtil.heartBeatFile();
if (heartbeatFile.exists()) {
fis = new FileInputStream(heartbeatFile);
String heartheatTempLast = IoUtils.toString(fis, Constants.ENCODE);
heartheatLastStamp = Timestamp.valueOf(heartheatTempLast);
if (TimeUtils.getCurrentTime().getTime() - heartheatLastStamp.getTime()
< timeStep * 60 * 60 * 1000) {
isAllDump = false;
}
}
}
if (isAllDump) {
LogUtil.DEFAULT_LOG.info("start clear all config-info.");
DiskUtil.clearAll();
dumpAllProcessor.process(new DumpAllTask());
} else {
Timestamp beforeTimeStamp = getBeforeStamp(heartheatLastStamp, timeStep);
DumpChangeProcessor dumpChangeProcessor = new DumpChangeProcessor(this, beforeTimeStamp,
TimeUtils.getCurrentTime());
dumpChangeProcessor.process(new DumpChangeTask());
Runnable checkMd5Task = () -> {
LogUtil.DEFAULT_LOG.error("start checkMd5Task");
List<String> diffList = ConfigCacheService.checkMd5();
for (String groupKey : diffList) {
String[] dg = GroupKey.parseKey(groupKey);
String dataId = dg[0];
String group = dg[1];
String tenant = dg[2];
ConfigInfoWrapper configInfo = configInfoPersistService.queryConfigInfo(dataId, group, tenant);
ConfigCacheService.dumpChange(dataId, group, tenant, configInfo.getContent(),
configInfo.getLastModified(), configInfo.getEncryptedDataKey());
}
LogUtil.DEFAULT_LOG.error("end checkMd5Task");
};
ConfigExecutor.scheduleConfigTask(checkMd5Task, 0, 12, TimeUnit.HOURS);
}
} catch (IOException e) {
LogUtil.DEFAULT_LOG.info("start clear all config-info.");
DiskUtil.clearAll();
dumpAllProcessor.process(new DumpAllTask());
} catch (Exception e) {
LogUtil.FATAL_LOG.error("dump config fail" + e.getMessage());
throw e;
} finally {
if (null != fis) {
try {
fis.close();
} catch (IOException e) {
LogUtil.DEFAULT_LOG.warn("close file failed");
}
}
}
}
@ -360,20 +318,6 @@ public abstract class DumpService {
return Timestamp.valueOf(format.format(cal.getTime()));
}
private Boolean isQuickStart() {
try {
String val;
val = EnvUtil.getProperty("isQuickStart");
if (TRUE_STR.equals(val)) {
isQuickStart = true;
}
FATAL_LOG.warn("isQuickStart:{}", isQuickStart);
} catch (Exception e) {
FATAL_LOG.error("read application.properties wrong", e);
}
return isQuickStart;
}
private int getRetentionDays() {
String val = EnvUtil.getProperty("nacos.config.retention.days");
if (null == val) {

View File

@ -64,7 +64,7 @@ public class DumpAllProcessor implements NacosTaskProcessor {
ClientIpWhiteList.load(cf.getContent());
}
if (cf.getDataId().equals(SwitchService.SWITCH_META_DATAID)) {
if (cf.getDataId().equals(SwitchService.SWITCH_META_DATA_ID)) {
SwitchService.load(cf.getContent());
}

View File

@ -1,109 +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.config.server.service.dump.processor;
import com.alibaba.nacos.common.task.NacosTask;
import com.alibaba.nacos.common.task.NacosTaskProcessor;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.model.ConfigInfo;
import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
import com.alibaba.nacos.config.server.service.ConfigCacheService;
import com.alibaba.nacos.config.server.service.dump.DumpService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService;
import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService;
import com.alibaba.nacos.config.server.utils.GroupKey2;
import com.alibaba.nacos.config.server.utils.LogUtil;
import java.sql.Timestamp;
import java.util.List;
/**
* Dump change processor.
*
* @author Nacos
* @date 2020/7/5 12:19 PM
*/
public class DumpChangeProcessor implements NacosTaskProcessor {
final DumpService dumpService;
final ConfigInfoPersistService configInfoPersistService;
final HistoryConfigInfoPersistService historyConfigInfoPersistService;
final Timestamp startTime;
final Timestamp endTime;
public DumpChangeProcessor(DumpService dumpService, Timestamp startTime, Timestamp endTime) {
this.dumpService = dumpService;
this.configInfoPersistService = dumpService.getConfigInfoPersistService();
this.historyConfigInfoPersistService = dumpService.getHistoryConfigInfoPersistService();
this.startTime = startTime;
this.endTime = endTime;
}
@Override
public boolean process(NacosTask task) {
LogUtil.DEFAULT_LOG.warn("quick start; startTime:{},endTime:{}", startTime, endTime);
LogUtil.DEFAULT_LOG.warn("updateMd5 start");
long startUpdateMd5 = System.currentTimeMillis();
List<ConfigInfoWrapper> updateMd5List = configInfoPersistService.listAllGroupKeyMd5();
LogUtil.DEFAULT_LOG.warn("updateMd5 count:{}", updateMd5List.size());
for (ConfigInfoWrapper config : updateMd5List) {
final String groupKey = GroupKey2.getKey(config.getDataId(), config.getGroup());
ConfigCacheService
.updateMd5(groupKey, config.getMd5(), config.getLastModified(), config.getEncryptedDataKey());
}
long endUpdateMd5 = System.currentTimeMillis();
LogUtil.DEFAULT_LOG.warn("updateMd5 done,cost:{}", endUpdateMd5 - startUpdateMd5);
LogUtil.DEFAULT_LOG.warn("deletedConfig start");
long startDeletedConfigTime = System.currentTimeMillis();
List<ConfigInfo> configDeleted = historyConfigInfoPersistService.findDeletedConfig(startTime, endTime);
LogUtil.DEFAULT_LOG.warn("deletedConfig count:{}", configDeleted.size());
for (ConfigInfo configInfo : configDeleted) {
if (configInfoPersistService.findConfigInfo(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant())
== null) {
ConfigCacheService.remove(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant());
}
}
long endDeletedConfigTime = System.currentTimeMillis();
LogUtil.DEFAULT_LOG.warn("deletedConfig done,cost:{}", endDeletedConfigTime - startDeletedConfigTime);
LogUtil.DEFAULT_LOG.warn("changeConfig start");
final long startChangeConfigTime = System.currentTimeMillis();
List<ConfigInfoWrapper> changeConfigs = configInfoPersistService.findChangeConfig(startTime, endTime);
LogUtil.DEFAULT_LOG.warn("changeConfig count:{}", changeConfigs.size());
for (ConfigInfoWrapper cf : changeConfigs) {
ConfigCacheService.dumpChange(cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getContent(),
cf.getLastModified(), cf.getEncryptedDataKey());
final String content = cf.getContent();
final String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
LogUtil.DEFAULT_LOG
.info("[dump-change-ok] {}, {}, length={}, md5={}", GroupKey2.getKey(cf.getDataId(), cf.getGroup()),
cf.getLastModified(), content.length(), md5);
}
ConfigCacheService.reloadConfig();
long endChangeConfigTime = System.currentTimeMillis();
LogUtil.DEFAULT_LOG.warn("changeConfig done,cost:{}", endChangeConfigTime - startChangeConfigTime);
return true;
}
}

View File

@ -18,9 +18,10 @@ package com.alibaba.nacos.config.server.service.dump.processor;
import com.alibaba.nacos.common.task.NacosTask;
import com.alibaba.nacos.common.task.NacosTaskProcessor;
import com.alibaba.nacos.config.server.model.ConfigInfo;
import com.alibaba.nacos.config.server.model.ConfigInfo4Beta;
import com.alibaba.nacos.config.server.model.ConfigInfo4Tag;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper;
import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper;
import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
import com.alibaba.nacos.config.server.model.event.ConfigDumpEvent;
import com.alibaba.nacos.config.server.service.dump.DumpConfigHandler;
import com.alibaba.nacos.config.server.service.dump.DumpService;
@ -29,7 +30,7 @@ import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistS
import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService;
import com.alibaba.nacos.config.server.utils.GroupKey2;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.config.server.utils.LogUtil;
import java.util.Objects;
@ -63,39 +64,50 @@ public class DumpProcessor implements NacosTaskProcessor {
String dataId = pair[0];
String group = pair[1];
String tenant = pair[2];
long lastModified = dumpTask.getLastModified();
long lastModifiedOut = dumpTask.getLastModified();
String handleIp = dumpTask.getHandleIp();
boolean isBeta = dumpTask.isBeta();
String tag = dumpTask.getTag();
boolean isBatch = dumpTask.isBatch();
ConfigDumpEvent.ConfigDumpEventBuilder build = ConfigDumpEvent.builder().namespaceId(tenant).dataId(dataId)
.group(group).isBeta(isBeta).tag(tag).lastModifiedTs(lastModified).handleIp(handleIp);
.group(group).isBatch(isBatch).isBeta(isBeta).tag(tag).handleIp(handleIp);
String type = "formal";
if (isBeta) {
type = "beta";
} else if (StringUtils.isNotBlank(tag)) {
type = "tag-" + tag;
}
LogUtil.DUMP_LOG.info("[dump] process {} task. groupKey={}", type, dumpTask.getGroupKey());
if (isBeta) {
// if publish beta, then dump config, update beta cache
ConfigInfo4Beta cf = configInfoBetaPersistService.findConfigInfo4Beta(dataId, group, tenant);
ConfigInfoBetaWrapper cf = configInfoBetaPersistService.findConfigInfo4Beta(dataId, group, tenant);
build.remove(Objects.isNull(cf));
build.betaIps(Objects.isNull(cf) ? null : cf.getBetaIps());
build.content(Objects.isNull(cf) ? null : cf.getContent());
build.type(Objects.isNull(cf) ? null : cf.getType());
build.encryptedDataKey(Objects.isNull(cf) ? null : cf.getEncryptedDataKey());
build.lastModifiedTs(Objects.isNull(cf) ? lastModifiedOut : cf.getLastModified());
return DumpConfigHandler.configDump(build.build());
}
if (StringUtils.isBlank(tag)) {
ConfigInfo cf = configInfoPersistService.findConfigInfo(dataId, group, tenant);
if (StringUtils.isNotBlank(tag)) {
ConfigInfoTagWrapper cf = configInfoTagPersistService.findConfigInfo4Tag(dataId, group, tenant, tag);
build.remove(Objects.isNull(cf));
build.content(Objects.isNull(cf) ? null : cf.getContent());
build.type(Objects.isNull(cf) ? null : cf.getType());
build.encryptedDataKey(Objects.isNull(cf) ? null : cf.getEncryptedDataKey());
} else {
ConfigInfo4Tag cf = configInfoTagPersistService.findConfigInfo4Tag(dataId, group, tenant, tag);
build.remove(Objects.isNull(cf));
build.content(Objects.isNull(cf) ? null : cf.getContent());
build.lastModifiedTs(Objects.isNull(cf) ? lastModifiedOut : cf.getLastModified());
return DumpConfigHandler.configDump(build.build());
}
ConfigInfoWrapper cf = configInfoPersistService.findConfigInfo(dataId, group, tenant);
build.remove(Objects.isNull(cf));
build.content(Objects.isNull(cf) ? null : cf.getContent());
build.type(Objects.isNull(cf) ? null : cf.getType());
build.encryptedDataKey(Objects.isNull(cf) ? null : cf.getEncryptedDataKey());
build.lastModifiedTs(Objects.isNull(cf) ? lastModifiedOut : cf.getLastModified());
return DumpConfigHandler.configDump(build.build());
}
}

View File

@ -433,13 +433,14 @@ public interface ConfigInfoPersistService {
final String group, final String content) throws IOException;
/**
* Query change config.
* Query change config.order by id asc.
*
* @param startTime start time
* @param endTime end time
* @param lastMaxId lastMaxId
* @param pageSize pageSize
* @return {@link ConfigInfoWrapper} list
*/
List<ConfigInfoWrapper> findChangeConfig(final Timestamp startTime, final Timestamp endTime);
List<ConfigInfoWrapper> findChangeConfig(final Timestamp startTime, long lastMaxId, final int pageSize);
/**
* According to the time period and configuration conditions to query the eligible configuration.

View File

@ -74,12 +74,15 @@ public class ConfigRowMapperInjector {
public static final ConfigHistoryRowMapper HISTORY_LIST_ROW_MAPPER = new ConfigHistoryRowMapper();
public static final ConfigHistoryDetailRowMapper HISTORY_DETAIL_ROW_MAPPER = new ConfigHistoryDetailRowMapper();
public ConfigRowMapperInjector() {
static {
injectConfigRowMapper();
}
private void injectConfigRowMapper() {
public ConfigRowMapperInjector() {
}
private static void injectConfigRowMapper() {
// CONFIG_INFO_WRAPPER_ROW_MAPPER
RowMapperManager

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.config.server.service.repository;
import com.alibaba.nacos.config.server.model.ConfigHistoryInfo;
import com.alibaba.nacos.config.server.model.ConfigInfo;
import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
import com.alibaba.nacos.persistence.model.Page;
import com.alibaba.nacos.persistence.repository.PaginationHelper;
@ -46,7 +47,7 @@ public interface HistoryConfigInfoPersistService {
* @param list origin data
* @return {@link ConfigInfo} list
*/
List<ConfigInfo> convertDeletedConfig(List<Map<String, Object>> list);
List<ConfigInfoWrapper> convertDeletedConfig(List<Map<String, Object>> list);
//------------------------------------------insert---------------------------------------------//
@ -78,10 +79,11 @@ public interface HistoryConfigInfoPersistService {
* Query deleted config.
*
* @param startTime start time
* @param endTime end time
* @param startId last max id
* @param size page size
* @return {@link ConfigInfo} list
*/
List<ConfigInfo> findDeletedConfig(final Timestamp startTime, final Timestamp endTime);
List<ConfigInfoWrapper> findDeletedConfig(final Timestamp startTime, final long startId, int size);
/**
* List configuration history change record.

View File

@ -301,7 +301,7 @@ public interface PersistService {
Map<String, Object> configAdvanceInfo, boolean notify);
/**
* insert or update cas..
* insert or update cas.
*
* @param srcIp remote ip
* @param srcUser user
@ -591,7 +591,7 @@ public interface PersistService {
/**
* Returns the number of beta configuration items.
*
* @return number of configuration items..
* @return number of configuration items.
*/
@Deprecated
int configInfoBetaCount();
@ -599,7 +599,7 @@ public interface PersistService {
/**
* Returns the number of beta configuration items.
*
* @return number of configuration items..
* @return number of configuration items.
*/
@Deprecated
int configInfoTagCount();
@ -703,8 +703,8 @@ public interface PersistService {
/**
* Query all tag config info for dump task.
*
* @param pageNo page numbser
* @param pageSize page sizxe
* @param pageNo page numbers
* @param pageSize page size
* @return {@link Page} with {@link ConfigInfoWrapper} generation
*/
@Deprecated
@ -1050,19 +1050,19 @@ public interface PersistService {
/**
* insert tenant info.
*
* @param kp kp
* @param tenantId tenant Id
* @param tenantName tenant name
* @param tenantDesc tenant description
* @param createResoure create resouce
* @param time time
* @param kp kp
* @param tenantId tenant Id
* @param tenantName tenant name
* @param tenantDesc tenant description
* @param createResource create resource
* @param time time
*/
@Deprecated
void insertTenantInfoAtomic(String kp, String tenantId, String tenantName, String tenantDesc, String createResoure,
void insertTenantInfoAtomic(String kp, String tenantId, String tenantName, String tenantDesc, String createResource,
final long time);
/**
* Update tenantInfo showname.
* Update tenantInfo show name.
*
* @param kp kp
* @param tenantId tenant Id

View File

@ -342,7 +342,7 @@ public class EmbeddedConfigInfoAggrPersistServiceImpl implements ConfigInfoAggrP
ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(),
TableConstant.CONFIG_INFO_AGGR);
final int startRow = (pageNo - 1) * pageSize;
final String sqlCountRows = configInfoAggrMapper.select(Arrays.asList("count(*)"),
final String sqlCountRows = configInfoAggrMapper.select(Collections.singletonList("count(*)"),
Arrays.asList("data_id", "group_id", "tenant_id"));
MapperContext context = new MapperContext();

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