commit
1d88d5d773
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,3 +15,4 @@ derby.log
|
||||
work
|
||||
test/logs
|
||||
derby.log
|
||||
yarn.lock
|
||||
|
@ -28,9 +28,13 @@ before_install:
|
||||
|
||||
script:
|
||||
- mvn -B clean package apache-rat:check findbugs:findbugs -Dmaven.test.skip=true
|
||||
- mvn clean -Premove-test-data
|
||||
- mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
|
||||
- mvn clean -Premove-test-data
|
||||
- mvn clean install -Pcit-test
|
||||
- mvn clean -Premove-test-data
|
||||
- mvn clean package -Pit-test
|
||||
- mvn clean -Premove-test-data
|
||||
after_success:
|
||||
- mvn clean package -Pit-test
|
||||
- mvn sonar:sonar -Psonar-apache
|
||||
|
@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -18,6 +18,7 @@ package com.alibaba.nacos.address.component;
|
||||
|
||||
import com.alibaba.nacos.address.constant.AddressServerConstants;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.utils.IPUtil;
|
||||
import com.alibaba.nacos.naming.core.Instance;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -85,14 +86,11 @@ public class AddressServerGeneratorManager {
|
||||
}
|
||||
|
||||
private String[] generateIpAndPort(String ip) {
|
||||
|
||||
int index = ip.indexOf(AddressServerConstants.IP_PORT_SEPARATOR);
|
||||
if (index != -1) {
|
||||
|
||||
return new String[] {ip.substring(0, index), ip.substring(index + 1)};
|
||||
String[] result = IPUtil.splitIPPortStr(ip);
|
||||
if (result.length != IPUtil.SPLIT_IP_PORT_RESULT_LENGTH) {
|
||||
return new String[] {result[0], String.valueOf(AddressServerConstants.DEFAULT_SERVER_PORT)};
|
||||
}
|
||||
|
||||
return new String[] {ip, String.valueOf(AddressServerConstants.DEFAULT_SERVER_PORT)};
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,11 +38,6 @@ public interface AddressServerConstants {
|
||||
*/
|
||||
String DEFAULT_PRODUCT = "nacos";
|
||||
|
||||
/**
|
||||
* the separator between ip and port.
|
||||
*/
|
||||
String IP_PORT_SEPARATOR = ":";
|
||||
|
||||
/**
|
||||
* the separator for service name between raw service name and group.
|
||||
*/
|
||||
|
@ -20,9 +20,9 @@ import com.alibaba.nacos.address.component.AddressServerGeneratorManager;
|
||||
import com.alibaba.nacos.address.component.AddressServerManager;
|
||||
import com.alibaba.nacos.address.constant.AddressServerConstants;
|
||||
import com.alibaba.nacos.address.misc.Loggers;
|
||||
import com.alibaba.nacos.address.util.AddressServerParamCheckUtil;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
|
||||
import com.alibaba.nacos.common.utils.IPUtil;
|
||||
import com.alibaba.nacos.naming.core.Cluster;
|
||||
import com.alibaba.nacos.naming.core.Instance;
|
||||
import com.alibaba.nacos.naming.core.Service;
|
||||
@ -87,8 +87,8 @@ public class AddressServerClusterController {
|
||||
clusterObj.setHealthChecker(new AbstractHealthChecker.None());
|
||||
serviceManager.createServiceIfAbsent(Constants.DEFAULT_NAMESPACE_ID, serviceName, false, clusterObj);
|
||||
String[] ipArray = addressServerManager.splitIps(ips);
|
||||
String checkResult = AddressServerParamCheckUtil.checkIps(ipArray);
|
||||
if (AddressServerParamCheckUtil.CHECK_OK.equals(checkResult)) {
|
||||
String checkResult = IPUtil.checkIPs(ipArray);
|
||||
if (IPUtil.checkOK(checkResult)) {
|
||||
List<Instance> instanceList = addressServerGeneratorManager
|
||||
.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray);
|
||||
for (Instance instance : instanceList) {
|
||||
@ -143,8 +143,8 @@ public class AddressServerClusterController {
|
||||
} else {
|
||||
// delete specified ip list
|
||||
String[] ipArray = addressServerManager.splitIps(ips);
|
||||
String checkResult = AddressServerParamCheckUtil.checkIps(ipArray);
|
||||
if (AddressServerParamCheckUtil.CHECK_OK.equals(checkResult)) {
|
||||
String checkResult = IPUtil.checkIPs(ipArray);
|
||||
if (IPUtil.checkOK(checkResult)) {
|
||||
List<Instance> instanceList = addressServerGeneratorManager
|
||||
.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray);
|
||||
serviceManager.removeInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, false,
|
||||
|
@ -1,67 +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.address.util;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Provides a unified tool class for address server parameter verification.
|
||||
*
|
||||
* @author pbting
|
||||
* @date 2019-06-19 11:19 AM
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class AddressServerParamCheckUtil {
|
||||
|
||||
public static final String CHECK_OK = "ok";
|
||||
|
||||
public static final String ILLEGAL_IP_PREFIX = "illegal ip: ";
|
||||
|
||||
private static final String IP_REGEX = "(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3}";
|
||||
|
||||
private static final Pattern IP_PATTERN = Pattern.compile(IP_REGEX);
|
||||
|
||||
/**
|
||||
* Check ips.
|
||||
*
|
||||
* @param ips ips
|
||||
* @return 'ok' if check passed, otherwise illegal ip
|
||||
*/
|
||||
public static String checkIps(String... ips) {
|
||||
|
||||
if (ips == null || ips.length == 0) {
|
||||
|
||||
return CHECK_OK;
|
||||
}
|
||||
// illegal response
|
||||
StringBuilder illegalResponse = new StringBuilder();
|
||||
for (String ip : ips) {
|
||||
Matcher matcher = IP_PATTERN.matcher(ip);
|
||||
if (matcher.matches()) {
|
||||
continue;
|
||||
}
|
||||
illegalResponse.append(ip + ",");
|
||||
}
|
||||
|
||||
if (illegalResponse.length() == 0) {
|
||||
return CHECK_OK;
|
||||
}
|
||||
|
||||
return ILLEGAL_IP_PREFIX + illegalResponse.substring(0, illegalResponse.length() - 1);
|
||||
}
|
||||
}
|
@ -16,17 +16,17 @@
|
||||
|
||||
package com.alibaba.nacos.address;
|
||||
|
||||
import com.alibaba.nacos.address.util.AddressServerParamCheckUtil;
|
||||
import com.alibaba.nacos.common.utils.IPUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ParamCheckUtilTests {
|
||||
|
||||
@Test
|
||||
public void checkIps() {
|
||||
public void checkIPs() {
|
||||
String[] ips = {"127.0.0.1"};
|
||||
System.out.println(AddressServerParamCheckUtil.checkIps(ips));
|
||||
System.out.println(IPUtil.checkIPs(ips));
|
||||
|
||||
String[] illlegalIps = {"127.100.19", "127.0.0.1"};
|
||||
System.err.println(AddressServerParamCheckUtil.checkIps(illlegalIps));
|
||||
System.err.println(IPUtil.checkIPs(illlegalIps));
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -55,10 +55,6 @@
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
@ -64,7 +64,11 @@ public class PropertyKeyConst {
|
||||
public static final String NAMING_CLIENT_BEAT_THREAD_COUNT = "namingClientBeatThreadCount";
|
||||
|
||||
public static final String NAMING_POLLING_THREAD_COUNT = "namingPollingThreadCount";
|
||||
|
||||
public static final String NAMING_REQUEST_DOMAIN_RETRY_COUNT = "namingRequestDomainMaxRetryCount";
|
||||
|
||||
public static final String NAMING_PUSH_EMPTY_PROTECTION = "namingPushEmptyProtection";
|
||||
|
||||
/**
|
||||
* Get the key value of some variable value from the system property.
|
||||
*/
|
||||
|
@ -188,4 +188,6 @@ public class Constants {
|
||||
|
||||
public static final String HTTP_PREFIX = "http";
|
||||
|
||||
public static final String ALL_PATTERN = "*";
|
||||
|
||||
}
|
||||
|
@ -79,6 +79,18 @@ public interface ConfigService {
|
||||
*/
|
||||
boolean publishConfig(String dataId, String group, String content) throws NacosException;
|
||||
|
||||
/**
|
||||
* Publish config.
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param content content
|
||||
* @param type config type {@link ConfigType}
|
||||
* @return Whether publish
|
||||
* @throws NacosException NacosException
|
||||
*/
|
||||
boolean publishConfig(String dataId, String group, String content, String type) throws NacosException;
|
||||
|
||||
/**
|
||||
* Remove config.
|
||||
*
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.api.config;
|
||||
|
||||
import com.alibaba.nacos.api.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Config data type.
|
||||
*
|
||||
@ -51,7 +53,12 @@ public enum ConfigType {
|
||||
/**
|
||||
* config type is "yaml".
|
||||
*/
|
||||
YAML("yaml");
|
||||
YAML("yaml"),
|
||||
|
||||
/**
|
||||
* not a real type.
|
||||
*/
|
||||
UNSET("unset");
|
||||
|
||||
String type;
|
||||
|
||||
@ -62,4 +69,26 @@ public enum ConfigType {
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static ConfigType getDefaultType() {
|
||||
return TEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* check input type is valid.
|
||||
*
|
||||
* @param type config type
|
||||
* @return it the type valid
|
||||
*/
|
||||
public static Boolean isValidType(String type) {
|
||||
if (StringUtils.isBlank(type)) {
|
||||
return false;
|
||||
}
|
||||
for (ConfigType value : values()) {
|
||||
if (value.type.equals(type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -57,9 +57,9 @@ public @interface NacosConfigListener {
|
||||
/**
|
||||
* Nacos Config type.
|
||||
*
|
||||
* @return "properties"
|
||||
* @return default value is {@link ConfigType#UNSET}
|
||||
*/
|
||||
ConfigType type() default ConfigType.PROPERTIES;
|
||||
ConfigType type() default ConfigType.UNSET;
|
||||
|
||||
/**
|
||||
* Specify {@link NacosConfigConverter Nacos configuraion convertor} class to convert target type instance.
|
||||
|
@ -72,9 +72,9 @@ public @interface NacosConfigurationProperties {
|
||||
/**
|
||||
* config style.
|
||||
*
|
||||
* @return default value is {@link ConfigType#PROPERTIES}
|
||||
* @return default value is {@link ConfigType#UNSET}
|
||||
*/
|
||||
ConfigType type() default ConfigType.PROPERTIES;
|
||||
ConfigType type() default ConfigType.UNSET;
|
||||
|
||||
/**
|
||||
* It indicates the properties of current doBind bean is auto-refreshed when Nacos configuration is changed.
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Abstract event listener, to support handle event by user custom executor.
|
||||
*
|
||||
* @author horizonzy
|
||||
* @since 1.4.1
|
||||
*/
|
||||
public abstract class AbstractEventListener implements EventListener {
|
||||
|
||||
/**
|
||||
* Get executor for execute this receive.
|
||||
*
|
||||
* @return Executor
|
||||
*/
|
||||
public Executor getExecutor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -31,6 +31,7 @@ import java.util.List;
|
||||
* ServiceInfo.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author shizhengxing
|
||||
*/
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class ServiceInfo {
|
||||
@ -67,19 +68,28 @@ public class ServiceInfo {
|
||||
this.allIPs = allIPs;
|
||||
}
|
||||
|
||||
/**
|
||||
* There is only one form of the key:groupName@@name@clusters. This constuctor used by DiskCache.read(String) and
|
||||
* FailoverReactor.FailoverFileReader,you should know that 'groupName' must not be null,and 'clusters' can be null.
|
||||
*/
|
||||
public ServiceInfo(String key) {
|
||||
|
||||
int maxIndex = 2;
|
||||
int clusterIndex = 1;
|
||||
int serviceNameIndex = 0;
|
||||
int clusterIndex = 2;
|
||||
int serviceNameIndex = 1;
|
||||
int groupIndex = 0;
|
||||
|
||||
String[] keys = key.split(Constants.SERVICE_INFO_SPLITER);
|
||||
if (keys.length >= maxIndex) {
|
||||
if (keys.length >= maxIndex + 1) {
|
||||
this.groupName = keys[groupIndex];
|
||||
this.name = keys[serviceNameIndex];
|
||||
this.clusters = keys[clusterIndex];
|
||||
} else if (keys.length == maxIndex) {
|
||||
this.groupName = keys[groupIndex];
|
||||
this.name = keys[serviceNameIndex];
|
||||
} else {
|
||||
//defensive programming
|
||||
throw new IllegalArgumentException("Cann't parse out 'groupName',but it must not be null!");
|
||||
}
|
||||
|
||||
this.name = keys[0];
|
||||
}
|
||||
|
||||
public ServiceInfo(String name, String clusters) {
|
||||
@ -157,6 +167,10 @@ public class ServiceInfo {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hosts == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Instance> validHosts = new ArrayList<Instance>();
|
||||
for (Instance host : hosts) {
|
||||
if (!host.isHealthy()) {
|
||||
@ -167,8 +181,8 @@ public class ServiceInfo {
|
||||
validHosts.add(host);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
//No valid hosts, return false.
|
||||
return !validHosts.isEmpty();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@ -182,7 +196,8 @@ public class ServiceInfo {
|
||||
|
||||
@JsonIgnore
|
||||
public String getKey() {
|
||||
return getKey(name, clusters);
|
||||
String serviceName = getGroupedServiceName();
|
||||
return getKey(serviceName, clusters);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@ -197,11 +212,21 @@ public class ServiceInfo {
|
||||
|
||||
@JsonIgnore
|
||||
public String getKeyEncoded() {
|
||||
String serviceName = getGroupedServiceName();
|
||||
try {
|
||||
return getKey(URLEncoder.encode(name, "UTF-8"), clusters);
|
||||
serviceName = URLEncoder.encode(serviceName, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return getKey();
|
||||
//do nothing
|
||||
}
|
||||
return getKey(serviceName, clusters);
|
||||
}
|
||||
|
||||
private String getGroupedServiceName() {
|
||||
String serviceName = this.name;
|
||||
if (!isEmpty(groupName) && serviceName.indexOf(Constants.SERVICE_INFO_SPLITER) == -1) {
|
||||
serviceName = groupName + Constants.SERVICE_INFO_SPLITER + serviceName;
|
||||
}
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,7 +35,8 @@ import java.io.Serializable;
|
||||
@JsonTypeInfo(use = Id.NAME, property = "type", defaultImpl = None.class)
|
||||
@JsonSubTypes({@JsonSubTypes.Type(name = Http.TYPE, value = Http.class),
|
||||
@JsonSubTypes.Type(name = Mysql.TYPE, value = Mysql.class),
|
||||
@JsonSubTypes.Type(name = Tcp.TYPE, value = Tcp.class)})
|
||||
@JsonSubTypes.Type(name = Tcp.TYPE, value = Tcp.class),
|
||||
@JsonSubTypes.Type(name = None.TYPE, value = None.class)})
|
||||
public abstract class AbstractHealthChecker implements Cloneable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3848305577423336421L;
|
||||
|
@ -17,6 +17,8 @@
|
||||
package com.alibaba.nacos.api.naming.utils;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.utils.StringUtils;
|
||||
|
||||
/**
|
||||
@ -27,6 +29,19 @@ import com.alibaba.nacos.api.utils.StringUtils;
|
||||
*/
|
||||
public class NamingUtils {
|
||||
|
||||
/**
|
||||
* Returns a combined string with serviceName and groupName. serviceName can not be nil.
|
||||
*
|
||||
* <p>In most cases, serviceName can not be nil. In other cases, for search or anything, See {@link
|
||||
* com.alibaba.nacos.api.naming.utils.NamingUtils#getGroupedNameOptional(String, String)}
|
||||
*
|
||||
* <p>etc:
|
||||
* <p>serviceName | groupName | result</p>
|
||||
* <p>serviceA | groupA | groupA@@serviceA</p>
|
||||
* <p>nil | groupA | threw IllegalArgumentException</p>
|
||||
*
|
||||
* @return 'groupName@@serviceName'
|
||||
*/
|
||||
public static String getGroupedName(final String serviceName, final String groupName) {
|
||||
if (StringUtils.isBlank(serviceName)) {
|
||||
throw new IllegalArgumentException("Param 'serviceName' is illegal, serviceName is blank");
|
||||
@ -56,13 +71,11 @@ public class NamingUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* check combineServiceName format. the serviceName can't be blank. some relational logic in {@link
|
||||
* com.alibaba.nacos.naming.web.DistroFilter#doFilter}, it will handle combineServiceName in some case, you should
|
||||
* know it.
|
||||
* check combineServiceName format. the serviceName can't be blank.
|
||||
* <pre>
|
||||
* serviceName = "@@"; the length = 0; illegal
|
||||
* serviceName = "group@@"; the length = 1; illegal
|
||||
* serviceName = "@@serviceName"; the length = 2; legal
|
||||
* serviceName = "@@"; the length = 0; illegal
|
||||
* serviceName = "group@@"; the length = 1; illegal
|
||||
* serviceName = "@@serviceName"; the length = 2; legal
|
||||
* serviceName = "group@@serviceName"; the length = 2; legal
|
||||
* </pre>
|
||||
*
|
||||
@ -75,4 +88,40 @@ public class NamingUtils {
|
||||
"Param 'serviceName' is illegal, it should be format as 'groupName@@serviceName'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a combined string with serviceName and groupName. Such as 'groupName@@serviceName'
|
||||
* <p>This method works similar with {@link com.alibaba.nacos.api.naming.utils.NamingUtils#getGroupedName} But not
|
||||
* verify any parameters.
|
||||
*
|
||||
* </p> etc:
|
||||
* <p>serviceName | groupName | result</p>
|
||||
* <p>serviceA | groupA | groupA@@serviceA</p>
|
||||
* <p>nil | groupA | groupA@@</p>
|
||||
* <p>nil | nil | @@</p>
|
||||
*
|
||||
* @return 'groupName@@serviceName'
|
||||
*/
|
||||
public static String getGroupedNameOptional(final String serviceName, final String groupName) {
|
||||
return groupName + Constants.SERVICE_INFO_SPLITER + serviceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Check instance param about keep alive.</p>
|
||||
*
|
||||
* <pre>
|
||||
* heart beat timeout must > heart beat interval
|
||||
* ip delete timeout must > heart beat interval
|
||||
* </pre>
|
||||
*
|
||||
* @param instance need checked instance
|
||||
* @throws NacosException if check failed, throw exception
|
||||
*/
|
||||
public static void checkInstanceIsLegal(Instance instance) throws NacosException {
|
||||
if (instance.getInstanceHeartBeatTimeOut() < instance.getInstanceHeartBeatInterval()
|
||||
|| instance.getIpDeleteTimeout() < instance.getInstanceHeartBeatInterval()) {
|
||||
throw new NacosException(NacosException.INVALID_PARAM,
|
||||
"Instance 'heart beat interval' must less than 'heart beat timeout' and 'ip delete timeout'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@ -38,13 +40,13 @@ public class ServiceInfoTest {
|
||||
public void setUp() throws Exception {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
serviceInfo = new ServiceInfo("testName", "testClusters");
|
||||
serviceInfo = new ServiceInfo("G@@testName", "testClusters");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialize() throws JsonProcessingException {
|
||||
String actual = mapper.writeValueAsString(serviceInfo);
|
||||
assertTrue(actual.contains("\"name\":\"testName\""));
|
||||
assertTrue(actual.contains("\"name\":\"G@@testName\""));
|
||||
assertTrue(actual.contains("\"clusters\":\"testClusters\""));
|
||||
assertTrue(actual.contains("\"cacheMillis\":1000"));
|
||||
assertTrue(actual.contains("\"hosts\":[]"));
|
||||
@ -58,11 +60,11 @@ public class ServiceInfoTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("checkstyle:linelength")
|
||||
public void testDeserialize() throws IOException {
|
||||
String example = "{\"name\":\"testName\",\"clusters\":\"testClusters\",\"cacheMillis\":1000,\"hosts\":[],\"lastRefTime\":0,\"checksum\":\"\",\"allIPs\":false,\"valid\":true,\"groupName\":\"\"}";
|
||||
String example = "{\"name\":\"G@@testName\",\"clusters\":\"testClusters\",\"cacheMillis\":1000,\"hosts\":[],"
|
||||
+ "\"lastRefTime\":0,\"checksum\":\"\",\"allIPs\":false,\"valid\":true,\"groupName\":\"\"}";
|
||||
ServiceInfo actual = mapper.readValue(example, ServiceInfo.class);
|
||||
assertEquals("testName", actual.getName());
|
||||
assertEquals("G@@testName", actual.getName());
|
||||
assertEquals("testClusters", actual.getClusters());
|
||||
assertEquals("", actual.getChecksum());
|
||||
assertEquals("", actual.getGroupName());
|
||||
@ -72,4 +74,32 @@ public class ServiceInfoTest {
|
||||
assertTrue(actual.isValid());
|
||||
assertFalse(actual.isAllIPs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetKey() {
|
||||
String key = serviceInfo.getKey();
|
||||
assertEquals("G@@testName@@testClusters", key);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetKeyEncode() {
|
||||
String key = serviceInfo.getKeyEncoded();
|
||||
String encodeName = null;
|
||||
try {
|
||||
encodeName = URLEncoder.encode("G@@testName", "utf-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
assertEquals(key, ServiceInfo.getKey(encodeName, "testClusters"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceInfoConstructor() {
|
||||
String key1 = "group@@name";
|
||||
String key2 = "group@@name@@c2";
|
||||
ServiceInfo s1 = new ServiceInfo(key1);
|
||||
ServiceInfo s2 = new ServiceInfo(key2);
|
||||
assertEquals(key1, s1.getKey());
|
||||
assertEquals(key2, s2.getKey());
|
||||
}
|
||||
}
|
||||
|
@ -17,12 +17,18 @@
|
||||
package com.alibaba.nacos.api.naming.pojo.healthcheck;
|
||||
|
||||
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Tcp;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class HealthCheckerFactoryTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
HealthCheckerFactory.registerSubType(TestChecker.class, TestChecker.TYPE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialize() {
|
||||
@ -33,7 +39,6 @@ public class HealthCheckerFactoryTest {
|
||||
|
||||
@Test
|
||||
public void testSerializeExtend() {
|
||||
HealthCheckerFactory.registerSubType(TestChecker.class, TestChecker.TYPE);
|
||||
TestChecker testChecker = new TestChecker();
|
||||
String actual = HealthCheckerFactory.serialize(testChecker);
|
||||
assertTrue(actual.contains("\"type\":\"TEST\""));
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import com.alibaba.nacos.api.utils.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class NamingUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testGetGroupedNameOptional() {
|
||||
String onlyGroupName = NamingUtils.getGroupedNameOptional(StringUtils.EMPTY, "groupA");
|
||||
assertEquals(onlyGroupName, "groupA@@");
|
||||
|
||||
String onlyServiceName = NamingUtils.getGroupedNameOptional("serviceA", StringUtils.EMPTY);
|
||||
assertEquals(onlyServiceName, "@@serviceA");
|
||||
|
||||
String groupNameAndServiceName = NamingUtils.getGroupedNameOptional("serviceA", "groupA");
|
||||
assertEquals(groupNameAndServiceName, "groupA@@serviceA");
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.nacos.auth.common;
|
||||
|
||||
import com.alibaba.nacos.common.JustForTest;
|
||||
import com.alibaba.nacos.sys.utils.ApplicationUtils;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -53,7 +53,7 @@ public class AuthConfigs {
|
||||
/**
|
||||
* Token validity time(seconds).
|
||||
*/
|
||||
@Value("${nacos.core.auth.default.token.expire.seconds:1800}")
|
||||
@Value("${nacos.core.auth.default.token.expire.seconds:18000}")
|
||||
private long tokenValidityInSeconds;
|
||||
|
||||
/**
|
||||
@ -62,6 +62,15 @@ public class AuthConfigs {
|
||||
@Value("${nacos.core.auth.system.type:}")
|
||||
private String nacosAuthSystemType;
|
||||
|
||||
@Value("${nacos.core.auth.server.identity.key:}")
|
||||
private String serverIdentityKey;
|
||||
|
||||
@Value(("${nacos.core.auth.server.identity.value:}"))
|
||||
private String serverIdentityValue;
|
||||
|
||||
@Value(("${nacos.core.auth.enable.userAgentAuthWhite:true}"))
|
||||
private boolean enableUserAgentAuthWhite;
|
||||
|
||||
public byte[] getSecretKeyBytes() {
|
||||
if (secretKeyBytes == null) {
|
||||
secretKeyBytes = Decoders.BASE64.decode(secretKey);
|
||||
@ -77,6 +86,18 @@ public class AuthConfigs {
|
||||
return nacosAuthSystemType;
|
||||
}
|
||||
|
||||
public String getServerIdentityKey() {
|
||||
return serverIdentityKey;
|
||||
}
|
||||
|
||||
public String getServerIdentityValue() {
|
||||
return serverIdentityValue;
|
||||
}
|
||||
|
||||
public boolean isEnableUserAgentAuthWhite() {
|
||||
return enableUserAgentAuthWhite;
|
||||
}
|
||||
|
||||
/**
|
||||
* auth function is open.
|
||||
*
|
||||
@ -89,7 +110,7 @@ public class AuthConfigs {
|
||||
return BooleanUtils.toBoolean(enabled);
|
||||
}
|
||||
return BooleanUtils
|
||||
.toBoolean(ApplicationUtils.getProperty("nacos.core.auth.enabled", "false"));
|
||||
.toBoolean(EnvUtil.getProperty("nacos.core.auth.enabled", "false"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,7 +123,7 @@ public class AuthConfigs {
|
||||
return cachingEnabled;
|
||||
}
|
||||
return BooleanUtils
|
||||
.toBoolean(ApplicationUtils.getProperty("nacos.core.auth.caching.enabled", "true"));
|
||||
.toBoolean(EnvUtil.getProperty("nacos.core.auth.caching.enabled", "true"));
|
||||
}
|
||||
|
||||
@JustForTest
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 1999-2020 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.util;
|
||||
|
||||
import com.alibaba.nacos.auth.common.AuthConfigs;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.sys.utils.ApplicationUtils;
|
||||
|
||||
/**
|
||||
* Auth header util.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class AuthHeaderUtil {
|
||||
|
||||
/**
|
||||
* Add identity info to Http header.
|
||||
*
|
||||
* @param header http header
|
||||
*/
|
||||
public static void addIdentityToHeader(Header header) {
|
||||
AuthConfigs authConfigs = ApplicationUtils.getBean(AuthConfigs.class);
|
||||
if (StringUtils.isNotBlank(authConfigs.getServerIdentityKey())) {
|
||||
header.addParam(authConfigs.getServerIdentityKey(), authConfigs.getServerIdentityValue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -19,6 +19,7 @@ package com.alibaba.nacos.client.config;
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
|
||||
@ -112,7 +113,12 @@ public class NacosConfigService implements ConfigService {
|
||||
|
||||
@Override
|
||||
public boolean publishConfig(String dataId, String group, String content) throws NacosException {
|
||||
return publishConfigInner(namespace, dataId, group, null, null, null, content);
|
||||
return publishConfig(dataId, group, content, ConfigType.getDefaultType().getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean publishConfig(String dataId, String group, String content, String type) throws NacosException {
|
||||
return publishConfigInner(namespace, dataId, group, null, null, null, content, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -211,7 +217,7 @@ public class NacosConfigService implements ConfigService {
|
||||
}
|
||||
|
||||
private boolean publishConfigInner(String tenant, String dataId, String group, String tag, String appName,
|
||||
String betaIps, String content) throws NacosException {
|
||||
String betaIps, String content, String type) throws NacosException {
|
||||
group = null2defaultGroup(group);
|
||||
ParamUtils.checkParam(dataId, group, content);
|
||||
|
||||
@ -228,6 +234,7 @@ public class NacosConfigService implements ConfigService {
|
||||
params.put("dataId", dataId);
|
||||
params.put("group", group);
|
||||
params.put("content", content);
|
||||
params.put("type", type);
|
||||
if (StringUtils.isNotEmpty(tenant)) {
|
||||
params.put("tenant", tenant);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import com.alibaba.nacos.client.config.impl.ServerListManager;
|
||||
import com.alibaba.nacos.client.config.impl.SpasAdapter;
|
||||
import com.alibaba.nacos.client.identify.StsConfig;
|
||||
import com.alibaba.nacos.client.security.SecurityProxy;
|
||||
import com.alibaba.nacos.client.utils.ContextPathUtil;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.client.utils.TemplateUtils;
|
||||
@ -247,9 +248,7 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
private String getUrl(String serverAddr, String relativePath) {
|
||||
String contextPath = serverListMgr.getContentPath().startsWith("/") ? serverListMgr.getContentPath()
|
||||
: "/" + serverListMgr.getContentPath();
|
||||
return serverAddr + contextPath + relativePath;
|
||||
return serverAddr + ContextPathUtil.normalizeContextPath(serverListMgr.getContentPath()) + relativePath;
|
||||
}
|
||||
|
||||
private boolean isFail(HttpRestResult<String> result) {
|
||||
@ -454,6 +453,7 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, LOGGER);
|
||||
ConfigHttpClientManager.getInstance().shutdown();
|
||||
SpasAdapter.freeCredentialInstance();
|
||||
LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
|
@ -49,11 +49,11 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.CONFIG_TYPE;
|
||||
import static com.alibaba.nacos.api.common.Constants.LINE_SEPARATOR;
|
||||
@ -160,26 +160,17 @@ public class ClientWorker implements Closeable {
|
||||
|
||||
private void removeCache(String dataId, String group) {
|
||||
String groupKey = GroupKey.getKey(dataId, group);
|
||||
synchronized (cacheMap) {
|
||||
Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
|
||||
copy.remove(groupKey);
|
||||
cacheMap.set(copy);
|
||||
}
|
||||
cacheMap.remove(groupKey);
|
||||
LOGGER.info("[{}] [unsubscribe] {}", this.agent.getName(), groupKey);
|
||||
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.size());
|
||||
}
|
||||
|
||||
void removeCache(String dataId, String group, String tenant) {
|
||||
String groupKey = GroupKey.getKeyTenant(dataId, group, tenant);
|
||||
synchronized (cacheMap) {
|
||||
Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
|
||||
copy.remove(groupKey);
|
||||
cacheMap.set(copy);
|
||||
}
|
||||
cacheMap.remove(groupKey);
|
||||
LOGGER.info("[{}] [unsubscribe] {}", agent.getName(), groupKey);
|
||||
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.size());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,37 +181,27 @@ public class ClientWorker implements Closeable {
|
||||
* @return cache data
|
||||
*/
|
||||
public CacheData addCacheDataIfAbsent(String dataId, String group) {
|
||||
CacheData cache = getCache(dataId, group);
|
||||
if (null != cache) {
|
||||
return cache;
|
||||
}
|
||||
|
||||
String key = GroupKey.getKey(dataId, group);
|
||||
cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group);
|
||||
|
||||
synchronized (cacheMap) {
|
||||
CacheData cacheFromMap = getCache(dataId, group);
|
||||
// multiple listeners on the same dataid+group and race condition,so double check again
|
||||
//other listener thread beat me to set to cacheMap
|
||||
if (null != cacheFromMap) {
|
||||
cache = cacheFromMap;
|
||||
//reset so that server not hang this check
|
||||
cache.setInitializing(true);
|
||||
} else {
|
||||
int taskId = cacheMap.get().size() / (int) ParamUtil.getPerTaskConfigSize();
|
||||
cache.setTaskId(taskId);
|
||||
}
|
||||
|
||||
Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
|
||||
copy.put(key, cache);
|
||||
cacheMap.set(copy);
|
||||
CacheData cacheData = cacheMap.get(key);
|
||||
if (cacheData != null) {
|
||||
return cacheData;
|
||||
}
|
||||
|
||||
cacheData = new CacheData(configFilterChainManager, agent.getName(), dataId, group);
|
||||
// multiple listeners on the same dataid+group and race condition
|
||||
CacheData lastCacheData = cacheMap.putIfAbsent(key, cacheData);
|
||||
if (lastCacheData == null) {
|
||||
int taskId = cacheMap.size() / (int) ParamUtil.getPerTaskConfigSize();
|
||||
lastCacheData = cacheData;
|
||||
lastCacheData.setTaskId(taskId);
|
||||
}
|
||||
// reset so that server not hang this check
|
||||
lastCacheData.setInitializing(true);
|
||||
|
||||
LOGGER.info("[{}] [subscribe] {}", this.agent.getName(), key);
|
||||
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
|
||||
|
||||
return cache;
|
||||
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.size());
|
||||
return lastCacheData;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -232,38 +213,33 @@ public class ClientWorker implements Closeable {
|
||||
* @return cache data
|
||||
*/
|
||||
public CacheData addCacheDataIfAbsent(String dataId, String group, String tenant) throws NacosException {
|
||||
CacheData cache = getCache(dataId, group, tenant);
|
||||
if (null != cache) {
|
||||
return cache;
|
||||
}
|
||||
String key = GroupKey.getKeyTenant(dataId, group, tenant);
|
||||
synchronized (cacheMap) {
|
||||
CacheData cacheFromMap = getCache(dataId, group, tenant);
|
||||
// multiple listeners on the same dataid+group and race condition,so
|
||||
// double check again
|
||||
// other listener thread beat me to set to cacheMap
|
||||
if (null != cacheFromMap) {
|
||||
cache = cacheFromMap;
|
||||
// reset so that server not hang this check
|
||||
cache.setInitializing(true);
|
||||
} else {
|
||||
cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant);
|
||||
// fix issue # 1317
|
||||
if (enableRemoteSyncConfig) {
|
||||
String[] ct = getServerConfig(dataId, group, tenant, 3000L);
|
||||
cache.setContent(ct[0]);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, CacheData> copy = new HashMap<String, CacheData>(this.cacheMap.get());
|
||||
copy.put(key, cache);
|
||||
cacheMap.set(copy);
|
||||
CacheData cacheData = cacheMap.get(key);
|
||||
if (cacheData != null) {
|
||||
return cacheData;
|
||||
}
|
||||
|
||||
cacheData = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant);
|
||||
// multiple listeners on the same dataid+group and race condition
|
||||
CacheData lastCacheData = cacheMap.putIfAbsent(key, cacheData);
|
||||
if (lastCacheData == null) {
|
||||
//fix issue # 1317
|
||||
if (enableRemoteSyncConfig) {
|
||||
String[] ct = getServerConfig(dataId, group, tenant, 3000L);
|
||||
cacheData.setContent(ct[0]);
|
||||
}
|
||||
int taskId = cacheMap.size() / (int) ParamUtil.getPerTaskConfigSize();
|
||||
cacheData.setTaskId(taskId);
|
||||
lastCacheData = cacheData;
|
||||
}
|
||||
|
||||
// reset so that server not hang this check
|
||||
lastCacheData.setInitializing(true);
|
||||
|
||||
LOGGER.info("[{}] [subscribe] {}", agent.getName(), key);
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.size());
|
||||
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
|
||||
|
||||
return cache;
|
||||
return lastCacheData;
|
||||
}
|
||||
|
||||
public CacheData getCache(String dataId, String group) {
|
||||
@ -274,7 +250,7 @@ public class ClientWorker implements Closeable {
|
||||
if (null == dataId || null == group) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
|
||||
return cacheMap.get(GroupKey.getKeyTenant(dataId, group, tenant));
|
||||
}
|
||||
|
||||
public String[] getServerConfig(String dataId, String group, String tenant, long readTimeout)
|
||||
@ -389,7 +365,7 @@ public class ClientWorker implements Closeable {
|
||||
*/
|
||||
public void checkConfigInfo() {
|
||||
// Dispatch taskes.
|
||||
int listenerSize = cacheMap.get().size();
|
||||
int listenerSize = cacheMap.size();
|
||||
// Round up the longingTaskCount.
|
||||
int longingTaskCount = (int) Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
|
||||
if (longingTaskCount > currentLongingTaskCount) {
|
||||
@ -602,7 +578,7 @@ public class ClientWorker implements Closeable {
|
||||
List<String> inInitializingCacheList = new ArrayList<String>();
|
||||
try {
|
||||
// check failover config
|
||||
for (CacheData cacheData : cacheMap.get().values()) {
|
||||
for (CacheData cacheData : cacheMap.values()) {
|
||||
if (cacheData.getTaskId() == taskId) {
|
||||
cacheDatas.add(cacheData);
|
||||
try {
|
||||
@ -632,7 +608,7 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
try {
|
||||
String[] ct = getServerConfig(dataId, group, tenant, 3000L);
|
||||
CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
|
||||
CacheData cache = cacheMap.get(GroupKey.getKeyTenant(dataId, group, tenant));
|
||||
cache.setContent(ct[0]);
|
||||
if (null != ct[1]) {
|
||||
cache.setType(ct[1]);
|
||||
@ -682,8 +658,7 @@ public class ClientWorker implements Closeable {
|
||||
/**
|
||||
* groupKey -> cacheData.
|
||||
*/
|
||||
private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
|
||||
new HashMap<String, CacheData>());
|
||||
private final ConcurrentHashMap<String, CacheData> cacheMap = new ConcurrentHashMap<String, CacheData>();
|
||||
|
||||
private final HttpAgent agent;
|
||||
|
||||
|
@ -164,7 +164,7 @@ public class ConfigHttpClientManager implements Closeable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,305 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.impl;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||
import com.alibaba.nacos.common.utils.VersionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Http tool.
|
||||
*
|
||||
* @author Nacos
|
||||
* @deprecated Use NacosRestTemplate{@link NacosRestTemplate} unified http client
|
||||
*/
|
||||
@Deprecated
|
||||
public class HttpSimpleClient {
|
||||
|
||||
/**
|
||||
* Get method.
|
||||
*
|
||||
* @param url url
|
||||
* @param headers headers
|
||||
* @param paramValues paramValues
|
||||
* @param encoding encoding
|
||||
* @param readTimeoutMs readTimeoutMs
|
||||
* @param isSsl isSsl
|
||||
* @return result
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
public static HttpResult httpGet(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs, boolean isSsl) throws IOException {
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
url += (null == encodedContent) ? "" : ("?" + encodedContent);
|
||||
if (Limiter
|
||||
.isLimit(MD5Utils.md5Hex(new StringBuilder(url).append(encodedContent).toString(), Constants.ENCODE))) {
|
||||
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
|
||||
"More than client-side current limit threshold");
|
||||
}
|
||||
|
||||
HttpURLConnection conn = null;
|
||||
|
||||
try {
|
||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
|
||||
conn.setReadTimeout((int) readTimeoutMs);
|
||||
List<String> newHeaders = getHeaders(url, headers, paramValues);
|
||||
setHeaders(conn, newHeaders, encoding);
|
||||
|
||||
conn.connect();
|
||||
|
||||
int respCode = conn.getResponseCode();
|
||||
String resp = null;
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
resp = IoUtils.toString(conn.getInputStream(), encoding);
|
||||
} else {
|
||||
resp = IoUtils.toString(conn.getErrorStream(), encoding);
|
||||
}
|
||||
return new HttpResult(respCode, conn.getHeaderFields(), resp);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送GET请求.
|
||||
*/
|
||||
public static HttpResult httpGet(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送POST请求.
|
||||
*
|
||||
* @param url url
|
||||
* @param headers 请求Header,可以为null
|
||||
* @param paramValues 参数,可以为null
|
||||
* @param encoding URL编码使用的字符集
|
||||
* @param readTimeoutMs 响应超时
|
||||
* @param isSsl 是否https
|
||||
* @return result
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
public static HttpResult httpPost(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs, boolean isSsl) throws IOException {
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
encodedContent = (null == encodedContent) ? "" : encodedContent;
|
||||
if (Limiter
|
||||
.isLimit(MD5Utils.md5Hex(new StringBuilder(url).append(encodedContent).toString(), Constants.ENCODE))) {
|
||||
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
|
||||
"More than client-side current limit threshold");
|
||||
}
|
||||
HttpURLConnection conn = null;
|
||||
try {
|
||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 3000 ? ParamUtil.getConnectTimeout() : 3000);
|
||||
conn.setReadTimeout((int) readTimeoutMs);
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
List<String> newHeaders = getHeaders(url, headers, paramValues);
|
||||
setHeaders(conn, newHeaders, encoding);
|
||||
|
||||
conn.getOutputStream().write(encodedContent.getBytes(encoding));
|
||||
|
||||
int respCode = conn.getResponseCode();
|
||||
String resp = null;
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
resp = IoUtils.toString(conn.getInputStream(), encoding);
|
||||
} else {
|
||||
resp = IoUtils.toString(conn.getErrorStream(), encoding);
|
||||
}
|
||||
return new HttpResult(respCode, conn.getHeaderFields(), resp);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送POST请求.
|
||||
*
|
||||
* @param url url
|
||||
* @param headers 请求Header,可以为null
|
||||
* @param paramValues 参数,可以为null
|
||||
* @param encoding URL编码使用的字符集
|
||||
* @param readTimeoutMs 响应超时
|
||||
* @return result
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
public static HttpResult httpPost(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
return httpPost(url, headers, paramValues, encoding, readTimeoutMs, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method.
|
||||
*
|
||||
* @param url url
|
||||
* @param headers 请求Header,可以为null
|
||||
* @param paramValues 参数,可以为null
|
||||
* @param encoding URL编码使用的字符集
|
||||
* @param readTimeoutMs 响应超时
|
||||
* @param isSsl 是否https
|
||||
* @return result
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
public static HttpResult httpDelete(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs, boolean isSsl) throws IOException {
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
url += (null == encodedContent) ? "" : ("?" + encodedContent);
|
||||
if (Limiter
|
||||
.isLimit(MD5Utils.md5Hex(new StringBuilder(url).append(encodedContent).toString(), Constants.ENCODE))) {
|
||||
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
|
||||
"More than client-side current limit threshold");
|
||||
}
|
||||
|
||||
HttpURLConnection conn = null;
|
||||
|
||||
try {
|
||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setRequestMethod("DELETE");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
|
||||
conn.setReadTimeout((int) readTimeoutMs);
|
||||
List<String> newHeaders = getHeaders(url, headers, paramValues);
|
||||
setHeaders(conn, newHeaders, encoding);
|
||||
|
||||
conn.connect();
|
||||
|
||||
int respCode = conn.getResponseCode();
|
||||
String resp = null;
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
resp = IoUtils.toString(conn.getInputStream(), encoding);
|
||||
} else {
|
||||
resp = IoUtils.toString(conn.getErrorStream(), encoding);
|
||||
}
|
||||
return new HttpResult(respCode, conn.getHeaderFields(), resp);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method.
|
||||
*
|
||||
* @param url url
|
||||
* @param headers 请求Header,可以为null
|
||||
* @param paramValues 参数,可以为null
|
||||
* @param encoding URL编码使用的字符集
|
||||
* @param readTimeoutMs 响应超时
|
||||
* @return result
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
public static HttpResult httpDelete(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false);
|
||||
}
|
||||
|
||||
private static void setHeaders(HttpURLConnection conn, List<String> headers, String encoding) {
|
||||
if (null != headers) {
|
||||
for (Iterator<String> iter = headers.iterator(); iter.hasNext(); ) {
|
||||
conn.addRequestProperty(iter.next(), iter.next());
|
||||
}
|
||||
}
|
||||
conn.addRequestProperty(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version);
|
||||
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding);
|
||||
|
||||
String ts = String.valueOf(System.currentTimeMillis());
|
||||
String token = MD5Utils.md5Hex(ts + ParamUtil.getAppKey(), Constants.ENCODE);
|
||||
|
||||
conn.addRequestProperty(Constants.CLIENT_APPNAME_HEADER, ParamUtil.getAppName());
|
||||
conn.addRequestProperty(Constants.CLIENT_REQUEST_TS_HEADER, ts);
|
||||
conn.addRequestProperty(Constants.CLIENT_REQUEST_TOKEN_HEADER, token);
|
||||
}
|
||||
|
||||
private static List<String> getHeaders(String url, List<String> headers, List<String> paramValues)
|
||||
throws IOException {
|
||||
List<String> newHeaders = new ArrayList<String>();
|
||||
newHeaders.add("exConfigInfo");
|
||||
newHeaders.add("true");
|
||||
newHeaders.add("RequestId");
|
||||
newHeaders.add(UuidUtils.generateUuid());
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
return newHeaders;
|
||||
}
|
||||
|
||||
private static String encodingParams(List<String> paramValues, String encoding)
|
||||
throws UnsupportedEncodingException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (null == paramValues) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext(); ) {
|
||||
sb.append(iter.next()).append("=");
|
||||
sb.append(URLEncoder.encode(iter.next(), encoding));
|
||||
if (iter.hasNext()) {
|
||||
sb.append("&");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static class HttpResult {
|
||||
|
||||
public final int code;
|
||||
|
||||
public final Map<String, List<String>> headers;
|
||||
|
||||
public final String content;
|
||||
|
||||
public HttpResult(int code, String content) {
|
||||
this.code = code;
|
||||
this.headers = null;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public HttpResult(int code, Map<String, List<String>> headers, String content) {
|
||||
this.code = code;
|
||||
this.headers = headers;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HttpResult{" + "code=" + code + ", headers=" + headers + ", content='" + content + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ package com.alibaba.nacos.client.config.impl;
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.SystemPropertyKeyConst;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.client.utils.ContextPathUtil;
|
||||
import com.alibaba.nacos.client.utils.EnvUtil;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
@ -30,6 +31,7 @@ import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.IPUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.slf4j.Logger;
|
||||
@ -87,9 +89,9 @@ public class ServerListManager implements Closeable {
|
||||
this.isStarted = true;
|
||||
List<String> serverAddrs = new ArrayList<String>();
|
||||
for (String serverAddr : fixed) {
|
||||
String[] serverAddrArr = serverAddr.split(":");
|
||||
String[] serverAddrArr = IPUtil.splitIPPortStr(serverAddr);
|
||||
if (serverAddrArr.length == 1) {
|
||||
serverAddrs.add(serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
|
||||
serverAddrs.add(serverAddrArr[0] + IPUtil.IP_PORT_SPLITER + ParamUtil.getDefaultServerPort());
|
||||
} else {
|
||||
serverAddrs.add(serverAddr);
|
||||
}
|
||||
@ -108,7 +110,9 @@ public class ServerListManager implements Closeable {
|
||||
this.isFixed = false;
|
||||
this.isStarted = false;
|
||||
this.name = CUSTOM_NAME + "-" + host + "-" + port;
|
||||
this.addressServerUrl = String.format("http://%s:%d/%s/%s", host, port, this.contentPath, this.serverListName);
|
||||
this.addressServerUrl = String
|
||||
.format("http://%s:%d%s/%s", host, port, ContextPathUtil.normalizeContextPath(this.contentPath),
|
||||
this.serverListName);
|
||||
}
|
||||
|
||||
public ServerListManager(String endpoint) throws NacosException {
|
||||
@ -127,8 +131,8 @@ public class ServerListManager implements Closeable {
|
||||
}
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
this.name = endpoint;
|
||||
this.addressServerUrl = String
|
||||
.format("http://%s:%d/%s/%s", endpoint, this.endpointPort, this.contentPath, this.serverListName);
|
||||
this.addressServerUrl = String.format("http://%s:%d%s/%s", endpoint, this.endpointPort,
|
||||
ContextPathUtil.normalizeContextPath(this.contentPath), this.serverListName);
|
||||
} else {
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
@ -136,9 +140,8 @@ public class ServerListManager implements Closeable {
|
||||
this.name = endpoint + "-" + namespace;
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
this.addressServerUrl = String
|
||||
.format("http://%s:%d/%s/%s?namespace=%s", endpoint, this.endpointPort, this.contentPath,
|
||||
this.serverListName, namespace);
|
||||
this.addressServerUrl = String.format("http://%s:%d%s/%s?namespace=%s", endpoint, this.endpointPort,
|
||||
ContextPathUtil.normalizeContextPath(this.contentPath), this.serverListName, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,9 +159,10 @@ public class ServerListManager implements Closeable {
|
||||
if (serverAddr.startsWith(HTTPS) || serverAddr.startsWith(HTTP)) {
|
||||
serverAddrs.add(serverAddr);
|
||||
} else {
|
||||
String[] serverAddrArr = serverAddr.split(":");
|
||||
String[] serverAddrArr = IPUtil.splitIPPortStr(serverAddr);
|
||||
if (serverAddrArr.length == 1) {
|
||||
serverAddrs.add(HTTP + serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
|
||||
serverAddrs.add(HTTP + serverAddrArr[0] + IPUtil.IP_PORT_SPLITER + ParamUtil
|
||||
.getDefaultServerPort());
|
||||
} else {
|
||||
serverAddrs.add(HTTP + serverAddr);
|
||||
}
|
||||
@ -181,16 +185,15 @@ public class ServerListManager implements Closeable {
|
||||
this.isFixed = false;
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
this.name = endpoint;
|
||||
this.addressServerUrl = String
|
||||
.format("http://%s:%d/%s/%s", this.endpoint, this.endpointPort, this.contentPath,
|
||||
this.serverListName);
|
||||
this.addressServerUrl = String.format("http://%s:%d%s/%s", this.endpoint, this.endpointPort,
|
||||
ContextPathUtil.normalizeContextPath(this.contentPath), this.serverListName);
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
this.name = this.endpoint + "-" + namespace;
|
||||
this.addressServerUrl = String
|
||||
.format("http://%s:%d/%s/%s?namespace=%s", this.endpoint, this.endpointPort, this.contentPath,
|
||||
this.serverListName, namespace);
|
||||
.format("http://%s:%d%s/%s?namespace=%s", this.endpoint, this.endpointPort,
|
||||
ContextPathUtil.normalizeContextPath(this.contentPath), this.serverListName, namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -355,10 +358,10 @@ public class ServerListManager implements Closeable {
|
||||
List<String> result = new ArrayList<String>(lines.size());
|
||||
for (String serverAddr : lines) {
|
||||
if (StringUtils.isNotBlank(serverAddr)) {
|
||||
String[] ipPort = serverAddr.trim().split(":");
|
||||
String[] ipPort = IPUtil.splitIPPortStr(serverAddr.trim());
|
||||
String ip = ipPort[0].trim();
|
||||
if (ipPort.length == 1) {
|
||||
result.add(ip + ":" + ParamUtil.getDefaultServerPort());
|
||||
result.add(ip + IPUtil.IP_PORT_SPLITER + ParamUtil.getDefaultServerPort());
|
||||
} else {
|
||||
result.add(serverAddr);
|
||||
}
|
||||
|
@ -74,6 +74,10 @@ public class SpasAdapter {
|
||||
return CredentialService.getInstance().getCredential().getAccessKey();
|
||||
}
|
||||
|
||||
public static void freeCredentialInstance() {
|
||||
CredentialService.freeInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign with hmac SHA1 encrtpt.
|
||||
*
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.client.config.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -89,7 +90,7 @@ public class ConcurrentDiskUtil {
|
||||
rlock = null;
|
||||
}
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
IoUtils.closeQuietly(fis);
|
||||
fis = null;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.nacos.client.config.utils;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.utils.IpUtils;
|
||||
import com.alibaba.nacos.common.utils.IPUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
@ -190,7 +190,7 @@ public class ParamUtils {
|
||||
}
|
||||
String[] ipsArr = betaIps.split(",");
|
||||
for (String ip : ipsArr) {
|
||||
if (!IpUtils.isIpv4(ip)) {
|
||||
if (!IPUtil.isIP(ip)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@ -27,8 +29,8 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Credential Watcher.
|
||||
@ -39,7 +41,7 @@ public class CredentialWatcher {
|
||||
|
||||
private static final Logger SPAS_LOGGER = LogUtils.logger(CredentialWatcher.class);
|
||||
|
||||
private static final long REFRESH_INTERVAL = 10 * 1000;
|
||||
private static final long REFRESH_INTERVAL = 10 * 1000L;
|
||||
|
||||
private final CredentialService serviceInstance;
|
||||
|
||||
@ -47,24 +49,21 @@ public class CredentialWatcher {
|
||||
|
||||
private String propertyPath;
|
||||
|
||||
private final TimerTask watcher;
|
||||
|
||||
private boolean stopped;
|
||||
|
||||
@SuppressWarnings("PMD.AvoidUseTimerRule")
|
||||
private final ScheduledExecutorService executor;
|
||||
|
||||
public CredentialWatcher(String appName, CredentialService serviceInstance) {
|
||||
this.appName = appName;
|
||||
this.serviceInstance = serviceInstance;
|
||||
loadCredential(true);
|
||||
watcher = new TimerTask() {
|
||||
private final Timer timer = new Timer(true);
|
||||
|
||||
|
||||
executor = ExecutorFactory
|
||||
.newSingleScheduledExecutorService(new NameThreadFactory("com.alibaba.nacos.client.identify.watcher"));
|
||||
|
||||
executor.scheduleWithFixedDelay(new Runnable() {
|
||||
private long modified = 0;
|
||||
|
||||
{
|
||||
timer.schedule(this, REFRESH_INTERVAL, REFRESH_INTERVAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (this) {
|
||||
@ -87,7 +86,7 @@ public class CredentialWatcher {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}, REFRESH_INTERVAL, REFRESH_INTERVAL, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,10 +96,10 @@ public class CredentialWatcher {
|
||||
if (stopped) {
|
||||
return;
|
||||
}
|
||||
if (watcher != null) {
|
||||
synchronized (watcher) {
|
||||
watcher.cancel();
|
||||
if (executor != null) {
|
||||
synchronized (executor) {
|
||||
stopped = true;
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
SPAS_LOGGER.info("[{}] {} is stopped", appName, this.getClass().getSimpleName());
|
||||
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.logging;
|
||||
|
||||
import com.alibaba.nacos.client.logging.log4j2.Log4J2NacosLogging;
|
||||
import com.alibaba.nacos.client.logging.logback.LogbackNacosLogging;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
* nacos logging.
|
||||
*
|
||||
* @author mai.jh
|
||||
*/
|
||||
public class NacosLogging {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NacosLogging.class);
|
||||
|
||||
private AbstractNacosLogging nacosLogging;
|
||||
|
||||
private boolean isLogback = false;
|
||||
|
||||
private NacosLogging() {
|
||||
try {
|
||||
Class.forName("ch.qos.logback.classic.Logger");
|
||||
nacosLogging = new LogbackNacosLogging();
|
||||
isLogback = true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
nacosLogging = new Log4J2NacosLogging();
|
||||
}
|
||||
}
|
||||
|
||||
private static class NacosLoggingInstance {
|
||||
|
||||
private static final NacosLogging INSTANCE = new NacosLogging();
|
||||
}
|
||||
|
||||
public static NacosLogging getInstance() {
|
||||
return NacosLoggingInstance.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load logging Configuration.
|
||||
*/
|
||||
public void loadConfiguration() {
|
||||
try {
|
||||
nacosLogging.loadConfiguration();
|
||||
} catch (Throwable t) {
|
||||
if (isLogback) {
|
||||
LOGGER.warn("Load Logback Configuration of Nacos fail, message: {}", t.getMessage());
|
||||
} else {
|
||||
LOGGER.warn("Load Log4j Configuration of Nacos fail, message: {}", t.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -65,7 +65,7 @@ public class NacosNamingMaintainService implements NamingMaintainService {
|
||||
namespace = InitUtils.initNamespaceForNaming(properties);
|
||||
InitUtils.initSerialization();
|
||||
initServerAddr(properties);
|
||||
InitUtils.initWebRootContext();
|
||||
InitUtils.initWebRootContext(properties);
|
||||
serverProxy = new NamingProxy(namespace, endpoint, serverList, properties);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@ import com.alibaba.nacos.api.selector.AbstractSelector;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatInfo;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatReactor;
|
||||
import com.alibaba.nacos.client.naming.core.Balancer;
|
||||
import com.alibaba.nacos.client.naming.core.EventDispatcher;
|
||||
import com.alibaba.nacos.client.naming.core.HostReactor;
|
||||
import com.alibaba.nacos.client.naming.net.NamingProxy;
|
||||
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
|
||||
@ -70,8 +69,6 @@ public class NacosNamingService implements NamingService {
|
||||
|
||||
private BeatReactor beatReactor;
|
||||
|
||||
private EventDispatcher eventDispatcher;
|
||||
|
||||
private NamingProxy serverProxy;
|
||||
|
||||
public NacosNamingService(String serverList) throws NacosException {
|
||||
@ -89,15 +86,14 @@ public class NacosNamingService implements NamingService {
|
||||
this.namespace = InitUtils.initNamespaceForNaming(properties);
|
||||
InitUtils.initSerialization();
|
||||
initServerAddr(properties);
|
||||
InitUtils.initWebRootContext();
|
||||
InitUtils.initWebRootContext(properties);
|
||||
initCacheDir();
|
||||
initLogName(properties);
|
||||
|
||||
this.eventDispatcher = new EventDispatcher();
|
||||
this.serverProxy = new NamingProxy(this.namespace, this.endpoint, this.serverList, properties);
|
||||
this.beatReactor = new BeatReactor(this.serverProxy, initClientBeatThreadCount(properties));
|
||||
this.hostReactor = new HostReactor(this.eventDispatcher, this.serverProxy, beatReactor, this.cacheDir,
|
||||
isLoadCacheAtStart(properties), initPollingThreadCount(properties));
|
||||
this.hostReactor = new HostReactor(this.serverProxy, beatReactor, this.cacheDir, isLoadCacheAtStart(properties),
|
||||
isPushEmptyProtect(properties), initPollingThreadCount(properties));
|
||||
}
|
||||
|
||||
private int initClientBeatThreadCount(Properties properties) {
|
||||
@ -130,6 +126,16 @@ public class NacosNamingService implements NamingService {
|
||||
return loadCacheAtStart;
|
||||
}
|
||||
|
||||
private boolean isPushEmptyProtect(Properties properties) {
|
||||
boolean pushEmptyProtection = false;
|
||||
if (properties != null && StringUtils
|
||||
.isNotEmpty(properties.getProperty(PropertyKeyConst.NAMING_PUSH_EMPTY_PROTECTION))) {
|
||||
pushEmptyProtection = ConvertUtils
|
||||
.toBoolean(properties.getProperty(PropertyKeyConst.NAMING_PUSH_EMPTY_PROTECTION));
|
||||
}
|
||||
return pushEmptyProtection;
|
||||
}
|
||||
|
||||
private void initServerAddr(Properties properties) {
|
||||
serverList = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
|
||||
endpoint = InitUtils.initEndpoint(properties);
|
||||
@ -154,8 +160,8 @@ public class NacosNamingService implements NamingService {
|
||||
private void initCacheDir() {
|
||||
String jmSnapshotPath = System.getProperty("JM.SNAPSHOT.PATH");
|
||||
if (!StringUtils.isBlank(jmSnapshotPath)) {
|
||||
cacheDir = jmSnapshotPath + File.separator + "nacos" + File.separator + "naming"
|
||||
+ File.separator + namespace;
|
||||
cacheDir =
|
||||
jmSnapshotPath + File.separator + "nacos" + File.separator + "naming" + File.separator + namespace;
|
||||
} else {
|
||||
cacheDir = System.getProperty("user.home") + File.separator + "nacos" + File.separator + "naming"
|
||||
+ File.separator + namespace;
|
||||
@ -197,6 +203,7 @@ public class NacosNamingService implements NamingService {
|
||||
|
||||
@Override
|
||||
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
NamingUtils.checkInstanceIsLegal(instance);
|
||||
String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
|
||||
if (instance.isEphemeral()) {
|
||||
BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
|
||||
@ -447,9 +454,8 @@ public class NacosNamingService implements NamingService {
|
||||
@Override
|
||||
public void subscribe(String serviceName, String groupName, List<String> clusters, EventListener listener)
|
||||
throws NacosException {
|
||||
eventDispatcher.addListener(hostReactor
|
||||
.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ",")),
|
||||
StringUtils.join(clusters, ","), listener);
|
||||
hostReactor.subscribe(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","),
|
||||
listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -470,9 +476,8 @@ public class NacosNamingService implements NamingService {
|
||||
@Override
|
||||
public void unsubscribe(String serviceName, String groupName, List<String> clusters, EventListener listener)
|
||||
throws NacosException {
|
||||
eventDispatcher
|
||||
.removeListener(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","),
|
||||
listener);
|
||||
hostReactor.unSubscribe(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","),
|
||||
listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -499,7 +504,7 @@ public class NacosNamingService implements NamingService {
|
||||
|
||||
@Override
|
||||
public List<ServiceInfo> getSubscribeServices() {
|
||||
return eventDispatcher.getSubscribeServices();
|
||||
return hostReactor.getSubscribeServices();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -514,7 +519,6 @@ public class NacosNamingService implements NamingService {
|
||||
@Override
|
||||
public void shutDown() throws NacosException {
|
||||
beatReactor.shutdown();
|
||||
eventDispatcher.shutdown();
|
||||
hostReactor.shutdown();
|
||||
serverProxy.shutdown();
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.client.naming.cache;
|
||||
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@ -88,7 +90,7 @@ public class ConcurrentDiskUtil {
|
||||
rlock = null;
|
||||
}
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
IoUtils.closeQuietly(fis);
|
||||
fis = null;
|
||||
}
|
||||
}
|
||||
|
@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.core;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.listener.EventListener;
|
||||
import com.alibaba.nacos.api.naming.listener.NamingEvent;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Event dispatcher.
|
||||
*
|
||||
* @author xuanyin
|
||||
*/
|
||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
||||
public class EventDispatcher implements Closeable {
|
||||
|
||||
private ExecutorService executor = null;
|
||||
|
||||
private final BlockingQueue<ServiceInfo> changedServices = new LinkedBlockingQueue<ServiceInfo>();
|
||||
|
||||
private final ConcurrentMap<String, List<EventListener>> observerMap = new ConcurrentHashMap<String, List<EventListener>>();
|
||||
|
||||
private volatile boolean closed = false;
|
||||
|
||||
public EventDispatcher() {
|
||||
|
||||
this.executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r, "com.alibaba.nacos.naming.client.listener");
|
||||
thread.setDaemon(true);
|
||||
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
|
||||
this.executor.execute(new Notifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add listener.
|
||||
*
|
||||
* @param serviceInfo service info
|
||||
* @param clusters clusters
|
||||
* @param listener listener
|
||||
*/
|
||||
public void addListener(ServiceInfo serviceInfo, String clusters, EventListener listener) {
|
||||
|
||||
NAMING_LOGGER.info("[LISTENER] adding " + serviceInfo.getName() + " with " + clusters + " to listener map");
|
||||
List<EventListener> observers = Collections.synchronizedList(new ArrayList<EventListener>());
|
||||
observers.add(listener);
|
||||
|
||||
observers = observerMap.putIfAbsent(ServiceInfo.getKey(serviceInfo.getName(), clusters), observers);
|
||||
if (observers != null) {
|
||||
observers.add(listener);
|
||||
}
|
||||
|
||||
serviceChanged(serviceInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove listener.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param clusters clusters
|
||||
* @param listener listener
|
||||
*/
|
||||
public void removeListener(String serviceName, String clusters, EventListener listener) {
|
||||
|
||||
NAMING_LOGGER.info("[LISTENER] removing " + serviceName + " with " + clusters + " from listener map");
|
||||
|
||||
List<EventListener> observers = observerMap.get(ServiceInfo.getKey(serviceName, clusters));
|
||||
if (observers != null) {
|
||||
Iterator<EventListener> iter = observers.iterator();
|
||||
while (iter.hasNext()) {
|
||||
EventListener oldListener = iter.next();
|
||||
if (oldListener.equals(listener)) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
if (observers.isEmpty()) {
|
||||
observerMap.remove(ServiceInfo.getKey(serviceName, clusters));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSubscribed(String serviceName, String clusters) {
|
||||
return observerMap.containsKey(ServiceInfo.getKey(serviceName, clusters));
|
||||
}
|
||||
|
||||
public List<ServiceInfo> getSubscribeServices() {
|
||||
List<ServiceInfo> serviceInfos = new ArrayList<ServiceInfo>();
|
||||
for (String key : observerMap.keySet()) {
|
||||
serviceInfos.add(ServiceInfo.fromKey(key));
|
||||
}
|
||||
return serviceInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Service changed.
|
||||
*
|
||||
* @param serviceInfo service info
|
||||
*/
|
||||
public void serviceChanged(ServiceInfo serviceInfo) {
|
||||
if (serviceInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
changedServices.add(serviceInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executor, NAMING_LOGGER);
|
||||
closed = true;
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
private class Notifier implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!closed) {
|
||||
|
||||
ServiceInfo serviceInfo = null;
|
||||
try {
|
||||
serviceInfo = changedServices.poll(5, TimeUnit.MINUTES);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
if (serviceInfo == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
List<EventListener> listeners = observerMap.get(serviceInfo.getKey());
|
||||
|
||||
if (!CollectionUtils.isEmpty(listeners)) {
|
||||
for (EventListener listener : listeners) {
|
||||
List<Instance> hosts = Collections.unmodifiableList(serviceInfo.getHosts());
|
||||
listener.onEvent(new NamingEvent(serviceInfo.getName(), serviceInfo.getGroupName(),
|
||||
serviceInfo.getClusters(), hosts));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
NAMING_LOGGER.error("[NA] notify error for service: " + serviceInfo.getName() + ", clusters: "
|
||||
+ serviceInfo.getClusters(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
package com.alibaba.nacos.client.naming.core;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.listener.EventListener;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.client.monitor.MetricsMonitor;
|
||||
@ -24,10 +25,13 @@ import com.alibaba.nacos.client.naming.backups.FailoverReactor;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatInfo;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatReactor;
|
||||
import com.alibaba.nacos.client.naming.cache.DiskCache;
|
||||
import com.alibaba.nacos.client.naming.event.InstancesChangeEvent;
|
||||
import com.alibaba.nacos.client.naming.event.InstancesChangeNotifier;
|
||||
import com.alibaba.nacos.client.naming.net.NamingProxy;
|
||||
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
@ -66,8 +70,6 @@ public class HostReactor implements Closeable {
|
||||
|
||||
private final PushReceiver pushReceiver;
|
||||
|
||||
private final EventDispatcher eventDispatcher;
|
||||
|
||||
private final BeatReactor beatReactor;
|
||||
|
||||
private final NamingProxy serverProxy;
|
||||
@ -76,15 +78,18 @@ public class HostReactor implements Closeable {
|
||||
|
||||
private final String cacheDir;
|
||||
|
||||
private final boolean pushEmptyProtection;
|
||||
|
||||
private final ScheduledExecutorService executor;
|
||||
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, BeatReactor beatReactor,
|
||||
String cacheDir) {
|
||||
this(eventDispatcher, serverProxy, beatReactor, cacheDir, false, UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
|
||||
private final InstancesChangeNotifier notifier;
|
||||
|
||||
public HostReactor(NamingProxy serverProxy, BeatReactor beatReactor, String cacheDir) {
|
||||
this(serverProxy, beatReactor, cacheDir, false, false, UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
|
||||
}
|
||||
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, BeatReactor beatReactor,
|
||||
String cacheDir, boolean loadCacheAtStart, int pollingThreadCount) {
|
||||
public HostReactor(NamingProxy serverProxy, BeatReactor beatReactor, String cacheDir, boolean loadCacheAtStart,
|
||||
boolean pushEmptyProtection, int pollingThreadCount) {
|
||||
// init executorService
|
||||
this.executor = new ScheduledThreadPoolExecutor(pollingThreadCount, new ThreadFactory() {
|
||||
@Override
|
||||
@ -95,7 +100,7 @@ public class HostReactor implements Closeable {
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
|
||||
this.beatReactor = beatReactor;
|
||||
this.serverProxy = serverProxy;
|
||||
this.cacheDir = cacheDir;
|
||||
@ -104,10 +109,14 @@ public class HostReactor implements Closeable {
|
||||
} else {
|
||||
this.serviceInfoMap = new ConcurrentHashMap<String, ServiceInfo>(16);
|
||||
}
|
||||
|
||||
this.pushEmptyProtection = pushEmptyProtection;
|
||||
this.updatingMap = new ConcurrentHashMap<String, Object>();
|
||||
this.failoverReactor = new FailoverReactor(this, cacheDir);
|
||||
this.pushReceiver = new PushReceiver(this);
|
||||
this.notifier = new InstancesChangeNotifier();
|
||||
|
||||
NotifyCenter.registerToPublisher(InstancesChangeEvent.class, 16384);
|
||||
NotifyCenter.registerSubscriber(notifier);
|
||||
}
|
||||
|
||||
public Map<String, ServiceInfo> getServiceInfoMap() {
|
||||
@ -118,6 +127,33 @@ public class HostReactor implements Closeable {
|
||||
return executor.schedule(task, DEFAULT_DELAY, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* subscribe instancesChangeEvent.
|
||||
*
|
||||
* @param serviceName combineServiceName, such as 'xxx@@xxx'
|
||||
* @param clusters clusters, concat by ','. such as 'xxx,yyy'
|
||||
* @param eventListener custom listener
|
||||
*/
|
||||
public void subscribe(String serviceName, String clusters, EventListener eventListener) {
|
||||
notifier.registerListener(serviceName, clusters, eventListener);
|
||||
getServiceInfo(serviceName, clusters);
|
||||
}
|
||||
|
||||
/**
|
||||
* unsubscribe instancesChangeEvent.
|
||||
*
|
||||
* @param serviceName combineServiceName, such as 'xxx@@xxx'
|
||||
* @param clusters clusters, concat by ','. such as 'xxx,yyy'
|
||||
* @param eventListener custom listener
|
||||
*/
|
||||
public void unSubscribe(String serviceName, String clusters, EventListener eventListener) {
|
||||
notifier.deregisterListener(serviceName, clusters, eventListener);
|
||||
}
|
||||
|
||||
public List<ServiceInfo> getSubscribeServices() {
|
||||
return notifier.getSubscribeServices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process service json.
|
||||
*
|
||||
@ -127,7 +163,8 @@ public class HostReactor implements Closeable {
|
||||
public ServiceInfo processServiceJson(String json) {
|
||||
ServiceInfo serviceInfo = JacksonUtils.toObj(json, ServiceInfo.class);
|
||||
ServiceInfo oldService = serviceInfoMap.get(serviceInfo.getKey());
|
||||
if (serviceInfo.getHosts() == null || !serviceInfo.validate()) {
|
||||
|
||||
if (pushEmptyProtection && !serviceInfo.validate()) {
|
||||
//empty or error push, just ignore
|
||||
return oldService;
|
||||
}
|
||||
@ -208,7 +245,8 @@ public class HostReactor implements Closeable {
|
||||
serviceInfo.setJsonFromServer(json);
|
||||
|
||||
if (newHosts.size() > 0 || remvHosts.size() > 0 || modHosts.size() > 0) {
|
||||
eventDispatcher.serviceChanged(serviceInfo);
|
||||
NotifyCenter.publishEvent(new InstancesChangeEvent(serviceInfo.getName(), serviceInfo.getGroupName(),
|
||||
serviceInfo.getClusters(), serviceInfo.getHosts()));
|
||||
DiskCache.write(serviceInfo, cacheDir);
|
||||
}
|
||||
|
||||
@ -217,7 +255,8 @@ public class HostReactor implements Closeable {
|
||||
NAMING_LOGGER.info("init new ips(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() + " -> "
|
||||
+ JacksonUtils.toJson(serviceInfo.getHosts()));
|
||||
serviceInfoMap.put(serviceInfo.getKey(), serviceInfo);
|
||||
eventDispatcher.serviceChanged(serviceInfo);
|
||||
NotifyCenter.publishEvent(new InstancesChangeEvent(serviceInfo.getName(), serviceInfo.getGroupName(),
|
||||
serviceInfo.getClusters(), serviceInfo.getHosts()));
|
||||
serviceInfo.setJsonFromServer(json);
|
||||
DiskCache.write(serviceInfo, cacheDir);
|
||||
}
|
||||
@ -371,6 +410,7 @@ public class HostReactor implements Closeable {
|
||||
ThreadUtils.shutdownThreadPool(executor, NAMING_LOGGER);
|
||||
pushReceiver.shutdown();
|
||||
failoverReactor.shutdown();
|
||||
NotifyCenter.deregisterSubscriber(notifier);
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
@ -427,7 +467,7 @@ public class HostReactor implements Closeable {
|
||||
|
||||
lastRefTime = serviceObj.getLastRefTime();
|
||||
|
||||
if (!eventDispatcher.isSubscribed(serviceName, clusters) && !futureMap
|
||||
if (!notifier.isSubscribed(serviceName, clusters) && !futureMap
|
||||
.containsKey(ServiceInfo.getKey(serviceName, clusters))) {
|
||||
// abort the update task
|
||||
NAMING_LOGGER.info("update task is stopped, service:" + serviceName + ", clusters:" + clusters);
|
||||
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.event;
|
||||
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.common.notify.Event;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Instances change event.
|
||||
*
|
||||
* @author horizonzy
|
||||
* @since 1.4.1
|
||||
*/
|
||||
public class InstancesChangeEvent extends Event {
|
||||
|
||||
private static final long serialVersionUID = -8823087028212249603L;
|
||||
|
||||
private final String serviceName;
|
||||
|
||||
private final String groupName;
|
||||
|
||||
private final String clusters;
|
||||
|
||||
private final List<Instance> hosts;
|
||||
|
||||
public InstancesChangeEvent(String serviceName, String groupName, String clusters, List<Instance> hosts) {
|
||||
this.serviceName = serviceName;
|
||||
this.groupName = groupName;
|
||||
this.clusters = clusters;
|
||||
this.hosts = hosts;
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
public String getGroupName() {
|
||||
return groupName;
|
||||
}
|
||||
|
||||
public String getClusters() {
|
||||
return clusters;
|
||||
}
|
||||
|
||||
public List<Instance> getHosts() {
|
||||
return hosts;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.event;
|
||||
|
||||
import com.alibaba.nacos.api.naming.listener.AbstractEventListener;
|
||||
import com.alibaba.nacos.api.naming.listener.EventListener;
|
||||
import com.alibaba.nacos.api.naming.listener.NamingEvent;
|
||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.common.notify.Event;
|
||||
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||
import com.alibaba.nacos.common.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* A subscriber to notify eventListener callback.
|
||||
*
|
||||
* @author horizonzy
|
||||
* @since 1.4.1
|
||||
*/
|
||||
public class InstancesChangeNotifier extends Subscriber<InstancesChangeEvent> {
|
||||
|
||||
private final Map<String, ConcurrentHashSet<EventListener>> listenerMap = new ConcurrentHashMap<String, ConcurrentHashSet<EventListener>>();
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
/**
|
||||
* register listener.
|
||||
*
|
||||
* @param serviceName combineServiceName, such as 'xxx@@xxx'
|
||||
* @param clusters clusters, concat by ','. such as 'xxx,yyy'
|
||||
* @param listener custom listener
|
||||
*/
|
||||
public void registerListener(String serviceName, String clusters, EventListener listener) {
|
||||
String key = ServiceInfo.getKey(serviceName, clusters);
|
||||
ConcurrentHashSet<EventListener> eventListeners = listenerMap.get(key);
|
||||
if (eventListeners == null) {
|
||||
synchronized (lock) {
|
||||
eventListeners = listenerMap.get(key);
|
||||
if (eventListeners == null) {
|
||||
eventListeners = new ConcurrentHashSet<EventListener>();
|
||||
listenerMap.put(key, eventListeners);
|
||||
}
|
||||
}
|
||||
}
|
||||
eventListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* deregister listener.
|
||||
*
|
||||
* @param serviceName combineServiceName, such as 'xxx@@xxx'
|
||||
* @param clusters clusters, concat by ','. such as 'xxx,yyy'
|
||||
* @param listener custom listener
|
||||
*/
|
||||
public void deregisterListener(String serviceName, String clusters, EventListener listener) {
|
||||
String key = ServiceInfo.getKey(serviceName, clusters);
|
||||
ConcurrentHashSet<EventListener> eventListeners = listenerMap.get(key);
|
||||
if (eventListeners == null) {
|
||||
return;
|
||||
}
|
||||
eventListeners.remove(listener);
|
||||
if (CollectionUtils.isEmpty(eventListeners)) {
|
||||
listenerMap.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check serviceName,clusters is subscribed.
|
||||
*
|
||||
* @param serviceName combineServiceName, such as 'xxx@@xxx'
|
||||
* @param clusters clusters, concat by ','. such as 'xxx,yyy'
|
||||
* @return is serviceName,clusters subscribed
|
||||
*/
|
||||
public boolean isSubscribed(String serviceName, String clusters) {
|
||||
String key = ServiceInfo.getKey(serviceName, clusters);
|
||||
ConcurrentHashSet<EventListener> eventListeners = listenerMap.get(key);
|
||||
return CollectionUtils.isNotEmpty(eventListeners);
|
||||
}
|
||||
|
||||
public List<ServiceInfo> getSubscribeServices() {
|
||||
List<ServiceInfo> serviceInfos = new ArrayList<ServiceInfo>();
|
||||
for (String key : listenerMap.keySet()) {
|
||||
serviceInfos.add(ServiceInfo.fromKey(key));
|
||||
}
|
||||
return serviceInfos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(InstancesChangeEvent event) {
|
||||
String key = ServiceInfo.getKey(event.getServiceName(), event.getClusters());
|
||||
ConcurrentHashSet<EventListener> eventListeners = listenerMap.get(key);
|
||||
if (CollectionUtils.isEmpty(eventListeners)) {
|
||||
return;
|
||||
}
|
||||
for (final EventListener listener : eventListeners) {
|
||||
final com.alibaba.nacos.api.naming.listener.Event namingEvent = transferToNamingEvent(event);
|
||||
if (listener instanceof AbstractEventListener && ((AbstractEventListener) listener).getExecutor() != null) {
|
||||
((AbstractEventListener) listener).getExecutor().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
listener.onEvent(namingEvent);
|
||||
}
|
||||
});
|
||||
continue;
|
||||
}
|
||||
listener.onEvent(namingEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private com.alibaba.nacos.api.naming.listener.Event transferToNamingEvent(
|
||||
InstancesChangeEvent instancesChangeEvent) {
|
||||
return new NamingEvent(instancesChangeEvent.getServiceName(), instancesChangeEvent.getGroupName(),
|
||||
instancesChangeEvent.getClusters(), instancesChangeEvent.getHosts());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Event> subscribeType() {
|
||||
return InstancesChangeEvent.class;
|
||||
}
|
||||
|
||||
}
|
@ -1,248 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.net;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.tls.TlsSystemConfig;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Http client.
|
||||
*
|
||||
* @author nkorange
|
||||
* @deprecated Use NacosRestTemplate{@link NacosRestTemplate} unified http client
|
||||
*/
|
||||
@Deprecated
|
||||
public class HttpClient {
|
||||
|
||||
public static final int READ_TIME_OUT_MILLIS = Integer
|
||||
.getInteger("com.alibaba.nacos.client.naming.rtimeout", 50000);
|
||||
|
||||
public static final int CON_TIME_OUT_MILLIS = Integer.getInteger("com.alibaba.nacos.client.naming.ctimeout", 3000);
|
||||
|
||||
private static final boolean ENABLE_HTTPS = Boolean.getBoolean(TlsSystemConfig.TLS_ENABLE);
|
||||
|
||||
static {
|
||||
// limit max redirection
|
||||
System.setProperty("http.maxRedirects", "5");
|
||||
}
|
||||
|
||||
public static String getPrefix() {
|
||||
if (ENABLE_HTTPS) {
|
||||
return "https://";
|
||||
}
|
||||
|
||||
return "http://";
|
||||
|
||||
}
|
||||
|
||||
public static HttpResult httpGet(String url, List<String> headers, Map<String, String> paramValues,
|
||||
String encoding) {
|
||||
return request(url, headers, paramValues, StringUtils.EMPTY, encoding, HttpMethod.GET);
|
||||
}
|
||||
|
||||
/**
|
||||
* request.
|
||||
*
|
||||
* @param url url
|
||||
* @param headers headers
|
||||
* @param paramValues paramValues
|
||||
* @param body body
|
||||
* @param encoding encoding
|
||||
* @param method method
|
||||
* @return result
|
||||
*/
|
||||
public static HttpResult request(String url, List<String> headers, Map<String, String> paramValues, String body,
|
||||
String encoding, String method) {
|
||||
HttpURLConnection conn = null;
|
||||
try {
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
url += (StringUtils.isEmpty(encodedContent)) ? "" : ("?" + encodedContent);
|
||||
|
||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
|
||||
setHeaders(conn, headers, encoding);
|
||||
conn.setConnectTimeout(CON_TIME_OUT_MILLIS);
|
||||
conn.setReadTimeout(READ_TIME_OUT_MILLIS);
|
||||
conn.setRequestMethod(method);
|
||||
conn.setDoOutput(true);
|
||||
if (StringUtils.isNotBlank(body)) {
|
||||
byte[] b = body.getBytes();
|
||||
conn.setRequestProperty("Content-Length", String.valueOf(b.length));
|
||||
conn.getOutputStream().write(b, 0, b.length);
|
||||
conn.getOutputStream().flush();
|
||||
conn.getOutputStream().close();
|
||||
}
|
||||
conn.connect();
|
||||
if (NAMING_LOGGER.isDebugEnabled()) {
|
||||
NAMING_LOGGER.debug("Request from server: " + url);
|
||||
}
|
||||
return getResult(conn);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
if (conn != null) {
|
||||
NAMING_LOGGER.warn("failed to request " + conn.getURL() + " from " + InetAddress
|
||||
.getByName(conn.getURL().getHost()).getHostAddress());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
NAMING_LOGGER.error("[NA] failed to request ", ex);
|
||||
//ignore
|
||||
}
|
||||
|
||||
NAMING_LOGGER.error("[NA] failed to request ", e);
|
||||
|
||||
return new HttpResult(500, e.toString(), Collections.<String, String>emptyMap());
|
||||
} finally {
|
||||
IoUtils.closeQuietly(conn);
|
||||
}
|
||||
}
|
||||
|
||||
private static HttpResult getResult(HttpURLConnection conn) throws IOException {
|
||||
int respCode = conn.getResponseCode();
|
||||
|
||||
InputStream inputStream;
|
||||
if (HttpURLConnection.HTTP_OK == respCode || HttpURLConnection.HTTP_NOT_MODIFIED == respCode
|
||||
|| Constants.WRITE_REDIRECT_CODE == respCode) {
|
||||
inputStream = conn.getInputStream();
|
||||
} else {
|
||||
inputStream = conn.getErrorStream();
|
||||
}
|
||||
|
||||
Map<String, String> respHeaders = new HashMap<String, String>(conn.getHeaderFields().size());
|
||||
for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
|
||||
respHeaders.put(entry.getKey(), entry.getValue().get(0));
|
||||
}
|
||||
|
||||
String encodingGzip = "gzip";
|
||||
|
||||
if (encodingGzip.equals(respHeaders.get(HttpHeaders.CONTENT_ENCODING))) {
|
||||
inputStream = new GZIPInputStream(inputStream);
|
||||
}
|
||||
HttpResult httpResult = new HttpResult(respCode, IoUtils.toString(inputStream, getCharset(conn)), respHeaders);
|
||||
|
||||
//InputStream from HttpURLConnection can be closed automatically,but new GZIPInputStream can't be closed automatically
|
||||
//so needs to close it manually
|
||||
if (inputStream instanceof GZIPInputStream) {
|
||||
inputStream.close();
|
||||
}
|
||||
return httpResult;
|
||||
}
|
||||
|
||||
private static String getCharset(HttpURLConnection conn) {
|
||||
String contentType = conn.getContentType();
|
||||
if (StringUtils.isEmpty(contentType)) {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
String[] values = contentType.split(";");
|
||||
if (values.length == 0) {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
String charset = "UTF-8";
|
||||
for (String value : values) {
|
||||
value = value.trim();
|
||||
|
||||
if (value.toLowerCase().startsWith("charset=")) {
|
||||
charset = value.substring("charset=".length());
|
||||
}
|
||||
}
|
||||
|
||||
return charset;
|
||||
}
|
||||
|
||||
private static void setHeaders(HttpURLConnection conn, List<String> headers, String encoding) {
|
||||
if (null != headers) {
|
||||
for (Iterator<String> iter = headers.iterator(); iter.hasNext(); ) {
|
||||
conn.addRequestProperty(iter.next(), iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding);
|
||||
conn.addRequestProperty("Accept-Charset", encoding);
|
||||
}
|
||||
|
||||
private static String encodingParams(Map<String, String> params, String encoding)
|
||||
throws UnsupportedEncodingException {
|
||||
if (null == params || params.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
params.put("encoding", encoding);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
if (StringUtils.isEmpty(entry.getValue())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.append(entry.getKey()).append("=");
|
||||
sb.append(URLEncoder.encode(entry.getValue(), encoding));
|
||||
sb.append("&");
|
||||
}
|
||||
|
||||
if (sb.length() > 0) {
|
||||
sb = sb.deleteCharAt(sb.length() - 1);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static class HttpResult {
|
||||
|
||||
public final int code;
|
||||
|
||||
public final String content;
|
||||
|
||||
private final Map<String, String> respHeaders;
|
||||
|
||||
public HttpResult(int code, String content, Map<String, String> respHeaders) {
|
||||
this.code = code;
|
||||
this.content = content;
|
||||
this.respHeaders = respHeaders;
|
||||
}
|
||||
|
||||
public String getHeader(String name) {
|
||||
return respHeaders.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HttpResult{" + "code=" + code + ", content='" + content + '\'' + ", respHeaders=" + respHeaders
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
@ -43,8 +43,10 @@ import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.IPUtil;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
@ -107,6 +109,8 @@ public class NamingProxy implements Closeable {
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
private int maxRetry;
|
||||
|
||||
public NamingProxy(String namespaceId, String endpoint, String serverList, Properties properties) {
|
||||
|
||||
this.securityProxy = new SecurityProxy(properties, nacosRestTemplate);
|
||||
@ -114,6 +118,9 @@ public class NamingProxy implements Closeable {
|
||||
this.setServerPort(DEFAULT_SERVER_PORT);
|
||||
this.namespaceId = namespaceId;
|
||||
this.endpoint = endpoint;
|
||||
this.maxRetry = ConvertUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_REQUEST_DOMAIN_RETRY_COUNT,
|
||||
String.valueOf(UtilAndComs.REQUEST_DOMAIN_RETRY_COUNT)));
|
||||
|
||||
if (StringUtils.isNotEmpty(serverList)) {
|
||||
this.serverList = Arrays.asList(serverList.split(","));
|
||||
if (this.serverList.size() == 1) {
|
||||
@ -507,14 +514,24 @@ public class NamingProxy implements Closeable {
|
||||
|
||||
params.put(CommonParams.NAMESPACE_ID, getNamespaceId());
|
||||
|
||||
if (CollectionUtils.isEmpty(servers) && StringUtils.isEmpty(nacosDomain)) {
|
||||
if (CollectionUtils.isEmpty(servers) && StringUtils.isBlank(nacosDomain)) {
|
||||
throw new NacosException(NacosException.INVALID_PARAM, "no server available");
|
||||
}
|
||||
|
||||
NacosException exception = new NacosException();
|
||||
|
||||
if (servers != null && !servers.isEmpty()) {
|
||||
|
||||
if (StringUtils.isNotBlank(nacosDomain)) {
|
||||
for (int i = 0; i < maxRetry; i++) {
|
||||
try {
|
||||
return callServer(api, params, body, nacosDomain, method);
|
||||
} catch (NacosException e) {
|
||||
exception = e;
|
||||
if (NAMING_LOGGER.isDebugEnabled()) {
|
||||
NAMING_LOGGER.debug("request {} failed.", nacosDomain, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Random random = new Random(System.currentTimeMillis());
|
||||
int index = random.nextInt(servers.size());
|
||||
|
||||
@ -532,19 +549,6 @@ public class NamingProxy implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(nacosDomain)) {
|
||||
for (int i = 0; i < UtilAndComs.REQUEST_DOMAIN_RETRY_COUNT; i++) {
|
||||
try {
|
||||
return callServer(api, params, body, nacosDomain, method);
|
||||
} catch (NacosException e) {
|
||||
exception = e;
|
||||
if (NAMING_LOGGER.isDebugEnabled()) {
|
||||
NAMING_LOGGER.debug("request {} failed.", nacosDomain, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NAMING_LOGGER.error("request: {} failed, servers: {}, code: {}, msg: {}", api, servers, exception.getErrCode(),
|
||||
exception.getErrMsg());
|
||||
|
||||
@ -588,8 +592,8 @@ public class NamingProxy implements Closeable {
|
||||
if (curServer.startsWith(UtilAndComs.HTTPS) || curServer.startsWith(UtilAndComs.HTTP)) {
|
||||
url = curServer + api;
|
||||
} else {
|
||||
if (!curServer.contains(UtilAndComs.SERVER_ADDR_IP_SPLITER)) {
|
||||
curServer = curServer + UtilAndComs.SERVER_ADDR_IP_SPLITER + serverPort;
|
||||
if (!IPUtil.containsPort(curServer)) {
|
||||
curServer = curServer + IPUtil.IP_PORT_SPLITER + serverPort;
|
||||
}
|
||||
url = NamingHttpClientManager.getInstance().getPrefix() + curServer + api;
|
||||
}
|
||||
@ -715,6 +719,7 @@ public class NamingProxy implements Closeable {
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
||||
NamingHttpClientManager.getInstance().shutdown();
|
||||
SpasAdapter.freeCredentialInstance();
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.api.selector.ExpressionSelector;
|
||||
import com.alibaba.nacos.api.selector.NoneSelector;
|
||||
import com.alibaba.nacos.api.selector.SelectorType;
|
||||
import com.alibaba.nacos.client.utils.ContextPathUtil;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.client.utils.TemplateUtils;
|
||||
@ -100,15 +101,34 @@ public class InitUtils {
|
||||
|
||||
/**
|
||||
* Init web root context.
|
||||
*
|
||||
* @param properties properties
|
||||
* @since 1.4.1
|
||||
*/
|
||||
public static void initWebRootContext(Properties properties) {
|
||||
final String webContext = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
|
||||
TemplateUtils.stringNotEmptyAndThenExecute(webContext, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UtilAndComs.webContext = ContextPathUtil.normalizeContextPath(webContext);
|
||||
UtilAndComs.nacosUrlBase = UtilAndComs.webContext + "/v1/ns";
|
||||
UtilAndComs.nacosUrlInstance = UtilAndComs.nacosUrlBase + "/instance";
|
||||
}
|
||||
});
|
||||
initWebRootContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init web root context.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void initWebRootContext() {
|
||||
// support the web context with ali-yun if the app deploy by EDAS
|
||||
final String webContext = System.getProperty(SystemPropertyKeyConst.NAMING_WEB_CONTEXT);
|
||||
TemplateUtils.stringNotEmptyAndThenExecute(webContext, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UtilAndComs.webContext = webContext.indexOf("/") > -1 ? webContext : "/" + webContext;
|
||||
|
||||
UtilAndComs.webContext = ContextPathUtil.normalizeContextPath(webContext);
|
||||
UtilAndComs.nacosUrlBase = UtilAndComs.webContext + "/v1/ns";
|
||||
UtilAndComs.nacosUrlInstance = UtilAndComs.nacosUrlBase + "/instance";
|
||||
}
|
||||
|
@ -51,8 +51,6 @@ public class UtilAndComs {
|
||||
|
||||
public static final String NACOS_NAMING_LOG_LEVEL = "com.alibaba.nacos.naming.log.level";
|
||||
|
||||
public static final String SERVER_ADDR_IP_SPLITER = ":";
|
||||
|
||||
public static final int DEFAULT_CLIENT_BEAT_THREAD_COUNT =
|
||||
Runtime.getRuntime().availableProcessors() > 1 ? Runtime.getRuntime().availableProcessors() / 2 : 1;
|
||||
|
||||
|
@ -18,6 +18,7 @@ package com.alibaba.nacos.client.security;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.client.utils.ContextPathUtil;
|
||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
@ -88,8 +89,7 @@ public class SecurityProxy {
|
||||
public SecurityProxy(Properties properties, NacosRestTemplate nacosRestTemplate) {
|
||||
username = properties.getProperty(PropertyKeyConst.USERNAME, StringUtils.EMPTY);
|
||||
password = properties.getProperty(PropertyKeyConst.PASSWORD, StringUtils.EMPTY);
|
||||
contextPath = properties.getProperty(PropertyKeyConst.CONTEXT_PATH, "/nacos");
|
||||
contextPath = contextPath.startsWith("/") ? contextPath : "/" + contextPath;
|
||||
contextPath = ContextPathUtil.normalizeContextPath(properties.getProperty(PropertyKeyConst.CONTEXT_PATH, "/nacos"));
|
||||
this.nacosRestTemplate = nacosRestTemplate;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Context path Util.
|
||||
*
|
||||
* @author Wei.Wang
|
||||
*/
|
||||
public class ContextPathUtil {
|
||||
|
||||
private static final String ROOT_WEB_CONTEXT_PATH = "/";
|
||||
|
||||
/**
|
||||
* normalize context path.
|
||||
*
|
||||
* @param contextPath origin context path
|
||||
* @return normalized context path
|
||||
*/
|
||||
public static String normalizeContextPath(String contextPath) {
|
||||
if (StringUtils.isBlank(contextPath) || ROOT_WEB_CONTEXT_PATH.equals(contextPath)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return contextPath.startsWith("/") ? contextPath : "/" + contextPath;
|
||||
}
|
||||
}
|
@ -16,9 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.client.logging.AbstractNacosLogging;
|
||||
import com.alibaba.nacos.client.logging.log4j2.Log4J2NacosLogging;
|
||||
import com.alibaba.nacos.client.logging.logback.LogbackNacosLogging;
|
||||
import com.alibaba.nacos.client.logging.NacosLogging;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
@ -34,33 +32,7 @@ public class LogUtils {
|
||||
public static final Logger NAMING_LOGGER;
|
||||
|
||||
static {
|
||||
try {
|
||||
boolean isLogback = false;
|
||||
AbstractNacosLogging nacosLogging;
|
||||
|
||||
try {
|
||||
Class.forName("ch.qos.logback.classic.Logger");
|
||||
nacosLogging = new LogbackNacosLogging();
|
||||
isLogback = true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
nacosLogging = new Log4J2NacosLogging();
|
||||
}
|
||||
|
||||
try {
|
||||
nacosLogging.loadConfiguration();
|
||||
} catch (Throwable t) {
|
||||
if (isLogback) {
|
||||
getLogger(LogUtils.class)
|
||||
.warn("Load Logback Configuration of Nacos fail, message: {}", t.getMessage());
|
||||
} else {
|
||||
getLogger(LogUtils.class)
|
||||
.warn("Load Log4j Configuration of Nacos fail, message: {}", t.getMessage());
|
||||
}
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
getLogger(LogUtils.class).warn("Init Nacos Logging fail, message: {}", ex.getMessage());
|
||||
}
|
||||
|
||||
NacosLogging.getInstance().loadConfiguration();
|
||||
NAMING_LOGGER = getLogger("com.alibaba.nacos.client.naming");
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ public class DiskCacheTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
System.out.println(CACHE_DIR);
|
||||
serviceInfo = new ServiceInfo("testName", "testClusters");
|
||||
serviceInfo = new ServiceInfo("G@@testName", "testClusters");
|
||||
instance = new Instance();
|
||||
instance.setClusterName("testClusters");
|
||||
instance.setIp("1.1.1.1");
|
||||
@ -66,8 +66,8 @@ public class DiskCacheTest {
|
||||
DiskCache.write(serviceInfo, CACHE_DIR);
|
||||
Map<String, ServiceInfo> actual = DiskCache.read(CACHE_DIR);
|
||||
assertEquals(1, actual.size());
|
||||
assertTrue(actual.containsKey(serviceInfo.getKeyEncoded()));
|
||||
assertServiceInfo(actual.get(serviceInfo.getKeyEncoded()), serviceInfo);
|
||||
assertTrue(actual.containsKey(serviceInfo.getKey()));
|
||||
assertServiceInfo(actual.get(serviceInfo.getKey()), serviceInfo);
|
||||
}
|
||||
|
||||
private void assertServiceInfo(ServiceInfo actual, ServiceInfo expected) {
|
||||
|
@ -17,11 +17,18 @@
|
||||
package com.alibaba.nacos.client.naming.core;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.listener.AbstractEventListener;
|
||||
import com.alibaba.nacos.api.naming.listener.Event;
|
||||
import com.alibaba.nacos.api.naming.listener.EventListener;
|
||||
import com.alibaba.nacos.api.naming.listener.NamingEvent;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatInfo;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatReactor;
|
||||
import com.alibaba.nacos.client.naming.event.InstancesChangeEvent;
|
||||
import com.alibaba.nacos.client.naming.net.NamingProxy;
|
||||
import com.alibaba.nacos.common.utils.ClassUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -29,6 +36,13 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@ -44,9 +58,6 @@ public class HostReactorTest {
|
||||
@Mock
|
||||
private NamingProxy namingProxy;
|
||||
|
||||
@Mock
|
||||
private EventDispatcher eventDispatcher;
|
||||
|
||||
private HostReactor hostReactor;
|
||||
|
||||
private BeatReactor beatReactor;
|
||||
@ -64,7 +75,7 @@ public class HostReactorTest {
|
||||
beatInfo.setScheduled(false);
|
||||
beatInfo.setPeriod(1000L);
|
||||
beatReactor.addBeatInfo("testName", beatInfo);
|
||||
hostReactor = new HostReactor(eventDispatcher, namingProxy, beatReactor, CACHE_DIR);
|
||||
hostReactor = new HostReactor(namingProxy, beatReactor, CACHE_DIR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -83,6 +94,106 @@ public class HostReactorTest {
|
||||
assertServiceInfo(actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubscribe() throws InterruptedException {
|
||||
final AtomicInteger count = new AtomicInteger(1);
|
||||
EventListener eventListener = new EventListener() {
|
||||
@Override
|
||||
public void onEvent(Event event) {
|
||||
if (event instanceof NamingEvent) {
|
||||
List<Instance> instances = ((NamingEvent) event).getInstances();
|
||||
assertInstance(instances.get(0));
|
||||
Assert.assertEquals("nacos.publisher-" + ClassUtils.getCanonicalName(InstancesChangeEvent.class),
|
||||
Thread.currentThread().getName());
|
||||
count.decrementAndGet();
|
||||
}
|
||||
}
|
||||
};
|
||||
hostReactor.subscribe("testName", "testClusters", eventListener);
|
||||
hostReactor.processServiceJson(EXAMPLE);
|
||||
Thread.sleep(1000);
|
||||
Assert.assertEquals(0, count.intValue());
|
||||
hostReactor.unSubscribe("testName", "testClusters", eventListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncSubscribe() throws InterruptedException {
|
||||
final AtomicInteger count = new AtomicInteger(1);
|
||||
|
||||
ThreadFactory threadFactory = new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r);
|
||||
thread.setName("test-thread");
|
||||
return thread;
|
||||
}
|
||||
};
|
||||
|
||||
final Executor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(), threadFactory);
|
||||
EventListener eventListener = new AbstractEventListener() {
|
||||
|
||||
@Override
|
||||
public Executor getExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(Event event) {
|
||||
if (event instanceof NamingEvent) {
|
||||
List<Instance> instances = ((NamingEvent) event).getInstances();
|
||||
assertInstance(instances.get(0));
|
||||
Assert.assertEquals("test-thread", Thread.currentThread().getName());
|
||||
count.decrementAndGet();
|
||||
}
|
||||
}
|
||||
};
|
||||
hostReactor.subscribe("testName", "testClusters", eventListener);
|
||||
hostReactor.processServiceJson(EXAMPLE);
|
||||
Thread.sleep(1000);
|
||||
Assert.assertEquals(0, count.intValue());
|
||||
hostReactor.unSubscribe("testName", "testClusters", eventListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsubscribe() throws InterruptedException {
|
||||
Thread.sleep(1000);
|
||||
final AtomicInteger count = new AtomicInteger(1);
|
||||
EventListener eventListener = new EventListener() {
|
||||
@Override
|
||||
public void onEvent(Event event) {
|
||||
count.decrementAndGet();
|
||||
}
|
||||
};
|
||||
hostReactor.subscribe("testName", "testClusters", eventListener);
|
||||
hostReactor.processServiceJson(EXAMPLE);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
hostReactor.unSubscribe("testName", "testClusters", eventListener);
|
||||
hostReactor.processServiceJson(CHANGE_DATA_EXAMPLE);
|
||||
|
||||
Assert.assertEquals(0, count.intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSubscribeServices() {
|
||||
EventListener listener = new EventListener() {
|
||||
@Override
|
||||
public void onEvent(Event event) {
|
||||
}
|
||||
};
|
||||
hostReactor.subscribe("testGroup@@testName", "testClusters", listener);
|
||||
|
||||
Assert.assertEquals(1, hostReactor.getSubscribeServices().size());
|
||||
Assert.assertEquals("testName", hostReactor.getSubscribeServices().get(0).getName());
|
||||
Assert.assertEquals("testGroup", hostReactor.getSubscribeServices().get(0).getGroupName());
|
||||
Assert.assertEquals("testClusters", hostReactor.getSubscribeServices().get(0).getClusters());
|
||||
|
||||
hostReactor.unSubscribe("testGroup@@testName", "testClusters", listener);
|
||||
Assert.assertEquals(0, hostReactor.getSubscribeServices().size());
|
||||
}
|
||||
|
||||
private void assertServiceInfo(ServiceInfo actual) {
|
||||
assertEquals("testName", actual.getName());
|
||||
assertEquals("testClusters", actual.getClusters());
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* ContextPathUtil test.
|
||||
*
|
||||
* @author Wei.Wang
|
||||
* @date 2020/11/26 3:13 PM
|
||||
*/
|
||||
public class ContextPathUtilTest {
|
||||
|
||||
@Test
|
||||
public void testNormalizeContextPath() {
|
||||
assertEquals("/nacos", ContextPathUtil.normalizeContextPath("/nacos"));
|
||||
assertEquals("/nacos", ContextPathUtil.normalizeContextPath("nacos"));
|
||||
assertEquals("", ContextPathUtil.normalizeContextPath("/"));
|
||||
assertEquals("", ContextPathUtil.normalizeContextPath(""));
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -18,8 +18,8 @@ package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.http.client.request.DefaultHttpClientRequest;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.protocol.RequestContent;
|
||||
|
||||
/**
|
||||
* apache http client factory implements.
|
||||
@ -31,9 +31,10 @@ public abstract class AbstractApacheHttpClientFactory extends AbstractHttpClient
|
||||
@Override
|
||||
public final NacosRestTemplate createNacosRestTemplate() {
|
||||
final HttpClientConfig originalRequestConfig = buildHttpClientConfig();
|
||||
final RequestConfig requestConfig = getRequestConfig();
|
||||
return new NacosRestTemplate(assignLogger(), new DefaultHttpClientRequest(
|
||||
HttpClients.custom().setDefaultRequestConfig(requestConfig)
|
||||
HttpClients.custom()
|
||||
.addInterceptorLast(new RequestContent(true))
|
||||
.setDefaultRequestConfig(getRequestConfig())
|
||||
.setUserAgent(originalRequestConfig.getUserAgent())
|
||||
.setMaxConnTotal(originalRequestConfig.getMaxConnTotal())
|
||||
.setMaxConnPerRoute(originalRequestConfig.getMaxConnPerRoute())
|
||||
|
@ -27,6 +27,8 @@ import com.alibaba.nacos.common.tls.TlsSystemConfig;
|
||||
import com.alibaba.nacos.common.utils.BiConsumer;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
||||
import org.apache.http.protocol.RequestContent;
|
||||
import org.apache.http.impl.nio.reactor.IOReactorConfig;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
@ -68,19 +70,27 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory {
|
||||
@Override
|
||||
public NacosAsyncRestTemplate createNacosAsyncRestTemplate() {
|
||||
final HttpClientConfig originalRequestConfig = buildHttpClientConfig();
|
||||
final RequestConfig requestConfig = getRequestConfig();
|
||||
return new NacosAsyncRestTemplate(assignLogger(), new DefaultAsyncHttpClientRequest(
|
||||
HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig)
|
||||
HttpAsyncClients.custom()
|
||||
.addInterceptorLast(new RequestContent(true))
|
||||
.setDefaultIOReactorConfig(getIoReactorConfig())
|
||||
.setDefaultRequestConfig(getRequestConfig())
|
||||
.setMaxConnTotal(originalRequestConfig.getMaxConnTotal())
|
||||
.setMaxConnPerRoute(originalRequestConfig.getMaxConnPerRoute())
|
||||
.setUserAgent(originalRequestConfig.getUserAgent()).build()));
|
||||
}
|
||||
|
||||
protected IOReactorConfig getIoReactorConfig() {
|
||||
HttpClientConfig httpClientConfig = buildHttpClientConfig();
|
||||
return IOReactorConfig.custom().setIoThreadCount(httpClientConfig.getIoThreadCount()).build();
|
||||
}
|
||||
|
||||
protected RequestConfig getRequestConfig() {
|
||||
HttpClientConfig httpClientConfig = buildHttpClientConfig();
|
||||
return RequestConfig.custom().setConnectTimeout(httpClientConfig.getConTimeOutMillis())
|
||||
.setSocketTimeout(httpClientConfig.getReadTimeOutMillis())
|
||||
.setConnectionRequestTimeout(httpClientConfig.getConnectionRequestTimeout())
|
||||
.setContentCompressionEnabled(httpClientConfig.getContentCompressionEnabled())
|
||||
.setMaxRedirects(httpClientConfig.getMaxRedirects()).build();
|
||||
}
|
||||
|
||||
|
@ -1,124 +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;
|
||||
|
||||
import com.alibaba.nacos.common.http.handler.ResponseHandler;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.utils.HttpClientUtils;
|
||||
import org.apache.http.concurrent.FutureCallback;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Base http client.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.request.HttpClientRequest}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class BaseHttpClient {
|
||||
|
||||
protected <T> RestResult<T> execute(CloseableHttpClient httpClient, final Type type, HttpUriRequest request)
|
||||
throws Exception {
|
||||
CloseableHttpResponse response = httpClient.execute(request);
|
||||
try {
|
||||
final String body = EntityUtils.toString(response.getEntity());
|
||||
RestResult<T> data = ResponseHandler.convert(body, type);
|
||||
return data;
|
||||
} finally {
|
||||
HttpClientUtils.closeQuietly(response);
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> void execute(CloseableHttpAsyncClient httpAsyncClient, final Type type, final Callback<T> callback,
|
||||
final HttpUriRequest request) {
|
||||
if (!httpAsyncClient.isRunning()) {
|
||||
throw new IllegalArgumentException("httpAsyncClient already shutdown");
|
||||
}
|
||||
httpAsyncClient.execute(request, new FutureCallback<HttpResponse>() {
|
||||
|
||||
@Override
|
||||
public void completed(HttpResponse response) {
|
||||
try {
|
||||
final String body = EntityUtils.toString(response.getEntity());
|
||||
RestResult<T> data = ResponseHandler.convert(body, type);
|
||||
data.setCode(response.getStatusLine().getStatusCode());
|
||||
callback.onReceive(data);
|
||||
} catch (Throwable e) {
|
||||
callback.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception ex) {
|
||||
callback.onError(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
callback.onCancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected String buildUrl(String baseUrl, Query query) {
|
||||
if (query.isEmpty()) {
|
||||
return baseUrl;
|
||||
}
|
||||
return baseUrl + "?" + query.toQueryUrl();
|
||||
}
|
||||
|
||||
protected HttpRequestBase build(String url, Header header, String method) throws Exception {
|
||||
return build(url, header, null, method);
|
||||
}
|
||||
|
||||
protected HttpRequestBase build(String url, Header header, Object body, String method) throws Exception {
|
||||
|
||||
final BaseHttpMethod httpMethod = BaseHttpMethod.sourceOf(method);
|
||||
final HttpRequestBase httpRequestBase = httpMethod.init(url);
|
||||
HttpUtils.initRequestHeader(httpRequestBase, header);
|
||||
HttpUtils.initRequestEntity(httpRequestBase, body, header);
|
||||
return httpRequestBase;
|
||||
}
|
||||
|
||||
public static class HttpGetWithEntity extends HttpEntityEnclosingRequestBase {
|
||||
|
||||
public static final String METHOD_NAME = "GET";
|
||||
|
||||
public HttpGetWithEntity(String url) {
|
||||
super();
|
||||
setURI(URI.create(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -18,10 +18,14 @@ 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.utils.ExceptionUtil;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Create a rest template to ensure that each custom client config and rest template are in one-to-one correspondence.
|
||||
@ -30,11 +34,24 @@ import java.util.Map;
|
||||
*/
|
||||
public final class HttpClientBeanHolder {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientBeanHolder.class);
|
||||
|
||||
private static final Map<String, NacosRestTemplate> SINGLETON_REST = new HashMap<String, NacosRestTemplate>(10);
|
||||
|
||||
private static final Map<String, NacosAsyncRestTemplate> SINGLETON_ASYNC_REST = new HashMap<String, NacosAsyncRestTemplate>(
|
||||
10);
|
||||
|
||||
private static final AtomicBoolean ALREADY_SHUTDOWN = new AtomicBoolean(false);
|
||||
|
||||
static {
|
||||
ThreadUtils.addShutdownHook(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
shutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static NacosRestTemplate getNacosRestTemplate(Logger logger) {
|
||||
return getNacosRestTemplate(new DefaultHttpClientFactory(logger));
|
||||
}
|
||||
@ -81,6 +98,22 @@ public final class HttpClientBeanHolder {
|
||||
return nacosAsyncRestTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown common http client.
|
||||
*/
|
||||
private static void shutdown() {
|
||||
if (!ALREADY_SHUTDOWN.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
LOGGER.warn("[HttpClientBeanHolder] Start destroying common HttpClient");
|
||||
try {
|
||||
shutdown(DefaultHttpClientFactory.class.getName());
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error("An exception occurred when the common HTTP client was closed : {}", ExceptionUtil.getStackTrace(ex));
|
||||
}
|
||||
LOGGER.warn("[HttpClientBeanHolder] Destruction of the end");
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown http client holder and close remove template.
|
||||
*
|
||||
|
@ -65,13 +65,24 @@ public class HttpClientConfig {
|
||||
*/
|
||||
private final int maxConnPerRoute;
|
||||
|
||||
/**
|
||||
* is HTTP compression enabled.
|
||||
*/
|
||||
private final boolean contentCompressionEnabled;
|
||||
|
||||
/**
|
||||
* io thread count.
|
||||
*/
|
||||
private final int ioThreadCount;
|
||||
|
||||
/**
|
||||
* user agent.
|
||||
*/
|
||||
private final String userAgent;
|
||||
|
||||
public HttpClientConfig(int conTimeOutMillis, int readTimeOutMillis, long connTimeToLive, TimeUnit timeUnit,
|
||||
int connectionRequestTimeout, int maxRedirects, int maxConnTotal, int maxConnPerRoute, String userAgent) {
|
||||
int connectionRequestTimeout, int maxRedirects, int maxConnTotal, int maxConnPerRoute,
|
||||
boolean contentCompressionEnabled, int ioThreadCount, String userAgent) {
|
||||
this.conTimeOutMillis = conTimeOutMillis;
|
||||
this.readTimeOutMillis = readTimeOutMillis;
|
||||
this.connTimeToLive = connTimeToLive;
|
||||
@ -80,6 +91,8 @@ public class HttpClientConfig {
|
||||
this.maxRedirects = maxRedirects;
|
||||
this.maxConnTotal = maxConnTotal;
|
||||
this.maxConnPerRoute = maxConnPerRoute;
|
||||
this.contentCompressionEnabled = contentCompressionEnabled;
|
||||
this.ioThreadCount = ioThreadCount;
|
||||
this.userAgent = userAgent;
|
||||
}
|
||||
|
||||
@ -115,6 +128,14 @@ public class HttpClientConfig {
|
||||
return maxConnPerRoute;
|
||||
}
|
||||
|
||||
public boolean getContentCompressionEnabled() {
|
||||
return contentCompressionEnabled;
|
||||
}
|
||||
|
||||
public int getIoThreadCount() {
|
||||
return ioThreadCount;
|
||||
}
|
||||
|
||||
public String getUserAgent() {
|
||||
return userAgent;
|
||||
}
|
||||
@ -141,6 +162,10 @@ public class HttpClientConfig {
|
||||
|
||||
private int maxConnPerRoute = 0;
|
||||
|
||||
private boolean contentCompressionEnabled = true;
|
||||
|
||||
private int ioThreadCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
private String userAgent;
|
||||
|
||||
public HttpClientConfigBuilder setConTimeOutMillis(int conTimeOutMillis) {
|
||||
@ -158,7 +183,7 @@ public class HttpClientConfig {
|
||||
this.connTimeToLiveTimeUnit = connTimeToLiveTimeUnit;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public HttpClientConfigBuilder setConnectionRequestTimeout(int connectionRequestTimeout) {
|
||||
this.connectionRequestTimeout = connectionRequestTimeout;
|
||||
return this;
|
||||
@ -179,14 +204,30 @@ public class HttpClientConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfigBuilder setContentCompressionEnabled(boolean contentCompressionEnabled) {
|
||||
this.contentCompressionEnabled = contentCompressionEnabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfigBuilder setIoThreadCount(int ioThreadCount) {
|
||||
this.ioThreadCount = ioThreadCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfigBuilder setUserAgent(String userAgent) {
|
||||
this.userAgent = userAgent;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* build http client config.
|
||||
*
|
||||
* @return HttpClientConfig
|
||||
*/
|
||||
public HttpClientConfig build() {
|
||||
return new HttpClientConfig(conTimeOutMillis, readTimeOutMillis, connTimeToLive, connTimeToLiveTimeUnit,
|
||||
connectionRequestTimeout, maxRedirects, maxConnTotal, maxConnPerRoute, userAgent);
|
||||
connectionRequestTimeout, maxRedirects, maxConnTotal, maxConnPerRoute, contentCompressionEnabled,
|
||||
ioThreadCount, userAgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,88 +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;
|
||||
|
||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Use the same HttpClient object in the same space.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link HttpClientBeanHolder}
|
||||
*/
|
||||
@Deprecated
|
||||
public class HttpClientManager {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientManager.class);
|
||||
|
||||
private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000);
|
||||
|
||||
private static final RequestConfig DEFAULT_CONFIG = RequestConfig.custom().setConnectTimeout(TIMEOUT)
|
||||
.setSocketTimeout(TIMEOUT << 1).build();
|
||||
|
||||
private static final NSyncHttpClient SYNC_HTTP_CLIENT = new NacosSyncHttpClient(
|
||||
HttpClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
|
||||
|
||||
private static final NAsyncHttpClient ASYNC_HTTP_CLIENT = new NacosAsyncHttpClient(
|
||||
HttpAsyncClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
|
||||
|
||||
private static final AtomicBoolean ALREADY_SHUTDOWN = new AtomicBoolean(false);
|
||||
|
||||
static {
|
||||
ThreadUtils.addShutdownHook(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
shutdown();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static NSyncHttpClient getSyncHttpClient() {
|
||||
return SYNC_HTTP_CLIENT;
|
||||
}
|
||||
|
||||
public static NAsyncHttpClient getAsyncHttpClient() {
|
||||
return ASYNC_HTTP_CLIENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown http client manager and close http client.
|
||||
*/
|
||||
public static void shutdown() {
|
||||
if (!ALREADY_SHUTDOWN.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
LOGGER.warn("[HttpClientManager] Start destroying HttpClient");
|
||||
try {
|
||||
SYNC_HTTP_CLIENT.close();
|
||||
ASYNC_HTTP_CLIENT.close();
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error("An exception occurred when the HTTP client was closed : {}", ExceptionUtil.getStackTrace(ex));
|
||||
}
|
||||
LOGGER.warn("[HttpClientManager] Destruction of the end");
|
||||
}
|
||||
|
||||
}
|
@ -27,12 +27,14 @@ import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.conn.ConnectTimeoutException;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLDecoder;
|
||||
@ -42,6 +44,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@ -58,7 +61,7 @@ public final class HttpUtils {
|
||||
* Init http header.
|
||||
*
|
||||
* @param requestBase requestBase {@link HttpRequestBase}
|
||||
* @param header header
|
||||
* @param header header
|
||||
*/
|
||||
public static void initRequestHeader(HttpRequestBase requestBase, Header header) {
|
||||
Iterator<Map.Entry<String, String>> iterator = header.iterator();
|
||||
@ -72,8 +75,8 @@ public final class HttpUtils {
|
||||
* Init http entity.
|
||||
*
|
||||
* @param requestBase requestBase {@link HttpRequestBase}
|
||||
* @param body body
|
||||
* @param header request header
|
||||
* @param body body
|
||||
* @param header request header
|
||||
* @throws Exception exception
|
||||
*/
|
||||
public static void initRequestEntity(HttpRequestBase requestBase, Object body, Header header) throws Exception {
|
||||
@ -88,7 +91,8 @@ public final class HttpUtils {
|
||||
if (body instanceof byte[]) {
|
||||
entity = new ByteArrayEntity((byte[]) body, contentType);
|
||||
} else {
|
||||
entity = new StringEntity(body instanceof String ? (String) body : JacksonUtils.toJson(body), contentType);
|
||||
entity = new StringEntity(body instanceof String ? (String) body : JacksonUtils.toJson(body),
|
||||
contentType);
|
||||
}
|
||||
request.setEntity(entity);
|
||||
}
|
||||
@ -98,11 +102,12 @@ public final class HttpUtils {
|
||||
* Init request from entity map.
|
||||
*
|
||||
* @param requestBase requestBase {@link HttpRequestBase}
|
||||
* @param body body map
|
||||
* @param charset charset of entity
|
||||
* @param body body map
|
||||
* @param charset charset of entity
|
||||
* @throws Exception exception
|
||||
*/
|
||||
public static void initRequestFromEntity(HttpRequestBase requestBase, Map<String, String> body, String charset) throws Exception {
|
||||
public static void initRequestFromEntity(HttpRequestBase requestBase, Map<String, String> body, String charset)
|
||||
throws Exception {
|
||||
if (body == null || body.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@ -244,6 +249,17 @@ public final class HttpUtils {
|
||||
return new URI(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP request exception is a timeout exception.
|
||||
*
|
||||
* @param throwable http request throwable
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isTimeoutException(Throwable throwable) {
|
||||
return throwable instanceof SocketTimeoutException || throwable instanceof ConnectTimeoutException
|
||||
|| throwable instanceof TimeoutException || throwable.getCause() instanceof TimeoutException;
|
||||
}
|
||||
|
||||
private static String innerDecode(String pre, String now, String encode) throws UnsupportedEncodingException {
|
||||
// Because the data may be encoded by the URL more than once,
|
||||
// it needs to be decoded recursively until it is fully successful
|
||||
@ -254,4 +270,5 @@ public final class HttpUtils {
|
||||
now = URLDecoder.decode(now, encode);
|
||||
return innerDecode(pre, now, encode);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,95 +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;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Nacos async http client interface.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("all")
|
||||
public interface NAsyncHttpClient extends NHttpClient {
|
||||
|
||||
/**
|
||||
* http get
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void get(String url, Header header, Query query, Type token, Callback<T> callback) throws Exception;
|
||||
|
||||
/**
|
||||
* get request, may be pulling a lot of data
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body get with body
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void getLarge(String url, Header header, Query query, Object body, Type token, Callback<T> callback)
|
||||
throws Exception;
|
||||
|
||||
/**
|
||||
* http delete
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void delete(String url, Header header, Query query, Type token, Callback<T> callback) throws Exception;
|
||||
|
||||
/**
|
||||
* http put
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void put(String url, Header header, Query query, Object body, Type token, Callback<T> callback)
|
||||
throws Exception;
|
||||
|
||||
/**
|
||||
* http post
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param token return type
|
||||
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
<T> void post(String url, Header header, Query query, Object body, Type token, Callback<T> callback)
|
||||
throws Exception;
|
||||
|
||||
}
|
@ -1,98 +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;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Nacos sync http client.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.NacosRestTemplate}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("all")
|
||||
public interface NSyncHttpClient extends NHttpClient {
|
||||
|
||||
/**
|
||||
* http get
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param token return type
|
||||
* @return {@link RestResult <T>}
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> get(String url, Header header, Query query, Type token) throws Exception;
|
||||
|
||||
/**
|
||||
* get request, may be pulling a lot of data
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body get with body
|
||||
* @param token return type
|
||||
* @return {@link RestResult <T>}
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> getLarge(String url, Header header, Query query, Object body, Type token) throws Exception;
|
||||
|
||||
/**
|
||||
* http delete
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param token return type
|
||||
* @return {@link RestResult <T>}
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> delete(String url, Header header, Query query, Type token) throws Exception;
|
||||
|
||||
/**
|
||||
* http put
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param token return type
|
||||
* @return {@link RestResult}
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> put(String url, Header header, Query query, Object body, Type token) throws Exception;
|
||||
|
||||
/**
|
||||
* http post
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param token return type
|
||||
* @return {@link RestResult}
|
||||
* @throws Exception
|
||||
*/
|
||||
<T> RestResult<T> post(String url, Header header, Query query, Object body, Type token) throws Exception;
|
||||
|
||||
}
|
@ -1,83 +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;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Nacos async http client.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.request.DefaultAsyncHttpClientRequest}
|
||||
*/
|
||||
@Deprecated
|
||||
class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpClient {
|
||||
|
||||
private CloseableHttpAsyncClient asyncClient;
|
||||
|
||||
NacosAsyncHttpClient(CloseableHttpAsyncClient asyncClient) {
|
||||
this.asyncClient = asyncClient;
|
||||
this.asyncClient.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void get(final String url, final Header header, final Query query, final Type token,
|
||||
final Callback<T> callback) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.GET);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void getLarge(final String url, final Header header, final Query query, final Object body,
|
||||
final Type token, final Callback<T> callback) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.GET_LARGE);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void delete(final String url, final Header header, final Query query, final Type token,
|
||||
final Callback<T> callback) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.DELETE);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void put(final String url, final Header header, final Query query, final Object body, final Type token,
|
||||
final Callback<T> callback) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.PUT);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void post(final String url, final Header header, final Query query, final Object body, final Type token,
|
||||
final Callback<T> callback) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.POST);
|
||||
execute(asyncClient, token, callback, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
asyncClient.close();
|
||||
}
|
||||
}
|
@ -1,83 +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;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Nacos sync http client.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.request.JdkHttpClientRequest}
|
||||
*/
|
||||
@Deprecated
|
||||
class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClient {
|
||||
|
||||
private CloseableHttpClient client;
|
||||
|
||||
NacosSyncHttpClient(CloseableHttpClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> RestResult<T> get(final String url, final Header header, final Query query, final Type token)
|
||||
throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.GET);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> RestResult<T> getLarge(String url, Header header, Query query, Object body, Type token)
|
||||
throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.GET_LARGE);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> RestResult<T> delete(final String url, final Header header, final Query query, final Type token)
|
||||
throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.DELETE);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> RestResult<T> put(final String url, final Header header, final Query query, final Object body,
|
||||
final Type token) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.PUT);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> RestResult<T> post(final String url, final Header header, final Query query, final Object body,
|
||||
final Type token) throws Exception {
|
||||
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.POST);
|
||||
return execute(client, token, requestBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
client.close();
|
||||
}
|
||||
}
|
@ -24,12 +24,14 @@ import com.alibaba.nacos.common.http.client.response.JdkHttpClientResponse;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
@ -101,9 +103,10 @@ public class JdkHttpClientRequest implements HttpClientRequest {
|
||||
conn.setDoOutput(true);
|
||||
byte[] b = bodyStr.getBytes();
|
||||
conn.setRequestProperty("Content-Length", String.valueOf(b.length));
|
||||
conn.getOutputStream().write(b, 0, b.length);
|
||||
conn.getOutputStream().flush();
|
||||
conn.getOutputStream().close();
|
||||
OutputStream outputStream = conn.getOutputStream();
|
||||
outputStream.write(b, 0, b.length);
|
||||
outputStream.flush();
|
||||
IoUtils.closeQuietly(outputStream);
|
||||
}
|
||||
}
|
||||
conn.connect();
|
||||
|
@ -62,9 +62,7 @@ public interface HttpClientResponse extends Closeable {
|
||||
|
||||
/**
|
||||
* close response InputStream.
|
||||
*
|
||||
* @throws IOException ex
|
||||
*/
|
||||
@Override
|
||||
void close() throws IOException;
|
||||
void close();
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.common.model;
|
||||
|
||||
import com.alibaba.nacos.common.model.core.IResultCode;
|
||||
|
||||
/**
|
||||
* Rest result utils.
|
||||
*
|
||||
@ -31,6 +33,10 @@ public class RestResultUtils {
|
||||
return RestResult.<T>builder().withCode(200).withData(data).build();
|
||||
}
|
||||
|
||||
public static <T> RestResult<T> success(String msg, T data) {
|
||||
return RestResult.<T>builder().withCode(200).withMsg(msg).withData(data).build();
|
||||
}
|
||||
|
||||
public static <T> RestResult<T> success(int code, T data) {
|
||||
return RestResult.<T>builder().withCode(code).withData(data).build();
|
||||
}
|
||||
@ -54,5 +60,8 @@ public class RestResultUtils {
|
||||
public static <T> RestResult<T> failedWithMsg(int code, String errMsg) {
|
||||
return RestResult.<T>builder().withCode(code).withMsg(errMsg).build();
|
||||
}
|
||||
|
||||
|
||||
public static <T> RestResult<T> buildResult(IResultCode resultCode, T data) {
|
||||
return RestResult.<T>builder().withCode(resultCode.getCode()).withMsg(resultCode.getCodeMsg()).withData(data).build();
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.result.core;
|
||||
package com.alibaba.nacos.common.model.core;
|
||||
|
||||
/**
|
||||
* IResultCode.
|
@ -17,9 +17,9 @@
|
||||
package com.alibaba.nacos.common.notify;
|
||||
|
||||
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||
import com.alibaba.nacos.common.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import com.alibaba.nacos.common.utils.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -79,7 +79,7 @@ public class DefaultSharePublisher extends DefaultPublisher {
|
||||
try {
|
||||
Set<Subscriber> sets = subMappings.get(subSlowEventType);
|
||||
|
||||
if (sets != null && sets.contains(subscriber)) {
|
||||
if (sets != null) {
|
||||
sets.remove(subscriber);
|
||||
}
|
||||
} finally {
|
||||
|
@ -71,4 +71,5 @@ public interface EventPublisher extends Closeable {
|
||||
* @param event {@link Event}
|
||||
*/
|
||||
void notifySubscriber(Subscriber subscriber, Event event);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ package com.alibaba.nacos.common.notify;
|
||||
|
||||
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
|
||||
import com.alibaba.nacos.common.JustForTest;
|
||||
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||
import com.alibaba.nacos.common.notify.listener.SmartSubscriber;
|
||||
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||
import com.alibaba.nacos.common.utils.BiFunction;
|
||||
import com.alibaba.nacos.common.utils.ClassUtils;
|
||||
import com.alibaba.nacos.common.utils.MapUtils;
|
||||
@ -27,10 +27,10 @@ import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@ -170,7 +170,6 @@ public class NotifyCenter {
|
||||
* @param <T> event type
|
||||
*/
|
||||
public static <T> void registerSubscriber(final Subscriber consumer) {
|
||||
final Class<? extends Event> cls = consumer.subscribeType();
|
||||
// If you want to listen to multiple events, you do it separately,
|
||||
// based on subclass's subscribeTypes method return list, it can register to publisher.
|
||||
if (consumer instanceof SmartSubscriber) {
|
||||
@ -186,16 +185,17 @@ public class NotifyCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ClassUtils.isAssignableFrom(SlowEvent.class, cls)) {
|
||||
INSTANCE.sharePublisher.addSubscriber(consumer, cls);
|
||||
final Class<? extends Event> subscribeType = consumer.subscribeType();
|
||||
if (ClassUtils.isAssignableFrom(SlowEvent.class, subscribeType)) {
|
||||
INSTANCE.sharePublisher.addSubscriber(consumer, subscribeType);
|
||||
return;
|
||||
}
|
||||
|
||||
addSubscriber(consumer, consumer.subscribeType());
|
||||
addSubscriber(consumer, subscribeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a subscriber to pusblisher.
|
||||
* Add a subscriber to publisher.
|
||||
*
|
||||
* @param consumer subscriber instance.
|
||||
* @param subscribeType subscribeType.
|
||||
@ -217,7 +217,6 @@ public class NotifyCenter {
|
||||
* @param consumer subscriber instance.
|
||||
*/
|
||||
public static <T> void deregisterSubscriber(final Subscriber consumer) {
|
||||
final Class<? extends Event> cls = consumer.subscribeType();
|
||||
if (consumer instanceof SmartSubscriber) {
|
||||
for (Class<? extends Event> subscribeType : ((SmartSubscriber) consumer).subscribeTypes()) {
|
||||
if (ClassUtils.isAssignableFrom(SlowEvent.class, subscribeType)) {
|
||||
@ -229,15 +228,16 @@ public class NotifyCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ClassUtils.isAssignableFrom(SlowEvent.class, cls)) {
|
||||
INSTANCE.sharePublisher.removeSubscriber(consumer, cls);
|
||||
final Class<? extends Event> subscribeType = consumer.subscribeType();
|
||||
if (ClassUtils.isAssignableFrom(SlowEvent.class, subscribeType)) {
|
||||
INSTANCE.sharePublisher.removeSubscriber(consumer, subscribeType);
|
||||
return;
|
||||
}
|
||||
|
||||
if (removeSubscriber(consumer, consumer.subscribeType())) {
|
||||
if (removeSubscriber(consumer, subscribeType)) {
|
||||
return;
|
||||
}
|
||||
throw new NoSuchElementException("The subcriber has no event publisher");
|
||||
throw new NoSuchElementException("The subscriber has no event publisher");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,12 +250,11 @@ public class NotifyCenter {
|
||||
private static boolean removeSubscriber(final Subscriber consumer, Class<? extends Event> subscribeType) {
|
||||
|
||||
final String topic = ClassUtils.getCanonicalName(subscribeType);
|
||||
if (INSTANCE.publisherMap.containsKey(topic)) {
|
||||
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
||||
publisher.removeSubscriber(consumer);
|
||||
EventPublisher eventPublisher = INSTANCE.publisherMap.get(topic);
|
||||
if (eventPublisher != null) {
|
||||
eventPublisher.removeSubscriber(consumer);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -281,16 +280,16 @@ public class NotifyCenter {
|
||||
* @param event event instance.
|
||||
*/
|
||||
private static boolean publishEvent(final Class<? extends Event> eventType, final Event event) {
|
||||
final String topic = ClassUtils.getCanonicalName(eventType);
|
||||
if (ClassUtils.isAssignableFrom(SlowEvent.class, eventType)) {
|
||||
return INSTANCE.sharePublisher.publish(event);
|
||||
}
|
||||
|
||||
if (INSTANCE.publisherMap.containsKey(topic)) {
|
||||
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
||||
final String topic = ClassUtils.getCanonicalName(eventType);
|
||||
|
||||
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
||||
if (publisher != null) {
|
||||
return publisher.publish(event);
|
||||
}
|
||||
|
||||
LOGGER.warn("There are no [{}] publishers for this event, please register", topic);
|
||||
return false;
|
||||
}
|
||||
@ -321,8 +320,7 @@ public class NotifyCenter {
|
||||
// MapUtils.computeIfAbsent is a unsafe method.
|
||||
MapUtils.computeIfAbsent(INSTANCE.publisherMap, topic, publisherFactory, eventType, queueMaxSize);
|
||||
}
|
||||
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
||||
return publisher;
|
||||
return INSTANCE.publisherMap.get(topic);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.common.tls;
|
||||
|
||||
import com.alibaba.nacos.common.utils.IpUtils;
|
||||
import com.alibaba.nacos.common.utils.IPUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -38,7 +38,7 @@ public final class SelfHostnameVerifier implements HostnameVerifier {
|
||||
|
||||
private static ConcurrentHashMap<String, Boolean> hosts = new ConcurrentHashMap<String, Boolean>();
|
||||
|
||||
private static final String[] LOCALHOST_HOSTNAME = new String[] {"localhost", "127.0.0.1"};
|
||||
private static final String[] LOCALHOST_HOSTNAME = new String[] {"localhost", IPUtil.localHostIP()};
|
||||
|
||||
public SelfHostnameVerifier(HostnameVerifier hv) {
|
||||
this.hv = hv;
|
||||
@ -49,22 +49,22 @@ public final class SelfHostnameVerifier implements HostnameVerifier {
|
||||
if (LOCALHOST_HOSTNAME[0].equalsIgnoreCase(hostname) || LOCALHOST_HOSTNAME[1].equals(hostname)) {
|
||||
return true;
|
||||
}
|
||||
if (isIpv4(hostname)) {
|
||||
if (isIP(hostname)) {
|
||||
return true;
|
||||
}
|
||||
return hv.verify(hostname, session);
|
||||
}
|
||||
|
||||
private static boolean isIpv4(String host) {
|
||||
private static boolean isIP(String host) {
|
||||
if (host == null || host.isEmpty()) {
|
||||
LOGGER.warn("host is empty, isIPv4 = false");
|
||||
LOGGER.warn("host is empty, isIP = false");
|
||||
return false;
|
||||
}
|
||||
Boolean cacheHostVerify = hosts.get(host);
|
||||
if (cacheHostVerify != null) {
|
||||
return cacheHostVerify;
|
||||
}
|
||||
boolean isIp = IpUtils.isIpv4(host);
|
||||
boolean isIp = IPUtil.isIP(host);
|
||||
hosts.putIfAbsent(host, isIp);
|
||||
return isIp;
|
||||
}
|
||||
|
@ -27,6 +27,11 @@ import java.io.PrintStream;
|
||||
*/
|
||||
public class ExceptionUtil {
|
||||
|
||||
/**
|
||||
* Represents an empty exception, that is, no exception occurs, only a constant.
|
||||
*/
|
||||
public static final Exception NONE_EXCEPTION = new RuntimeException("");
|
||||
|
||||
public static String getAllExceptionMsg(Throwable e) {
|
||||
Throwable cause = e;
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
|
222
common/src/main/java/com/alibaba/nacos/common/utils/IPUtil.java
Normal file
222
common/src/main/java/com/alibaba/nacos/common/utils/IPUtil.java
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* ip tool.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@SuppressWarnings({"checkstyle:AbbreviationAsWordInName", "PMD.ClassNamingShouldBeCamelRule"})
|
||||
public class IPUtil {
|
||||
|
||||
public static final boolean PREFER_IPV6_ADDRESSES = Boolean.parseBoolean(System.getProperty("java.net.preferIPv6Addresses"));
|
||||
|
||||
public static final String IPV6_START_MARK = "[";
|
||||
|
||||
public static final String IPV6_END_MARK = "]";
|
||||
|
||||
public static final String ILLEGAL_IP_PREFIX = "illegal ip: ";
|
||||
|
||||
public static final String IP_PORT_SPLITER = ":";
|
||||
|
||||
public static final int SPLIT_IP_PORT_RESULT_LENGTH = 2;
|
||||
|
||||
public static final String PERCENT_SIGN_IN_IPV6 = "%";
|
||||
|
||||
private static final String LOCAL_HOST_IP_V4 = "127.0.0.1";
|
||||
|
||||
private static final String LOCAL_HOST_IP_V6 = "[::1]";
|
||||
|
||||
private static Pattern ipv4Pattern = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
|
||||
|
||||
private static final int IPV4_ADDRESS_LENGTH = 4;
|
||||
|
||||
private static final int IPV6_ADDRESS_LENGTH = 16;
|
||||
|
||||
private static final String CHECK_OK = "ok";
|
||||
|
||||
/**
|
||||
* get localhost ip.
|
||||
* @return java.lang.String
|
||||
*/
|
||||
public static String localHostIP() {
|
||||
if (PREFER_IPV6_ADDRESSES) {
|
||||
return LOCAL_HOST_IP_V6;
|
||||
}
|
||||
return LOCAL_HOST_IP_V4;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the ip address is IPv4.
|
||||
*
|
||||
* @param addr ip address
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isIPv4(String addr) {
|
||||
try {
|
||||
return InetAddress.getByName(addr).getAddress().length == IPV4_ADDRESS_LENGTH;
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the ip address is IPv6.
|
||||
*
|
||||
* @param addr ip address
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isIPv6(String addr) {
|
||||
try {
|
||||
return InetAddress.getByName(addr).getAddress().length == IPV6_ADDRESS_LENGTH;
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the str is ip address (IPv4 or IPv6).
|
||||
*
|
||||
* @param addr ip address str
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isIP(String addr) {
|
||||
try {
|
||||
InetAddress.getByName(addr);
|
||||
return true;
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the address contains a port.
|
||||
* 2020/9/3 14:53
|
||||
* @param address address string
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean containsPort(String address) {
|
||||
return splitIPPortStr(address).length == SPLIT_IP_PORT_RESULT_LENGTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split IP and port strings, support IPv4 and IPv6, IP in IPv6 must be enclosed with [].
|
||||
*
|
||||
* @param str ip and port string
|
||||
* @return java.lang.String[]
|
||||
*/
|
||||
public static String[] splitIPPortStr(String str) {
|
||||
if (StringUtils.isBlank(str)) {
|
||||
throw new IllegalArgumentException("ip and port string cannot be empty!");
|
||||
}
|
||||
String[] serverAddrArr;
|
||||
if (str.startsWith(IPV6_START_MARK) && StringUtils.containsIgnoreCase(str, IPV6_END_MARK)) {
|
||||
if (str.endsWith(IPV6_END_MARK)) {
|
||||
serverAddrArr = new String[1];
|
||||
serverAddrArr[0] = str;
|
||||
} else {
|
||||
serverAddrArr = new String[2];
|
||||
serverAddrArr[0] = str.substring(0, (str.indexOf(IPV6_END_MARK) + 1));
|
||||
serverAddrArr[1] = str.substring((str.indexOf(IPV6_END_MARK) + 2));
|
||||
}
|
||||
if (!isIPv6(serverAddrArr[0])) {
|
||||
throw new IllegalArgumentException("The IPv6 address(\"" + serverAddrArr[0] + "\") is incorrect.");
|
||||
}
|
||||
} else {
|
||||
serverAddrArr = str.split(":");
|
||||
if (serverAddrArr.length > SPLIT_IP_PORT_RESULT_LENGTH) {
|
||||
throw new IllegalArgumentException("The IP address(\"" + str
|
||||
+ "\") is incorrect. If it is an IPv6 address, please use [] to enclose the IP part!");
|
||||
}
|
||||
if (!isIPv4(serverAddrArr[0])) {
|
||||
throw new IllegalArgumentException("The IPv4 address(\"" + serverAddrArr[0] + "\") is incorrect.");
|
||||
}
|
||||
}
|
||||
return serverAddrArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the IP from the string containing the IP address.
|
||||
* @param str string containing IP address
|
||||
* @return java.lang.String
|
||||
*/
|
||||
public static String getIPFromString(String str) {
|
||||
if (StringUtils.isBlank(str)) {
|
||||
return "";
|
||||
}
|
||||
String result = "";
|
||||
if (StringUtils.containsIgnoreCase(str, IPV6_START_MARK) && StringUtils.containsIgnoreCase(str, IPV6_END_MARK)) {
|
||||
result = str.substring(str.indexOf(IPV6_START_MARK), (str.indexOf(IPV6_END_MARK) + 1));
|
||||
if (!isIPv6(result)) {
|
||||
result = "";
|
||||
}
|
||||
} else {
|
||||
Matcher m = ipv4Pattern.matcher(str);
|
||||
if (m.find()) {
|
||||
result = m.group();
|
||||
if (!isIPv4(result)) {
|
||||
result = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check ips.
|
||||
*
|
||||
* @param ips ips
|
||||
* @return 'ok' if check passed, otherwise illegal ip
|
||||
*/
|
||||
public static String checkIPs(String... ips) {
|
||||
|
||||
if (ips == null || ips.length == 0) {
|
||||
|
||||
return CHECK_OK;
|
||||
}
|
||||
// illegal response
|
||||
StringBuilder illegalResponse = new StringBuilder();
|
||||
for (String ip : ips) {
|
||||
if (IPUtil.isIP(ip)) {
|
||||
continue;
|
||||
}
|
||||
illegalResponse.append(ip + ",");
|
||||
}
|
||||
|
||||
if (illegalResponse.length() == 0) {
|
||||
return CHECK_OK;
|
||||
}
|
||||
|
||||
return ILLEGAL_IP_PREFIX + illegalResponse.substring(0, illegalResponse.length() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether checkIPs result is "ok".
|
||||
* @param checkIPsResult checkIPs result
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean checkOK(String checkIPsResult) {
|
||||
return CHECK_OK.equals(checkIPsResult);
|
||||
}
|
||||
|
||||
}
|
@ -63,12 +63,8 @@ public class IoUtils {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
if (gis != null) {
|
||||
gis.close();
|
||||
}
|
||||
closeQuietly(out);
|
||||
closeQuietly(gis);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -94,12 +90,8 @@ public class IoUtils {
|
||||
IoUtils.copy(gis, out);
|
||||
return out.toByteArray();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
if (gis != null) {
|
||||
gis.close();
|
||||
}
|
||||
closeQuietly(out);
|
||||
closeQuietly(gis);
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,9 +114,7 @@ public class IoUtils {
|
||||
os.write(data.getBytes(encoding));
|
||||
os.flush();
|
||||
} finally {
|
||||
if (null != os) {
|
||||
os.close();
|
||||
}
|
||||
closeQuietly(os);
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,12 +301,8 @@ public class IoUtils {
|
||||
sc = new FileInputStream(sf).getChannel();
|
||||
sc.transferTo(0, sc.size(), tc);
|
||||
} finally {
|
||||
if (null != sc) {
|
||||
sc.close();
|
||||
}
|
||||
if (null != tc) {
|
||||
tc.close();
|
||||
}
|
||||
closeQuietly(sc);
|
||||
closeQuietly(tc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,49 +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.utils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* ip tool.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class IpUtils {
|
||||
|
||||
private static final Pattern IPV4_PATTERN = Pattern
|
||||
.compile("^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$");
|
||||
|
||||
private static final Pattern IPV6_PATTERN = Pattern.compile("^([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}$");
|
||||
|
||||
public static boolean isIpv4(String addr) {
|
||||
return isMatch(addr, IPV4_PATTERN);
|
||||
}
|
||||
|
||||
public static boolean isIpv6(String addr) {
|
||||
return isMatch(addr, IPV6_PATTERN);
|
||||
}
|
||||
|
||||
private static boolean isMatch(String data, Pattern pattern) {
|
||||
if (StringUtils.isBlank(data)) {
|
||||
return false;
|
||||
}
|
||||
Matcher mat = pattern.matcher(data);
|
||||
return mat.find();
|
||||
}
|
||||
}
|
@ -131,7 +131,7 @@ public class MapUtils {
|
||||
*
|
||||
* @param target target Map data.
|
||||
* @param key map key.
|
||||
* @param mappingFunction funtion which is need to be executed.
|
||||
* @param mappingFunction function which is need to be executed.
|
||||
* @param param1 function's parameter value1.
|
||||
* @param param2 function's parameter value1.
|
||||
* @return
|
||||
@ -140,10 +140,11 @@ public class MapUtils {
|
||||
public static Object computeIfAbsent(Map target, Object key, BiFunction mappingFunction, Object param1,
|
||||
Object param2) {
|
||||
|
||||
Objects.requireNonNull(target, "target");
|
||||
Objects.requireNonNull(key, "key");
|
||||
Objects.requireNonNull(key, "mappingFunction");
|
||||
Objects.requireNonNull(key, "param1");
|
||||
Objects.requireNonNull(key, "param2");
|
||||
Objects.requireNonNull(mappingFunction, "mappingFunction");
|
||||
Objects.requireNonNull(param1, "param1");
|
||||
Objects.requireNonNull(param2, "param2");
|
||||
|
||||
Object val = target.get(key);
|
||||
if (val == null) {
|
||||
|
@ -14,9 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
/**
|
||||
* namespace(tenant) util.
|
@ -143,7 +143,7 @@ public class ResourceUtils {
|
||||
Properties props = new Properties();
|
||||
InputStream in = getResourceAsStream(loader, resource);
|
||||
props.load(in);
|
||||
in.close();
|
||||
IoUtils.closeQuietly(in);
|
||||
return props;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* test IpUtil.
|
||||
* @ClassName: IpUtilTest
|
||||
* @date 2020/9/3 10:31
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
|
||||
public class IPUtilTest {
|
||||
|
||||
@Test
|
||||
public void testIsIPv4() {
|
||||
Assert.assertTrue(IPUtil.isIPv4("127.0.0.1"));
|
||||
Assert.assertFalse(IPUtil.isIPv4("[::1]"));
|
||||
Assert.assertFalse(IPUtil.isIPv4("asdfasf"));
|
||||
Assert.assertFalse(IPUtil.isIPv4("ffgertert"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsIPv6() {
|
||||
Assert.assertTrue(IPUtil.isIPv6("[::1]"));
|
||||
Assert.assertFalse(IPUtil.isIPv6("127.0.0.1"));
|
||||
Assert.assertFalse(IPUtil.isIPv6("er34234"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsIP() {
|
||||
Assert.assertTrue(IPUtil.isIP("[::1]"));
|
||||
Assert.assertTrue(IPUtil.isIP("127.0.0.1"));
|
||||
Assert.assertFalse(IPUtil.isIP("er34234"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIPFromString() {
|
||||
Assert.assertEquals("[::1]", IPUtil.getIPFromString("http://[::1]:666/xzdsfasdf/awerwef" + "?eewer=2&xxx=3"));
|
||||
Assert.assertEquals("[::1]", IPUtil.getIPFromString(
|
||||
"jdbc:mysql://[::1]:3306/nacos_config_test?characterEncoding=utf8&connectTimeout=1000"
|
||||
+ "&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"));
|
||||
Assert.assertEquals("127.0.0.1",
|
||||
IPUtil.getIPFromString("http://127.0.0.1:666/xzdsfasdf/awerwef" + "?eewer=2&xxx=3"));
|
||||
Assert.assertEquals("127.0.0.1", IPUtil.getIPFromString(
|
||||
"jdbc:mysql://127.0.0.1:3306/nacos_config_test?characterEncoding=utf8&connectTimeout=1000"
|
||||
+ "&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"));
|
||||
|
||||
Assert.assertEquals("",
|
||||
IPUtil.getIPFromString("http://[dddd]:666/xzdsfasdf/awerwef" + "?eewer=2&xxx=3"));
|
||||
Assert.assertEquals("", IPUtil.getIPFromString(
|
||||
"jdbc:mysql://[127.0.0.1]:3306/nacos_config_test?characterEncoding=utf8&connectTimeout=1000"
|
||||
+ "&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"));
|
||||
Assert.assertEquals("", IPUtil.getIPFromString(
|
||||
"jdbc:mysql://666.288.333.444:3306/nacos_config_test?characterEncoding=utf8&connectTimeout=1000"
|
||||
+ "&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSplitIpPort() {
|
||||
checkSplitIPPortStr("[::1]:88", false, "[::1]", "88");
|
||||
checkSplitIPPortStr("[::1]", false, "[::1]");
|
||||
checkSplitIPPortStr("127.0.0.1:88", false, "127.0.0.1", "88");
|
||||
checkSplitIPPortStr("127.0.0.1", false, "127.0.0.1");
|
||||
checkSplitIPPortStr("[2001:db8:0:0:1:0:0:1]:88", false, "[2001:db8:0:0:1:0:0:1]", "88");
|
||||
checkSplitIPPortStr("[2001:0db8:0:0:1:0:0:1]:88", false, "[2001:0db8:0:0:1:0:0:1]", "88");
|
||||
checkSplitIPPortStr("[2001:db8::1:0:0:1]:88", false, "[2001:db8::1:0:0:1]", "88");
|
||||
checkSplitIPPortStr("[2001:db8::0:1:0:0:1]:88", false, "[2001:db8::0:1:0:0:1]", "88");
|
||||
checkSplitIPPortStr("[2001:0db8::1:0:0:1]:88", false, "[2001:0db8::1:0:0:1]", "88");
|
||||
checkSplitIPPortStr("[2001:db8:0:0:1::1]:88", false, "[2001:db8:0:0:1::1]", "88");
|
||||
checkSplitIPPortStr("[2001:db8:0000:0:1::1]:88", false, "[2001:db8:0000:0:1::1]", "88");
|
||||
checkSplitIPPortStr("[2001:DB8:0:0:1::1]:88", false, "[2001:DB8:0:0:1::1]", "88");
|
||||
checkSplitIPPortStr("[fe80::3ce6:7132:808e:707a%19]:88", false, "[fe80::3ce6:7132:808e:707a%19]", "88");
|
||||
|
||||
checkSplitIPPortStr("::1:88", true);
|
||||
checkSplitIPPortStr("[::1:88", true);
|
||||
checkSplitIPPortStr("[127.0.0.1]:88", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* checkSplitIpPortStr.
|
||||
* 2020/9/4 14:12
|
||||
* @param addr addr
|
||||
* @param isEx isEx
|
||||
* @param equalsStrs equalsStrs
|
||||
*/
|
||||
public static void checkSplitIPPortStr(String addr, boolean isEx, String... equalsStrs) {
|
||||
try {
|
||||
String[] array = IPUtil.splitIPPortStr(addr);
|
||||
Assert.assertTrue(array.length == equalsStrs.length);
|
||||
if (array.length > 1) {
|
||||
Assert.assertTrue(array[0].equals(equalsStrs[0]));
|
||||
Assert.assertTrue(array[1].equals(equalsStrs[1]));
|
||||
} else {
|
||||
Assert.assertTrue(array[0].equals(equalsStrs[0]));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (!isEx) {
|
||||
// No exception is expected here, but an exception has occurred
|
||||
Assert.assertTrue("Unexpected exception", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.utils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -65,10 +65,6 @@
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
|
@ -20,6 +20,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.nacos.auth.model.Resource;
|
||||
import com.alibaba.nacos.auth.parser.ResourceParser;
|
||||
import com.alibaba.nacos.common.utils.NamespaceUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
@ -35,7 +36,7 @@ public class ConfigResourceParser implements ResourceParser {
|
||||
@Override
|
||||
public String parseName(Object request) {
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
String namespaceId = req.getParameter("tenant");
|
||||
String namespaceId = NamespaceUtil.processNamespaceParameter(req.getParameter("tenant"));
|
||||
String groupName = req.getParameter("group");
|
||||
String dataId = req.getParameter("dataId");
|
||||
|
||||
|
@ -18,9 +18,9 @@ package com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.repository.embedded.EmbeddedStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.service.repository.embedded.DatabaseOperate;
|
||||
import com.alibaba.nacos.config.server.service.repository.embedded.EmbeddedStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.sql.EmbeddedStorageContextUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -28,6 +28,8 @@ import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.repository.RowMapperManager.PERMISSION_ROW_MAPPER;
|
||||
|
||||
@ -51,15 +53,17 @@ public class EmbeddedPermissionPersistServiceImpl implements PermissionPersistSe
|
||||
|
||||
String sqlCountRows = "select count(*) from permissions where ";
|
||||
String sqlFetchRows = "select role,resource,action from permissions where ";
|
||||
|
||||
String where = " role='" + role + "' ";
|
||||
|
||||
if (StringUtils.isBlank(role)) {
|
||||
|
||||
String where = " role= ? ";
|
||||
List<String> params = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(role)) {
|
||||
params = Collections.singletonList(role);
|
||||
} else {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
Page<PermissionInfo> pageInfo = helper
|
||||
.fetchPage(sqlCountRows + where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
.fetchPage(sqlCountRows + where, sqlFetchRows + where, params.toArray(), pageNo,
|
||||
pageSize, PERMISSION_ROW_MAPPER);
|
||||
|
||||
if (pageInfo == null) {
|
||||
|
@ -18,9 +18,9 @@ package com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.repository.embedded.EmbeddedStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.service.repository.embedded.DatabaseOperate;
|
||||
import com.alibaba.nacos.config.server.service.repository.embedded.EmbeddedStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.sql.EmbeddedStorageContextUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -28,6 +28,7 @@ import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.repository.RowMapperManager.ROLE_INFO_ROW_MAPPER;
|
||||
@ -74,14 +75,16 @@ public class EmbeddedRolePersistServiceImpl implements RolePersistService {
|
||||
|
||||
String sqlCountRows = "select count(*) from roles where ";
|
||||
String sqlFetchRows = "select role,username from roles where ";
|
||||
|
||||
String where = " username='" + username + "' ";
|
||||
|
||||
if (StringUtils.isBlank(username)) {
|
||||
|
||||
String where = " username= ? ";
|
||||
List<String> params = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(username)) {
|
||||
params = Collections.singletonList(username);
|
||||
} else {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
return helper.fetchPage(sqlCountRows + where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
return helper.fetchPage(sqlCountRows + where, sqlFetchRows + where, params.toArray(), pageNo,
|
||||
pageSize, ROLE_INFO_ROW_MAPPER);
|
||||
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ package com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnExternalStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.repository.extrnal.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.service.repository.extrnal.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -30,6 +30,8 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.repository.RowMapperManager.PERMISSION_ROW_MAPPER;
|
||||
|
||||
@ -57,16 +59,18 @@ public class ExternalPermissionPersistServiceImpl implements PermissionPersistSe
|
||||
|
||||
String sqlCountRows = "select count(*) from permissions where ";
|
||||
String sqlFetchRows = "select role,resource,action from permissions where ";
|
||||
|
||||
String where = " role='" + role + "' ";
|
||||
|
||||
if (StringUtils.isBlank(role)) {
|
||||
|
||||
String where = " role= ? ";
|
||||
List<String> params = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(role)) {
|
||||
params = Collections.singletonList(role);
|
||||
} else {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
try {
|
||||
Page<PermissionInfo> pageInfo = helper
|
||||
.fetchPage(sqlCountRows + where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
.fetchPage(sqlCountRows + where, sqlFetchRows + where, params.toArray(), pageNo,
|
||||
pageSize, PERMISSION_ROW_MAPPER);
|
||||
|
||||
if (pageInfo == null) {
|
||||
|
@ -18,8 +18,8 @@ package com.alibaba.nacos.config.server.auth;
|
||||
|
||||
import com.alibaba.nacos.config.server.configuration.ConditionOnExternalStorage;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.service.repository.extrnal.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.config.server.service.repository.extrnal.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -33,6 +33,7 @@ import javax.annotation.PostConstruct;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.alibaba.nacos.config.server.service.repository.RowMapperManager.ROLE_INFO_ROW_MAPPER;
|
||||
@ -88,16 +89,17 @@ public class ExternalRolePersistServiceImpl implements RolePersistService {
|
||||
String sqlCountRows = "select count(*) from roles where ";
|
||||
String sqlFetchRows = "select role,username from roles where ";
|
||||
|
||||
String where = " username='" + username + "' ";
|
||||
|
||||
if (StringUtils.isBlank(username)) {
|
||||
String where = " username= ? ";
|
||||
List<String> params = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(username)) {
|
||||
params = Collections.singletonList(username);
|
||||
} else {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
try {
|
||||
return helper
|
||||
.fetchPage(sqlCountRows + where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, ROLE_INFO_ROW_MAPPER);
|
||||
return helper.fetchPage(sqlCountRows + where, sqlFetchRows + where, params.toArray(), pageNo, pageSize,
|
||||
ROLE_INFO_ROW_MAPPER);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.FATAL_LOG.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
@ -107,7 +109,7 @@ public class ExternalRolePersistServiceImpl implements RolePersistService {
|
||||
/**
|
||||
* Execute add role operation.
|
||||
*
|
||||
* @param role role string value.
|
||||
* @param role role string value.
|
||||
* @param userName username string value.
|
||||
*/
|
||||
public void addRole(String role, String userName) {
|
||||
@ -140,7 +142,7 @@ public class ExternalRolePersistServiceImpl implements RolePersistService {
|
||||
/**
|
||||
* Execute delete role operation.
|
||||
*
|
||||
* @param role role string value.
|
||||
* @param role role string value.
|
||||
* @param username username string value.
|
||||
*/
|
||||
public void deleteRole(String role, String username) {
|
||||
@ -156,7 +158,7 @@ public class ExternalRolePersistServiceImpl implements RolePersistService {
|
||||
@Override
|
||||
public List<String> findRolesLikeRoleName(String role) {
|
||||
String sql = "SELECT role FROM roles WHERE role like '%' ? '%'";
|
||||
List<String> users = this.jt.queryForList(sql, new String[]{role}, String.class);
|
||||
List<String> users = this.jt.queryForList(sql, new String[] {role}, String.class);
|
||||
return users;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.nacos.config.server.configuration;
|
||||
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.sys.utils.ApplicationUtils;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
@ -31,6 +31,6 @@ public class ConditionDistributedEmbedStorage implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode();
|
||||
return PropertyUtil.isEmbeddedStorage() && !EnvUtil.getStandaloneMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.nacos.config.server.configuration;
|
||||
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.sys.utils.ApplicationUtils;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
@ -32,6 +32,6 @@ public class ConditionStandaloneEmbedStorage implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return PropertyUtil.isEmbeddedStorage() && ApplicationUtils.getStandaloneMode();
|
||||
return PropertyUtil.isEmbeddedStorage() && EnvUtil.getStandaloneMode();
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,12 @@
|
||||
|
||||
package com.alibaba.nacos.config.server.controller;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.auth.annotation.Secured;
|
||||
import com.alibaba.nacos.auth.common.ActionTypes;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import com.alibaba.nacos.common.model.RestResultUtils;
|
||||
import com.alibaba.nacos.common.utils.MapUtils;
|
||||
import com.alibaba.nacos.config.server.auth.ConfigResourceParser;
|
||||
import com.alibaba.nacos.config.server.constant.Constants;
|
||||
@ -32,10 +34,9 @@ import com.alibaba.nacos.config.server.model.GroupkeyListenserStatus;
|
||||
import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.model.SameConfigPolicy;
|
||||
import com.alibaba.nacos.config.server.model.SampleResult;
|
||||
import com.alibaba.nacos.config.server.result.ResultBuilder;
|
||||
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
||||
import com.alibaba.nacos.config.server.result.code.ResultCodeEnum;
|
||||
import com.alibaba.nacos.config.server.service.AggrWhitelist;
|
||||
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
||||
import com.alibaba.nacos.config.server.service.ConfigChangePublisher;
|
||||
import com.alibaba.nacos.config.server.service.ConfigSubService;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
@ -43,7 +44,7 @@ import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
||||
import com.alibaba.nacos.config.server.utils.MD5Util;
|
||||
import com.alibaba.nacos.config.server.utils.ParamUtils;
|
||||
import com.alibaba.nacos.config.server.utils.RequestUtil;
|
||||
import com.alibaba.nacos.config.server.utils.NamespaceUtil;
|
||||
import com.alibaba.nacos.common.utils.NamespaceUtil;
|
||||
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
||||
import com.alibaba.nacos.config.server.utils.ZipUtils;
|
||||
import com.alibaba.nacos.sys.utils.InetUtils;
|
||||
@ -134,6 +135,10 @@ public class ConfigController {
|
||||
final String srcIp = RequestUtil.getRemoteIp(request);
|
||||
final String requestIpApp = RequestUtil.getAppName(request);
|
||||
srcUser = RequestUtil.getSrcUserName(request);
|
||||
//check type
|
||||
if (!ConfigType.isValidType(type)) {
|
||||
type = ConfigType.getDefaultType().getType();
|
||||
}
|
||||
// check tenant
|
||||
ParamUtils.checkTenant(tenant);
|
||||
ParamUtils.checkParam(dataId, group, "datumId", content);
|
||||
@ -279,7 +284,7 @@ public class ConfigController {
|
||||
null, time.getTime(), clientIp, ConfigTraceService.PERSISTENCE_EVENT_REMOVE, null);
|
||||
}
|
||||
}
|
||||
return ResultBuilder.buildSuccessResult(true);
|
||||
return RestResultUtils.success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/catalog")
|
||||
@ -523,13 +528,13 @@ public class ConfigController {
|
||||
Map<String, Object> failedData = new HashMap<>(4);
|
||||
|
||||
if (Objects.isNull(file)) {
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.DATA_EMPTY, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.DATA_EMPTY, failedData);
|
||||
}
|
||||
|
||||
namespace = NamespaceUtil.processNamespaceParameter(namespace);
|
||||
if (StringUtils.isNotBlank(namespace) && persistService.tenantInfoCountByTenantId(namespace) <= 0) {
|
||||
failedData.put("succCount", 0);
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.NAMESPACE_NOT_EXIST, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.NAMESPACE_NOT_EXIST, failedData);
|
||||
}
|
||||
|
||||
List<ConfigAllInfo> configInfoList = null;
|
||||
@ -544,7 +549,7 @@ public class ConfigController {
|
||||
String[] metaDataItemArr = metaDataItem.split("=");
|
||||
if (metaDataItemArr.length != 2) {
|
||||
failedData.put("succCount", 0);
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.METADATA_ILLEGAL, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.METADATA_ILLEGAL, failedData);
|
||||
}
|
||||
metaDataMap.put(metaDataItemArr[0], metaDataItemArr[1]);
|
||||
}
|
||||
@ -556,7 +561,7 @@ public class ConfigController {
|
||||
String[] groupAdnDataId = item.getItemName().split("/");
|
||||
if (!item.getItemName().contains("/") || groupAdnDataId.length != 2) {
|
||||
failedData.put("succCount", 0);
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.DATA_VALIDATION_FAILED, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.DATA_VALIDATION_FAILED, failedData);
|
||||
}
|
||||
String group = groupAdnDataId[0];
|
||||
String dataId = groupAdnDataId[1];
|
||||
@ -580,11 +585,11 @@ public class ConfigController {
|
||||
} catch (IOException e) {
|
||||
failedData.put("succCount", 0);
|
||||
LOGGER.error("parsing data failed", e);
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.PARSING_DATA_FAILED, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.PARSING_DATA_FAILED, failedData);
|
||||
}
|
||||
if (configInfoList == null || configInfoList.isEmpty()) {
|
||||
failedData.put("succCount", 0);
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.DATA_EMPTY, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.DATA_EMPTY, failedData);
|
||||
}
|
||||
final String srcIp = RequestUtil.getRemoteIp(request);
|
||||
String requestIpApp = RequestUtil.getAppName(request);
|
||||
@ -600,7 +605,7 @@ public class ConfigController {
|
||||
requestIpApp, time.getTime(), InetUtils.getSelfIP(),
|
||||
ConfigTraceService.PERSISTENCE_EVENT_PUB, configInfo.getContent());
|
||||
}
|
||||
return ResultBuilder.buildSuccessResult("导入成功", saveResult);
|
||||
return RestResultUtils.success("导入成功", saveResult);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -624,14 +629,14 @@ public class ConfigController {
|
||||
Map<String, Object> failedData = new HashMap<>(4);
|
||||
if (CollectionUtils.isEmpty(configBeansList)) {
|
||||
failedData.put("succCount", 0);
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.NO_SELECTED_CONFIG, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.NO_SELECTED_CONFIG, failedData);
|
||||
}
|
||||
configBeansList.removeAll(Collections.singleton(null));
|
||||
|
||||
namespace = NamespaceUtil.processNamespaceParameter(namespace);
|
||||
if (StringUtils.isNotBlank(namespace) && persistService.tenantInfoCountByTenantId(namespace) <= 0) {
|
||||
failedData.put("succCount", 0);
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.NAMESPACE_NOT_EXIST, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.NAMESPACE_NOT_EXIST, failedData);
|
||||
}
|
||||
|
||||
List<Long> idList = new ArrayList<>(configBeansList.size());
|
||||
@ -645,7 +650,7 @@ public class ConfigController {
|
||||
|
||||
if (queryedDataList == null || queryedDataList.isEmpty()) {
|
||||
failedData.put("succCount", 0);
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.DATA_EMPTY, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.DATA_EMPTY, failedData);
|
||||
}
|
||||
|
||||
List<ConfigAllInfo> configInfoList4Clone = new ArrayList<>(queryedDataList.size());
|
||||
@ -669,7 +674,7 @@ public class ConfigController {
|
||||
|
||||
if (configInfoList4Clone.isEmpty()) {
|
||||
failedData.put("succCount", 0);
|
||||
return ResultBuilder.buildResult(ResultCodeEnum.DATA_EMPTY, failedData);
|
||||
return RestResultUtils.buildResult(ResultCodeEnum.DATA_EMPTY, failedData);
|
||||
}
|
||||
final String srcIp = RequestUtil.getRemoteIp(request);
|
||||
String requestIpApp = RequestUtil.getAppName(request);
|
||||
@ -685,7 +690,7 @@ public class ConfigController {
|
||||
requestIpApp, time.getTime(), InetUtils.getSelfIP(),
|
||||
ConfigTraceService.PERSISTENCE_EVENT_PUB, configInfo.getContent());
|
||||
}
|
||||
return ResultBuilder.buildSuccessResult("Clone Completed Successfully", saveResult);
|
||||
return RestResultUtils.success("Clone Completed Successfully", saveResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ public class ConfigOpsController {
|
||||
* @return {@link RestResult}
|
||||
*/
|
||||
@GetMapping(value = "/derby")
|
||||
@Secured(action = ActionTypes.READ, resource = "nacos/admin")
|
||||
public RestResult<Object> derbyOps(@RequestParam(value = "sql") String sql) {
|
||||
String selectSign = "select";
|
||||
String limitSign = "ROWS FETCH NEXT";
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.alibaba.nacos.config.server.controller;
|
||||
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.config.server.constant.Constants;
|
||||
import com.alibaba.nacos.config.server.enums.FileTypeEnum;
|
||||
import com.alibaba.nacos.config.server.model.CacheItem;
|
||||
@ -138,17 +139,12 @@ public class ConfigServletInner {
|
||||
isBeta = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final String configType =
|
||||
(null != cacheItem.getType()) ? cacheItem.getType() : FileTypeEnum.TEXT.getFileType();
|
||||
response.setHeader("Config-Type", configType);
|
||||
|
||||
String contentTypeHeader;
|
||||
try {
|
||||
contentTypeHeader = FileTypeEnum.valueOf(configType.toUpperCase()).getContentType();
|
||||
} catch (IllegalArgumentException ex) {
|
||||
contentTypeHeader = FileTypeEnum.TEXT.getContentType();
|
||||
}
|
||||
FileTypeEnum fileTypeEnum = FileTypeEnum.getFileTypeEnumByFileExtensionOrFileType(configType);
|
||||
String contentTypeHeader = fileTypeEnum.getContentType();
|
||||
response.setHeader(HttpHeaderConsts.CONTENT_TYPE, contentTypeHeader);
|
||||
}
|
||||
File file = null;
|
||||
@ -276,9 +272,7 @@ public class ConfigServletInner {
|
||||
|
||||
} finally {
|
||||
releaseConfigReadLock(groupKey);
|
||||
if (null != fis) {
|
||||
fis.close();
|
||||
}
|
||||
IoUtils.closeQuietly(fis);
|
||||
}
|
||||
} else if (lockResult == 0) {
|
||||
|
||||
|
@ -47,9 +47,9 @@ public class HistoryController {
|
||||
* @param group group string value.
|
||||
* @param tenant tenant string value.
|
||||
* @param appName appName string value.
|
||||
* @param pageNo pageNo string value.
|
||||
* @param pageSize pageSize string value.
|
||||
* @param modelMap modeMap.
|
||||
* @param pageNo pageNo integer value.
|
||||
* @param pageSize pageSize integer value.
|
||||
* @param modelMap modelMap.
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(params = "search=accurate")
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.alibaba.nacos.config.server.enums;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Config file type enum.
|
||||
@ -98,4 +99,24 @@ public enum FileTypeEnum {
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the corresponding FileTypeEnum by file extension or fileType. If not found FileTypeEnum.TEXT is returned
|
||||
*
|
||||
* @param extOrFileType file extension or fileType
|
||||
* @return
|
||||
*/
|
||||
public static FileTypeEnum getFileTypeEnumByFileExtensionOrFileType(String extOrFileType) {
|
||||
if (StringUtils.isNotBlank(extOrFileType)) {
|
||||
String upperExtName = extOrFileType.trim().toUpperCase();
|
||||
for (FileTypeEnum value : VALUES) {
|
||||
if (value.name().equals(upperExtName)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FileTypeEnum.TEXT;
|
||||
}
|
||||
|
||||
private static final FileTypeEnum[] VALUES = FileTypeEnum.values();
|
||||
}
|
||||
|
@ -39,8 +39,6 @@ public class ConfigAllInfo extends ConfigInfo {
|
||||
|
||||
private String effect;
|
||||
|
||||
private String type;
|
||||
|
||||
private String schema;
|
||||
|
||||
private String configTags;
|
||||
@ -103,15 +101,7 @@ public class ConfigAllInfo extends ConfigInfo {
|
||||
public void setEffect(String effect) {
|
||||
this.effect = effect;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
public String getSchema() {
|
||||
return schema;
|
||||
}
|
||||
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.result;
|
||||
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import com.alibaba.nacos.config.server.result.code.ResultCodeEnum;
|
||||
import com.alibaba.nacos.config.server.result.core.IResultCode;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* ResultBuilder.
|
||||
*
|
||||
* @author klw
|
||||
* @ClassName: ResultBuilder
|
||||
* @Description: util for generating {@link RestResult}
|
||||
* @date 2019/6/28 14:47
|
||||
*/
|
||||
public class ResultBuilder {
|
||||
|
||||
/**
|
||||
* BuildResult.
|
||||
*
|
||||
* @param resultCode resultCode.
|
||||
* @param resultData resultData.
|
||||
* @param <T> T.
|
||||
* @return RestResult.
|
||||
*/
|
||||
public static <T extends Object> RestResult<T> buildResult(IResultCode resultCode, T resultData) {
|
||||
Assert.notNull(resultCode, "the resultCode can not be null");
|
||||
RestResult<T> rr = new RestResult<>(resultCode.getCode(), resultCode.getCodeMsg(), resultData);
|
||||
return rr;
|
||||
}
|
||||
|
||||
public static <T extends Object> RestResult<T> buildSuccessResult(T resultData) {
|
||||
return buildResult(ResultCodeEnum.SUCCESS, resultData);
|
||||
}
|
||||
|
||||
/**
|
||||
* BuildSuccessResult.
|
||||
*
|
||||
* @param successMsg successMsg string value.
|
||||
* @param resultData resultData.
|
||||
* @param <T> T.
|
||||
* @return RestResult.
|
||||
*/
|
||||
public static <T extends Object> RestResult<T> buildSuccessResult(String successMsg, T resultData) {
|
||||
RestResult<T> rr = buildResult(ResultCodeEnum.SUCCESS, resultData);
|
||||
rr.setMessage(successMsg);
|
||||
return rr;
|
||||
}
|
||||
|
||||
public static <T extends Object> RestResult<T> buildSuccessResult() {
|
||||
return buildResult(ResultCodeEnum.SUCCESS, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* BuildSuccessResult.
|
||||
*
|
||||
* @param successMsg successMsg string value.
|
||||
* @param <T> T.
|
||||
* @return RestResult.
|
||||
*/
|
||||
public static <T extends Object> RestResult<T> buildSuccessResult(String successMsg) {
|
||||
RestResult<T> rr = buildResult(ResultCodeEnum.SUCCESS, null);
|
||||
rr.setMessage(successMsg);
|
||||
return rr;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user