Merge remote-tracking branch 'upstream/develop' into issue#5696-merge-develop

# Conflicts:
#	auth/src/main/java/com/alibaba/nacos/auth/common/AuthConfigs.java
#	client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java
#	client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingMaintainService.java
#	client/src/main/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxy.java
#	client/src/main/java/com/alibaba/nacos/client/naming/remote/NamingClientProxyDelegate.java
#	client/src/test/java/com/alibaba/nacos/client/naming/remote/AbstractNamingClientProxyTest.java
This commit is contained in:
KomachiSion 2022-01-12 16:52:14 +08:00
commit 78de31dbdd
435 changed files with 16343 additions and 34817 deletions

View File

@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
java: [8, 11]
java: [8, 8.0.192, 11, 11.0.3]
steps:
- name: Cache Maven Repos
uses: actions/cache@v2
@ -29,7 +29,7 @@ jobs:
uses: actions/setup-java@v2
with:
java-version: ${{ matrix.java }}
distribution: 'adopt'
distribution: 'zulu'
architecture: x64
- name: Test Config
run: mvn clean package -Pcit-test

3
.gitignore vendored
View File

@ -1,4 +1,4 @@
# Except this file !.gitignore
# Except this file !.gitignore
.classpath
.project
.settings
@ -9,6 +9,7 @@ target
.factorypath
/logs
*.iml
*.log
node_modules
test/derby.log
derby.log

View File

