nacos grpc connection supports TLS Encryption (#9980)

support tls encryption on grpc transport on client and server side

---------

Co-authored-by: githubcheng2978 <yeliang.cheng@freemud.com>
This commit is contained in:
githubcheng2978 2023-03-15 09:41:25 +08:00 committed by GitHub
parent 81dda26709
commit 214e0c9077
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 3387 additions and 175 deletions

View File

@ -38,6 +38,7 @@ import com.alibaba.nacos.api.remote.RemoteConstants;
import com.alibaba.nacos.api.remote.request.Request;
import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.client.env.NacosClientProperties;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import com.alibaba.nacos.plugin.auth.api.RequestResource;
import com.alibaba.nacos.client.config.common.GroupKey;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
@ -877,13 +878,12 @@ public class ClientWorker implements Closeable {
private RpcClient ensureRpcClient(String taskId) throws NacosException {
synchronized (ClientWorker.this) {
Map<String, String> labels = getLabels();
Map<String, String> newLabels = new HashMap<>(labels);
newLabels.put("taskId", taskId);
RpcClient rpcClient = RpcClientFactory.createClient(uuid + "_config-" + taskId, getConnectionType(),
newLabels);
newLabels, RpcClientTlsConfig.properties(this.properties));
if (rpcClient.isWaitInitiated()) {
initRpcClientHandler(rpcClient);
rpcClient.setTenant(getTenant());

View File

@ -53,6 +53,7 @@ import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.remote.client.RpcClient;
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
import com.alibaba.nacos.common.remote.client.ServerListFactory;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.JacksonUtils;
@ -92,7 +93,7 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
Map<String, String> labels = new HashMap<>();
labels.put(RemoteConstants.LABEL_SOURCE, RemoteConstants.LABEL_SOURCE_SDK);
labels.put(RemoteConstants.LABEL_MODULE, RemoteConstants.LABEL_MODULE_NAMING);
this.rpcClient = RpcClientFactory.createClient(uuid, ConnectionType.GRPC, labels);
this.rpcClient = RpcClientFactory.createClient(uuid, ConnectionType.GRPC, labels, RpcClientTlsConfig.properties(properties.asProperties()));
this.redoService = new NamingGrpcRedoService(this);
start(serverListFactory, serviceInfoHolder);
}

View File

@ -0,0 +1,156 @@
/*
* 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.common.remote;
/**
* gRPC config.
*
* @author githubcheng2978
*/
public class TlsConfig {
/**
* ssl provider,default OPENSSL,JDK,OPENSSL_REFCNT.
*/
private String sslProvider = "OPENSSL";
/**
* enable tls.
*/
private Boolean enableTls = false;
/**
* tls version: TLSv1.1,TLSv1.2,TLSv1.3
* if want to support multi protocol, use comma seperated. like TLSv1.1,TLSv1.2,TLSv1.3
*/
private String protocols;
/**
* cipherList, same of usage protocols.
*/
private String ciphers;
/**
* private key.
*/
private String certPrivateKey;
/**
* certificate file.
*/
private String certChainFile;
/**
* read certPrivateKey file when need password.
*/
private String certPrivateKeyPassword;
/**
* mutualAuth,if true,need provider certPrivateKey and certChainFile.
*/
private Boolean mutualAuthEnable = false;
/**
* ignore certificate valid.
*/
private Boolean trustAll = false;
/**
* collection of trust certificate file.
*/
private String trustCollectionCertFile;
public Boolean getEnableTls() {
return enableTls;
}
public void setEnableTls(Boolean enableTls) {
this.enableTls = enableTls;
}
public Boolean getMutualAuthEnable() {
return mutualAuthEnable;
}
public void setMutualAuthEnable(Boolean mutualAuthEnable) {
this.mutualAuthEnable = mutualAuthEnable;
}
public String getProtocols() {
return protocols;
}
public void setProtocols(String protocols) {
this.protocols = protocols;
}
public Boolean getTrustAll() {
return trustAll;
}
public void setTrustAll(Boolean trustAll) {
this.trustAll = trustAll;
}
public String getCiphers() {
return ciphers;
}
public void setCiphers(String ciphers) {
this.ciphers = ciphers;
}
public String getTrustCollectionCertFile() {
return trustCollectionCertFile;
}
public void setTrustCollectionCertFile(String trustCollectionCertFile) {
this.trustCollectionCertFile = trustCollectionCertFile;
}
public String getCertPrivateKeyPassword() {
return certPrivateKeyPassword;
}
public void setCertPrivateKeyPassword(String certPrivateKeyPassword) {
this.certPrivateKeyPassword = certPrivateKeyPassword;
}
public String getCertPrivateKey() {
return certPrivateKey;
}
public void setCertPrivateKey(String certPrivateKey) {
this.certPrivateKey = certPrivateKey;
}
public String getCertChainFile() {
return certChainFile;
}
public void setCertChainFile(String certChainFile) {
this.certChainFile = certChainFile;
}
public String getSslProvider() {
return sslProvider;
}
public void setSslProvider(String sslProvider) {
this.sslProvider = sslProvider;
}
}

View File

@ -30,6 +30,8 @@ import com.alibaba.nacos.api.remote.response.ConnectResetResponse;
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.packagescan.resource.DefaultResourceLoader;
import com.alibaba.nacos.common.packagescan.resource.ResourceLoader;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.remote.PayloadRegistry;
import com.alibaba.nacos.common.utils.CollectionUtils;
@ -99,7 +101,9 @@ public abstract class RpcClient implements Closeable {
private static final Pattern EXCLUDE_PROTOCOL_PATTERN = Pattern.compile("(?<=\\w{1,5}://)(.*)");
protected RpcClientConfig rpcClientConfig;
protected final ResourceLoader resourceLoader = new DefaultResourceLoader();
static {
PayloadRegistry.init();
}

View File

@ -74,7 +74,19 @@ public class RpcClientFactory {
public static RpcClient createClient(String clientName, ConnectionType connectionType, Map<String, String> labels) {
return createClient(clientName, connectionType, null, null, labels);
}
public static RpcClient createClient(String clientName, ConnectionType connectionType, Map<String, String> labels,
RpcClientTlsConfig tlsConfig) {
return createClient(clientName, connectionType, null, null, labels, tlsConfig);
}
public static RpcClient createClient(String clientName, ConnectionType connectionType, Integer
threadPoolCoreSize,
Integer threadPoolMaxSize, Map<String, String> labels) {
return createClient(clientName, connectionType, threadPoolCoreSize, threadPoolMaxSize, labels, null);
}
/**
* create a rpc client.
*
@ -82,10 +94,12 @@ public class RpcClientFactory {
* @param connectionType client type.
* @param threadPoolCoreSize grpc thread pool core size
* @param threadPoolMaxSize grpc thread pool max size
* @param tlsConfig tlsconfig
* @return rpc client.
*/
public static RpcClient createClient(String clientName, ConnectionType connectionType, Integer threadPoolCoreSize,
Integer threadPoolMaxSize, Map<String, String> labels) {
Integer threadPoolMaxSize, Map<String, String> labels, RpcClientTlsConfig tlsConfig) {
if (!ConnectionType.GRPC.equals(connectionType)) {
throw new UnsupportedOperationException("unsupported connection type :" + connectionType.getType());
}
@ -93,7 +107,7 @@ public class RpcClientFactory {
return CLIENT_MAP.computeIfAbsent(clientName, clientNameInner -> {
LOGGER.info("[RpcClientFactory] create a new rpc client of " + clientName);
try {
return new GrpcSdkClient(clientNameInner, threadPoolCoreSize, threadPoolMaxSize, labels);
return new GrpcSdkClient(clientNameInner, threadPoolCoreSize, threadPoolMaxSize, labels, tlsConfig);
} catch (Throwable throwable) {
LOGGER.error("Error to init GrpcSdkClient for client name :" + clientName, throwable);
throw throwable;
@ -110,10 +124,15 @@ public class RpcClientFactory {
* @return rpc client.
*/
public static RpcClient createClusterClient(String clientName, ConnectionType connectionType,
Map<String, String> labels) {
Map<String, String> labels) {
return createClusterClient(clientName, connectionType, null, null, labels);
}
public static RpcClient createClusterClient(String clientName, ConnectionType connectionType,
Map<String, String> labels, RpcClientTlsConfig tlsConfig) {
return createClusterClient(clientName, connectionType, null, null, labels, tlsConfig);
}
/**
* create a rpc client.
*
@ -124,14 +143,29 @@ public class RpcClientFactory {
* @return rpc client.
*/
public static RpcClient createClusterClient(String clientName, ConnectionType connectionType,
Integer threadPoolCoreSize, Integer threadPoolMaxSize, Map<String, String> labels) {
Integer threadPoolCoreSize, Integer threadPoolMaxSize, Map<String, String> labels) {
return createClusterClient(clientName, connectionType, threadPoolCoreSize, threadPoolMaxSize, labels, null);
}
/**
* createClusterClient.
* @param clientName client name.
* @param connectionType connectionType.
* @param threadPoolCoreSize coreSize.
* @param threadPoolMaxSize threadPoolSize.
* @param labels tables.
* @param tlsConfig tlsConfig.
* @return
*/
public static RpcClient createClusterClient(String clientName, ConnectionType connectionType, Integer threadPoolCoreSize,
Integer threadPoolMaxSize, Map<String, String> labels, RpcClientTlsConfig tlsConfig) {
if (!ConnectionType.GRPC.equals(connectionType)) {
throw new UnsupportedOperationException("unsupported connection type :" + connectionType.getType());
}
return CLIENT_MAP.computeIfAbsent(clientName,
clientNameInner -> new GrpcClusterClient(clientNameInner, threadPoolCoreSize, threadPoolMaxSize,
labels));
labels, tlsConfig));
}
}

View File

@ -0,0 +1,85 @@
/*
* 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.common.remote.client;
import com.alibaba.nacos.common.remote.TlsConfig;
import java.util.Properties;
/**
* gRPC config for sdk.
*
* @author githubcheng2978
*/
public class RpcClientTlsConfig extends TlsConfig {
/**
* get tls config from properties.
* @param properties Properties.
* @return tls of config.
*/
public static RpcClientTlsConfig properties(Properties properties) {
RpcClientTlsConfig tlsConfig = new RpcClientTlsConfig();
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_ENABLE)) {
tlsConfig.setEnableTls(Boolean.parseBoolean(
properties.getProperty(RpcConstants.RPC_CLIENT_TLS_ENABLE)));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_PROVIDER)) {
tlsConfig.setSslProvider(properties.getProperty(RpcConstants.RPC_CLIENT_TLS_PROVIDER));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_MUTUAL_AUTH)) {
tlsConfig.setMutualAuthEnable(Boolean.parseBoolean(
properties.getProperty(RpcConstants.RPC_CLIENT_MUTUAL_AUTH)));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_PROTOCOLS)) {
tlsConfig.setProtocols(RpcConstants.RPC_CLIENT_TLS_PROTOCOLS);
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_CIPHERS)) {
tlsConfig.setCiphers(properties.getProperty(RpcConstants.RPC_CLIENT_TLS_CIPHERS));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH)) {
tlsConfig.setTrustCollectionCertFile(properties.getProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_CERT_CHAIN_PATH)) {
tlsConfig.setCertChainFile(properties.getProperty(RpcConstants.RPC_CLIENT_TLS_CERT_CHAIN_PATH));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_CERT_KEY)) {
tlsConfig.setCertPrivateKey(properties.getProperty(RpcConstants.RPC_CLIENT_TLS_CERT_KEY));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_TRUST_ALL)) {
tlsConfig.setTrustAll(Boolean.parseBoolean(properties.getProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_ALL)));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_TRUST_PWD)) {
tlsConfig.setCertPrivateKeyPassword(properties.getProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_PWD));
}
if (properties.containsKey(RpcConstants.RPC_CLIENT_TLS_PROVIDER)) {
tlsConfig.setSslProvider(properties.getProperty(RpcConstants.RPC_CLIENT_TLS_PROVIDER));
}
return tlsConfig;
}
}

View File

