commit
8ac6c84a58
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -46,4 +46,4 @@ jobs:
|
||||
- name: "Codecov"
|
||||
uses: codecov/codecov-action@v3.1.0
|
||||
with:
|
||||
files: ./address/target/site/jacoco/jacoco.xml,./api/target/site/jacoco/jacoco.xml,./auth/target/site/jacoco/jacoco.xml,./client/target/site/jacoco/jacoco.xml,./common/target/site/jacoco/jacoco.xml,./consistency/target/site/jacoco/jacoco.xml,./console/target/site/jacoco/jacoco.xml,./core/target/site/jacoco/jacoco.xml,./naming/target/site/jacoco/jacoco.xml,./plugin-default-impl/target/site/jacoco/jacoco.xml,./plugin/auth/target/site/jacoco/jacoco.xml,./plugin/encryption/target/site/jacoco/jacoco.xml,./sys/target/site/jacoco/jacoco.xml
|
||||
files: ./address/target/site/jacoco/jacoco.xml,./api/target/site/jacoco/jacoco.xml,./auth/target/site/jacoco/jacoco.xml,./client/target/site/jacoco/jacoco.xml,./common/target/site/jacoco/jacoco.xml,./consistency/target/site/jacoco/jacoco.xml,./console/target/site/jacoco/jacoco.xml,./core/target/site/jacoco/jacoco.xml,./naming/target/site/jacoco/jacoco.xml,./persistence/target/site/jacoco/jacoco.xml,./plugin-default-impl/nacos-default-auth-plugin/target/site/jacoco/jacoco.xml,./plugin/auth/target/site/jacoco/jacoco.xml,./plugin/config/target/site/jacoco/jacoco.xml,./plugin/control/target/site/jacoco/jacoco.xml,./plugin/datasource/target/site/jacoco/jacoco.xml,./plugin/encryption/target/site/jacoco/jacoco.xml,./plugin/environment/target/site/jacoco/jacoco.xml,./plugin/trace/target/site/jacoco/jacoco.xml,./prometheus/target/site/jacoco/jacoco.xml,./sys/target/site/jacoco/jacoco.xml
|
||||
|
2
.github/workflows/pr-ci.yml
vendored
2
.github/workflows/pr-ci.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
name: Upload distribution tar
|
||||
with:
|
||||
name: nacos
|
||||
path: distribution/target/nacos-server-*-SNAPSHOT.tar.gz
|
||||
path: distribution/target/nacos-server-*.tar.gz
|
||||
- name: Save PR number
|
||||
run: |
|
||||
mkdir -p ./pr
|
||||
|
2
.github/workflows/pr-e2e-test.yml
vendored
2
.github/workflows/pr-e2e-test.yml
vendored
@ -62,7 +62,7 @@ jobs:
|
||||
- name: Build and save docker images
|
||||
id: build-images
|
||||
run: |
|
||||
mv nacos-server-*-SNAPSHOT.tar.gz nacos-e2e/cicd/build
|
||||
mv nacos-server-*.tar.gz nacos-e2e/cicd/build
|
||||
cd nacos-e2e/cicd/build
|
||||
version=${{ github.event.pull_request.number || github.ref_name }}-$(uuidgen)
|
||||
mkdir versionlist
|
||||
|
4
.github/workflows/push-ci.yaml
vendored
4
.github/workflows/push-ci.yaml
vendored
@ -42,7 +42,7 @@ jobs:
|
||||
name: Upload distribution tar
|
||||
with:
|
||||
name: nacos
|
||||
path: distribution/target/nacos-server-*-SNAPSHOT.tar.gz
|
||||
path: distribution/target/nacos-server-*.tar.gz
|
||||
|
||||
docker:
|
||||
if: ${{ success() }}
|
||||
@ -74,7 +74,7 @@ jobs:
|
||||
- name: Build and save docker images
|
||||
id: build-images
|
||||
run: |
|
||||
mv nacos-server-*-SNAPSHOT.tar.gz nacos-e2e/cicd/build/
|
||||
mv nacos-server-*.tar.gz nacos-e2e/cicd/build/
|
||||
cd nacos-e2e/cicd/build
|
||||
version=${{ github.event.pull_request.number || github.ref_name }}-$(uuidgen)
|
||||
mkdir versionlist
|
||||
|
@ -18,8 +18,8 @@ package com.alibaba.nacos.api.ability.constant;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -30,6 +30,12 @@ import java.util.stream.Collectors;
|
||||
* @date 2022/8/31 12:27
|
||||
**/
|
||||
public enum AbilityKey {
|
||||
|
||||
/**
|
||||
* Server support register or deregister persistent instance by grpc.
|
||||
*/
|
||||
SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC("supportPersistentInstanceByGrpc",
|
||||
"support persistent instance by grpc", AbilityMode.SERVER),
|
||||
|
||||
/**
|
||||
* For Test temporarily.
|
||||
|
@ -45,6 +45,7 @@ public class ServerAbilities extends AbstractAbilityRegistry {
|
||||
*
|
||||
*/
|
||||
// put ability here, which you want current server supports
|
||||
supportedAbilities.put(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC, true);
|
||||
}
|
||||
|
||||
/**.
|
||||
|
@ -188,18 +188,14 @@ public class ServiceInfo {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Instance> validHosts = new ArrayList<>();
|
||||
boolean existValidHosts = false;
|
||||
for (Instance host : hosts) {
|
||||
if (!host.isHealthy()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < host.getWeight(); i++) {
|
||||
validHosts.add(host);
|
||||
if (host.isHealthy() && host.getWeight() > 0) {
|
||||
existValidHosts = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//No valid hosts, return false.
|
||||
return !validHosts.isEmpty();
|
||||
return existValidHosts;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.api.naming.remote.request;
|
||||
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
|
||||
/**
|
||||
* Nacos persistent instances request.
|
||||
*
|
||||
* @author blake.qiu
|
||||
*/
|
||||
public class PersistentInstanceRequest extends AbstractNamingRequest {
|
||||
|
||||
private String type;
|
||||
|
||||
private Instance instance;
|
||||
|
||||
public PersistentInstanceRequest() {
|
||||
}
|
||||
|
||||
public PersistentInstanceRequest(String namespace, String serviceName, String groupName, String type, Instance instance) {
|
||||
super(namespace, serviceName, groupName);
|
||||
this.type = type;
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Instance getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void setInstance(Instance instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
}
|
@ -138,6 +138,10 @@ public class NamingUtils {
|
||||
* @throws NacosException if check failed, throw exception
|
||||
*/
|
||||
public static void checkInstanceIsLegal(Instance instance) throws NacosException {
|
||||
if (null == instance) {
|
||||
throw new NacosApiException(NacosException.INVALID_PARAM, ErrorCode.INSTANCE_ERROR,
|
||||
"Instance can not be null.");
|
||||
}
|
||||
if (instance.getInstanceHeartBeatTimeOut() < instance.getInstanceHeartBeatInterval()
|
||||
|| instance.getIpDeleteTimeout() < instance.getInstanceHeartBeatInterval()) {
|
||||
throw new NacosApiException(NacosException.INVALID_PARAM, ErrorCode.INSTANCE_ERROR,
|
||||
|
@ -47,6 +47,7 @@ com.alibaba.nacos.api.config.remote.request.cluster.ConfigChangeClusterSyncReque
|
||||
com.alibaba.nacos.api.config.remote.response.cluster.ConfigChangeClusterSyncResponse
|
||||
com.alibaba.nacos.api.naming.remote.request.BatchInstanceRequest
|
||||
com.alibaba.nacos.api.naming.remote.request.InstanceRequest
|
||||
com.alibaba.nacos.api.naming.remote.request.PersistentInstanceRequest
|
||||
com.alibaba.nacos.api.naming.remote.request.NotifySubscriberRequest
|
||||
com.alibaba.nacos.api.naming.remote.request.ServiceListRequest
|
||||
com.alibaba.nacos.api.naming.remote.request.ServiceQueryRequest
|
||||
|
@ -16,15 +16,21 @@
|
||||
|
||||
package com.alibaba.nacos.api.ability.register.impl;
|
||||
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityKey;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ServerAbilitiesTest {
|
||||
|
||||
@Test
|
||||
public void testGetStaticAbilities() {
|
||||
// TODO add the server abilities.
|
||||
assertTrue(ServerAbilities.getStaticAbilities().isEmpty());
|
||||
assertFalse(ServerAbilities.getStaticAbilities().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportPersistentInstanceByGrpcAbilities() {
|
||||
assertTrue(ServerAbilities.getStaticAbilities().get(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC));
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ import com.alibaba.nacos.api.remote.ability.ServerRemoteAbility;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
@ -41,6 +42,7 @@ public class ServerRemoteAbilityTest {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
mapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
|
||||
}
|
||||
|
||||
@Before
|
||||
@ -52,7 +54,8 @@ public class ServerRemoteAbilityTest {
|
||||
public void testSerialize() throws JsonProcessingException {
|
||||
serverAbilities = new ServerRemoteAbility();
|
||||
String json = mapper.writeValueAsString(serverAbilities);
|
||||
assertEquals("{\"supportRemoteConnection\":false,\"grpcReportEnabled\":true}", json);
|
||||
assertTrue(json.contains("\"supportRemoteConnection\":false"));
|
||||
assertTrue(json.contains("\"grpcReportEnabled\":true"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -20,6 +20,7 @@ import com.alibaba.nacos.api.remote.request.Request;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
@ -60,6 +61,7 @@ public abstract class BasedConfigRequestTest {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
mapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
|
||||
}
|
||||
|
||||
public abstract void testSerialize() throws JsonProcessingException;
|
||||
|
@ -35,7 +35,7 @@ public class ConfigBatchListenRequestTest extends BasedConfigRequestTest {
|
||||
String json = mapper.writeValueAsString(configBatchListenRequest);
|
||||
assertTrue(json.contains("\"listen\":" + "true"));
|
||||
assertTrue(json.contains(
|
||||
"\"configListenContexts\":[{\"group\":\"group\",\"md5\":\"test_MD5\",\"dataId\":\"test_data\",\"tenant\":\"test_tenant\"}]"));
|
||||
"\"configListenContexts\":[{\"dataId\":\"test_data\",\"group\":\"group\",\"md5\":\"test_MD5\",\"tenant\":\"test_tenant\"}]"));
|
||||
assertTrue(json.contains("\"module\":\"" + Constants.Config.CONFIG_MODULE));
|
||||
assertTrue(json.contains("\"requestId\":\"" + requestId));
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public class ConfigChangeBatchListenResponseTest extends BasedConfigResponseTest
|
||||
assertTrue(json.contains("\"resultCode\":" + ResponseCode.SUCCESS.getCode()));
|
||||
assertTrue(json.contains("\"errorCode\":0"));
|
||||
assertTrue(json.contains(
|
||||
"\"changedConfigs\":[{\"group\":\"group\",\"dataId\":\"test_data\",\"tenant\":\"test_tenant\"}]"));
|
||||
"\"changedConfigs\":[{\"dataId\":\"test_data\",\"group\":\"group\",\"tenant\":\"test_tenant\"}]"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.api.naming.remote.request;
|
||||
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.remote.NamingRemoteConstants;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class PersistentInstanceRequestTest extends BasedNamingRequestTest {
|
||||
|
||||
@Test
|
||||
public void testSerialize() throws JsonProcessingException {
|
||||
PersistentInstanceRequest request = new PersistentInstanceRequest(NAMESPACE, SERVICE, GROUP,
|
||||
NamingRemoteConstants.REGISTER_INSTANCE, new Instance());
|
||||
String json = mapper.writeValueAsString(request);
|
||||
checkSerializeBasedInfo(json);
|
||||
assertTrue(json.contains("\"type\":\"" + NamingRemoteConstants.REGISTER_INSTANCE + "\""));
|
||||
assertTrue(json.contains("\"instance\":{"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserialize() throws JsonProcessingException {
|
||||
String json = "{\"headers\":{},\"namespace\":\"namespace\",\"serviceName\":\"service\",\"groupName\":\"group\","
|
||||
+ "\"type\":\"deregisterInstance\",\"instance\":{\"port\":0,\"weight\":1.0,\"healthy\":true,"
|
||||
+ "\"enabled\":true,\"ephemeral\":true,\"metadata\":{},\"instanceIdGenerator\":\"simple\","
|
||||
+ "\"instanceHeartBeatInterval\":5000,\"instanceHeartBeatTimeOut\":15000,\"ipDeleteTimeout\":30000},"
|
||||
+ "\"module\":\"naming\"}";
|
||||
PersistentInstanceRequest actual = mapper.readValue(json, PersistentInstanceRequest.class);
|
||||
checkNamingRequestBasedInfo(actual);
|
||||
assertEquals(NamingRemoteConstants.DE_REGISTER_INSTANCE, actual.getType());
|
||||
assertEquals(new Instance(), actual.getInstance());
|
||||
}
|
||||
}
|
@ -231,6 +231,19 @@ public class NamingUtilsTest {
|
||||
Assert.assertEquals(e.getErrCode(), NacosException.INVALID_PARAM);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckInstanceIsNull() throws NacosException {
|
||||
Instance instance = new Instance();
|
||||
instance.setIp("127.0.0.1");
|
||||
instance.setPort(9089);
|
||||
NamingUtils.checkInstanceIsLegal(instance);
|
||||
try {
|
||||
NamingUtils.checkInstanceIsLegal(null);
|
||||
} catch (NacosException e) {
|
||||
Assert.assertEquals(e.getErrCode(), NacosException.INVALID_PARAM);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNumber() {
|
||||
|
@ -21,6 +21,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@ -40,6 +41,7 @@ public class ServerRemoteAbilityTest {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
mapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
|
||||
}
|
||||
|
||||
@Before
|
||||
@ -51,7 +53,8 @@ public class ServerRemoteAbilityTest {
|
||||
public void testSerialize() throws JsonProcessingException {
|
||||
serverAbilities = new ServerRemoteAbility();
|
||||
String json = mapper.writeValueAsString(serverAbilities);
|
||||
assertEquals("{\"supportRemoteConnection\":false,\"grpcReportEnabled\":true}", json);
|
||||
assertTrue(json.contains("\"supportRemoteConnection\":false"));
|
||||
assertTrue(json.contains("\"grpcReportEnabled\":true"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -44,16 +44,20 @@ public class AbilityKeyTest {
|
||||
|
||||
enumMap.put(AbilityKey.SERVER_TEST_1, true);
|
||||
enumMap.put(AbilityKey.SERVER_TEST_2, false);
|
||||
enumMap.put(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC, false);
|
||||
stringBooleanMap = AbilityKey.mapStr(enumMap);
|
||||
assertEquals(2, stringBooleanMap.size());
|
||||
assertEquals(3, stringBooleanMap.size());
|
||||
Assert.assertTrue(stringBooleanMap.get(AbilityKey.SERVER_TEST_1.getName()));
|
||||
Assert.assertFalse(stringBooleanMap.get(AbilityKey.SERVER_TEST_2.getName()));
|
||||
Assert.assertFalse(stringBooleanMap.get(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC.getName()));
|
||||
|
||||
enumMap.put(AbilityKey.SERVER_TEST_2, true);
|
||||
enumMap.put(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC, true);
|
||||
stringBooleanMap = AbilityKey.mapStr(enumMap);
|
||||
assertEquals(2, stringBooleanMap.size());
|
||||
assertEquals(3, stringBooleanMap.size());
|
||||
Assert.assertTrue(stringBooleanMap.get(AbilityKey.SERVER_TEST_1.getName()));
|
||||
Assert.assertTrue(stringBooleanMap.get(AbilityKey.SERVER_TEST_2.getName()));
|
||||
Assert.assertTrue(stringBooleanMap.get(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -71,23 +75,27 @@ public class AbilityKeyTest {
|
||||
|
||||
mapStr.put(AbilityKey.SERVER_TEST_2.getName(), false);
|
||||
mapStr.put(AbilityKey.SERVER_TEST_1.getName(), true);
|
||||
mapStr.put(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC.getName(), true);
|
||||
enumMap = AbilityKey.mapEnum(AbilityMode.SERVER, mapStr);
|
||||
Assert.assertFalse(enumMap.get(AbilityKey.SERVER_TEST_2));
|
||||
Assert.assertTrue(enumMap.get(AbilityKey.SERVER_TEST_1));
|
||||
Assert.assertTrue(enumMap.get(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC));
|
||||
|
||||
mapStr.clear();
|
||||
mapStr.put(AbilityKey.SERVER_TEST_2.getName(), true);
|
||||
mapStr.put(AbilityKey.SERVER_TEST_1.getName(), true);
|
||||
mapStr.put(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC.getName(), true);
|
||||
enumMap = AbilityKey.mapEnum(AbilityMode.SERVER, mapStr);
|
||||
Assert.assertTrue(enumMap.get(AbilityKey.SERVER_TEST_2));
|
||||
Assert.assertTrue(enumMap.get(AbilityKey.SERVER_TEST_1));
|
||||
Assert.assertTrue(enumMap.get(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllValues() {
|
||||
Collection<AbilityKey> actual = AbilityKey.getAllValues(AbilityMode.SERVER);
|
||||
assertEquals(2, actual.size());
|
||||
assertEquals(3, actual.size());
|
||||
actual = AbilityKey.getAllValues(AbilityMode.SDK_CLIENT);
|
||||
assertEquals(1, actual.size());
|
||||
actual = AbilityKey.getAllValues(AbilityMode.CLUSTER_CLIENT);
|
||||
@ -97,7 +105,7 @@ public class AbilityKeyTest {
|
||||
@Test
|
||||
public void testGetAllNames() {
|
||||
Collection<String> actual = AbilityKey.getAllNames(AbilityMode.SERVER);
|
||||
assertEquals(2, actual.size());
|
||||
assertEquals(3, actual.size());
|
||||
actual = AbilityKey.getAllNames(AbilityMode.SDK_CLIENT);
|
||||
assertEquals(1, actual.size());
|
||||
actual = AbilityKey.getAllNames(AbilityMode.CLUSTER_CLIENT);
|
||||
|
@ -111,10 +111,16 @@
|
||||
<artifactId>httpasyncclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.prometheus</groupId>
|
||||
<artifactId>simpleclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
|
@ -22,6 +22,7 @@ import com.alibaba.nacos.api.config.filter.IConfigRequest;
|
||||
import com.alibaba.nacos.api.config.filter.IConfigResponse;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.utils.Pair;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.plugin.encryption.handler.EncryptionHandler;
|
||||
|
||||
import java.util.Objects;
|
||||
@ -54,9 +55,14 @@ public class ConfigEncryptionFilter extends AbstractConfigFilter {
|
||||
Pair<String, String> pair = EncryptionHandler.encryptHandler(dataId, content);
|
||||
String secretKey = pair.getFirst();
|
||||
String encryptContent = pair.getSecond();
|
||||
|
||||
((ConfigRequest) request).setContent(encryptContent);
|
||||
((ConfigRequest) request).setEncryptedDataKey(secretKey);
|
||||
if (!StringUtils.isBlank(encryptContent) && !encryptContent.equals(content)) {
|
||||
((ConfigRequest) request).setContent(encryptContent);
|
||||
}
|
||||
if (!StringUtils.isBlank(secretKey) && !secretKey.equals(((ConfigRequest) request).getEncryptedDataKey())) {
|
||||
((ConfigRequest) request).setEncryptedDataKey(secretKey);
|
||||
} else if (StringUtils.isBlank(((ConfigRequest) request).getEncryptedDataKey()) && StringUtils.isBlank(secretKey)) {
|
||||
((ConfigRequest) request).setEncryptedDataKey("");
|
||||
}
|
||||
}
|
||||
if (Objects.nonNull(response) && response instanceof ConfigResponse && Objects.isNull(request)) {
|
||||
|
||||
@ -68,8 +74,16 @@ public class ConfigEncryptionFilter extends AbstractConfigFilter {
|
||||
String content = configResponse.getContent();
|
||||
|
||||
Pair<String, String> pair = EncryptionHandler.decryptHandler(dataId, encryptedDataKey, content);
|
||||
String secretKey = pair.getFirst();
|
||||
String decryptContent = pair.getSecond();
|
||||
((ConfigResponse) response).setContent(decryptContent);
|
||||
if (!StringUtils.isBlank(decryptContent) && !decryptContent.equals(content)) {
|
||||
((ConfigResponse) response).setContent(decryptContent);
|
||||
}
|
||||
if (!StringUtils.isBlank(secretKey) && !secretKey.equals(((ConfigResponse) response).getEncryptedDataKey())) {
|
||||
((ConfigResponse) response).setEncryptedDataKey(secretKey);
|
||||
} else if (StringUtils.isBlank(((ConfigResponse) response).getEncryptedDataKey()) && StringUtils.isBlank(secretKey)) {
|
||||
((ConfigResponse) response).setEncryptedDataKey("");
|
||||
}
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ public class ConfigFilterChainManager implements IConfigFilterChain {
|
||||
public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException {
|
||||
new VirtualFilterChain(this.filters).doFilter(request, response);
|
||||
}
|
||||
|
||||
|
||||
private static class VirtualFilterChain implements IConfigFilterChain {
|
||||
|
||||
private final List<? extends IConfigFilter> additionalFilters;
|
||||
@ -100,5 +100,5 @@ public class ConfigFilterChainManager implements IConfigFilterChain {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public class CacheData {
|
||||
LOGGER.info("nacos.cache.data.init.snapshot = {} ", initSnapshot);
|
||||
}
|
||||
|
||||
private final String envName;
|
||||
public final String envName;
|
||||
|
||||
private final ConfigFilterChainManager configFilterChainManager;
|
||||
|
||||
@ -124,13 +124,13 @@ public class CacheData {
|
||||
/**
|
||||
* local cache change timestamp.
|
||||
*/
|
||||
private volatile AtomicLong lastModifiedTs = new AtomicLong(0);
|
||||
private final AtomicLong lastModifiedTs = new AtomicLong(0);
|
||||
|
||||
/**
|
||||
* notify change flag,for notify&sync concurrent control. 1.reset to false if starting to sync with server. 2.update
|
||||
* to true if receive config change notification.
|
||||
*/
|
||||
private volatile AtomicBoolean receiveNotifyChanged = new AtomicBoolean(false);
|
||||
private final AtomicBoolean receiveNotifyChanged = new AtomicBoolean(false);
|
||||
|
||||
private int taskId;
|
||||
|
||||
@ -139,7 +139,7 @@ public class CacheData {
|
||||
/**
|
||||
* if is cache data md5 sync with the server.
|
||||
*/
|
||||
private volatile AtomicBoolean isConsistentWithServer = new AtomicBoolean();
|
||||
private final AtomicBoolean isConsistentWithServer = new AtomicBoolean();
|
||||
|
||||
/**
|
||||
* if is cache data is discard,need to remove.
|
||||
|
@ -36,8 +36,6 @@ import com.alibaba.nacos.api.exception.NacosException;
|
||||
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.common.remote.client.Connection;
|
||||
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;
|
||||
import com.alibaba.nacos.client.config.filter.impl.ConfigResponse;
|
||||
@ -55,6 +53,7 @@ import com.alibaba.nacos.common.notify.Event;
|
||||
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||
import com.alibaba.nacos.common.remote.ConnectionType;
|
||||
import com.alibaba.nacos.common.remote.client.Connection;
|
||||
import com.alibaba.nacos.common.remote.client.ConnectionEventListener;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClient;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
|
||||
@ -66,10 +65,12 @@ import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import com.alibaba.nacos.common.utils.VersionUtils;
|
||||
import com.alibaba.nacos.plugin.auth.api.RequestResource;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@ -122,26 +123,26 @@ public class ClientWorker implements Closeable {
|
||||
private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<>(new HashMap<>());
|
||||
|
||||
private final ConfigFilterChainManager configFilterChainManager;
|
||||
|
||||
private String uuid = UUID.randomUUID().toString();
|
||||
|
||||
private final String uuid = UUID.randomUUID().toString();
|
||||
|
||||
private long timeout;
|
||||
|
||||
private ConfigRpcTransportClient agent;
|
||||
private final ConfigRpcTransportClient agent;
|
||||
|
||||
private int taskPenaltyTime;
|
||||
|
||||
private boolean enableRemoteSyncConfig = false;
|
||||
|
||||
|
||||
private static final int MIN_THREAD_NUM = 2;
|
||||
|
||||
|
||||
private static final int THREAD_MULTIPLE = 1;
|
||||
|
||||
|
||||
/**
|
||||
* index(taskId)-> total cache count for this taskId.
|
||||
*/
|
||||
private final List<AtomicInteger> taskIdCacheCountList = new ArrayList<>();
|
||||
|
||||
|
||||
/**
|
||||
* Add listeners for data.
|
||||
*
|
||||
@ -404,11 +405,11 @@ public class ClientWorker implements Closeable {
|
||||
private void increaseTaskIdCount(int taskId) {
|
||||
taskIdCacheCountList.get(taskId).incrementAndGet();
|
||||
}
|
||||
|
||||
|
||||
private void decreaseTaskIdCount(int taskId) {
|
||||
taskIdCacheCountList.get(taskId).decrementAndGet();
|
||||
}
|
||||
|
||||
|
||||
private int calculateTaskId() {
|
||||
int perTaskSize = (int) ParamUtil.getPerTaskConfigSize();
|
||||
for (int index = 0; index < taskIdCacheCountList.size(); index++) {
|
||||
@ -419,7 +420,7 @@ public class ClientWorker implements Closeable {
|
||||
taskIdCacheCountList.add(new AtomicInteger(0));
|
||||
return taskIdCacheCountList.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
public CacheData getCache(String dataId, String group) {
|
||||
return getCache(dataId, group, TenantUtil.getUserTenantForAcm());
|
||||
}
|
||||
@ -567,15 +568,15 @@ public class ClientWorker implements Closeable {
|
||||
public class ConfigRpcTransportClient extends ConfigTransportClient {
|
||||
|
||||
Map<String, ExecutorService> multiTaskExecutor = new HashMap<>();
|
||||
|
||||
|
||||
private final BlockingQueue<Object> listenExecutebell = new ArrayBlockingQueue<>(1);
|
||||
|
||||
private Object bellItem = new Object();
|
||||
|
||||
private final Object bellItem = new Object();
|
||||
|
||||
private long lastAllSyncTime = System.currentTimeMillis();
|
||||
|
||||
Subscriber subscriber = null;
|
||||
|
||||
|
||||
/**
|
||||
* 3 minutes to check all listen cache keys.
|
||||
*/
|
||||
@ -779,37 +780,30 @@ public class ClientWorker implements Closeable {
|
||||
for (CacheData cache : cacheMap.get().values()) {
|
||||
|
||||
synchronized (cache) {
|
||||
|
||||
//check local listeners consistent.
|
||||
|
||||
checkLocalConfig(cache);
|
||||
|
||||
// check local listeners consistent.
|
||||
if (cache.isConsistentWithServer()) {
|
||||
cache.checkListenerMd5();
|
||||
if (!needAllSync) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If local configuration information is used, then skip the processing directly.
|
||||
if (cache.isUseLocalConfigInfo()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cache.isDiscard()) {
|
||||
//get listen config
|
||||
if (!cache.isUseLocalConfigInfo()) {
|
||||
List<CacheData> cacheDatas = listenCachesMap.get(String.valueOf(cache.getTaskId()));
|
||||
if (cacheDatas == null) {
|
||||
cacheDatas = new LinkedList<>();
|
||||
listenCachesMap.put(String.valueOf(cache.getTaskId()), cacheDatas);
|
||||
}
|
||||
cacheDatas.add(cache);
|
||||
|
||||
}
|
||||
} else if (cache.isDiscard() && CollectionUtils.isEmpty(cache.getListeners())) {
|
||||
|
||||
if (!cache.isUseLocalConfigInfo()) {
|
||||
List<CacheData> cacheDatas = removeListenCachesMap.get(String.valueOf(cache.getTaskId()));
|
||||
if (cacheDatas == null) {
|
||||
cacheDatas = new LinkedList<>();
|
||||
removeListenCachesMap.put(String.valueOf(cache.getTaskId()), cacheDatas);
|
||||
}
|
||||
cacheDatas.add(cache);
|
||||
|
||||
}
|
||||
List<CacheData> cacheDatas = listenCachesMap.computeIfAbsent(String.valueOf(cache.getTaskId()),
|
||||
k -> new LinkedList<>());
|
||||
cacheDatas.add(cache);
|
||||
} else {
|
||||
List<CacheData> cacheDatas = removeListenCachesMap.computeIfAbsent(
|
||||
String.valueOf(cache.getTaskId()), k -> new LinkedList<>());
|
||||
cacheDatas.add(cache);
|
||||
}
|
||||
}
|
||||
|
||||
@ -820,7 +814,7 @@ public class ClientWorker implements Closeable {
|
||||
|
||||
//execute check remove listen.
|
||||
checkRemoveListenCache(removeListenCachesMap);
|
||||
|
||||
|
||||
if (needAllSync) {
|
||||
lastAllSyncTime = now;
|
||||
}
|
||||
@ -828,9 +822,59 @@ public class ClientWorker implements Closeable {
|
||||
if (hasChangedKeys) {
|
||||
notifyListenConfig();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks and handles local configuration for a given CacheData object. This method evaluates the use of
|
||||
* failover files for local configuration storage and updates the CacheData accordingly.
|
||||
*
|
||||
* @param cacheData The CacheData object to be processed.
|
||||
*/
|
||||
public void checkLocalConfig(CacheData cacheData) {
|
||||
final String dataId = cacheData.dataId;
|
||||
final String group = cacheData.group;
|
||||
final String tenant = cacheData.tenant;
|
||||
final String envName = cacheData.envName;
|
||||
|
||||
// Check if a failover file exists for the specified dataId, group, and tenant.
|
||||
File file = LocalConfigInfoProcessor.getFailoverFile(envName, dataId, group, tenant);
|
||||
|
||||
// If not using local config info and a failover file exists, load and use it.
|
||||
if (!cacheData.isUseLocalConfigInfo() && file.exists()) {
|
||||
String content = LocalConfigInfoProcessor.getFailover(envName, dataId, group, tenant);
|
||||
final String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
|
||||
cacheData.setUseLocalConfigInfo(true);
|
||||
cacheData.setLocalConfigInfoVersion(file.lastModified());
|
||||
cacheData.setContent(content);
|
||||
LOGGER.warn(
|
||||
"[{}] [failover-change] failover file created. dataId={}, group={}, tenant={}, md5={}, content={}",
|
||||
envName, dataId, group, tenant, md5, ContentUtils.truncateContent(content));
|
||||
return;
|
||||
}
|
||||
|
||||
// If use local config info, but the failover file is deleted, switch back to server config.
|
||||
if (cacheData.isUseLocalConfigInfo() && !file.exists()) {
|
||||
cacheData.setUseLocalConfigInfo(false);
|
||||
LOGGER.warn("[{}] [failover-change] failover file deleted. dataId={}, group={}, tenant={}", envName,
|
||||
dataId, group, tenant);
|
||||
return;
|
||||
}
|
||||
|
||||
// When the failover file content changes, indicating a change in local configuration.
|
||||
if (cacheData.isUseLocalConfigInfo() && file.exists()
|
||||
&& cacheData.getLocalConfigInfoVersion() != file.lastModified()) {
|
||||
String content = LocalConfigInfoProcessor.getFailover(envName, dataId, group, tenant);
|
||||
final String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
|
||||
cacheData.setUseLocalConfigInfo(true);
|
||||
cacheData.setLocalConfigInfoVersion(file.lastModified());
|
||||
cacheData.setContent(content);
|
||||
LOGGER.warn(
|
||||
"[{}] [failover-change] failover file changed. dataId={}, group={}, tenant={}, md5={}, content={}",
|
||||
envName, dataId, group, tenant, md5, ContentUtils.truncateContent(content));
|
||||
}
|
||||
}
|
||||
|
||||
private ExecutorService ensureSyncExecutor(String taskId) {
|
||||
if (!multiTaskExecutor.containsKey(taskId)) {
|
||||
multiTaskExecutor.put(taskId,
|
||||
@ -842,14 +886,14 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
return multiTaskExecutor.get(taskId);
|
||||
}
|
||||
|
||||
|
||||
private void checkRemoveListenCache(Map<String, List<CacheData>> removeListenCachesMap) {
|
||||
if (!removeListenCachesMap.isEmpty()) {
|
||||
List<Future> listenFutures = new ArrayList<>();
|
||||
|
||||
|
||||
for (Map.Entry<String, List<CacheData>> entry : removeListenCachesMap.entrySet()) {
|
||||
String taskId = entry.getKey();
|
||||
|
||||
|
||||
ExecutorService executorService = ensureSyncExecutor(taskId);
|
||||
Future future = executorService.submit(() -> {
|
||||
List<CacheData> removeListenCaches = entry.getValue();
|
||||
@ -868,7 +912,7 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Async remove listen config change error ", e);
|
||||
try {
|
||||
@ -880,7 +924,7 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
});
|
||||
listenFutures.add(future);
|
||||
|
||||
|
||||
}
|
||||
for (Future future : listenFutures) {
|
||||
try {
|
||||
@ -891,9 +935,9 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean checkListenCache(Map<String, List<CacheData>> listenCachesMap) {
|
||||
|
||||
|
||||
final AtomicBoolean hasChangedKeys = new AtomicBoolean(false);
|
||||
if (!listenCachesMap.isEmpty()) {
|
||||
List<Future> listenFutures = new ArrayList<>();
|
||||
@ -913,9 +957,9 @@ public class ClientWorker implements Closeable {
|
||||
ConfigChangeBatchListenResponse listenResponse = (ConfigChangeBatchListenResponse) requestProxy(
|
||||
rpcClient, configChangeListenRequest);
|
||||
if (listenResponse != null && listenResponse.isSuccess()) {
|
||||
|
||||
|
||||
Set<String> changeKeys = new HashSet<String>();
|
||||
|
||||
|
||||
List<ConfigChangeBatchListenResponse.ConfigContext> changedConfigs = listenResponse.getChangedConfigs();
|
||||
//handle changed keys,notify listener
|
||||
if (!CollectionUtils.isEmpty(changedConfigs)) {
|
||||
@ -927,9 +971,9 @@ public class ClientWorker implements Closeable {
|
||||
boolean isInitializing = cacheMap.get().get(changeKey).isInitializing();
|
||||
refreshContentAndCheck(changeKey, !isInitializing);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (CacheData cacheData : listenCaches) {
|
||||
if (cacheData.getReceiveNotifyChanged().get()) {
|
||||
String changeKey = GroupKey.getKeyTenant(cacheData.dataId, cacheData.group,
|
||||
@ -940,7 +984,7 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//handler content configs
|
||||
for (CacheData cacheData : listenCaches) {
|
||||
cacheData.setInitializing(false);
|
||||
@ -954,7 +998,7 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Execute listen config change error ", e);
|
||||
@ -967,7 +1011,7 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
});
|
||||
listenFutures.add(future);
|
||||
|
||||
|
||||
}
|
||||
for (Future future : listenFutures) {
|
||||
try {
|
||||
@ -976,7 +1020,7 @@ public class ClientWorker implements Closeable {
|
||||
LOGGER.error("Async listen config change error ", throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return hasChangedKeys.get();
|
||||
}
|
||||
@ -999,7 +1043,7 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* build config string.
|
||||
*
|
||||
@ -1170,7 +1214,7 @@ public class ClientWorker implements Closeable {
|
||||
ConfigRemoveResponse response = (ConfigRemoveResponse) requestProxy(getOneRunningClient(), request);
|
||||
return response.isSuccess();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check server is health.
|
||||
*
|
||||
@ -1180,7 +1224,7 @@ public class ClientWorker implements Closeable {
|
||||
try {
|
||||
return getOneRunningClient().isRunning();
|
||||
} catch (NacosException e) {
|
||||
LOGGER.warn("check server status failed. error={}", e);
|
||||
LOGGER.warn("check server status failed.", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ public class ConfigHttpClientManager implements Closeable {
|
||||
public void shutdown() throws NacosException {
|
||||
NAMING_LOGGER.warn("[ConfigHttpClientManager] Start destroying NacosRestTemplate");
|
||||
try {
|
||||
HttpClientBeanHolder.shutdownNacostSyncRest(HTTP_CLIENT_FACTORY.getClass().getName());
|
||||
HttpClientBeanHolder.shutdownNacosSyncRest(HTTP_CLIENT_FACTORY.getClass().getName());
|
||||
} catch (Exception ex) {
|
||||
NAMING_LOGGER.error("[ConfigHttpClientManager] An exception occurred when the HTTP client was closed : {}",
|
||||
ExceptionUtil.getStackTrace(ex));
|
||||
|
@ -25,16 +25,16 @@ import com.alibaba.nacos.client.logging.AbstractNacosLogging;
|
||||
import com.alibaba.nacos.common.log.NacosLogbackConfigurator;
|
||||
import com.alibaba.nacos.common.spi.NacosServiceLoader;
|
||||
import com.alibaba.nacos.common.utils.ResourceUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Support for Logback version 1.0.8 or higher
|
||||
*
|
||||
* @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
|
||||
* @author <a href="mailto:hujun3@xiaomi.com">hujun</a>
|
||||
*
|
||||
* @since 0.9.0
|
||||
*/
|
||||
public class LogbackNacosLogging extends AbstractNacosLogging {
|
||||
@ -61,7 +61,7 @@ public class LogbackNacosLogging extends AbstractNacosLogging {
|
||||
addListener(loggerContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean hasListener(LoggerContext loggerContext) {
|
||||
for (LoggerContextListener loggerContextListener : loggerContext.getCopyOfListenerList()) {
|
||||
if (loggerContextListener instanceof NacosLoggerContextListener) {
|
||||
@ -70,50 +70,55 @@ public class LogbackNacosLogging extends AbstractNacosLogging {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private LoggerContext loadConfigurationOnStart() {
|
||||
String location = getLocation(NACOS_LOGBACK_LOCATION);
|
||||
try {
|
||||
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||
Collection<NacosLogbackConfigurator> nacosLogbackConfigurators = NacosServiceLoader.load(
|
||||
NacosLogbackConfigurator.class);
|
||||
NacosLogbackConfigurator nacosLogbackConfigurator = nacosLogbackConfigurators.stream()
|
||||
.filter(c -> c.getVersion() == userVersion).collect(Collectors.toList()).get(0);
|
||||
nacosLogbackConfigurator.setContext(loggerContext);
|
||||
nacosLogbackConfigurator.configure(ResourceUtils.getResourceUrl(location));
|
||||
return loggerContext;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Could not initialize Logback Nacos logging from " + location, e);
|
||||
}
|
||||
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||
Collection<NacosLogbackConfigurator> nacosLogbackConfigurators = NacosServiceLoader.load(
|
||||
NacosLogbackConfigurator.class);
|
||||
nacosLogbackConfigurators.stream().filter(c -> c.getVersion() == userVersion).findFirst()
|
||||
.ifPresent(nacosLogbackConfigurator -> {
|
||||
nacosLogbackConfigurator.setContext(loggerContext);
|
||||
if (StringUtils.isNotBlank(location)) {
|
||||
try {
|
||||
nacosLogbackConfigurator.configure(ResourceUtils.getResourceUrl(location));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize Logback Nacos logging from " + location, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
return loggerContext;
|
||||
}
|
||||
|
||||
|
||||
class NacosLoggerContextListener implements LoggerContextListener {
|
||||
|
||||
@Override
|
||||
public boolean isResetResistant() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onReset(LoggerContext context) {
|
||||
loadConfigurationOnStart();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStart(LoggerContext context) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStop(LoggerContext context) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLevelChange(Logger logger, Level level) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addListener(LoggerContext loggerContext) {
|
||||
loggerContext.addListener(new NacosLoggerContextListener());
|
||||
}
|
||||
|
@ -142,6 +142,7 @@ public class NacosNamingService implements NamingService {
|
||||
@Override
|
||||
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
NamingUtils.checkInstanceIsLegal(instance);
|
||||
checkAndStripGroupNamePrefix(instance, groupName);
|
||||
clientProxy.registerService(serviceName, groupName, instance);
|
||||
}
|
||||
|
||||
@ -149,6 +150,7 @@ public class NacosNamingService implements NamingService {
|
||||
public void batchRegisterInstance(String serviceName, String groupName, List<Instance> instances)
|
||||
throws NacosException {
|
||||
NamingUtils.batchCheckInstanceIsLegal(instances);
|
||||
batchCheckAndStripGroupNamePrefix(instances, groupName);
|
||||
clientProxy.batchRegisterService(serviceName, groupName, instances);
|
||||
}
|
||||
|
||||
@ -156,6 +158,7 @@ public class NacosNamingService implements NamingService {
|
||||
public void batchDeregisterInstance(String serviceName, String groupName, List<Instance> instances)
|
||||
throws NacosException {
|
||||
NamingUtils.batchCheckInstanceIsLegal(instances);
|
||||
batchCheckAndStripGroupNamePrefix(instances, groupName);
|
||||
clientProxy.batchDeregisterService(serviceName, groupName, instances);
|
||||
}
|
||||
|
||||
@ -191,6 +194,8 @@ public class NacosNamingService implements NamingService {
|
||||
|
||||
@Override
|
||||
public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
NamingUtils.checkInstanceIsLegal(instance);
|
||||
checkAndStripGroupNamePrefix(instance, groupName);
|
||||
clientProxy.deregisterService(serviceName, groupName, instance);
|
||||
}
|
||||
|
||||
@ -470,4 +475,22 @@ public class NacosNamingService implements NamingService {
|
||||
NotifyCenter.deregisterSubscriber(changeNotifier);
|
||||
|
||||
}
|
||||
|
||||
private void batchCheckAndStripGroupNamePrefix(List<Instance> instances, String groupName) throws NacosException {
|
||||
for (Instance instance : instances) {
|
||||
checkAndStripGroupNamePrefix(instance, groupName);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAndStripGroupNamePrefix(Instance instance, String groupName) throws NacosException {
|
||||
String serviceName = instance.getServiceName();
|
||||
if (serviceName != null) {
|
||||
String groupNameOfInstance = NamingUtils.getGroupName(serviceName);
|
||||
if (!groupName.equals(groupNameOfInstance)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, String.format(
|
||||
"wrong group name prefix of instance service name! it should be: %s, Instance: %s", groupName, instance));
|
||||
}
|
||||
instance.setServiceName(NamingUtils.getServiceName(serviceName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.client.naming.remote;
|
||||
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityKey;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.ListView;
|
||||
@ -194,7 +195,10 @@ public class NamingClientProxyDelegate implements NamingClientProxy {
|
||||
}
|
||||
|
||||
private NamingClientProxy getExecuteClientProxy(Instance instance) {
|
||||
return instance.isEphemeral() ? grpcClientProxy : httpClientProxy;
|
||||
if (instance.isEphemeral() || grpcClientProxy.isAbilitySupportedByServer(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC)) {
|
||||
return grpcClientProxy;
|
||||
}
|
||||
return httpClientProxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.client.naming.remote.gprc;
|
||||
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityKey;
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityStatus;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.CommonParams;
|
||||
@ -27,6 +29,7 @@ import com.alibaba.nacos.api.naming.remote.NamingRemoteConstants;
|
||||
import com.alibaba.nacos.api.naming.remote.request.AbstractNamingRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.request.BatchInstanceRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.request.InstanceRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.request.PersistentInstanceRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.request.ServiceListRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.request.ServiceQueryRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.request.SubscribeServiceRequest;
|
||||
@ -62,6 +65,7 @@ import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -128,6 +132,14 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
|
||||
public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance {}", namespaceId, serviceName,
|
||||
instance);
|
||||
if (instance.isEphemeral()) {
|
||||
registerServiceForEphemeral(serviceName, groupName, instance);
|
||||
} else {
|
||||
doRegisterServiceForPersistent(serviceName, groupName, instance);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerServiceForEphemeral(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
redoService.cacheInstanceForRedo(serviceName, groupName, instance);
|
||||
doRegisterService(serviceName, groupName, instance);
|
||||
}
|
||||
@ -153,43 +165,60 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param groupName group name
|
||||
* @param instances instance list
|
||||
* @return instance list that need to be deregistered.
|
||||
* @param deRegisterInstances deregister instance list
|
||||
* @return instance list that need to be retained.
|
||||
*/
|
||||
private List<Instance> getRetainInstance(String serviceName, String groupName, List<Instance> instances)
|
||||
private List<Instance> getRetainInstance(String serviceName, String groupName, List<Instance> deRegisterInstances)
|
||||
throws NacosException {
|
||||
if (CollectionUtils.isEmpty(instances)) {
|
||||
if (CollectionUtils.isEmpty(deRegisterInstances)) {
|
||||
throw new NacosException(NacosException.INVALID_PARAM,
|
||||
String.format("[Batch deRegistration] need deRegister instance is empty, instances: %s,",
|
||||
instances));
|
||||
deRegisterInstances));
|
||||
}
|
||||
String combinedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
|
||||
InstanceRedoData instanceRedoData = redoService.getRegisteredInstancesByKey(combinedServiceName);
|
||||
if (!(instanceRedoData instanceof BatchInstanceRedoData)) {
|
||||
throw new NacosException(NacosException.INVALID_PARAM, String.format(
|
||||
"[Batch deRegistration] batch deRegister is not BatchInstanceRedoData type , instances: %s,",
|
||||
instances));
|
||||
deRegisterInstances));
|
||||
}
|
||||
|
||||
BatchInstanceRedoData batchInstanceRedoData = (BatchInstanceRedoData) instanceRedoData;
|
||||
List<Instance> allInstance = batchInstanceRedoData.getInstances();
|
||||
if (CollectionUtils.isEmpty(allInstance)) {
|
||||
List<Instance> allRedoInstances = batchInstanceRedoData.getInstances();
|
||||
if (CollectionUtils.isEmpty(allRedoInstances)) {
|
||||
throw new NacosException(NacosException.INVALID_PARAM, String.format(
|
||||
"[Batch deRegistration] not found all registerInstance , serviceName:%s , groupName: %s",
|
||||
serviceName, groupName));
|
||||
}
|
||||
|
||||
Map<Instance, Instance> instanceMap = instances.stream()
|
||||
Map<Instance, Instance> deRegisterInstanceMap = deRegisterInstances.stream()
|
||||
.collect(Collectors.toMap(Function.identity(), Function.identity()));
|
||||
List<Instance> retainInstances = new ArrayList<>();
|
||||
for (Instance instance : allInstance) {
|
||||
if (!instanceMap.containsKey(instance)) {
|
||||
retainInstances.add(instance);
|
||||
for (Instance redoInstance : allRedoInstances) {
|
||||
boolean needRetained = true;
|
||||
Iterator<Map.Entry<Instance, Instance>> it = deRegisterInstanceMap.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Instance deRegisterInstance = it.next().getKey();
|
||||
// only compare Ip & Port because redoInstance's instanceId or serviceName might be null but deRegisterInstance's might not be null.
|
||||
if (compareIpAndPort(deRegisterInstance, redoInstance)) {
|
||||
needRetained = false;
|
||||
// clear current entry to speed up next redoInstance comparing.
|
||||
it.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (needRetained) {
|
||||
retainInstances.add(redoInstance);
|
||||
}
|
||||
}
|
||||
return retainInstances;
|
||||
}
|
||||
|
||||
private boolean compareIpAndPort(Instance deRegisterInstance, Instance redoInstance) {
|
||||
return ((deRegisterInstance.getIp().equals(redoInstance.getIp()))
|
||||
&& (deRegisterInstance.getPort() == redoInstance.getPort()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute batch register operation.
|
||||
*
|
||||
@ -221,10 +250,32 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
|
||||
redoService.instanceRegistered(serviceName, groupName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute register operation for persistent instance.
|
||||
*
|
||||
* @param serviceName name of service
|
||||
* @param groupName group of service
|
||||
* @param instance instance to register
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public void doRegisterServiceForPersistent(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
PersistentInstanceRequest request = new PersistentInstanceRequest(namespaceId, serviceName, groupName,
|
||||
NamingRemoteConstants.REGISTER_INSTANCE, instance);
|
||||
requestToServer(request, Response.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregisterService(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
NAMING_LOGGER.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}", namespaceId,
|
||||
serviceName, instance);
|
||||
if (instance.isEphemeral()) {
|
||||
deregisterServiceForEphemeral(serviceName, groupName, instance);
|
||||
} else {
|
||||
doDeregisterServiceForPersistent(serviceName, groupName, instance);
|
||||
}
|
||||
}
|
||||
|
||||
private void deregisterServiceForEphemeral(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
String key = NamingUtils.getGroupedName(serviceName, groupName);
|
||||
InstanceRedoData instanceRedoData = redoService.getRegisteredInstancesByKey(key);
|
||||
if (instanceRedoData instanceof BatchInstanceRedoData) {
|
||||
@ -253,6 +304,20 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
|
||||
requestToServer(request, Response.class);
|
||||
redoService.instanceDeregistered(serviceName, groupName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute deregister operation for persistent instance.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param groupName group name
|
||||
* @param instance instance
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public void doDeregisterServiceForPersistent(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
PersistentInstanceRequest request = new PersistentInstanceRequest(namespaceId, serviceName, groupName,
|
||||
NamingRemoteConstants.DE_REGISTER_INSTANCE, instance);
|
||||
requestToServer(request, Response.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateInstance(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
@ -366,6 +431,16 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
|
||||
return rpcClient.isRunning();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether nacos-server supports the capability.
|
||||
*
|
||||
* @param abilityKey ability key
|
||||
* @return true if supported, otherwise false
|
||||
*/
|
||||
public boolean isAbilitySupportedByServer(AbilityKey abilityKey) {
|
||||
return rpcClient.getConnectionAbility(abilityKey) == AbilityStatus.SUPPORTED;
|
||||
}
|
||||
|
||||
private <T extends Response> T requestToServer(AbstractNamingRequest request, Class<T> responseClass)
|
||||
throws NacosException {
|
||||
Response response = null;
|
||||
|
@ -73,7 +73,7 @@ public class NamingHttpClientManager implements Closeable {
|
||||
public void shutdown() throws NacosException {
|
||||
NAMING_LOGGER.warn("[NamingHttpClientManager] Start destroying NacosRestTemplate");
|
||||
try {
|
||||
HttpClientBeanHolder.shutdownNacostSyncRest(HTTP_CLIENT_FACTORY.getClass().getName());
|
||||
HttpClientBeanHolder.shutdownNacosSyncRest(HTTP_CLIENT_FACTORY.getClass().getName());
|
||||
} catch (Exception ex) {
|
||||
NAMING_LOGGER.error("[NamingHttpClientManager] An exception occurred when the HTTP client was closed : {}",
|
||||
ExceptionUtil.getStackTrace(ex));
|
||||
|
@ -268,7 +268,6 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
|
||||
|
||||
@Override
|
||||
public boolean serverHealthy() {
|
||||
|
||||
try {
|
||||
String result = reqApi(UtilAndComs.nacosUrlBase + "/operator/metrics", new HashMap<>(8), HttpMethod.GET);
|
||||
JsonNode json = JacksonUtils.toObj(result);
|
||||
|
@ -61,14 +61,14 @@ public class ConfigEncryptionFilterTest {
|
||||
public void testDoFilter() throws NacosException {
|
||||
configEncryptionFilter.doFilter(configRequest, null, iConfigFilterChain);
|
||||
|
||||
Mockito.verify(configRequest).getDataId();
|
||||
Mockito.verify(configRequest).getContent();
|
||||
Mockito.verify(configRequest, Mockito.atLeast(1)).getDataId();
|
||||
Mockito.verify(configRequest, Mockito.atLeast(1)).getContent();
|
||||
|
||||
configEncryptionFilter.doFilter(null, configResponse, iConfigFilterChain);
|
||||
|
||||
Mockito.verify(configResponse).getDataId();
|
||||
Mockito.verify(configResponse).getContent();
|
||||
Mockito.verify(configResponse).getEncryptedDataKey();
|
||||
Mockito.verify(configResponse, Mockito.atLeast(1)).getDataId();
|
||||
Mockito.verify(configResponse, Mockito.atLeast(1)).getContent();
|
||||
Mockito.verify(configResponse, Mockito.atLeast(1)).getEncryptedDataKey();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -18,9 +18,12 @@
|
||||
|
||||
package com.alibaba.nacos.client.logging.logback;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.slf4j.ILoggerFactory;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.isA;
|
||||
|
||||
@ -31,9 +34,12 @@ public class LogbackNacosLoggingTest {
|
||||
|
||||
@Test
|
||||
public void testLoadConfiguration() {
|
||||
exceptionRule.expectCause(isA(ClassCastException.class));
|
||||
exceptionRule.expectMessage("Could not initialize Logback Nacos logging from classpath:nacos-logback.xml");
|
||||
LogbackNacosLogging logbackNacosLogging = new LogbackNacosLogging();
|
||||
logbackNacosLogging.loadConfiguration();
|
||||
ILoggerFactory loggerFactory;
|
||||
if ((loggerFactory = LoggerFactory.getILoggerFactory()) != null && loggerFactory instanceof LoggerContext) {
|
||||
exceptionRule.expectCause(isA(ClassCastException.class));
|
||||
exceptionRule.expectMessage("Could not initialize Logback Nacos logging from classpath:nacos-logback.xml");
|
||||
LogbackNacosLogging logbackNacosLogging = new LogbackNacosLogging();
|
||||
logbackNacosLogging.loadConfiguration();
|
||||
}
|
||||
}
|
||||
}
|
@ -120,6 +120,46 @@ public class NacosNamingServiceTest {
|
||||
argThat(instances -> CollectionUtils.isEqualCollection(instanceList, instances)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBatchRegisterInstanceWithGroupNamePrefix() throws NacosException {
|
||||
Instance instance = new Instance();
|
||||
String serviceName = "service1";
|
||||
String ip = "1.1.1.1";
|
||||
int port = 10000;
|
||||
instance.setServiceName(Constants.DEFAULT_GROUP + "@@" + serviceName);
|
||||
instance.setEphemeral(true);
|
||||
instance.setPort(port);
|
||||
instance.setIp(ip);
|
||||
List<Instance> instanceList = new ArrayList<>();
|
||||
instanceList.add(instance);
|
||||
//when
|
||||
client.batchRegisterInstance(serviceName, Constants.DEFAULT_GROUP, instanceList);
|
||||
//then
|
||||
verify(proxy, times(1)).batchRegisterService(eq(serviceName), eq(Constants.DEFAULT_GROUP),
|
||||
argThat(instances -> CollectionUtils.isEqualCollection(instanceList, instances)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBatchRegisterInstanceWithWrongGroupNamePrefix() throws NacosException {
|
||||
Instance instance = new Instance();
|
||||
String serviceName = "service1";
|
||||
String ip = "1.1.1.1";
|
||||
int port = 10000;
|
||||
instance.setServiceName("WrongGroup" + "@@" + serviceName);
|
||||
instance.setEphemeral(true);
|
||||
instance.setPort(port);
|
||||
instance.setIp(ip);
|
||||
List<Instance> instanceList = new ArrayList<>();
|
||||
instanceList.add(instance);
|
||||
//when
|
||||
try {
|
||||
client.batchRegisterInstance(serviceName, Constants.DEFAULT_GROUP, instanceList);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e instanceof NacosException);
|
||||
Assert.assertTrue(e.getMessage().contains("wrong group name prefix of instance service name"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBatchDeRegisterInstance() throws NacosException {
|
||||
Instance instance = new Instance();
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package com.alibaba.nacos.client.naming.remote;
|
||||
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityKey;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.Service;
|
||||
@ -46,7 +47,7 @@ import static org.mockito.Mockito.when;
|
||||
public class NamingClientProxyDelegateTest {
|
||||
|
||||
@Test
|
||||
public void testRegisterServiceByGrpc() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
public void testRegisterEphemeralServiceByGrpc() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
String ns = "ns1";
|
||||
ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class);
|
||||
Properties props = new Properties();
|
||||
@ -100,7 +101,36 @@ public class NamingClientProxyDelegateTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterServiceByHttp() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
public void testRegisterPersistentServiceByGrpc() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
String ns = "ns1";
|
||||
ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class);
|
||||
Properties props = new Properties();
|
||||
props.setProperty("serverAddr", "localhost");
|
||||
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
|
||||
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
|
||||
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
|
||||
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);
|
||||
Field grpcClientProxyField = NamingClientProxyDelegate.class.getDeclaredField("grpcClientProxy");
|
||||
grpcClientProxyField.setAccessible(true);
|
||||
grpcClientProxyField.set(delegate, mockGrpcClient);
|
||||
|
||||
String serviceName = "service1";
|
||||
String groupName = "group1";
|
||||
Instance instance = new Instance();
|
||||
instance.setServiceName(serviceName);
|
||||
instance.setClusterName(groupName);
|
||||
instance.setIp("1.1.1.1");
|
||||
instance.setPort(1);
|
||||
// persistent instance
|
||||
instance.setEphemeral(false);
|
||||
// when server support register persistent instance by grpc, will use grpc to register
|
||||
when(mockGrpcClient.isAbilitySupportedByServer(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC)).thenReturn(true);
|
||||
delegate.registerService(serviceName, groupName, instance);
|
||||
verify(mockGrpcClient, times(1)).registerService(serviceName, groupName, instance);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterPersistentServiceByHttp() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
String ns = "ns1";
|
||||
ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class);
|
||||
Properties props = new Properties();
|
||||
@ -121,14 +151,15 @@ public class NamingClientProxyDelegateTest {
|
||||
instance.setClusterName(groupName);
|
||||
instance.setIp("1.1.1.1");
|
||||
instance.setPort(1);
|
||||
// use grpc
|
||||
// persistent instance
|
||||
instance.setEphemeral(false);
|
||||
// when server do not support register persistent instance by grpc, will use http to register
|
||||
delegate.registerService(serviceName, groupName, instance);
|
||||
verify(mockHttpClient, times(1)).registerService(serviceName, groupName, instance);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeregisterServiceGrpc() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
public void testDeregisterEphemeralServiceGrpc() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
String ns = "ns1";
|
||||
ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class);
|
||||
Properties props = new Properties();
|
||||
@ -156,13 +187,43 @@ public class NamingClientProxyDelegateTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeregisterServiceHttp() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
public void testDeregisterPersistentServiceGrpc() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
String ns = "ns1";
|
||||
ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class);
|
||||
Properties props = new Properties();
|
||||
props.setProperty("serverAddr", "localhost");
|
||||
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
|
||||
|
||||
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
|
||||
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
|
||||
NamingGrpcClientProxy mockGrpcClient = Mockito.mock(NamingGrpcClientProxy.class);
|
||||
Field grpcClientProxyField = NamingClientProxyDelegate.class.getDeclaredField("grpcClientProxy");
|
||||
grpcClientProxyField.setAccessible(true);
|
||||
grpcClientProxyField.set(delegate, mockGrpcClient);
|
||||
|
||||
String serviceName = "service1";
|
||||
String groupName = "group1";
|
||||
Instance instance = new Instance();
|
||||
instance.setServiceName(serviceName);
|
||||
instance.setClusterName(groupName);
|
||||
instance.setIp("1.1.1.1");
|
||||
instance.setPort(1);
|
||||
// persistent instance
|
||||
instance.setEphemeral(false);
|
||||
// when server support deregister persistent instance by grpc, will use grpc to deregister
|
||||
when(mockGrpcClient.isAbilitySupportedByServer(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC)).thenReturn(true);
|
||||
delegate.deregisterService(serviceName, groupName, instance);
|
||||
verify(mockGrpcClient, times(1)).deregisterService(serviceName, groupName, instance);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeregisterPersistentServiceHttp() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
String ns = "ns1";
|
||||
ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class);
|
||||
Properties props = new Properties();
|
||||
props.setProperty("serverAddr", "localhost");
|
||||
InstancesChangeNotifier notifier = new InstancesChangeNotifier();
|
||||
|
||||
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(props);
|
||||
NamingClientProxyDelegate delegate = new NamingClientProxyDelegate(ns, holder, nacosClientProperties, notifier);
|
||||
NamingHttpClientProxy mockHttpClient = Mockito.mock(NamingHttpClientProxy.class);
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
package com.alibaba.nacos.client.naming.remote.gprc;
|
||||
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityKey;
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityStatus;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
@ -27,6 +29,7 @@ import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.api.naming.remote.NamingRemoteConstants;
|
||||
import com.alibaba.nacos.api.naming.remote.request.BatchInstanceRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.request.InstanceRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.request.PersistentInstanceRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.request.SubscribeServiceRequest;
|
||||
import com.alibaba.nacos.api.naming.remote.response.BatchInstanceResponse;
|
||||
import com.alibaba.nacos.api.naming.remote.response.InstanceResponse;
|
||||
@ -123,6 +126,8 @@ public class NamingGrpcClientProxyTest {
|
||||
|
||||
private Instance instance;
|
||||
|
||||
private Instance persistentInstance;
|
||||
|
||||
private String uuid;
|
||||
|
||||
@Rule
|
||||
@ -143,7 +148,7 @@ public class NamingGrpcClientProxyTest {
|
||||
Field uuidField = NamingGrpcClientProxy.class.getDeclaredField("uuid");
|
||||
uuidField.setAccessible(true);
|
||||
uuid = (String) uuidField.get(client);
|
||||
|
||||
|
||||
Assert.assertNotNull(RpcClientFactory.getClient(uuid));
|
||||
Field rpcClientField = NamingGrpcClientProxy.class.getDeclaredField("rpcClient");
|
||||
rpcClientField.setAccessible(true);
|
||||
@ -156,6 +161,12 @@ public class NamingGrpcClientProxyTest {
|
||||
instance.setServiceName(SERVICE_NAME);
|
||||
instance.setIp("1.1.1.1");
|
||||
instance.setPort(1111);
|
||||
|
||||
persistentInstance = new Instance();
|
||||
persistentInstance.setServiceName(SERVICE_NAME);
|
||||
persistentInstance.setIp("1.1.1.1");
|
||||
persistentInstance.setPort(1111);
|
||||
persistentInstance.setEphemeral(false);
|
||||
}
|
||||
|
||||
@After
|
||||
@ -177,6 +188,18 @@ public class NamingGrpcClientProxyTest {
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterPersistentService() throws NacosException {
|
||||
client.registerService(SERVICE_NAME, GROUP_NAME, persistentInstance);
|
||||
verify(this.rpcClient, times(1)).request(argThat(request -> {
|
||||
if (request instanceof PersistentInstanceRequest) {
|
||||
PersistentInstanceRequest request1 = (PersistentInstanceRequest) request;
|
||||
return request1.getType().equals(NamingRemoteConstants.REGISTER_INSTANCE);
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterServiceThrowsNacosException() throws NacosException {
|
||||
expectedException.expect(NacosException.class);
|
||||
@ -220,6 +243,18 @@ public class NamingGrpcClientProxyTest {
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeregisterPersistentService() throws NacosException {
|
||||
client.deregisterService(SERVICE_NAME, GROUP_NAME, persistentInstance);
|
||||
verify(this.rpcClient, times(1)).request(argThat(request -> {
|
||||
if (request instanceof PersistentInstanceRequest) {
|
||||
PersistentInstanceRequest request1 = (PersistentInstanceRequest) request;
|
||||
return request1.getType().equals(NamingRemoteConstants.DE_REGISTER_INSTANCE);
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeregisterServiceForBatchRegistered() throws NacosException {
|
||||
@ -327,6 +362,36 @@ public class NamingGrpcClientProxyTest {
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBatchDeregisterServiceWithOtherPortInstance() throws NacosException {
|
||||
try {
|
||||
List<Instance> instanceList = new ArrayList<>();
|
||||
instance.setHealthy(true);
|
||||
instanceList.add(instance);
|
||||
instanceList.add(new Instance());
|
||||
client.batchRegisterService(SERVICE_NAME, GROUP_NAME, instanceList);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
response = new BatchInstanceResponse();
|
||||
when(this.rpcClient.request(any())).thenReturn(response);
|
||||
Instance otherPortInstance = new Instance();
|
||||
otherPortInstance.setServiceName(SERVICE_NAME);
|
||||
otherPortInstance.setIp("1.1.1.1");
|
||||
otherPortInstance.setPort(2222);
|
||||
List<Instance> instanceList = new ArrayList<>();
|
||||
instanceList.add(otherPortInstance);
|
||||
client.batchDeregisterService(SERVICE_NAME, GROUP_NAME, instanceList);
|
||||
verify(this.rpcClient, times(2)).request(argThat(request -> {
|
||||
if (request instanceof BatchInstanceRequest) {
|
||||
BatchInstanceRequest request1 = (BatchInstanceRequest) request;
|
||||
request1.setRequestId("1");
|
||||
return request1.getInstances().size() == 2 && request1.getType()
|
||||
.equals(NamingRemoteConstants.BATCH_REGISTER_INSTANCE);
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateInstance() throws Exception {
|
||||
//TODO thrown.expect(UnsupportedOperationException.class);
|
||||
@ -431,6 +496,42 @@ public class NamingGrpcClientProxyTest {
|
||||
Assert.assertTrue(client.serverHealthy());
|
||||
verify(this.rpcClient, times(1)).isRunning();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAbilitySupportedByServer1() {
|
||||
when(this.rpcClient.getConnectionAbility(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC))
|
||||
.thenReturn(AbilityStatus.SUPPORTED);
|
||||
Assert.assertTrue(client.isAbilitySupportedByServer(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC));
|
||||
verify(this.rpcClient, times(1))
|
||||
.getConnectionAbility(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAbilitySupportedByServer2() {
|
||||
when(this.rpcClient.getConnectionAbility(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC))
|
||||
.thenReturn(AbilityStatus.NOT_SUPPORTED);
|
||||
Assert.assertFalse(client.isAbilitySupportedByServer(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC));
|
||||
verify(this.rpcClient, times(1))
|
||||
.getConnectionAbility(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAbilitySupportedByServer3() {
|
||||
when(this.rpcClient.getConnectionAbility(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC))
|
||||
.thenReturn(AbilityStatus.UNKNOWN);
|
||||
Assert.assertFalse(client.isAbilitySupportedByServer(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC));
|
||||
verify(this.rpcClient, times(1))
|
||||
.getConnectionAbility(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAbilitySupportedByServer4() {
|
||||
when(this.rpcClient.getConnectionAbility(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC))
|
||||
.thenReturn(null);
|
||||
Assert.assertFalse(client.isAbilitySupportedByServer(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC));
|
||||
verify(this.rpcClient, times(1))
|
||||
.getConnectionAbility(AbilityKey.SERVER_SUPPORT_PERSISTENT_INSTANCE_BY_GRPC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShutdown() throws Exception {
|
||||
|
@ -61,6 +61,18 @@
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
|
@ -196,9 +196,6 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory {
|
||||
|
||||
@SuppressWarnings("checkstyle:abbreviationaswordinname")
|
||||
protected synchronized SSLContext loadSSLContext() {
|
||||
if (!TlsSystemConfig.tlsEnable) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return TlsHelper.buildSslContext(true);
|
||||
} catch (NoSuchAlgorithmException | KeyManagementException e) {
|
||||
|
@ -118,7 +118,7 @@ public final class HttpClientBeanHolder {
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public static void shutdown(String className) throws Exception {
|
||||
shutdownNacostSyncRest(className);
|
||||
shutdownNacosSyncRest(className);
|
||||
shutdownNacosAsyncRest(className);
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ public final class HttpClientBeanHolder {
|
||||
* @param className HttpClientFactory implement class name
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public static void shutdownNacostSyncRest(String className) throws Exception {
|
||||
public static void shutdownNacosSyncRest(String className) throws Exception {
|
||||
final NacosRestTemplate nacosRestTemplate = SINGLETON_REST.get(className);
|
||||
if (nacosRestTemplate != null) {
|
||||
nacosRestTemplate.close();
|
||||
|
@ -66,9 +66,6 @@ public class JdkHttpClientResponse implements HttpClientResponse {
|
||||
// Used to process http content_encoding, when content_encoding is GZIP, use GZIPInputStream
|
||||
if (CONTENT_ENCODING.equals(contentEncoding)) {
|
||||
byte[] bytes = IoUtils.tryDecompress(this.responseStream);
|
||||
if (bytes == null) {
|
||||
throw new IOException("decompress http response error");
|
||||
}
|
||||
return new ByteArrayInputStream(bytes);
|
||||
}
|
||||
return this.responseStream;
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.handler;
|
||||
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Response handler.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public final class ResponseHandler {
|
||||
|
||||
public static <T> T convert(String s, Class<T> cls) throws Exception {
|
||||
return JacksonUtils.toObj(s, cls);
|
||||
}
|
||||
|
||||
public static <T> T convert(String s, Type type) throws Exception {
|
||||
return JacksonUtils.toObj(s, type);
|
||||
}
|
||||
|
||||
public static <T> T convert(InputStream inputStream, Type type) throws Exception {
|
||||
return JacksonUtils.toObj(inputStream, type);
|
||||
}
|
||||
}
|
@ -42,24 +42,21 @@ public class Header {
|
||||
|
||||
private static final String DEFAULT_CHARSET = "UTF-8";
|
||||
|
||||
private static final String DEFAULT_ENCODING = "gzip";
|
||||
|
||||
private Header() {
|
||||
header = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
originalResponseHeader = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_JSON);
|
||||
addParam(HttpHeaderConsts.ACCEPT_CHARSET, DEFAULT_CHARSET);
|
||||
//addParam(HttpHeaderConsts.ACCEPT_ENCODING, DEFAULT_ENCODING);
|
||||
}
|
||||
|
||||
public static Header newInstance() {
|
||||
return new Header();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the key and value to the header.
|
||||
*
|
||||
* @param key the key
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @return header
|
||||
*/
|
||||
@ -77,10 +74,6 @@ public class Header {
|
||||
return addParam(HttpHeaderConsts.CONTENT_TYPE, contentType);
|
||||
}
|
||||
|
||||
public Header build() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getValue(String key) {
|
||||
return header.get(key);
|
||||
}
|
||||
@ -146,7 +139,7 @@ public class Header {
|
||||
*
|
||||
* <p>Currently only corresponds to the response header of JDK.
|
||||
*
|
||||
* @param key original response header key
|
||||
* @param key original response header key
|
||||
* @param values original response header values
|
||||
*/
|
||||
public void addOriginalResponseHeader(String key, List<String> values) {
|
||||
@ -179,7 +172,7 @@ public class Header {
|
||||
private String analysisCharset(String contentType) {
|
||||
String[] values = contentType.split(";");
|
||||
String charset = Constants.ENCODE;
|
||||
if (values.length == 0) {
|
||||
if (values.length == 1) {
|
||||
return charset;
|
||||
}
|
||||
for (String value : values) {
|
||||
|
@ -21,7 +21,6 @@ import com.alibaba.nacos.common.utils.MapUtil;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@ -80,20 +79,6 @@ public class Query {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add query parameters from KV list. KV list: odd index is key, even index is value.
|
||||
*
|
||||
* @param list KV list
|
||||
*/
|
||||
public void initParams(List<String> list) {
|
||||
if ((list.size() & 1) != 0) {
|
||||
throw new IllegalArgumentException("list size must be a multiple of 2");
|
||||
}
|
||||
for (int i = 0; i < list.size(); ) {
|
||||
addParam(list.get(i++), list.get(i++));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print query as a http url param string. Like K=V&K=V.
|
||||
*
|
||||
@ -122,8 +107,8 @@ public class Query {
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
isEmpty = false;
|
||||
params.clear();
|
||||
isEmpty = true;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.packagescan.util.PathMatcher;
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.utils.AbstractObjectUtils;
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractObjectUtils;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
import com.alibaba.nacos.common.utils.ClassUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.packagescan.util.ResourceUtils;
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
import com.alibaba.nacos.common.utils.ClassUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -18,7 +18,7 @@ package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.packagescan.util.PathMatcher;
|
||||
import com.alibaba.nacos.common.packagescan.util.ResourceUtils;
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
import com.alibaba.nacos.common.utils.ClassUtils;
|
||||
import com.alibaba.nacos.common.utils.ReflectUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.packagescan.util.ResourceUtils;
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.common.packagescan.resource;
|
||||
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.AbstractAssert;
|
||||
import com.alibaba.nacos.common.packagescan.util.NestedIoException;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@ -14,7 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.utils;
|
||||
package com.alibaba.nacos.common.packagescan.util;
|
||||
|
||||
import com.alibaba.nacos.common.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.utils;
|
||||
package com.alibaba.nacos.common.packagescan.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
@ -17,7 +17,6 @@
|
||||
package com.alibaba.nacos.common.packagescan.util;
|
||||
|
||||
import com.alibaba.nacos.common.packagescan.resource.Resource;
|
||||
import com.alibaba.nacos.common.utils.AbstractAssert;
|
||||
import com.alibaba.nacos.common.utils.ClassUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
|
@ -29,9 +29,9 @@ public enum ConnectionType {
|
||||
*/
|
||||
GRPC("GRPC", "Grpc Connection");
|
||||
|
||||
String type;
|
||||
final String type;
|
||||
|
||||
String name;
|
||||
final String name;
|
||||
|
||||
public static ConnectionType getByType(String type) {
|
||||
ConnectionType[] values = ConnectionType.values();
|
||||
@ -57,15 +57,6 @@ public enum ConnectionType {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter method for property <tt>type</tt>.
|
||||
*
|
||||
* @param type value to be assigned to property type
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter method for property <tt>name</tt>.
|
||||
*
|
||||
@ -74,13 +65,4 @@ public enum ConnectionType {
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter method for property <tt>name</tt>.
|
||||
*
|
||||
* @param name value to be assigned to property name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
@ -83,7 +82,7 @@ public abstract class RpcClient implements Closeable {
|
||||
private final BlockingQueue<ReconnectContext> reconnectionSignal = new ArrayBlockingQueue<>(1);
|
||||
|
||||
protected volatile Connection currentConnection;
|
||||
|
||||
|
||||
private String tenant;
|
||||
|
||||
private long lastActiveTimeStamp = System.currentTimeMillis();
|
||||
@ -101,9 +100,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();
|
||||
}
|
||||
@ -117,7 +116,7 @@ public abstract class RpcClient implements Closeable {
|
||||
this.serverListFactory = serverListFactory;
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
protected void init() {
|
||||
if (this.serverListFactory != null) {
|
||||
rpcClientStatus.compareAndSet(RpcClientStatus.WAIT_INIT, RpcClientStatus.INITIALIZED);
|
||||
@ -126,10 +125,6 @@ public abstract class RpcClient implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> labels() {
|
||||
return Collections.unmodifiableMap(rpcClientConfig.labels());
|
||||
}
|
||||
|
||||
/**
|
||||
* init server list factory. only can init once.
|
||||
*
|
||||
@ -170,7 +165,7 @@ public abstract class RpcClient implements Closeable {
|
||||
/**
|
||||
* Notify when client new connected.
|
||||
*
|
||||
* @param connection connection has connected
|
||||
* @param connection connection has connected
|
||||
*/
|
||||
protected void notifyConnected(Connection connection) {
|
||||
if (connectionEventListeners.isEmpty()) {
|
||||
@ -277,8 +272,8 @@ public abstract class RpcClient implements Closeable {
|
||||
if (isShutdown()) {
|
||||
break;
|
||||
}
|
||||
ReconnectContext reconnectContext = reconnectionSignal.poll(rpcClientConfig.connectionKeepAlive(),
|
||||
TimeUnit.MILLISECONDS);
|
||||
ReconnectContext reconnectContext = reconnectionSignal
|
||||
.poll(rpcClientConfig.connectionKeepAlive(), TimeUnit.MILLISECONDS);
|
||||
if (reconnectContext == null) {
|
||||
// check alive time.
|
||||
if (System.currentTimeMillis() - lastActiveTimeStamp >= rpcClientConfig.connectionKeepAlive()) {
|
||||
@ -296,8 +291,8 @@ public abstract class RpcClient implements Closeable {
|
||||
break;
|
||||
}
|
||||
|
||||
boolean statusFLowSuccess = RpcClient.this.rpcClientStatus.compareAndSet(
|
||||
rpcClientStatus, RpcClientStatus.UNHEALTHY);
|
||||
boolean statusFLowSuccess = RpcClient.this.rpcClientStatus
|
||||
.compareAndSet(rpcClientStatus, RpcClientStatus.UNHEALTHY);
|
||||
if (statusFLowSuccess) {
|
||||
reconnectContext = new ReconnectContext(null, false);
|
||||
} else {
|
||||
@ -364,9 +359,10 @@ public abstract class RpcClient implements Closeable {
|
||||
}
|
||||
|
||||
if (connectToServer != null) {
|
||||
LoggerUtils.printIfInfoEnabled(LOGGER,
|
||||
"[{}] Success to connect to server [{}] on start up, connectionId = {}", rpcClientConfig.name(),
|
||||
connectToServer.serverInfo.getAddress(), connectToServer.getConnectionId());
|
||||
LoggerUtils
|
||||
.printIfInfoEnabled(LOGGER, "[{}] Success to connect to server [{}] on start up, connectionId = {}",
|
||||
rpcClientConfig.name(), connectToServer.serverInfo.getAddress(),
|
||||
connectToServer.getConnectionId());
|
||||
this.currentConnection = connectToServer;
|
||||
rpcClientStatus.set(RpcClientStatus.RUNNING);
|
||||
eventLinkedBlockingQueue.offer(new ConnectionEvent(ConnectionEvent.CONNECTED, currentConnection));
|
||||
@ -400,8 +396,8 @@ public abstract class RpcClient implements Closeable {
|
||||
ConnectResetRequest connectResetRequest = (ConnectResetRequest) request;
|
||||
if (StringUtils.isNotBlank(connectResetRequest.getServerIp())) {
|
||||
ServerInfo serverInfo = resolveServerInfo(
|
||||
connectResetRequest.getServerIp() + Constants.COLON
|
||||
+ connectResetRequest.getServerPort());
|
||||
connectResetRequest.getServerIp() + Constants.COLON + connectResetRequest
|
||||
.getServerPort());
|
||||
switchServerAsync(serverInfo, false);
|
||||
} else {
|
||||
switchServerAsync();
|
||||
@ -418,15 +414,15 @@ public abstract class RpcClient implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**.
|
||||
* invoke after receiving reset request
|
||||
/**
|
||||
* . invoke after receiving reset request
|
||||
*
|
||||
* @param request request for resetting
|
||||
*/
|
||||
protected void afterReset(ConnectResetRequest request) {
|
||||
// hook for GrpcClient
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
LOGGER.info("Shutdown rpc client, set status to shutdown");
|
||||
@ -451,8 +447,8 @@ public abstract class RpcClient implements Closeable {
|
||||
if (reTryTimes > 1) {
|
||||
Thread.sleep(random.nextInt(500));
|
||||
}
|
||||
Response response = this.currentConnection.request(healthCheckRequest,
|
||||
rpcClientConfig.healthCheckTimeOut());
|
||||
Response response = this.currentConnection
|
||||
.request(healthCheckRequest, rpcClientConfig.healthCheckTimeOut());
|
||||
// not only check server is ok, also check connection is register.
|
||||
return response != null && response.isSuccess();
|
||||
} catch (Exception e) {
|
||||
@ -508,9 +504,10 @@ public abstract class RpcClient implements Closeable {
|
||||
// 2.create a new channel to new server
|
||||
Connection connectionNew = connectToServer(serverInfo);
|
||||
if (connectionNew != null) {
|
||||
LoggerUtils.printIfInfoEnabled(LOGGER,
|
||||
"[{}] Success to connect a server [{}], connectionId = {}", rpcClientConfig.name(),
|
||||
serverInfo.getAddress(), connectionNew.getConnectionId());
|
||||
LoggerUtils
|
||||
.printIfInfoEnabled(LOGGER, "[{}] Success to connect a server [{}], connectionId = {}",
|
||||
rpcClientConfig.name(), serverInfo.getAddress(),
|
||||
connectionNew.getConnectionId());
|
||||
// successfully create a new connect.
|
||||
if (currentConnection != null) {
|
||||
LoggerUtils.printIfInfoEnabled(LOGGER,
|
||||
@ -579,8 +576,9 @@ public abstract class RpcClient implements Closeable {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LoggerUtils.printIfWarnEnabled(LOGGER, "[{}] Fail to reconnect to server, error is {}",
|
||||
rpcClientConfig.name(), e);
|
||||
LoggerUtils
|
||||
.printIfWarnEnabled(LOGGER, "[{}] Fail to reconnect to server, error is {}", rpcClientConfig.name(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -713,8 +711,8 @@ public abstract class RpcClient implements Closeable {
|
||||
int retryTimes = 0;
|
||||
Throwable exceptionToThrow = null;
|
||||
long start = System.currentTimeMillis();
|
||||
while (retryTimes <= rpcClientConfig.retryTimes()
|
||||
&& System.currentTimeMillis() < start + callback.getTimeout()) {
|
||||
while (retryTimes <= rpcClientConfig.retryTimes() && System.currentTimeMillis() < start + callback
|
||||
.getTimeout()) {
|
||||
boolean waitReconnect = false;
|
||||
try {
|
||||
if (this.currentConnection == null || !isRunning()) {
|
||||
@ -763,8 +761,8 @@ public abstract class RpcClient implements Closeable {
|
||||
int retryTimes = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
Exception exceptionToThrow = null;
|
||||
while (retryTimes <= rpcClientConfig.retryTimes()
|
||||
&& System.currentTimeMillis() < start + rpcClientConfig.timeOutMills()) {
|
||||
while (retryTimes <= rpcClientConfig.retryTimes() && System.currentTimeMillis() < start + rpcClientConfig
|
||||
.timeOutMills()) {
|
||||
boolean waitReconnect = false;
|
||||
try {
|
||||
if (this.currentConnection == null || !isRunning()) {
|
||||
@ -979,7 +977,7 @@ public abstract class RpcClient implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public class ConnectionEvent {
|
||||
public static class ConnectionEvent {
|
||||
|
||||
public static final int CONNECTED = 1;
|
||||
|
||||
@ -988,7 +986,7 @@ public abstract class RpcClient implements Closeable {
|
||||
int eventType;
|
||||
|
||||
Connection connection;
|
||||
|
||||
|
||||
public ConnectionEvent(int eventType, Connection connection) {
|
||||
this.eventType = eventType;
|
||||
this.connection = connection;
|
||||
@ -1012,7 +1010,7 @@ public abstract class RpcClient implements Closeable {
|
||||
return rpcClientConfig.labels();
|
||||
}
|
||||
|
||||
class ReconnectContext {
|
||||
static class ReconnectContext {
|
||||
|
||||
public ReconnectContext(ServerInfo serverInfo, boolean onRequestFail) {
|
||||
this.onRequestFail = onRequestFail;
|
||||
@ -1031,7 +1029,7 @@ public abstract class RpcClient implements Closeable {
|
||||
public void setTenant(String tenant) {
|
||||
this.tenant = tenant;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return ability of current connection.
|
||||
*
|
||||
|
@ -74,19 +74,18 @@ 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) {
|
||||
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) {
|
||||
|
||||
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.
|
||||
*
|
||||
@ -98,21 +97,15 @@ public class RpcClientFactory {
|
||||
* @return rpc client.
|
||||
*/
|
||||
public static RpcClient createClient(String clientName, ConnectionType connectionType, Integer threadPoolCoreSize,
|
||||
Integer threadPoolMaxSize, Map<String, String> labels, RpcClientTlsConfig tlsConfig) {
|
||||
|
||||
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 -> {
|
||||
LOGGER.info("[RpcClientFactory] create a new rpc client of " + clientName);
|
||||
try {
|
||||
return new GrpcSdkClient(clientNameInner, threadPoolCoreSize, threadPoolMaxSize, labels, tlsConfig);
|
||||
} catch (Throwable throwable) {
|
||||
LOGGER.error("Error to init GrpcSdkClient for client name :" + clientName, throwable);
|
||||
throw throwable;
|
||||
}
|
||||
|
||||
return new GrpcSdkClient(clientNameInner, threadPoolCoreSize, threadPoolMaxSize, labels, tlsConfig);
|
||||
});
|
||||
}
|
||||
|
||||
@ -124,15 +117,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) {
|
||||
Map<String, String> labels, RpcClientTlsConfig tlsConfig) {
|
||||
return createClusterClient(clientName, connectionType, null, null, labels, tlsConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create a rpc client.
|
||||
*
|
||||
@ -143,29 +136,31 @@ 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 clientName client name.
|
||||
* @param connectionType connectionType.
|
||||
* @param threadPoolCoreSize coreSize.
|
||||
* @param threadPoolMaxSize threadPoolSize.
|
||||
* @param labels tables.
|
||||
* @param tlsConfig tlsConfig.
|
||||
* @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) {
|
||||
|
||||
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, tlsConfig));
|
||||
clientNameInner -> new GrpcClusterClient(clientNameInner, threadPoolCoreSize, threadPoolMaxSize, labels,
|
||||
tlsConfig));
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,9 @@ 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.annotation.Target;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@ -33,64 +32,64 @@ import java.util.Set;
|
||||
* @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";
|
||||
|
||||
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)) {
|
||||
if (declaredField.getType().equals(String.class) && null != declaredField
|
||||
.getAnnotation(RpcConfigLabel.class)) {
|
||||
try {
|
||||
CONFIG_NAMES.add((String) declaredField.get(null));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Set<String> getRpcParams() {
|
||||
return Collections.unmodifiableSet(CONFIG_NAMES);
|
||||
}
|
||||
|
@ -251,59 +251,59 @@ public class DefaultGrpcClientConfig implements GrpcClientConfig {
|
||||
* @return Builder
|
||||
*/
|
||||
public Builder fromProperties(Properties properties) {
|
||||
if (properties.contains(GrpcConstants.GRPC_NAME)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_NAME)) {
|
||||
this.name = properties.getProperty(GrpcConstants.GRPC_NAME);
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_RETRY_TIMES)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_RETRY_TIMES)) {
|
||||
this.retryTimes = Integer.parseInt(properties.getProperty(GrpcConstants.GRPC_RETRY_TIMES));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_TIMEOUT_MILLS)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_TIMEOUT_MILLS)) {
|
||||
this.timeOutMills = Long.parseLong(properties.getProperty(GrpcConstants.GRPC_TIMEOUT_MILLS));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_CONNECT_KEEP_ALIVE_TIME)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_CONNECT_KEEP_ALIVE_TIME)) {
|
||||
this.connectionKeepAlive = Long
|
||||
.parseLong(properties.getProperty(GrpcConstants.GRPC_CONNECT_KEEP_ALIVE_TIME));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_THREADPOOL_KEEPALIVETIME)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_THREADPOOL_KEEPALIVETIME)) {
|
||||
this.threadPoolKeepAlive = Long
|
||||
.parseLong(properties.getProperty(GrpcConstants.GRPC_THREADPOOL_KEEPALIVETIME));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_THREADPOOL_CORE_SIZE)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_THREADPOOL_CORE_SIZE)) {
|
||||
this.threadPoolCoreSize = Integer
|
||||
.parseInt(properties.getProperty(GrpcConstants.GRPC_THREADPOOL_CORE_SIZE));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_THREADPOOL_MAX_SIZE)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_THREADPOOL_MAX_SIZE)) {
|
||||
this.threadPoolMaxSize = Integer
|
||||
.parseInt(properties.getProperty(GrpcConstants.GRPC_THREADPOOL_MAX_SIZE));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_SERVER_CHECK_TIMEOUT)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_SERVER_CHECK_TIMEOUT)) {
|
||||
this.serverCheckTimeOut = Long
|
||||
.parseLong(properties.getProperty(GrpcConstants.GRPC_SERVER_CHECK_TIMEOUT));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_QUEUESIZE)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_QUEUESIZE)) {
|
||||
this.threadPoolQueueSize = Integer.parseInt(properties.getProperty(GrpcConstants.GRPC_QUEUESIZE));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_MAX_INBOUND_MESSAGE_SIZE)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_MAX_INBOUND_MESSAGE_SIZE)) {
|
||||
this.maxInboundMessageSize = Integer
|
||||
.parseInt(properties.getProperty(GrpcConstants.GRPC_MAX_INBOUND_MESSAGE_SIZE));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_CHANNEL_KEEP_ALIVE_TIME)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_CHANNEL_KEEP_ALIVE_TIME)) {
|
||||
this.channelKeepAlive = Integer
|
||||
.parseInt(properties.getProperty(GrpcConstants.GRPC_CHANNEL_KEEP_ALIVE_TIME));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_CHANNEL_CAPABILITY_NEGOTIATION_TIMEOUT)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_CHANNEL_CAPABILITY_NEGOTIATION_TIMEOUT)) {
|
||||
this.capabilityNegotiationTimeout = Integer
|
||||
.parseInt(properties.getProperty(GrpcConstants.GRPC_CHANNEL_CAPABILITY_NEGOTIATION_TIMEOUT));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_HEALTHCHECK_RETRY_TIMES)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_HEALTHCHECK_RETRY_TIMES)) {
|
||||
this.healthCheckRetryTimes = Integer
|
||||
.parseInt(properties.getProperty(GrpcConstants.GRPC_HEALTHCHECK_RETRY_TIMES));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_HEALTHCHECK_TIMEOUT)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_HEALTHCHECK_TIMEOUT)) {
|
||||
this.healthCheckTimeOut = Long
|
||||
.parseLong(properties.getProperty(GrpcConstants.GRPC_HEALTHCHECK_TIMEOUT));
|
||||
}
|
||||
if (properties.contains(GrpcConstants.GRPC_CHANNEL_KEEP_ALIVE_TIMEOUT)) {
|
||||
if (properties.containsKey(GrpcConstants.GRPC_CHANNEL_KEEP_ALIVE_TIMEOUT)) {
|
||||
this.channelKeepAliveTimeout = Integer
|
||||
.parseInt(properties.getProperty(GrpcConstants.GRPC_CHANNEL_KEEP_ALIVE_TIMEOUT));
|
||||
}
|
||||
@ -414,8 +414,9 @@ public class DefaultGrpcClientConfig implements GrpcClientConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setCapabilityNegotiationTimeout(long capabilityNegotiationTimeout) {
|
||||
public Builder setCapabilityNegotiationTimeout(long capabilityNegotiationTimeout) {
|
||||
this.capabilityNegotiationTimeout = capabilityNegotiationTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,18 +33,18 @@ import com.alibaba.nacos.api.remote.response.SetupAckResponse;
|
||||
import com.alibaba.nacos.common.ability.discover.NacosAbilityManagerHolder;
|
||||
import com.alibaba.nacos.common.packagescan.resource.Resource;
|
||||
import com.alibaba.nacos.common.remote.ConnectionType;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClientStatus;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClient;
|
||||
import com.alibaba.nacos.common.remote.client.ServerListFactory;
|
||||
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.RpcClientTlsConfig;
|
||||
import com.alibaba.nacos.common.remote.client.ServerListFactory;
|
||||
import com.alibaba.nacos.common.remote.client.ServerRequestHandler;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.LoggerUtils;
|
||||
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.alibaba.nacos.common.utils.TlsTypeResolve;
|
||||
import com.alibaba.nacos.common.utils.VersionUtils;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import io.grpc.CompressorRegistry;
|
||||
import io.grpc.DecompressorRegistry;
|
||||
@ -60,10 +60,10 @@ import io.grpc.stub.StreamObserver;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
@ -89,12 +89,12 @@ public abstract class GrpcClient extends RpcClient {
|
||||
* Block to wait setup success response.
|
||||
*/
|
||||
private final RecAbilityContext recAbilityContext = new RecAbilityContext(null);
|
||||
|
||||
|
||||
/**
|
||||
* for receiving server abilities.
|
||||
*/
|
||||
private SetupRequestHandler setupRequestHandler;
|
||||
|
||||
|
||||
@Override
|
||||
public ConnectionType getConnectionType() {
|
||||
return ConnectionType.GRPC;
|
||||
@ -108,7 +108,7 @@ public abstract class GrpcClient extends RpcClient {
|
||||
public GrpcClient(String name) {
|
||||
this(DefaultGrpcClientConfig.newBuilder().setName(name).build());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* constructor.
|
||||
*
|
||||
@ -140,7 +140,7 @@ public abstract class GrpcClient extends RpcClient {
|
||||
this.clientConfig = clientConfig;
|
||||
initSetupHandler();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* setup handler.
|
||||
*/
|
||||
@ -188,17 +188,17 @@ public abstract class GrpcClient extends RpcClient {
|
||||
grpcExecutor.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a stub using a channel.
|
||||
*
|
||||
* @param managedChannelTemp channel.
|
||||
* @return if server check success,return a non-null stub.
|
||||
*/
|
||||
private RequestGrpc.RequestFutureStub createNewChannelStub(ManagedChannel managedChannelTemp) {
|
||||
protected RequestGrpc.RequestFutureStub createNewChannelStub(ManagedChannel managedChannelTemp) {
|
||||
return RequestGrpc.newFutureStub(managedChannelTemp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create a new channel with specific server address.
|
||||
*
|
||||
@ -209,15 +209,15 @@ public abstract class GrpcClient extends RpcClient {
|
||||
private ManagedChannel createNewManagedChannel(String serverIp, int 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())
|
||||
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);
|
||||
return managedChannelBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* shutdown a channel.
|
||||
*
|
||||
@ -237,9 +237,6 @@ public abstract class GrpcClient extends RpcClient {
|
||||
*/
|
||||
private Response serverCheck(String ip, int port, RequestGrpc.RequestFutureStub requestBlockingStub) {
|
||||
try {
|
||||
if (requestBlockingStub == null) {
|
||||
return null;
|
||||
}
|
||||
ServerCheckRequest serverCheckRequest = new ServerCheckRequest();
|
||||
Payload grpcRequest = GrpcUtils.convert(serverCheckRequest);
|
||||
ListenableFuture<Payload> responseFuture = requestBlockingStub.request(grpcRequest);
|
||||
@ -291,8 +288,8 @@ public abstract class GrpcClient extends RpcClient {
|
||||
} catch (Exception e) {
|
||||
LoggerUtils.printIfErrorEnabled(LOGGER, "[{}]Handle server request exception: {}",
|
||||
grpcConn.getConnectionId(), payload.toString(), e.getMessage());
|
||||
Response errResponse = ErrorResponse.build(NacosException.CLIENT_ERROR,
|
||||
"Handle server request error");
|
||||
Response errResponse = ErrorResponse
|
||||
.build(NacosException.CLIENT_ERROR, "Handle server request error");
|
||||
errResponse.setRequestId(request.getRequestId());
|
||||
sendResponse(errResponse);
|
||||
}
|
||||
@ -366,7 +363,7 @@ public abstract class GrpcClient extends RpcClient {
|
||||
int port = serverInfo.getServerPort() + rpcPortOffset();
|
||||
ManagedChannel managedChannel = createNewManagedChannel(serverInfo.getServerIp(), port);
|
||||
RequestGrpc.RequestFutureStub newChannelStubTemp = createNewChannelStub(managedChannel);
|
||||
|
||||
|
||||
Response response = serverCheck(serverInfo.getServerIp(), port, newChannelStubTemp);
|
||||
if (!(response instanceof ServerCheckResponse)) {
|
||||
shuntDownChannel(managedChannel);
|
||||
@ -376,9 +373,9 @@ public abstract class GrpcClient extends RpcClient {
|
||||
// ability table will be null if server doesn't support ability table
|
||||
ServerCheckResponse serverCheckResponse = (ServerCheckResponse) response;
|
||||
connectionId = serverCheckResponse.getConnectionId();
|
||||
|
||||
BiRequestStreamGrpc.BiRequestStreamStub biRequestStreamStub = BiRequestStreamGrpc.newStub(
|
||||
newChannelStubTemp.getChannel());
|
||||
|
||||
BiRequestStreamGrpc.BiRequestStreamStub biRequestStreamStub = BiRequestStreamGrpc
|
||||
.newStub(newChannelStubTemp.getChannel());
|
||||
GrpcConnection grpcConn = new GrpcConnection(serverInfo, grpcExecutor);
|
||||
grpcConn.setConnectionId(connectionId);
|
||||
// if not supported, it will be false
|
||||
@ -388,10 +385,10 @@ public abstract class GrpcClient extends RpcClient {
|
||||
// promise null if no abilities receive
|
||||
grpcConn.setAbilityTable(null);
|
||||
}
|
||||
|
||||
|
||||
//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);
|
||||
@ -401,8 +398,8 @@ public abstract class GrpcClient extends RpcClient {
|
||||
conSetupRequest.setClientVersion(VersionUtils.getFullClientVersion());
|
||||
conSetupRequest.setLabels(super.getLabels());
|
||||
// set ability table
|
||||
conSetupRequest.setAbilityTable(
|
||||
NacosAbilityManagerHolder.getInstance().getCurrentNodeAbilities(abilityMode()));
|
||||
conSetupRequest
|
||||
.setAbilityTable(NacosAbilityManagerHolder.getInstance().getCurrentNodeAbilities(abilityMode()));
|
||||
conSetupRequest.setTenant(super.getTenant());
|
||||
grpcConn.sendRequest(conSetupRequest);
|
||||
// wait for response
|
||||
@ -427,14 +424,14 @@ public abstract class GrpcClient extends RpcClient {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ability mode: sdk client or cluster client.
|
||||
*
|
||||
* @return mode
|
||||
*/
|
||||
protected abstract AbilityMode abilityMode();
|
||||
|
||||
|
||||
@Override
|
||||
protected void afterReset(ConnectResetRequest request) {
|
||||
recAbilityContext.release(null);
|
||||
@ -454,14 +451,14 @@ public abstract class GrpcClient extends RpcClient {
|
||||
* way to block client.
|
||||
*/
|
||||
private volatile CountDownLatch blocker;
|
||||
|
||||
|
||||
private volatile boolean needToSync = false;
|
||||
|
||||
|
||||
public RecAbilityContext(Connection connection) {
|
||||
this.connection = connection;
|
||||
this.blocker = new CountDownLatch(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* whether to sync for ability table.
|
||||
*
|
||||
@ -470,7 +467,7 @@ public abstract class GrpcClient extends RpcClient {
|
||||
public boolean isNeedToSync() {
|
||||
return this.needToSync;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* reset with new connection which is waiting for ability table.
|
||||
*
|
||||
@ -481,7 +478,7 @@ public abstract class GrpcClient extends RpcClient {
|
||||
this.blocker = new CountDownLatch(1);
|
||||
this.needToSync = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* notify sync by abilities.
|
||||
*
|
||||
@ -503,7 +500,7 @@ public abstract class GrpcClient extends RpcClient {
|
||||
* await for abilities.
|
||||
*
|
||||
* @param timeout timeout.
|
||||
* @param unit unit.
|
||||
* @param unit unit.
|
||||
* @throws InterruptedException by blocker.
|
||||
*/
|
||||
public void await(long timeout, TimeUnit unit) throws InterruptedException {
|
||||
@ -512,16 +509,17 @@ public abstract class GrpcClient extends RpcClient {
|
||||
}
|
||||
this.needToSync = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check whether receive abilities.
|
||||
*
|
||||
* @param connection conn.
|
||||
* @return whether receive abilities.
|
||||
* @param connection conn.
|
||||
* @return whether receive abilities.
|
||||
*/
|
||||
public boolean check(Connection connection) {
|
||||
if (!connection.isAbilitiesSet()) {
|
||||
LOGGER.error("Client don't receive server abilities table even empty table but server supports ability negotiation."
|
||||
LOGGER.error(
|
||||
"Client don't receive server abilities table even empty table but server supports ability negotiation."
|
||||
+ " You can check if it is need to adjust the timeout of ability negotiation by property: {}"
|
||||
+ " if always fail to connect.",
|
||||
GrpcConstants.GRPC_CHANNEL_CAPABILITY_NEGOTIATION_TIMEOUT);
|
||||
@ -532,26 +530,26 @@ public abstract class GrpcClient extends RpcClient {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setup response handler.
|
||||
*/
|
||||
class SetupRequestHandler implements ServerRequestHandler {
|
||||
|
||||
|
||||
private final RecAbilityContext abilityContext;
|
||||
|
||||
|
||||
public SetupRequestHandler(RecAbilityContext abilityContext) {
|
||||
this.abilityContext = abilityContext;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Response requestReply(Request request, Connection connection) {
|
||||
// if finish setup
|
||||
if (request instanceof SetupAckRequest) {
|
||||
SetupAckRequest setupAckRequest = (SetupAckRequest) request;
|
||||
// remove and count down
|
||||
recAbilityContext.release(Optional.ofNullable(setupAckRequest.getAbilityTable())
|
||||
.orElse(new HashMap<>(0)));
|
||||
recAbilityContext
|
||||
.release(Optional.ofNullable(setupAckRequest.getAbilityTable()).orElse(new HashMap<>(0)));
|
||||
return new SetupAckResponse();
|
||||
}
|
||||
return null;
|
||||
@ -562,14 +560,14 @@ public abstract class GrpcClient extends RpcClient {
|
||||
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.empty();
|
||||
@ -579,7 +577,7 @@ public abstract class GrpcClient extends RpcClient {
|
||||
if (StringUtils.isNotBlank(tlsConfig.getSslProvider())) {
|
||||
builder.sslProvider(TlsTypeResolve.getSslProvider(tlsConfig.getSslProvider()));
|
||||
}
|
||||
|
||||
|
||||
if (StringUtils.isNotBlank(tlsConfig.getProtocols())) {
|
||||
builder.protocols(tlsConfig.getProtocols().split(","));
|
||||
}
|
||||
@ -595,10 +593,10 @@ public abstract class GrpcClient extends RpcClient {
|
||||
Resource resource = resourceLoader.getResource(tlsConfig.getTrustCollectionCertFile());
|
||||
builder.trustManager(resource.getInputStream());
|
||||
}
|
||||
|
||||
|
||||
if (tlsConfig.getMutualAuthEnable()) {
|
||||
if (StringUtils.isBlank(tlsConfig.getCertChainFile()) || StringUtils.isBlank(
|
||||
tlsConfig.getCertPrivateKey())) {
|
||||
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());
|
||||
|
@ -172,16 +172,14 @@ public class GrpcConnection extends Connection {
|
||||
if (this.payloadStreamObserver != null) {
|
||||
try {
|
||||
payloadStreamObserver.onCompleted();
|
||||
} catch (Throwable throwable) {
|
||||
//ignore.
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.channel != null && !channel.isShutdown()) {
|
||||
try {
|
||||
this.channel.shutdownNow();
|
||||
} catch (Throwable throwable) {
|
||||
//ignore.
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,8 +100,7 @@ public class GrpcConstants {
|
||||
GRpcConfigLabel.class)) {
|
||||
try {
|
||||
CONFIG_NAMES.add((String) declaredField.get(null));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,9 +62,7 @@ public class GrpcUtils {
|
||||
|
||||
// request body .
|
||||
byte[] jsonBytes = convertRequestToByte(request);
|
||||
return payloadBuilder
|
||||
.setBody(Any.newBuilder().setValue(UnsafeByteOperations.unsafeWrap(jsonBytes)))
|
||||
.build();
|
||||
return payloadBuilder.setBody(Any.newBuilder().setValue(UnsafeByteOperations.unsafeWrap(jsonBytes))).build();
|
||||
|
||||
}
|
||||
|
||||
@ -83,8 +81,7 @@ public class GrpcUtils {
|
||||
|
||||
Payload.Builder builder = Payload.newBuilder();
|
||||
|
||||
return builder
|
||||
.setBody(Any.newBuilder().setValue(UnsafeByteOperations.unsafeWrap(jsonBytes)))
|
||||
return builder.setBody(Any.newBuilder().setValue(UnsafeByteOperations.unsafeWrap(jsonBytes)))
|
||||
.setMetadata(newMeta).build();
|
||||
|
||||
}
|
||||
@ -99,8 +96,7 @@ public class GrpcUtils {
|
||||
byte[] jsonBytes = JacksonUtils.toJsonBytes(response);
|
||||
|
||||
Metadata.Builder metaBuilder = Metadata.newBuilder().setType(response.getClass().getSimpleName());
|
||||
return Payload.newBuilder()
|
||||
.setBody(Any.newBuilder().setValue(UnsafeByteOperations.unsafeWrap(jsonBytes)))
|
||||
return Payload.newBuilder().setBody(Any.newBuilder().setValue(UnsafeByteOperations.unsafeWrap(jsonBytes)))
|
||||
.setMetadata(metaBuilder.build()).build();
|
||||
}
|
||||
|
||||
@ -132,50 +128,5 @@ public class GrpcUtils {
|
||||
throw new RemoteException(NacosException.SERVER_ERROR,
|
||||
"Unknown payload type:" + payload.getMetadata().getType());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class PlainRequest {
|
||||
|
||||
String type;
|
||||
|
||||
Object body;
|
||||
|
||||
/**
|
||||
* Getter method for property <tt>type</tt>.
|
||||
*
|
||||
* @return property value of type
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter method for property <tt>type</tt>.
|
||||
*
|
||||
* @param type value to be assigned to property type
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter method for property <tt>body</tt>.
|
||||
*
|
||||
* @return property value of body
|
||||
*/
|
||||
public Object getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter method for property <tt>body</tt>.
|
||||
*
|
||||
* @param body value to be assigned to property body
|
||||
*/
|
||||
public void setBody(Object body) {
|
||||
this.body = body;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class ConnectionAlreadyClosedException extends RemoteException {
|
||||
private static final int CONNECTION_ALREADY_CLOSED = 600;
|
||||
|
||||
public ConnectionAlreadyClosedException(String msg) {
|
||||
super(CONNECTION_ALREADY_CLOSED);
|
||||
super(CONNECTION_ALREADY_CLOSED, msg);
|
||||
}
|
||||
|
||||
public ConnectionAlreadyClosedException() {
|
||||
|
@ -43,7 +43,7 @@ import static com.alibaba.nacos.api.exception.NacosException.SERVER_ERROR;
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public final class ClassUtils {
|
||||
|
||||
|
||||
private ClassUtils() {
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ public final class ClassUtils {
|
||||
*/
|
||||
public static Class<?> forName(String name, ClassLoader classLoader) throws ClassNotFoundException, LinkageError {
|
||||
|
||||
AbstractAssert.notNull(name, "Name must not be null");
|
||||
Objects.requireNonNull(name, "Name must not be null");
|
||||
|
||||
Class<?> clazz = resolvePrimitiveClassName(name);
|
||||
if (clazz == null) {
|
||||
@ -386,7 +386,7 @@ public final class ClassUtils {
|
||||
* @return the corresponding resource path, pointing to the class
|
||||
*/
|
||||
public static String convertClassNameToResourcePath(String className) {
|
||||
AbstractAssert.notNull(className, "Class name must not be null");
|
||||
Objects.requireNonNull(className, "Class name must not be null");
|
||||
return className.replace(PACKAGE_SEPARATOR, PATH_SEPARATOR);
|
||||
}
|
||||
|
||||
@ -397,7 +397,7 @@ public final class ClassUtils {
|
||||
* @return the corresponding resource path, pointing to the class
|
||||
*/
|
||||
public static String resourcePathToConvertClassName(String className) {
|
||||
AbstractAssert.notNull(className, "Class name must not be null");
|
||||
Objects.requireNonNull(className, "Class name must not be null");
|
||||
return className.replace(PATH_SEPARATOR, PACKAGE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
/**
|
||||
* Copyright 2018-2021 Dynatrace LLC
|
||||
* 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.
|
||||
* Copyright 2018-2021 Dynatrace LLC 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;
|
||||
@ -22,7 +18,7 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
@SuppressWarnings({"checkstyle:AbbreviationAsWordInName", "PMD.ClassNamingShouldBeCamelRule"})
|
||||
public class InetAddressValidator {
|
||||
|
||||
|
||||
private InetAddressValidator() {
|
||||
}
|
||||
|
||||
@ -59,9 +55,8 @@ public class InetAddressValidator {
|
||||
.compile("^" + "(?:[0-9a-fA-F]{1,4}:){6}" + "$");
|
||||
|
||||
/**
|
||||
* Check if <code>input</code> is a valid IPv4 address.
|
||||
* The format is 'xxx.xxx.xxx.xxx'. Four blocks of integer numbers ranging from 0 to 255
|
||||
* are required. Letters are not allowed.
|
||||
* Check if <code>input</code> is a valid IPv4 address. The format is 'xxx.xxx.xxx.xxx'. Four blocks of integer
|
||||
* numbers ranging from 0 to 255 are required. Letters are not allowed.
|
||||
*
|
||||
* @param input ip-address to check
|
||||
* @return true if <code>input</code> is in correct IPv4 notation.
|
||||
@ -71,9 +66,8 @@ public class InetAddressValidator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given address is a valid IPv6 address in the standard format
|
||||
* The format is 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'. Eight blocks of hexadecimal digits
|
||||
* are required.
|
||||
* Check if the given address is a valid IPv6 address in the standard format The format is
|
||||
* 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'. Eight blocks of hexadecimal digits are required.
|
||||
*
|
||||
* @param input ip-address to check
|
||||
* @return true if <code>input</code> is in correct IPv6 notation.
|
||||
@ -83,9 +77,8 @@ public class InetAddressValidator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given address is a valid IPv6 address in the hex-compressed notation
|
||||
* The format is 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'. If all digits in a block are '0'
|
||||
* the block can be left empty.
|
||||
* Check if the given address is a valid IPv6 address in the hex-compressed notation The format is
|
||||
* 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'. If all digits in a block are '0' the block can be left empty.
|
||||
*
|
||||
* @param input ip-address to check
|
||||
* @return true if <code>input</code> is in correct IPv6 (hex-compressed) notation.
|
||||
@ -95,13 +88,8 @@ public class InetAddressValidator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if <code>input</code> is a IPv6 address.
|
||||
* Possible notations for valid IPv6 are:
|
||||
* - Standard IPv6 address
|
||||
* - Hex-compressed IPv6 address
|
||||
* - Link-local IPv6 address
|
||||
* - IPv4-mapped-to-IPV6 address
|
||||
* - IPv6 mixed address
|
||||
* Check if <code>input</code> is a IPv6 address. Possible notations for valid IPv6 are: - Standard IPv6 address -
|
||||
* Hex-compressed IPv6 address - Link-local IPv6 address - IPv4-mapped-to-IPV6 address - IPv6 mixed address
|
||||
*
|
||||
* @param input ip-address to check
|
||||
* @return true if <code>input</code> is in correct IPv6 notation.
|
||||
@ -112,11 +100,9 @@ public class InetAddressValidator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given address is a valid IPv6 address in the mixed-standard or mixed-compressed notation.
|
||||
* IPV6 Mixed mode consists of two parts, the first 96 bits (up to 6 blocks of 4 hex digits) are IPv6
|
||||
* the IPV6 part can be either compressed or uncompressed
|
||||
* the second block is a full IPv4 address
|
||||
* e.g. '0:0:0:0:0:0:172.12.55.18'
|
||||
* Check if the given address is a valid IPv6 address in the mixed-standard or mixed-compressed notation. IPV6 Mixed
|
||||
* mode consists of two parts, the first 96 bits (up to 6 blocks of 4 hex digits) are IPv6 the IPV6 part can be
|
||||
* either compressed or uncompressed the second block is a full IPv4 address e.g. '0:0:0:0:0:0:172.12.55.18'
|
||||
*
|
||||
* @param input ip-address to check
|
||||
* @return true if <code>input</code> is in correct IPv6 (mixed-standard or mixed-compressed) notation.
|
||||
@ -143,9 +129,8 @@ public class InetAddressValidator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if <code>input</code> is an IPv4 address mapped into a IPv6 address. These are
|
||||
* starting with "::ffff:" followed by the IPv4 address in a dot-seperated notation.
|
||||
* The format is '::ffff:d.d.d.d'
|
||||
* Check if <code>input</code> is an IPv4 address mapped into a IPv6 address. These are starting with "::ffff:"
|
||||
* followed by the IPv4 address in a dot-seperated notation. The format is '::ffff:d.d.d.d'
|
||||
*
|
||||
* @param input ip-address to check
|
||||
* @return true if <code>input</code> is in correct IPv6 notation containing an IPv4 address
|
||||
@ -159,8 +144,8 @@ public class InetAddressValidator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if <code>input</code> is a link local IPv6 address starting with "fe80:" and containing
|
||||
* a zone index with "%xxx". The zone index will not be checked.
|
||||
* Check if <code>input</code> is a link local IPv6 address starting with "fe80:" and containing a zone index with
|
||||
* "%xxx". The zone index will not be checked.
|
||||
*
|
||||
* @param input ip-address to check
|
||||
* @return true if address part of <code>input</code> is in correct IPv6 notation.
|
||||
@ -176,27 +161,4 @@ public class InetAddressValidator {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if <code>input</code> is a valid IPv4 or IPv6 address.
|
||||
*
|
||||
* @param ipAddress ip-address to check
|
||||
* @return <code>true</code> if <code>ipAddress</code> is a valid ip-address
|
||||
*/
|
||||
public static boolean isValidIP(String ipAddress) {
|
||||
if (ipAddress == null || ipAddress.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isIPv4Address(ipAddress) || isIPv6Address(ipAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* get to ipv4 pattern.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Pattern getIpv4Pattern() {
|
||||
return IPV4_PATTERN;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.CharArrayWriter;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -33,7 +32,6 @@ import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -46,7 +44,7 @@ import java.util.zip.GZIPOutputStream;
|
||||
* @author nacos
|
||||
*/
|
||||
public class IoUtils {
|
||||
|
||||
|
||||
private IoUtils() {
|
||||
}
|
||||
|
||||
@ -75,11 +73,7 @@ public class IoUtils {
|
||||
if (!isGzipStream(raw)) {
|
||||
return raw;
|
||||
}
|
||||
try (GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(raw));
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||
copy(gis, out);
|
||||
return out.toByteArray();
|
||||
}
|
||||
return tryDecompress(new ByteArrayInputStream(raw));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -276,31 +270,6 @@ public class IoUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy File.
|
||||
*
|
||||
* @param source source file path
|
||||
* @param target target file path
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
public static void copyFile(String source, String target) throws IOException {
|
||||
File sf = new File(source);
|
||||
if (!sf.exists()) {
|
||||
throw new IllegalArgumentException("source file does not exist.");
|
||||
}
|
||||
File tf = new File(target);
|
||||
if (!tf.getParentFile().mkdirs()) {
|
||||
throw new RuntimeException("failed to create parent directory.");
|
||||
}
|
||||
if (!tf.exists() && !tf.createNewFile()) {
|
||||
throw new RuntimeException("failed to create target file.");
|
||||
}
|
||||
try (FileChannel sc = new FileInputStream(sf).getChannel();
|
||||
FileChannel tc = new FileOutputStream(tf).getChannel()) {
|
||||
sc.transferTo(0, sc.size(), tc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge whether is Gzip stream.
|
||||
*
|
||||
|
@ -16,9 +16,6 @@
|
||||
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
@ -26,7 +23,6 @@ import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
@ -36,7 +32,7 @@ import java.util.StringTokenizer;
|
||||
* @author zzq
|
||||
*/
|
||||
public class StringUtils {
|
||||
|
||||
|
||||
private StringUtils() {
|
||||
}
|
||||
|
||||
@ -226,108 +222,6 @@ public class StringUtils {
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public static String escapeJavaScript(String str) {
|
||||
return escapeJavaStyleString(str, true, true);
|
||||
}
|
||||
|
||||
private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes, boolean escapeForwardSlash) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
StringWriter writer = new StringWriter(str.length() * 2);
|
||||
escapeJavaStyleString(writer, str, escapeSingleQuotes, escapeForwardSlash);
|
||||
return writer.toString();
|
||||
} catch (IOException ioe) {
|
||||
// this should never ever happen while writing to a StringWriter
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote,
|
||||
boolean escapeForwardSlash) throws IOException {
|
||||
if (out == null) {
|
||||
throw new IllegalArgumentException("The Writer must not be null");
|
||||
}
|
||||
if (str == null) {
|
||||
return;
|
||||
}
|
||||
int sz;
|
||||
sz = str.length();
|
||||
for (int i = 0; i < sz; i++) {
|
||||
char ch = str.charAt(i);
|
||||
|
||||
// handle unicode
|
||||
if (ch > 0xfff) {
|
||||
out.write("\\u" + hex(ch));
|
||||
} else if (ch > 0xff) {
|
||||
out.write("\\u0" + hex(ch));
|
||||
} else if (ch > 0x7f) {
|
||||
out.write("\\u00" + hex(ch));
|
||||
} else if (ch < 32) {
|
||||
switch (ch) {
|
||||
case '\b':
|
||||
out.write('\\');
|
||||
out.write('b');
|
||||
break;
|
||||
case '\n':
|
||||
out.write('\\');
|
||||
out.write('n');
|
||||
break;
|
||||
case '\t':
|
||||
out.write('\\');
|
||||
out.write('t');
|
||||
break;
|
||||
case '\f':
|
||||
out.write('\\');
|
||||
out.write('f');
|
||||
break;
|
||||
case '\r':
|
||||
out.write('\\');
|
||||
out.write('r');
|
||||
break;
|
||||
default:
|
||||
if (ch > 0xf) {
|
||||
out.write("\\u00" + hex(ch));
|
||||
} else {
|
||||
out.write("\\u000" + hex(ch));
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (ch) {
|
||||
case '\'':
|
||||
if (escapeSingleQuote) {
|
||||
out.write('\\');
|
||||
}
|
||||
out.write('\'');
|
||||
break;
|
||||
case '"':
|
||||
out.write('\\');
|
||||
out.write('"');
|
||||
break;
|
||||
case '\\':
|
||||
out.write('\\');
|
||||
out.write('\\');
|
||||
break;
|
||||
case '/':
|
||||
if (escapeForwardSlash) {
|
||||
out.write('\\');
|
||||
}
|
||||
out.write('/');
|
||||
break;
|
||||
default:
|
||||
out.write(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String hex(char ch) {
|
||||
return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if CharSequence contains a search CharSequence irrespective of case, handling {@code null}.
|
||||
* Case-insensitivity is defined as by {@link String#equalsIgnoreCase(String)}.
|
||||
@ -503,10 +397,6 @@ public class StringUtils {
|
||||
return str.split(separatorChars);
|
||||
}
|
||||
|
||||
private static String[] tokenizeLocaleSource(String localeSource) {
|
||||
return tokenizeToStringArray(localeSource, "_ ", false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenize the given {@code String} into a {@code String} array via a {@link StringTokenizer}.
|
||||
*
|
||||
@ -899,21 +789,17 @@ public class StringUtils {
|
||||
* @return the capitalized {@code String}
|
||||
*/
|
||||
public static String capitalize(String str) {
|
||||
return changeFirstCharacterCase(str, true);
|
||||
return changeFirstCharacterCase(str);
|
||||
}
|
||||
|
||||
private static String changeFirstCharacterCase(String str, boolean capitalize) {
|
||||
private static String changeFirstCharacterCase(String str) {
|
||||
if (!hasLength(str)) {
|
||||
return str;
|
||||
}
|
||||
|
||||
char baseChar = str.charAt(0);
|
||||
char updatedChar;
|
||||
if (capitalize) {
|
||||
updatedChar = Character.toUpperCase(baseChar);
|
||||
} else {
|
||||
updatedChar = Character.toLowerCase(baseChar);
|
||||
}
|
||||
updatedChar = Character.toUpperCase(baseChar);
|
||||
if (baseChar == updatedChar) {
|
||||
return str;
|
||||
}
|
||||
|
@ -29,25 +29,12 @@ import java.util.concurrent.TimeUnit;
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public final class ThreadUtils {
|
||||
|
||||
|
||||
private ThreadUtils() {
|
||||
}
|
||||
|
||||
private static final int THREAD_MULTIPLER = 2;
|
||||
|
||||
/**
|
||||
* Wait.
|
||||
*
|
||||
* @param object load object
|
||||
*/
|
||||
public static void objectWait(Object object) {
|
||||
try {
|
||||
object.wait();
|
||||
} catch (InterruptedException ignore) {
|
||||
Thread.interrupted();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleep.
|
||||
*
|
||||
|
@ -1,217 +0,0 @@
|
||||
/*
|
||||
* 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 java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* container for top n counter metrics, increment and remove cost O(1) time.
|
||||
*
|
||||
* @author <a href="mailto:liuyixiao0821@gmail.com">liuyixiao</a>
|
||||
*/
|
||||
public class TopnCounterMetricsContainer {
|
||||
|
||||
/**
|
||||
* dataId -> count.
|
||||
*/
|
||||
private ConcurrentHashMap<String, AtomicInteger> dataCount;
|
||||
|
||||
/**
|
||||
* count -> node.
|
||||
*/
|
||||
private ConcurrentHashMap<Integer, DoublyLinkedNode> specifiedCountDataIdSets;
|
||||
|
||||
private DoublyLinkedNode dummyHead;
|
||||
|
||||
public TopnCounterMetricsContainer() {
|
||||
dataCount = new ConcurrentHashMap<>();
|
||||
specifiedCountDataIdSets = new ConcurrentHashMap<>();
|
||||
dummyHead = new DoublyLinkedNode(null, null, null, -1);
|
||||
dummyHead.next = new DoublyLinkedNode(null, dummyHead, new ConcurrentHashSet<>(), 0);
|
||||
specifiedCountDataIdSets.put(0, dummyHead.next);
|
||||
}
|
||||
|
||||
public List<Pair<String, AtomicInteger>> getTopNCounter(int n) {
|
||||
List<Pair<String, AtomicInteger>> topnCounter = new LinkedList<>();
|
||||
DoublyLinkedNode curr = dummyHead;
|
||||
while (curr.next != null && topnCounter.size() < n) {
|
||||
for (String dataId : curr.next.dataSet) {
|
||||
// use inner AtomicInteger to reflect change to prometheus
|
||||
topnCounter.add(new Pair<>(dataId, dataCount.get(dataId)));
|
||||
if (topnCounter.size() == n) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
curr = curr.next;
|
||||
}
|
||||
return topnCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* put(String dataId, 0).
|
||||
*
|
||||
* @param dataId data name or data key.
|
||||
*/
|
||||
public void put(String dataId) {
|
||||
put(dataId, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* put new data into container, if already exist, update it.
|
||||
* this method could be slow (O(N)), most time use increment.
|
||||
*
|
||||
* @param dataId data name or data key.
|
||||
* @param count data count.
|
||||
*/
|
||||
public void put(String dataId, int count) {
|
||||
if (dataCount.containsKey(dataId)) {
|
||||
removeFromSpecifiedCountDataIdSets(dataId);
|
||||
dataCount.get(dataId).set(count);
|
||||
} else {
|
||||
dataCount.put(dataId, new AtomicInteger(count));
|
||||
}
|
||||
insertIntoSpecifiedCountDataIdSets(dataId, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* get data count by dataId.
|
||||
*
|
||||
* @param dataId data name or data key.
|
||||
* @return data count or -1 if not exist.
|
||||
*/
|
||||
public int get(String dataId) {
|
||||
if (dataCount.containsKey(dataId)) {
|
||||
return dataCount.get(dataId).get();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* increment the count of dataId.
|
||||
*
|
||||
* @param dataId data name or data key.
|
||||
*/
|
||||
public void increment(String dataId) {
|
||||
if (!dataCount.containsKey(dataId)) {
|
||||
put(dataId);
|
||||
}
|
||||
DoublyLinkedNode prev = removeFromSpecifiedCountDataIdSets(dataId);
|
||||
int newCount = dataCount.get(dataId).incrementAndGet();
|
||||
if (!isDummyHead(prev) && prev.count == newCount) {
|
||||
insertIntoSpecifiedCountDataIdSets(dataId, prev);
|
||||
} else {
|
||||
// prev.count > newCount
|
||||
DoublyLinkedNode newNode = new DoublyLinkedNode(prev.next, prev, new ConcurrentHashSet<>(), newCount);
|
||||
if (prev.next != null) {
|
||||
prev.next.prev = newNode;
|
||||
}
|
||||
prev.next = newNode;
|
||||
newNode.dataSet.add(dataId);
|
||||
specifiedCountDataIdSets.put(newCount, newNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove data.
|
||||
*
|
||||
* @param dataId data name or data key.
|
||||
* @return data count or null if data is not exist.
|
||||
*/
|
||||
public AtomicInteger remove(String dataId) {
|
||||
if (dataCount.containsKey(dataId)) {
|
||||
removeFromSpecifiedCountDataIdSets(dataId);
|
||||
return dataCount.remove(dataId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove all data.
|
||||
*/
|
||||
public void removeAll() {
|
||||
for (String dataId : dataCount.keySet()) {
|
||||
removeFromSpecifiedCountDataIdSets(dataId);
|
||||
}
|
||||
dataCount.clear();
|
||||
}
|
||||
|
||||
private DoublyLinkedNode removeFromSpecifiedCountDataIdSets(String dataId) {
|
||||
int count = dataCount.get(dataId).get();
|
||||
DoublyLinkedNode node = specifiedCountDataIdSets.get(count);
|
||||
node.dataSet.remove(dataId);
|
||||
// keep the 0 count node.
|
||||
if (node.dataSet.size() == 0 && node.count != 0) {
|
||||
node.prev.next = node.next;
|
||||
if (node.next != null) {
|
||||
node.next.prev = node.prev;
|
||||
}
|
||||
specifiedCountDataIdSets.remove(node.count);
|
||||
}
|
||||
return node.prev;
|
||||
}
|
||||
|
||||
private void insertIntoSpecifiedCountDataIdSets(String dataId, int count) {
|
||||
if (specifiedCountDataIdSets.containsKey(count)) {
|
||||
specifiedCountDataIdSets.get(count).dataSet.add(dataId);
|
||||
} else {
|
||||
DoublyLinkedNode prev = dummyHead;
|
||||
while (prev.next != null) {
|
||||
if (prev.next.count < count) {
|
||||
break;
|
||||
} else {
|
||||
prev = prev.next;
|
||||
}
|
||||
}
|
||||
DoublyLinkedNode newNode = new DoublyLinkedNode(prev.next, prev, new ConcurrentHashSet<>(), count);
|
||||
if (prev.next != null) {
|
||||
prev.next.prev = newNode;
|
||||
}
|
||||
prev.next = newNode;
|
||||
newNode.dataSet.add(dataId);
|
||||
specifiedCountDataIdSets.put(count, newNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void insertIntoSpecifiedCountDataIdSets(String dataId, DoublyLinkedNode targetSet) {
|
||||
targetSet.dataSet.add(dataId);
|
||||
}
|
||||
|
||||
private boolean isDummyHead(DoublyLinkedNode node) {
|
||||
return node.count == -1;
|
||||
}
|
||||
|
||||
private class DoublyLinkedNode {
|
||||
|
||||
public DoublyLinkedNode next;
|
||||
|
||||
public DoublyLinkedNode prev;
|
||||
|
||||
public ConcurrentHashSet<String> dataSet;
|
||||
|
||||
public int count;
|
||||
|
||||
public DoublyLinkedNode(DoublyLinkedNode next, DoublyLinkedNode prev, ConcurrentHashSet<String> dataSet, int count) {
|
||||
this.next = next;
|
||||
this.prev = prev;
|
||||
this.dataSet = dataSet;
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
}
|
18
common/src/test/java/ClassUtilsTestMockClass.java
Normal file
18
common/src/test/java/ClassUtilsTestMockClass.java
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
public class ClassUtilsTestMockClass {
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.http.client.request.DefaultHttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.client.request.HttpClientRequest;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AbstractApacheHttpClientFactoryTest {
|
||||
|
||||
@Mock
|
||||
private Logger logger;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNacosRestTemplate() throws NoSuchFieldException, IllegalAccessException {
|
||||
HttpClientFactory factory = new AbstractApacheHttpClientFactory() {
|
||||
@Override
|
||||
protected HttpClientConfig buildHttpClientConfig() {
|
||||
return HttpClientConfig.builder().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Logger assignLogger() {
|
||||
return logger;
|
||||
}
|
||||
};
|
||||
NacosRestTemplate template = factory.createNacosRestTemplate();
|
||||
assertNotNull(template);
|
||||
Field field = NacosRestTemplate.class.getDeclaredField("requestClient");
|
||||
field.setAccessible(true);
|
||||
HttpClientRequest requestClient = (HttpClientRequest) field.get(template);
|
||||
assertTrue(requestClient instanceof DefaultHttpClientRequest);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.tls.TlsSystemConfig;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AbstractHttpClientFactoryTest {
|
||||
|
||||
@Mock
|
||||
private Logger logger;
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
TlsSystemConfig.tlsEnable = false;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNacosRestTemplateWithSsl() throws Exception {
|
||||
TlsSystemConfig.tlsEnable = true;
|
||||
HttpClientFactory httpClientFactory = new DefaultHttpClientFactory(logger);
|
||||
NacosRestTemplate nacosRestTemplate = httpClientFactory.createNacosRestTemplate();
|
||||
assertNotNull(nacosRestTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNacosAsyncRestTemplate() {
|
||||
HttpClientFactory httpClientFactory = new AbstractHttpClientFactory() {
|
||||
@Override
|
||||
protected HttpClientConfig buildHttpClientConfig() {
|
||||
return HttpClientConfig.builder().setMaxConnTotal(10).setMaxConnPerRoute(10).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Logger assignLogger() {
|
||||
return logger;
|
||||
}
|
||||
};
|
||||
NacosAsyncRestTemplate nacosRestTemplate = httpClientFactory.createNacosAsyncRestTemplate();
|
||||
assertNotNull(nacosRestTemplate);
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BaseHttpMethodTest {
|
||||
|
||||
@Test
|
||||
public void testHttpGet() {
|
||||
BaseHttpMethod method = BaseHttpMethod.GET;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("GET", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpGetLarge() {
|
||||
BaseHttpMethod method = BaseHttpMethod.GET_LARGE;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("GET", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpPost() {
|
||||
BaseHttpMethod method = BaseHttpMethod.POST;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("POST", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpPut() {
|
||||
BaseHttpMethod method = BaseHttpMethod.PUT;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("PUT", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpDelete() {
|
||||
BaseHttpMethod method = BaseHttpMethod.DELETE;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("DELETE", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpDeleteLarge() {
|
||||
BaseHttpMethod method = BaseHttpMethod.DELETE_LARGE;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("DELETE", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpHead() {
|
||||
BaseHttpMethod method = BaseHttpMethod.HEAD;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("HEAD", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpTrace() {
|
||||
BaseHttpMethod method = BaseHttpMethod.TRACE;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("TRACE", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpPatch() {
|
||||
BaseHttpMethod method = BaseHttpMethod.PATCH;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("PATCH", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpOptions() {
|
||||
BaseHttpMethod method = BaseHttpMethod.OPTIONS;
|
||||
HttpRequestBase request = method.init("http://example.com");
|
||||
Assert.assertEquals("TRACE", request.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSourceOf() {
|
||||
BaseHttpMethod method = BaseHttpMethod.sourceOf("GET");
|
||||
Assert.assertEquals(BaseHttpMethod.GET, method);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testSourceOfNotFound() {
|
||||
BaseHttpMethod.sourceOf("Not Found");
|
||||
}
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class HttpClientBeanHolderTest {
|
||||
|
||||
private Map<String, NacosRestTemplate> cachedRestTemplateMap;
|
||||
|
||||
private Map<String, NacosRestTemplate> restMap;
|
||||
|
||||
private Map<String, NacosAsyncRestTemplate> cachedAsyncRestTemplateMap;
|
||||
|
||||
private Map<String, NacosAsyncRestTemplate> restAsyncMap;
|
||||
|
||||
@Mock
|
||||
private NacosRestTemplate mockRestTemplate;
|
||||
|
||||
@Mock
|
||||
private NacosAsyncRestTemplate mockAsyncRestTemplate;
|
||||
|
||||
@Mock
|
||||
private HttpClientFactory mockFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
cachedRestTemplateMap = new HashMap<>();
|
||||
cachedAsyncRestTemplateMap = new HashMap<>();
|
||||
restMap = (Map<String, NacosRestTemplate>) getCachedMap("SINGLETON_REST");
|
||||
restAsyncMap = (Map<String, NacosAsyncRestTemplate>) getCachedMap("SINGLETON_ASYNC_REST");
|
||||
cachedRestTemplateMap.putAll(restMap);
|
||||
cachedAsyncRestTemplateMap.putAll(restAsyncMap);
|
||||
restMap.clear();
|
||||
restAsyncMap.clear();
|
||||
when(mockFactory.createNacosRestTemplate()).thenReturn(mockRestTemplate);
|
||||
when(mockFactory.createNacosAsyncRestTemplate()).thenReturn(mockAsyncRestTemplate);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
restMap.putAll(cachedRestTemplateMap);
|
||||
restAsyncMap.putAll(cachedAsyncRestTemplateMap);
|
||||
cachedRestTemplateMap.clear();
|
||||
cachedAsyncRestTemplateMap.clear();
|
||||
}
|
||||
|
||||
private Object getCachedMap(String mapName) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field field = HttpClientBeanHolder.class.getDeclaredField(mapName);
|
||||
field.setAccessible(true);
|
||||
return field.get(HttpClientBeanHolder.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNacosRestTemplateWithDefault() {
|
||||
assertTrue(restMap.isEmpty());
|
||||
NacosRestTemplate actual = HttpClientBeanHolder.getNacosRestTemplate((Logger) null);
|
||||
assertEquals(1, restMap.size());
|
||||
NacosRestTemplate duplicateGet = HttpClientBeanHolder.getNacosRestTemplate((Logger) null);
|
||||
assertEquals(1, restMap.size());
|
||||
assertEquals(actual, duplicateGet);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void testGetNacosRestTemplateForNullFactory() {
|
||||
HttpClientBeanHolder.getNacosRestTemplate((HttpClientFactory) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNacosRestTemplateWithCustomFactory() {
|
||||
assertTrue(restMap.isEmpty());
|
||||
HttpClientBeanHolder.getNacosRestTemplate((Logger) null);
|
||||
assertEquals(1, restMap.size());
|
||||
NacosRestTemplate actual = HttpClientBeanHolder.getNacosRestTemplate(mockFactory);
|
||||
assertEquals(2, restMap.size());
|
||||
assertEquals(mockRestTemplate, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNacosAsyncRestTemplateWithDefault() {
|
||||
assertTrue(restAsyncMap.isEmpty());
|
||||
NacosAsyncRestTemplate actual = HttpClientBeanHolder.getNacosAsyncRestTemplate((Logger) null);
|
||||
assertEquals(1, restAsyncMap.size());
|
||||
NacosAsyncRestTemplate duplicateGet = HttpClientBeanHolder.getNacosAsyncRestTemplate((Logger) null);
|
||||
assertEquals(1, restAsyncMap.size());
|
||||
assertEquals(actual, duplicateGet);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void testGetNacosAsyncRestTemplateForNullFactory() {
|
||||
HttpClientBeanHolder.getNacosAsyncRestTemplate((HttpClientFactory) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNacosAsyncRestTemplateWithCustomFactory() {
|
||||
assertTrue(restAsyncMap.isEmpty());
|
||||
HttpClientBeanHolder.getNacosAsyncRestTemplate((Logger) null);
|
||||
assertEquals(1, restAsyncMap.size());
|
||||
NacosAsyncRestTemplate actual = HttpClientBeanHolder.getNacosAsyncRestTemplate(mockFactory);
|
||||
assertEquals(2, restAsyncMap.size());
|
||||
assertEquals(mockAsyncRestTemplate, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shutdown() throws Exception {
|
||||
HttpClientBeanHolder.getNacosRestTemplate((Logger) null);
|
||||
HttpClientBeanHolder.getNacosAsyncRestTemplate((Logger) null);
|
||||
assertEquals(1, restMap.size());
|
||||
assertEquals(1, restAsyncMap.size());
|
||||
HttpClientBeanHolder.shutdown(DefaultHttpClientFactory.class.getName());
|
||||
assertEquals(0, restMap.size());
|
||||
assertEquals(0, restAsyncMap.size());
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
public class HttpClientConfigTest {
|
||||
|
||||
@Test
|
||||
public void testGetConTimeOutMillis() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setConTimeOutMillis(1000).build();
|
||||
assertEquals(1000, config.getConTimeOutMillis());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetReadTimeOutMillis() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setReadTimeOutMillis(2000).build();
|
||||
assertEquals(2000, config.getReadTimeOutMillis());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConnTimeToLive() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setConnectionTimeToLive(3000, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
assertEquals(3000, config.getConnTimeToLive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConnTimeToLiveTimeUnit() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setConnectionTimeToLive(4000, TimeUnit.SECONDS).build();
|
||||
assertEquals(TimeUnit.SECONDS, config.getConnTimeToLiveTimeUnit());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConnectionRequestTimeout() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setConnectionRequestTimeout(5000).build();
|
||||
assertEquals(5000, config.getConnectionRequestTimeout());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMaxRedirects() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setMaxRedirects(60).build();
|
||||
assertEquals(60, config.getMaxRedirects());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMaxConnTotal() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setMaxConnTotal(70).build();
|
||||
assertEquals(70, config.getMaxConnTotal());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMaxConnPerRoute() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setMaxConnPerRoute(80).build();
|
||||
assertEquals(80, config.getMaxConnPerRoute());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetContentCompressionEnabled() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setContentCompressionEnabled(false).build();
|
||||
assertFalse(config.getContentCompressionEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIoThreadCount() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setIoThreadCount(90).build();
|
||||
assertEquals(90, config.getIoThreadCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserAgent() {
|
||||
HttpClientConfig config = HttpClientConfig.builder().setUserAgent("testUserAgent").build();
|
||||
assertEquals("testUserAgent", config.getUserAgent());
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class HttpRestResultTest {
|
||||
|
||||
@Test
|
||||
public void testSetHeader() {
|
||||
HttpRestResult<String> result = new HttpRestResult<>();
|
||||
result.setData("test data");
|
||||
Header header = Header.newInstance();
|
||||
result.setHeader(header);
|
||||
assertEquals(header, result.getHeader());
|
||||
assertEquals("test data", result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFullConstructor() {
|
||||
Header header = Header.newInstance();
|
||||
HttpRestResult<String> result = new HttpRestResult<>(header, 200, "test data", "message");
|
||||
assertEquals(header, result.getHeader());
|
||||
assertEquals("test data", result.getData());
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client;
|
||||
|
||||
import com.alibaba.nacos.common.http.client.handler.BeanResponseHandler;
|
||||
import com.alibaba.nacos.common.http.client.handler.ResponseHandler;
|
||||
import com.alibaba.nacos.common.http.client.handler.RestResultResponseHandler;
|
||||
import com.alibaba.nacos.common.http.client.handler.StringResponseHandler;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AbstractNacosRestTemplateTest {
|
||||
|
||||
@Mock
|
||||
private ResponseHandler mockResponseHandler;
|
||||
|
||||
MockNacosRestTemplate restTemplate;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
restTemplate = new MockNacosRestTemplate(null);
|
||||
restTemplate.registerResponseHandler(MockNacosRestTemplate.class.getName(), mockResponseHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectResponseHandlerForNull() {
|
||||
assertTrue(restTemplate.testFindResponseHandler(null) instanceof StringResponseHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectResponseHandlerForRestResult() {
|
||||
assertTrue(restTemplate.testFindResponseHandler(RestResult.class) instanceof RestResultResponseHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectResponseHandlerForDefault() {
|
||||
assertTrue(restTemplate
|
||||
.testFindResponseHandler(AbstractNacosRestTemplateTest.class) instanceof BeanResponseHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectResponseHandlerForCustom() {
|
||||
assertEquals(mockResponseHandler, restTemplate.testFindResponseHandler(MockNacosRestTemplate.class));
|
||||
}
|
||||
|
||||
private static class MockNacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
|
||||
public MockNacosRestTemplate(Logger logger) {
|
||||
super(logger);
|
||||
}
|
||||
|
||||
private ResponseHandler testFindResponseHandler(Type responseType) {
|
||||
return super.selectResponseHandler(responseType);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client;
|
||||
|
||||
import com.alibaba.nacos.common.http.client.request.HttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.client.response.HttpClientResponse;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class InterceptingHttpClientRequestTest {
|
||||
|
||||
@Mock
|
||||
private HttpClientRequest httpClientRequest;
|
||||
|
||||
@Mock
|
||||
private HttpClientRequestInterceptor interceptor;
|
||||
|
||||
@Mock
|
||||
private HttpClientResponse interceptorResponse;
|
||||
|
||||
@Mock
|
||||
private HttpClientResponse httpClientResponse;
|
||||
|
||||
InterceptingHttpClientRequest clientRequest;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
List<HttpClientRequestInterceptor> interceptorList = new LinkedList<>();
|
||||
interceptorList.add(interceptor);
|
||||
clientRequest = new InterceptingHttpClientRequest(httpClientRequest, interceptorList.listIterator());
|
||||
when(interceptor.intercept()).thenReturn(interceptorResponse);
|
||||
when(httpClientRequest.execute(any(), any(), any())).thenReturn(httpClientResponse);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
clientRequest.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteIntercepted() throws Exception {
|
||||
when(interceptor.isIntercept(any(), any(), any())).thenReturn(true);
|
||||
HttpClientResponse response = clientRequest
|
||||
.execute(URI.create("http://example.com"), "GET", new RequestHttpEntity(Header.EMPTY, Query.EMPTY));
|
||||
assertEquals(interceptorResponse, response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteNotIntercepted() throws Exception {
|
||||
HttpClientResponse response = clientRequest
|
||||
.execute(URI.create("http://example.com"), "GET", new RequestHttpEntity(Header.EMPTY, Query.EMPTY));
|
||||
assertEquals(httpClientResponse, response);
|
||||
}
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client;
|
||||
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.http.Callback;
|
||||
import com.alibaba.nacos.common.http.client.request.AsyncHttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NacosAsyncRestTemplateTest {
|
||||
|
||||
private static final String TEST_URL = "http://127.0.0.1:8848/nacos/test";
|
||||
|
||||
@Mock
|
||||
private AsyncHttpClientRequest requestClient;
|
||||
|
||||
@Mock
|
||||
private Logger logger;
|
||||
|
||||
@Mock
|
||||
private Callback<String> mockCallback;
|
||||
|
||||
private NacosAsyncRestTemplate restTemplate;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
restTemplate = new NacosAsyncRestTemplate(logger, requestClient);
|
||||
when(logger.isDebugEnabled()).thenReturn(true);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
restTemplate.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGet() throws Exception {
|
||||
restTemplate.get(TEST_URL, Header.EMPTY, Query.EMPTY, String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("GET"), any(), any(), eq(mockCallback));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWithException() throws Exception {
|
||||
doThrow(new RuntimeException("test")).when(requestClient).execute(any(), any(), any(), any(), any());
|
||||
restTemplate.get(TEST_URL, Header.EMPTY, Query.EMPTY, String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("GET"), any(), any(), eq(mockCallback));
|
||||
verify(mockCallback).onError(any(RuntimeException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLarge() throws Exception {
|
||||
restTemplate.getLarge(TEST_URL, Header.EMPTY, Query.EMPTY, new Object(), String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("GET-LARGE"), any(), any(), eq(mockCallback));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteWithBody() throws Exception {
|
||||
restTemplate.delete(TEST_URL, Header.EMPTY, Query.EMPTY, String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("DELETE"), any(), any(), eq(mockCallback));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteLarge() throws Exception {
|
||||
restTemplate.delete(TEST_URL, Header.EMPTY, "body", String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("DELETE_LARGE"), any(), any(), eq(mockCallback));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPut() throws Exception {
|
||||
restTemplate.put(TEST_URL, Header.EMPTY, Query.EMPTY, "body", String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("PUT"), any(), any(), eq(mockCallback));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutJson() throws Exception {
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
restTemplate.putJson(TEST_URL, header, "body", String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("PUT"), any(), any(), eq(mockCallback));
|
||||
assertEquals(MediaType.APPLICATION_JSON, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutJsonWithQuery() throws Exception {
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
restTemplate.putJson(TEST_URL, header, Query.EMPTY, "body", String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("PUT"), any(), any(), eq(mockCallback));
|
||||
assertEquals(MediaType.APPLICATION_JSON, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutForm() throws Exception {
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
restTemplate.putForm(TEST_URL, header, new HashMap<>(), String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("PUT"), any(), any(), eq(mockCallback));
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutFormWithQuery() throws Exception {
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
restTemplate.putForm(TEST_URL, header, Query.EMPTY, new HashMap<>(), String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("PUT"), any(), any(), eq(mockCallback));
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPost() throws Exception {
|
||||
restTemplate.post(TEST_URL, Header.EMPTY, Query.EMPTY, "body", String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("POST"), any(), any(), eq(mockCallback));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostJson() throws Exception {
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
restTemplate.postJson(TEST_URL, header, "body", String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("POST"), any(), any(), eq(mockCallback));
|
||||
assertEquals(MediaType.APPLICATION_JSON, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostJsonWithQuery() throws Exception {
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
restTemplate.postJson(TEST_URL, header, Query.EMPTY, "body", String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("POST"), any(), any(), eq(mockCallback));
|
||||
assertEquals(MediaType.APPLICATION_JSON, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostForm() throws Exception {
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
restTemplate.postForm(TEST_URL, header, new HashMap<>(), String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("POST"), any(), any(), eq(mockCallback));
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostFormWithQuery() throws Exception {
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
restTemplate.postForm(TEST_URL, header, Query.EMPTY, new HashMap<>(), String.class, mockCallback);
|
||||
verify(requestClient).execute(any(), eq("POST"), any(), any(), eq(mockCallback));
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
}
|
@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client;
|
||||
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||
import com.alibaba.nacos.common.http.client.request.HttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.client.response.HttpClientResponse;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NacosRestTemplateTest {
|
||||
|
||||
@Mock
|
||||
private HttpClientRequest requestClient;
|
||||
|
||||
@Mock
|
||||
private Logger logger;
|
||||
|
||||
@Mock
|
||||
private HttpClientResponse mockResponse;
|
||||
|
||||
@Mock
|
||||
private HttpClientRequestInterceptor interceptor;
|
||||
|
||||
private NacosRestTemplate restTemplate;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
restTemplate = new NacosRestTemplate(logger, requestClient);
|
||||
when(logger.isDebugEnabled()).thenReturn(true);
|
||||
when(mockResponse.getHeaders()).thenReturn(Header.EMPTY);
|
||||
when(interceptor.isIntercept(any(), any(), any())).thenReturn(true);
|
||||
when(interceptor.intercept()).thenReturn(mockResponse);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
restTemplate.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWithDefaultConfig() throws Exception {
|
||||
when(requestClient.execute(any(), eq("GET"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.get("http://127.0.0.1:8848/nacos/test", Header.EMPTY, Query.EMPTY, String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWithCustomConfig() throws Exception {
|
||||
when(requestClient.execute(any(), eq("GET"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpClientConfig config = HttpClientConfig.builder().setConTimeOutMillis(1000).build();
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.get("http://127.0.0.1:8848/nacos/test", config, Header.EMPTY, Query.EMPTY, String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWithInterceptor() throws Exception {
|
||||
when(mockResponse.getStatusCode()).thenReturn(300);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test interceptor".getBytes()));
|
||||
restTemplate.setInterceptors(Collections.singletonList(interceptor));
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.get("http://127.0.0.1:8848/nacos/test", Header.EMPTY, Query.EMPTY, String.class);
|
||||
assertFalse(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test interceptor", result.getMessage());
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testGetWithException() throws Exception {
|
||||
when(requestClient.execute(any(), eq("GET"), any())).thenThrow(new RuntimeException("test"));
|
||||
restTemplate.get("http://127.0.0.1:8848/nacos/test", Header.EMPTY, Query.EMPTY, String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLarge() throws Exception {
|
||||
when(requestClient.execute(any(), eq("GET-LARGE"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.getLarge("http://127.0.0.1:8848/nacos/test", Header.EMPTY, Query.EMPTY, new Object(), String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteWithDefaultConfig() throws Exception {
|
||||
when(requestClient.execute(any(), eq("DELETE"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.delete("http://127.0.0.1:8848/nacos/test", Header.EMPTY, Query.EMPTY, String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteWithCustomConfig() throws Exception {
|
||||
when(requestClient.execute(any(), eq("DELETE"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpClientConfig config = HttpClientConfig.builder().setConTimeOutMillis(1000).build();
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.delete("http://127.0.0.1:8848/nacos/test", config, Header.EMPTY, Query.EMPTY, String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPut() throws Exception {
|
||||
when(requestClient.execute(any(), eq("PUT"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.put("http://127.0.0.1:8848/nacos/test", Header.EMPTY, Query.EMPTY, new Object(), String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutJson() throws Exception {
|
||||
when(requestClient.execute(any(), eq("PUT"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.putJson("http://127.0.0.1:8848/nacos/test", header, "body", String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_JSON, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutJsonWithQuery() throws Exception {
|
||||
when(requestClient.execute(any(), eq("PUT"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.putJson("http://127.0.0.1:8848/nacos/test", header, Query.EMPTY, "body", String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_JSON, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutForm() throws Exception {
|
||||
when(requestClient.execute(any(), eq("PUT"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.putForm("http://127.0.0.1:8848/nacos/test", header, new HashMap<>(), String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutFormWithQuery() throws Exception {
|
||||
when(requestClient.execute(any(), eq("PUT"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.putForm("http://127.0.0.1:8848/nacos/test", header, Query.EMPTY, new HashMap<>(), String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutFormWithConfig() throws Exception {
|
||||
when(requestClient.execute(any(), eq("PUT"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpClientConfig config = HttpClientConfig.builder().setConTimeOutMillis(1000).build();
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.putForm("http://127.0.0.1:8848/nacos/test", config, header, new HashMap<>(), String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPost() throws Exception {
|
||||
when(requestClient.execute(any(), eq("POST"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.post("http://127.0.0.1:8848/nacos/test", Header.EMPTY, Query.EMPTY, new Object(), String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostJson() throws Exception {
|
||||
when(requestClient.execute(any(), eq("POST"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.postJson("http://127.0.0.1:8848/nacos/test", header, "body", String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_JSON, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostJsonWithQuery() throws Exception {
|
||||
when(requestClient.execute(any(), eq("POST"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.postJson("http://127.0.0.1:8848/nacos/test", header, Query.EMPTY, "body", String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_JSON, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostForm() throws Exception {
|
||||
when(requestClient.execute(any(), eq("POST"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.postForm("http://127.0.0.1:8848/nacos/test", header, new HashMap<>(), String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostFormWithQuery() throws Exception {
|
||||
when(requestClient.execute(any(), eq("POST"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.postForm("http://127.0.0.1:8848/nacos/test", header, Query.EMPTY, new HashMap<>(), String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostFormWithConfig() throws Exception {
|
||||
when(requestClient.execute(any(), eq("POST"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpClientConfig config = HttpClientConfig.builder().setConTimeOutMillis(1000).build();
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.postForm("http://127.0.0.1:8848/nacos/test", config, header, new HashMap<>(), String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExchangeForm() throws Exception {
|
||||
when(requestClient.execute(any(), eq("PUT"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
Header header = Header.newInstance().setContentType(MediaType.APPLICATION_XML);
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.exchangeForm("http://127.0.0.1:8848/nacos/test", header, Query.EMPTY, new HashMap<>(), "PUT",
|
||||
String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExchange() throws Exception {
|
||||
when(requestClient.execute(any(), eq("PUT"), any())).thenReturn(mockResponse);
|
||||
when(mockResponse.getStatusCode()).thenReturn(200);
|
||||
when(mockResponse.getBody()).thenReturn(new ByteArrayInputStream("test".getBytes()));
|
||||
HttpClientConfig config = HttpClientConfig.builder().setConTimeOutMillis(1000).build();
|
||||
HttpRestResult<String> result = restTemplate
|
||||
.exchange("http://127.0.0.1:8848/nacos/test", config, Header.EMPTY, Query.EMPTY, new Object(), "PUT",
|
||||
String.class);
|
||||
assertTrue(result.ok());
|
||||
assertEquals(Header.EMPTY, result.getHeader());
|
||||
assertEquals("test", result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInterceptors() {
|
||||
assertTrue(restTemplate.getInterceptors().isEmpty());
|
||||
restTemplate.setInterceptors(Collections.singletonList(interceptor));
|
||||
assertEquals(1, restTemplate.getInterceptors().size());
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client.handler;
|
||||
|
||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||
import com.alibaba.nacos.common.http.client.response.HttpClientResponse;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class BeanResponseHandlerTest {
|
||||
|
||||
@Test
|
||||
public void testConvertResult() throws Exception {
|
||||
List<Integer> testCase = new LinkedList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
testCase.add(i);
|
||||
}
|
||||
byte[] bytes = JacksonUtils.toJsonBytes(testCase);
|
||||
InputStream inputStream = new ByteArrayInputStream(bytes);
|
||||
HttpClientResponse response = mock(HttpClientResponse.class);
|
||||
when(response.getBody()).thenReturn(inputStream);
|
||||
when(response.getHeaders()).thenReturn(Header.EMPTY);
|
||||
when(response.getStatusCode()).thenReturn(200);
|
||||
BeanResponseHandler<List<Integer>> beanResponseHandler = new BeanResponseHandler<>();
|
||||
beanResponseHandler.setResponseType(List.class);
|
||||
HttpRestResult<List<Integer>> actual = beanResponseHandler.handle(response);
|
||||
assertEquals(200, actual.getCode());
|
||||
assertEquals(testCase, actual.getData());
|
||||
assertNull(actual.getMessage());
|
||||
assertEquals(Header.EMPTY, actual.getHeader());
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client.handler;
|
||||
|
||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||
import com.alibaba.nacos.common.http.client.response.HttpClientResponse;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class RestResultResponseHandlerTest {
|
||||
|
||||
@Test
|
||||
public void testConvertResult() throws Exception {
|
||||
RestResult<String> testCase = RestResult.<String>builder().withCode(200).withData("ok").withMsg("msg").build();
|
||||
InputStream inputStream = new ByteArrayInputStream(JacksonUtils.toJsonBytes(testCase));
|
||||
HttpClientResponse response = mock(HttpClientResponse.class);
|
||||
when(response.getBody()).thenReturn(inputStream);
|
||||
when(response.getHeaders()).thenReturn(Header.EMPTY);
|
||||
when(response.getStatusCode()).thenReturn(200);
|
||||
RestResultResponseHandler<String> handler = new RestResultResponseHandler<>();
|
||||
handler.setResponseType(RestResult.class);
|
||||
HttpRestResult<String> actual = handler.handle(response);
|
||||
assertEquals(testCase.getCode(), actual.getCode());
|
||||
assertEquals(testCase.getData(), actual.getData());
|
||||
assertEquals(testCase.getMessage(), actual.getMessage());
|
||||
assertEquals(Header.EMPTY, actual.getHeader());
|
||||
}
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client.request;
|
||||
|
||||
import com.alibaba.nacos.common.http.Callback;
|
||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||
import com.alibaba.nacos.common.http.client.handler.ResponseHandler;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.concurrent.FutureCallback;
|
||||
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
|
||||
import org.apache.http.impl.nio.reactor.ExceptionEvent;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DefaultAsyncHttpClientRequestTest {
|
||||
|
||||
@Mock
|
||||
private CloseableHttpAsyncClient client;
|
||||
|
||||
@Mock
|
||||
private DefaultConnectingIOReactor ioReactor;
|
||||
|
||||
@Mock
|
||||
private Callback callback;
|
||||
|
||||
@Mock
|
||||
private ResponseHandler responseHandler;
|
||||
|
||||
private RequestConfig defaultConfig;
|
||||
|
||||
DefaultAsyncHttpClientRequest httpClientRequest;
|
||||
|
||||
private URI uri;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
defaultConfig = RequestConfig.DEFAULT;
|
||||
httpClientRequest = new DefaultAsyncHttpClientRequest(client, ioReactor, defaultConfig);
|
||||
uri = URI.create("http://127.0.0.1:8080");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
httpClientRequest.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteOnFail() throws Exception {
|
||||
Header header = Header.newInstance();
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("test", "test");
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(header, Query.EMPTY, body);
|
||||
RuntimeException exception = new RuntimeException("test");
|
||||
when(client.execute(any(), any())).thenAnswer(invocationOnMock -> {
|
||||
((FutureCallback) invocationOnMock.getArgument(1)).failed(exception);
|
||||
return null;
|
||||
});
|
||||
httpClientRequest.execute(uri, "PUT", httpEntity, responseHandler, callback);
|
||||
verify(callback).onError(exception);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteOnCancel() throws Exception {
|
||||
Header header = Header.newInstance();
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("test", "test");
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(header, Query.EMPTY, body);
|
||||
when(client.execute(any(), any())).thenAnswer(invocationOnMock -> {
|
||||
((FutureCallback) invocationOnMock.getArgument(1)).cancelled();
|
||||
return null;
|
||||
});
|
||||
httpClientRequest.execute(uri, "PUT", httpEntity, responseHandler, callback);
|
||||
verify(callback).onCancel();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteOnComplete() throws Exception {
|
||||
Header header = Header.newInstance();
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("test", "test");
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(header, Query.EMPTY, body);
|
||||
HttpResponse response = mock(HttpResponse.class);
|
||||
HttpRestResult restResult = new HttpRestResult();
|
||||
when(responseHandler.handle(any())).thenReturn(restResult);
|
||||
when(client.execute(any(), any())).thenAnswer(invocationOnMock -> {
|
||||
((FutureCallback) invocationOnMock.getArgument(1)).completed(response);
|
||||
return null;
|
||||
});
|
||||
httpClientRequest.execute(uri, "PUT", httpEntity, responseHandler, callback);
|
||||
verify(callback).onReceive(restResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteOnCompleteWithException() throws Exception {
|
||||
Header header = Header.newInstance();
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("test", "test");
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(header, Query.EMPTY, body);
|
||||
HttpResponse response = mock(HttpResponse.class);
|
||||
RuntimeException exception = new RuntimeException("test");
|
||||
when(responseHandler.handle(any())).thenThrow(exception);
|
||||
when(client.execute(any(), any())).thenAnswer(invocationOnMock -> {
|
||||
((FutureCallback) invocationOnMock.getArgument(1)).completed(response);
|
||||
return null;
|
||||
});
|
||||
httpClientRequest.execute(uri, "PUT", httpEntity, responseHandler, callback);
|
||||
verify(callback).onError(exception);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteException() throws Exception {
|
||||
Header header = Header.newInstance();
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("test", "test");
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(header, Query.EMPTY, body);
|
||||
IllegalStateException exception = new IllegalStateException("test");
|
||||
when(client.execute(any(), any())).thenThrow(exception);
|
||||
when(ioReactor.getAuditLog()).thenReturn(Collections.singletonList(new ExceptionEvent(exception, new Date())));
|
||||
try {
|
||||
httpClientRequest.execute(uri, "PUT", httpEntity, responseHandler, callback);
|
||||
} catch (Exception e) {
|
||||
assertEquals(exception, e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client.request;
|
||||
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||
import com.alibaba.nacos.common.http.client.response.HttpClientResponse;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.junit.After;
|
||||
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.Field;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DefaultHttpClientRequestTest {
|
||||
|
||||
@Mock
|
||||
private CloseableHttpClient client;
|
||||
|
||||
@Mock
|
||||
private CloseableHttpResponse response;
|
||||
|
||||
private RequestConfig defaultConfig;
|
||||
|
||||
DefaultHttpClientRequest httpClientRequest;
|
||||
|
||||
private boolean isForm;
|
||||
|
||||
private boolean withConfig;
|
||||
|
||||
private URI uri;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
defaultConfig = RequestConfig.DEFAULT;
|
||||
httpClientRequest = new DefaultHttpClientRequest(client, defaultConfig);
|
||||
when(client.execute(argThat(httpUriRequest -> {
|
||||
HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) httpUriRequest;
|
||||
boolean result = isForm == (entityRequest.getEntity() instanceof UrlEncodedFormEntity);
|
||||
HttpRequestBase baseHttpRequest = (HttpRequestBase) httpUriRequest;
|
||||
if (withConfig) {
|
||||
result &= null != baseHttpRequest.getConfig();
|
||||
}
|
||||
return result;
|
||||
}))).thenReturn(response);
|
||||
uri = URI.create("http://127.0.0.1:8080");
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
isForm = false;
|
||||
withConfig = false;
|
||||
httpClientRequest.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteForFormWithoutConfig() throws Exception {
|
||||
isForm = true;
|
||||
Header header = Header.newInstance()
|
||||
.addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED);
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("test", "test");
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(header, Query.EMPTY, body);
|
||||
HttpClientResponse actual = httpClientRequest.execute(uri, "PUT", httpEntity);
|
||||
assertEquals(response, getActualResponse(actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteForFormWithConfig() throws Exception {
|
||||
isForm = true;
|
||||
withConfig = true;
|
||||
Header header = Header.newInstance()
|
||||
.addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED);
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("test", "test");
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(HttpClientConfig.builder().build(), header, Query.EMPTY,
|
||||
body);
|
||||
HttpClientResponse actual = httpClientRequest.execute(uri, "PUT", httpEntity);
|
||||
assertEquals(response, getActualResponse(actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteForOther() throws Exception {
|
||||
Header header = Header.newInstance();
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(header, Query.EMPTY, "body");
|
||||
HttpClientResponse actual = httpClientRequest.execute(uri, "PUT", httpEntity);
|
||||
assertEquals(response, getActualResponse(actual));
|
||||
}
|
||||
|
||||
private CloseableHttpResponse getActualResponse(HttpClientResponse actual)
|
||||
throws IllegalAccessException, NoSuchFieldException {
|
||||
Field field = actual.getClass().getDeclaredField("response");
|
||||
field.setAccessible(true);
|
||||
return (CloseableHttpResponse) field.get(actual);
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client.request;
|
||||
|
||||
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||
import com.alibaba.nacos.common.http.HttpUtils;
|
||||
import com.alibaba.nacos.common.http.client.response.HttpClientResponse;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class JdkHttpClientRequestTest {
|
||||
|
||||
@Mock
|
||||
private HttpURLConnection connection;
|
||||
|
||||
@Mock
|
||||
private URI uri;
|
||||
|
||||
@Mock
|
||||
private URL url;
|
||||
|
||||
@Mock
|
||||
private OutputStream outputStream;
|
||||
|
||||
JdkHttpClientRequest httpClientRequest;
|
||||
|
||||
private HttpClientConfig httpClientConfig;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
when(uri.toURL()).thenReturn(url);
|
||||
when(url.openConnection()).thenReturn(connection);
|
||||
when(connection.getOutputStream()).thenReturn(outputStream);
|
||||
httpClientConfig = HttpClientConfig.builder().build();
|
||||
httpClientRequest = new JdkHttpClientRequest(httpClientConfig);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
httpClientRequest.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteNormal() throws Exception {
|
||||
Header header = Header.newInstance();
|
||||
HttpClientConfig config = HttpClientConfig.builder().build();
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(config, header, Query.EMPTY, "a=bo&dy");
|
||||
HttpClientResponse response = httpClientRequest.execute(uri, "GET", httpEntity);
|
||||
byte[] writeBytes = "a=bo&dy".getBytes(StandardCharsets.UTF_8);
|
||||
verify(outputStream).write(writeBytes, 0, writeBytes.length);
|
||||
assertEquals(connection, getActualConnection(response));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteForm() throws Exception {
|
||||
Header header = Header.newInstance();
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
HttpClientConfig config = HttpClientConfig.builder().build();
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("a", "bo&dy");
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(config, header, Query.EMPTY, body);
|
||||
HttpClientResponse response = httpClientRequest.execute(uri, "GET", httpEntity);
|
||||
byte[] writeBytes = HttpUtils.encodingParams(body, StandardCharsets.UTF_8.name())
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
verify(outputStream).write(writeBytes, 0, writeBytes.length);
|
||||
assertEquals(connection, getActualConnection(response));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteEmptyBody() throws Exception {
|
||||
Header header = Header.newInstance();
|
||||
RequestHttpEntity httpEntity = new RequestHttpEntity(header, Query.EMPTY);
|
||||
HttpClientResponse response = httpClientRequest.execute(uri, "GET", httpEntity);
|
||||
verify(outputStream, never()).write(any(), eq(0), anyInt());
|
||||
assertEquals(connection, getActualConnection(response));
|
||||
|
||||
}
|
||||
|
||||
private HttpURLConnection getActualConnection(HttpClientResponse actual)
|
||||
throws IllegalAccessException, NoSuchFieldException {
|
||||
Field field = actual.getClass().getDeclaredField("conn");
|
||||
field.setAccessible(true);
|
||||
return (HttpURLConnection) field.get(actual);
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client.response;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DefaultClientHttpResponseTest {
|
||||
|
||||
@Mock
|
||||
private HttpResponse response;
|
||||
|
||||
@Mock
|
||||
private StatusLine statusLine;
|
||||
|
||||
@Mock
|
||||
private HttpEntity httpEntity;
|
||||
|
||||
@Mock
|
||||
private InputStream inputStream;
|
||||
|
||||
@Mock
|
||||
private Header header;
|
||||
|
||||
DefaultClientHttpResponse clientHttpResponse;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
when(httpEntity.getContent()).thenReturn(inputStream);
|
||||
when(response.getEntity()).thenReturn(httpEntity);
|
||||
when(response.getStatusLine()).thenReturn(statusLine);
|
||||
when(response.getAllHeaders()).thenReturn(new Header[] {header});
|
||||
when(header.getName()).thenReturn("testName");
|
||||
when(header.getValue()).thenReturn("testValue");
|
||||
clientHttpResponse = new DefaultClientHttpResponse(response);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
clientHttpResponse.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStatusCode() {
|
||||
when(statusLine.getStatusCode()).thenReturn(200);
|
||||
assertEquals(200, clientHttpResponse.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStatusText() {
|
||||
when(statusLine.getReasonPhrase()).thenReturn("test");
|
||||
assertEquals("test", clientHttpResponse.getStatusText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHeaders() {
|
||||
assertEquals(3, clientHttpResponse.getHeaders().getHeader().size());
|
||||
assertEquals("testValue", clientHttpResponse.getHeaders().getValue("testName"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBody() throws IOException {
|
||||
assertEquals(inputStream, clientHttpResponse.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseResponseWithException() {
|
||||
when(response.getEntity()).thenThrow(new RuntimeException("test"));
|
||||
clientHttpResponse.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client.response;
|
||||
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class JdkClientHttpResponseTest {
|
||||
|
||||
@Mock
|
||||
private HttpURLConnection connection;
|
||||
|
||||
@Mock
|
||||
private InputStream inputStream;
|
||||
|
||||
private Map<String, List<String>> headers;
|
||||
|
||||
JdkHttpClientResponse clientHttpResponse;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
headers = new HashMap<>();
|
||||
headers.put("testName", Collections.singletonList("testValue"));
|
||||
when(connection.getHeaderFields()).thenReturn(headers);
|
||||
clientHttpResponse = new JdkHttpClientResponse(connection);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
clientHttpResponse.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStatusCode() throws IOException {
|
||||
when(connection.getResponseCode()).thenReturn(200);
|
||||
assertEquals(200, clientHttpResponse.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStatusText() throws IOException {
|
||||
when(connection.getResponseMessage()).thenReturn("test");
|
||||
assertEquals("test", clientHttpResponse.getStatusText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHeaders() {
|
||||
assertEquals(3, clientHttpResponse.getHeaders().getHeader().size());
|
||||
assertEquals("testValue", clientHttpResponse.getHeaders().getValue("testName"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBody() throws IOException {
|
||||
when(connection.getInputStream()).thenReturn(inputStream);
|
||||
assertEquals(inputStream, clientHttpResponse.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBodyWithGzip() throws IOException {
|
||||
byte[] testCase = IoUtils.tryCompress("test", StandardCharsets.UTF_8.name());
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(testCase);
|
||||
when(connection.getInputStream()).thenReturn(byteArrayInputStream);
|
||||
headers.put(HttpHeaderConsts.CONTENT_ENCODING, Collections.singletonList("gzip"));
|
||||
assertEquals("test", IoUtils.toString(clientHttpResponse.getBody(), StandardCharsets.UTF_8.name()));
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.handler;
|
||||
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.TypeUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ResponseHandlerTest {
|
||||
|
||||
private final ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
|
||||
@Test
|
||||
public void testDeserializationType() throws Exception {
|
||||
String json = JacksonUtils.toJson(list);
|
||||
ArrayList<Integer> tmp = ResponseHandler.convert(json, TypeUtils.parameterize(List.class, Integer.class));
|
||||
Assert.assertEquals(list, tmp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestResult() throws Exception {
|
||||
String json = "{\"code\":200,\"message\":null,\"data\":[{\"USERNAME\":\"nacos\",\"PASSWORD\":"
|
||||
+ "\"$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu\",\"ENABLED\":true}]}";
|
||||
RestResult<Object> result = ResponseHandler.convert(json, TypeUtils.parameterize(RestResult.class, Object.class));
|
||||
Assert.assertEquals(200, result.getCode());
|
||||
Assert.assertNull(result.getMessage());
|
||||
Assert.assertNotNull(result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializationClass() throws Exception {
|
||||
String json = JacksonUtils.toJson(list);
|
||||
ArrayList<Integer> tmp = ResponseHandler.convert(json, TypeUtils.parameterize(List.class, Integer.class));
|
||||
Assert.assertEquals(list, tmp);
|
||||
}
|
||||
}
|
@ -16,16 +16,122 @@
|
||||
|
||||
package com.alibaba.nacos.common.http.param;
|
||||
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class HeaderTest {
|
||||
|
||||
@Test
|
||||
public void testSetContentType() {
|
||||
Header header = Header.newInstance();
|
||||
header.setContentType(null);
|
||||
assertEquals(MediaType.APPLICATION_JSON, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
header.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
assertEquals(MediaType.MULTIPART_FORM_DATA, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeaderKyeIgnoreCase() {
|
||||
Header header = Header.newInstance();
|
||||
header.addParam("Content-Encoding", "gzip");
|
||||
assertEquals("gzip", header.getValue("content-encoding"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToList() {
|
||||
Header header = Header.newInstance();
|
||||
List<String> list = header.toList();
|
||||
assertTrue(list.contains(HttpHeaderConsts.CONTENT_TYPE));
|
||||
assertTrue(list.contains(MediaType.APPLICATION_JSON));
|
||||
assertEquals(1, list.indexOf(MediaType.APPLICATION_JSON) - list.indexOf(HttpHeaderConsts.CONTENT_TYPE));
|
||||
assertTrue(list.contains(HttpHeaderConsts.ACCEPT_CHARSET));
|
||||
assertTrue(list.contains("UTF-8"));
|
||||
assertEquals(1, list.indexOf("UTF-8") - list.indexOf(HttpHeaderConsts.ACCEPT_CHARSET));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAllForMap() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("test1", "test2");
|
||||
map.put("test3", "test4");
|
||||
Header header = Header.newInstance();
|
||||
header.addAll(map);
|
||||
assertEquals("test2", header.getValue("test1"));
|
||||
assertEquals("test4", header.getValue("test3"));
|
||||
assertEquals(4, header.getHeader().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAllForList() {
|
||||
List<String> list = new ArrayList<>(4);
|
||||
list.add("test1");
|
||||
list.add("test2");
|
||||
list.add("test3");
|
||||
list.add("test4");
|
||||
Header header = Header.newInstance();
|
||||
header.addAll(list);
|
||||
assertEquals("test2", header.getValue("test1"));
|
||||
assertEquals("test4", header.getValue("test3"));
|
||||
assertEquals(4, header.getHeader().size());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAddAllForListWithWrongLength() {
|
||||
List<String> list = new ArrayList<>(3);
|
||||
list.add("test1");
|
||||
list.add("test2");
|
||||
list.add("test3");
|
||||
Header header = Header.newInstance();
|
||||
header.addAll(list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddOriginalResponseHeader() {
|
||||
List<String> list = new ArrayList<>(4);
|
||||
list.add("test1");
|
||||
list.add("test2");
|
||||
list.add("test3");
|
||||
list.add("test4");
|
||||
Header header = Header.newInstance();
|
||||
header.addOriginalResponseHeader("test", list);
|
||||
assertEquals("test1", header.getValue("test"));
|
||||
assertEquals(1, header.getOriginalResponseHeader().size());
|
||||
assertEquals(list, header.getOriginalResponseHeader().get("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCharset() {
|
||||
Header header = Header.newInstance();
|
||||
assertEquals("UTF-8", header.getCharset());
|
||||
header.addParam(HttpHeaderConsts.ACCEPT_CHARSET, null);
|
||||
header.setContentType(MediaType.APPLICATION_JSON);
|
||||
assertEquals("UTF-8", header.getCharset());
|
||||
header.setContentType("application/json;charset=GBK");
|
||||
assertEquals("GBK", header.getCharset());
|
||||
header.setContentType("application/json");
|
||||
assertEquals("UTF-8", header.getCharset());
|
||||
header.setContentType("");
|
||||
assertEquals("UTF-8", header.getCharset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear() {
|
||||
Header header = Header.newInstance();
|
||||
header.addOriginalResponseHeader("test", Collections.singletonList("test"));
|
||||
assertEquals(3, header.getHeader().size());
|
||||
assertEquals(1, header.getOriginalResponseHeader().size());
|
||||
header.clear();
|
||||
assertEquals(0, header.getHeader().size());
|
||||
assertEquals(0, header.getOriginalResponseHeader().size());
|
||||
assertEquals("Header{headerToMap={}}", header.toString());
|
||||
}
|
||||
}
|
||||
|
@ -59,4 +59,13 @@ public class MediaTypeTest {
|
||||
assertEquals(excepted, mediaType.toString());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValueOfWithEmpty() {
|
||||
MediaType.valueOf("");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testValueOfWithEmpty2() {
|
||||
MediaType.valueOf("", "UTF-8");
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
package com.alibaba.nacos.common.http.param;
|
||||
|
||||
import com.alibaba.nacos.api.naming.CommonParams;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
@ -26,11 +25,13 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class QueryTest {
|
||||
|
||||
@Test
|
||||
public void testToQueryUrl() {
|
||||
public void testInitParams() {
|
||||
Map<String, String> parameters = new LinkedHashMap<String, String>();
|
||||
parameters.put(CommonParams.NAMESPACE_ID, "namespace");
|
||||
parameters.put(CommonParams.SERVICE_NAME, "service");
|
||||
@ -41,16 +42,27 @@ public class QueryTest {
|
||||
parameters.put("weight", String.valueOf(1.0));
|
||||
parameters.put("ephemeral", String.valueOf(true));
|
||||
String excepted = "namespaceId=namespace&serviceName=service&groupName=group&ip=1.1.1.1&port=9999&weight=1.0&ephemeral=true";
|
||||
assertEquals(excepted, Query.newInstance().initParams(parameters).toQueryUrl());
|
||||
Query actual = Query.newInstance().initParams(parameters);
|
||||
assertEquals(excepted, actual.toQueryUrl());
|
||||
assertEquals("namespace", actual.getValue(CommonParams.NAMESPACE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToQueryUrl2() throws Exception {
|
||||
Query query = Query.newInstance().addParam("key-1", "value-1")
|
||||
.addParam("key-2", "value-2");
|
||||
public void testAddParams() throws Exception {
|
||||
Query query = Query.newInstance().addParam("key-1", "value-1").addParam("key-2", "value-2");
|
||||
String s1 = query.toQueryUrl();
|
||||
String s2 = "key-1=" + URLEncoder.encode("value-1", StandardCharsets.UTF_8.name())
|
||||
+ "&key-2=" + URLEncoder.encode("value-2", StandardCharsets.UTF_8.name());
|
||||
Assert.assertEquals(s1, s2);
|
||||
String s2 = "key-1=" + URLEncoder.encode("value-1", StandardCharsets.UTF_8.name()) + "&key-2=" + URLEncoder
|
||||
.encode("value-2", StandardCharsets.UTF_8.name());
|
||||
assertEquals(s2, s1);
|
||||
assertEquals("value-1", query.getValue("key-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear() {
|
||||
Query query = Query.newInstance().addParam("key-1", "value-1").addParam("key-2", "value-2");
|
||||
assertFalse(query.isEmpty());
|
||||
assertEquals("value-1", query.getValue("key-1"));
|
||||
query.clear();
|
||||
assertTrue(query.isEmpty());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.remote;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class ConnectionTypeTest {
|
||||
|
||||
@Test
|
||||
public void testGetByType() {
|
||||
ConnectionType connectionType = ConnectionType.getByType("GRPC");
|
||||
assertNotNull(connectionType);
|
||||
assertEquals("GRPC", connectionType.getType());
|
||||
assertEquals("Grpc Connection", connectionType.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetByNonExistType() {
|
||||
ConnectionType connectionType = ConnectionType.getByType("HTTP");
|
||||
assertNull(connectionType);
|
||||
}
|
||||
}
|
@ -16,24 +16,28 @@
|
||||
|
||||
package com.alibaba.nacos.common.remote;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Assert;
|
||||
import com.alibaba.nacos.api.remote.request.Request;
|
||||
import com.alibaba.nacos.api.remote.response.ErrorResponse;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PayloadRegistryTest extends TestCase {
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class PayloadRegistryTest {
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
@BeforeClass
|
||||
public static void setUpBefore() {
|
||||
PayloadRegistry.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInit() {
|
||||
PayloadRegistry.init();
|
||||
Assert.assertNotNull(PayloadRegistry.getClassByType("NotifySubscriberResponse"));
|
||||
Assert.assertNotNull(PayloadRegistry.getClassByType("InstanceRequest"));
|
||||
public void testRegisterInvalidClass() {
|
||||
PayloadRegistry.register("test", Request.class);
|
||||
assertNull(PayloadRegistry.getClassByType("test"));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testRegisterDuplicated() {
|
||||
PayloadRegistry.register("ErrorResponse", ErrorResponse.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.remote;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TlsConfigTest {
|
||||
|
||||
@Test
|
||||
public void testTlsConfig() {
|
||||
TlsConfig tlsConfig = new TlsConfig();
|
||||
assertFalse(tlsConfig.getEnableTls());
|
||||
assertFalse(tlsConfig.getMutualAuthEnable());
|
||||
assertNull(tlsConfig.getProtocols());
|
||||
assertNull(tlsConfig.getCiphers());
|
||||
assertFalse(tlsConfig.getTrustAll());
|
||||
assertNull(tlsConfig.getTrustCollectionCertFile());
|
||||
assertNull(tlsConfig.getCertPrivateKeyPassword());
|
||||
assertNull(tlsConfig.getCertPrivateKey());
|
||||
assertNull(tlsConfig.getCertChainFile());
|
||||
assertEquals("", tlsConfig.getSslProvider());
|
||||
|
||||
// Set values
|
||||
tlsConfig.setEnableTls(true);
|
||||
tlsConfig.setMutualAuthEnable(true);
|
||||
tlsConfig.setProtocols("TLSv1.1,TLSv1.2,TLSv1.3");
|
||||
tlsConfig.setCiphers("cipher1,cipher2");
|
||||
tlsConfig.setTrustAll(true);
|
||||
tlsConfig.setTrustCollectionCertFile("certFile");
|
||||
tlsConfig.setCertPrivateKeyPassword("password");
|
||||
tlsConfig.setCertPrivateKey("privateKey");
|
||||
tlsConfig.setCertChainFile("chainFile");
|
||||
tlsConfig.setSslProvider("OPENSSL");
|
||||
|
||||
// Test values
|
||||
assertTrue(tlsConfig.getEnableTls());
|
||||
assertTrue(tlsConfig.getMutualAuthEnable());
|
||||
assertEquals("TLSv1.1,TLSv1.2,TLSv1.3", tlsConfig.getProtocols());
|
||||
assertEquals("cipher1,cipher2", tlsConfig.getCiphers());
|
||||
assertTrue(tlsConfig.getTrustAll());
|
||||
assertEquals("certFile", tlsConfig.getTrustCollectionCertFile());
|
||||
assertEquals("password", tlsConfig.getCertPrivateKeyPassword());
|
||||
assertEquals("privateKey", tlsConfig.getCertPrivateKey());
|
||||
assertEquals("chainFile", tlsConfig.getCertChainFile());
|
||||
assertEquals("OPENSSL", tlsConfig.getSslProvider());
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.remote.client;
|
||||
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityKey;
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityStatus;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.remote.RequestCallBack;
|
||||
import com.alibaba.nacos.api.remote.RequestFuture;
|
||||
import com.alibaba.nacos.api.remote.request.Request;
|
||||
import com.alibaba.nacos.api.remote.response.Response;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ConnectionTest {
|
||||
|
||||
Connection connection;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
connection = new Connection(new RpcClient.ServerInfo("127.0.0.1", 8848)) {
|
||||
@Override
|
||||
public Response request(Request request, long timeoutMills) throws NacosException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestFuture requestFuture(Request request) throws NacosException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void asyncRequest(Request request, RequestCallBack requestCallBack) throws NacosException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetConnectionId() {
|
||||
assertNull(connection.getConnectionId());
|
||||
connection.setConnectionId("testConnectionId");
|
||||
assertEquals("testConnectionId", connection.getConnectionId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConnectionAbility() {
|
||||
assertFalse(connection.isAbilitiesSet());
|
||||
assertEquals(AbilityStatus.UNKNOWN, connection.getConnectionAbility(AbilityKey.SDK_CLIENT_TEST_1));
|
||||
connection.setAbilityTable(Collections.singletonMap(AbilityKey.SERVER_TEST_2.getName(), true));
|
||||
assertTrue(connection.isAbilitiesSet());
|
||||
assertEquals(AbilityStatus.UNKNOWN, connection.getConnectionAbility(AbilityKey.SDK_CLIENT_TEST_1));
|
||||
assertEquals(AbilityStatus.SUPPORTED, connection.getConnectionAbility(AbilityKey.SERVER_TEST_2));
|
||||
connection.setAbilityTable(Collections.singletonMap(AbilityKey.SERVER_TEST_2.getName(), false));
|
||||
assertEquals(AbilityStatus.NOT_SUPPORTED, connection.getConnectionAbility(AbilityKey.SERVER_TEST_2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetAbandon() {
|
||||
assertFalse(connection.isAbandon());
|
||||
connection.setAbandon(true);
|
||||
assertTrue(connection.isAbandon());
|
||||
}
|
||||
}
|
@ -16,10 +16,19 @@
|
||||
|
||||
package com.alibaba.nacos.common.remote.client;
|
||||
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityKey;
|
||||
import com.alibaba.nacos.api.ability.constant.AbilityStatus;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.remote.RequestCallBack;
|
||||
import com.alibaba.nacos.api.remote.request.ClientDetectionRequest;
|
||||
import com.alibaba.nacos.api.remote.request.ConnectResetRequest;
|
||||
import com.alibaba.nacos.api.remote.request.HealthCheckRequest;
|
||||
import com.alibaba.nacos.api.remote.request.Request;
|
||||
import com.alibaba.nacos.api.remote.response.ClientDetectionResponse;
|
||||
import com.alibaba.nacos.api.remote.response.ConnectResetResponse;
|
||||
import com.alibaba.nacos.api.remote.response.ErrorResponse;
|
||||
import com.alibaba.nacos.api.remote.response.HealthCheckResponse;
|
||||
import com.alibaba.nacos.api.remote.response.Response;
|
||||
import com.alibaba.nacos.common.remote.ConnectionType;
|
||||
import com.alibaba.nacos.common.remote.client.grpc.DefaultGrpcClientConfig;
|
||||
import com.alibaba.nacos.common.remote.client.grpc.GrpcConnection;
|
||||
@ -38,17 +47,28 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@ -159,7 +179,7 @@ public class RpcClientTest {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws IllegalAccessException {
|
||||
public void tearDown() throws IllegalAccessException, NacosException {
|
||||
rpcClientConfig.labels().clear();
|
||||
rpcClient.rpcClientStatus.set(RpcClientStatus.WAIT_INIT);
|
||||
serverListFactoryField.set(rpcClient, null);
|
||||
@ -167,6 +187,7 @@ public class RpcClientTest {
|
||||
rpcClient.currentConnection = null;
|
||||
System.clearProperty("nacos.server.port");
|
||||
rpcClient.eventLinkedBlockingQueue.clear();
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -263,6 +284,7 @@ public class RpcClientTest {
|
||||
map.put("labelKey2", "labelValue2");
|
||||
when(rpcClientConfig.labels()).thenReturn(map);
|
||||
assertEquals(1, rpcClient.getLabels().size());
|
||||
assertEquals("test", rpcClient.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -319,14 +341,17 @@ public class RpcClientTest {
|
||||
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "10.10.10.10::8848")).getAddress());
|
||||
assertEquals("10.10.10.10:8848",
|
||||
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "10.10.10.10:8848")).getAddress());
|
||||
assertEquals("10.10.10.10:8848", ((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient,
|
||||
"http://10.10.10.10:8848")).getAddress());
|
||||
assertEquals("10.10.10.10:8848", ((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient,
|
||||
"http://10.10.10.10::8848")).getAddress());
|
||||
assertEquals("10.10.10.10:8848",
|
||||
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "http://10.10.10.10:8848"))
|
||||
.getAddress());
|
||||
assertEquals("10.10.10.10:8848",
|
||||
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "http://10.10.10.10::8848"))
|
||||
.getAddress());
|
||||
assertEquals("10.10.10.10:8848",
|
||||
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "http://10.10.10.10")).getAddress());
|
||||
assertEquals("10.10.10.10:8848", ((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient,
|
||||
"https://10.10.10.10::8848")).getAddress());
|
||||
assertEquals("10.10.10.10:8848",
|
||||
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "https://10.10.10.10::8848"))
|
||||
.getAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -336,11 +361,30 @@ public class RpcClientTest {
|
||||
((RpcClient.ServerInfo) resolveServerInfoMethod.invoke(rpcClient, "http://10.10.10.10")).getAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestSuccess() throws NacosException, NoSuchFieldException, IllegalAccessException {
|
||||
rpcClient.currentConnection = connection;
|
||||
rpcClient.rpcClientStatus.set(RpcClientStatus.RUNNING);
|
||||
when(connection.request(any(), anyLong())).thenReturn(new HealthCheckResponse());
|
||||
Field lastActiveTimeStampField = RpcClient.class.getDeclaredField("lastActiveTimeStamp");
|
||||
lastActiveTimeStampField.setAccessible(true);
|
||||
final long lastActiveTimeStamp = (long) lastActiveTimeStampField.get(rpcClient);
|
||||
Response response = rpcClient.request(new HealthCheckRequest());
|
||||
assertTrue(response instanceof HealthCheckResponse);
|
||||
assertTrue(lastActiveTimeStamp <= (long) lastActiveTimeStampField.get(rpcClient));
|
||||
}
|
||||
|
||||
@Test(expected = NacosException.class)
|
||||
public void testRequestWithoutAnyTry() throws NacosException {
|
||||
when(rpcClientConfig.retryTimes()).thenReturn(-1);
|
||||
rpcClient.request(null);
|
||||
}
|
||||
|
||||
@Test(expected = NacosException.class)
|
||||
public void testRequestWhenClientAlreadyShutDownThenThrowException() throws NacosException {
|
||||
rpcClient.rpcClientStatus.set(RpcClientStatus.SHUTDOWN);
|
||||
rpcClient.currentConnection = connection;
|
||||
rpcClient.request(null, 10000);
|
||||
rpcClient.request(null);
|
||||
}
|
||||
|
||||
@Test(expected = NacosException.class)
|
||||
@ -348,7 +392,6 @@ public class RpcClientTest {
|
||||
rpcClient.rpcClientStatus.set(RpcClientStatus.RUNNING);
|
||||
rpcClient.currentConnection = connection;
|
||||
doReturn(null).when(connection).request(any(), anyLong());
|
||||
|
||||
rpcClient.request(null, 10000);
|
||||
}
|
||||
|
||||
@ -357,7 +400,6 @@ public class RpcClientTest {
|
||||
rpcClient.rpcClientStatus.set(RpcClientStatus.RUNNING);
|
||||
rpcClient.currentConnection = connection;
|
||||
doReturn(new ErrorResponse()).when(connection).request(any(), anyLong());
|
||||
|
||||
rpcClient.request(null, 10000);
|
||||
}
|
||||
|
||||
@ -381,6 +423,22 @@ public class RpcClientTest {
|
||||
Assert.assertNotNull(exception);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncRequestSuccess() throws NacosException {
|
||||
rpcClient.currentConnection = connection;
|
||||
rpcClient.rpcClientStatus.set(RpcClientStatus.RUNNING);
|
||||
RequestCallBack<?> requestCallBack = mock(RequestCallBack.class);
|
||||
when(requestCallBack.getTimeout()).thenReturn(1000L);
|
||||
rpcClient.asyncRequest(null, requestCallBack);
|
||||
verify(connection).asyncRequest(any(), any());
|
||||
}
|
||||
|
||||
@Test(expected = NacosException.class)
|
||||
public void testAsyncRequestWithoutAnyTry() throws NacosException {
|
||||
when(rpcClientConfig.retryTimes()).thenReturn(-1);
|
||||
rpcClient.asyncRequest(null, null);
|
||||
}
|
||||
|
||||
@Test(expected = NacosException.class)
|
||||
public void testAsyncRequestWhenClientAlreadyShutDownThenThrowException() throws NacosException {
|
||||
rpcClient.rpcClientStatus.set(RpcClientStatus.SHUTDOWN);
|
||||
@ -411,6 +469,12 @@ public class RpcClientTest {
|
||||
assertEquals(RpcClientStatus.UNHEALTHY, rpcClient.rpcClientStatus.get());
|
||||
}
|
||||
|
||||
@Test(expected = NacosException.class)
|
||||
public void testRequestFutureWithoutAnyTry() throws NacosException {
|
||||
when(rpcClientConfig.retryTimes()).thenReturn(-1);
|
||||
rpcClient.requestFuture(null);
|
||||
}
|
||||
|
||||
@Test(expected = NacosException.class)
|
||||
public void testRequestFutureWhenClientAlreadyShutDownThenThrowException() throws NacosException {
|
||||
rpcClient.rpcClientStatus.set(RpcClientStatus.SHUTDOWN);
|
||||
@ -419,8 +483,7 @@ public class RpcClientTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestFutureWhenRetryReachMaxRetryTimesThenSwitchServer()
|
||||
throws NacosException, IllegalAccessException {
|
||||
public void testRequestFutureWhenRetryReachMaxRetryTimesThenSwitchServer() throws NacosException {
|
||||
when(rpcClientConfig.timeOutMills()).thenReturn(5000L);
|
||||
when(rpcClientConfig.retryTimes()).thenReturn(3);
|
||||
rpcClient.rpcClientStatus.set(RpcClientStatus.RUNNING);
|
||||
@ -489,12 +552,13 @@ public class RpcClientTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection connectToServer(ServerInfo serverInfo) throws Exception {
|
||||
public Connection connectToServer(ServerInfo serverInfo) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
rpcClient.shutdown();
|
||||
assertTrue(rpcClient.isShutdown());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -622,7 +686,7 @@ public class RpcClientTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection connectToServer(ServerInfo serverInfo) throws Exception {
|
||||
public Connection connectToServer(ServerInfo serverInfo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -647,4 +711,435 @@ public class RpcClientTest {
|
||||
});
|
||||
rpcClient.handleServerRequest(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyDisConnectedForEmpty() {
|
||||
rpcClient.notifyDisConnected(null);
|
||||
verify(rpcClientConfig, never()).name();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyDisConnected() {
|
||||
ConnectionEventListener listener = mock(ConnectionEventListener.class);
|
||||
rpcClient.registerConnectionListener(listener);
|
||||
rpcClient.notifyDisConnected(null);
|
||||
verify(listener).onDisConnect(null);
|
||||
verify(rpcClientConfig, times(2)).name();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyDisConnectedException() {
|
||||
ConnectionEventListener listener = mock(ConnectionEventListener.class);
|
||||
rpcClient.registerConnectionListener(listener);
|
||||
doThrow(new RuntimeException("test")).when(listener).onDisConnect(null);
|
||||
rpcClient.notifyDisConnected(null);
|
||||
verify(rpcClientConfig, times(3)).name();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyConnectedForEmpty() {
|
||||
rpcClient.notifyConnected(null);
|
||||
verify(rpcClientConfig, never()).name();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyConnected() {
|
||||
ConnectionEventListener listener = mock(ConnectionEventListener.class);
|
||||
rpcClient.registerConnectionListener(listener);
|
||||
rpcClient.notifyConnected(null);
|
||||
verify(listener).onConnected(null);
|
||||
verify(rpcClientConfig, times(2)).name();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyConnectedException() {
|
||||
ConnectionEventListener listener = mock(ConnectionEventListener.class);
|
||||
rpcClient.registerConnectionListener(listener);
|
||||
doThrow(new RuntimeException("test")).when(listener).onConnected(null);
|
||||
rpcClient.notifyConnected(null);
|
||||
verify(rpcClientConfig, times(3)).name();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartClient() throws NacosException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848");
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(new Function<RpcClient.ServerInfo, Connection>() {
|
||||
|
||||
private int count;
|
||||
|
||||
@Override
|
||||
public Connection apply(RpcClient.ServerInfo serverInfo) {
|
||||
if (count == 0) {
|
||||
count++;
|
||||
throw new RuntimeException("test");
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
});
|
||||
try {
|
||||
rpcClient.start();
|
||||
assertTrue(rpcClient.isRunning());
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartClientWithFailed() throws NacosException, InterruptedException {
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> null);
|
||||
try {
|
||||
rpcClient.start();
|
||||
TimeUnit.MILLISECONDS.sleep(1000);
|
||||
assertFalse(rpcClient.isRunning());
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartClientAfterShutdown() throws NacosException {
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> null);
|
||||
rpcClient.shutdown();
|
||||
rpcClient.start();
|
||||
assertTrue(rpcClient.isShutdown());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisConnectionEventAfterStart() throws NacosException, InterruptedException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848");
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> connection);
|
||||
ConnectionEventListener listener = mock(ConnectionEventListener.class);
|
||||
rpcClient.registerConnectionListener(listener);
|
||||
try {
|
||||
rpcClient.start();
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
rpcClient.eventLinkedBlockingQueue.put(new RpcClient.ConnectionEvent(0, connection));
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
verify(listener).onDisConnect(connection);
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconnectContextAfterStartWithNullConnection() throws NacosException, InterruptedException {
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> null);
|
||||
try {
|
||||
when(rpcClientConfig.connectionKeepAlive()).thenReturn(-1L);
|
||||
rpcClient.start();
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
verify(rpcClientConfig, never()).healthCheckRetryTimes();
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconnectContextAfterStartWithConnectionHealthCheckFail()
|
||||
throws NacosException, InterruptedException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848");
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(new Function<RpcClient.ServerInfo, Connection>() {
|
||||
|
||||
private int count;
|
||||
|
||||
@Override
|
||||
public Connection apply(RpcClient.ServerInfo serverInfo) {
|
||||
if (count == 0) {
|
||||
count++;
|
||||
return connection;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
try {
|
||||
when(rpcClientConfig.connectionKeepAlive()).thenReturn(10L);
|
||||
rpcClient.start();
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
assertEquals(RpcClientStatus.UNHEALTHY, rpcClient.rpcClientStatus.get());
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconnectContextAfterStartWithConnectionHealthCheckSuccess()
|
||||
throws NacosException, InterruptedException, NoSuchFieldException, IllegalAccessException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848");
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> connection);
|
||||
when(connection.request(any(Request.class), anyLong())).thenReturn(new HealthCheckResponse());
|
||||
try {
|
||||
Field lastActiveTimeStampField = RpcClient.class.getDeclaredField("lastActiveTimeStamp");
|
||||
lastActiveTimeStampField.setAccessible(true);
|
||||
final long lastActiveTimeStamp = (long) lastActiveTimeStampField.get(rpcClient);
|
||||
when(rpcClientConfig.connectionKeepAlive()).thenReturn(10L);
|
||||
rpcClient.start();
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
assertEquals(RpcClientStatus.RUNNING, rpcClient.rpcClientStatus.get());
|
||||
long newLastActiveTimeStamp = (long) lastActiveTimeStampField.get(rpcClient);
|
||||
assertTrue(newLastActiveTimeStamp > lastActiveTimeStamp);
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconnectContextAfterStartWithActiveTimeIsNew()
|
||||
throws NacosException, InterruptedException, NoSuchFieldException, IllegalAccessException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848");
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> connection);
|
||||
try {
|
||||
Field lastActiveTimeStampField = RpcClient.class.getDeclaredField("lastActiveTimeStamp");
|
||||
lastActiveTimeStampField.setAccessible(true);
|
||||
long setTime = System.currentTimeMillis() + 10000;
|
||||
lastActiveTimeStampField.set(rpcClient, setTime);
|
||||
when(rpcClientConfig.connectionKeepAlive()).thenReturn(10L);
|
||||
rpcClient.start();
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
assertEquals(RpcClientStatus.RUNNING, rpcClient.rpcClientStatus.get());
|
||||
long newLastActiveTimeStamp = (long) lastActiveTimeStampField.get(rpcClient);
|
||||
assertEquals(setTime, newLastActiveTimeStamp);
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconnectContextAfterStartWithOldServiceInfo()
|
||||
throws NacosException, InterruptedException, IllegalAccessException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848");
|
||||
when(serverListFactory.getServerList()).thenReturn(Collections.singletonList("127.0.0.1:8848"));
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> connection);
|
||||
try {
|
||||
rpcClient.start();
|
||||
RpcClient.ReconnectContext reconnectContext = new RpcClient.ReconnectContext(
|
||||
new RpcClient.ServerInfo("127.0.0.1", 0), false);
|
||||
((BlockingQueue<RpcClient.ReconnectContext>) reconnectionSignalField.get(rpcClient)).put(reconnectContext);
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
assertEquals(RpcClientStatus.RUNNING, rpcClient.rpcClientStatus.get());
|
||||
assertEquals(8848, reconnectContext.serverInfo.serverPort);
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconnectContextAfterStartWithNewServiceInfo()
|
||||
throws NacosException, InterruptedException, IllegalAccessException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848");
|
||||
when(serverListFactory.getServerList()).thenReturn(Collections.singletonList("1.1.1.1:8848"));
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> connection);
|
||||
try {
|
||||
rpcClient.start();
|
||||
RpcClient.ReconnectContext reconnectContext = new RpcClient.ReconnectContext(
|
||||
new RpcClient.ServerInfo("127.0.0.1", 0), false);
|
||||
((BlockingQueue<RpcClient.ReconnectContext>) reconnectionSignalField.get(rpcClient)).put(reconnectContext);
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
assertEquals(RpcClientStatus.RUNNING, rpcClient.rpcClientStatus.get());
|
||||
assertNull(reconnectContext.serverInfo);
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleConnectionResetRequestWithoutServer() throws NacosException, InterruptedException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848", "1.1.1.1:8848");
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> {
|
||||
connection.serverInfo = serverInfo;
|
||||
return connection;
|
||||
});
|
||||
try {
|
||||
rpcClient.start();
|
||||
Response response = rpcClient.handleServerRequest(new ConnectResetRequest());
|
||||
assertTrue(response instanceof ConnectResetResponse);
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
assertEquals("1.1.1.1", connection.serverInfo.getServerIp());
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleConnectionResetRequestWithServer() throws NacosException, InterruptedException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848", "1.1.1.1:8848");
|
||||
List<String> serverList = new LinkedList<>();
|
||||
serverList.add("127.0.0.1:8848");
|
||||
serverList.add("1.1.1.1:8848");
|
||||
serverList.add("2.2.2.2:8848");
|
||||
when(serverListFactory.getServerList()).thenReturn(serverList);
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> {
|
||||
connection.serverInfo = serverInfo;
|
||||
return connection;
|
||||
});
|
||||
try {
|
||||
rpcClient.start();
|
||||
ConnectResetRequest connectResetRequest = new ConnectResetRequest();
|
||||
connectResetRequest.setServerIp("2.2.2.2");
|
||||
connectResetRequest.setServerPort("8848");
|
||||
Response response = rpcClient.handleServerRequest(connectResetRequest);
|
||||
assertTrue(response instanceof ConnectResetResponse);
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
assertEquals("2.2.2.2", connection.serverInfo.getServerIp());
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleConnectionResetRequestWithException() throws NacosException, InterruptedException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848", "1.1.1.1:8848");
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> {
|
||||
connection.serverInfo = serverInfo;
|
||||
return connection;
|
||||
});
|
||||
try {
|
||||
rpcClient.start();
|
||||
System.setProperty("nacos.server.port", "2.2.2.2");
|
||||
ConnectResetRequest connectResetRequest = new ConnectResetRequest();
|
||||
connectResetRequest.setServerIp("2.2.2.2");
|
||||
Response response = rpcClient.handleServerRequest(connectResetRequest);
|
||||
assertTrue(response instanceof ConnectResetResponse);
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
assertEquals("127.0.0.1", connection.serverInfo.getServerIp());
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleClientDetectionRequest() throws NacosException {
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> null);
|
||||
try {
|
||||
rpcClient.start();
|
||||
Response response = rpcClient.handleServerRequest(new ClientDetectionRequest());
|
||||
assertTrue(response instanceof ClientDetectionResponse);
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleOtherRequest() throws NacosException {
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> null);
|
||||
try {
|
||||
rpcClient.start();
|
||||
Response response = rpcClient.handleServerRequest(new HealthCheckRequest());
|
||||
assertNull(response);
|
||||
} finally {
|
||||
rpcClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconnectForRequestFailButHealthCheckOK() throws NacosException {
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> null);
|
||||
rpcClient.currentConnection = connection;
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
when(connection.request(any(Request.class), anyLong())).thenReturn(new HealthCheckResponse());
|
||||
rpcClient.reconnect(null, true);
|
||||
assertTrue(rpcClient.isRunning());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReconnectFailTimes() throws NacosException {
|
||||
when(serverListFactory.genNextServer()).thenReturn("127.0.0.1:8848");
|
||||
when(serverListFactory.getServerList()).thenReturn(Collections.singletonList("127.0.0.1:8848"));
|
||||
final AtomicInteger count = new AtomicInteger(0);
|
||||
RpcClient rpcClient = buildTestStartClient(serverInfo -> {
|
||||
int actual = count.incrementAndGet();
|
||||
return actual > 3 ? connection : null;
|
||||
});
|
||||
rpcClient.currentConnection = connection;
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
long start = System.currentTimeMillis();
|
||||
rpcClient.reconnect(null, false);
|
||||
assertTrue(rpcClient.isRunning());
|
||||
assertTrue(System.currentTimeMillis() - start > 400);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCurrentServer() {
|
||||
assertNull(rpcClient.getCurrentServer());
|
||||
rpcClient.currentConnection = connection;
|
||||
rpcClient.serverListFactory(serverListFactory);
|
||||
connection.serverInfo = new RpcClient.ServerInfo("127.0.0.1", 8848);
|
||||
assertNotNull(rpcClient.getCurrentServer());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCurrentRpcServer() throws IllegalAccessException {
|
||||
when(serverListFactory.getCurrentServer()).thenReturn("127.0.0.1:8848");
|
||||
serverListFactoryField.set(rpcClient, serverListFactory);
|
||||
RpcClient.ServerInfo serverInfo = rpcClient.currentRpcServer();
|
||||
assertEquals("127.0.0.1", serverInfo.getServerIp());
|
||||
assertEquals(8848, serverInfo.getServerPort());
|
||||
assertEquals("127.0.0.1:8848", serverInfo.getAddress());
|
||||
}
|
||||
|
||||
private RpcClient buildTestStartClient(Function<RpcClient.ServerInfo, Connection> function) {
|
||||
return new RpcClient(rpcClientConfig, serverListFactory) {
|
||||
|
||||
@Override
|
||||
public ConnectionType getConnectionType() {
|
||||
return ConnectionType.GRPC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rpcPortOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection connectToServer(ServerInfo serverInfo) {
|
||||
return function.apply(serverInfo);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerInfoSet() {
|
||||
RpcClient.ServerInfo serverInfo = new RpcClient.ServerInfo();
|
||||
String ip = "127.0.0.1";
|
||||
int port = 80;
|
||||
serverInfo.setServerIp(ip);
|
||||
serverInfo.setServerPort(port);
|
||||
assertEquals("127.0.0.1:80", serverInfo.getAddress());
|
||||
assertEquals(port, serverInfo.getServerPort());
|
||||
assertEquals(ip, serverInfo.getServerIp());
|
||||
String expected = "{serverIp = '127.0.0.1', server main port = 80}";
|
||||
assertEquals(expected, serverInfo.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetTenant() {
|
||||
String tenant = "testTenant";
|
||||
assertNull(rpcClient.getTenant());
|
||||
rpcClient.setTenant(tenant);
|
||||
assertEquals(tenant, rpcClient.getTenant());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConnectionAbilityWithNullConnection() {
|
||||
AbilityStatus abilityStatus = rpcClient.getConnectionAbility(AbilityKey.SERVER_TEST_1);
|
||||
assertNull(abilityStatus);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConnectionAbilityWithReadyConnection() {
|
||||
when(connection.getConnectionAbility(AbilityKey.SERVER_TEST_1)).thenReturn(AbilityStatus.SUPPORTED);
|
||||
rpcClient.currentConnection = connection;
|
||||
AbilityStatus abilityStatus = rpcClient.getConnectionAbility(AbilityKey.SERVER_TEST_1);
|
||||
assertNotNull(abilityStatus);
|
||||
assertEquals(AbilityStatus.SUPPORTED, abilityStatus);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.remote.client;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class RpcClientTlsConfigTest {
|
||||
|
||||
@Test
|
||||
public void testEnableTls() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_TLS_ENABLE, "true");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertTrue(tlsConfig.getEnableTls());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSslProvider() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_TLS_PROVIDER, "provider");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertEquals("provider", tlsConfig.getSslProvider());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMutualAuthEnable() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_MUTUAL_AUTH, "true");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertTrue(tlsConfig.getMutualAuthEnable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProtocols() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_TLS_PROTOCOLS, "protocols");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertEquals("protocols", tlsConfig.getProtocols());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCiphers() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_TLS_CIPHERS, "ciphers");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertEquals("ciphers", tlsConfig.getCiphers());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrustCollectionCertFile() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_COLLECTION_CHAIN_PATH, "trustCollectionCertFile");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertEquals("trustCollectionCertFile", tlsConfig.getTrustCollectionCertFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCertChainFile() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_TLS_CERT_CHAIN_PATH, "certChainFile");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertEquals("certChainFile", tlsConfig.getCertChainFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCertPrivateKey() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_TLS_CERT_KEY, "certPrivateKey");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertEquals("certPrivateKey", tlsConfig.getCertPrivateKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrustAll() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_ALL, "true");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertTrue(tlsConfig.getTrustAll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCertPrivateKeyPassword() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(RpcConstants.RPC_CLIENT_TLS_TRUST_PWD, "trustPwd");
|
||||
RpcClientTlsConfig tlsConfig = RpcClientTlsConfig.properties(properties);
|
||||
assertEquals("trustPwd", tlsConfig.getCertPrivateKeyPassword());
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user