@ -36,6 +36,15 @@ Nacos provides four major functions.
## Quick Start
It is super easy to get started with your first project.
### Deploying Nacos on cloud
You can deploy Nacos on cloud, which is the easiest and most convenient way to start Nacos.
Use the following [Nacos deployment guide](https://cn.aliyun.com/product/aliware/mse?spm=nacos-website.topbar.0.0.0) to see more information and deploy a stable and out-of-the-box Nacos server.
### Start by the provided startup package
#### Step 1: Download the binary package
You can download the package from the [latest stable release](https://github.com/alibaba/nacos/releases).
@ -76,11 +85,21 @@ You can view the full documentation from the [Nacos website](https://nacos.io/en
All the latest and long-term notice can also be found here from [Github notice issue](https://github.com/alibaba/nacos/labels/notice).
## Contributing
Contributors are welcomed to join Nacos project. Please check [CONTRIBUTING](./CONTRIBUTING.md) about how to contribute to this project.
### How can I contribute?
* Take a look at issues with tags marked [`good first issue`](https://github.com/alibaba/nacos/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) or [`contribution welcome`](https://github.com/alibaba/nacos/issues?q=is%3Aopen+is%3Aissue+label%3A%22contribution+welcome%22).
* Answer questions on [issues](https://github.com/alibaba/nacos/issues).
* Fix bugs reported on [issues](https://github.com/alibaba/nacos/issues), and send us a pull request.
* Review the existing [pull request](https://github.com/alibaba/nacos/pulls).
* Improve the [website](https://github.com/nacos-group/nacos-group.github.io), typically we need
* blog post
* translation on documentation
* use cases around the integration of Nacos in enterprise systems.
## Other Related Project Repositories
* [nacos-spring-project](https://github.com/nacos-group/nacos-spring-project) provides the integration functionality for Spring.
@ -101,12 +120,17 @@ Contributors are welcomed to join Nacos project. Please check [CONTRIBUTING](./C
![Nacos](https://nacos.io/img/nacos_dingding.jpg)
## Enterprise Service
If you need Nacos enterprise service support, or purchase cloud product services, you can join the discussion by scanning the following DingTalk group. It can also be directly activated and used through the microservice engine (MSE) provided by Alibaba Cloud.
https://cn.aliyun.com/product/aliware/mse?spm=nacos-website.topbar.0.0.0
![image](https://user-images.githubusercontent.com/17695352/128659442-65b030b8-c5f4-4bb7-baa2-e5b3ef0cbc15.png)
## Download
- [Github Release](https://github.com/alibaba/nacos/releases)
- [Baidu Netdisk](https://pan.baidu.com/s/1186nmlqPGows9gUZKAx8Zw) Fetch Code : `rest`
## Who is using
These are only part of the companies using Nacos, for reference only. If you are using Nacos, please [add your company here](https://github.com/alibaba/nacos/issues/273) to tell us your scenario to make Nacos better.

View File

@ -33,7 +33,7 @@ public class AddressServerManager {
public String getRawProductName(String name) {
if (StringUtils.isBlank(name) || AddressServerConstants.DEFAULT_PRODUCT.equals(name)) {
if (StringUtils.isBlank(name)) {
return AddressServerConstants.DEFAULT_PRODUCT;
}
@ -50,7 +50,7 @@ public class AddressServerManager {
*/
public String getDefaultClusterNameIfEmpty(String name) {
if (StringUtils.isEmpty(name) || AddressServerConstants.DEFAULT_GET_CLUSTER.equals(name)) {
if (StringUtils.isEmpty(name)) {
return AddressServerConstants.DEFAULT_GET_CLUSTER;
}

View File

@ -0,0 +1,44 @@
/*
* 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.address.component;
import com.alibaba.nacos.address.constant.AddressServerConstants;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class AddressServerManagerTests {
private static final AddressServerManager ADDRESS_SERVER_MANAGER = new AddressServerManager();
@Test
public void getRawProductName() {
assertEquals(AddressServerConstants.DEFAULT_PRODUCT, ADDRESS_SERVER_MANAGER.getRawProductName(""));
assertEquals(AddressServerConstants.DEFAULT_PRODUCT,
ADDRESS_SERVER_MANAGER.getRawProductName(AddressServerConstants.DEFAULT_PRODUCT));
assertEquals("otherProduct", ADDRESS_SERVER_MANAGER.getRawProductName("otherProduct"));
}
@Test
public void getDefaultClusterNameIfEmpty() {
assertEquals(AddressServerConstants.DEFAULT_GET_CLUSTER, ADDRESS_SERVER_MANAGER.getDefaultClusterNameIfEmpty(""));
assertEquals(AddressServerConstants.DEFAULT_GET_CLUSTER,
ADDRESS_SERVER_MANAGER.getDefaultClusterNameIfEmpty(AddressServerConstants.DEFAULT_GET_CLUSTER));
assertEquals("otherServerList", ADDRESS_SERVER_MANAGER.getDefaultClusterNameIfEmpty("otherServerList"));
}
}

View File

@ -89,11 +89,6 @@
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>

View File

@ -16,8 +16,11 @@
package com.alibaba.nacos.api.ability;
import com.alibaba.nacos.api.config.ClientConfigAbility;
import com.alibaba.nacos.api.naming.ClientNamingAbility;
import com.alibaba.nacos.api.config.ability.ClientConfigAbility;
import com.alibaba.nacos.api.naming.ability.ClientNamingAbility;
import com.alibaba.nacos.api.remote.ability.ClientRemoteAbility;
import java.io.Serializable;
/**
* abilities of nacos client.
@ -25,7 +28,9 @@ import com.alibaba.nacos.api.naming.ClientNamingAbility;
* @author liuzunfei
* @version $Id: ClientAbilities.java, v 0.1 2021年01月24日 00:09 AM liuzunfei Exp $
*/
public class ClientAbilities {
public class ClientAbilities implements Serializable {
private static final long serialVersionUID = -3590789441404549261L;
private ClientRemoteAbility remoteAbility = new ClientRemoteAbility();

View File

@ -16,8 +16,9 @@
package com.alibaba.nacos.api.ability;
import com.alibaba.nacos.api.config.ServerConfigAbility;
import com.alibaba.nacos.api.naming.ServerNamingAbility;
import com.alibaba.nacos.api.config.ability.ServerConfigAbility;
import com.alibaba.nacos.api.naming.ability.ServerNamingAbility;
import com.alibaba.nacos.api.remote.ability.ServerRemoteAbility;
import java.io.Serializable;
import java.util.Objects;
@ -30,6 +31,8 @@ import java.util.Objects;
*/
public class ServerAbilities implements Serializable {
private static final long serialVersionUID = -2120543002911304171L;
private ServerRemoteAbility remoteAbility = new ServerRemoteAbility();
private ServerConfigAbility configAbility = new ServerConfigAbility();

View File

@ -0,0 +1,32 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.api.ability.initializer;
/**
* Nacos ability initializer.
*
* @author xiweng.yy
*/
public interface AbilityInitializer<A> {
/**
* Initialize target type abilities content.
*
* @param abilities abilities
*/
void initialize(A abilities);
}

View File

@ -209,4 +209,42 @@ public class Constants {
public static final String LOCATION_TAG = "Location-Tag";
public static final String CHARSET_KEY = "charset";
/**
* The constants in config directory.
*/
public static class Config {
public static final String CONFIG_MODULE = "config";
public static final String NOTIFY_HEADER = "notify";
}
/**
* The constants in naming directory.
*/
public static class Naming {
public static final String NAMING_MODULE = "naming";
public static final String CMDB_CONTEXT_TYPE = "CMDB";
}
/**
* The constants in remote directory.
*/
public static class Remote {
public static final String INTERNAL_MODULE = "internal";
}
/**
* The constants in exception directory.
*/
public static class Exception {
public static final int DESERIALIZE_ERROR_CODE = 101;
public static final int SERIALIZE_ERROR_CODE = 100;
}
}

View File

@ -52,7 +52,7 @@ public class ConfigFactory {
*
* @param serverAddr serverList
* @return Config
* @throws ConfigService Exception
* @throws NacosException create configService failed Exception
*/
public static ConfigService createConfigService(String serverAddr) throws NacosException {
Properties properties = new Properties();

View File

@ -95,6 +95,6 @@ public enum ConfigType {
if (StringUtils.isBlank(type)) {
return false;
}
return null != LOCAL_MAP.get(type) ? true : false;
return null != LOCAL_MAP.get(type);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.alibaba.nacos.api.config;
package com.alibaba.nacos.api.config.ability;
/**
* config abilities of nacos client.

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.alibaba.nacos.api.config;
package com.alibaba.nacos.api.config.ability;
import java.io.Serializable;
import java.util.Objects;

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.api.config.remote.request;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.remote.request.Request;
/**
@ -24,11 +25,9 @@ import com.alibaba.nacos.api.remote.request.Request;
* @version $Id: ConfigCommonRequest.java, v 0.1 2020年07月13日 9:05 PM liuzunfei Exp $
*/
public abstract class AbstractConfigRequest extends Request {
private static final String MODULE = "config";
@Override
public String getModule() {
return MODULE;
return Constants.Config.CONFIG_MODULE;
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.api.config.remote.request;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.remote.request.ServerRequest;
import java.io.Serializable;
@ -31,13 +32,11 @@ import java.util.Objects;
*/
public class ClientConfigMetricRequest extends ServerRequest {
private static final String MODULE = "config";
private List<MetricsKey> metricsKeys = new ArrayList<MetricsKey>();
private List<MetricsKey> metricsKeys = new ArrayList<>();
@Override
public String getModule() {
return MODULE;
return Constants.Config.CONFIG_MODULE;
}
public List<MetricsKey> getMetricsKeys() {

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.api.config.remote.request;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.remote.request.ServerRequest;
/**
@ -26,8 +27,6 @@ import com.alibaba.nacos.api.remote.request.ServerRequest;
*/
public class ConfigChangeNotifyRequest extends ServerRequest {
private static final String MODULE = "config";
String dataId;
String group;
@ -76,6 +75,6 @@ public class ConfigChangeNotifyRequest extends ServerRequest {
@Override
public String getModule() {
return MODULE;
return Constants.Config.CONFIG_MODULE;
}
}

View File

@ -61,7 +61,7 @@ public class ConfigPublishRequest extends AbstractConfigRequest {
*/
public void putAdditionalParam(String key, String value) {
if (additionMap == null) {
additionMap = new HashMap<String, String>(2);
additionMap = new HashMap<>(2);
}
additionMap.put(key, value);
}

View File

@ -16,6 +16,8 @@
package com.alibaba.nacos.api.config.remote.request;
import com.alibaba.nacos.api.common.Constants;
/**
* request to query config content.
*
@ -24,8 +26,6 @@ package com.alibaba.nacos.api.config.remote.request;
*/
public class ConfigQueryRequest extends AbstractConfigRequest {
private static final String NOTIFY_HEADER = "notify";
private String dataId;
private String group;
@ -123,7 +123,7 @@ public class ConfigQueryRequest extends AbstractConfigRequest {
}
public boolean isNotify() {
String notify = getHeader(NOTIFY_HEADER, Boolean.FALSE.toString());
String notify = getHeader(Constants.Config.NOTIFY_HEADER, Boolean.FALSE.toString());
return Boolean.parseBoolean(notify);
}
}

View File

@ -148,6 +148,11 @@ public class NacosException extends Exception {
*/
public static final int SERVER_ERROR = 500;
/**
* client errorclient异常返回给服务端.
*/
public static final int CLIENT_ERROR = -500;
/**
* bad gateway路由异常如nginx后面的Server挂掉.
*/

View File

@ -18,6 +18,8 @@ package com.alibaba.nacos.api.exception.runtime;
import java.lang.reflect.Type;
import static com.alibaba.nacos.api.common.Constants.Exception.DESERIALIZE_ERROR_CODE;
/**
* Nacos deserialization exception.
*
@ -25,8 +27,6 @@ import java.lang.reflect.Type;
*/
public class NacosDeserializationException extends NacosRuntimeException {
public static final int ERROR_CODE = 101;
private static final long serialVersionUID = -2742350751684273728L;
private static final String DEFAULT_MSG = "Nacos deserialize failed. ";
@ -36,29 +36,29 @@ public class NacosDeserializationException extends NacosRuntimeException {
private Class<?> targetClass;
public NacosDeserializationException() {
super(ERROR_CODE);
super(DESERIALIZE_ERROR_CODE);
}
public NacosDeserializationException(Class<?> targetClass) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetClass.getName()));
super(DESERIALIZE_ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetClass.getName()));
this.targetClass = targetClass;
}
public NacosDeserializationException(Type targetType) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetType.toString()));
super(DESERIALIZE_ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetType.toString()));
}
public NacosDeserializationException(Throwable throwable) {
super(ERROR_CODE, DEFAULT_MSG, throwable);
super(DESERIALIZE_ERROR_CODE, DEFAULT_MSG, throwable);
}
public NacosDeserializationException(Class<?> targetClass, Throwable throwable) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetClass.getName()), throwable);
super(DESERIALIZE_ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetClass.getName()), throwable);
this.targetClass = targetClass;
}
public NacosDeserializationException(Type targetType, Throwable throwable) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetType.toString()), throwable);
super(DESERIALIZE_ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetType.toString()), throwable);
}
public Class<?> getTargetClass() {

View File

@ -16,6 +16,8 @@
package com.alibaba.nacos.api.exception.runtime;
import static com.alibaba.nacos.api.common.Constants.Exception.SERIALIZE_ERROR_CODE;
/**
* Nacos serialization exception.
*
@ -23,8 +25,6 @@ package com.alibaba.nacos.api.exception.runtime;
*/
public class NacosSerializationException extends NacosRuntimeException {
public static final int ERROR_CODE = 100;
private static final long serialVersionUID = -4308536346316915612L;
private static final String DEFAULT_MSG = "Nacos serialize failed. ";
@ -34,20 +34,20 @@ public class NacosSerializationException extends NacosRuntimeException {
private Class<?> serializedClass;
public NacosSerializationException() {
super(ERROR_CODE);
super(SERIALIZE_ERROR_CODE);
}
public NacosSerializationException(Class<?> serializedClass) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, serializedClass.getName()));
super(SERIALIZE_ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, serializedClass.getName()));
this.serializedClass = serializedClass;
}
public NacosSerializationException(Throwable throwable) {
super(ERROR_CODE, DEFAULT_MSG, throwable);
super(SERIALIZE_ERROR_CODE, DEFAULT_MSG, throwable);
}
public NacosSerializationException(Class<?> serializedClass, Throwable throwable) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, serializedClass.getName()), throwable);
super(SERIALIZE_ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, serializedClass.getName()), throwable);
this.serializedClass = serializedClass;
}

View File

@ -1,298 +0,0 @@
/*
* Copyright 1999-2020 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.api.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)",
comments = "Source: nacos_grpc_service.proto")
public final class RequestStreamGrpc {
private RequestStreamGrpc() {}
public static final String SERVICE_NAME = "RequestStream";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<com.alibaba.nacos.api.grpc.auto.Payload,
com.alibaba.nacos.api.grpc.auto.Payload> getRequestStreamMethod;
@io.grpc.stub.annotations.RpcMethod(
fullMethodName = SERVICE_NAME + '/' + "requestStream",
requestType = com.alibaba.nacos.api.grpc.auto.Payload.class,
responseType = com.alibaba.nacos.api.grpc.auto.Payload.class,
methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
public static io.grpc.MethodDescriptor<com.alibaba.nacos.api.grpc.auto.Payload,
com.alibaba.nacos.api.grpc.auto.Payload> getRequestStreamMethod() {
io.grpc.MethodDescriptor<com.alibaba.nacos.api.grpc.auto.Payload, com.alibaba.nacos.api.grpc.auto.Payload> getRequestStreamMethod;
if ((getRequestStreamMethod = RequestStreamGrpc.getRequestStreamMethod) == null) {
synchronized (RequestStreamGrpc.class) {
if ((getRequestStreamMethod = RequestStreamGrpc.getRequestStreamMethod) == null) {
RequestStreamGrpc.getRequestStreamMethod = getRequestStreamMethod =
io.grpc.MethodDescriptor.<com.alibaba.nacos.api.grpc.auto.Payload, com.alibaba.nacos.api.grpc.auto.Payload>newBuilder()
.setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
.setFullMethodName(generateFullMethodName(
"RequestStream", "requestStream"))
.setSampledToLocalTracing(true)
.setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
com.alibaba.nacos.api.grpc.auto.Payload.getDefaultInstance()))
.setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
com.alibaba.nacos.api.grpc.auto.Payload.getDefaultInstance()))
.setSchemaDescriptor(new RequestStreamMethodDescriptorSupplier("requestStream"))
.build();
}
}
}
return getRequestStreamMethod;
}
/**
* Creates a new async stub that supports all call types for the service
*/
public static RequestStreamStub newStub(io.grpc.Channel channel) {
return new RequestStreamStub(channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
public static RequestStreamBlockingStub newBlockingStub(
io.grpc.Channel channel) {
return new RequestStreamBlockingStub(channel);
}
/**
* Creates a new ListenableFuture-style stub that supports unary calls on the service
*/
public static RequestStreamFutureStub newFutureStub(
io.grpc.Channel channel) {
return new RequestStreamFutureStub(channel);
}
/**
*/
public static abstract class RequestStreamImplBase implements io.grpc.BindableService {
/**
* <pre>
* build a streamRequest
* </pre>
*/
public void requestStream(com.alibaba.nacos.api.grpc.auto.Payload request,
io.grpc.stub.StreamObserver<com.alibaba.nacos.api.grpc.auto.Payload> responseObserver) {
asyncUnimplementedUnaryCall(getRequestStreamMethod(), responseObserver);
}
@Override public final io.grpc.ServerServiceDefinition bindService() {
return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
.addMethod(
getRequestStreamMethod(),
asyncServerStreamingCall(
new MethodHandlers<
com.alibaba.nacos.api.grpc.auto.Payload,
com.alibaba.nacos.api.grpc.auto.Payload>(
this, METHODID_REQUEST_STREAM)))
.build();
}
}
/**
*/
public static final class RequestStreamStub extends io.grpc.stub.AbstractStub<RequestStreamStub> {
private RequestStreamStub(io.grpc.Channel channel) {
super(channel);
}
private RequestStreamStub(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@Override
protected RequestStreamStub build(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
return new RequestStreamStub(channel, callOptions);
}
/**
* <pre>
* build a streamRequest
* </pre>
*/
public void requestStream(com.alibaba.nacos.api.grpc.auto.Payload request,
io.grpc.stub.StreamObserver<com.alibaba.nacos.api.grpc.auto.Payload> responseObserver) {
asyncServerStreamingCall(
getChannel().newCall(getRequestStreamMethod(), getCallOptions()), request, responseObserver);
}
}
/**
*/
public static final class RequestStreamBlockingStub extends io.grpc.stub.AbstractStub<RequestStreamBlockingStub> {
private RequestStreamBlockingStub(io.grpc.Channel channel) {
super(channel);
}
private RequestStreamBlockingStub(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@Override
protected RequestStreamBlockingStub build(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
return new RequestStreamBlockingStub(channel, callOptions);
}
/**
* <pre>
* build a streamRequest
* </pre>
*/
public java.util.Iterator<com.alibaba.nacos.api.grpc.auto.Payload> requestStream(
com.alibaba.nacos.api.grpc.auto.Payload request) {
return blockingServerStreamingCall(
getChannel(), getRequestStreamMethod(), getCallOptions(), request);
}
}
/**
*/
public static final class RequestStreamFutureStub extends io.grpc.stub.AbstractStub<RequestStreamFutureStub> {
private RequestStreamFutureStub(io.grpc.Channel channel) {
super(channel);
}
private RequestStreamFutureStub(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@Override
protected RequestStreamFutureStub build(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
return new RequestStreamFutureStub(channel, callOptions);
}
}
private static final int METHODID_REQUEST_STREAM = 0;
private static final class MethodHandlers<Req, Resp> implements
io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
private final RequestStreamImplBase serviceImpl;
private final int methodId;
MethodHandlers(RequestStreamImplBase serviceImpl, int methodId) {
this.serviceImpl = serviceImpl;
this.methodId = methodId;
}
@Override
@SuppressWarnings("unchecked")
public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
switch (methodId) {
case METHODID_REQUEST_STREAM:
serviceImpl.requestStream((com.alibaba.nacos.api.grpc.auto.Payload) request,
(io.grpc.stub.StreamObserver<com.alibaba.nacos.api.grpc.auto.Payload>) responseObserver);
break;
default:
throw new AssertionError();
}
}
@Override
@SuppressWarnings("unchecked")
public io.grpc.stub.StreamObserver<Req> invoke(
io.grpc.stub.StreamObserver<Resp> responseObserver) {
switch (methodId) {
default:
throw new AssertionError();
}
}
}
private static abstract class RequestStreamBaseDescriptorSupplier
implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
RequestStreamBaseDescriptorSupplier() {}
@Override
public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
return com.alibaba.nacos.api.grpc.auto.NacosGrpcService.getDescriptor();
}
@Override
public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
return getFileDescriptor().findServiceByName("RequestStream");
}
}
private static final class RequestStreamFileDescriptorSupplier
extends RequestStreamBaseDescriptorSupplier {
RequestStreamFileDescriptorSupplier() {}
}
private static final class RequestStreamMethodDescriptorSupplier
extends RequestStreamBaseDescriptorSupplier
implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
private final String methodName;
RequestStreamMethodDescriptorSupplier(String methodName) {
this.methodName = methodName;
}
@Override
public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
return getServiceDescriptor().findMethodByName(methodName);
}
}
private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
public static io.grpc.ServiceDescriptor getServiceDescriptor() {
io.grpc.ServiceDescriptor result = serviceDescriptor;
if (result == null) {
synchronized (RequestStreamGrpc.class) {
result = serviceDescriptor;
if (result == null) {
serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
.setSchemaDescriptor(new RequestStreamFileDescriptorSupplier())
.addMethod(getRequestStreamMethod())
.build();
}
}
}
return result;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.alibaba.nacos.api.naming;
package com.alibaba.nacos.api.naming.ability;
/**
* naming abilities of nacos client.

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.alibaba.nacos.api.naming;
package com.alibaba.nacos.api.naming.ability;
import java.io.Serializable;
import java.util.Objects;

View File

@ -20,8 +20,8 @@ import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
import com.alibaba.nacos.api.utils.StringUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.Objects;
import java.util.Objects;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -89,7 +89,7 @@ public class Http extends AbstractHealthChecker {
@Override
public int hashCode() {
return Objects.hashCode(path, headers, expectedResponseCode);
return Objects.hash(path, headers, expectedResponseCode);
}
@Override

View File

@ -18,7 +18,8 @@ package com.alibaba.nacos.api.naming.pojo.healthcheck.impl;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
import com.alibaba.nacos.api.utils.StringUtils;
import com.google.common.base.Objects;
import java.util.Objects;
/**
* Implementation of health checker for MYSQL.
@ -67,7 +68,7 @@ public class Mysql extends AbstractHealthChecker {
@Override
public int hashCode() {
return Objects.hashCode(user, pwd, cmd);
return Objects.hash(user, pwd, cmd);
}
@Override

View File

@ -17,7 +17,8 @@
package com.alibaba.nacos.api.naming.pojo.healthcheck.impl;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
import com.google.common.base.Objects;
import java.util.Objects;
/**
* Implementation of health checker for TCP.
@ -36,7 +37,7 @@ public class Tcp extends AbstractHealthChecker {
@Override
public int hashCode() {
return Objects.hashCode(TYPE);
return Objects.hash(TYPE);
}
@Override

View File

@ -18,6 +18,8 @@ package com.alibaba.nacos.api.naming.remote.request;
import com.alibaba.nacos.api.remote.request.Request;
import static com.alibaba.nacos.api.common.Constants.Naming.NAMING_MODULE;
/**
* Uniform remote request of naming module.
*
@ -25,8 +27,6 @@ import com.alibaba.nacos.api.remote.request.Request;
*/
public abstract class AbstractNamingRequest extends Request {
private static final String MODULE = "naming";
private String namespace;
private String serviceName;
@ -44,7 +44,7 @@ public abstract class AbstractNamingRequest extends Request {
@Override
public String getModule() {
return MODULE;
return NAMING_MODULE;
}
public String getNamespace() {

View File

@ -19,15 +19,15 @@ package com.alibaba.nacos.api.naming.remote.request;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.remote.request.ServerRequest;
import static com.alibaba.nacos.api.common.Constants.Naming.NAMING_MODULE;
/**
* Notify subscriber response.
* Notify subscriber request.
*
* @author xiweng.yy
*/
public class NotifySubscriberRequest extends ServerRequest {
private static final String MODULE = "naming";
private String namespace;
private String serviceName;
@ -41,25 +41,15 @@ public class NotifySubscriberRequest extends ServerRequest {
@Override
public String getModule() {
return MODULE;
return NAMING_MODULE;
}
private NotifySubscriberRequest(ServiceInfo serviceInfo, String message) {
private NotifySubscriberRequest(ServiceInfo serviceInfo) {
this.serviceInfo = serviceInfo;
}
public static NotifySubscriberRequest buildSuccessResponse(ServiceInfo serviceInfo) {
return new NotifySubscriberRequest(serviceInfo, "success");
}
/**
* Build fail response.
*
* @param message error message
* @return fail response
*/
public static NotifySubscriberRequest buildFailResponse(String message) {
return new NotifySubscriberRequest();
public static NotifySubscriberRequest buildNotifySubscriberRequest(ServiceInfo serviceInfo) {
return new NotifySubscriberRequest(serviceInfo);
}
public ServiceInfo getServiceInfo() {

View File

@ -36,7 +36,7 @@ import java.util.Set;
public class PayloadRegistry {
private static final Map<String, Class> REGISTRY_REQUEST = new HashMap<String, Class>();
private static final Map<String, Class<?>> REGISTRY_REQUEST = new HashMap<>();
static boolean initialized = false;
@ -55,7 +55,7 @@ public class PayloadRegistry {
for (String pkg : requestScanPackage) {
Reflections reflections = new Reflections(pkg);
Set<Class<? extends Request>> subTypesRequest = reflections.getSubTypesOf(Request.class);
for (Class clazz : subTypesRequest) {
for (Class<?> clazz : subTypesRequest) {
register(clazz.getSimpleName(), clazz);
}
}
@ -67,7 +67,7 @@ public class PayloadRegistry {
for (String pkg : responseScanPackage) {
Reflections reflections = new Reflections(pkg);
Set<Class<? extends Response>> subTypesOfResponse = reflections.getSubTypesOf(Response.class);
for (Class clazz : subTypesOfResponse) {
for (Class<?> clazz : subTypesOfResponse) {
register(clazz.getSimpleName(), clazz);
}
}
@ -75,7 +75,7 @@ public class PayloadRegistry {
initialized = true;
}
static void register(String type, Class clazz) {
static void register(String type, Class<?> clazz) {
if (Modifier.isAbstract(clazz.getModifiers())) {
return;
}
@ -88,7 +88,7 @@ public class PayloadRegistry {
REGISTRY_REQUEST.put(type, clazz);
}
public static Class getClassByType(String type) {
public static Class<?> getClassByType(String type) {
return REGISTRY_REQUEST.get(type);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.alibaba.nacos.api.ability;
package com.alibaba.nacos.api.remote.ability;
/**
* remote abilities of nacos client.

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.alibaba.nacos.api.ability;
package com.alibaba.nacos.api.remote.ability;
import java.io.Serializable;
import java.util.Objects;

View File

@ -16,6 +16,8 @@
package com.alibaba.nacos.api.remote.request;
import static com.alibaba.nacos.api.common.Constants.Remote.INTERNAL_MODULE;
/**
* client active detection request from server.
*
@ -24,11 +26,9 @@ package com.alibaba.nacos.api.remote.request;
*/
public class ClientDetectionRequest extends ServerRequest {
private static final String MODULE = "internal";
@Override
public String getModule() {
return MODULE;
return INTERNAL_MODULE;
}
}

View File

@ -16,6 +16,8 @@
package com.alibaba.nacos.api.remote.request;
import static com.alibaba.nacos.api.common.Constants.Remote.INTERNAL_MODULE;
/**
* ConnectResetRequest.
*
@ -24,15 +26,13 @@ package com.alibaba.nacos.api.remote.request;
*/
public class ConnectResetRequest extends ServerRequest {
private static final String MODULE = "internal";
String serverIp;
String serverPort;
@Override
public String getModule() {
return MODULE;
return INTERNAL_MODULE;
}
/**

View File

@ -16,6 +16,8 @@
package com.alibaba.nacos.api.remote.request;
import static com.alibaba.nacos.api.common.Constants.Remote.INTERNAL_MODULE;
/**
* internal request .
*
@ -25,10 +27,8 @@ package com.alibaba.nacos.api.remote.request;
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class InternalRequest extends Request {
private static final String MODULE = "internal";
@Override
public String getModule() {
return MODULE;
return INTERNAL_MODULE;
}
}

View File

@ -24,4 +24,17 @@ package com.alibaba.nacos.api.remote.response;
*/
public class ErrorResponse extends Response {
/**
* build an error response.
*
* @param errorCode errorCode
* @param msg msg
* @return response
*/
public static Response build(int errorCode, String msg) {
ErrorResponse response = new ErrorResponse();
response.setErrorInfo(errorCode, msg);
return response;
}
}

View File

@ -15,13 +15,16 @@
*
*/
package com.alibaba.nacos.api.naming.selector;
package com.alibaba.nacos.api.selector;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.selector.context.CmdbContext;
import com.alibaba.nacos.api.selector.context.CmdbContext;
import java.util.List;
import static com.alibaba.nacos.api.common.Constants.Naming.CMDB_CONTEXT_TYPE;
/**
* {@link AbstractCmdbSelector} will provide one default implement of {@link Selector}, users can implement it to use the {@link CmdbContext}.
* And return the result as default subclass of {@link Instance}.
@ -31,7 +34,33 @@ import java.util.List;
*/
public abstract class AbstractCmdbSelector<T extends Instance> implements Selector<List<T>, CmdbContext<T>, String> {
private static final String DEFAULT_CONTEXT_TYPE = "CMDB";
/**
* the labels expression.
*/
protected String expression;
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
@Override
public Selector<List<T>, CmdbContext<T>, String> parse(String expression) throws NacosException {
this.expression = expression;
doParse(expression);
return this;
}
/**
* The real parse logic implement by sub class.
*
* @param expression expression.
* @throws NacosException parse failed exception.
*/
protected abstract void doParse(String expression) throws NacosException;
@Override
public List<T> select(CmdbContext<T> context) {
@ -48,6 +77,6 @@ public abstract class AbstractCmdbSelector<T extends Instance> implements Select
@Override
public String getContextType() {
return DEFAULT_CONTEXT_TYPE;
return CMDB_CONTEXT_TYPE;
}
}

View File

@ -15,7 +15,7 @@
*
*/
package com.alibaba.nacos.api.naming.selector;
package com.alibaba.nacos.api.selector;
import com.alibaba.nacos.api.exception.NacosException;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@ -36,17 +36,17 @@ import java.io.Serializable;
* @author chenglu
* @date 2021-07-09 21:24
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION, property = "type")
public interface Selector<R, C, D> extends Serializable {
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface Selector<R, C, E> extends Serializable {
/**
* parse the selector, build the inner info which used by {@link #select(Object)}.
*
* @param condition condition.
* @param expression expression.
* @return selector.
* @throws NacosException parse failed exception.
*/
Selector<R, C, D> parse(D condition) throws NacosException;
Selector<R, C, E> parse(E expression) throws NacosException;
/**
* select the target result.

View File

@ -15,16 +15,17 @@
*
*/
package com.alibaba.nacos.api.naming.selector.context;
package com.alibaba.nacos.api.selector.context;
import com.alibaba.nacos.api.cmdb.pojo.Entity;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.selector.Selector;
import java.util.List;
/**
* The CMDB context is given by the {@link SelectorContextBuilder#build(Object, Object)} and used for the
* {@link com.alibaba.nacos.api.naming.selector.Selector#select(Object)}.
* {@link Selector#select(Object)}.
*
* @author chenglu
* @date 2021-07-09 21:31

View File

@ -15,10 +15,12 @@
*
*/
package com.alibaba.nacos.api.naming.selector.context;
package com.alibaba.nacos.api.selector.context;
import com.alibaba.nacos.api.selector.Selector;
/**
* The {@link SelectorContextBuilder} mainly for provide the context for {@link com.alibaba.nacos.api.naming.selector.Selector#select(Object)}.
* The {@link SelectorContextBuilder} mainly for provide the context for {@link Selector#select(Object)}.
* It provides {@link #build(Object, Object)} method for build context. And also provide {@link #getContextType()} for get the contextType.
*
* @author chenglu
@ -27,12 +29,12 @@ package com.alibaba.nacos.api.naming.selector.context;
public interface SelectorContextBuilder<T, C, P> {
/**
* build the context for {@link com.alibaba.nacos.api.naming.selector.Selector#select(Object)}. The user must provide consumer and provider.
* build the context for {@link Selector#select(Object)}. The user must provide consumer and provider.
* we provide {@link CmdbContext} for user default who want to use the {@link com.alibaba.nacos.api.naming.pojo.Instance}'s CMDB info.
*
* @param consumer consumer who launch the select.
* @param provider the provides who are selected by consumer.
* @return selectorContext use by {@link com.alibaba.nacos.api.naming.selector.Selector#select(Object)}.
* @return selectorContext use by {@link Selector#select(Object)}.
*/
T build(C consumer, P provider);

View File

@ -29,18 +29,11 @@ message Metadata {
map<string, string> headers = 7;
}
message Payload {
Metadata metadata = 2;
google.protobuf.Any body = 3;
}
service RequestStream {
// build a streamRequest
rpc requestStream (Payload) returns (stream Payload) {
}
}
service Request {
// Sends a commonRequest
rpc request (Payload) returns (Payload) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2020 Alibaba Group Holding Ltd.
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.alibaba.nacos.api.naming;
package com.alibaba.nacos.api.naming.ability;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;

View File

@ -25,11 +25,13 @@ import com.alibaba.nacos.common.notify.listener.Subscriber;
import com.alibaba.nacos.common.utils.ConvertUtils;
import com.alibaba.nacos.sys.env.EnvUtil;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.DecodingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
/**
@ -97,7 +99,12 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
public byte[] getSecretKeyBytes() {
if (secretKeyBytes == null) {
secretKeyBytes = Decoders.BASE64.decode(secretKey);
try {
secretKeyBytes = Decoders.BASE64.decode(secretKey);
} catch (DecodingException e) {
secretKeyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
}
}
return secretKeyBytes;
}
@ -162,7 +169,8 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
serverIdentityKey = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SERVER_IDENTITY_KEY, "");
serverIdentityValue = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SERVER_IDENTITY_VALUE, "");
enableUserAgentAuthWhite = EnvUtil.getProperty(
Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE, Boolean.class, false);
Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE, Boolean.class,
false);
authorityKey = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_AUTHORITY_KEY, "").split(",");
nacosAuthSystemType = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SYSTEM_TYPE, "");
} catch (Exception e) {

View File

@ -284,54 +284,51 @@ public class CacheData {
name, dataId, group, md5, listener);
return;
}
Runnable job = new Runnable() {
@Override
public void run() {
long start = System.currentTimeMillis();
ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader appClassLoader = listener.getClass().getClassLoader();
try {
if (listener instanceof AbstractSharedListener) {
AbstractSharedListener adapter = (AbstractSharedListener) listener;
adapter.fillContext(dataId, group);
LOGGER.info("[{}] [notify-context] dataId={}, group={}, md5={}", name, dataId, group, md5);
}
// Before executing the callback, set the thread classloader to the classloader of
// the specific webapp to avoid exceptions or misuses when calling the spi interface in
// the callback method (this problem occurs only in multi-application deployment).
Thread.currentThread().setContextClassLoader(appClassLoader);
ConfigResponse cr = new ConfigResponse();
cr.setDataId(dataId);
cr.setGroup(group);
cr.setContent(content);
cr.setEncryptedDataKey(encryptedDataKey);
configFilterChainManager.doFilter(null, cr);
String contentTmp = cr.getContent();
listenerWrap.inNotifying = true;
listener.receiveConfigInfo(contentTmp);
// compare lastContent and content
if (listener instanceof AbstractConfigChangeListener) {
Map data = ConfigChangeHandler.getInstance()
.parseChangeData(listenerWrap.lastContent, content, type);
ConfigChangeEvent event = new ConfigChangeEvent(data);
((AbstractConfigChangeListener) listener).receiveConfigChange(event);
listenerWrap.lastContent = content;
}
listenerWrap.lastCallMd5 = md5;
LOGGER.info("[{}] [notify-ok] dataId={}, group={}, md5={}, listener={} ,cost={} millis.", name,
dataId, group, md5, listener, (System.currentTimeMillis() - start));
} catch (NacosException ex) {
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} errCode={} errMsg={}",
name, dataId, group, md5, listener, ex.getErrCode(), ex.getErrMsg());
} catch (Throwable t) {
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} tx={}", name, dataId,
group, md5, listener, t.getCause());
} finally {
listenerWrap.inNotifying = false;
Thread.currentThread().setContextClassLoader(myClassLoader);
Runnable job = () -> {
long start = System.currentTimeMillis();
ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader appClassLoader = listener.getClass().getClassLoader();
try {
if (listener instanceof AbstractSharedListener) {
AbstractSharedListener adapter = (AbstractSharedListener) listener;
adapter.fillContext(dataId, group);
LOGGER.info("[{}] [notify-context] dataId={}, group={}, md5={}", name, dataId, group, md5);
}
// Before executing the callback, set the thread classloader to the classloader of
// the specific webapp to avoid exceptions or misuses when calling the spi interface in
// the callback method (this problem occurs only in multi-application deployment).
Thread.currentThread().setContextClassLoader(appClassLoader);
ConfigResponse cr = new ConfigResponse();
cr.setDataId(dataId);
cr.setGroup(group);
cr.setContent(content);
cr.setEncryptedDataKey(encryptedDataKey);
configFilterChainManager.doFilter(null, cr);
String contentTmp = cr.getContent();
listenerWrap.inNotifying = true;
listener.receiveConfigInfo(contentTmp);
// compare lastContent and content
if (listener instanceof AbstractConfigChangeListener) {
Map data = ConfigChangeHandler.getInstance()
.parseChangeData(listenerWrap.lastContent, content, type);
ConfigChangeEvent event = new ConfigChangeEvent(data);
((AbstractConfigChangeListener) listener).receiveConfigChange(event);
listenerWrap.lastContent = content;
}
listenerWrap.lastCallMd5 = md5;
LOGGER.info("[{}] [notify-ok] dataId={}, group={}, md5={}, listener={} ,cost={} millis.", name,
dataId, group, md5, listener, (System.currentTimeMillis() - start));
} catch (NacosException ex) {
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} errCode={} errMsg={}",
name, dataId, group, md5, listener, ex.getErrCode(), ex.getErrMsg());
} catch (Throwable t) {
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} tx={}", name, dataId,
group, md5, listener, t.getCause());
} finally {
listenerWrap.inNotifying = false;
Thread.currentThread().setContextClassLoader(myClassLoader);
}
};
@ -396,7 +393,7 @@ public class CacheData {
this.dataId = dataId;
this.group = group;
this.tenant = TenantUtil.getUserTenantForAcm();
listeners = new CopyOnWriteArrayList<ManagerListenerWrap>();
listeners = new CopyOnWriteArrayList<>();
this.isInitializing = true;
this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
this.md5 = getMd5String(content);
@ -413,7 +410,7 @@ public class CacheData {
this.dataId = dataId;
this.group = group;
this.tenant = tenant;
listeners = new CopyOnWriteArrayList<ManagerListenerWrap>();
listeners = new CopyOnWriteArrayList<>();
this.isInitializing = true;
this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
this.md5 = getMd5String(content);

View File

@ -68,7 +68,6 @@ import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@ -112,8 +111,7 @@ public class ClientWorker implements Closeable {
/**
* groupKey -> cacheData.
*/
private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
new HashMap<>());
private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<>(new HashMap<>());
private final ConfigFilterChainManager configFilterChainManager;
@ -128,7 +126,11 @@ public class ClientWorker implements Closeable {
private int taskPenaltyTime;
private boolean enableRemoteSyncConfig = false;
private static final int MIN_THREAD_NUM = 2;
private static final int THREAD_MULTIPLE = 1;
/**
* Add listeners for data.
*
@ -242,18 +244,6 @@ public class ClientWorker implements Closeable {
}
}
private void removeCache(String dataId, String group) {
String groupKey = GroupKey.getKey(dataId, group);
synchronized (cacheMap) {
Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
copy.remove(groupKey);
cacheMap.set(copy);
}
LOGGER.info("[{}] [unsubscribe] {}", this.agent.getName(), groupKey);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
}
void removeCache(String dataId, String group, String tenant) {
String groupKey = GroupKey.getKeyTenant(dataId, group, tenant);
synchronized (cacheMap) {
@ -406,47 +396,6 @@ public class ClientWorker implements Closeable {
return this.agent.queryConfig(dataId, group, tenant, readTimeout, notify);
}
private void checkLocalConfig(String agentName, CacheData cacheData) {
final String dataId = cacheData.dataId;
final String group = cacheData.group;
final String tenant = cacheData.tenant;
File path = LocalConfigInfoProcessor.getFailoverFile(agentName, dataId, group, tenant);
if (!cacheData.isUseLocalConfigInfo() && path.exists()) {
String content = LocalConfigInfoProcessor.getFailover(agentName, dataId, group, tenant);
final String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
cacheData.setUseLocalConfigInfo(true);
cacheData.setLocalConfigInfoVersion(path.lastModified());
cacheData.setContent(content);
LOGGER.warn(
"[{}] [failover-change] failover file created. dataId={}, group={}, tenant={}, md5={}, content={}",
agentName, dataId, group, tenant, md5, ContentUtils.truncateContent(content));
return;
}
// If use local config info, then it doesn't notify business listener and notify after getting from server.
if (cacheData.isUseLocalConfigInfo() && !path.exists()) {
cacheData.setUseLocalConfigInfo(false);
LOGGER.warn("[{}] [failover-change] failover file deleted. dataId={}, group={}, tenant={}", agentName,
dataId, group, tenant);
return;
}
// When it changed.
if (cacheData.isUseLocalConfigInfo() && path.exists() && cacheData.getLocalConfigInfoVersion() != path
.lastModified()) {
String content = LocalConfigInfoProcessor.getFailover(agentName, dataId, group, tenant);
final String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
cacheData.setUseLocalConfigInfo(true);
cacheData.setLocalConfigInfoVersion(path.lastModified());
cacheData.setContent(content);
LOGGER.warn(
"[{}] [failover-change] failover file changed. dataId={}, group={}, tenant={}, md5={}, content={}",
agentName, dataId, group, tenant, md5, ContentUtils.truncateContent(content));
}
}
private String blank2defaultGroup(String group) {
return StringUtils.isBlank(group) ? Constants.DEFAULT_GROUP : group.trim();
}
@ -459,9 +408,9 @@ public class ClientWorker implements Closeable {
init(properties);
agent = new ConfigRpcTransportClient(properties, serverListManager);
int count = ThreadUtils.getSuitableThreadCount(THREAD_MULTIPLE);
ScheduledExecutorService executorService = Executors
.newScheduledThreadPool(ThreadUtils.getSuitableThreadCount(1), r -> {
.newScheduledThreadPool(Math.max(count, MIN_THREAD_NUM), r -> {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker");
t.setDaemon(true);
@ -596,25 +545,25 @@ public class ClientWorker implements Closeable {
public void shutdown() throws NacosException {
super.shutdown();
synchronized (RpcClientFactory.getAllClientEntries()) {
LOGGER.info("Trying to shutdown transport client " + this);
LOGGER.info("Trying to shutdown transport client {}", this);
Set<Map.Entry<String, RpcClient>> allClientEntries = RpcClientFactory.getAllClientEntries();
Iterator<Map.Entry<String, RpcClient>> iterator = allClientEntries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, RpcClient> entry = iterator.next();
if (entry.getKey().startsWith(uuid)) {
LOGGER.info("Trying to shutdown rpc client " + entry.getKey());
LOGGER.info("Trying to shutdown rpc client {}", entry.getKey());
try {
entry.getValue().shutdown();
} catch (NacosException nacosException) {
nacosException.printStackTrace();
}
LOGGER.info("Remove rpc client " + entry.getKey());
LOGGER.info("Remove rpc client {}", entry.getKey());
iterator.remove();
}
}
LOGGER.info("Shutdown executor " + executor);
LOGGER.info("Shutdown executor {}", executor);
executor.shutdown();
Map<String, CacheData> stringCacheDataMap = cacheMap.get();
for (Map.Entry<String, CacheData> entry : stringCacheDataMap.entrySet()) {
@ -721,9 +670,9 @@ public class ClientWorker implements Closeable {
}
});
NotifyCenter.registerSubscriber(new Subscriber() {
NotifyCenter.registerSubscriber(new Subscriber<ServerlistChangeEvent>() {
@Override
public void onEvent(Event event) {
public void onEvent(ServerlistChangeEvent event) {
rpcClientInner.onServerListChange();
}
@ -736,19 +685,16 @@ public class ClientWorker implements Closeable {
@Override
public void startInternal() throws NacosException {
executor.schedule(new Runnable() {
@Override
public void run() {
while (!executor.isShutdown() && !executor.isTerminated()) {
try {
listenExecutebell.poll(5L, TimeUnit.SECONDS);
if (executor.isShutdown() || executor.isTerminated()) {
continue;
}
executeConfigListen();
} catch (Exception e) {
LOGGER.error("[ rpc listen execute ] [rpc listen] exception", e);
executor.schedule(() -> {
while (!executor.isShutdown() && !executor.isTerminated()) {
try {
listenExecutebell.poll(5L, TimeUnit.SECONDS);
if (executor.isShutdown() || executor.isTerminated()) {
continue;
}
executeConfigListen();
} catch (Exception e) {
LOGGER.error("[ rpc listen execute ] [rpc listen] exception", e);
}
}
}, 0L, TimeUnit.MILLISECONDS);
@ -789,7 +735,7 @@ public class ClientWorker implements Closeable {
if (!cache.isUseLocalConfigInfo()) {
List<CacheData> cacheDatas = listenCachesMap.get(String.valueOf(cache.getTaskId()));
if (cacheDatas == null) {
cacheDatas = new LinkedList<CacheData>();
cacheDatas = new LinkedList<>();
listenCachesMap.put(String.valueOf(cache.getTaskId()), cacheDatas);
}
cacheDatas.add(cache);
@ -800,7 +746,7 @@ public class ClientWorker implements Closeable {
if (!cache.isUseLocalConfigInfo()) {
List<CacheData> cacheDatas = removeListenCachesMap.get(String.valueOf(cache.getTaskId()));
if (cacheDatas == null) {
cacheDatas = new LinkedList<CacheData>();
cacheDatas = new LinkedList<>();
removeListenCachesMap.put(String.valueOf(cache.getTaskId()), cacheDatas);
}
cacheDatas.add(cache);
@ -858,11 +804,9 @@ public class ClientWorker implements Closeable {
if (!cacheData.getListeners().isEmpty()) {
Long previousTimesStamp = timestampMap.get(groupKey);
if (previousTimesStamp != null) {
if (!cacheData.getLastModifiedTs().compareAndSet(previousTimesStamp,
System.currentTimeMillis())) {
continue;
}
if (previousTimesStamp != null && !cacheData.getLastModifiedTs().compareAndSet(previousTimesStamp,
System.currentTimeMillis())) {
continue;
}
cacheData.setSyncWithServer(true);
}
@ -1032,7 +976,7 @@ public class ClientWorker implements Closeable {
LOGGER.error("[{}] [sub-server-error] dataId={}, group={}, tenant={}, code={}", this.getName(), dataId,
group, tenant, response);
throw new NacosException(response.getErrorCode(),
"http error, code=" + response.getErrorCode() + ",dataId=" + dataId + ",group=" + group
"http error, code=" + response.getErrorCode() + ",msg=" + response.getMessage() + ",dataId=" + dataId + ",group=" + group
+ ",tenant=" + tenant);
}

View File

@ -17,13 +17,11 @@
package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.client.utils.LogUtils;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.alibaba.nacos.common.cache.Cache;
import com.alibaba.nacos.common.cache.builder.CacheBuilder;
import com.google.common.util.concurrent.RateLimiter;
import org.slf4j.Logger;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
@ -39,8 +37,15 @@ public class Limiter {
private static final int LIMIT_TIME = 1000;
private static final Cache<String, RateLimiter> CACHE = CacheBuilder.newBuilder().initialCapacity(CAPACITY_SIZE)
.expireAfterAccess(1, TimeUnit.MINUTES).build();
private static final Cache<String, RateLimiter> CACHE;
static {
CACHE = CacheBuilder.builder()
.expireNanos(1, TimeUnit.MINUTES)
.initializeCapacity(CAPACITY_SIZE)
.sync(true)
.build();
}
private static final String LIMIT_TIME_PROPERTY = "limitTime";
@ -68,13 +73,8 @@ public class Limiter {
public static boolean isLimit(String accessKeyID) {
RateLimiter rateLimiter = null;
try {
rateLimiter = CACHE.get(accessKeyID, new Callable<RateLimiter>() {
@Override
public RateLimiter call() throws Exception {
return RateLimiter.create(limit);
}
});
} catch (ExecutionException e) {
rateLimiter = CACHE.get(accessKeyID, () -> RateLimiter.create(limit));
} catch (Exception e) {
LOGGER.error("create limit fail", e);
}
if (rateLimiter != null && !rateLimiter.tryAcquire(LIMIT_TIME, TimeUnit.MILLISECONDS)) {

View File

@ -44,10 +44,8 @@ import java.util.List;
import java.util.Properties;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.concurrent.Callable;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
/**
@ -65,14 +63,11 @@ public class ServerListManager implements Closeable {
private final NacosRestTemplate nacosRestTemplate = ConfigHttpClientManager.getInstance().getNacosRestTemplate();
private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.ServerListManager");
t.setDaemon(true);
return t;
}
private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, r -> {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.ServerListManager");
t.setDaemon(true);
return t;
});
/**
@ -109,7 +104,7 @@ public class ServerListManager implements Closeable {
private String serverListName = ParamUtil.getDefaultNodesPath();
volatile List<String> serverUrls = new ArrayList<String>();
volatile List<String> serverUrls = new ArrayList<>();
private volatile String currentServerAddr;
@ -134,7 +129,7 @@ public class ServerListManager implements Closeable {
public ServerListManager(List<String> fixed, String namespace) {
this.isFixed = true;
this.isStarted = true;
List<String> serverAddrs = new ArrayList<String>();
List<String> serverAddrs = new ArrayList<>();
for (String serverAddr : fixed) {
String[] serverAddrArr = InternetAddressUtil.splitIPPortStr(serverAddr);
if (serverAddrArr.length == 1) {
@ -143,7 +138,7 @@ public class ServerListManager implements Closeable {
serverAddrs.add(serverAddr);
}
}
this.serverUrls = new ArrayList<String>(serverAddrs);
this.serverUrls = new ArrayList<>(serverAddrs);
if (StringUtils.isBlank(namespace)) {
this.name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()]));
} else {
@ -200,7 +195,7 @@ public class ServerListManager implements Closeable {
if (StringUtils.isNotEmpty(serverAddrsStr)) {
this.isFixed = true;
List<String> serverAddrs = new ArrayList<String>();
List<String> serverAddrs = new ArrayList<>();
StringTokenizer serverAddrsTokens = new StringTokenizer(this.serverAddrsStr, ",;");
while (serverAddrsTokens.hasMoreTokens()) {
String serverAddr = serverAddrsTokens.nextToken().trim();
@ -263,12 +258,7 @@ public class ServerListManager implements Closeable {
String endpointPortTmp = TemplateUtils
.stringEmptyAndThenExecute(System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT),
new Callable<String>() {
@Override
public String call() {
return properties.getProperty(PropertyKeyConst.ENDPOINT_PORT);
}
});
() -> properties.getProperty(PropertyKeyConst.ENDPOINT_PORT));
if (StringUtils.isNotBlank(endpointPortTmp)) {
this.endpointPort = Integer.parseInt(endpointPortTmp);
@ -370,7 +360,7 @@ public class ServerListManager implements Closeable {
return;
}
List<String> newServerAddrList = new ArrayList<String>();
List<String> newServerAddrList = new ArrayList<>();
for (String server : newList) {
if (server.startsWith(HTTP) || server.startsWith(HTTPS)) {
newServerAddrList.add(server);
@ -385,7 +375,7 @@ public class ServerListManager implements Closeable {
if (newServerAddrList.equals(serverUrls)) {
return;
}
serverUrls = new ArrayList<String>(newServerAddrList);
serverUrls = new ArrayList<>(newServerAddrList);
iterator = iterator();
currentServerAddr = iterator.next();
@ -403,7 +393,7 @@ public class ServerListManager implements Closeable {
EnvUtil.setSelfEnv(httpResult.getHeader().getOriginalResponseHeader());
}
List<String> lines = IoUtils.readLines(new StringReader(httpResult.getData()));
List<String> result = new ArrayList<String>(lines.size());
List<String> result = new ArrayList<>(lines.size());
for (String serverAddr : lines) {
if (StringUtils.isNotBlank(serverAddr)) {
String[] ipPort = InternetAddressUtil.splitIPPortStr(serverAddr.trim());
@ -543,7 +533,7 @@ public class ServerListManager implements Closeable {
}
public ServerAddressIterator(List<String> source) {
sorted = new ArrayList<RandomizedServerAddress>();
sorted = new ArrayList<>();
for (String address : source) {
sorted.add(new RandomizedServerAddress(address));
}

View File

@ -0,0 +1,67 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.constant;
import java.util.concurrent.TimeUnit;
/**
* All the constants.
*
* @author onew
*/
public class Constants {
public static class SysEnv {
public static final String USER_HOME = "user.home";
public static final String PROJECT_NAME = "project.name";
public static final String JM_LOG_PATH = "JM.LOG.PATH";
public static final String JM_SNAPSHOT_PATH = "JM.SNAPSHOT.PATH";
}
public static class Disk {
public static final String READ_ONLY = "r";
public static final String READ_WRITE = "rw";
}
public static class HealthCheck {
public static final String UP = "UP";
public static final String DOWN = "DOWN";
}
public static class Protocols {
public static final String HTTP = "http://";
public static final String HTTPS = "https://";
}
public static class Security {
public static final long SECURITY_INFO_REFRESH_INTERVAL_MILLS = TimeUnit.SECONDS.toMillis(5);
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.client.logging;
import com.alibaba.nacos.client.constant.Constants;
import com.alibaba.nacos.common.utils.ConvertUtils;
import com.alibaba.nacos.common.utils.StringUtils;
@ -33,13 +34,13 @@ public abstract class AbstractNacosLogging {
private static final String NACOS_LOGGING_DEFAULT_CONFIG_ENABLED_PROPERTY = "nacos.logging.default.config.enabled";
private static final String NACOS_LOGGING_PATH_PROPERTY = "JM.LOG.PATH";
private static final String NACOS_LOGGING_PATH_DIR = "logs";
static {
String loggingPath = System.getProperty(NACOS_LOGGING_PATH_PROPERTY);
String loggingPath = System.getProperty(Constants.SysEnv.JM_LOG_PATH);
if (StringUtils.isBlank(loggingPath)) {
String userHome = System.getProperty("user.home");
System.setProperty(NACOS_LOGGING_PATH_PROPERTY, userHome + File.separator + "logs");
String userHome = System.getProperty(Constants.SysEnv.USER_HOME);
System.setProperty(Constants.SysEnv.JM_LOG_PATH, userHome + File.separator + NACOS_LOGGING_PATH_DIR);
}
}

View File

@ -44,6 +44,10 @@ public class NacosLogging {
}
}
public boolean isLogback() {
return isLogback;
}
private static class NacosLoggingInstance {
private static final NacosLogging INSTANCE = new NacosLogging();

View File

@ -21,7 +21,6 @@ import ch.qos.logback.classic.util.ContextInitializer;
import com.alibaba.nacos.client.logging.AbstractNacosLogging;
import com.alibaba.nacos.common.utils.ResourceUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import org.slf4j.impl.StaticLoggerBinder;
/**
* Support for Logback version 1.0.8 or higher
@ -33,6 +32,12 @@ public class LogbackNacosLogging extends AbstractNacosLogging {
private static final String NACOS_LOGBACK_LOCATION = "classpath:nacos-logback.xml";
private static LoggerContext loggerContext;
public static LoggerContext getLoggerContext() {
return loggerContext;
}
@Override
public void loadConfiguration() {
String location = getLocation(NACOS_LOGBACK_LOCATION);
@ -41,7 +46,7 @@ public class LogbackNacosLogging extends AbstractNacosLogging {
}
try {
LoggerContext loggerContext = (LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory();
loggerContext = new LoggerContext();
new ContextInitializer(loggerContext).configureByResource(ResourceUtils.getResourceUrl(location));
} catch (Exception e) {
throw new IllegalStateException("Could not initialize Logback Nacos logging from " + location, e);

View File

@ -31,9 +31,16 @@ import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy;
import com.alibaba.nacos.client.naming.utils.InitUtils;
import com.alibaba.nacos.client.security.SecurityProxy;
import com.alibaba.nacos.client.utils.ValidatorUtils;
import com.alibaba.nacos.common.utils.ThreadUtils;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.client.constant.Constants.Security.SECURITY_INFO_REFRESH_INTERVAL_MILLS;
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
/**
* Nacos naming maintain service.
@ -48,6 +55,12 @@ public class NacosNamingMaintainService implements NamingMaintainService {
private NamingHttpClientProxy serverProxy;
private ServerListManager serverListManager;
private SecurityProxy securityProxy;
private ScheduledExecutorService executorService;
public NacosNamingMaintainService(String serverList) throws NacosException {
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverList);
@ -63,12 +76,26 @@ public class NacosNamingMaintainService implements NamingMaintainService {
namespace = InitUtils.initNamespaceForNaming(properties);
InitUtils.initSerialization();
InitUtils.initWebRootContext(properties);
ServerListManager serverListManager = new ServerListManager(properties, namespace);
SecurityProxy securityProxy = new SecurityProxy(serverListManager.getServerList(),
serverListManager = new ServerListManager(properties, namespace);
securityProxy = new SecurityProxy(serverListManager.getServerList(),
NamingHttpClientManager.getInstance().getNacosRestTemplate());
initSecurityProxy();
serverProxy = new NamingHttpClientProxy(namespace, securityProxy, serverListManager, properties, null);
}
private void initSecurityProxy() {
this.executorService = new ScheduledThreadPoolExecutor(1, r -> {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.naming.maintainService.security");
t.setDaemon(true);
return t;
});
this.securityProxy.login(serverListManager.getServerList());
this.executorService.scheduleWithFixedDelay(() -> securityProxy.login(serverListManager.getServerList()), 0,
SECURITY_INFO_REFRESH_INTERVAL_MILLS, TimeUnit.MILLISECONDS);
}
@Override
public void updateInstance(String serviceName, Instance instance) throws NacosException {
updateInstance(serviceName, Constants.DEFAULT_GROUP, instance);
@ -167,6 +194,11 @@ public class NacosNamingMaintainService implements NamingMaintainService {
@Override
public void shutDown() throws NacosException {
String className = this.getClass().getName();
NAMING_LOGGER.info("{} do shutdown begin", className);
serverListManager.shutdown();
serverProxy.shutdown();
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
NAMING_LOGGER.info("{} do shutdown stop", className);
}
}

View File

@ -225,7 +225,7 @@ 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 {

View File

@ -151,8 +151,8 @@ public class FailoverReactor implements Closeable {
try {
File switchFile = new File(failoverDir + UtilAndComs.FAILOVER_SWITCH);
if (!switchFile.exists()) {
switchParams.put("failover-mode", "false");
NAMING_LOGGER.debug("failover switch is not found, " + switchFile.getName());
switchParams.put(FAILOVER_MODE_PARAM, Boolean.FALSE.toString());
NAMING_LOGGER.debug("failover switch is not found, {}", switchFile.getName());
return;
}
@ -227,12 +227,12 @@ public class FailoverReactor implements Closeable {
try {
dom = JacksonUtils.toObj(json, ServiceInfo.class);
} catch (Exception e) {
NAMING_LOGGER.error("[NA] error while parsing cached dom : " + json, e);
NAMING_LOGGER.error("[NA] error while parsing cached dom : {}", json, e);
}
}
} catch (Exception e) {
NAMING_LOGGER.error("[NA] failed to read cache for dom: " + file.getName(), e);
NAMING_LOGGER.error("[NA] failed to read cache for dom: {}", file.getName(), e);
} finally {
try {
if (reader != null) {

View File

@ -69,9 +69,9 @@ public class ServiceInfoHolder implements Closeable {
public ServiceInfoHolder(String namespace, Properties properties) {
initCacheDir(namespace, properties);
if (isLoadCacheAtStart(properties)) {
this.serviceInfoMap = new ConcurrentHashMap<String, ServiceInfo>(DiskCache.read(this.cacheDir));
this.serviceInfoMap = new ConcurrentHashMap<>(DiskCache.read(this.cacheDir));
} else {
this.serviceInfoMap = new ConcurrentHashMap<String, ServiceInfo>(16);
this.serviceInfoMap = new ConcurrentHashMap<>(16);
}
this.failoverReactor = new FailoverReactor(this, cacheDir);
this.pushEmptyProtection = isPushEmptyProtect(properties);
@ -119,7 +119,7 @@ public class ServiceInfoHolder implements Closeable {
}
public ServiceInfo getServiceInfo(final String serviceName, final String groupName, final String clusters) {
NAMING_LOGGER.debug("failover-mode: " + failoverReactor.isFailoverSwitch());
NAMING_LOGGER.debug("failover-mode: {}", failoverReactor.isFailoverSwitch());
String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
String key = ServiceInfo.getKey(groupedServiceName, clusters);
if (failoverReactor.isFailoverSwitch()) {
@ -163,8 +163,8 @@ public class ServiceInfoHolder implements Closeable {
}
MetricsMonitor.getServiceInfoMapSizeMonitor().set(serviceInfoMap.size());
if (changed) {
NAMING_LOGGER.info("current ips:(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() + " -> "
+ JacksonUtils.toJson(serviceInfo.getHosts()));
NAMING_LOGGER.info("current ips:({}) service: {} -> {}", serviceInfo.ipCount(), serviceInfo.getKey(),
JacksonUtils.toJson(serviceInfo.getHosts()));
NotifyCenter.publishEvent(new InstancesChangeEvent(serviceInfo.getName(), serviceInfo.getGroupName(),
serviceInfo.getClusters(), serviceInfo.getHosts()));
DiskCache.write(serviceInfo, cacheDir);
@ -178,14 +178,14 @@ public class ServiceInfoHolder implements Closeable {
private boolean isChangedServiceInfo(ServiceInfo oldService, ServiceInfo newService) {
if (null == oldService) {
NAMING_LOGGER.info("init new ips(" + newService.ipCount() + ") service: " + newService.getKey() + " -> "
+ JacksonUtils.toJson(newService.getHosts()));
NAMING_LOGGER.info("init new ips({}) service: {} -> {}", newService.ipCount(), newService.getKey(),
JacksonUtils.toJson(newService.getHosts()));
return true;
}
if (oldService.getLastRefTime() > newService.getLastRefTime()) {
NAMING_LOGGER
.warn("out of date data received, old-t: " + oldService.getLastRefTime() + ", new-t: " + newService
.getLastRefTime());
NAMING_LOGGER.warn("out of date data received, old-t: {}, new-t: {}", oldService.getLastRefTime(),
newService.getLastRefTime());
return false;
}
boolean changed = false;
Map<String, Instance> oldHostMap = new HashMap<String, Instance>(oldService.getHosts().size());
@ -231,21 +231,20 @@ public class ServiceInfoHolder implements Closeable {
if (newHosts.size() > 0) {
changed = true;
NAMING_LOGGER
.info("new ips(" + newHosts.size() + ") service: " + newService.getKey() + " -> " + JacksonUtils
.toJson(newHosts));
NAMING_LOGGER.info("new ips({}) service: {} -> {}", newHosts.size(), newService.getKey(),
JacksonUtils.toJson(newHosts));
}
if (remvHosts.size() > 0) {
changed = true;
NAMING_LOGGER.info("removed ips(" + remvHosts.size() + ") service: " + newService.getKey() + " -> "
+ JacksonUtils.toJson(remvHosts));
NAMING_LOGGER.info("removed ips({}) service: {} -> {}", remvHosts.size(), newService.getKey(),
JacksonUtils.toJson(remvHosts));
}
if (modHosts.size() > 0) {
changed = true;
NAMING_LOGGER.info("modified ips(" + modHosts.size() + ") service: " + newService.getKey() + " -> "
+ JacksonUtils.toJson(modHosts));
NAMING_LOGGER.info("modified ips({}) service: {} -> {}", modHosts.size(), newService.getKey(),
JacksonUtils.toJson(modHosts));
}
return changed;
}

View File

@ -149,10 +149,10 @@ public class ServerListManager implements ServerListFactory, Closeable {
}
if (null == serversFromEndpoint || !CollectionUtils.isEqualCollection(list, serversFromEndpoint)) {
NAMING_LOGGER.info("[SERVER-LIST] server list is updated: " + list);
serversFromEndpoint = list;
lastServerListRefreshTime = System.currentTimeMillis();
NotifyCenter.publishEvent(new ServerListChangedEvent());
}
serversFromEndpoint = list;
lastServerListRefreshTime = System.currentTimeMillis();
NotifyCenter.publishEvent(new ServerListChangedEvent());
} catch (Throwable e) {
NAMING_LOGGER.warn("failed to update server list", e);
}

View File

@ -136,6 +136,8 @@ public class ServiceInfoUpdateService implements Closeable {
long lastRefTime = Long.MAX_VALUE;
private boolean isCancel;
private final String serviceName;
private final String groupName;
@ -145,7 +147,7 @@ public class ServiceInfoUpdateService implements Closeable {
private final String groupedServiceName;
private final String serviceKey;
/**
* the fail situation. 1:can't connect to server 2:serviceInfo's hosts is empty
*/
@ -164,9 +166,10 @@ public class ServiceInfoUpdateService implements Closeable {
long delayTime = DEFAULT_DELAY;
try {
if (!changeNotifier.isSubscribed(groupName, serviceName, clusters) && !futureMap.containsKey(serviceKey)) {
NAMING_LOGGER
.info("update task is stopped, service:" + groupedServiceName + ", clusters:" + clusters);
if (!changeNotifier.isSubscribed(groupName, serviceName, clusters) && !futureMap.containsKey(
serviceKey)) {
NAMING_LOGGER.info("update task is stopped, service:{}, clusters:{}", groupedServiceName, clusters);
isCancel = true;
return;
}
@ -192,12 +195,15 @@ public class ServiceInfoUpdateService implements Closeable {
resetFailCount();
} catch (Throwable e) {
incFailCount();
NAMING_LOGGER.warn("[NA] failed to update serviceName: " + groupedServiceName, e);
NAMING_LOGGER.warn("[NA] failed to update serviceName: {}", groupedServiceName, e);
} finally {
executor.schedule(this, Math.min(delayTime << failCount, DEFAULT_DELAY * 60), TimeUnit.MILLISECONDS);
if (!isCancel) {
executor.schedule(this, Math.min(delayTime << failCount, DEFAULT_DELAY * 60),
TimeUnit.MILLISECONDS);
}
}
}
private void incFailCount() {
int limit = 6;
if (failCount == limit) {
@ -205,7 +211,7 @@ public class ServiceInfoUpdateService implements Closeable {
}
failCount++;
}
private void resetFailCount() {
failCount = 0;
}

View File

@ -149,6 +149,17 @@ public interface NamingClientProxy extends Closeable {
*/
void unsubscribe(String serviceName, String groupName, String clusters) throws NacosException;
/**
* Judge whether service has been subscribed.
*
* @param serviceName service name
* @param groupName group name
* @param clusters clusters, current only support subscribe all clusters, maybe deprecated
* @return {@code true} if subscribed, otherwise {@code false}
* @throws NacosException nacos exception
*/
boolean isSubscribed(String serviceName, String groupName, String clusters) throws NacosException;
/**
* Update beat info.
*

View File

@ -39,6 +39,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.client.constant.Constants.Security.SECURITY_INFO_REFRESH_INTERVAL_MILLS;
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
/**
@ -48,8 +49,6 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
*/
public class NamingClientProxyDelegate implements NamingClientProxy {
private final long securityInfoRefreshIntervalMills = TimeUnit.SECONDS.toMillis(5);
private final ServerListManager serverListManager;
private final ServiceInfoUpdateService serviceInfoUpdateService;
@ -87,7 +86,7 @@ public class NamingClientProxyDelegate implements NamingClientProxy {
});
this.securityProxy.login(properties);
this.executorService.scheduleWithFixedDelay(() -> securityProxy.login(properties), 0,
securityInfoRefreshIntervalMills, TimeUnit.MILLISECONDS);
SECURITY_INFO_REFRESH_INTERVAL_MILLS, TimeUnit.MILLISECONDS);
}
@Override
@ -139,11 +138,12 @@ public class NamingClientProxyDelegate implements NamingClientProxy {
@Override
public ServiceInfo subscribe(String serviceName, String groupName, String clusters) throws NacosException {
NAMING_LOGGER.info("[SUBSCRIBE-SERVICE] service:{}, group:{}, clusters:{} ", serviceName, groupName, clusters);
String serviceNameWithGroup = NamingUtils.getGroupedName(serviceName, groupName);
String serviceKey = ServiceInfo.getKey(serviceNameWithGroup, clusters);
serviceInfoUpdateService.scheduleUpdateIfAbsent(serviceName, groupName, clusters);
ServiceInfo result = serviceInfoHolder.getServiceInfoMap().get(serviceKey);
if (null == result) {
if (null == result || !isSubscribed(serviceName, groupName, clusters)) {
result = grpcClientProxy.subscribe(serviceName, groupName, clusters);
}
serviceInfoHolder.processServiceInfo(result);
@ -152,10 +152,16 @@ 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);
serviceInfoUpdateService.stopUpdateIfContain(serviceName, groupName, clusters);
grpcClientProxy.unsubscribe(serviceName, groupName, clusters);
}
@Override
public boolean isSubscribed(String serviceName, String groupName, String clusters) throws NacosException {
return grpcClientProxy.isSubscribed(serviceName, groupName, clusters);
}
@Override
public void updateBeatInfo(Set<Instance> modifiedInstances) {
httpClientProxy.updateBeatInfo(modifiedInstances);

View File

@ -207,6 +207,9 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
@Override
public ServiceInfo subscribe(String serviceName, String groupName, String clusters) throws NacosException {
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER.debug("[GRPC-SUBSCRIBE] service:{}, group:{}, cluster:{} ", serviceName, groupName, clusters);
}
redoService.cacheSubscriberForRedo(serviceName, groupName, clusters);
return doSubscribe(serviceName, groupName, clusters);
}
@ -230,10 +233,18 @@ 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);
}
redoService.subscriberDeregister(serviceName, groupName, clusters);
doUnsubscribe(serviceName, groupName, clusters);
}
@Override
public boolean isSubscribed(String serviceName, String groupName, String clusters) throws NacosException {
return redoService.isSubscriberRegistered(serviceName, groupName, clusters);
}
/**
* Execute unsubscribe operation.
*

View File

@ -214,6 +214,22 @@ public class NamingGrpcRedoService implements ConnectionEventListener {
}
}
/**
* Judge subscriber has registered to server.
*
* @param serviceName service name
* @param groupName group name
* @param cluster cluster
* @return {@code true} if subscribed, otherwise {@code false}
*/
public boolean isSubscriberRegistered(String serviceName, String groupName, String cluster) {
String key = ServiceInfo.getKey(NamingUtils.getGroupedName(serviceName, groupName), cluster);
synchronized (subscribes) {
SubscriberRedoData redoData = subscribes.get(key);
return null != redoData && redoData.isRegistered();
}
}
/**
* Remove subscriber for redo.
*

View File

@ -146,7 +146,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
beatReactor.addBeatInfo(groupedServiceName, beatInfo);
}
final Map<String, String> params = new HashMap<String, String>(16);
final Map<String, String> params = new HashMap<String, String>(32);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, groupedServiceName);
params.put(CommonParams.GROUP_NAME, groupName);
@ -172,7 +172,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), instance.getIp(),
instance.getPort());
}
final Map<String, String> params = new HashMap<String, String>(8);
final Map<String, String> params = new HashMap<String, String>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, NamingUtils.getGroupedName(serviceName, groupName));
params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
@ -188,7 +188,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
NAMING_LOGGER
.info("[UPDATE-SERVICE] {} update service {} with instance: {}", namespaceId, serviceName, instance);
final Map<String, String> params = new HashMap<String, String>(8);
final Map<String, String> params = new HashMap<String, String>(32);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
@ -206,7 +206,7 @@ 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<String, String>(8);
final Map<String, String> params = new HashMap<String, String>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, NamingUtils.getGroupedName(serviceName, groupName));
params.put(CLUSTERS_PARAM, clusters);
@ -224,7 +224,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
public Service queryService(String serviceName, String groupName) throws NacosException {
NAMING_LOGGER.info("[QUERY-SERVICE] {} query service : {}, {}", namespaceId, serviceName, groupName);
final Map<String, String> params = new HashMap<String, String>(3);
final Map<String, String> params = new HashMap<String, String>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
@ -238,7 +238,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
NAMING_LOGGER.info("[CREATE-SERVICE] {} creating service : {}", namespaceId, service);
final Map<String, String> params = new HashMap<String, String>(6);
final Map<String, String> params = new HashMap<String, String>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, service.getName());
params.put(CommonParams.GROUP_NAME, service.getGroupName());
@ -255,7 +255,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
NAMING_LOGGER.info("[DELETE-SERVICE] {} deleting service : {} with groupName : {}", namespaceId, serviceName,
groupName);
final Map<String, String> params = new HashMap<String, String>(6);
final Map<String, String> params = new HashMap<String, String>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
@ -268,7 +268,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
public void updateService(Service service, AbstractSelector selector) throws NacosException {
NAMING_LOGGER.info("[UPDATE-SERVICE] {} updating service : {}", namespaceId, service);
final Map<String, String> params = new HashMap<String, String>(6);
final Map<String, String> params = new HashMap<String, String>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, service.getName());
params.put(CommonParams.GROUP_NAME, service.getGroupName());
@ -292,7 +292,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER.debug("[BEAT] {} sending beat to server: {}", namespaceId, beatInfo.toString());
}
Map<String, String> params = new HashMap<String, String>(8);
Map<String, String> params = new HashMap<String, String>(16);
Map<String, String> bodyMap = new HashMap<String, String>(2);
if (!lightBeatEnabled) {
bodyMap.put("beat", JacksonUtils.toJson(beatInfo));
@ -310,7 +310,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
public boolean serverHealthy() {
try {
String result = reqApi(UtilAndComs.nacosUrlBase + "/operator/metrics", new HashMap<String, String>(2),
String result = reqApi(UtilAndComs.nacosUrlBase + "/operator/metrics", new HashMap<String, String>(8),
HttpMethod.GET);
JsonNode json = JacksonUtils.toObj(result);
String serverStatus = json.get("status").asText();
@ -324,7 +324,7 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
public ListView<String> getServiceList(int pageNo, int pageSize, String groupName, AbstractSelector selector)
throws NacosException {
Map<String, String> params = new HashMap<String, String>(4);
Map<String, String> params = new HashMap<String, String>(16);
params.put("pageNo", String.valueOf(pageNo));
params.put("pageSize", String.valueOf(pageSize));
params.put(CommonParams.NAMESPACE_ID, namespaceId);
@ -363,6 +363,11 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
public void unsubscribe(String serviceName, String groupName, String clusters) throws NacosException {
}
@Override
public boolean isSubscribed(String serviceName, String groupName, String clusters) throws NacosException {
return true;
}
@Override
public void updateBeatInfo(Set<Instance> modifiedInstances) {
for (Instance instance : modifiedInstances) {

View File

@ -31,7 +31,6 @@ import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import java.util.Properties;
import java.util.concurrent.Callable;
/**
* Init utils.
@ -62,35 +61,24 @@ public class InitUtils {
tmpNamespace = TenantUtil.getUserTenantForAns();
LogUtils.NAMING_LOGGER.info("initializer namespace from System Property : {}", tmpNamespace);
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Environment :" + namespace);
return namespace;
}
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, () -> {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Environment :" + namespace);
return namespace;
});
}
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = System.getProperty(PropertyKeyConst.NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Property :" + namespace);
return namespace;
}
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, () -> {
String namespace = System.getProperty(PropertyKeyConst.NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Property :" + namespace);
return namespace;
});
if (StringUtils.isEmpty(tmpNamespace)) {
tmpNamespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
}
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
return UtilAndComs.DEFAULT_NAMESPACE_ID;
}
});
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, () -> UtilAndComs.DEFAULT_NAMESPACE_ID);
return tmpNamespace;
}
@ -102,13 +90,10 @@ public class InitUtils {
*/
public static void initWebRootContext(Properties properties) {
final String webContext = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
TemplateUtils.stringNotEmptyAndThenExecute(webContext, new Runnable() {
@Override
public void run() {
UtilAndComs.webContext = ContextPathUtil.normalizeContextPath(webContext);
UtilAndComs.nacosUrlBase = UtilAndComs.webContext + "/v1/ns";
UtilAndComs.nacosUrlInstance = UtilAndComs.nacosUrlBase + "/instance";
}
TemplateUtils.stringNotEmptyAndThenExecute(webContext, () -> {
UtilAndComs.webContext = ContextPathUtil.normalizeContextPath(webContext);
UtilAndComs.nacosUrlBase = UtilAndComs.webContext + "/v1/ns";
UtilAndComs.nacosUrlInstance = UtilAndComs.nacosUrlBase + "/instance";
});
initWebRootContext();
}
@ -120,13 +105,10 @@ public class InitUtils {
public static void initWebRootContext() {
// support the web context with ali-yun if the app deploy by EDAS
final String webContext = System.getProperty(SystemPropertyKeyConst.NAMING_WEB_CONTEXT);
TemplateUtils.stringNotEmptyAndThenExecute(webContext, new Runnable() {
@Override
public void run() {
UtilAndComs.webContext = ContextPathUtil.normalizeContextPath(webContext);
UtilAndComs.nacosUrlBase = UtilAndComs.webContext + "/v1/ns";
UtilAndComs.nacosUrlInstance = UtilAndComs.nacosUrlBase + "/instance";
}
TemplateUtils.stringNotEmptyAndThenExecute(webContext, () -> {
UtilAndComs.webContext = ContextPathUtil.normalizeContextPath(webContext);
UtilAndComs.nacosUrlBase = UtilAndComs.webContext + "/v1/ns";
UtilAndComs.nacosUrlInstance = UtilAndComs.nacosUrlBase + "/instance";
});
}
@ -164,20 +146,9 @@ public class InitUtils {
String endpointPort = TemplateUtils
.stringEmptyAndThenExecute(System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT),
new Callable<String>() {
@Override
public String call() {
return properties.getProperty(PropertyKeyConst.ENDPOINT_PORT);
}
});
() -> properties.getProperty(PropertyKeyConst.ENDPOINT_PORT));
endpointPort = TemplateUtils.stringEmptyAndThenExecute(endpointPort, new Callable<String>() {
@Override
public String call() {
return DEFAULT_END_POINT_PORT;
}
});
endpointPort = TemplateUtils.stringEmptyAndThenExecute(endpointPort, () -> DEFAULT_END_POINT_PORT);
return endpointUrl + ":" + endpointPort;
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.client.utils;
import com.alibaba.nacos.client.constant.Constants;
import com.alibaba.nacos.common.utils.StringUtils;
import java.io.File;
@ -27,8 +28,6 @@ import java.io.File;
*/
public class AppNameUtils {
private static final String PARAM_MARKING_PROJECT = "project.name";
private static final String PARAM_MARKING_JBOSS = "jboss.server.home.dir";
private static final String PARAM_MARKING_JETTY = "jetty.home";
@ -64,7 +63,7 @@ public class AppNameUtils {
}
private static String getAppNameByProjectName() {
return System.getProperty(PARAM_MARKING_PROJECT);
return System.getProperty(Constants.SysEnv.PROJECT_NAME);
}
private static String getAppNameByServerHome() {

View File

@ -17,6 +17,7 @@
package com.alibaba.nacos.client.utils;
import com.alibaba.nacos.client.logging.NacosLogging;
import com.alibaba.nacos.client.logging.logback.LogbackNacosLogging;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
@ -33,10 +34,29 @@ public class LogUtils {
static {
NacosLogging.getInstance().loadConfiguration();
NAMING_LOGGER = getLogger("com.alibaba.nacos.client.naming");
NAMING_LOGGER = logger("com.alibaba.nacos.client.naming");
}
/**
* get logger by name.
* @param name logger name
*/
public static Logger logger(String name) {
if (NacosLogging.getInstance().isLogback()) {
return LogbackNacosLogging.getLoggerContext().getLogger(name);
}
return getLogger(name);
}
/**
* get logger by clazz.
*
* @param clazz logger clazz
*/
public static Logger logger(Class<?> clazz) {
if (NacosLogging.getInstance().isLogback()) {
return LogbackNacosLogging.getLoggerContext().getLogger(clazz);
}
return getLogger(clazz);
}

View File

@ -24,7 +24,6 @@ import com.alibaba.nacos.common.utils.VersionUtils;
import org.slf4j.Logger;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.regex.Pattern;
/**
@ -185,12 +184,9 @@ public class ParamUtil {
if (Boolean.parseBoolean(isUseCloudNamespaceParsing)) {
namespaceTmp = TenantUtil.getUserTenantForAcm();
namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, new Callable<String>() {
@Override
public String call() {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
return StringUtils.isNotBlank(namespace) ? namespace : StringUtils.EMPTY;
}
namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, () -> {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
return StringUtils.isNotBlank(namespace) ? namespace : StringUtils.EMPTY;
});
}
@ -228,12 +224,7 @@ public class ParamUtil {
String endpointUrlSource = TemplateUtils
.stringBlankAndThenExecute(System.getProperty(endpointUrl, System.getenv(endpointUrl)),
new Callable<String>() {
@Override
public String call() {
return System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_URL);
}
});
() -> System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_URL));
if (StringUtils.isBlank(endpointUrlSource)) {
if (StringUtils.isNotBlank(defaultEndpointUrl)) {

View File

@ -41,7 +41,7 @@ public class TemplateUtils {
try {
runnable.run();
} catch (Exception e) {
LogUtils.NAMING_LOGGER.error("string empty and then execute cause an exception.", e);
LogUtils.NAMING_LOGGER.error("string not empty and then execute cause an exception.", e);
}
}
}

View File

@ -28,12 +28,14 @@ public class TenantUtil {
private static final String USER_TENANT;
private static final String ACM_NAMESPACE_PROPERTY = "acm.namespace";
private static final String DEFAULT_ACM_NAMESPACE = "";
private static final String TENANT_ID = "tenant.id";
private static final String ACM_NAMESPACE_PROPERTY = "acm.namespace";
static {
USER_TENANT = System.getProperty("tenant.id", "");
USER_TENANT = System.getProperty(TENANT_ID, "");
}
/**

View File

@ -73,8 +73,7 @@ public class CacheDataTest {
Assert.assertEquals(123, cacheData1.getTaskId());
Assert.assertTrue(cacheData1.isSyncWithServer());
//TODO FIX getType
// Assert.assertFalse("123",cacheData1.getType());
Assert.assertEquals("123", cacheData1.getType());
Assert.assertTrue(cacheData1.isUseLocalConfigInfo());
Assert.assertEquals(timeStamp, cacheData1.getLastModifiedTs().longValue());
Assert.assertEquals(timeStamp, cacheData1.getLocalConfigInfoVersion());

View File

@ -140,7 +140,7 @@ public class ClientWorkerTest {
clientWorker.removeConfig(dataId, group, tenant, tag);
Assert.fail();
} catch (NacosException e) {
Assert.assertEquals("Client not connected,current status:STARTING", e.getErrMsg());
Assert.assertEquals("Client not connected, current status:STARTING", e.getErrMsg());
Assert.assertEquals(-401, e.getErrCode());
}
@ -148,7 +148,7 @@ public class ClientWorkerTest {
clientWorker.getServerConfig(dataId, group, tenant, 100, false);
Assert.fail();
} catch (NacosException e) {
Assert.assertEquals("Client not connected,current status:STARTING", e.getErrMsg());
Assert.assertEquals("Client not connected, current status:STARTING", e.getErrMsg());
Assert.assertEquals(-401, e.getErrCode());
}
}

View File

@ -18,21 +18,12 @@
package com.alibaba.nacos.client.logging.logback;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.hamcrest.CoreMatchers.isA;
public class LogbackNacosLoggingTest {
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@Test
public void testLoadConfiguration() {
exceptionRule.expectCause(isA(ClassCastException.class));
exceptionRule.expectMessage("Could not initialize Logback Nacos logging from classpath:nacos-logback.xml");
LogbackNacosLogging logbackNacosLogging = new LogbackNacosLogging();
logbackNacosLogging.loadConfiguration();
}

View File

@ -26,7 +26,9 @@ import com.alibaba.nacos.api.naming.pojo.Service;
import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.api.selector.ExpressionSelector;
import com.alibaba.nacos.api.selector.NoneSelector;
import com.alibaba.nacos.client.naming.core.ServerListManager;
import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy;
import com.alibaba.nacos.client.security.SecurityProxy;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@ -37,6 +39,7 @@ import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ScheduledExecutorService;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
@ -49,15 +52,35 @@ public class NacosNamingMaintainServiceTest {
private NamingHttpClientProxy serverProxy;
private ServerListManager serverListManager;
private SecurityProxy securityProxy;
private ScheduledExecutorService executorService;
@Before
public void setUp() throws Exception {
Properties prop = new Properties();
prop.setProperty(PropertyKeyConst.NAMESPACE, "public");
nacosNamingMaintainService = new NacosNamingMaintainService(prop);
serverProxy = mock(NamingHttpClientProxy.class);
serverListManager = mock(ServerListManager.class);
securityProxy = mock(SecurityProxy.class);
executorService = mock(ScheduledExecutorService.class);
Field serverProxyField = NacosNamingMaintainService.class.getDeclaredField("serverProxy");
serverProxyField.setAccessible(true);
serverProxyField.set(nacosNamingMaintainService, serverProxy);
Field serverListManagerField = NacosNamingMaintainService.class.getDeclaredField("serverListManager");
serverListManagerField.setAccessible(true);
serverListManagerField.set(nacosNamingMaintainService, serverListManager);
Field securityProxyFiled = NacosNamingMaintainService.class.getDeclaredField("securityProxy");
securityProxyFiled.setAccessible(true);
securityProxyFiled.set(nacosNamingMaintainService, securityProxy);
Field executorServiceField = NacosNamingMaintainService.class.getDeclaredField("executorService");
executorServiceField.setAccessible(true);
executorServiceField.set(nacosNamingMaintainService, executorService);
}
@After
@ -275,8 +298,11 @@ public class NacosNamingMaintainServiceTest {
@Test
public void testShutDown() throws NacosException {
//when
nacosNamingMaintainService.shutDown();
//then
verify(serverProxy, times(1)).shutdown();
verify(serverListManager, times(1)).shutdown();
verify(executorService, times(1)).shutdown();
}
}

View File

@ -25,9 +25,9 @@ import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.Service;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.client.auth.ram.utils.SignUtil;
import com.alibaba.nacos.client.auth.spi.RequestResource;
import com.alibaba.nacos.client.naming.event.ServerListChangedEvent;
import com.alibaba.nacos.client.auth.ram.utils.SignUtil;
import com.alibaba.nacos.client.security.SecurityProxy;
import com.alibaba.nacos.client.utils.AppNameUtils;
import com.alibaba.nacos.common.notify.Event;
@ -147,6 +147,11 @@ public class AbstractNamingClientProxyTest {
}
@Override
public boolean isSubscribed(String serviceName, String groupName, String clusters) throws NacosException {
return false;
}
@Override
public void updateBeatInfo(Set<Instance> modifiedInstances) {

View File

@ -39,7 +39,7 @@ public class NamingPushRequestHandlerTest {
ServiceInfoHolder holder = mock(ServiceInfoHolder.class);
NamingPushRequestHandler handler = new NamingPushRequestHandler(holder);
ServiceInfo info = new ServiceInfo("name", "cluster1");
Request req = NotifySubscriberRequest.buildSuccessResponse(info);
Request req = NotifySubscriberRequest.buildNotifySubscriberRequest(info);
//when
Response response = handler.requestReply(req);
//then

View File

@ -0,0 +1,35 @@
/*
* 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;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Means a class is in beta version.
*
* @author wuzhiguo
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Beta {
}

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.cache;
import java.util.concurrent.Callable;
/**
* Cache method collection definition.
* @author zzq
* @date 2021/7/30
*/
public interface Cache<K, V> {
/**
* Cache a pair of key value. If the key value already exists, the value will be overwritten.
* @param key cache key
* @param val cache value
*/
void put(K key, V val);
/**
* Take the corresponding value from the cache according to the cache key.
* @param key cache key
* @return cache value
*/
V get(K key);
/**
* Get the value in the cache according to the primary key, and put it into the cache after processing by the function.
* @param key cache key
* @param call a function, the return value of the function will be updated to the cache
* @return cache value
* @throws Exception callable function interface throw exception
*/
V get(K key, Callable<? extends V> call) throws Exception;
/**
* Take the corresponding value from the cache according to the cache key, and remove this record from the cache.
* @param key cache key
* @return cache value
*/
V remove(K key);
/**
* Clear the entire cache.
*/
void clear();
/**
* Returns the number of key-value pairs in the cache.
* @return number of key-value pairs
*/
int getSize();
}

View File

@ -0,0 +1,131 @@
/*
* 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.cache.builder;
import com.alibaba.nacos.common.cache.Cache;
import com.alibaba.nacos.common.cache.decorators.AutoExpireCache;
import com.alibaba.nacos.common.cache.decorators.LruCache;
import com.alibaba.nacos.common.cache.decorators.SynchronizedCache;
import com.alibaba.nacos.common.cache.impl.SimpleCache;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* Cache builder.
* @author zzq
* @date 2021/7/30
*/
public class CacheBuilder<K, V> {
private static final int DEFAULT_MAXIMUMSIZE = 1024;
private static final int DEFAULT_INITIALIZE_CAPACITY = 1024;
private static final int DEFAULT_EXPIRE_NANOS = -1;
private long expireNanos = DEFAULT_EXPIRE_NANOS;
private int maximumSize = DEFAULT_MAXIMUMSIZE;
private int initializeCapacity = DEFAULT_INITIALIZE_CAPACITY;
private boolean sync = false;
private boolean lru = false;
public static CacheBuilder builder() {
return new CacheBuilder();
}
/**
* Set expiration time.
*/
public CacheBuilder expireNanos(long duration, TimeUnit unit) {
checkExpireNanos(duration, unit);
this.expireNanos = unit.toNanos(duration);
return this;
}
private void checkExpireNanos(long duration, TimeUnit unit) {
if (duration < 0) {
throw new IllegalArgumentException("duration cannot be negative");
}
if (Objects.isNull(unit)) {
throw new IllegalArgumentException("unit cannot be null");
}
}
/**
* Set the maximum capacity of the cache pair.
* @param maximumSize maximum capacity
*/
public CacheBuilder<K, V> maximumSize(int maximumSize) {
if (maximumSize < 0) {
throw new IllegalArgumentException("size cannot be negative");
}
this.maximumSize = maximumSize;
return this;
}
/**
* Set whether the cache method is synchronized.
* @param sync if sync value is true, each method of the constructed cache is synchronized.
*/
public CacheBuilder<K, V> sync(boolean sync) {
this.sync = sync;
return this;
}
/**
* Does the constructed cache support lru.
* @param lru If the cache built for true is an lru cache.
*/
public CacheBuilder<K, V> lru(boolean lru) {
this.lru = lru;
return this;
}
/**
* Set the initial capacity of the cache pair.
* @param initializeCapacity initialize capacity
*/
public CacheBuilder<K, V> initializeCapacity(int initializeCapacity) {
if (initializeCapacity < 0) {
throw new IllegalArgumentException("initializeCapacity cannot be negative");
}
this.initializeCapacity = initializeCapacity;
return this;
}
/**
* Build the cache according to the builder attribute.
*/
public Cache<K, V> build() {
Cache<K, V> cache = new SimpleCache<>(initializeCapacity);
if (lru) {
cache = new LruCache<>(cache, maximumSize);
}
if (expireNanos != -1) {
cache = new AutoExpireCache<>(cache, expireNanos);
}
if (sync) {
cache = new SynchronizedCache<>(cache);
}
return cache;
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.cache.builder;
/**
* Cache item's own attributes.
* @author zzq
* @date 2021/7/30
*/
public class CacheItemProperties {
private long expireNanos;
public long getExpireNanos() {
return expireNanos;
}
public void setExpireNanos(long expireNanos) {
this.expireNanos = expireNanos;
}
}

View File

@ -0,0 +1,90 @@
/*
* 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.cache.decorators;
import com.alibaba.nacos.common.cache.Cache;
import com.alibaba.nacos.common.cache.builder.CacheItemProperties;
import java.util.HashMap;
import java.util.concurrent.Callable;
/**
* A wrapper that automatically expires the cache.
* @author zzq
* @date 2021/7/30
*/
public class AutoExpireCache<K, V> implements Cache<K, V> {
private long expireNanos;
private Cache<K, V> delegate;
private HashMap<K, CacheItemProperties> keyProp = new HashMap<>();
public AutoExpireCache(Cache<K, V> delegate, long expireNanos) {
this.expireNanos = expireNanos;
this.delegate = delegate;
}
@Override
public void put(K key, V val) {
keyProp.put(key, cacheItemProperties());
this.delegate.put(key, val);
}
@Override
public V get(K key) {
if (keyProp.get(key) != null && isExpire(keyProp.get(key))) {
this.keyProp.remove(key);
this.delegate.remove(key);
return null;
}
return this.delegate.get(key);
}
@Override
public V get(K key, Callable<? extends V> call) throws Exception {
return this.delegate.get(key, call);
}
@Override
public V remove(K key) {
keyProp.remove(key);
return this.delegate.remove(key);
}
@Override
public void clear() {
keyProp.clear();
this.delegate.clear();
}
@Override
public int getSize() {
return this.delegate.getSize();
}
private boolean isExpire(CacheItemProperties itemProperties) {
return expireNanos != -1 && (System.nanoTime() - itemProperties.getExpireNanos() > expireNanos);
}
private CacheItemProperties cacheItemProperties() {
CacheItemProperties cacheItemProperties = new CacheItemProperties();
cacheItemProperties.setExpireNanos(System.nanoTime());
return cacheItemProperties;
}
}

View File

@ -0,0 +1,100 @@
/*
* 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.cache.decorators;
import com.alibaba.nacos.common.cache.Cache;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* A wrapper that lru cache.
* @author zzq
* @date 2021/7/30
*/
public class LruCache<K, V> implements Cache<K, V> {
private final Cache<K, V> delegate;
private Map<K, V> keyMap;
private K eldestKey;
public LruCache(Cache<K, V> delegate, int size) {
this.delegate = delegate;
setSize(size);
}
@Override
public int getSize() {
return delegate.getSize();
}
public void setSize(final int size) {
keyMap = new LinkedHashMap<K, V>(size, .75F, true) {
private static final long serialVersionUID = 4267176411845948333L;
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
boolean tooBig = size() > size;
if (tooBig) {
eldestKey = eldest.getKey();
}
return tooBig;
}
};
}
@Override
public void put(K key, V val) {
delegate.put(key, val);
cycleKeyList(key);
}
@Override
public V get(K key) {
keyMap.get(key);
return delegate.get(key);
}
@Override
public V get(K key, Callable<? extends V> call) throws Exception {
return this.delegate.get(key, call);
}
@Override
public V remove(K key) {
return delegate.remove(key);
}
@Override
public void clear() {
delegate.clear();
keyMap.clear();
}
private void cycleKeyList(K key) {
keyMap.put(key, null);
if (eldestKey != null) {
delegate.remove(eldestKey);
eldestKey = null;
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.cache.decorators;
import com.alibaba.nacos.common.cache.Cache;
import java.util.concurrent.Callable;
/**
* A wrapper that thread-safe cache.
* @author zzq
* @date 2021/7/30
*/
public class SynchronizedCache<K, V> implements Cache<K, V> {
private final Cache<K, V> delegate;
public SynchronizedCache(Cache<K, V> delegate) {
this.delegate = delegate;
}
@Override
public synchronized void put(K key, V val) {
this.delegate.put(key, val);
}
@Override
public synchronized V get(K key) {
return this.delegate.get(key);
}
@Override
public V get(K key, Callable<? extends V> call) throws Exception {
return this.delegate.get(key, call);
}
@Override
public synchronized V remove(K key) {
return this.delegate.remove(key);
}
@Override
public synchronized void clear() {
this.delegate.clear();
}
@Override
public synchronized int getSize() {
return this.delegate.getSize();
}
}

View File

@ -0,0 +1,73 @@
/*
* 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.cache.impl;
import com.alibaba.nacos.common.cache.Cache;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* Simple implementation of {@code Cache}.
* @author zzq
* @date 2021/7/30
*/
public class SimpleCache<K, V> implements Cache<K, V> {
private Map<K, V> cache;
public SimpleCache(int size) {
cache = new HashMap(size);
}
@Override
public void put(K key, V val) {
cache.put(key, val);
}
@Override
public V get(K key) {
return cache.get(key);
}
@Override
public V get(K key, Callable<? extends V> call) throws Exception {
if (cache.containsKey(key)) {
return cache.get(key);
} else {
V v2 = call.call();
cache.put(key, v2);
return v2;
}
}
@Override
public V remove(K key) {
return cache.remove(key);
}
@Override
public void clear() {
cache.clear();
}
@Override
public int getSize() {
return cache.size();
}
}

View File

@ -16,6 +16,8 @@
package com.alibaba.nacos.common.executor;
import com.alibaba.nacos.common.JustForTest;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
@ -164,7 +166,7 @@ public final class ExecutorFactory {
* @param coreThreads core thread number
* @param maxThreads max thread number
* @param keepAliveTimeMs keep alive time milliseconds
* @param threadFactory thread facotry
* @param threadFactory thread factory
* @return new custom executor service
*/
public static ThreadPoolExecutor newCustomerThreadExecutor(final String group, final int coreThreads,
@ -174,5 +176,10 @@ public final class ExecutorFactory {
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executor);
return executor;
}
@JustForTest
public static ThreadPoolManager getThreadPoolManager() {
return THREAD_POOL_MANAGER;
}
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.common.executor;
import com.alibaba.nacos.common.JustForTest;
import com.alibaba.nacos.common.utils.ThreadUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -81,9 +82,7 @@ public final class ThreadPoolManager {
*/
public void register(String namespace, String group, ExecutorService executor) {
if (!resourcesManager.containsKey(namespace)) {
synchronized (this) {
lockers.put(namespace, new Object());
}
lockers.putIfAbsent(namespace, new Object());
}
final Object monitor = lockers.get(namespace);
synchronized (monitor) {
@ -198,4 +197,13 @@ public final class ThreadPoolManager {
}
}
@JustForTest
public Map<String, Map<String, Set<ExecutorService>>> getResourcesManager() {
return resourcesManager;
}
@JustForTest
public Map<String, Object> getLockers() {
return lockers;
}
}

View File

@ -24,11 +24,24 @@ import com.alibaba.nacos.common.tls.SelfHostnameVerifier;
import com.alibaba.nacos.common.tls.TlsFileWatcher;
import com.alibaba.nacos.common.tls.TlsHelper;
import com.alibaba.nacos.common.tls.TlsSystemConfig;
import com.alibaba.nacos.common.utils.BiConsumer;
import java.util.function.BiConsumer;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.protocol.RequestContent;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.conn.NHttpClientConnectionManager;
import org.apache.http.nio.conn.NoopIOSessionStrategy;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
import org.apache.http.nio.reactor.IOReactorException;
import org.apache.http.nio.reactor.IOReactorExceptionHandler;
import org.apache.http.protocol.RequestContent;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import javax.net.ssl.HostnameVerifier;
@ -77,7 +90,65 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory {
.setDefaultRequestConfig(getRequestConfig())
.setMaxConnTotal(originalRequestConfig.getMaxConnTotal())
.setMaxConnPerRoute(originalRequestConfig.getMaxConnPerRoute())
.setUserAgent(originalRequestConfig.getUserAgent()).build()));
.setUserAgent(originalRequestConfig.getUserAgent())
.setConnectionManager(getConnectionManager(originalRequestConfig))
.build()));
}
/**
* create the {@link NHttpClientConnectionManager}, the code mainly from {@link HttpAsyncClientBuilder#build()}.
* we add the {@link IOReactorExceptionHandler} to handle the {@link IOException} and {@link RuntimeException}
* thrown by the {@link org.apache.http.impl.nio.reactor.BaseIOReactor} when process the event of Network.
* Using this way to avoid the {@link DefaultConnectingIOReactor} killed by unknown error of network.
*
* @param originalRequestConfig request config.
* @return {@link NHttpClientConnectionManager}.
*/
private NHttpClientConnectionManager getConnectionManager(HttpClientConfig originalRequestConfig) {
SSLContext sslcontext = SSLContexts.createDefault();
HostnameVerifier hostnameVerifier = new DefaultHostnameVerifier();
SchemeIOSessionStrategy sslStrategy = new SSLIOSessionStrategy(sslcontext, null, null, hostnameVerifier);
final DefaultConnectingIOReactor ioreactor;
try {
ioreactor = new DefaultConnectingIOReactor(getIoReactorConfig());
} catch (IOReactorException e) {
assignLogger().error("[NHttpClientConnectionManager] Create DefaultConnectingIOReactor failed", e);
throw new IllegalStateException();
}
// if the handle return true, then the exception thrown by IOReactor will be ignore, and will not finish the IOReactor.
ioreactor.setExceptionHandler(new IOReactorExceptionHandler() {
@Override
public boolean handle(IOException ex) {
assignLogger().warn("[NHttpClientConnectionManager] handle IOException, ignore it.", ex);
return true;
}
@Override
public boolean handle(RuntimeException ex) {
assignLogger().warn("[NHttpClientConnectionManager] handle RuntimeException, ignore it.", ex);
return true;
}
});
Registry<SchemeIOSessionStrategy> registry = RegistryBuilder.<SchemeIOSessionStrategy>create()
.register("http", NoopIOSessionStrategy.INSTANCE)
.register("https", sslStrategy)
.build();
final PoolingNHttpClientConnectionManager poolingmgr = new PoolingNHttpClientConnectionManager(ioreactor, registry);
int maxTotal = originalRequestConfig.getMaxConnTotal();
if (maxTotal > 0) {
poolingmgr.setMaxTotal(maxTotal);
}
int maxPerRoute = originalRequestConfig.getMaxConnPerRoute();
if (maxPerRoute > 0) {
poolingmgr.setDefaultMaxPerRoute(maxPerRoute);
}
return poolingmgr;
}
protected IOReactorConfig getIoReactorConfig() {

View File

@ -174,7 +174,7 @@ public class DefaultPublisher extends Thread implements EventPublisher {
final long currentEventSequence = event.sequence();
if (!hasSubscriber()) {
LOGGER.warn("[NotifyCenter] the {} is lost, because there is no subscriber.");
LOGGER.warn("[NotifyCenter] the {} is lost, because there is no subscriber.", event);
return;
}

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.common.notify;
import com.alibaba.nacos.common.utils.BiFunction;
import java.util.function.BiFunction;
/**
* Event publisher factory.

View File

@ -32,7 +32,9 @@ import com.alibaba.nacos.api.remote.response.ErrorResponse;
import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.common.lifecycle.Closeable;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.LoggerUtils;
import com.alibaba.nacos.common.utils.NumberUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -46,9 +48,10 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.alibaba.nacos.api.exception.NacosException.SERVER_ERROR;
@ -65,18 +68,18 @@ public abstract class RpcClient implements Closeable {
private ServerListFactory serverListFactory;
protected LinkedBlockingQueue<ConnectionEvent> eventLinkedBlockingQueue = new LinkedBlockingQueue<ConnectionEvent>();
protected LinkedBlockingQueue<ConnectionEvent> eventLinkedBlockingQueue = new LinkedBlockingQueue<>();
protected volatile AtomicReference<RpcClientStatus> rpcClientStatus = new AtomicReference<RpcClientStatus>(
protected volatile AtomicReference<RpcClientStatus> rpcClientStatus = new AtomicReference<>(
RpcClientStatus.WAIT_INIT);
protected ScheduledExecutorService clientEventExecutor;
private final BlockingQueue<ReconnectContext> reconnectionSignal = new ArrayBlockingQueue<ReconnectContext>(1);
private final BlockingQueue<ReconnectContext> reconnectionSignal = new ArrayBlockingQueue<>(1);
protected volatile Connection currentConnection;
protected Map<String, String> labels = new HashMap<String, String>();
protected Map<String, String> labels = new HashMap<>();
private String name;
@ -98,12 +101,14 @@ public abstract class RpcClient implements Closeable {
/**
* listener called where connection's status changed.
*/
protected List<ConnectionEventListener> connectionEventListeners = new ArrayList<ConnectionEventListener>();
protected List<ConnectionEventListener> connectionEventListeners = new ArrayList<>();
/**
* handlers to process server push request.
*/
protected List<ServerRequestHandler> serverRequestHandlers = new ArrayList<ServerRequestHandler>();
protected List<ServerRequestHandler> serverRequestHandlers = new ArrayList<>();
private static final Pattern EXCLUDE_PROTOCOL_PATTERN = Pattern.compile("(?<=\\w{1,5}://)(.*)");
static {
PayloadRegistry.init();
@ -116,7 +121,7 @@ public abstract class RpcClient implements Closeable {
public RpcClient(ServerListFactory serverListFactory) {
this.serverListFactory = serverListFactory;
rpcClientStatus.compareAndSet(RpcClientStatus.WAIT_INIT, RpcClientStatus.INITIALIZED);
LoggerUtils.printIfInfoEnabled(LOGGER, "RpcClient init in constructor, ServerListFactory ={}",
LoggerUtils.printIfInfoEnabled(LOGGER, "RpcClient init in constructor, ServerListFactory = {}",
serverListFactory.getClass().getName());
}
@ -124,7 +129,7 @@ public abstract class RpcClient implements Closeable {
this(name);
this.serverListFactory = serverListFactory;
rpcClientStatus.compareAndSet(RpcClientStatus.WAIT_INIT, RpcClientStatus.INITIALIZED);
LoggerUtils.printIfInfoEnabled(LOGGER, "RpcClient init in constructor, ServerListFactory ={}",
LoggerUtils.printIfInfoEnabled(LOGGER, "RpcClient init in constructor, ServerListFactory = {}",
serverListFactory.getClass().getName());
}
@ -139,7 +144,7 @@ public abstract class RpcClient implements Closeable {
}
/**
* init server list factory.only can init once.
* init server list factory. only can init once.
*
* @param serverListFactory serverListFactory
*/
@ -150,7 +155,7 @@ public abstract class RpcClient implements Closeable {
this.serverListFactory = serverListFactory;
rpcClientStatus.compareAndSet(RpcClientStatus.WAIT_INIT, RpcClientStatus.INITIALIZED);
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]RpcClient init, ServerListFactory ={}", name,
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] RpcClient init, ServerListFactory = {}", name,
serverListFactory.getClass().getName());
return this;
}
@ -162,7 +167,7 @@ public abstract class RpcClient implements Closeable {
*/
public RpcClient labels(Map<String, String> labels) {
this.labels.putAll(labels);
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]RpcClient init label, labels={}", name, this.labels);
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] RpcClient init label, labels = {}", name, this.labels);
return this;
}
@ -174,7 +179,7 @@ public abstract class RpcClient implements Closeable {
*/
public RpcClient keepAlive(long keepAliveTime, TimeUnit timeUnit) {
this.keepAliveTime = keepAliveTime * timeUnit.toMillis(keepAliveTime);
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]RpcClient init keepalive time, keepAliveTimeMillis={}", name,
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] RpcClient init keepalive time, keepAliveTimeMillis = {}", name,
keepAliveTime);
return this;
}
@ -186,12 +191,12 @@ public abstract class RpcClient implements Closeable {
if (connectionEventListeners.isEmpty()) {
return;
}
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]Notify disconnected event to listeners", name);
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Notify disconnected event to listeners", name);
for (ConnectionEventListener connectionEventListener : connectionEventListeners) {
try {
connectionEventListener.onDisConnect();
} catch (Throwable throwable) {
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}]Notify disconnect listener error,listener ={}", name,
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}] Notify disconnect listener error, listener = {}", name,
connectionEventListener.getClass().getName());
}
}
@ -204,12 +209,12 @@ public abstract class RpcClient implements Closeable {
if (connectionEventListeners.isEmpty()) {
return;
}
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]Notify connected event to listeners.", name);
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Notify connected event to listeners.", name);
for (ConnectionEventListener connectionEventListener : connectionEventListeners) {
try {
connectionEventListener.onConnected();
} catch (Throwable throwable) {
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}]Notify connect listener error,listener ={}", name,
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}] Notify connect listener error, listener = {}", name,
connectionEventListener.getClass().getName());
}
}
@ -243,7 +248,7 @@ public abstract class RpcClient implements Closeable {
}
/**
* check if current connected server is in serverlist ,if not switch server.
* check if current connected server is in server list, if not switch server.
*/
public void onServerListChange() {
if (currentConnection != null && currentConnection.serverInfo != null) {
@ -257,7 +262,7 @@ public abstract class RpcClient implements Closeable {
}
if (!found) {
LoggerUtils.printIfInfoEnabled(LOGGER,
"Current connected server {} is not in latest server list,switch switchServerAsync",
"Current connected server {} is not in latest server list, switch switchServerAsync",
serverInfo.getAddress());
switchServerAsync();
}
@ -275,110 +280,101 @@ public abstract class RpcClient implements Closeable {
return;
}
clientEventExecutor = new ScheduledThreadPoolExecutor(2, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.remote.worker");
t.setDaemon(true);
return t;
}
clientEventExecutor = new ScheduledThreadPoolExecutor(2, r -> {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.remote.worker");
t.setDaemon(true);
return t;
});
// connection event consumer.
clientEventExecutor.submit(new Runnable() {
@Override
public void run() {
while (!clientEventExecutor.isTerminated() && !clientEventExecutor.isShutdown()) {
ConnectionEvent take = null;
try {
take = eventLinkedBlockingQueue.take();
if (take.isConnected()) {
notifyConnected();
} else if (take.isDisConnected()) {
notifyDisConnected();
}
} catch (Throwable e) {
//Do nothing
clientEventExecutor.submit(() -> {
while (!clientEventExecutor.isTerminated() && !clientEventExecutor.isShutdown()) {
ConnectionEvent take;
try {
take = eventLinkedBlockingQueue.take();
if (take.isConnected()) {
notifyConnected();
} else if (take.isDisConnected()) {
notifyDisConnected();
}
} catch (Throwable e) {
// Do nothing
}
}
});
clientEventExecutor.submit(new Runnable() {
@Override
public void run() {
while (true) {
try {
if (isShutdown()) {
break;
}
ReconnectContext reconnectContext = reconnectionSignal
.poll(keepAliveTime, TimeUnit.MILLISECONDS);
if (reconnectContext == null) {
//check alive time.
if (System.currentTimeMillis() - lastActiveTimeStamp >= keepAliveTime) {
boolean isHealthy = healthCheck();
if (!isHealthy) {
if (currentConnection == null) {
continue;
}
LoggerUtils.printIfInfoEnabled(LOGGER,
"[{}]Server healthy check fail,currentConnection={}", name,
currentConnection.getConnectionId());
RpcClientStatus rpcClientStatus = RpcClient.this.rpcClientStatus.get();
if (RpcClientStatus.SHUTDOWN.equals(rpcClientStatus)) {
break;
}
boolean success = RpcClient.this.rpcClientStatus
.compareAndSet(rpcClientStatus, RpcClientStatus.UNHEALTHY);
if (success) {
reconnectContext = new ReconnectContext(null, false);
} else {
continue;
}
} else {
lastActiveTimeStamp = System.currentTimeMillis();
clientEventExecutor.submit(() -> {
while (true) {
try {
if (isShutdown()) {
break;
}
ReconnectContext reconnectContext = reconnectionSignal
.poll(keepAliveTime, TimeUnit.MILLISECONDS);
if (reconnectContext == null) {
// check alive time.
if (System.currentTimeMillis() - lastActiveTimeStamp >= keepAliveTime) {
boolean isHealthy = healthCheck();
if (!isHealthy) {
if (currentConnection == null) {
continue;
}
} else {
continue;
}
}
if (reconnectContext.serverInfo != null) {
//clear recommend server if server is not in server list.
boolean serverExist = false;
for (String server : getServerListFactory().getServerList()) {
ServerInfo serverInfo = resolveServerInfo(server);
if (serverInfo.getServerIp().equals(reconnectContext.serverInfo.getServerIp())) {
serverExist = true;
reconnectContext.serverInfo.serverPort = serverInfo.serverPort;
LoggerUtils.printIfInfoEnabled(LOGGER,
"[{}] Server healthy check fail, currentConnection = {}", name,
currentConnection.getConnectionId());
RpcClientStatus rpcClientStatus = RpcClient.this.rpcClientStatus.get();
if (RpcClientStatus.SHUTDOWN.equals(rpcClientStatus)) {
break;
}
boolean statusFLowSuccess = RpcClient.this.rpcClientStatus
.compareAndSet(rpcClientStatus, RpcClientStatus.UNHEALTHY);
if (statusFLowSuccess) {
reconnectContext = new ReconnectContext(null, false);
} else {
continue;
}
} else {
lastActiveTimeStamp = System.currentTimeMillis();
continue;
}
if (!serverExist) {
LoggerUtils.printIfInfoEnabled(LOGGER,
"[{}] Recommend server is not in server list ,ignore recommend server {}", name,
reconnectContext.serverInfo.getAddress());
reconnectContext.serverInfo = null;
} else {
continue;
}
}
if (reconnectContext.serverInfo != null) {
// clear recommend server if server is not in server list.
boolean serverExist = false;
for (String server : getServerListFactory().getServerList()) {
ServerInfo serverInfo = resolveServerInfo(server);
if (serverInfo.getServerIp().equals(reconnectContext.serverInfo.getServerIp())) {
serverExist = true;
reconnectContext.serverInfo.serverPort = serverInfo.serverPort;
break;
}
}
reconnect(reconnectContext.serverInfo, reconnectContext.onRequestFail);
} catch (Throwable throwable) {
//Do nothing
if (!serverExist) {
LoggerUtils.printIfInfoEnabled(LOGGER,
"[{}] Recommend server is not in server list, ignore recommend server {}", name,
reconnectContext.serverInfo.getAddress());
reconnectContext.serverInfo = null;
}
}
reconnect(reconnectContext.serverInfo, reconnectContext.onRequestFail);
} catch (Throwable throwable) {
// Do nothing
}
}
});
//connect to server ,try to connect to server sync once, async starting if fail.
// connect to server, try to connect to server sync RETRY_TIMES times, async starting if failed.
Connection connectToServer = null;
rpcClientStatus.set(RpcClientStatus.STARTING);
@ -394,14 +390,14 @@ public abstract class RpcClient implements Closeable {
connectToServer = connectToServer(serverInfo);
} catch (Throwable e) {
LoggerUtils.printIfWarnEnabled(LOGGER,
"[{}]Fail to connect to server on start up, error message={}, start up retry times left: {}",
"[{}] Fail to connect to server on start up, error message = {}, start up retry times left: {}",
name, e.getMessage(), startUpRetryTimes);
}
}
if (connectToServer != null) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Success to connect to server [{}] on start up,connectionId={}",
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Success to connect to server [{}] on start up, connectionId = {}",
name, connectToServer.serverInfo.getAddress(), connectToServer.getConnectionId());
this.currentConnection = connectToServer;
rpcClientStatus.set(RpcClientStatus.RUNNING);
@ -412,16 +408,13 @@ public abstract class RpcClient implements Closeable {
registerServerRequestHandler(new ConnectResetRequestHandler());
//register client detection request.
registerServerRequestHandler(new ServerRequestHandler() {
@Override
public Response requestReply(Request request) {
if (request instanceof ClientDetectionRequest) {
return new ClientDetectionResponse();
}
return null;
// register client detection request.
registerServerRequestHandler(request -> {
if (request instanceof ClientDetectionRequest) {
return new ClientDetectionResponse();
}
return null;
});
}
@ -448,7 +441,7 @@ public abstract class RpcClient implements Closeable {
}
}
} catch (Exception e) {
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}]Switch server error ,{}", name, e);
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}] Switch server error, {}", name, e);
}
return new ConnectResetResponse();
}
@ -458,11 +451,12 @@ public abstract class RpcClient implements Closeable {
@Override
public void shutdown() throws NacosException {
LOGGER.info("Shutdown rpc client ,set status to shutdown");
LOGGER.info("Shutdown rpc client, set status to shutdown");
rpcClientStatus.set(RpcClientStatus.SHUTDOWN);
LOGGER.info("Shutdown client event executor " + clientEventExecutor);
clientEventExecutor.shutdownNow();
LOGGER.info("Close current connection " + currentConnection.getConnectionId());
LOGGER.info("Shutdown client event executor " + clientEventExecutor);
if (clientEventExecutor != null) {
clientEventExecutor.shutdownNow();
}
closeConnection(currentConnection);
}
@ -473,10 +467,10 @@ public abstract class RpcClient implements Closeable {
}
try {
Response response = this.currentConnection.request(healthCheckRequest, 3000L);
//not only check server is ok ,also check connection is register.
// not only check server is ok, also check connection is register.
return response != null && response.isSuccess();
} catch (NacosException e) {
//ignore
// ignore
}
return false;
}
@ -500,16 +494,16 @@ public abstract class RpcClient implements Closeable {
try {
AtomicReference<ServerInfo> recommendServer = new AtomicReference<ServerInfo>(recommendServerInfo);
AtomicReference<ServerInfo> recommendServer = new AtomicReference<>(recommendServerInfo);
if (onRequestFail && healthCheck()) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Server check success,currentServer is{} ", name,
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Server check success, currentServer is {} ", name,
currentConnection.serverInfo.getAddress());
rpcClientStatus.set(RpcClientStatus.RUNNING);
return;
}
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] try to re connect to a new server ,server is {}", name,
recommendServerInfo == null ? " not appointed,will choose a random server."
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Try to reconnect to a new server, server is {}", name,
recommendServerInfo == null ? " not appointed, will choose a random server."
: (recommendServerInfo.getAddress() + ", will try it once."));
// loop until start client success.
@ -517,35 +511,35 @@ public abstract class RpcClient implements Closeable {
int reConnectTimes = 0;
int retryTurns = 0;
Exception lastException = null;
Exception lastException;
while (!switchSuccess && !isShutdown()) {
//1.get a new server
// 1.get a new server
ServerInfo serverInfo = null;
try {
serverInfo = recommendServer.get() == null ? nextRpcServer() : recommendServer.get();
//2.create a new channel to new server
// 2.create a new channel to new server
Connection connectionNew = connectToServer(serverInfo);
if (connectionNew != null) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] success to connect a server [{}],connectionId={}",
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Success to connect a server [{}], connectionId = {}",
name, serverInfo.getAddress(), connectionNew.getConnectionId());
//successfully create a new connect.
// successfully create a new connect.
if (currentConnection != null) {
LoggerUtils.printIfInfoEnabled(LOGGER,
"[{}] Abandon prev connection ,server is {}, connectionId is {}", name,
"[{}] Abandon prev connection, server is {}, connectionId is {}", name,
currentConnection.serverInfo.getAddress(), currentConnection.getConnectionId());
//set current connection to enable connection event.
// set current connection to enable connection event.
currentConnection.setAbandon(true);
closeConnection(currentConnection);
}
currentConnection = connectionNew;
rpcClientStatus.set(RpcClientStatus.RUNNING);
switchSuccess = true;
boolean s = eventLinkedBlockingQueue.add(new ConnectionEvent(ConnectionEvent.CONNECTED));
eventLinkedBlockingQueue.add(new ConnectionEvent(ConnectionEvent.CONNECTED));
return;
}
//close connection if client is already shutdown.
// close connection if client is already shutdown.
if (isShutdown()) {
closeConnection(currentConnection);
}
@ -561,7 +555,7 @@ public abstract class RpcClient implements Closeable {
if (reConnectTimes > 0
&& reConnectTimes % RpcClient.this.serverListFactory.getServerList().size() == 0) {
LoggerUtils.printIfInfoEnabled(LOGGER,
"[{}] fail to connect server,after trying {} times, last try server is {},error={}", name,
"[{}] Fail to connect server, after trying {} times, last try server is {}, error = {}", name,
reConnectTimes, serverInfo, lastException == null ? "unknown" : lastException);
if (Integer.MAX_VALUE == retryTurns) {
retryTurns = 50;
@ -573,27 +567,28 @@ public abstract class RpcClient implements Closeable {
reConnectTimes++;
try {
//sleep x milliseconds to switch next server.
// sleep x milliseconds to switch next server.
if (!isRunning()) {
// first round ,try servers at a delay 100ms;second round ,200ms; max delays 5s. to be reconsidered.
// first round, try servers at a delay 100ms;second round, 200ms; max delays 5s. to be reconsidered.
Thread.sleep(Math.min(retryTurns + 1, 50) * 100L);
}
} catch (InterruptedException e) {
// Do nothing.
// Do nothing.
}
}
if (isShutdown()) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Client is shutdown ,stop reconnect to server", name);
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Client is shutdown, stop reconnect to server", name);
}
} catch (Exception e) {
LoggerUtils.printIfWarnEnabled(LOGGER, "[{}] Fail to re connect to server ,error is {}", name, e);
LoggerUtils.printIfWarnEnabled(LOGGER, "[{}] Fail to reconnect to server, error is {}", name, e);
}
}
private void closeConnection(Connection connection) {
if (connection != null) {
LOGGER.info("Close current connection " + connection.getConnectionId());
connection.close();
eventLinkedBlockingQueue.add(new ConnectionEvent(ConnectionEvent.DISCONNECTED));
}
@ -643,7 +638,7 @@ public abstract class RpcClient implements Closeable {
*/
public Response request(Request request, long timeoutMills) throws NacosException {
int retryTimes = 0;
Response response = null;
Response response;
Exception exceptionThrow = null;
long start = System.currentTimeMillis();
while (retryTimes < RETRY_TIMES && System.currentTimeMillis() < timeoutMills + start) {
@ -652,7 +647,7 @@ public abstract class RpcClient implements Closeable {
if (this.currentConnection == null || !isRunning()) {
waitReconnect = true;
throw new NacosException(NacosException.CLIENT_DISCONNECT,
"Client not connected,current status:" + rpcClientStatus.get());
"Client not connected, current status:" + rpcClientStatus.get());
}
response = this.currentConnection.request(request, timeoutMills);
if (response == null) {
@ -664,7 +659,7 @@ public abstract class RpcClient implements Closeable {
waitReconnect = true;
if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) {
LoggerUtils.printIfErrorEnabled(LOGGER,
"Connection is unregistered, switch server,connectionId={},request={}",
"Connection is unregistered, switch server, connectionId = {}, request = {}",
currentConnection.getConnectionId(), request.getClass().getSimpleName());
switchServerAsync();
}
@ -680,14 +675,14 @@ public abstract class RpcClient implements Closeable {
} catch (Exception e) {
if (waitReconnect) {
try {
//wait client to re connect.
// wait client to reconnect.
Thread.sleep(Math.min(100, timeoutMills / 3));
} catch (Exception exception) {
//Do nothing.
// Do nothing.
}
}
LoggerUtils.printIfErrorEnabled(LOGGER, "Send request fail, request={}, retryTimes={},errorMessage={}",
LoggerUtils.printIfErrorEnabled(LOGGER, "Send request fail, request = {}, retryTimes = {}, errorMessage = {}",
request, retryTimes, e.getMessage());
exceptionThrow = e;
@ -731,14 +726,14 @@ public abstract class RpcClient implements Closeable {
} catch (Exception e) {
if (waitReconnect) {
try {
//wait client to re connect.
// wait client to reconnect.
Thread.sleep(Math.min(100, callback.getTimeout() / 3));
} catch (Exception exception) {
//Do nothing.
// Do nothing.
}
}
LoggerUtils
.printIfErrorEnabled(LOGGER, "[{}]Send request fail, request={}, retryTimes={},errorMessage={}",
.printIfErrorEnabled(LOGGER, "[{}] Send request fail, request = {}, retryTimes = {}, errorMessage = {}",
name, request, retryTimes, e.getMessage());
exceptionToThrow = e;
@ -779,18 +774,19 @@ public abstract class RpcClient implements Closeable {
} catch (Exception e) {
if (waitReconnect) {
try {
//wait client to re connect.
// wait client to reconnect.
Thread.sleep(100L);
} catch (Exception exception) {
//Do nothing.
// Do nothing.
}
}
LoggerUtils
.printIfErrorEnabled(LOGGER, "[{}]Send request fail, request={}, retryTimes={},errorMessage={}",
.printIfErrorEnabled(LOGGER, "[{}] Send request fail, request = {}, retryTimes = {}, errorMessage = {}",
name, request, retryTimes, e.getMessage());
exceptionToThrow = e;
}
retryTimes++;
}
if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) {
@ -823,7 +819,7 @@ public abstract class RpcClient implements Closeable {
*/
protected Response handleServerRequest(final Request request) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]receive server push request,request={},requestId={}", name,
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Receive server push request, request = {}, requestId = {}", name,
request.getClass().getSimpleName(), request.getRequestId());
lastActiveTimeStamp = System.currentTimeMillis();
for (ServerRequestHandler serverRequestHandler : serverRequestHandlers) {
@ -831,12 +827,12 @@ public abstract class RpcClient implements Closeable {
Response response = serverRequestHandler.requestReply(request);
if (response != null) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]ack server push request,request={},requestId={}", name,
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Ack server push request, request = {}, requestId = {}", name,
request.getClass().getSimpleName(), request.getRequestId());
return response;
}
} catch (Exception e) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]handleServerRequest:{}, errorMessage={}", name,
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] HandleServerRequest:{}, errorMessage = {}", name,
serverRequestHandler.getClass().getName(), e.getMessage());
}
@ -851,7 +847,7 @@ public abstract class RpcClient implements Closeable {
*/
public synchronized void registerConnectionListener(ConnectionEventListener connectionEventListener) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]Registry connection listener to current client:{}", name,
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Registry connection listener to current client:{}", name,
connectionEventListener.getClass().getName());
this.connectionEventListeners.add(connectionEventListener);
}
@ -862,7 +858,7 @@ public abstract class RpcClient implements Closeable {
* @param serverRequestHandler serverRequestHandler
*/
public synchronized void registerServerRequestHandler(ServerRequestHandler serverRequestHandler) {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]Register server push request handler:{}", name,
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}] Register server push request handler:{}", name,
serverRequestHandler.getClass().getName());
this.serverRequestHandlers.add(serverRequestHandler);
@ -913,25 +909,16 @@ public abstract class RpcClient implements Closeable {
*/
@SuppressWarnings("PMD.UndefineMagicConstantRule")
private ServerInfo resolveServerInfo(String serverAddress) {
String property = System.getProperty("nacos.server.port", "8848");
int serverPort = Integer.parseInt(property);
ServerInfo serverInfo = null;
if (serverAddress.contains(Constants.HTTP_PREFIX)) {
String[] split = serverAddress.split(Constants.COLON);
String serverIp = split[1].replaceAll("//", "");
if (split.length > 2 && StringUtils.isNotBlank(split[2])) {
serverPort = Integer.parseInt(split[2]);
}
serverInfo = new ServerInfo(serverIp, serverPort);
} else {
String[] split = serverAddress.split(Constants.COLON);
String serverIp = split[0];
if (split.length > 1 && StringUtils.isNotBlank(split[1])) {
serverPort = Integer.parseInt(split[1]);
}
serverInfo = new ServerInfo(serverIp, serverPort);
Matcher matcher = EXCLUDE_PROTOCOL_PATTERN.matcher(serverAddress);
if (matcher.find()) {
serverAddress = matcher.group(1);
}
return serverInfo;
String[] ipPortTuple = serverAddress.split(Constants.COLON, 2);
int defaultPort = Integer.parseInt(System.getProperty("nacos.server.port", "8848"));
String serverPort = CollectionUtils.getOrDefault(ipPortTuple, 1, Integer.toString(defaultPort));
return new ServerInfo(ipPortTuple[0], NumberUtils.toInt(serverPort, defaultPort));
}
public static class ServerInfo {
@ -996,7 +983,7 @@ public abstract class RpcClient implements Closeable {
@Override
public String toString() {
return "{serverIp='" + serverIp + '\'' + ", server main port=" + serverPort + '}';
return "{serverIp = '" + serverIp + '\'' + ", server main port = " + serverPort + '}';
}
}

View File

@ -28,7 +28,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* RpcClientFactory.to support muti client for diffrent modules of usage.
* RpcClientFactory.to support multi client for different modules of usage.
*
* @author liuzunfei
* @version $Id: RpcClientFactory.java, v 0.1 2020年07月14日 3:41 PM liuzunfei Exp $
@ -72,17 +72,14 @@ public class RpcClientFactory {
* @return rpc client.
*/
public static RpcClient createClient(String clientName, ConnectionType connectionType, Map<String, String> labels) {
return CLIENT_MAP.compute(clientName, (clientNameInner, client) -> {
if (client == null) {
LOGGER.info("[RpcClientFactory] create a new rpc client of " + clientName);
if (ConnectionType.GRPC.equals(connectionType)) {
client = new GrpcSdkClient(clientNameInner);
}
if (client == null) {
throw new UnsupportedOperationException("unsupported connection type :" + connectionType.getType());
}
client.labels(labels);
}
if (!ConnectionType.GRPC.equals(connectionType)) {
throw new UnsupportedOperationException("unsupported connection type :" + connectionType.getType());
}
return CLIENT_MAP.computeIfAbsent(clientName, clientNameInner -> {
LOGGER.info("[RpcClientFactory] create a new rpc client of " + clientName);
RpcClient client = new GrpcSdkClient(clientNameInner);
client.labels(labels);
return client;
});
}
@ -96,17 +93,13 @@ public class RpcClientFactory {
*/
public static RpcClient createClusterClient(String clientName, ConnectionType connectionType,
Map<String, String> labels) {
return CLIENT_MAP.compute(clientName, (clientNameInner, client) -> {
if (client == null) {
if (ConnectionType.GRPC.equals(connectionType)) {
client = new GrpcClusterClient(clientNameInner);
}
if (client == null) {
throw new UnsupportedOperationException("unsupported connection type :" + connectionType.getType());
}
client.labels(labels);
return client;
}
if (!ConnectionType.GRPC.equals(connectionType)) {
throw new UnsupportedOperationException("unsupported connection type :" + connectionType.getType());
}
return CLIENT_MAP.computeIfAbsent(clientName, clientNameInner -> {
RpcClient client = new GrpcClusterClient(clientNameInner);
client.labels(labels);
return client;
});
}

View File

@ -21,9 +21,9 @@ import com.alibaba.nacos.api.grpc.auto.BiRequestStreamGrpc;
import com.alibaba.nacos.api.grpc.auto.Payload;
import com.alibaba.nacos.api.grpc.auto.RequestGrpc;
import com.alibaba.nacos.api.remote.request.ConnectionSetupRequest;
import com.alibaba.nacos.api.remote.request.PushAckRequest;
import com.alibaba.nacos.api.remote.request.Request;
import com.alibaba.nacos.api.remote.request.ServerCheckRequest;
import com.alibaba.nacos.api.remote.response.ErrorResponse;
import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.api.remote.response.ServerCheckResponse;
import com.alibaba.nacos.common.remote.ConnectionType;
@ -31,10 +31,10 @@ import com.alibaba.nacos.common.remote.client.Connection;
import com.alibaba.nacos.common.remote.client.RpcClient;
import com.alibaba.nacos.common.remote.client.RpcClientStatus;
import com.alibaba.nacos.common.utils.LoggerUtils;
import com.alibaba.nacos.common.utils.ThreadFactoryBuilder;
import com.alibaba.nacos.common.utils.ThreadUtils;
import com.alibaba.nacos.common.utils.VersionUtils;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.grpc.CompressorRegistry;
import io.grpc.DecompressorRegistry;
import io.grpc.ManagedChannel;
@ -58,6 +58,8 @@ public abstract class GrpcClient extends RpcClient {
static final Logger LOGGER = LoggerFactory.getLogger(GrpcClient.class);
protected static final String NACOS_SERVER_GRPC_PORT_OFFSET_KEY = "nacos.server.grpc.port.offset";
private ThreadPoolExecutor grpcExecutor = null;
private static final long DEFAULT_MAX_INBOUND_MESSAGE_SIZE = 10 * 1024 * 1024L;
@ -181,7 +183,10 @@ public abstract class GrpcClient extends RpcClient {
} catch (Exception e) {
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}]Handle server request exception: {}",
grpcConn.getConnectionId(), payload.toString(), e.getMessage());
sendResponse(request.getRequestId(), false);
Response errResponse = ErrorResponse
.build(NacosException.CLIENT_ERROR, "Handle server request error");
errResponse.setRequestId(request.getRequestId());
sendResponse(errResponse);
}
}
@ -231,15 +236,6 @@ public abstract class GrpcClient extends RpcClient {
});
}
private void sendResponse(String ackId, boolean success) {
try {
PushAckRequest request = PushAckRequest.build(ackId, success);
this.currentConnection.request(request, 3000L);
} catch (Exception e) {
LOGGER.error("[{}]Error to send ack response, ackId->{}", this.currentConnection.getConnectionId(), ackId);
}
}
private void sendResponse(Response response) {
try {
((GrpcConnection) this.currentConnection).sendResponse(response);
@ -256,7 +252,7 @@ public abstract class GrpcClient extends RpcClient {
int threadNumber = ThreadUtils.getSuitableThreadCount(8);
grpcExecutor = new ThreadPoolExecutor(threadNumber, threadNumber, 10L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(10000),
new ThreadFactoryBuilder().setDaemon(true).setNameFormat("nacos-grpc-client-executor-%d")
new ThreadFactoryBuilder().daemon(true).nameFormat("nacos-grpc-client-executor-%d")
.build());
grpcExecutor.allowCoreThreadTimeOut(true);

View File

@ -24,6 +24,8 @@ package com.alibaba.nacos.common.remote.client.grpc;
*/
public class GrpcClusterClient extends GrpcClient {
private static final String NACOS_SERVER_CLUSTER_GRPC_PORT_DEFAULT_OFFSET = "1001";
/**
* Empty constructor.
*
@ -35,7 +37,8 @@ public class GrpcClusterClient extends GrpcClient {
@Override
public int rpcPortOffset() {
return 1001;
return Integer.parseInt(System.getProperty(
NACOS_SERVER_GRPC_PORT_OFFSET_KEY, NACOS_SERVER_CLUSTER_GRPC_PORT_DEFAULT_OFFSET));
}
}

View File

@ -24,6 +24,8 @@ package com.alibaba.nacos.common.remote.client.grpc;
*/
public class GrpcSdkClient extends GrpcClient {
private static final String NACOS_SERVER_GRPC_PORT_DEFAULT_OFFSET = "1000";
/**
* Empty constructor.
*
@ -35,7 +37,8 @@ public class GrpcSdkClient extends GrpcClient {
@Override
public int rpcPortOffset() {
return 1000;
return Integer.parseInt(System.getProperty(
NACOS_SERVER_GRPC_PORT_OFFSET_KEY, NACOS_SERVER_GRPC_PORT_DEFAULT_OFFSET));
}
}

View File

@ -33,7 +33,7 @@ public abstract class AbstractNacosTaskExecuteEngine<T extends NacosTask> implem
private final Logger log;
private final ConcurrentHashMap<Object, NacosTaskProcessor> taskProcessors = new ConcurrentHashMap<Object, NacosTaskProcessor>();
private final ConcurrentHashMap<Object, NacosTaskProcessor> taskProcessors = new ConcurrentHashMap<>();
private NacosTaskProcessor defaultTaskProcessor;

View File

@ -155,7 +155,7 @@ public class NacosDelayTaskExecuteEngine extends AbstractNacosTaskExecuteEngine<
retryFailedTask(taskKey, task);
}
} catch (Throwable e) {
getEngineLog().error("Nacos task execute error : " + e.toString(), e);
getEngineLog().error("Nacos task execute error ", e);
retryFailedTask(taskKey, task);
}
}

View File

@ -52,9 +52,9 @@ public final class TlsFileWatcher {
private final int checkInterval = TlsSystemConfig.tlsFileCheckInterval;
private Map<String, String> fileMd5Map = new HashMap<String, String>();
private Map<String, String> fileMd5Map = new HashMap<>();
private ConcurrentHashMap<String, FileChangeListener> watchFilesMap = new ConcurrentHashMap<String, FileChangeListener>();
private ConcurrentHashMap<String, FileChangeListener> watchFilesMap = new ConcurrentHashMap<>();
private final ScheduledExecutorService service = ExecutorFactory.Managed
.newSingleScheduledExecutorService(ClassUtils.getCanonicalName(TlsFileWatcher.class),
@ -97,28 +97,25 @@ public final class TlsFileWatcher {
*/
public void start() {
if (started.compareAndSet(false, true)) {
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
for (Map.Entry<String, FileChangeListener> item : watchFilesMap.entrySet()) {
String filePath = item.getKey();
String newHash;
InputStream in = null;
try {
in = new FileInputStream(filePath);
newHash = MD5Utils.md5Hex(IoUtils.toString(in, Constants.ENCODE), Constants.ENCODE);
} catch (Exception ignored) {
LOGGER.warn(" service has exception when calculate the file MD5. " + ignored);
continue;
} finally {
IoUtils.closeQuietly(in);
}
if (!newHash.equals(fileMd5Map.get(filePath))) {
LOGGER.info(filePath + " file hash changed,need reload sslcontext");
fileMd5Map.put(filePath, newHash);
item.getValue().onChanged(filePath);
LOGGER.info(filePath + " onChanged success!");
}
service.scheduleAtFixedRate(() -> {
for (Map.Entry<String, FileChangeListener> item : watchFilesMap.entrySet()) {
String filePath = item.getKey();
String newHash;
InputStream in = null;
try {
in = new FileInputStream(filePath);
newHash = MD5Utils.md5Hex(IoUtils.toString(in, Constants.ENCODE), Constants.ENCODE);
} catch (Exception exception) {
LOGGER.warn(" service has exception when calculate the file MD5. " + exception);
continue;
} finally {
IoUtils.closeQuietly(in);
}
if (!newHash.equals(fileMd5Map.get(filePath))) {
LOGGER.info(filePath + " file hash changed, need reload ssl context");
fileMd5Map.put(filePath, newHash);
item.getValue().onChanged(filePath);
LOGGER.info(filePath + " onChanged success!");
}
}
}, 1, checkInterval, TimeUnit.MINUTES);

View File

@ -17,11 +17,17 @@
package com.alibaba.nacos.common.utils;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* Copy from {@link org.apache.commons.collections}.
@ -231,18 +237,81 @@ public final class CollectionUtils {
* Returns the value to which the specified index , or {@code defaultValue} if this collection contains no value for
* the index.
*
* @param coll the collection to get a value from
* @param obj the object to get a value from
* @param index the index to get
* @param defaultValue default value
* @param <T> General Type
* @return the value to which the specified index , or {@code defaultValue} if this collection contains no value for
* the index.
*/
public static <T> T getOrDefault(Collection<T> coll, int index, T defaultValue) {
public static <T> T getOrDefault(Object obj, int index, T defaultValue) {
try {
return (T) get(coll, index);
return (T) get(obj, index);
} catch (IndexOutOfBoundsException e) {
return defaultValue;
}
}
/**
* return an arraylist containing all input parameters.
* @author zzq
* @param elements element array
* @return arraylist containing all input parameters
*/
public static <T> List<T> list(T... elements) {
if (elements == null) {
throw new IllegalArgumentException("Expected an array of elements (or empty array) but received a null.");
}
ArrayList<T> list = new ArrayList<>(elements.length);
Collections.addAll(list, elements);
return list;
}
/**
* Return an set containing all input parameters.
* @param elements elements element array
* @return set containing all input parameters
*/
public static <T> Set<T> set(T... elements) {
if (elements == null) {
throw new IllegalArgumentException("Expected an array of elements (or empty array) but received a null.");
} else {
return new LinkedHashSet(Arrays.asList(elements));
}
}
/**
* return the first element, if the iterator contains multiple elements,
* will throw {@code IllegalArgumentException}.
* @throws NoSuchElementException if the iterator is empty
* @throws IllegalArgumentException if the iterator contains multiple elements.
* The state of the iterator is unspecified.
*/
public static <T> T getOnlyElement(Iterable<T> iterable) {
if (iterable == null) {
throw new IllegalArgumentException("iterable cannot be null.");
}
Iterator<T> iterator = iterable.iterator();
T first = iterator.next();
if (!iterator.hasNext()) {
return first;
}
throw new IllegalArgumentException(buildExceptionMessage(iterator, first));
}
@SuppressWarnings("PMD.UndefineMagicConstantRule")
private static <T> String buildExceptionMessage(Iterator<T> iterator, T first) {
String msg = "";
msg += "expected one element but was: <";
msg += first;
for (int i = 0; i < 4 && iterator.hasNext(); i++) {
msg += ", ";
msg += iterator.next();
}
if (iterator.hasNext()) {
msg += ", ...";
}
msg += '>';
return msg;
}
}

View File

@ -16,10 +16,7 @@
package com.alibaba.nacos.common.utils;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import java.util.HashSet;
import java.util.Set;
/**
* Value Convert Utils.
@ -30,9 +27,9 @@ public final class ConvertUtils {
private static final String NULL_STR = "null";
public static final HashSet<String> TRUE_SET = Sets.newHashSet("y", "yes", "on", "true", "t");
public static final Set<String> TRUE_SET = CollectionUtils.set("y", "yes", "on", "true", "t");
public static final HashSet<String> FALSE_SET = Sets.newHashSet("n", "no", "off", "false", "f");
public static final Set<String> FALSE_SET = CollectionUtils.set("n", "no", "off", "false", "f");
/**
* Convert String value to int value if parameter value is legal. And it automatically defaults to 0 if parameter
@ -194,7 +191,7 @@ public final class ConvertUtils {
*/
@SuppressWarnings("all")
public static Boolean toBooleanObject(String str) {
String formatStr = Strings.nullToEmpty(str).toLowerCase();
String formatStr = (str == null ? StringUtils.EMPTY : str).toLowerCase();
if (TRUE_SET.contains(formatStr)) {
return true;

View File

@ -23,6 +23,7 @@ import java.util.Dictionary;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.function.BiFunction;
/**
* Map utils.

View File

@ -0,0 +1,58 @@
/*
* 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.utils;
import java.util.Objects;
/**
* Check precondition, throws an {@code IllegalArgumentException} If the conditions are not met.
* @author zzq
* @date 2021/7/29
*/
public class Preconditions {
/**
* check precondition.
* @param expression a boolean expression
* @param errorMessage the exception message to use if the check fails
* @throws IllegalArgumentException if {@code expression} is false
*/
public static void checkArgument(boolean expression, Object errorMessage) {
if (Objects.isNull(errorMessage)) {
throw new IllegalArgumentException("errorMessage cannot be null.");
}
if (!expression) {
throw new IllegalArgumentException(String.valueOf(errorMessage));
}
}
/**
* check precondition.
* @param expression a boolean expression
* @param errorMessageTemplate the exception message template to use if the check fails
* @param errorMessageArgs the arguments to be substituted into the message template.
* @throws IllegalArgumentException if {@code expression} is false
*/
public static void checkArgument(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
if (Objects.isNull(errorMessageArgs) || Objects.isNull(errorMessageTemplate)) {
throw new IllegalArgumentException("errorMessageTemplate or errorMessage cannot be null.");
}
if (!expression) {
throw new IllegalArgumentException(String.format(errorMessageTemplate, errorMessageArgs));
}
}
}

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