@ -0,0 +1,97 @@
/*
* 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.common.remote.client;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* RpcConstants.
*
* @author githubcheng2978.
*/
public class RpcConstants {
public static final String NACOS_CLIENT_RPC = "nacos.remote.client.rpc";
@RpcConfigLabel
public static final String RPC_CLIENT_TLS_ENABLE = NACOS_CLIENT_RPC + ".tls.enable";
@RpcConfigLabel
public static final String RPC_CLIENT_TLS_PROVIDER = NACOS_CLIENT_RPC + ".tls.provider";
@RpcConfigLabel
public static final String RPC_CLIENT_MUTUAL_AUTH = NACOS_CLIENT_RPC + ".tls.mutualAuth";
@RpcConfigLabel
public static final String RPC_CLIENT_TLS_PROTOCOLS = NACOS_CLIENT_RPC + ".tls.protocols";
@RpcConfigLabel
public static final String RPC_CLIENT_TLS_CIPHERS = NACOS_CLIENT_RPC + ".tls.ciphers";
@RpcConfigLabel
public static final String RPC_CLIENT_TLS_CERT_CHAIN_PATH = NACOS_CLIENT_RPC + ".tls.certChainFile";
@RpcConfigLabel
public static final String RPC_CLIENT_TLS_CERT_KEY = NACOS_CLIENT_RPC + ".tls.certPrivateKey";
@RpcConfigLabel
public static final String RPC_CLIENT_TLS_TRUST_PWD = NACOS_CLIENT_RPC + ".tls.certPrivateKeyPassword";
@RpcConfigLabel
public static final String RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH = NACOS_CLIENT_RPC + ".tls.trustCollectionChainPath";
@RpcConfigLabel
public static final String RPC_CLIENT_TLS_TRUST_ALL = NACOS_CLIENT_RPC + ".tls.trustAll";
private static final Set<String> CONFIG_NAMES = new HashSet<>();
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
protected @interface RpcConfigLabel {
}
static {
Class clazz = RpcConstants.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
if (declaredField.getType().equals(String.class) && null != declaredField.getAnnotation(
RpcConfigLabel.class)) {
try {
CONFIG_NAMES.add((String) declaredField.get(null));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
public static Set<String> getRpcParams() {
return Collections.unmodifiableSet(CONFIG_NAMES);
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.common.remote.client.grpc;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import com.alibaba.nacos.common.utils.ThreadUtils;
import java.util.HashMap;
@ -60,7 +61,9 @@ public class DefaultGrpcClientConfig implements GrpcClientConfig {
private long healthCheckTimeOut;
private Map<String, String> labels;
private RpcClientTlsConfig tlsConfig = new RpcClientTlsConfig();
/**
* constructor.
*
@ -88,6 +91,9 @@ public class DefaultGrpcClientConfig implements GrpcClientConfig {
this.channelKeepAliveTimeout = loadLongConfig(GrpcConstants.GRPC_CHANNEL_KEEP_ALIVE_TIMEOUT,
builder.channelKeepAliveTimeout);
this.labels = builder.labels;
if (Objects.nonNull(builder.tlsConfig)) {
this.tlsConfig = builder.tlsConfig;
}
}
private int loadIntegerConfig(String key, int builderValue) {
@ -157,17 +163,26 @@ public class DefaultGrpcClientConfig implements GrpcClientConfig {
public long channelKeepAliveTimeout() {
return channelKeepAliveTimeout;
}
@Override
public RpcClientTlsConfig tlsConfig() {
return tlsConfig;
}
public void setTlsConfig(RpcClientTlsConfig tlsConfig) {
this.tlsConfig = tlsConfig;
}
@Override
public int healthCheckRetryTimes() {
return healthCheckRetryTimes;
}
@Override
public long healthCheckTimeOut() {
return healthCheckTimeOut;
}
@Override
public Map<String, String> labels() {
return this.labels;
@ -208,7 +223,9 @@ public class DefaultGrpcClientConfig implements GrpcClientConfig {
private long healthCheckTimeOut = 3000L;
private Map<String, String> labels = new HashMap<>();
private RpcClientTlsConfig tlsConfig = new RpcClientTlsConfig();
private Builder() {
}
@ -271,7 +288,7 @@ public class DefaultGrpcClientConfig implements GrpcClientConfig {
this.channelKeepAliveTimeout = Integer.parseInt(
properties.getProperty(GrpcConstants.GRPC_CHANNEL_KEEP_ALIVE_TIMEOUT));
}
this.tlsConfig = RpcClientTlsConfig.properties(properties);
return this;
}
@ -401,7 +418,18 @@ public class DefaultGrpcClientConfig implements GrpcClientConfig {
this.labels.putAll(labels);
return this;
}
/**
* set tlsConfig.
*
* @param tlsConfig tls of client.
* @return
*/
public Builder setTlsConfig(RpcClientTlsConfig tlsConfig) {
this.tlsConfig = tlsConfig;
return this;
}
/**
* build GrpcClientConfig.
*/
@ -409,5 +437,5 @@ public class DefaultGrpcClientConfig implements GrpcClientConfig {
return new DefaultGrpcClientConfig(this);
}
}
}

View File

@ -26,23 +26,37 @@ 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.packagescan.resource.Resource;
import com.alibaba.nacos.common.remote.ConnectionType;
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.remote.client.Connection;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import com.alibaba.nacos.common.remote.client.ServerListFactory;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.LoggerUtils;
import com.alibaba.nacos.common.utils.ThreadFactoryBuilder;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.common.utils.VersionUtils;
import com.alibaba.nacos.common.utils.TlsTypeResolve;
import com.alibaba.nacos.common.utils.ThreadFactoryBuilder;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
import io.grpc.CompressorRegistry;
import io.grpc.DecompressorRegistry;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.shaded.io.grpc.netty.NegotiationType;
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder;
import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.grpc.stub.StreamObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.LinkedBlockingQueue;
@ -57,18 +71,18 @@ import java.util.concurrent.TimeUnit;
*/
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class GrpcClient extends RpcClient {
private static final Logger LOGGER = LoggerFactory.getLogger(GrpcClient.class);
private final GrpcClientConfig clientConfig;
private ThreadPoolExecutor grpcExecutor;
@Override
public ConnectionType getConnectionType() {
return ConnectionType.GRPC;
}
/**
* constructor.
*
@ -77,7 +91,7 @@ public abstract class GrpcClient extends RpcClient {
public GrpcClient(String name) {
this(DefaultGrpcClientConfig.newBuilder().setName(name).build());
}
/**
* constructor.
*
@ -86,7 +100,7 @@ public abstract class GrpcClient extends RpcClient {
public GrpcClient(Properties properties) {
this(DefaultGrpcClientConfig.newBuilder().fromProperties(properties).build());
}
/**
* constructor.
*
@ -96,7 +110,7 @@ public abstract class GrpcClient extends RpcClient {
super(clientConfig);
this.clientConfig = clientConfig;
}
/**
* constructor.
*
@ -107,7 +121,7 @@ public abstract class GrpcClient extends RpcClient {
super(clientConfig, serverListFactory);
this.clientConfig = clientConfig;
}
/**
* constructor.
*
@ -120,7 +134,12 @@ public abstract class GrpcClient extends RpcClient {
this(DefaultGrpcClientConfig.newBuilder().setName(name).setThreadPoolCoreSize(threadPoolCoreSize)
.setThreadPoolMaxSize(threadPoolMaxSize).setLabels(labels).build());
}
public GrpcClient(String name, Integer threadPoolCoreSize, Integer threadPoolMaxSize, Map<String, String> labels, RpcClientTlsConfig tlsConfig) {
this(DefaultGrpcClientConfig.newBuilder().setName(name).setThreadPoolCoreSize(threadPoolCoreSize).setTlsConfig(tlsConfig)
.setThreadPoolMaxSize(threadPoolMaxSize).setLabels(labels).build());
}
protected ThreadPoolExecutor createGrpcExecutor(String serverIp) {
// Thread name will use String.format, ipv6 maybe contain special word %, so handle it first.
serverIp = serverIp.replaceAll("%", "-");
@ -132,7 +151,7 @@ public abstract class GrpcClient extends RpcClient {
grpcExecutor.allowCoreThreadTimeOut(true);
return grpcExecutor;
}
@Override
public void shutdown() throws NacosException {
super.shutdown();
@ -141,7 +160,7 @@ public abstract class GrpcClient extends RpcClient {
grpcExecutor.shutdown();
}
}
/**
* Create a stub using a channel.
*
@ -151,7 +170,7 @@ public abstract class GrpcClient extends RpcClient {
private RequestGrpc.RequestFutureStub createNewChannelStub(ManagedChannel managedChannelTemp) {
return RequestGrpc.newFutureStub(managedChannelTemp);
}
/**
* create a new channel with specific server address.
*
@ -160,15 +179,17 @@ public abstract class GrpcClient extends RpcClient {
* @return if server check success,return a non-null channel.
*/
private ManagedChannel createNewManagedChannel(String serverIp, int serverPort) {
ManagedChannelBuilder<?> managedChannelBuilder = ManagedChannelBuilder.forAddress(serverIp, serverPort)
LOGGER.info("grpc client connection server:{} ip,serverPort:{},grpcTslConfig:{}", serverIp, serverPort,
JacksonUtils.toJson(clientConfig.tlsConfig()));
ManagedChannelBuilder<?> managedChannelBuilder = buildChannel(serverIp, serverPort, buildSslContext())
.executor(grpcExecutor).compressorRegistry(CompressorRegistry.getDefaultInstance())
.decompressorRegistry(DecompressorRegistry.getDefaultInstance())
.maxInboundMessageSize(clientConfig.maxInboundMessageSize())
.keepAliveTime(clientConfig.channelKeepAlive(), TimeUnit.MILLISECONDS)
.keepAliveTimeout(clientConfig.channelKeepAliveTimeout(), TimeUnit.MILLISECONDS).usePlaintext();
.keepAliveTimeout(clientConfig.channelKeepAliveTimeout(), TimeUnit.MILLISECONDS);
return managedChannelBuilder.build();
}
/**
* shutdown a channel.
*
@ -179,7 +200,7 @@ public abstract class GrpcClient extends RpcClient {
managedChannel.shutdownNow();
}
}
/**
* check server if success.
*
@ -203,22 +224,22 @@ public abstract class GrpcClient extends RpcClient {
return null;
}
}
private StreamObserver<Payload> bindRequestStream(final BiRequestStreamGrpc.BiRequestStreamStub streamStub,
final GrpcConnection grpcConn) {
final GrpcConnection grpcConn) {
return streamStub.requestBiStream(new StreamObserver<Payload>() {
@Override
public void onNext(Payload payload) {
LoggerUtils.printIfDebugEnabled(LOGGER, "[{}]Stream server request receive, original info: {}",
grpcConn.getConnectionId(), payload.toString());
try {
Object parseBody = GrpcUtils.parse(payload);
final Request request = (Request) parseBody;
if (request != null) {
try {
Response response = handleServerRequest(request);
if (response != null) {
@ -228,7 +249,7 @@ public abstract class GrpcClient extends RpcClient {
LOGGER.warn("[{}]Fail to process server request, ackId->{}", grpcConn.getConnectionId(),
request.getRequestId());
}
} catch (Exception e) {
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}]Handle server request exception: {}",
grpcConn.getConnectionId(), payload.toString(), e.getMessage());
@ -237,16 +258,16 @@ public abstract class GrpcClient extends RpcClient {
errResponse.setRequestId(request.getRequestId());
sendResponse(errResponse);
}
}
} catch (Exception e) {
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}]Error to process server push response: {}",
grpcConn.getConnectionId(), payload.getBody().getValue().toStringUtf8());
}
}
@Override
public void onError(Throwable throwable) {
boolean isRunning = isRunning();
@ -257,14 +278,14 @@ public abstract class GrpcClient extends RpcClient {
if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) {
switchServerAsync();
}
} else {
LoggerUtils.printIfWarnEnabled(LOGGER, "[{}]Ignore error event,isRunning:{},isAbandon={}",
grpcConn.getConnectionId(), isRunning, isAbandon);
}
}
@Override
public void onCompleted() {
boolean isRunning = isRunning();
@ -275,16 +296,16 @@ public abstract class GrpcClient extends RpcClient {
if (rpcClientStatus.compareAndSet(RpcClientStatus.RUNNING, RpcClientStatus.UNHEALTHY)) {
switchServerAsync();
}
} else {
LoggerUtils.printIfInfoEnabled(LOGGER, "[{}]Ignore complete event,isRunning:{},isAbandon={}",
grpcConn.getConnectionId(), isRunning, isAbandon);
}
}
});
}
private void sendResponse(Response response) {
try {
((GrpcConnection) this.currentConnection).sendResponse(response);
@ -293,7 +314,7 @@ public abstract class GrpcClient extends RpcClient {
response.getRequestId());
}
}
@Override
public Connection connectToServer(ServerInfo serverInfo) {
try {
@ -304,21 +325,21 @@ public abstract class GrpcClient extends RpcClient {
ManagedChannel managedChannel = createNewManagedChannel(serverInfo.getServerIp(), port);
RequestGrpc.RequestFutureStub newChannelStubTemp = createNewChannelStub(managedChannel);
if (newChannelStubTemp != null) {
Response response = serverCheck(serverInfo.getServerIp(), port, newChannelStubTemp);
if (response == null || !(response instanceof ServerCheckResponse)) {
shuntDownChannel(managedChannel);
return null;
}
BiRequestStreamGrpc.BiRequestStreamStub biRequestStreamStub = BiRequestStreamGrpc.newStub(
newChannelStubTemp.getChannel());
GrpcConnection grpcConn = new GrpcConnection(serverInfo, grpcExecutor);
grpcConn.setConnectionId(((ServerCheckResponse) response).getConnectionId());
//create stream request and bind connection event to this connection.
StreamObserver<Payload> payloadStreamObserver = bindRequestStream(biRequestStreamStub, grpcConn);
// stream observer to send response to server
grpcConn.setPayloadStreamObserver(payloadStreamObserver);
grpcConn.setGrpcFutureServiceStub(newChannelStubTemp);
@ -340,7 +361,57 @@ public abstract class GrpcClient extends RpcClient {
}
return null;
}
private ManagedChannelBuilder buildChannel(String serverIp, int port, Optional<SslContext> sslContext) {
if (sslContext.isPresent()) {
return NettyChannelBuilder.forAddress(serverIp, port)
.negotiationType(NegotiationType.TLS)
.sslContext(sslContext.get());
} else {
return ManagedChannelBuilder
.forAddress(serverIp, port).usePlaintext();
}
}
private Optional<SslContext> buildSslContext() {
RpcClientTlsConfig tlsConfig = clientConfig.tlsConfig();
if (!tlsConfig.getEnableTls()) {
return Optional.absent();
}
try {
SslContextBuilder builder = GrpcSslContexts.forClient();
builder.sslProvider(TlsTypeResolve.getSslProvider(tlsConfig.getSslProvider()));
if (StringUtils.isNotBlank(tlsConfig.getProtocols())) {
builder.protocols(tlsConfig.getProtocols().split(","));
}
if (StringUtils.isNotBlank(tlsConfig.getCiphers())) {
builder.ciphers(Arrays.asList(tlsConfig.getCiphers().split(",")));
}
if (tlsConfig.getTrustAll()) {
builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
} else {
if (StringUtils.isBlank(tlsConfig.getTrustCollectionCertFile())) {
throw new IllegalArgumentException("trustCollectionCertFile must be not null");
}
Resource resource = resourceLoader.getResource(tlsConfig.getTrustCollectionCertFile());
builder.trustManager(resource.getInputStream());
}
if (tlsConfig.getMutualAuthEnable()) {
if (StringUtils.isBlank(tlsConfig.getCertChainFile()) || StringUtils.isBlank(tlsConfig.getCertPrivateKey())) {
throw new IllegalArgumentException("client certChainFile or certPrivateKey must be not null");
}
Resource certChainFile = resourceLoader.getResource(tlsConfig.getCertChainFile());
Resource privateKey = resourceLoader.getResource(tlsConfig.getCertPrivateKey());
builder.keyManager(certChainFile.getInputStream(), privateKey.getInputStream(), tlsConfig.getCertPrivateKeyPassword());
}
return Optional.of(builder.build());
} catch (Exception e) {
throw new RuntimeException("Unable to build SslContext", e);
}
}
}

View File

@ -17,6 +17,7 @@
package com.alibaba.nacos.common.remote.client.grpc;
import com.alibaba.nacos.common.remote.client.RpcClientConfig;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
/**
* GrpcCleint config. Use to collect and init Grpc client configuration.
@ -77,7 +78,22 @@ public interface GrpcClientConfig extends RpcClientConfig {
/**
* get channelKeepAliveTimeout.
*
* @return channelKeepAliveTimeout
* @return channelKeepAliveTimeout.
*/
long channelKeepAliveTimeout();
/**
* getTlsConfig.
*
* @return TlsConfig.
*/
RpcClientTlsConfig tlsConfig();
/**
*Set TlsConfig.
*
* @param tlsConfig tlsConfig of client.
*/
void setTlsConfig(RpcClientTlsConfig tlsConfig);
}

View File

@ -17,6 +17,7 @@
package com.alibaba.nacos.common.remote.client.grpc;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import java.util.Map;
import java.util.Properties;
@ -65,10 +66,15 @@ public class GrpcClusterClient extends GrpcClient {
* @param labels .
*/
public GrpcClusterClient(String name, Integer threadPoolCoreSize, Integer threadPoolMaxSize,
Map<String, String> labels) {
super(name, threadPoolCoreSize, threadPoolMaxSize, labels);
Map<String, String> labels) {
this(name, threadPoolCoreSize, threadPoolMaxSize, labels, null);
}
public GrpcClusterClient(String name, Integer threadPoolCoreSize, Integer threadPoolMaxSize,
Map<String, String> labels, RpcClientTlsConfig tlsConfig) {
super(name, threadPoolCoreSize, threadPoolMaxSize, labels, tlsConfig);
}
@Override
public int rpcPortOffset() {
return Integer.parseInt(System.getProperty(GrpcConstants.NACOS_SERVER_GRPC_PORT_OFFSET_KEY,

View File

@ -78,7 +78,7 @@ public class GrpcConstants {
@GRpcConfigLabel
public static final String GRPC_CHANNEL_KEEP_ALIVE_TIMEOUT = NACOS_CLIENT_GRPC + ".channel.keep.alive.timeout";
private static final Set<String> CONFIG_NAMES = new HashSet<>();
@Documented

View File

@ -17,6 +17,7 @@
package com.alibaba.nacos.common.remote.client.grpc;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import java.util.Map;
import java.util.Properties;
@ -55,11 +56,15 @@ public class GrpcSdkClient extends GrpcClient {
* @param threadPoolMaxSize .
* @param labels .
*/
public GrpcSdkClient(String name, Integer threadPoolCoreSize, Integer threadPoolMaxSize,
Map<String, String> labels) {
super(name, threadPoolCoreSize, threadPoolMaxSize, labels);
public GrpcSdkClient(String name, Integer threadPoolCoreSize, Integer threadPoolMaxSize, Map<String, String> labels) {
this(name, threadPoolCoreSize, threadPoolMaxSize, labels, null);
}
public GrpcSdkClient(String name, Integer threadPoolCoreSize, Integer threadPoolMaxSize, Map<String, String> labels,
RpcClientTlsConfig tlsConfig) {
super(name, threadPoolCoreSize, threadPoolMaxSize, labels, tlsConfig);
}
/**
* constructor.
*

View File

@ -0,0 +1,46 @@
/*
* 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 io.grpc.netty.shaded.io.netty.handler.ssl.SslProvider;
/**
* gRPC config for sdk.
*
* @author githubcheng2978
*/
public class TlsTypeResolve {
/**
* JDK SSL is very slower than OPENSSL, recommend use openSSl.
*
* @param provider name of ssl provider.
* @return SslProvider.
*/
public static SslProvider getSslProvider(String provider) {
if (SslProvider.OPENSSL.name().equalsIgnoreCase(provider)) {
return SslProvider.OPENSSL;
}
if (SslProvider.JDK.name().equalsIgnoreCase(provider)) {
return SslProvider.JDK;
}
if (SslProvider.OPENSSL_REFCNT.name().equalsIgnoreCase(provider)) {
return SslProvider.OPENSSL_REFCNT;
}
return SslProvider.OPENSSL;
}
}

View File

@ -25,6 +25,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.lang.reflect.Field;
@ -39,12 +40,15 @@ import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class RpcClientFactoryTest {
static Field clientMapField;
@Mock
RpcClient rpcClient;
@Mock(lenient = true)
RpcClientTlsConfig tlsConfig;
@BeforeClass
public static void setUpBeforeClass() throws NoSuchFieldException, IllegalAccessException {
clientMapField = RpcClientFactory.class.getDeclaredField("CLIENT_MAP");
@ -53,116 +57,132 @@ public class RpcClientFactoryTest {
modifiersField1.setAccessible(true);
modifiersField1.setInt(clientMapField, clientMapField.getModifiers() & ~Modifier.FINAL);
}
@After
public void tearDown() throws IllegalAccessException {
clientMapField.set(null, new ConcurrentHashMap<>());
}
@Test
public void testGetAllClientEntries() throws IllegalAccessException {
Assert.assertTrue(RpcClientFactory.getAllClientEntries().isEmpty());
clientMapField.set(null, Collections.singletonMap("testClient", rpcClient));
Assert.assertEquals(1, RpcClientFactory.getAllClientEntries().size());
}
@Test
public void testDestroyClientWhenClientExistThenRemoveAndShutDownRpcClient()
throws IllegalAccessException, NacosException {
clientMapField.set(null, new ConcurrentHashMap<>(Collections.singletonMap("testClient", rpcClient)));
RpcClientFactory.destroyClient("testClient");
Assert.assertTrue(RpcClientFactory.getAllClientEntries().isEmpty());
verify(rpcClient).shutdown();
}
@Test
public void testDestroyClientWhenClientNotExistThenDoNothing() throws IllegalAccessException, NacosException {
clientMapField.set(null, new ConcurrentHashMap<>(Collections.singletonMap("testClient", rpcClient)));
RpcClientFactory.destroyClient("notExistClientName");
Map.Entry<String, RpcClient> element = CollectionUtils.getOnlyElement(RpcClientFactory.getAllClientEntries());
Assert.assertEquals("testClient", element.getKey());
Assert.assertEquals(rpcClient, element.getValue());
verify(rpcClient, times(0)).shutdown();
}
@Test
public void testGetClient() throws IllegalAccessException {
// may be null
Assert.assertNull(RpcClientFactory.getClient("notExistClientName"));
clientMapField.set(null, new ConcurrentHashMap<>(Collections.singletonMap("testClient", rpcClient)));
Assert.assertEquals(rpcClient, RpcClientFactory.getClient("testClient"));
}
@Test
public void testCreateClientWhenNotCreatedThenCreate() {
RpcClient client = RpcClientFactory
.createClient("testClient", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"));
Assert.assertEquals(Collections.singletonMap("labelKey", "labelValue"), client.rpcClientConfig.labels());
Assert.assertEquals(ConnectionType.GRPC, client.getConnectionType());
Assert.assertEquals("testClient", CollectionUtils.getOnlyElement(RpcClientFactory.getAllClientEntries()).getKey());
}
@Test
public void testCreateClientWhenAlreadyCreatedThenNotCreateAgain() {
RpcClient client1 = RpcClientFactory
.createClient("testClient", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"));
RpcClient client2 = RpcClientFactory
.createClient("testClient", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"));
Assert.assertEquals(client1, client2);
Assert.assertEquals(1, RpcClientFactory.getAllClientEntries().size());
}
@Test(expected = Exception.class)
public void testCreatedClientWhenConnectionTypeNotMappingThenThrowException() {
RpcClientFactory.createClient("testClient", mock(ConnectionType.class),
Collections.singletonMap("labelKey", "labelValue"));
}
@Test
public void testCreateClusterClientWhenNotCreatedThenCreate() {
RpcClient client = RpcClientFactory.createClusterClient(
"testClient",
"testClient",
ConnectionType.GRPC,
Collections.singletonMap("labelKey", "labelValue")
);
Assert.assertEquals(Collections.singletonMap("labelKey", "labelValue"), client.rpcClientConfig.labels());
Assert.assertEquals(ConnectionType.GRPC, client.getConnectionType());
Assert.assertEquals("testClient", CollectionUtils.getOnlyElement(RpcClientFactory.getAllClientEntries()).getKey());
}
@Test
public void testCreateClusterClientWhenAlreadyCreatedThenNotCreateAgain() {
RpcClient client1 = RpcClientFactory.createClusterClient(
"testClient",
"testClient",
ConnectionType.GRPC,
Collections.singletonMap("labelKey", "labelValue")
);
RpcClient client2 = RpcClientFactory.createClusterClient(
"testClient",
"testClient",
ConnectionType.GRPC,
Collections.singletonMap("labelKey", "labelValue")
);
Assert.assertEquals(client1, client2);
Assert.assertEquals(1, RpcClientFactory.getAllClientEntries().size());
}
@Test(expected = Exception.class)
public void testCreatedClusterClientWhenConnectionTypeNotMappingThenThrowException() {
RpcClientFactory.createClusterClient(
"testClient",
mock(ConnectionType.class),
Collections.singletonMap("labelKey", "labelValue")
);
RpcClientFactory.createClusterClient("testClient", mock(ConnectionType.class),
Collections.singletonMap("labelKey", "labelValue"));
}
@Test
public void testCreateClusterClientTsl() {
Mockito.when(tlsConfig.getEnableTls()).thenReturn(true);
RpcClient client = RpcClientFactory.createClusterClient("testClient",
ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), tlsConfig);
Assert.assertEquals(Collections.singletonMap("labelKey", "labelValue"), client.rpcClientConfig.labels());
Assert.assertEquals(ConnectionType.GRPC, client.getConnectionType());
Assert.assertEquals("testClient", CollectionUtils.getOnlyElement(RpcClientFactory.getAllClientEntries()).getKey());
}
@Test
public void testCreateClientTsl() {
Mockito.when(tlsConfig.getEnableTls()).thenReturn(true);
RpcClient client = RpcClientFactory.createClient(
"testClient", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), tlsConfig);
Assert.assertEquals(Collections.singletonMap("labelKey", "labelValue"), client.rpcClientConfig.labels());
Assert.assertEquals(ConnectionType.GRPC, client.getConnectionType());
Assert.assertEquals("testClient", CollectionUtils.getOnlyElement(RpcClientFactory.getAllClientEntries()).getKey());
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.common.remote.client;
import org.junit.Test;
import java.lang.reflect.Field;
import static org.junit.Assert.assertEquals;
public class RpcConstantsTest {
@Test
public void testGetRpcParams() {
Class clazz = RpcConstants.class;
Field[] declaredFields = clazz.getDeclaredFields();
int i = 0;
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
if (declaredField.getType().equals(String.class) && null != declaredField.getAnnotation(
RpcConstants.RpcConfigLabel.class)) {
i++;
}
}
assertEquals(i, RpcConstants.getRpcParams().size());
}
}

View File

@ -18,41 +18,45 @@ package com.alibaba.nacos.common.remote.client.grpc;
import com.alibaba.nacos.api.grpc.auto.RequestGrpc;
import com.alibaba.nacos.common.remote.client.RpcClient;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import io.grpc.ManagedChannel;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class GrpcClientTest {
GrpcClient grpcClient;
Method createNewManagedChannelMethod;
Method createNewChannelStubMethod;
ManagedChannel managedChannel;
RpcClient.ServerInfo serverInfo;
@Before
public void setUp() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
GrpcClientConfig clientConfig = DefaultGrpcClientConfig.newBuilder().setName("testClient").build();
grpcClient = spy(new GrpcClient(clientConfig) {
@Override
public int rpcPortOffset() {
return 1000;
}
});
protected GrpcClient grpcClient;
@Mock(lenient = true)
RpcClientTlsConfig tlsConfig;
protected Method createNewManagedChannelMethod;
protected Method createNewChannelStubMethod;
protected ManagedChannel managedChannel;
protected RpcClient.ServerInfo serverInfo;
@Mock(lenient = true)
protected GrpcClientConfig clientConfig;
protected void init() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
when(clientConfig.channelKeepAlive()).thenReturn(6 * 60 * 1000);
when(clientConfig.channelKeepAliveTimeout()).thenReturn(TimeUnit.SECONDS.toMillis(20L));
RpcClient.ServerInfo serverInfo = spy(new RpcClient.ServerInfo("10.10.10.10", 8848));
createNewManagedChannelMethod = GrpcClient.class.getDeclaredMethod("createNewManagedChannel", String.class,
int.class);
@ -61,13 +65,27 @@ public class GrpcClientTest {
managedChannel = (ManagedChannel) createNewManagedChannelMethod.invoke(grpcClient, serverInfo.getServerIp(),
port);
}
@Before
public void setUp() throws Exception {
when(clientConfig.name()).thenReturn("testClient");
grpcClient = spy(new GrpcClient(clientConfig) {
@Override
public int rpcPortOffset() {
return 1000;
}
});
when(clientConfig.tlsConfig()).thenReturn(tlsConfig);
init();
}
@Test
public void testCreateNewManagedChannel() throws InvocationTargetException, IllegalAccessException {
GrpcConnection grpcConnection = new GrpcConnection(serverInfo, null);
grpcConnection.setChannel(managedChannel);
}
@Test
public void createNewChannelStub() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
createNewChannelStubMethod = GrpcClient.class.getDeclaredMethod("createNewChannelStub", ManagedChannel.class);
@ -75,10 +93,10 @@ public class GrpcClientTest {
Object invoke = createNewChannelStubMethod.invoke(grpcClient, managedChannel);
Assert.assertTrue(invoke instanceof RequestGrpc.RequestFutureStub);
}
@After
public void close() {
managedChannel.shutdownNow();
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.common.remote.client.grpc;
import org.junit.Test;
import static org.mockito.Mockito.when;
public class GrpcClientTlsTest extends GrpcClientTest {
@Test
public void testGrpcEnableTlsAndTrustPart() throws Exception {
when(tlsConfig.getEnableTls()).thenReturn(true);
when(tlsConfig.getTrustCollectionCertFile()).thenReturn("ca-cert.pem");
when(tlsConfig.getCiphers()).thenReturn("ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-RSA-AES256-GCM-SHA384");
when(tlsConfig.getProtocols()).thenReturn("TLSv1.2,TLSv1.3");
when(clientConfig.name()).thenReturn("testClient");
when(clientConfig.tlsConfig()).thenReturn(tlsConfig);
grpcClient = new GrpcClient(clientConfig) {
@Override
public int rpcPortOffset() {
return 1000;
}
};
}
@Test
public void testGrpcEnableTlsAndTrustAll() throws Exception {
when(tlsConfig.getEnableTls()).thenReturn(true);
when(tlsConfig.getTrustCollectionCertFile()).thenReturn("ca-cert.pem");
when(tlsConfig.getCiphers()).thenReturn("ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-RSA-AES256-GCM-SHA384");
when(tlsConfig.getProtocols()).thenReturn("TLSv1.2,TLSv1.3");
when(tlsConfig.getTrustAll()).thenReturn(true);
when(clientConfig.name()).thenReturn("testClient");
when(clientConfig.tlsConfig()).thenReturn(tlsConfig);
grpcClient = new GrpcClient(clientConfig) {
@Override
public int rpcPortOffset() {
return 1000;
}
};
}
@Test
public void testGrpcEnableTlsAndEnableMutualAuth() throws Exception {
when(tlsConfig.getEnableTls()).thenReturn(true);
when(tlsConfig.getTrustCollectionCertFile()).thenReturn("ca-cert.pem");
when(tlsConfig.getCiphers()).thenReturn("ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-RSA-AES256-GCM-SHA384");
when(tlsConfig.getProtocols()).thenReturn("TLSv1.2,TLSv1.3");
when(tlsConfig.getTrustAll()).thenReturn(true);
when(tlsConfig.getMutualAuthEnable()).thenReturn(true);
when(tlsConfig.getTrustCollectionCertFile()).thenReturn("ca-cert.pem");
when(tlsConfig.getCiphers()).thenReturn("client-cert.pem");
when(tlsConfig.getCertPrivateKey()).thenReturn("client-key.pem");
when(clientConfig.name()).thenReturn("testClient");
when(clientConfig.tlsConfig()).thenReturn(tlsConfig);
grpcClient = new GrpcClient(clientConfig) {
@Override
public int rpcPortOffset() {
return 1000;
}
};
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 1999-2022 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import io.grpc.netty.shaded.io.netty.handler.ssl.SslProvider;
import org.junit.Assert;
import org.junit.Test;
public class TlsTypeResolveTest {
@Test
public void test() {
SslProvider openssl = TlsTypeResolve.getSslProvider("openssl");
Assert.assertEquals(SslProvider.OPENSSL, openssl);
SslProvider openSsL = TlsTypeResolve.getSslProvider("openSSL");
Assert.assertEquals(SslProvider.OPENSSL, openSsL);
SslProvider jdk = TlsTypeResolve.getSslProvider("JDK");
Assert.assertEquals(SslProvider.JDK, jdk);
SslProvider anySsl = TlsTypeResolve.getSslProvider("anySSL");
Assert.assertEquals(SslProvider.OPENSSL, anySsl);
}
}

View File

@ -16,10 +16,13 @@
package com.alibaba.nacos.core.remote;
import com.alibaba.nacos.common.JustForTest;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.remote.PayloadRegistry;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.core.utils.Loggers;
import com.alibaba.nacos.sys.env.EnvUtil;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@ -31,22 +34,31 @@ import javax.annotation.PreDestroy;
* @version $Id: BaseRpcServer.java, v 0.1 2020年07月13日 3:41 PM liuzunfei Exp $
*/
public abstract class BaseRpcServer {
static {
PayloadRegistry.init();
}
@Autowired
protected RpcServerTlsConfig grpcServerConfig;
@JustForTest
public void setGrpcServerConfig(RpcServerTlsConfig grpcServerConfig) {
this.grpcServerConfig = grpcServerConfig;
}
/**
* Start sever.
*/
@PostConstruct
public void start() throws Exception {
String serverName = getClass().getSimpleName();
Loggers.REMOTE.info("Nacos {} Rpc server starting at port {}", serverName, getServicePort());
String tlsConfig = JacksonUtils.toJson(grpcServerConfig);
Loggers.REMOTE.info("Nacos {} Rpc server starting at port {} and tls config:{}", serverName, getServicePort(), tlsConfig);
startServer();
Loggers.REMOTE.info("Nacos {} Rpc server started at port {}", serverName, getServicePort());
Loggers.REMOTE.info("Nacos {} Rpc server started at port {} and tls config:{}", serverName, getServicePort(), tlsConfig);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
Loggers.REMOTE.info("Nacos {} Rpc server stopping", serverName);
try {

View File

@ -0,0 +1,44 @@
/*
* Copyright 1999-2022 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.core.remote;
import com.alibaba.nacos.common.remote.TlsConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* Grpc config.
*
* @author githubcheng2978.
*/
@ConfigurationProperties(prefix = RpcServerTlsConfig.PREFIX)
@Component
public class RpcServerTlsConfig extends TlsConfig {
public static final String PREFIX = "nacos.remote.server.rpc.tls";
private Boolean compatibility = true;
public Boolean getCompatibility() {
return compatibility;
}
public void setCompatibility(Boolean compatibility) {
this.compatibility = compatibility;
}
}

View File

@ -17,7 +17,13 @@
package com.alibaba.nacos.core.remote.grpc;
import com.alibaba.nacos.api.grpc.auto.Payload;
import com.alibaba.nacos.common.packagescan.resource.DefaultResourceLoader;
import com.alibaba.nacos.common.packagescan.resource.Resource;
import com.alibaba.nacos.common.packagescan.resource.ResourceLoader;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.common.utils.TlsTypeResolve;
import com.alibaba.nacos.core.remote.BaseRpcServer;
import com.alibaba.nacos.core.remote.ConnectionManager;
import com.alibaba.nacos.sys.env.EnvUtil;
@ -25,16 +31,26 @@ import io.grpc.CompressorRegistry;
import io.grpc.DecompressorRegistry;
import io.grpc.MethodDescriptor;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.ServerInterceptors;
import io.grpc.ServerServiceDefinition;
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder;
import io.grpc.netty.shaded.io.netty.handler.ssl.ClientAuth;
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder;
import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.grpc.protobuf.ProtoUtils;
import io.grpc.stub.ServerCalls;
import io.grpc.util.MutableHandlerRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@ -45,31 +61,40 @@ import java.util.concurrent.TimeUnit;
* @version $Id: BaseGrpcServer.java, v 0.1 2020年07月13日 3:42 PM liuzunfei Exp $
*/
public abstract class BaseGrpcServer extends BaseRpcServer {
private Server server;
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
@Autowired
private GrpcRequestAcceptor grpcCommonRequestAcceptor;
@Autowired
private GrpcBiStreamRequestAcceptor grpcBiStreamRequestAcceptor;
@Autowired
private ConnectionManager connectionManager;
@Override
public ConnectionType getConnectionType() {
return ConnectionType.GRPC;
}
@Override
public void startServer() throws Exception {
final MutableHandlerRegistry handlerRegistry = new MutableHandlerRegistry();
addServices(handlerRegistry, new GrpcConnectionInterceptor());
server = ServerBuilder.forPort(getServicePort()).executor(getRpcExecutor())
.maxInboundMessageSize(getMaxInboundMessageSize()).fallbackHandlerRegistry(handlerRegistry)
NettyServerBuilder builder = NettyServerBuilder.forPort(getServicePort()).executor(getRpcExecutor());
if (grpcServerConfig.getEnableTls()) {
if (grpcServerConfig.getCompatibility()) {
builder.protocolNegotiator(new OptionalTlsProtocolNegotiator(getSslContextBuilder()));
} else {
builder.sslContext(getSslContextBuilder());
}
}
server = builder.maxInboundMessageSize(getMaxInboundMessageSize()).fallbackHandlerRegistry(handlerRegistry)
.compressorRegistry(CompressorRegistry.getDefaultInstance())
.decompressorRegistry(DecompressorRegistry.getDefaultInstance())
.addTransportFilter(new AddressTransportFilter(connectionManager))
@ -77,22 +102,22 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
.keepAliveTimeout(getKeepAliveTimeout(), TimeUnit.MILLISECONDS)
.permitKeepAliveTime(getPermitKeepAliveTime(), TimeUnit.MILLISECONDS)
.build();
server.start();
}
protected long getPermitKeepAliveTime() {
return GrpcServerConstants.GrpcConfig.DEFAULT_GRPC_PERMIT_KEEP_ALIVE_TIME;
}
protected long getKeepAliveTime() {
return GrpcServerConstants.GrpcConfig.DEFAULT_GRPC_KEEP_ALIVE_TIME;
}
protected long getKeepAliveTimeout() {
return GrpcServerConstants.GrpcConfig.DEFAULT_GRPC_KEEP_ALIVE_TIMEOUT;
}
protected int getMaxInboundMessageSize() {
Integer property = EnvUtil.getProperty(GrpcServerConstants.GrpcConfig.MAX_INBOUND_MSG_SIZE_PROPERTY,
Integer.class);
@ -101,9 +126,9 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
}
return GrpcServerConstants.GrpcConfig.DEFAULT_GRPC_MAX_INBOUND_MSG_SIZE;
}
private void addServices(MutableHandlerRegistry handlerRegistry, ServerInterceptor... serverInterceptor) {
// unary common call register.
final MethodDescriptor<Payload, Payload> unaryPayloadMethod = MethodDescriptor.<Payload, Payload>newBuilder()
.setType(MethodDescriptor.MethodType.UNARY)
@ -111,44 +136,92 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
GrpcServerConstants.REQUEST_METHOD_NAME))
.setRequestMarshaller(ProtoUtils.marshaller(Payload.getDefaultInstance()))
.setResponseMarshaller(ProtoUtils.marshaller(Payload.getDefaultInstance())).build();
final ServerCallHandler<Payload, Payload> payloadHandler = ServerCalls
.asyncUnaryCall((request, responseObserver) -> grpcCommonRequestAcceptor.request(request, responseObserver));
final ServerServiceDefinition serviceDefOfUnaryPayload = ServerServiceDefinition.builder(
GrpcServerConstants.REQUEST_SERVICE_NAME)
.addMethod(unaryPayloadMethod, payloadHandler).build();
handlerRegistry.addService(ServerInterceptors.intercept(serviceDefOfUnaryPayload, serverInterceptor));
// bi stream register.
final ServerCallHandler<Payload, Payload> biStreamHandler = ServerCalls.asyncBidiStreamingCall(
(responseObserver) -> grpcBiStreamRequestAcceptor.requestBiStream(responseObserver));
final MethodDescriptor<Payload, Payload> biStreamMethod = MethodDescriptor.<Payload, Payload>newBuilder()
.setType(MethodDescriptor.MethodType.BIDI_STREAMING).setFullMethodName(MethodDescriptor
.generateFullMethodName(GrpcServerConstants.REQUEST_BI_STREAM_SERVICE_NAME,
GrpcServerConstants.REQUEST_BI_STREAM_METHOD_NAME))
.setRequestMarshaller(ProtoUtils.marshaller(Payload.newBuilder().build()))
.setResponseMarshaller(ProtoUtils.marshaller(Payload.getDefaultInstance())).build();
final ServerServiceDefinition serviceDefOfBiStream = ServerServiceDefinition
.builder(GrpcServerConstants.REQUEST_BI_STREAM_SERVICE_NAME).addMethod(biStreamMethod, biStreamHandler).build();
handlerRegistry.addService(ServerInterceptors.intercept(serviceDefOfBiStream, serverInterceptor));
}
@Override
public void shutdownServer() {
if (server != null) {
server.shutdownNow();
}
}
private SslContext getSslContextBuilder() {
try {
if (StringUtils.isBlank(grpcServerConfig.getCertChainFile()) || StringUtils.isBlank(grpcServerConfig.getCertPrivateKey())) {
throw new IllegalArgumentException("Server certChainFile or certPrivateKey must be not null");
}
InputStream certificateChainFile = getInputStream(grpcServerConfig.getCertChainFile(), "certChainFile");
InputStream privateKeyFile = getInputStream(grpcServerConfig.getCertPrivateKey(), "certPrivateKey");
SslContextBuilder sslClientContextBuilder = SslContextBuilder.forServer(certificateChainFile, privateKeyFile,
grpcServerConfig.getCertPrivateKeyPassword());
if (StringUtils.isNotBlank(grpcServerConfig.getProtocols())) {
sslClientContextBuilder.protocols(grpcServerConfig.getProtocols().split(","));
}
if (StringUtils.isNotBlank(grpcServerConfig.getCiphers())) {
sslClientContextBuilder.ciphers(Arrays.asList(grpcServerConfig.getCiphers().split(",")));
}
if (grpcServerConfig.getMutualAuthEnable()) {
// trust all certificate
if (grpcServerConfig.getTrustAll()) {
sslClientContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
} else {
if (StringUtils.isBlank(grpcServerConfig.getTrustCollectionCertFile())) {
throw new IllegalArgumentException("enable mutual auth,trustCollectionCertFile must be not null");
}
InputStream clientCert = getInputStream(grpcServerConfig.getTrustCollectionCertFile(), "trustCollectionCertFile");
sslClientContextBuilder.trustManager(clientCert);
}
sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);
}
SslContextBuilder configure = GrpcSslContexts.configure(sslClientContextBuilder,
TlsTypeResolve.getSslProvider(grpcServerConfig.getSslProvider()));
return configure.build();
} catch (SSLException e) {
throw new RuntimeException(e);
}
}
private InputStream getInputStream(String path, String config) {
try {
Resource resource = resourceLoader.getResource(path);
return resource.getInputStream();
} catch (IOException e) {
throw new RuntimeException(config + " load fail", e);
}
}
/**
* get rpc executor.
*
* @return executor.
*/
public abstract ThreadPoolExecutor getRpcExecutor();
}

View File

@ -0,0 +1,116 @@
/*
* Copyright 1999-2022 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.core.remote.grpc;
import io.grpc.netty.shaded.io.grpc.netty.GrpcHttp2ConnectionHandler;
import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiator;
import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiators;
import io.grpc.netty.shaded.io.grpc.netty.ProtocolNegotiationEvent;
import io.grpc.netty.shaded.io.netty.buffer.ByteBuf;
import io.grpc.netty.shaded.io.netty.channel.ChannelHandler;
import io.grpc.netty.shaded.io.netty.channel.ChannelHandlerContext;
import io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder;
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
import io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler;
import io.grpc.netty.shaded.io.netty.util.AsciiString;
import java.lang.reflect.Field;
import java.util.List;
/**
* support the tls and plain protocol one the same port.
*
* @author githubcheng2978.
*/
public class OptionalTlsProtocolNegotiator implements InternalProtocolNegotiator.ProtocolNegotiator {
private static final int MAGIC_VALUE = 5;
private SslContext sslContext;
public OptionalTlsProtocolNegotiator(SslContext sslContext) {
this.sslContext = sslContext;
}
@Override
public AsciiString scheme() {
return AsciiString.of("https");
}
@Override
public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHttp2ConnectionHandler) {
ChannelHandler plaintext =
InternalProtocolNegotiators.serverPlaintext().newHandler(grpcHttp2ConnectionHandler);
ChannelHandler ssl =
InternalProtocolNegotiators.serverTls(sslContext).newHandler(grpcHttp2ConnectionHandler);
ChannelHandler decoder = new PortUnificationServerHandler(ssl, plaintext);
return decoder;
}
@Override
public void close() {
}
private ProtocolNegotiationEvent getDefPne() {
ProtocolNegotiationEvent protocolNegotiationEvent = null;
try {
Field aDefault = ProtocolNegotiationEvent.class.getDeclaredField("DEFAULT");
aDefault.setAccessible(true);
return (ProtocolNegotiationEvent) aDefault.get(protocolNegotiationEvent);
} catch (Exception e) {
e.printStackTrace();
}
return protocolNegotiationEvent;
}
public class PortUnificationServerHandler extends ByteToMessageDecoder {
private ProtocolNegotiationEvent pne;
private final ChannelHandler ssl;
private final ChannelHandler plaintext;
public PortUnificationServerHandler(ChannelHandler ssl, ChannelHandler plaintext) {
this.ssl = ssl;
this.plaintext = plaintext;
this.pne = getDefPne();
}
private boolean isSsl(ByteBuf buf) {
return SslHandler.isEncrypted(buf);
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
throws Exception {
if (in.readableBytes() < MAGIC_VALUE) {
return;
}
if (isSsl(in)) {
ctx.pipeline().addAfter(ctx.name(), (String) null, this.ssl);
ctx.fireUserEventTriggered(pne);
ctx.pipeline().remove(this);
} else {
ctx.pipeline().addAfter(ctx.name(), (String) null, this.plaintext);
ctx.fireUserEventTriggered(pne);
ctx.pipeline().remove(this);
}
}
}
}

View File

@ -18,7 +18,7 @@
package com.alibaba.nacos.core.remote.grpc;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.core.remote.BaseRpcServer;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import com.alibaba.nacos.sys.env.EnvUtil;
import org.junit.Assert;
import org.junit.Before;
@ -27,41 +27,125 @@ import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.mock.env.MockEnvironment;
import java.util.concurrent.ThreadPoolExecutor;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* {@link GrpcSdkServer} and {@link GrpcClusterServer} unit test.
*
* @author chenglu
* @date 2021-06-30 14:32
*/
@RunWith(MockitoJUnitRunner.class)
@RunWith(MockitoJUnitRunner.Silent.class)
public class GrpcServerTest {
private final RpcServerTlsConfig grpcServerConfig = mock(RpcServerTlsConfig.class);
@Before
public void setUp() {
EnvUtil.setEnvironment(new MockEnvironment());
}
@Test
public void testGrpcSdkServer() throws Exception {
BaseGrpcServer grpcSdkServer = new GrpcSdkServer();
grpcSdkServer.setGrpcServerConfig(grpcServerConfig);
when(grpcServerConfig.getEnableTls()).thenReturn(false);
grpcSdkServer.start();
Assert.assertEquals(grpcSdkServer.getConnectionType(), ConnectionType.GRPC);
Assert.assertEquals(grpcSdkServer.rpcPortOffset(), 1000);
grpcSdkServer.stopServer();
}
@Test
public void testGrpcClusterServer() throws Exception {
BaseRpcServer grpcSdkServer = new GrpcClusterServer();
BaseGrpcServer grpcSdkServer = new GrpcClusterServer();
grpcSdkServer.setGrpcServerConfig(grpcServerConfig);
when(grpcServerConfig.getEnableTls()).thenReturn(false);
grpcSdkServer.start();
Assert.assertEquals(grpcSdkServer.getConnectionType(), ConnectionType.GRPC);
Assert.assertEquals(grpcSdkServer.rpcPortOffset(), 1001);
grpcSdkServer.stopServer();
}
@Test
public void testGrpcEnableTls() throws Exception {
final BaseGrpcServer grpcSdkServer = new BaseGrpcServer() {
@Override
public ThreadPoolExecutor getRpcExecutor() {
return null;
}
@Override
public int rpcPortOffset() {
return 100;
}
};
when(grpcServerConfig.getEnableTls()).thenReturn(true);
when(grpcServerConfig.getCiphers()).thenReturn("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
when(grpcServerConfig.getProtocols()).thenReturn("TLSv1.2,TLSv1.3");
when(grpcServerConfig.getCertPrivateKey()).thenReturn("test-server-key.pem");
when(grpcServerConfig.getCertChainFile()).thenReturn("test-server-cert.pem");
grpcSdkServer.setGrpcServerConfig(grpcServerConfig);
grpcSdkServer.start();
grpcSdkServer.shutdownServer();
}
@Test
public void testGrpcEnableMutualAuthAndTrustAll() throws Exception {
final BaseGrpcServer grpcSdkServer = new BaseGrpcServer() {
@Override
public ThreadPoolExecutor getRpcExecutor() {
return null;
}
@Override
public int rpcPortOffset() {
return 100;
}
};
when(grpcServerConfig.getEnableTls()).thenReturn(true);
when(grpcServerConfig.getTrustAll()).thenReturn(true);
when(grpcServerConfig.getCiphers()).thenReturn("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
when(grpcServerConfig.getProtocols()).thenReturn("TLSv1.2,TLSv1.3");
when(grpcServerConfig.getCertPrivateKey()).thenReturn("test-server-key.pem");
when(grpcServerConfig.getCertChainFile()).thenReturn("test-server-cert.pem");
grpcSdkServer.setGrpcServerConfig(grpcServerConfig);
grpcSdkServer.start();
grpcSdkServer.shutdownServer();
}
@Test
public void testGrpcEnableMutualAuthAndPart() throws Exception {
final BaseGrpcServer grpcSdkServer = new BaseGrpcServer() {
@Override
public ThreadPoolExecutor getRpcExecutor() {
return null;
}
@Override
public int rpcPortOffset() {
return 100;
}
};
when(grpcServerConfig.getEnableTls()).thenReturn(true);
when(grpcServerConfig.getMutualAuthEnable()).thenReturn(true);
when(grpcServerConfig.getEnableTls()).thenReturn(true);
when(grpcServerConfig.getCiphers()).thenReturn("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
when(grpcServerConfig.getProtocols()).thenReturn("TLSv1.2,TLSv1.3");
when(grpcServerConfig.getCertPrivateKey()).thenReturn("test-server-key.pem");
when(grpcServerConfig.getCertChainFile()).thenReturn("test-server-cert.pem");
when(grpcServerConfig.getTrustCollectionCertFile()).thenReturn("test-ca-cert.pem");
grpcSdkServer.setGrpcServerConfig(grpcServerConfig);
grpcSdkServer.start();
grpcSdkServer.shutdownServer();
}
}

View File

@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFgDCCA2gCCQCHXhY4/0hsxTANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMC
Q04xCzAJBgNVBAgMAlNDMQ8wDQYDVQQHDAZDaGVuRHUxDjAMBgNVBAoMBUFJU0hV
MREwDwYDVQQLDAhEYXRhYmFzZTERMA8GA1UEAwwIbmFjb3MuaW8xHjAcBgkqhkiG
9w0BCQEWD25hY29zQGdtYWlsLmNvbTAeFw0yMzAyMTcwMjA5MDdaFw0yNDAyMTcw
MjA5MDdaMIGBMQswCQYDVQQGEwJDTjELMAkGA1UECAwCU0MxDzANBgNVBAcMBkNo
ZW5EdTEOMAwGA1UECgwFQUlTSFUxETAPBgNVBAsMCERhdGFiYXNlMREwDwYDVQQD
DAhuYWNvcy5pbzEeMBwGCSqGSIb3DQEJARYPbmFjb3NAZ21haWwuY29tMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwAVnhxySTa0FKHloUOHFp2YqjXPz
Kc4giQpMGt7cqA99WSMyoKVshBLvV4+NMcWbDUgAromC/iEGFQOMLyiwDoxWY0Vd
MkDkcX3pNIV0zN75UKZwIEiyh3BeLV/IawmDXJNTzSUpeCsktbnkz3XrD+sp1gNE
RJV9S875V6cwWkJLpV7EUIo7SHTkTAVSyynVPc+/B6jIpsBL85wsp3krQpGjaFku
78/GX/c43pG5E6/PhdAukuT1Lhp8+h2wx30Via++F9EZPpBDs1xGWHuT4BDPRpyK
GyzdQ5kj+ytGCWHL2R0IguURUCW6rhm5jK5rB72YSGUidQEc1COqtqlcnnYJbupg
O4ykujwHLECDsutjsNfAH2s2W/yGphqn1MwStG9mvjK7BpehvA8ZTX1cEFf713KM
vGQL0KgYo3A6rDZrgnl7LpRBhZJCBzirMV9UKxw56nQMFoZV+qlYtlYqzq0EnliY
NCh6+m5wSw3oEAvAGQ81Ocd4iHdv8rmqJ//oBluS9C+zvjRa5inkv1sDwOEvwt4s
CKH0+stYSDq9k93pNxCUTDAFQK9jDIO+S6jr65cZGtQi8L9MRSPDycC33B67t047
xlMgWGvOmCqAY/n6rXxlxBAnsU03TW73SGuhN9s971Z0G4I87P1b4Ek++/+uIsuU
gwgpbuknLgDg9R8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAAlDteMVDv/M5hjTG
0bkRjEUMjR5G5IagTdoNJHYN70lepeuELS1lAax9anSV71f7bo2e+KHFlM03rvmq
zA9pCz6U5C1d1aPPqzkOTy7KlBuDGit0EHZLCIlP4Ry0c6KnbtMuMbtuNZ3MaEfa
i/UbAvFFXCsfq83ybq4Z11OJ8RZe1yL+zqYInnDXjN4RGUc4NAQhERlJzZjhAjmE
trKYdiXvmXgXKLfG5h1Y2icihPFpBuicoVRIyM35SVxorOQbIJ2/4YDEe6RtGh1m
FFHXb9d3w5COzOmtuRatedWkNDZv2HEelIGox+R+HAC8iAjZuq5PAai0Tvy7YupZ
psY/6IX7OJNh4RPDYHAoq6SXDT1V2V0AmKlzNmcIeo7D8Mlo+rcKGuAJSDiRhAY5
cDPpi6EOQSVQyx70YeHBu7we4Pkzr2oCa/9rdyjwSS1sojZR5WKWzj0IX81JjXx3
vRi5UdL29PfRB8jUyTJ+pRpLAjjusRn5rF6iReX9zR7Lv5Bfpm17xHB5lLmtkoOw
M+d4JCDuifktmEBGlqMTCVdltzD9cyUgad2rsThAkwXpAdpHGUNMWffyz2maO8b8
JUDimxvOfM23L9xg77NNJ4A39hlQGWlmasszY71e8d+Db8K4r4bJ6JxqGNXN67hE
7mnp2LvM239Nz9LuTc5E15FgxPg=
-----END CERTIFICATE-----

View File

@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFgDCCA2gCCQCENkzuoebfxzANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UEBhMC
Q04xCzAJBgNVBAgMAlNDMQ8wDQYDVQQHDAZDaGVuRHUxDjAMBgNVBAoMBUFJU0hV
MREwDwYDVQQLDAhEYXRhYmFzZTERMA8GA1UEAwwIbmFjb3MuaW8xHjAcBgkqhkiG
9w0BCQEWD25hY29zQGdtYWlsLmNvbTAeFw0yMzAyMTcwMjA5MDhaFw0yMzA0MTgw
MjA5MDhaMIGBMQswCQYDVQQGEwJDTjELMAkGA1UECAwCU0MxDzANBgNVBAcMBkNo
ZW5EdTEOMAwGA1UECgwFQUlTSFUxETAPBgNVBAsMCERhdGFiYXNlMREwDwYDVQQD
DAhuYWNvcy5pbzEeMBwGCSqGSIb3DQEJARYPbmFjb3NAZ21haWwuY29tMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqjaSgfHvTogerMc+kfMl0Z1HBmrS
ArNwviVaVWOtaTOPppygGghld6v1QCoLAtc/vEDpgcvheySt9WE7gIZTvsBeQb0+
NsB4gz+jyGsZSxhh6aGAEA48x8g1Yd2i5EeupnPMpyltGxW/d58KvK44KZAiojjV
OYOi1Izxz/Zy1BFE2dIVh5pCOgfiAXC5PINdAebStNxbNGm0KoPXmjbeMTStXAK+
vqyvsfKwLW+RGnYwtSk2m9E5GmS14oXpNFsTTwsz6WalbnW2znWTt3TAancUpMI2
OyY5Iu6xgQgzd8mHUUZvsVJLgxr9e9OvXt/CoKEJA+pWY0a+TpCm/K7RIlzNnLg/
JO2HiDrzvl+Ai1ycqNjjoKqAy4bC7fRy3MmXBgf7EHNcFqLucixsDLR0FsSW7a92
OfNHJiqjl0LVnbzCaLHwwbG5vS/yoBiiaFiymA5sXkQE2fK3Kfh04NmNsnjOowTF
h/rqk6vhKmuKrkDpHziKgYwkdbKzJjTbXCR56yjFZAyrVVUINjNAZvDAn2vucsLE
g0VbyJwI7TBR3ucIogpi37MqPBSu4NczNTXDyf00cfAbOAGfo+Bl5VqBMmW8nRJM
4qhQyWLDaADH3Y8eVVlW2qIzwuL7jOs5sodk28mIf9cOlQ+l+G/IjUR7iNb1tW3S
dEmyerRJjCtdCm8CAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAbusTUQAfg5eWEulk
iG8lNqr5Py75GlFRxOLvlqUfgHVSjuVFfpykYDA0YQKPS7qk3llTbfS3Cu15FWY/
fM3OOSGcZ/lUnaMhRePB3SL/z0ZaueLfUDEYgvDO45NoUH0qo0owlmL1C4gGMb1O
WluWuuUbX8FlYhoyyvLbza1dETeZKKQpsMKQmBCjfCv4WyI6VmELSzriaKjrPil/
laCEAoWmo5YdyJBpq90lVF9WELBkNdppuunjKPjSqAvkxc9/3PtIDiW4qUxlB9Jr
gJkiIDWrNwpDdeVtzBprYcGlPgjR4M9jPEPt6+nK9li//jiSsK4hYI/nQlf7vrOP
N/oCVDXy3rp1+qfl3yNOHvnhR3iaR1uuiZk2VrWEqtWADHPXSjsEyVf8AWvnjuOo
YhDJwS1ThQ12TeeHL3XJDndqr+1wQd/H9lpRhn8+8XU/I2G36J9HFsCAmyEe6TOc
X2NrAkeEpG/P53van2pEu3P4WIkkfgKFQ23KEnFC6+8WzYdRJ9ajqpAYtIq/wnGG
Yg+UMZbJ3dxwNPMgUk2OitMTtWBvtroiwg9VP8QHmNJETg32TdBanbKQyz1dcTmK
U168K33toj4htMmE694vIly73JX1aeGBwKSIO8ihL0Ac4HEjJQFtz/JV/gsqHIu4
H7A7EW3AbigoMqxjG+Y3dQgkTBA=
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
v6u2c/Ymelm+TmDaLTyeoAu9wKBHahw=
-----END PRIVATE KEY-----

View File

@ -131,7 +131,7 @@ public class InetUtils {
*
* @return ip address
*/
private static String getNacosIp() {
public static String getNacosIp() {
String nacosIp = System.getProperty(NACOS_SERVER_IP);
if (StringUtils.isBlank(nacosIp)) {
nacosIp = EnvUtil.getProperty(IP_ADDRESS);

View File

@ -28,13 +28,15 @@
<url>https://nacos.io</url>
<artifactId>config-test</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
<argLine>-Dnacos.standalone=true -Dnacos.server.ip=127.0.0.1</argLine>
<useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>

View File

@ -0,0 +1,103 @@
/*
* 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.test.config;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.config.ConfigChangeEvent;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.client.config.NacosConfigService;
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
import com.alibaba.nacos.common.remote.client.RpcConstants;
import com.alibaba.nacos.common.remote.client.grpc.GrpcConstants;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import com.alibaba.nacos.test.base.ConfigCleanUtils;
import org.junit.*;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* use configPublishRequest for communication verification between client and server.
*
* @author githubcheng2978.
*/
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@SpringBootTest(classes = {Nacos.class},
properties = {
"nacos.standalone=true",
RpcServerTlsConfig.PREFIX+".enableTls=true",
RpcServerTlsConfig.PREFIX+".compatibility=true",
RpcServerTlsConfig.PREFIX+".certChainFile=test-server-cert.pem",
RpcServerTlsConfig.PREFIX+".certPrivateKey=test-server-key.pem"},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class NacosConfigServiceComTlsGrpcClientTest {
public static AtomicInteger increment = new AtomicInteger(100);
@LocalServerPort
private int port;
@BeforeClass
public static void beforeClass() throws IOException {
ConfigCleanUtils.changeToNewTestNacosHome(NacosConfigServiceComTlsGrpcClientTest.class.getSimpleName());
}
@BeforeClass
@AfterClass
public static void cleanClientCache() throws Exception {
ConfigCleanUtils.cleanClientCache();
}
@Test
public void test_e_TlsServerAndPlainClient() throws Exception {
Properties propertiesfalse = new Properties();
propertiesfalse.put(RpcConstants.RPC_CLIENT_TLS_ENABLE, "false");
propertiesfalse.put("serverAddr", "127.0.0.1");
ConfigService configServiceFalse = new NacosConfigService(propertiesfalse);
String dataId = "test-group" + increment.getAndIncrement();
String groupId = "test-data" + increment.getAndIncrement();
String content = UUID.randomUUID().toString();
boolean res = configServiceFalse.publishConfig(dataId, groupId, content);
CountDownLatch latch2 = new CountDownLatch(1);
configServiceFalse.addListener(dataId, groupId, new AbstractConfigChangeListener() {
@Override
public void receiveConfigChange(ConfigChangeEvent event) {
ConfigChangeItem cci = event.getChangeItem("content");
System.out.println("content:" + cci);
if (!content.equals(cci.getNewValue())) {
return;
}
latch2.countDown();
}
});
latch2.await(5, TimeUnit.SECONDS);
Assert.assertTrue(res);
}
}

View File

@ -0,0 +1,126 @@
/*
* 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.test.config;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.config.ConfigChangeEvent;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.client.config.NacosConfigService;
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
import com.alibaba.nacos.common.remote.client.RpcConstants;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import com.alibaba.nacos.test.base.ConfigCleanUtils;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* use configPublishRequest for communication verification between client and server.
*
* @author githubcheng2978.
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Nacos.class},
properties = {
"nacos.standalone=true",
RpcServerTlsConfig.PREFIX+".enableTls=true",
RpcServerTlsConfig.PREFIX+".compatibility=false",
RpcServerTlsConfig.PREFIX+".certChainFile=test-server-cert.pem",
RpcServerTlsConfig.PREFIX+".certPrivateKey=test-server-key.pem"},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class NacosConfigServiceNoComTlsGrpcClientTest {
public static AtomicInteger increment = new AtomicInteger(100);
@BeforeClass
public static void beforeClass() throws IOException {
ConfigCleanUtils.changeToNewTestNacosHome(NacosConfigServiceNoComTlsGrpcClientTest.class.getSimpleName());
}
@BeforeClass
@AfterClass
public static void cleanClientCache() throws Exception {
ConfigCleanUtils.cleanClientCache();
}
@Test
public void test_e_TlsServerAndTlsClient() throws Exception {
Properties properties = new Properties();
properties.put(RpcConstants.RPC_CLIENT_TLS_ENABLE, "true");
properties.put(RpcConstants.RPC_CLIENT_TLS_PROVIDER, "openssl");
properties.put(RpcConstants.RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH, "test-ca-cert.pem");
properties.put("serverAddr", "127.0.0.1");
ConfigService configService = new NacosConfigService(properties);
String content = UUID.randomUUID().toString();
String dataId = "test-group" + increment.getAndIncrement();
String groupId = "test-data" + increment.getAndIncrement();
boolean b = configService.publishConfig("test-group" + increment.getAndIncrement(), "test-data" + increment.getAndIncrement(), content);
CountDownLatch latch = new CountDownLatch(1);
configService.addListener(dataId, groupId, new AbstractConfigChangeListener() {
@Override
public void receiveConfigChange(ConfigChangeEvent event) {
ConfigChangeItem cci = event.getChangeItem("content");
System.out.println("content:" + cci);
if (!content.equals(cci.getNewValue())) {
return;
}
latch.countDown();
}
});
latch.await(5, TimeUnit.SECONDS);
Assert.assertTrue(b);
}
@Test
public void test_e_TlsServerAndPlainClient() throws Exception {
Properties propertiesfalse = new Properties();
propertiesfalse.put(RpcConstants.RPC_CLIENT_TLS_ENABLE, "false");
propertiesfalse.put("serverAddr", "127.0.0.1");
ConfigService configServiceFalse = new NacosConfigService(propertiesfalse);
String dataId = "test-group" + increment.getAndIncrement();
String groupId = "test-data" + increment.getAndIncrement();
String content = UUID.randomUUID().toString();
boolean res = configServiceFalse.publishConfig(dataId, groupId, content);
CountDownLatch latch2 = new CountDownLatch(1);
configServiceFalse.addListener(dataId, groupId, new AbstractConfigChangeListener() {
@Override
public void receiveConfigChange(ConfigChangeEvent event) {
ConfigChangeItem cci = event.getChangeItem("content");
System.out.println("content:" + cci);
if (!content.equals(cci.getNewValue())) {
return;
}
latch2.countDown();
}
});
latch2.await(5, TimeUnit.SECONDS);
Assert.assertFalse(res);
}
}

View File

@ -0,0 +1,136 @@
/*
* 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.test.config;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.config.ConfigChangeEvent;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.client.config.NacosConfigService;
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
import com.alibaba.nacos.common.remote.client.RpcConstants;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import com.alibaba.nacos.test.base.ConfigCleanUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* use configPublishRequest for communication verification between client and server.
*
* @author githubcheng2978.
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Nacos.class},
properties = {
"nacos.standalone=true",
RpcServerTlsConfig.PREFIX+".enableTls=true",
RpcServerTlsConfig.PREFIX+".mutualAuthEnable=true",
RpcServerTlsConfig.PREFIX+".compatibility=false",
RpcServerTlsConfig.PREFIX+".certChainFile=test-server-cert.pem",
RpcServerTlsConfig.PREFIX+".certPrivateKey=test-server-key.pem",
RpcServerTlsConfig.PREFIX+".trustCollectionCertFile=test-ca-cert.pem",
},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class NacosConfigV2MutualAuthTest {
public static AtomicInteger increment = new AtomicInteger(100);
@BeforeClass
public static void beforeClass() throws IOException {
ConfigCleanUtils.changeToNewTestNacosHome(NacosConfigV2MutualAuthTest.class.getSimpleName());
}
@After
public void cleanClientCache() throws Exception {
ConfigCleanUtils.cleanClientCache();
}
@Test
public void test_d_MutualAuth() throws Exception {
Properties propertiesfalse = new Properties();
propertiesfalse.put(RpcConstants.RPC_CLIENT_TLS_ENABLE, "true");
propertiesfalse.put(RpcConstants.RPC_CLIENT_MUTUAL_AUTH,"true");
propertiesfalse.put(RpcConstants.RPC_CLIENT_TLS_CERT_KEY,"test-client-key.pem");
propertiesfalse.put(RpcConstants.RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH,"test-ca-cert.pem");
propertiesfalse.put(RpcConstants.RPC_CLIENT_TLS_CERT_CHAIN_PATH,"test-client-cert.pem");
propertiesfalse.put("serverAddr", "127.0.0.1");
ConfigService configServiceFalse = new NacosConfigService(propertiesfalse);
String dataId = "test-group" + increment.getAndIncrement();
String groupId = "test-data" + increment.getAndIncrement();
String content = UUID.randomUUID().toString();
boolean res = configServiceFalse.publishConfig(dataId, groupId, content);
CountDownLatch latch2 = new CountDownLatch(1);
configServiceFalse.addListener(dataId, groupId, new AbstractConfigChangeListener() {
@Override
public void receiveConfigChange(ConfigChangeEvent event) {
ConfigChangeItem cci = event.getChangeItem("content");
System.out.println("content:" + cci);
if (!content.equals(cci.getNewValue())) {
return;
}
latch2.countDown();
}
});
latch2.await(5, TimeUnit.SECONDS);
Assert.assertTrue(res);
}
@Test
public void test_d_MutualAuthButClientNot() throws Exception {
Properties propertiesfalse = new Properties();
propertiesfalse.put(RpcConstants.RPC_CLIENT_TLS_ENABLE, "true");
propertiesfalse.put(RpcConstants.RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH,"test-client-cert.pem");
propertiesfalse.put("serverAddr", "127.0.0.1");
ConfigService configServiceFalse = new NacosConfigService(propertiesfalse);
String dataId = "test-group" + increment.getAndIncrement();
String groupId = "test-data" + increment.getAndIncrement();
String content = UUID.randomUUID().toString();
boolean res = configServiceFalse.publishConfig(dataId, groupId, content);
CountDownLatch latch2 = new CountDownLatch(1);
configServiceFalse.addListener(dataId, groupId, new AbstractConfigChangeListener() {
@Override
public void receiveConfigChange(ConfigChangeEvent event) {
ConfigChangeItem cci = event.getChangeItem("content");
System.out.println("content:" + cci);
if (!content.equals(cci.getNewValue())) {
return;
}
latch2.countDown();
}
});
latch2.await(5, TimeUnit.SECONDS);
Assert.assertFalse(res);
}
}

View File

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFBDCCAuwCCQDasL456kc8pjANBgkqhkiG9w0BAQsFADBEMQswCQYDVQQGEwJH
QjEOMAwGA1UEBwwFQ2hpbmExDjAMBgNVBAoMBW5hY29zMRUwEwYDVQQDDAx3d3cu
bmFjb3MuaW8wHhcNMjMwMjE5MTMyOTQ4WhcNMjQwMjE5MTMyOTQ4WjBEMQswCQYD
VQQGEwJHQjEOMAwGA1UEBwwFQ2hpbmExDjAMBgNVBAoMBW5hY29zMRUwEwYDVQQD
DAx3d3cubmFjb3MuaW8wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDf
zBvzVtSK30CMvju45EqaHfe1vtnNcBP9aPwmci5f0bO7jjkhqpGirRMjEMd4rzGE
WMXDwhmO7B+hWfyRSzKasjIhhADzHA1vx3mPZcTzhEyyqfdUuyAg0LjhMqxvllQp
5BVuieo7l5CRtbhqyyzrY/RtZCJxvkSusJJHgjPhvPd5LqOZ2X4+h6Y41pPox4T0
9f4NZ1gdOr1ypgnOabcqYp+7zbdMNFlfjNtpnpCVYePlDfwj6pchJT3nEphaAIFM
5oM6Zb7MkNeedB4vHo4kYbobd1fgXNZixML2aQdsz5YoBGoYdTXZkoEotoQ0xwU3
FWNNwmlo22we6hmnAOBaTuj7hDeHw+1mfCzXQWjlm8/D0iL3O/K5D1YTcdi4mF5k
lL/WWvl/u6MapZx1+n+x95+H5NmzxCd3ieORj+8armBNLc10EJgANpiFyGO5Eozz
ghV/qEJx/GEcXdFq4Ju5Zkl0JLuR8tm6IVjH1mtCTQsh402HtsRgeweMir7gorPx
YLJky6MKGHv0VV+dhv/92CbTVhDvMoiOiuEmj87rZp+9X17VErHJreZWtEnF13aD
lzvXvl5E/pznLtSrDBJWeg9Sp4zG+Nl8G6EAHaoQiEQPihOGfwun36DB1Sf1iHYv
FaCaqDa90EWqnwPhJ7DvMbwh1R0frjwB8+3oO0tXbwIDAQABMA0GCSqGSIb3DQEB
CwUAA4ICAQCQiePDGv+rcHRnU82d3Gi0MpFY5s5Dizrb3zZc0MJNnILERCe8ANAz
pOkdenUjIi13iKlky6bM37BMQAiw7FNv7vdcic0NRz9ZYVowo/isi7ibvDpvI+Wk
yTzM3EpzKM56syEqYxv0ACoyBB0cfbDonSx6i4cD7BKeb7Bhmlbgf/eSjq7V7gXQ
+v0JApiBhVyApSE4jMWJbSsI2whrsS3pZQu8/kgqIxI2pB15bepOMSlHr+AxApJP
Pu8Qe4tTuSA1T33bo/oLyQmApRHdnM1ghUW5IjRq0vy7W2Z3PYrh8a74t53tPjIV
tECUYvWXOBCm2ihpDlAB9A0jMhYh0QofikZzik0CnG78CKkEF8pXc2WXyh4Je2GF
yE0UDkH5E+6KkOQaA7qPprQYLgrjtrVBz/mZqBCGVneM6AGj7lx4nuBZ1mzbPGHI
o0liANhkoaUiku0eTwP+IQ7q37A5wcAUeS4cWQFcQVQa3uq8lBbvRqWZXsgbwJF0
b94UBH1uCEtV3KX49GpReFtaouCMnfVHqL7TY9xcUvA+Jq32NxwBG/ZwusiYLx9z
vcqdYATjJmbc2SenxtcGq+qX9Jcx7EV5MYKb3TRW8U17i118rIppa6fY8lwIGoYm
8Vy9hrReUgbksjfDOAPbO9arwfmPWh/mXzM1YbxBbsMoxh/BuzUIjA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
F3cfpHAfPJvE2WW+4fRc1SHALKQ/9NY=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFHzCCAwegAwIBAgIJAI1Jk02oI3h1MA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFTATBgNVBAMM
DHd3dy5uYWNvcy5pbzAeFw0yMzAyMTkxMzI5NDlaFw0yMzA0MjAxMzI5NDlaMEUx
CzAJBgNVBAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFjAU
BgNVBAMMDXd3dy5uYWNvcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQDW4rrdJSIlItSKeXpwZK/dV8cZi+57HfwmX8llqR042cWUQCCc7syfqWY/
foL14zQl0plLd319iQYo+juT6omhefhv6bANOrXUW1X5s5ZWdmGVEn5h3Rlg7mhI
l/A7c5OeJCiYuqSKy09Mni9YXRFAUm6/xPQJN3AbBdrZLwxwHYcGW5vtqPjImNsW
dM/HOAOz9LMNrw0zMJ23WA8gX3aEmvXO4GLrXpx4ACJQqTME3bS9Ik+Pc1QnfNl9
w2SNv4Ci3g7nTT6lWj4MTL6qIELHm7SQDYyjBoihkICzDUbv8WdwHWCRuePd+QWt
7pdsOr9FuAEl+mq9UZJ7GhjUu4rg0rlMmfIfmJhskzvkPqql1L9uBfCsHaBSX/vA
24gLVhnVXw0haeEHTnN3JXOmA0bTxycz+JtyvkAJnTRGRBnwIZtCRrrQMqINj6EM
PP0CvtWBo1MN/hjOkIja1j+miZzgE+G1aDqPWAXHlxMv/scJtzxb9Grn+lUlbBrO
1cS0aUHNmFf9fV48gg9dgf4INwrLBhq5nd5/zt80O38qIMpVjQWrcOgs/7V+CLxc
IPBjrPrs2EKmmr/ZiTez0ZFNOM3mFN+ueisKzk4yutQKdIYrGXzfHWJVl9lcHYmy
uUFjIC3ekNaNA7QxvhkQmW2PQwjle7rbPTYbECjkMYRAAZOBsQIDAQABoxMwETAP
BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBBQUAA4ICAQA/USNWOir6FDNTjVYx
7yEcOj9eV6wtuOqr9WgeIwA1fLrv59weBoQO5zFEVfYnhENxMNyJAy21N5+URYf7
rfLrobvNK/VD06ZC3pnYXVohjFURqlmGz8fEs5GV930KkDaO2sBF/w9uGIfoEUlz
edhgWg+QWGAezaTyGFYfGnavkHBqsinADeK7xfeAH6HBdFFXH+/KqTjQyhi6P+Wy
gkfPPxiDiYrOPjrKFNftbaHi2b3fAZWmoEDLnKV9SaPSMcoQBzSCOW0cvnpdS+uu
m9wy1Y5t+S2nRIXQoh8XrKSnXWPEecA+pQd+jlZV+Q/au1O9qFAlM7nRehE6qjNj
umJyuUB7l9gVEQsjEjLJT0TOXSVtLCUefHJkUmXTFkUqqvDFFfbAFZzw7WwGIJMa
dKAhhvs81iLhJ1RmHm0HJeL5L+D6m8B6j3ZxgFdKLEY8VONAATbZzzAnNmjJSj/P
VcbkpzrVqBIn1+82f546zqRdOP8+vvbRPC4Sz1wQk6kZVYsh9mw8gpC1Y7swyoR6
5d0wiNzU9Ccu78Fa7RqGN7jji4PSFNHGruyUj5e1Mqk/nVSoBIZ2urS7p+97/kDr
2HqC2u2v/5wq46xeNilVU6pmr8o1NGsWRlPBlKVkguSwoCdzwEr+FGCOvGjRfn/x
PRjJzX50KpsYJhaLDSNHZ4cs9g==
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
xgFx4kxJCaRovojPOwqtfO+8wnwQ
-----END PRIVATE KEY-----

View File

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFHzCCAwegAwIBAgIJAI1Jk02oI3h0MA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFTATBgNVBAMM
DHd3dy5uYWNvcy5pbzAeFw0yMzAyMTkxMzI5NDlaFw0yMzA0MjAxMzI5NDlaMEUx
CzAJBgNVBAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFjAU
BgNVBAMMDXd3dy5uYWNvcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQD9PVyDu+rZox/kfnEf8u9aoUHkUa1lBbwcrYisTEQGSFGBXEx8jc0rhpG8
7d5dPMF1wojYrN2/WPJvXpMZ/hVw1ceECZf+TdNJdAKmto6R4CEimmZvOHpuakbO
YWx/+HzbrlWZJBC+WWZ0K/db8Ouvs7MJBtJzkrpMzNdqhJS5IzYy9W/ccZbPEMO0
zymKB7aAuD6RGWxhflJATIxi4gfgQUmepUyWrH4PPN/LAlsfq5ydH2sqVHCW2aDi
yLUP0/uC1JlApBVegpBv1VPgY1IwrC401B56w6gfU2w+l7kSaun6/ga9ppGvlxyW
an6iOGjpd/WN1muwdEc5+XeAcM1pioBxWg0VFdvJWBpJH/6gOOTFQ0E+6h95JCKf
ORU5cts/xkSz/h5uuBApv4EhOXnQLwHnh9pNI0dtRoEcBEjFHRZGmph9HpJ5xGGF
4RKFBCfLPZij14jhsk/OINQEn/eFHUXm/A3g2cKWutD5xMH3zxbBp3o7+xDhABzO
nZThYhsRGr2kvEd9lS6c+RLRc3iXVLGzWVtW1eroCV+qY5c41DbBrllb4bH03MRn
5uDB0fEaLwsxFHP8wFl8QCFacUQn9qriImjv5fdzPtt5IhD6Rvj3ccK1Afp7WnVd
+TOv0iDQAGeY4eF7mxMVw17+ydSaO77HLeALkqFVDBshGTDB/QIDAQABoxMwETAP
BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBBQUAA4ICAQA0EENDiwjHeFqgPQvC
8qV6IdalaYHp/4ZmPdX1hBLAMshFaPF0B3gI6OnFM9mTMRdiD1Wpn5r2pkhSGg8s
VDOclPjoxO4HOeVseRECPTGxdT6YKHoqrIshV+byCA/j7KdKNmQpFg++5NgdM5Xw
nee94UUkRoyutgv7kq0noXRxuq2RKYHvkmDm05pbzoWbrQkGKfg4Fgad0velRkEr
A5XK9NFrFF83Kl2FZ8v1iPdnt7qk79VLGi1N4+0+oa2dhfbPeepSan088j3/7YRP
NO/odwDVOHi21hcLbFzZu7iUSrn6rX4HyqHy4SlV5bUJyesakCRrxTBu9Mm2uOP2
IfdIGPZmC1n8DhRH0/2/yGPZjcbUserjI0HixOJjea8vsHmDLGABXP2rgZyO1xG3
glsyqLxOxd72FZCGQyuusS/4ziz12gpClc2N/xy+j80/rmFpXsoY7Q3b+wXL6Q6e
HJx4pv6qF/YuDA6NOO3LV0f3NaxdVEfXCXd8GMIqn172BUkBvNN6/WK0Hx4zMWun
nWnBt5pM+dOkRGdcrR0sfbG70HK8u6k/4Bjlp+TObjvg4NcMqDKPJz8Uus3aHhBk
F4nstwoy9pyZX8nhKn2e6wletdMRnwWk7m5LQ3SgQtjSrbZEUQoINUDhLxLco2t8
GDVPSUOGQpuP8EZ9P8KCNM2xPA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
hUyvH4+U/oi/7nvF3ms0M0bPnX0jNA==
-----END PRIVATE KEY-----

View File

@ -34,7 +34,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
<argLine>-Dnacos.standalone=true -Dnacos.server.ip=127.0.0.1</argLine>
<useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>

View File

@ -0,0 +1,48 @@
/*
* 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.test;
import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
import com.alibaba.nacos.sys.utils.DiskUtils;
import java.io.File;
import java.io.IOException;
/**
* Cache files to clear tool classes.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ConfigCleanUtils {
public static void cleanClientCache() throws IOException {
DiskUtils.deleteDirThenMkdir(LocalConfigInfoProcessor.LOCAL_SNAPSHOT_PATH);
}
/**
* Change test env to new nacos home.
*
* @param caseName test case name
*/
public static String changeToNewTestNacosHome(String caseName) {
String userHome = System.getProperty("user.home");
String testNacosHome = userHome + File.separator + "nacos" + File.separator + caseName;
System.setProperty("nacos.home", testNacosHome);
return testNacosHome;
}
}

View File

@ -0,0 +1,136 @@
/*
* 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.test.client;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest;
import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.remote.client.Connection;
import com.alibaba.nacos.common.remote.client.RpcClient;
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import com.alibaba.nacos.test.ConfigCleanUtils;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* use configPublishRequest for communication verification between client and server
*
* @author githubcheng2978
*/
@RunWith(SpringRunner.class)
@TestConfiguration
@SpringBootTest(classes = {Nacos.class},
properties = {
"server.servlet.context-path=/nacos",
RpcServerTlsConfig.PREFIX+".compatibility=false",
RpcServerTlsConfig.PREFIX+".enableTls=true",
RpcServerTlsConfig.PREFIX+".certChainFile=test-server-cert.pem",
RpcServerTlsConfig.PREFIX+".certPrivateKey=test-server-key.pem",
},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class ConfigIntegrationV1ServerNonCompatibility_CITCase {
public static AtomicInteger increment = new AtomicInteger(100);
@LocalServerPort
private int port;
@BeforeClass
public static void beforeClass() throws IOException {
ConfigCleanUtils.changeToNewTestNacosHome(ConfigIntegrationV1ServerNonCompatibility_CITCase.class.getSimpleName());
}
@BeforeClass
@AfterClass
public static void cleanClientCache() throws Exception {
ConfigCleanUtils.cleanClientCache();
}
@Test
public void test_a_TlsServer() throws Exception {
RpcClient client = RpcClientFactory.createClient("testTlsServer", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), null);
RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo();
serverInfo.setServerIp("127.0.0.1");
serverInfo.setServerPort(port);
Connection connection = client.connectToServer(serverInfo);
Assert.assertNull(connection);
}
@Test
public void test_b_ServerTlsTrustAll() throws Exception {
RpcClientTlsConfig tlsConfig = new RpcClientTlsConfig();
tlsConfig.setEnableTls(true);
tlsConfig.setTrustAll(true);
RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo();
serverInfo.setServerIp("127.0.0.1");
serverInfo.setServerPort(port);
RpcClient clientTrustCa = RpcClientFactory.createClient("testServerTlsTrustCa", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), tlsConfig);
Connection connectionTrustCa = clientTrustCa.connectToServer(serverInfo);
ConfigPublishRequest configPublishRequest = new ConfigPublishRequest();
String content = UUID.randomUUID().toString();
configPublishRequest.setContent(content);
configPublishRequest.setGroup("test-group" + increment.getAndIncrement());
configPublishRequest.setDataId("test-data" + increment.getAndIncrement());
Response response = connectionTrustCa.request(configPublishRequest, TimeUnit.SECONDS.toMillis(3));
Assert.assertTrue(response.isSuccess());
connectionTrustCa.close();
}
@Test
public void test_c_ServerTlsTrustCa() throws Exception {
RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo();
serverInfo.setServerIp("127.0.0.1");
serverInfo.setServerPort(port);
RpcClientTlsConfig tlsConfig = new RpcClientTlsConfig();
tlsConfig.setEnableTls(true);
tlsConfig.setTrustCollectionCertFile("test-ca-cert.pem");
RpcClient clientTrustCa = RpcClientFactory.createClient("testServerTlsTrustCa", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), tlsConfig);
Connection connectionTrustCa = clientTrustCa.connectToServer(serverInfo);
ConfigPublishRequest configPublishRequestCa = new ConfigPublishRequest();
String contentCa = UUID.randomUUID().toString();
configPublishRequestCa.setContent(contentCa);
configPublishRequestCa.setGroup("test-group" + increment.getAndIncrement());
configPublishRequestCa.setDataId("test-data" + increment.getAndIncrement());
Response responseCa = connectionTrustCa.request(configPublishRequestCa, TimeUnit.SECONDS.toMillis(3));
Assert.assertTrue(responseCa.isSuccess());
connectionTrustCa.close();
}
}

View File

@ -0,0 +1,122 @@
/*
* 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.test.client;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest;
import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.remote.client.Connection;
import com.alibaba.nacos.common.remote.client.RpcClient;
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import com.alibaba.nacos.test.ConfigCleanUtils;
import org.junit.*;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* use configPublishRequest for communication verification between client and server
*
* @author githubcheng2978
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Nacos.class},
properties = {
"nacos.standalone=true",
RpcServerTlsConfig.PREFIX+".mutualAuthEnable=true",
RpcServerTlsConfig.PREFIX+".compatibility=false",
RpcServerTlsConfig.PREFIX+".enableTls=true",
RpcServerTlsConfig.PREFIX+".certChainFile=test-server-cert.pem",
RpcServerTlsConfig.PREFIX+".certPrivateKey=test-server-key.pem",
RpcServerTlsConfig.PREFIX+".trustCollectionCertFile=test-ca-cert.pem",
},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class ConfigIntegrationV2MutualAuthTest {
@LocalServerPort
private int port;
public static AtomicInteger increment = new AtomicInteger(100);
@BeforeClass
public static void beforeClass() throws IOException {
ConfigCleanUtils.changeToNewTestNacosHome(ConfigIntegrationV2MutualAuthTest.class.getSimpleName());
}
@After
public void cleanClientCache() throws Exception {
ConfigCleanUtils.cleanClientCache();
}
@Test
public void test_d_MutualAuth() throws Exception {
RpcClientTlsConfig tlsConfig = new RpcClientTlsConfig();
tlsConfig.setEnableTls(true);
tlsConfig.setMutualAuthEnable(true);
tlsConfig.setCertChainFile("test-client-cert.pem");
tlsConfig.setCertPrivateKey("test-client-key.pem");
tlsConfig.setTrustCollectionCertFile("test-ca-cert.pem");
RpcClient client = RpcClientFactory.createClient("testMutualAuth", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), tlsConfig);
RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo();
serverInfo.setServerIp("127.0.0.1");
serverInfo.setServerPort(port);
Connection connection = client.connectToServer(serverInfo);
ConfigPublishRequest configPublishRequest = new ConfigPublishRequest();
String content = UUID.randomUUID().toString();
configPublishRequest.setContent(content);
configPublishRequest.setGroup("test-group"+increment.getAndIncrement());
configPublishRequest.setDataId("test-data"+increment.getAndIncrement());
configPublishRequest.setRequestId(content);
Response response = connection.request(configPublishRequest, TimeUnit.SECONDS.toMillis(5));
Assert.assertTrue(response.isSuccess());
connection.close();
}
@Test
public void test_e_ServerMutualAuthOnly() throws Exception {
RpcClientTlsConfig tlsConfig = new RpcClientTlsConfig();
tlsConfig.setEnableTls(true);
tlsConfig.setTrustCollectionCertFile("test-ca-cert.pem");
RpcClient client = RpcClientFactory.createClient("testServerMutualAuthNoly", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), tlsConfig);
RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo();
serverInfo.setServerIp("127.0.0.1");
serverInfo.setServerPort(port);
Connection connection = client.connectToServer(serverInfo);
Assert.assertNull(connection);
TimeUnit.SECONDS.sleep(3);
}
}

View File

@ -0,0 +1,141 @@
/*
* 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.test.client;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest;
import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.remote.client.Connection;
import com.alibaba.nacos.common.remote.client.RpcClient;
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import com.alibaba.nacos.sys.env.EnvUtil;
import com.alibaba.nacos.test.ConfigCleanUtils;
import org.junit.*;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* use configPublishRequest for communication verification between client and server
*
* @author githubcheng2978
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Nacos.class},
properties = {
"nacos.standalone=true",
RpcServerTlsConfig.PREFIX+".enableTls=true",
RpcServerTlsConfig.PREFIX+".certChainFile=test-server-cert.pem",
RpcServerTlsConfig.PREFIX+".certPrivateKey=test-server-key.pem"
},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class ConfigIntegrationV3Test {
@LocalServerPort
private int port;
public static AtomicInteger increment = new AtomicInteger(100);
@BeforeClass
public static void beforeClass() throws IOException {
ConfigCleanUtils.changeToNewTestNacosHome(ConfigIntegrationV3Test.class.getSimpleName());
}
@BeforeClass
@AfterClass
public static void cleanClientCache() throws Exception {
ConfigCleanUtils.cleanClientCache();
}
@Test
public void test_e_TlsServerAndPlainClient() throws Exception {
RpcClient client = RpcClientFactory.createClient("testTlsServerAndPlainClient", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), null);
RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo();
serverInfo.setServerIp("127.0.0.1");
serverInfo.setServerPort(port);
Connection connection = client.connectToServer(serverInfo);
ConfigPublishRequest configPublishRequest = new ConfigPublishRequest();
String content = UUID.randomUUID().toString();
configPublishRequest.setContent(content);
configPublishRequest.setGroup("test-group" + increment.getAndIncrement());
configPublishRequest.setDataId("test-data" + increment.getAndIncrement());
configPublishRequest.setRequestId(content);
Response response = connection.request(configPublishRequest, TimeUnit.SECONDS.toMillis(3));
Assert.assertTrue(response.isSuccess());
connection.close();
}
@Test
public void test_f_ServerTlsTrustAll() throws Exception {
RpcClientTlsConfig tlsConfig = new RpcClientTlsConfig();
tlsConfig.setEnableTls(true);
tlsConfig.setTrustAll(true);
RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo();
serverInfo.setServerIp("127.0.0.1");
serverInfo.setServerPort(port);
RpcClient clientTrustAll = RpcClientFactory.createClient("testServerTlsTrustAll", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), tlsConfig);
Connection connectionTrustAll = clientTrustAll.connectToServer(serverInfo);
ConfigPublishRequest configPublishRequest = new ConfigPublishRequest();
String content = UUID.randomUUID().toString();
configPublishRequest.setContent(content);
configPublishRequest.setGroup("test-group" + increment.getAndIncrement());
configPublishRequest.setDataId("test-data" + increment.getAndIncrement());
Response response = connectionTrustAll.request(configPublishRequest, TimeUnit.SECONDS.toMillis(3));
Assert.assertTrue(response.isSuccess());
connectionTrustAll.close();
}
@Test
public void test_g_ServerTlsTrustCa() throws Exception {
RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo();
serverInfo.setServerIp("127.0.0.1");
serverInfo.setServerPort(EnvUtil.getPort());
RpcClientTlsConfig tlsConfig = new RpcClientTlsConfig();
tlsConfig.setEnableTls(true);
tlsConfig.setTrustCollectionCertFile("test-ca-cert.pem");
RpcClient clientTrustCa = RpcClientFactory.createClient("testServerTlsTrustCa", ConnectionType.GRPC, Collections.singletonMap("labelKey", "labelValue"), tlsConfig);
Connection connectionTrustCa = clientTrustCa.connectToServer(serverInfo);
ConfigPublishRequest configPublishRequestCa = new ConfigPublishRequest();
String contentCa = UUID.randomUUID().toString();
configPublishRequestCa.setContent(contentCa);
configPublishRequestCa.setGroup("test-group" + increment.getAndIncrement());
configPublishRequestCa.setDataId("test-data" + increment.getAndIncrement());
Response responseCa = connectionTrustCa.request(configPublishRequestCa, TimeUnit.SECONDS.toMillis(3));
Assert.assertTrue(responseCa.isSuccess());
connectionTrustCa.close();
}
}

View File

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFBDCCAuwCCQDasL456kc8pjANBgkqhkiG9w0BAQsFADBEMQswCQYDVQQGEwJH
QjEOMAwGA1UEBwwFQ2hpbmExDjAMBgNVBAoMBW5hY29zMRUwEwYDVQQDDAx3d3cu
bmFjb3MuaW8wHhcNMjMwMjE5MTMyOTQ4WhcNMjQwMjE5MTMyOTQ4WjBEMQswCQYD
VQQGEwJHQjEOMAwGA1UEBwwFQ2hpbmExDjAMBgNVBAoMBW5hY29zMRUwEwYDVQQD
DAx3d3cubmFjb3MuaW8wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDf
zBvzVtSK30CMvju45EqaHfe1vtnNcBP9aPwmci5f0bO7jjkhqpGirRMjEMd4rzGE
WMXDwhmO7B+hWfyRSzKasjIhhADzHA1vx3mPZcTzhEyyqfdUuyAg0LjhMqxvllQp
5BVuieo7l5CRtbhqyyzrY/RtZCJxvkSusJJHgjPhvPd5LqOZ2X4+h6Y41pPox4T0
9f4NZ1gdOr1ypgnOabcqYp+7zbdMNFlfjNtpnpCVYePlDfwj6pchJT3nEphaAIFM
5oM6Zb7MkNeedB4vHo4kYbobd1fgXNZixML2aQdsz5YoBGoYdTXZkoEotoQ0xwU3
FWNNwmlo22we6hmnAOBaTuj7hDeHw+1mfCzXQWjlm8/D0iL3O/K5D1YTcdi4mF5k
lL/WWvl/u6MapZx1+n+x95+H5NmzxCd3ieORj+8armBNLc10EJgANpiFyGO5Eozz
ghV/qEJx/GEcXdFq4Ju5Zkl0JLuR8tm6IVjH1mtCTQsh402HtsRgeweMir7gorPx
YLJky6MKGHv0VV+dhv/92CbTVhDvMoiOiuEmj87rZp+9X17VErHJreZWtEnF13aD
lzvXvl5E/pznLtSrDBJWeg9Sp4zG+Nl8G6EAHaoQiEQPihOGfwun36DB1Sf1iHYv
FaCaqDa90EWqnwPhJ7DvMbwh1R0frjwB8+3oO0tXbwIDAQABMA0GCSqGSIb3DQEB
CwUAA4ICAQCQiePDGv+rcHRnU82d3Gi0MpFY5s5Dizrb3zZc0MJNnILERCe8ANAz
pOkdenUjIi13iKlky6bM37BMQAiw7FNv7vdcic0NRz9ZYVowo/isi7ibvDpvI+Wk
yTzM3EpzKM56syEqYxv0ACoyBB0cfbDonSx6i4cD7BKeb7Bhmlbgf/eSjq7V7gXQ
+v0JApiBhVyApSE4jMWJbSsI2whrsS3pZQu8/kgqIxI2pB15bepOMSlHr+AxApJP
Pu8Qe4tTuSA1T33bo/oLyQmApRHdnM1ghUW5IjRq0vy7W2Z3PYrh8a74t53tPjIV
tECUYvWXOBCm2ihpDlAB9A0jMhYh0QofikZzik0CnG78CKkEF8pXc2WXyh4Je2GF
yE0UDkH5E+6KkOQaA7qPprQYLgrjtrVBz/mZqBCGVneM6AGj7lx4nuBZ1mzbPGHI
o0liANhkoaUiku0eTwP+IQ7q37A5wcAUeS4cWQFcQVQa3uq8lBbvRqWZXsgbwJF0
b94UBH1uCEtV3KX49GpReFtaouCMnfVHqL7TY9xcUvA+Jq32NxwBG/ZwusiYLx9z
vcqdYATjJmbc2SenxtcGq+qX9Jcx7EV5MYKb3TRW8U17i118rIppa6fY8lwIGoYm
8Vy9hrReUgbksjfDOAPbO9arwfmPWh/mXzM1YbxBbsMoxh/BuzUIjA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
F3cfpHAfPJvE2WW+4fRc1SHALKQ/9NY=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFHzCCAwegAwIBAgIJAI1Jk02oI3h1MA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFTATBgNVBAMM
DHd3dy5uYWNvcy5pbzAeFw0yMzAyMTkxMzI5NDlaFw0yMzA0MjAxMzI5NDlaMEUx
CzAJBgNVBAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFjAU
BgNVBAMMDXd3dy5uYWNvcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQDW4rrdJSIlItSKeXpwZK/dV8cZi+57HfwmX8llqR042cWUQCCc7syfqWY/
foL14zQl0plLd319iQYo+juT6omhefhv6bANOrXUW1X5s5ZWdmGVEn5h3Rlg7mhI
l/A7c5OeJCiYuqSKy09Mni9YXRFAUm6/xPQJN3AbBdrZLwxwHYcGW5vtqPjImNsW
dM/HOAOz9LMNrw0zMJ23WA8gX3aEmvXO4GLrXpx4ACJQqTME3bS9Ik+Pc1QnfNl9
w2SNv4Ci3g7nTT6lWj4MTL6qIELHm7SQDYyjBoihkICzDUbv8WdwHWCRuePd+QWt
7pdsOr9FuAEl+mq9UZJ7GhjUu4rg0rlMmfIfmJhskzvkPqql1L9uBfCsHaBSX/vA
24gLVhnVXw0haeEHTnN3JXOmA0bTxycz+JtyvkAJnTRGRBnwIZtCRrrQMqINj6EM
PP0CvtWBo1MN/hjOkIja1j+miZzgE+G1aDqPWAXHlxMv/scJtzxb9Grn+lUlbBrO
1cS0aUHNmFf9fV48gg9dgf4INwrLBhq5nd5/zt80O38qIMpVjQWrcOgs/7V+CLxc
IPBjrPrs2EKmmr/ZiTez0ZFNOM3mFN+ueisKzk4yutQKdIYrGXzfHWJVl9lcHYmy
uUFjIC3ekNaNA7QxvhkQmW2PQwjle7rbPTYbECjkMYRAAZOBsQIDAQABoxMwETAP
BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBBQUAA4ICAQA/USNWOir6FDNTjVYx
7yEcOj9eV6wtuOqr9WgeIwA1fLrv59weBoQO5zFEVfYnhENxMNyJAy21N5+URYf7
rfLrobvNK/VD06ZC3pnYXVohjFURqlmGz8fEs5GV930KkDaO2sBF/w9uGIfoEUlz
edhgWg+QWGAezaTyGFYfGnavkHBqsinADeK7xfeAH6HBdFFXH+/KqTjQyhi6P+Wy
gkfPPxiDiYrOPjrKFNftbaHi2b3fAZWmoEDLnKV9SaPSMcoQBzSCOW0cvnpdS+uu
m9wy1Y5t+S2nRIXQoh8XrKSnXWPEecA+pQd+jlZV+Q/au1O9qFAlM7nRehE6qjNj
umJyuUB7l9gVEQsjEjLJT0TOXSVtLCUefHJkUmXTFkUqqvDFFfbAFZzw7WwGIJMa
dKAhhvs81iLhJ1RmHm0HJeL5L+D6m8B6j3ZxgFdKLEY8VONAATbZzzAnNmjJSj/P
VcbkpzrVqBIn1+82f546zqRdOP8+vvbRPC4Sz1wQk6kZVYsh9mw8gpC1Y7swyoR6
5d0wiNzU9Ccu78Fa7RqGN7jji4PSFNHGruyUj5e1Mqk/nVSoBIZ2urS7p+97/kDr
2HqC2u2v/5wq46xeNilVU6pmr8o1NGsWRlPBlKVkguSwoCdzwEr+FGCOvGjRfn/x
PRjJzX50KpsYJhaLDSNHZ4cs9g==
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
xgFx4kxJCaRovojPOwqtfO+8wnwQ
-----END PRIVATE KEY-----

View File

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFHzCCAwegAwIBAgIJAI1Jk02oI3h0MA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFTATBgNVBAMM
DHd3dy5uYWNvcy5pbzAeFw0yMzAyMTkxMzI5NDlaFw0yMzA0MjAxMzI5NDlaMEUx
CzAJBgNVBAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFjAU
BgNVBAMMDXd3dy5uYWNvcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQD9PVyDu+rZox/kfnEf8u9aoUHkUa1lBbwcrYisTEQGSFGBXEx8jc0rhpG8
7d5dPMF1wojYrN2/WPJvXpMZ/hVw1ceECZf+TdNJdAKmto6R4CEimmZvOHpuakbO
YWx/+HzbrlWZJBC+WWZ0K/db8Ouvs7MJBtJzkrpMzNdqhJS5IzYy9W/ccZbPEMO0
zymKB7aAuD6RGWxhflJATIxi4gfgQUmepUyWrH4PPN/LAlsfq5ydH2sqVHCW2aDi
yLUP0/uC1JlApBVegpBv1VPgY1IwrC401B56w6gfU2w+l7kSaun6/ga9ppGvlxyW
an6iOGjpd/WN1muwdEc5+XeAcM1pioBxWg0VFdvJWBpJH/6gOOTFQ0E+6h95JCKf
ORU5cts/xkSz/h5uuBApv4EhOXnQLwHnh9pNI0dtRoEcBEjFHRZGmph9HpJ5xGGF
4RKFBCfLPZij14jhsk/OINQEn/eFHUXm/A3g2cKWutD5xMH3zxbBp3o7+xDhABzO
nZThYhsRGr2kvEd9lS6c+RLRc3iXVLGzWVtW1eroCV+qY5c41DbBrllb4bH03MRn
5uDB0fEaLwsxFHP8wFl8QCFacUQn9qriImjv5fdzPtt5IhD6Rvj3ccK1Afp7WnVd
+TOv0iDQAGeY4eF7mxMVw17+ydSaO77HLeALkqFVDBshGTDB/QIDAQABoxMwETAP
BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBBQUAA4ICAQA0EENDiwjHeFqgPQvC
8qV6IdalaYHp/4ZmPdX1hBLAMshFaPF0B3gI6OnFM9mTMRdiD1Wpn5r2pkhSGg8s
VDOclPjoxO4HOeVseRECPTGxdT6YKHoqrIshV+byCA/j7KdKNmQpFg++5NgdM5Xw
nee94UUkRoyutgv7kq0noXRxuq2RKYHvkmDm05pbzoWbrQkGKfg4Fgad0velRkEr
A5XK9NFrFF83Kl2FZ8v1iPdnt7qk79VLGi1N4+0+oa2dhfbPeepSan088j3/7YRP
NO/odwDVOHi21hcLbFzZu7iUSrn6rX4HyqHy4SlV5bUJyesakCRrxTBu9Mm2uOP2
IfdIGPZmC1n8DhRH0/2/yGPZjcbUserjI0HixOJjea8vsHmDLGABXP2rgZyO1xG3
glsyqLxOxd72FZCGQyuusS/4ziz12gpClc2N/xy+j80/rmFpXsoY7Q3b+wXL6Q6e
HJx4pv6qF/YuDA6NOO3LV0f3NaxdVEfXCXd8GMIqn172BUkBvNN6/WK0Hx4zMWun
nWnBt5pM+dOkRGdcrR0sfbG70HK8u6k/4Bjlp+TObjvg4NcMqDKPJz8Uus3aHhBk
F4nstwoy9pyZX8nhKn2e6wletdMRnwWk7m5LQ3SgQtjSrbZEUQoINUDhLxLco2t8
GDVPSUOGQpuP8EZ9P8KCNM2xPA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQD9PVyDu+rZox/k
fnEf8u9aoUHkUa1lBbwcrYisTEQGSFGBXEx8jc0rhpG87d5dPMF1wojYrN2/WPJv
XpMZ/hVw1ceECZf+TdNJdAKmto6R4CEimmZvOHpuakbOYWx/+HzbrlWZJBC+WWZ0
K/db8Ouvs7MJBtJzkrpMzNdqhJS5IzYy9W/ccZbPEMO0zymKB7aAuD6RGWxhflJA
TIxi4gfgQUmepUyWrH4PPN/LAlsfq5ydH2sqVHCW2aDiyLUP0/uC1JlApBVegpBv
1VPgY1IwrC401B56w6gfU2w+l7kSaun6/ga9ppGvlxyWan6iOGjpd/WN1muwdEc5
+XeAcM1pioBxWg0VFdvJWBpJH/6gOOTFQ0E+6h95JCKfORU5cts/xkSz/h5uuBAp
v4EhOXnQLwHnh9pNI0dtRoEcBEjFHRZGmph9HpJ5xGGF4RKFBCfLPZij14jhsk/O
INQEn/eFHUXm/A3g2cKWutD5xMH3zxbBp3o7+xDhABzOnZThYhsRGr2kvEd9lS6c
+RLRc3iXVLGzWVtW1eroCV+qY5c41DbBrllb4bH03MRn5uDB0fEaLwsxFHP8wFl8
QCFacUQn9qriImjv5fdzPtt5IhD6Rvj3ccK1Afp7WnVd+TOv0iDQAGeY4eF7mxMV
w17+ydSaO77HLeALkqFVDBshGTDB/QIDAQABAoICAGiF7SuKYpLV25IKBlMziEuW
B4Zfl/v8c/o6PhEvoVweeVW1bPRz6t0uO/UJESDWtNsQIj+ciiIyak5BcOHnl53s
/t6mvw99u9mzgmyhKRNYuRR5OhJp806jmvoQCCKBw7dAq5/73NVUPQ9yHjTaqczp
lNoC8NY3F6IfYkJa2q/XssUxvKv2TlLFDqIQZ4rLSC603U4yeiN7aiOT9NXTiYCs
MeDDRWtjYtyTOaOnI0ldIdVQZIEiPR5mURuJ0AHqcwM7EM43a4KIzWj7WhVhqUjh
qGixrKrrGvdjDWiAYykQ6+Zm9w1MNRGOg4QqDH6UXekPVFDo0aYROFzbdNGUvZMi
Ico/fU8HPliRQFp/yGgBelhDSR1WnSFtEiGXt87iVkz+BXz2/P5jPOxA3wCR2Spj
mrForvwrCE9wC3YUyl2QK6JZ1GWbbFCLAUqsW1l37B/SSZhtY5vyMaYOqvPRIjPG
cy0t5rlxTXx1qYjyUv+qNxyyAeafTVxSbZObxCaDBrSd5atW3ZzdBDA+s2maFtrA
wNE6bnvMpritLV2lltM4bT6eE3yF8rqFk2SJo7oRPv/OI9NRUVrFNolU2fsMnJt3
1ornNXyyeFqptRQiheSn4i1G/W0hYUudCj9yJucNbprQIcPDu1od73umJvH5O8Wk
f6JH6YLCH34xp8iBRTWZAoIBAQD/Sin00KiJTIhiNdDyys5WftnfdNEXkPCy0CYq
7FZwxR3kFNRmAi9Da9Jo6D2+cvbjWGn3JVcdFyi/sFCcED88Fs6umKoQ3Og3gqoG
tBjKy1VzWaODQ3BTQhfh3aKSsahs9Nyi2fOi+u4d/qNpadJHENL9y+A53W5+JSyY
BjOBgUI5qWxiI4m8m93L/E99Sn8MuzhLvsgSpFkMUOjS/18e4BDvZW2uDUGYNKnm
EaGARFXHQRZJy33Un/tr+Xfl00+ESDSc+yHlnp4Knlk/CFwdOcj312Mph70uNrUo
GqQKOE0mX5Tr+j0SwQTCfq+geHWoL5VGGulNCA5YNR9fXvhnAoIBAQD98bzBXMRU
3FR6oAwif+SknTXbEbfaJHXpC56SZVFgG+4+wkV/XziBw/l6CY2FWE/yhTIzQYyr
11Irl+8Vdrd736okh6gNEQJ2MkvLxnPDpwArB6/qAnaY5q4fdPMJ8P/oS9uRP9HO
XWFzonGm9juNS/T5YYFQsZFJVgHSdEqDe58ZdmgLnlLz6gLt/Eol38NfzBA7LHu6
wM0mEvNHhub74Ok7tKrv8f9WEhQnOvFBSslQ3wtHYwK14Zs4VC1ccjBJe22y2ir5
xOGtTdu7MK1TkdG8xBS9Ew2IzbZFT9mP3a6bJbbfN5NkoFZW/hm+zFbYrAigvE6f
mTw+YBJCRgP7AoIBACKqLGZMywXRuZc0XYoKVdhS4zy/fQDpMnXlY7liXB519agZ
1/l+BHLwOiL6nh+1NqcKQ2FG1bxif6r/wwJeBmgfZLM6kaU2ieW3vWSpodAvqgu+
uUBCsQbtK5cE5GVs8ETTPv5x/+46iojSIdhXgTEbLLs/qtPQqIdCfvqppObJ6Xcw
9UGiN7q/o29mdFi7++J7rZpDbqFxZZIRjnvQJ1dm74XCTRFcRXLoe8V80WQ8YzVq
Nh+RHSX5D0fLGSfA+MQqldJXG3Q1hJpGhDHV7cQeK5bTzWg/QUX8Mb8fVvT4TimO
wwcD9LUONpo+X5S3pqpOw8NANju6g1Ag7oChwbMCggEALIiJJovDLnKZKgwJNL+i
9C9Rs4JO8KV2PBE6lMfJ1oXvaPgewfCL803P4VPtipXrJ0eufwiex7/x/A0f826n
TMTzjIZxtSDngpzdZ/X8dTJDOEiX0/zsmXHS1VdoC7VE25L6BWXgwETmAyZYsgP6
e5P3eQhdai5JoUfA+AxGyPoT854tLuRr/bRrIRseUbgFBja+HfJ2HFEVaPjnywJg
XYmavUq4s22H7qsq95pBlsaruU/0JWe6oPTYiK9SaSTpTOmlWjkiUjzxqre9sf0e
WEp5MpZcYLAHrpcMwOj46V7h8PlTMaAIbBwmKAlVsH0bOdIpjS6YxypTQ0kLyq2G
owKCAQEAubNmG1gmSpgM9QUptMQbfA+4xaYnpm1EId8Wg5DzP6v4z+udVcAaUIOd
jZonV9lYkQVtt0GKmVsP9KQHn4XiOc+TyVyLfL3qZn5QEzDhUpS4p1QbJlbptHZL
e0YzkRFKEuv7lgzPz5idU29h5lg3xbwbFOYae3pvdhhnabX3p7xZseLZ6PiEBDDc
mn3OY0RX9Plr9/ztszXBovgUgCMfcGkZPAHB30aAfoFLnFJLQnonFOtZX2ckHrQy
s42SbEUc+Hpm5UgF5Vh6pfcCJ8OV8ogQsRrsluCKk5xPBkCnWAqWepOCh585IAXN
hUyvH4+U/oi/7nvF3ms0M0bPnX0jNA==
-----END PRIVATE KEY-----

View File

@ -35,6 +35,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
<argLine>-Dnacos.standalone=true -Dnacos.server.ip=127.0.0.1 -Dnacos.naming.clean.empty-service.expired-time=1800000</argLine>
<useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>

View File

@ -0,0 +1,179 @@
/*
* 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.test.naming;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingMaintainFactory;
import com.alibaba.nacos.api.naming.NamingMaintainService;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.Service;
import com.alibaba.nacos.api.selector.ExpressionSelector;
import com.alibaba.nacos.api.selector.NoneSelector;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.test.naming.NamingBase.randomDomainName;
/**
* @author githucheng2978.
* @date .
**/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Nacos.class, properties = {
"server.servlet.context-path=/nacos",
RpcServerTlsConfig.PREFIX+".enableTls=true",
RpcServerTlsConfig.PREFIX+".compatibility=true",
RpcServerTlsConfig.PREFIX+".certChainFile=test-server-cert.pem",
RpcServerTlsConfig.PREFIX+".certPrivateKey=test-server-key.pem",
},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class NamingCompatibilityServiceTls_ITCase {
private NamingMaintainService namingMaintainService;
private NamingService namingService;
private Instance instance;
private String serviceName;
@LocalServerPort
private int port;
@Before
public void init() throws Exception {
NamingBase.prepareServer(port);
if (namingMaintainService == null) {
TimeUnit.SECONDS.sleep(10);
namingMaintainService = NamingMaintainFactory.createMaintainService("127.0.0.1" + ":" + port);
}
if (namingService == null) {
TimeUnit.SECONDS.sleep(10);
namingService = NamingFactory.createNamingService("127.0.0.1" + ":" + port);
}
instance = new Instance();
instance.setIp("127.0.0.1");
instance.setPort(8081);
instance.setWeight(2);
instance.setClusterName(Constants.DEFAULT_CLUSTER_NAME);
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external");
map.put("version", "1.0");
instance.setMetadata(map);
serviceName = randomDomainName();
}
@Test
public void updateInstance() throws NacosException, InterruptedException {
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external-update");
map.put("version", "2.0");
namingService.registerInstance(serviceName, instance);
instance.setMetadata(map);
namingMaintainService.updateInstance(serviceName, instance);
TimeUnit.SECONDS.sleep(3L);
List<Instance> instances = namingService.getAllInstances(serviceName, false);
Assert.assertEquals(instances.size(), 1);
Assert.assertEquals("2.0", instances.get(0).getMetadata().get("version"));
System.out.println(instances.get(0));
}
@Test
public void updateInstanceWithDisable() throws NacosException, InterruptedException {
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external-update");
map.put("version", "2.0");
namingService.registerInstance(serviceName, instance);
instance.setMetadata(map);
instance.setEnabled(false);
namingMaintainService.updateInstance(serviceName, instance);
TimeUnit.SECONDS.sleep(3L);
List<Instance> instances = namingService.getAllInstances(serviceName, false);
Assert.assertEquals(0, instances.size());
}
@Test
public void createAndUpdateService() throws NacosException {
String serviceName = randomDomainName();
// register service
Service preService = new Service();
preService.setName(serviceName);
preService.setGroupName(Constants.DEFAULT_GROUP);
preService.setProtectThreshold(1.0f);
Map<String, String> metadata = new HashMap<String, String>();
metadata.put(serviceName, "this is a register metadata");
preService.setMetadata(metadata);
ExpressionSelector selector = new ExpressionSelector();
selector.setExpression("CONSUMER.label.A=PROVIDER.label.A &CONSUMER.label.B=PROVIDER.label.B");
System.out.println("service info : " + preService);
namingMaintainService.createService(preService, selector);
Service remoteService = namingMaintainService.queryService(serviceName);
System.out.println("remote service info : " + remoteService);
Assert.assertEquals(preService.toString(), remoteService.toString());
// update service
Service nowService = new Service();
nowService.setName(serviceName);
nowService.setGroupName(Constants.DEFAULT_GROUP);
nowService.setProtectThreshold(1.0f);
metadata.clear();
metadata.put(serviceName, "this is a update metadata");
nowService.setMetadata(metadata);
namingMaintainService.updateService(nowService, new NoneSelector());
remoteService = namingMaintainService.queryService(serviceName);
System.out.println("remote service info : " + remoteService);
Assert.assertEquals(nowService.toString(), remoteService.toString());
}
@Test
public void deleteService() throws NacosException {
String serviceName = randomDomainName();
Service preService = new Service();
preService.setName(serviceName);
System.out.println("service info : " + preService);
namingMaintainService.createService(preService, new NoneSelector());
Assert.assertTrue(namingMaintainService.deleteService(serviceName));
}
@After
public void tearDown() throws NacosException {
namingMaintainService.shutDown();
namingService.shutDown();
}
}

View File

@ -0,0 +1,148 @@
/*
* 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.test.naming;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.common.remote.client.RpcConstants;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import org.junit.After;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.test.naming.NamingBase.randomDomainName;
/**
* @author githucheng2978.
* @date .
**/
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@SpringBootTest(classes = Nacos.class, properties = {
"server.servlet.context-path=/nacos",
RpcServerTlsConfig.PREFIX+".enableTls=true",
RpcServerTlsConfig.PREFIX+".mutualAuthEnable=true",
RpcServerTlsConfig.PREFIX+".compatibility=false",
RpcServerTlsConfig.PREFIX+".certChainFile=test-server-cert.pem",
RpcServerTlsConfig.PREFIX+".certPrivateKey=test-server-key.pem",
RpcServerTlsConfig.PREFIX+".trustCollectionCertFile=test-ca-cert.pem",
},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class NamingTlsServiceAndMutualAuth_ITCase {
@LocalServerPort
private int port;
@Test
public void test_a_MutualAuth() throws NacosException {
String serviceName = randomDomainName();
System.setProperty(RpcConstants.RPC_CLIENT_TLS_ENABLE,"true");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH,"test-ca-cert.pem");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_CERT_CHAIN_PATH,"test-client-cert.pem");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_CERT_KEY,"test-client-key.pem");
System.setProperty(RpcConstants.RPC_CLIENT_MUTUAL_AUTH,"true");
Instance instance = new Instance();
instance.setIp("127.0.0.1");
instance.setPort(8081);
instance.setWeight(2);
instance.setClusterName(Constants.DEFAULT_CLUSTER_NAME);
NamingService namingService = NamingFactory.createNamingService("127.0.0.1" + ":" + port);
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external-update");
map.put("version", "2.0");
instance.setMetadata(map);
namingService.registerInstance(serviceName, instance);
try {
TimeUnit.SECONDS.sleep(3L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
List<Instance> instances = namingService.getAllInstances(serviceName, false);
Assert.assertEquals(instances.size(), 1);
Assert.assertEquals("2.0", instances.get(0).getMetadata().get("version"));
namingService.shutDown();
}
@Test(expected = NacosException.class)
public void test_b_MutualAuthClientTrustCa() throws NacosException {
String serviceName = randomDomainName();
System.setProperty(RpcConstants.RPC_CLIENT_TLS_ENABLE,"true");
System.setProperty(RpcConstants.RPC_CLIENT_MUTUAL_AUTH,"true");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_CERT_CHAIN_PATH,"");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_CERT_KEY,"");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH,"test-ca-cert.pem");
Instance instance = new Instance();
instance.setIp("127.0.0.1");
instance.setPort(8081);
instance.setWeight(2);
instance.setClusterName(Constants.DEFAULT_CLUSTER_NAME);
NamingService namingService = NamingFactory.createNamingService("127.0.0.1" + ":" + port);
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external-update");
map.put("version", "2.0");
instance.setMetadata(map);
namingService.registerInstance(serviceName, instance);
namingService.shutDown();
}
@Test(expected = NacosException.class)
public void test_c_MutualAuthClientTrustALl() throws NacosException {
String serviceName = randomDomainName();
System.setProperty(RpcConstants.RPC_CLIENT_TLS_ENABLE,"true");
System.setProperty(RpcConstants.RPC_CLIENT_MUTUAL_AUTH,"true");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_CERT_CHAIN_PATH,"");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_CERT_KEY,"");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_ALL,"true");
Instance instance = new Instance();
instance.setIp("127.0.0.1");
instance.setPort(8081);
instance.setWeight(2);
instance.setClusterName(Constants.DEFAULT_CLUSTER_NAME);
NamingService namingService = NamingFactory.createNamingService("127.0.0.1" + ":" + port);
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external-update");
map.put("version", "2.0");
instance.setMetadata(map);
namingService.registerInstance(serviceName, instance);
namingService.shutDown();
}
@After
public void after(){
System.setProperty(RpcConstants.RPC_CLIENT_TLS_ENABLE,"");
}
}

View File

@ -0,0 +1,136 @@
/*
* 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.test.naming;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.common.remote.client.RpcConstants;
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.alibaba.nacos.test.naming.NamingBase.randomDomainName;
/**
* @author githucheng2978.
* @date .
**/
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@SpringBootTest(classes = Nacos.class, properties = {
"server.servlet.context-path=/nacos",
RpcServerTlsConfig.PREFIX+".enableTls=true",
RpcServerTlsConfig.PREFIX+".compatibility=false",
RpcServerTlsConfig.PREFIX+".certChainFile=test-server-cert.pem",
RpcServerTlsConfig.PREFIX+".certPrivateKey=test-server-key.pem",
},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class NamingTlsServiceTls_ITCase {
@LocalServerPort
private int port;
@Test(expected = NacosException.class)
public void Tls_a_ServerAndPlainClient() throws NacosException {
Instance instance = new Instance();
instance.setIp("127.0.0.1");
instance.setPort(8081);
instance.setWeight(2);
instance.setClusterName(Constants.DEFAULT_CLUSTER_NAME);
NamingService namingService = NamingFactory.createNamingService("127.0.0.1" + ":" + port);
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external-update");
map.put("version", "2.0");
namingService.registerInstance(randomDomainName(), instance);
namingService.shutDown();
}
@Test
public void Tls_b_ServerAndTlsClientTrustCa() throws NacosException {
String serviceName = randomDomainName();
System.setProperty(RpcConstants.RPC_CLIENT_TLS_ENABLE,"true");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH,"test-ca-cert.pem");
Instance instance = new Instance();
instance.setIp("127.0.0.1");
instance.setPort(8081);
instance.setWeight(2);
instance.setClusterName(Constants.DEFAULT_CLUSTER_NAME);
NamingService namingService = NamingFactory.createNamingService("127.0.0.1" + ":" + port);
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external-update");
map.put("version", "2.0");
instance.setMetadata(map);
try {
TimeUnit.SECONDS.sleep(1L);
namingService.registerInstance(serviceName, instance);
TimeUnit.SECONDS.sleep(3L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
List<Instance> instances = namingService.getAllInstances(serviceName, false);
Assert.assertEquals(instances.size(), 1);
Assert.assertEquals("2.0", instances.get(0).getMetadata().get("version"));
namingService.shutDown();
}
@Test
public void Tls_c_ServerAndTlsClientAll() throws NacosException {
String serviceName = randomDomainName();
System.setProperty(RpcConstants.RPC_CLIENT_TLS_ENABLE,"true");
System.setProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_ALL,"true");
Instance instance = new Instance();
instance.setIp("127.0.0.1");
instance.setPort(8081);
instance.setWeight(2);
instance.setClusterName(Constants.DEFAULT_CLUSTER_NAME);
NamingService namingService = NamingFactory.createNamingService("127.0.0.1" + ":" + port);
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external-update");
map.put("version", "2.0");
instance.setMetadata(map);
namingService.registerInstance(serviceName, instance);
try {
TimeUnit.SECONDS.sleep(3L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
List<Instance> instances = namingService.getAllInstances(serviceName, false);
Assert.assertEquals(instances.size(), 1);
Assert.assertEquals("2.0", instances.get(0).getMetadata().get("version"));
System.out.println(instances.get(0));
namingService.shutDown();
}
}

View File

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFBDCCAuwCCQDasL456kc8pjANBgkqhkiG9w0BAQsFADBEMQswCQYDVQQGEwJH
QjEOMAwGA1UEBwwFQ2hpbmExDjAMBgNVBAoMBW5hY29zMRUwEwYDVQQDDAx3d3cu
bmFjb3MuaW8wHhcNMjMwMjE5MTMyOTQ4WhcNMjQwMjE5MTMyOTQ4WjBEMQswCQYD
VQQGEwJHQjEOMAwGA1UEBwwFQ2hpbmExDjAMBgNVBAoMBW5hY29zMRUwEwYDVQQD
DAx3d3cubmFjb3MuaW8wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDf
zBvzVtSK30CMvju45EqaHfe1vtnNcBP9aPwmci5f0bO7jjkhqpGirRMjEMd4rzGE
WMXDwhmO7B+hWfyRSzKasjIhhADzHA1vx3mPZcTzhEyyqfdUuyAg0LjhMqxvllQp
5BVuieo7l5CRtbhqyyzrY/RtZCJxvkSusJJHgjPhvPd5LqOZ2X4+h6Y41pPox4T0
9f4NZ1gdOr1ypgnOabcqYp+7zbdMNFlfjNtpnpCVYePlDfwj6pchJT3nEphaAIFM
5oM6Zb7MkNeedB4vHo4kYbobd1fgXNZixML2aQdsz5YoBGoYdTXZkoEotoQ0xwU3
FWNNwmlo22we6hmnAOBaTuj7hDeHw+1mfCzXQWjlm8/D0iL3O/K5D1YTcdi4mF5k
lL/WWvl/u6MapZx1+n+x95+H5NmzxCd3ieORj+8armBNLc10EJgANpiFyGO5Eozz
ghV/qEJx/GEcXdFq4Ju5Zkl0JLuR8tm6IVjH1mtCTQsh402HtsRgeweMir7gorPx
YLJky6MKGHv0VV+dhv/92CbTVhDvMoiOiuEmj87rZp+9X17VErHJreZWtEnF13aD
lzvXvl5E/pznLtSrDBJWeg9Sp4zG+Nl8G6EAHaoQiEQPihOGfwun36DB1Sf1iHYv
FaCaqDa90EWqnwPhJ7DvMbwh1R0frjwB8+3oO0tXbwIDAQABMA0GCSqGSIb3DQEB
CwUAA4ICAQCQiePDGv+rcHRnU82d3Gi0MpFY5s5Dizrb3zZc0MJNnILERCe8ANAz
pOkdenUjIi13iKlky6bM37BMQAiw7FNv7vdcic0NRz9ZYVowo/isi7ibvDpvI+Wk
yTzM3EpzKM56syEqYxv0ACoyBB0cfbDonSx6i4cD7BKeb7Bhmlbgf/eSjq7V7gXQ
+v0JApiBhVyApSE4jMWJbSsI2whrsS3pZQu8/kgqIxI2pB15bepOMSlHr+AxApJP
Pu8Qe4tTuSA1T33bo/oLyQmApRHdnM1ghUW5IjRq0vy7W2Z3PYrh8a74t53tPjIV
tECUYvWXOBCm2ihpDlAB9A0jMhYh0QofikZzik0CnG78CKkEF8pXc2WXyh4Je2GF
yE0UDkH5E+6KkOQaA7qPprQYLgrjtrVBz/mZqBCGVneM6AGj7lx4nuBZ1mzbPGHI
o0liANhkoaUiku0eTwP+IQ7q37A5wcAUeS4cWQFcQVQa3uq8lBbvRqWZXsgbwJF0
b94UBH1uCEtV3KX49GpReFtaouCMnfVHqL7TY9xcUvA+Jq32NxwBG/ZwusiYLx9z
vcqdYATjJmbc2SenxtcGq+qX9Jcx7EV5MYKb3TRW8U17i118rIppa6fY8lwIGoYm
8Vy9hrReUgbksjfDOAPbO9arwfmPWh/mXzM1YbxBbsMoxh/BuzUIjA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
F3cfpHAfPJvE2WW+4fRc1SHALKQ/9NY=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFHzCCAwegAwIBAgIJAI1Jk02oI3h1MA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFTATBgNVBAMM
DHd3dy5uYWNvcy5pbzAeFw0yMzAyMTkxMzI5NDlaFw0yMzA0MjAxMzI5NDlaMEUx
CzAJBgNVBAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFjAU
BgNVBAMMDXd3dy5uYWNvcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQDW4rrdJSIlItSKeXpwZK/dV8cZi+57HfwmX8llqR042cWUQCCc7syfqWY/
foL14zQl0plLd319iQYo+juT6omhefhv6bANOrXUW1X5s5ZWdmGVEn5h3Rlg7mhI
l/A7c5OeJCiYuqSKy09Mni9YXRFAUm6/xPQJN3AbBdrZLwxwHYcGW5vtqPjImNsW
dM/HOAOz9LMNrw0zMJ23WA8gX3aEmvXO4GLrXpx4ACJQqTME3bS9Ik+Pc1QnfNl9
w2SNv4Ci3g7nTT6lWj4MTL6qIELHm7SQDYyjBoihkICzDUbv8WdwHWCRuePd+QWt
7pdsOr9FuAEl+mq9UZJ7GhjUu4rg0rlMmfIfmJhskzvkPqql1L9uBfCsHaBSX/vA
24gLVhnVXw0haeEHTnN3JXOmA0bTxycz+JtyvkAJnTRGRBnwIZtCRrrQMqINj6EM
PP0CvtWBo1MN/hjOkIja1j+miZzgE+G1aDqPWAXHlxMv/scJtzxb9Grn+lUlbBrO
1cS0aUHNmFf9fV48gg9dgf4INwrLBhq5nd5/zt80O38qIMpVjQWrcOgs/7V+CLxc
IPBjrPrs2EKmmr/ZiTez0ZFNOM3mFN+ueisKzk4yutQKdIYrGXzfHWJVl9lcHYmy
uUFjIC3ekNaNA7QxvhkQmW2PQwjle7rbPTYbECjkMYRAAZOBsQIDAQABoxMwETAP
BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBBQUAA4ICAQA/USNWOir6FDNTjVYx
7yEcOj9eV6wtuOqr9WgeIwA1fLrv59weBoQO5zFEVfYnhENxMNyJAy21N5+URYf7
rfLrobvNK/VD06ZC3pnYXVohjFURqlmGz8fEs5GV930KkDaO2sBF/w9uGIfoEUlz
edhgWg+QWGAezaTyGFYfGnavkHBqsinADeK7xfeAH6HBdFFXH+/KqTjQyhi6P+Wy
gkfPPxiDiYrOPjrKFNftbaHi2b3fAZWmoEDLnKV9SaPSMcoQBzSCOW0cvnpdS+uu
m9wy1Y5t+S2nRIXQoh8XrKSnXWPEecA+pQd+jlZV+Q/au1O9qFAlM7nRehE6qjNj
umJyuUB7l9gVEQsjEjLJT0TOXSVtLCUefHJkUmXTFkUqqvDFFfbAFZzw7WwGIJMa
dKAhhvs81iLhJ1RmHm0HJeL5L+D6m8B6j3ZxgFdKLEY8VONAATbZzzAnNmjJSj/P
VcbkpzrVqBIn1+82f546zqRdOP8+vvbRPC4Sz1wQk6kZVYsh9mw8gpC1Y7swyoR6
5d0wiNzU9Ccu78Fa7RqGN7jji4PSFNHGruyUj5e1Mqk/nVSoBIZ2urS7p+97/kDr
2HqC2u2v/5wq46xeNilVU6pmr8o1NGsWRlPBlKVkguSwoCdzwEr+FGCOvGjRfn/x
PRjJzX50KpsYJhaLDSNHZ4cs9g==
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
xgFx4kxJCaRovojPOwqtfO+8wnwQ
-----END PRIVATE KEY-----

View File

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFHzCCAwegAwIBAgIJAI1Jk02oI3h0MA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFTATBgNVBAMM
DHd3dy5uYWNvcy5pbzAeFw0yMzAyMTkxMzI5NDlaFw0yMzA0MjAxMzI5NDlaMEUx
CzAJBgNVBAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEOMAwGA1UECgwFbmFjb3MxFjAU
BgNVBAMMDXd3dy5uYWNvcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQD9PVyDu+rZox/kfnEf8u9aoUHkUa1lBbwcrYisTEQGSFGBXEx8jc0rhpG8
7d5dPMF1wojYrN2/WPJvXpMZ/hVw1ceECZf+TdNJdAKmto6R4CEimmZvOHpuakbO
YWx/+HzbrlWZJBC+WWZ0K/db8Ouvs7MJBtJzkrpMzNdqhJS5IzYy9W/ccZbPEMO0
zymKB7aAuD6RGWxhflJATIxi4gfgQUmepUyWrH4PPN/LAlsfq5ydH2sqVHCW2aDi
yLUP0/uC1JlApBVegpBv1VPgY1IwrC401B56w6gfU2w+l7kSaun6/ga9ppGvlxyW
an6iOGjpd/WN1muwdEc5+XeAcM1pioBxWg0VFdvJWBpJH/6gOOTFQ0E+6h95JCKf
ORU5cts/xkSz/h5uuBApv4EhOXnQLwHnh9pNI0dtRoEcBEjFHRZGmph9HpJ5xGGF
4RKFBCfLPZij14jhsk/OINQEn/eFHUXm/A3g2cKWutD5xMH3zxbBp3o7+xDhABzO
nZThYhsRGr2kvEd9lS6c+RLRc3iXVLGzWVtW1eroCV+qY5c41DbBrllb4bH03MRn
5uDB0fEaLwsxFHP8wFl8QCFacUQn9qriImjv5fdzPtt5IhD6Rvj3ccK1Afp7WnVd
+TOv0iDQAGeY4eF7mxMVw17+ydSaO77HLeALkqFVDBshGTDB/QIDAQABoxMwETAP
BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBBQUAA4ICAQA0EENDiwjHeFqgPQvC
8qV6IdalaYHp/4ZmPdX1hBLAMshFaPF0B3gI6OnFM9mTMRdiD1Wpn5r2pkhSGg8s
VDOclPjoxO4HOeVseRECPTGxdT6YKHoqrIshV+byCA/j7KdKNmQpFg++5NgdM5Xw
nee94UUkRoyutgv7kq0noXRxuq2RKYHvkmDm05pbzoWbrQkGKfg4Fgad0velRkEr
A5XK9NFrFF83Kl2FZ8v1iPdnt7qk79VLGi1N4+0+oa2dhfbPeepSan088j3/7YRP
NO/odwDVOHi21hcLbFzZu7iUSrn6rX4HyqHy4SlV5bUJyesakCRrxTBu9Mm2uOP2
IfdIGPZmC1n8DhRH0/2/yGPZjcbUserjI0HixOJjea8vsHmDLGABXP2rgZyO1xG3
glsyqLxOxd72FZCGQyuusS/4ziz12gpClc2N/xy+j80/rmFpXsoY7Q3b+wXL6Q6e
HJx4pv6qF/YuDA6NOO3LV0f3NaxdVEfXCXd8GMIqn172BUkBvNN6/WK0Hx4zMWun
nWnBt5pM+dOkRGdcrR0sfbG70HK8u6k/4Bjlp+TObjvg4NcMqDKPJz8Uus3aHhBk
F4nstwoy9pyZX8nhKn2e6wletdMRnwWk7m5LQ3SgQtjSrbZEUQoINUDhLxLco2t8
GDVPSUOGQpuP8EZ9P8KCNM2xPA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
hUyvH4+U/oi/7nvF3ms0M0bPnX0jNA==
-----END PRIVATE KEY-----