Merge branch 'develop' of https://github.com/alibaba/nacos into new_develop
This commit is contained in:
commit
abee9c4dcf
@ -22,7 +22,7 @@ Nacos provides four major functions.
|
||||
|
||||
* **Dynamic Configuration Management**
|
||||
|
||||
Dynamic Configuration Service allows you to manage configurations of all services in a centralized and dynamic manner across all environments. Nacos eliminates the need to redeploy applications and services when configurations are updated,which makes configuration changes more efficient and agile.
|
||||
Dynamic Configuration Service allows you to manage configurations of all services in a centralized and dynamic manner across all environments. Nacos eliminates the need to redeploy applications and services when configurations are updated, which makes configuration changes more efficient and agile.
|
||||
|
||||
* **Dynamic DNS Service**
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<version>1.3.1-BETA</version>
|
||||
<version>1.3.1</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
@ -26,6 +27,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
*/
|
||||
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
|
||||
public class AddressServer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
SpringApplication.run(AddressServer.class, args);
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address.component;
|
||||
|
||||
import com.alibaba.nacos.address.constant.AddressServerConstants;
|
||||
@ -35,6 +36,12 @@ import java.util.List;
|
||||
@Component
|
||||
public class AddressServerGeneratorManager {
|
||||
|
||||
/**
|
||||
* Generate product name.
|
||||
*
|
||||
* @param name name
|
||||
* @return product
|
||||
*/
|
||||
public String generateProductName(String name) {
|
||||
|
||||
if (StringUtils.isBlank(name) || AddressServerConstants.DEFAULT_PRODUCT.equals(name)) {
|
||||
@ -48,15 +55,15 @@ public class AddressServerGeneratorManager {
|
||||
/**
|
||||
* Note: if the parameter inputted is empty then will return the empty list.
|
||||
*
|
||||
* @param serviceName
|
||||
* @param clusterName
|
||||
* @param ipArray
|
||||
* @return
|
||||
* @param serviceName service name
|
||||
* @param clusterName cluster name
|
||||
* @param ipArray array of ips
|
||||
* @return instance list
|
||||
*/
|
||||
public List<Instance> generateInstancesByIps(String serviceName, String rawProductName, String clusterName, String[] ipArray) {
|
||||
if (StringUtils.isEmpty(serviceName)
|
||||
|| StringUtils.isEmpty(clusterName)
|
||||
|| ipArray == null || ipArray.length == 0) {
|
||||
public List<Instance> generateInstancesByIps(String serviceName, String rawProductName, String clusterName,
|
||||
String[] ipArray) {
|
||||
if (StringUtils.isEmpty(serviceName) || StringUtils.isEmpty(clusterName) || ipArray == null
|
||||
|| ipArray.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@ -77,18 +84,20 @@ public class AddressServerGeneratorManager {
|
||||
return instanceList;
|
||||
}
|
||||
|
||||
public String[] generateIpAndPort(String ip) {
|
||||
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)};
|
||||
return new String[] {ip.substring(0, index), ip.substring(index + 1)};
|
||||
}
|
||||
|
||||
return new String[]{ip, String.valueOf(AddressServerConstants.DEFAULT_SERVER_PORT)};
|
||||
return new String[] {ip, String.valueOf(AddressServerConstants.DEFAULT_SERVER_PORT)};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate response ips.
|
||||
*
|
||||
* @param instanceList a instance set will generate string response to client.
|
||||
* @return the result of response to client
|
||||
*/
|
||||
@ -104,7 +113,9 @@ public class AddressServerGeneratorManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rawServiceName the raw service name will not contains the {@Constans.DEFAULT_GROUP}
|
||||
* Generate nacos service name.
|
||||
*
|
||||
* @param rawServiceName the raw service name will not contains the {@link Constants#DEFAULT_GROUP}.
|
||||
* @return the nacos service name
|
||||
*/
|
||||
public String generateNacosServiceName(String rawServiceName) {
|
||||
|
@ -13,9 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address.component;
|
||||
|
||||
import com.alibaba.nacos.address.constant.AddressServerConstants;
|
||||
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -40,13 +42,11 @@ public class AddressServerManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* if the name is empty then return the default {@UtilAndCommons#DEFAULT_CLUSTER_NAME},
|
||||
* <p>
|
||||
* or return the source name by input
|
||||
* If the name is empty then return the default {@link UtilsAndCommons#DEFAULT_CLUSTER_NAME}, or return the source
|
||||
* name by input.
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
* @param name name
|
||||
* @return default cluster name
|
||||
*/
|
||||
public String getDefaultClusterNameIfEmpty(String name) {
|
||||
|
||||
@ -63,8 +63,10 @@ public class AddressServerManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Split ips.
|
||||
*
|
||||
* @param ips multi ip will separator by the ','
|
||||
* @return
|
||||
* @return array of ip
|
||||
*/
|
||||
public String[] splitIps(String ips) {
|
||||
|
||||
|
@ -13,12 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address.constant;
|
||||
|
||||
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
||||
|
||||
/**
|
||||
* Uniform constant parameter naming for address servers and default values for related parameters
|
||||
* Uniform constant parameter naming for address servers and default values for related parameters.
|
||||
*
|
||||
* @author pbting
|
||||
* @date 2019-06-17 7:23 PM
|
||||
@ -43,7 +44,7 @@ public interface AddressServerConstants {
|
||||
String IP_PORT_SEPARATOR = ":";
|
||||
|
||||
/**
|
||||
* the separator for {@Service#name} between raw service name and group
|
||||
* the separator for service name between raw service name and group.
|
||||
*/
|
||||
String GROUP_SERVICE_NAME_SEP = "@@";
|
||||
|
||||
@ -53,22 +54,22 @@ public interface AddressServerConstants {
|
||||
String DEFAULT_GET_CLUSTER = "serverlist";
|
||||
|
||||
/**
|
||||
* post multi ip will use the "," to separator
|
||||
* post multi ip will use the "," to separator.
|
||||
*/
|
||||
String MULTI_IPS_SEPARATOR = ",";
|
||||
|
||||
/**
|
||||
* the default product name when deploy nacos with naming and config
|
||||
* the default product name when deploy nacos with naming and config.
|
||||
*/
|
||||
String ALIWARE_NACOS_DEFAULT_PRODUCT_NAME = "nacos.as.default";
|
||||
|
||||
/**
|
||||
* when the config and naming will separate deploy,then must specify product name by the client。
|
||||
* when the config and naming will separate deploy,then must specify product name by the client.
|
||||
*/
|
||||
String ALIWARE_NACOS_PRODUCT_DOM_TEMPLATE = "nacos.as.%s";
|
||||
|
||||
/**
|
||||
* the url for address server prefix
|
||||
* the url for address server prefix.
|
||||
*/
|
||||
String ADDRESS_SERVER_REQUEST_URL =
|
||||
UtilsAndCommons.NACOS_SERVER_CONTEXT + UtilsAndCommons.NACOS_SERVER_VERSION + "/as";
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address.controller;
|
||||
|
||||
import com.alibaba.nacos.address.component.AddressServerGeneratorManager;
|
||||
@ -38,8 +39,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Address server cluster controller.
|
||||
*
|
||||
* @author pbting
|
||||
* @date 2019-06-10 9:59 AM
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@RestController
|
||||
@ -56,15 +58,16 @@ public class AddressServerClusterController {
|
||||
private AddressServerGeneratorManager addressServerGeneratorManager;
|
||||
|
||||
/**
|
||||
* Create new cluster.
|
||||
*
|
||||
* @param product Ip list of products to be associated
|
||||
* @param cluster Ip list of product cluster to be associated
|
||||
* @param ips will post ip list.
|
||||
* @return
|
||||
* @return result of create new cluster
|
||||
*/
|
||||
@RequestMapping(value = "", method = RequestMethod.POST)
|
||||
public ResponseEntity postCluster(@RequestParam(required = false) String product,
|
||||
@RequestParam(required = false) String cluster,
|
||||
@RequestParam(name = "ips") String ips) {
|
||||
@RequestParam(required = false) String cluster, @RequestParam(name = "ips") String ips) {
|
||||
|
||||
//1. prepare the storage name for product and cluster
|
||||
String productName = addressServerGeneratorManager.generateProductName(product);
|
||||
@ -73,7 +76,8 @@ public class AddressServerClusterController {
|
||||
//2. prepare the response name for product and cluster to client
|
||||
String rawProductName = addressServerManager.getRawProductName(product);
|
||||
String rawClusterName = addressServerManager.getRawClusterName(cluster);
|
||||
Loggers.addressLogger.info("put cluster node,the cluster name is " + cluster + "; the product name=" + product + "; the ip list=" + ips);
|
||||
Loggers.ADDRESS_LOGGER.info("put cluster node,the cluster name is " + cluster + "; the product name=" + product
|
||||
+ "; the ip list=" + ips);
|
||||
ResponseEntity responseEntity;
|
||||
try {
|
||||
String serviceName = addressServerGeneratorManager.generateNacosServiceName(productName);
|
||||
@ -85,11 +89,14 @@ public class AddressServerClusterController {
|
||||
String[] ipArray = addressServerManager.splitIps(ips);
|
||||
String checkResult = AddressServerParamCheckUtil.checkIps(ipArray);
|
||||
if (AddressServerParamCheckUtil.CHECK_OK.equals(checkResult)) {
|
||||
List<Instance> instanceList = addressServerGeneratorManager.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray);
|
||||
List<Instance> instanceList = addressServerGeneratorManager
|
||||
.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray);
|
||||
for (Instance instance : instanceList) {
|
||||
serviceManager.registerInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, instance);
|
||||
}
|
||||
responseEntity = ResponseEntity.ok("product=" + rawProductName + ",cluster=" + rawClusterName + "; put success with size=" + instanceList.size());
|
||||
responseEntity = ResponseEntity
|
||||
.ok("product=" + rawProductName + ",cluster=" + rawClusterName + "; put success with size="
|
||||
+ instanceList.size());
|
||||
} else {
|
||||
responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(checkResult);
|
||||
}
|
||||
@ -101,15 +108,16 @@ public class AddressServerClusterController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cluster.
|
||||
*
|
||||
* @param product Ip list of products to be associated
|
||||
* @param cluster Ip list of product cluster to be associated
|
||||
* @param ips will delete ips.
|
||||
* @return
|
||||
* @return delete result
|
||||
*/
|
||||
@RequestMapping(value = "", method = RequestMethod.DELETE)
|
||||
public ResponseEntity deleteCluster(@RequestParam(required = false) String product,
|
||||
@RequestParam(required = false) String cluster,
|
||||
@RequestParam String ips) {
|
||||
@RequestParam(required = false) String cluster, @RequestParam String ips) {
|
||||
//1. prepare the storage name for product and cluster
|
||||
String productName = addressServerGeneratorManager.generateProductName(product);
|
||||
String clusterName = addressServerManager.getDefaultClusterNameIfEmpty(cluster);
|
||||
@ -117,14 +125,16 @@ public class AddressServerClusterController {
|
||||
//2. prepare the response name for product and cluster to client
|
||||
String rawProductName = addressServerManager.getRawProductName(product);
|
||||
String rawClusterName = addressServerManager.getRawClusterName(cluster);
|
||||
ResponseEntity responseEntity = ResponseEntity.status(HttpStatus.OK).body("product=" + rawProductName + ", cluster=" + rawClusterName + " delete success.");
|
||||
ResponseEntity responseEntity = ResponseEntity.status(HttpStatus.OK)
|
||||
.body("product=" + rawProductName + ", cluster=" + rawClusterName + " delete success.");
|
||||
try {
|
||||
|
||||
String serviceName = addressServerGeneratorManager.generateNacosServiceName(productName);
|
||||
Service service = serviceManager.getService(Constants.DEFAULT_NAMESPACE_ID, serviceName);
|
||||
|
||||
if (service == null) {
|
||||
responseEntity = ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + rawProductName + " not found.");
|
||||
responseEntity = ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||||
.body("product=" + rawProductName + " not found.");
|
||||
} else {
|
||||
|
||||
if (StringUtils.isBlank(ips)) {
|
||||
@ -135,8 +145,10 @@ public class AddressServerClusterController {
|
||||
String[] ipArray = addressServerManager.splitIps(ips);
|
||||
String checkResult = AddressServerParamCheckUtil.checkIps(ipArray);
|
||||
if (AddressServerParamCheckUtil.CHECK_OK.equals(checkResult)) {
|
||||
List<Instance> instanceList = addressServerGeneratorManager.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray);
|
||||
serviceManager.removeInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, false, instanceList.toArray(new Instance[instanceList.size()]));
|
||||
List<Instance> instanceList = addressServerGeneratorManager
|
||||
.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray);
|
||||
serviceManager.removeInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, false,
|
||||
instanceList.toArray(new Instance[instanceList.size()]));
|
||||
} else {
|
||||
responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(checkResult);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address.controller;
|
||||
|
||||
import com.alibaba.nacos.address.component.AddressServerGeneratorManager;
|
||||
@ -29,8 +30,9 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Server list controller.
|
||||
*
|
||||
* @author pbting
|
||||
* @date 2019-06-18 5:04 PM
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@RestController
|
||||
@ -43,13 +45,14 @@ public class ServerListController {
|
||||
private AddressServerGeneratorManager addressServerBuilderManager;
|
||||
|
||||
/**
|
||||
* Get cluster.
|
||||
*
|
||||
* @param product will get Ip list of that products to be associated
|
||||
* @param cluster will get Ip list of that product cluster to be associated
|
||||
* @return
|
||||
* @return result of get
|
||||
*/
|
||||
@RequestMapping(value = "/{product}/{cluster}", method = RequestMethod.GET)
|
||||
public ResponseEntity getCluster(@PathVariable String product,
|
||||
@PathVariable String cluster) {
|
||||
public ResponseEntity getCluster(@PathVariable String product, @PathVariable String cluster) {
|
||||
|
||||
String productName = addressServerBuilderManager.generateProductName(product);
|
||||
String serviceName = addressServerBuilderManager.generateNacosServiceName(productName);
|
||||
@ -61,10 +64,12 @@ public class ServerListController {
|
||||
|
||||
if (!service.getClusterMap().containsKey(cluster)) {
|
||||
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + product + ",cluster=" + cluster + " not found.");
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||||
.body("product=" + product + ",cluster=" + cluster + " not found.");
|
||||
}
|
||||
|
||||
Cluster clusterObj = service.getClusterMap().get(cluster);
|
||||
return ResponseEntity.status(HttpStatus.OK).body(addressServerBuilderManager.generateResponseIps(clusterObj.allIPs(false)));
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(addressServerBuilderManager.generateResponseIps(clusterObj.allIPs(false)));
|
||||
}
|
||||
}
|
||||
|
@ -13,16 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address.misc;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Loggers holder.
|
||||
*
|
||||
* @author pbting
|
||||
* @date 2019-07-04 4:34 PM
|
||||
*/
|
||||
public class Loggers {
|
||||
|
||||
public static final Logger addressLogger = LoggerFactory.getLogger("com.alibaba.nacos.address.main");
|
||||
public static final Logger ADDRESS_LOGGER = LoggerFactory.getLogger("com.alibaba.nacos.address.main");
|
||||
}
|
||||
|
@ -13,13 +13,14 @@
|
||||
* 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
|
||||
* Provides a unified tool class for address server parameter verification.
|
||||
*
|
||||
* @author pbting
|
||||
* @date 2019-06-19 11:19 AM
|
||||
@ -35,6 +36,12 @@ public class AddressServerParamCheckUtil {
|
||||
|
||||
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) {
|
||||
|
@ -13,6 +13,5 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
server.port=8080
|
||||
server.servlet.context-path=/
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address;
|
||||
|
||||
import org.junit.Ignore;
|
||||
@ -20,25 +21,21 @@ import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
* @date 2019-06-18 2:37 PM
|
||||
*/
|
||||
@Ignore
|
||||
public class AddressServerControllerTests {
|
||||
|
||||
private static final String PRODUCT_NACOS = "nacos";
|
||||
|
||||
private static final String PRODUCT_CONFIG = "config";
|
||||
|
||||
private static final String PRODUCT_NAMING = "naming";
|
||||
|
||||
private static final String DEFAULT_URL_CLUSTER = "serverlist";
|
||||
|
||||
private static final String GET_SERVERLIST_URL_FORMART = "http://127.0.0.1:8080/%s/%s";
|
||||
|
||||
//-----------------product=nacos,cluster=DEFAULT -------------------//
|
||||
|
||||
/**
|
||||
* test the default product and cluster
|
||||
*/
|
||||
@Test
|
||||
public void postCluster() {
|
||||
|
||||
@ -85,10 +82,6 @@ public class AddressServerControllerTests {
|
||||
|
||||
//-----------------product=config,cluster=cluster01 -------------------//
|
||||
|
||||
/**
|
||||
* test with product
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void postClusterWithProduct() {
|
||||
|
||||
@ -136,12 +129,8 @@ public class AddressServerControllerTests {
|
||||
System.err.println(response);
|
||||
}
|
||||
|
||||
|
||||
//-----------------product=naming,cluster=cluster01 -------------------//
|
||||
|
||||
/**
|
||||
* test with product and cluster
|
||||
*/
|
||||
@Test
|
||||
public void postClusterWithProductAndCluster() {
|
||||
|
||||
|
@ -13,15 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address;
|
||||
|
||||
import com.alibaba.nacos.address.util.AddressServerParamCheckUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
* @date 2019-06-19 11:31 AM
|
||||
*/
|
||||
public class ParamCheckUtilTests {
|
||||
|
||||
@Test
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.address;
|
||||
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
@ -26,49 +27,46 @@ import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
* @date 2019-06-18 2:40 PM
|
||||
*/
|
||||
public class SimpleHttpTestUtils {
|
||||
|
||||
private static final String REQUEST_METHOD_DELETE = "DELETE";
|
||||
|
||||
private static final String REQUEST_METHOD_PUT = "PUT";
|
||||
|
||||
private static final String REQUEST_METHOD_POST = "POST";
|
||||
|
||||
private static final String REQUEST_METHOD_GET = "GET";
|
||||
|
||||
/**
|
||||
* 连接超时
|
||||
* 连接超时.
|
||||
*/
|
||||
private static int CONNECT_TIME_OUT = 2000;
|
||||
private static final int CONNECT_TIME_OUT = 2000;
|
||||
|
||||
/**
|
||||
* 读取数据超时
|
||||
* 读取数据超时.
|
||||
*/
|
||||
private static int READ_TIME_OUT = 2000;
|
||||
private static final int READ_TIME_OUT = 2000;
|
||||
|
||||
/**
|
||||
* 请求编码
|
||||
* 请求编码.
|
||||
*/
|
||||
public static String REQUEST_ENCODING = "UTF-8";
|
||||
public static final String REQUEST_ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
* 接收编码
|
||||
* 接收编码.
|
||||
*/
|
||||
public static String RESPONSE_ENCODING = "UTF-8";
|
||||
public static final String RESPONSE_ENCODING = "UTF-8";
|
||||
|
||||
public static final short OK = 200;
|
||||
|
||||
public static final short Bad_Request = 400;
|
||||
public static final short BAD_REQUEST = 400;
|
||||
|
||||
public static final short Internal_Server_Error = 500;
|
||||
public static final short INTERNAL_SERVER_ERROR = 500;
|
||||
|
||||
public static final short PARAM_ERROR_NO_ANALYSESOR = 1000;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 发送带参数的GET的HTTP请求
|
||||
* </pre>
|
||||
* 发送带参数的GET的HTTP请求.
|
||||
*
|
||||
* @param reqUrl HTTP请求URL
|
||||
* @param paramMap 参数映射表
|
||||
@ -79,9 +77,7 @@ public class SimpleHttpTestUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 发送带参数的POST的HTTP请求
|
||||
* </pre>
|
||||
* 发送带参数的POST的HTTP请求.
|
||||
*
|
||||
* @param reqUrl HTTP请求URL
|
||||
* @param paramMap 参数映射表
|
||||
@ -92,9 +88,7 @@ public class SimpleHttpTestUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 发送带参数的 PUT 的 HTTP 请求
|
||||
* </pre>
|
||||
* 发送带参数的 PUT 的 HTTP 请求.
|
||||
*
|
||||
* @param reqUrl HTTP请求URL
|
||||
* @param paramMap 参数映射表
|
||||
@ -105,9 +99,7 @@ public class SimpleHttpTestUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 发送带参数的 DELETE 的 HTTP 请求
|
||||
* </pre>
|
||||
* 发送带参数的 DELETE 的 HTTP 请求.
|
||||
*
|
||||
* @param reqUrl HTTP请求URL
|
||||
* @param paramMap 参数映射表
|
||||
@ -117,12 +109,14 @@ public class SimpleHttpTestUtils {
|
||||
return doRequest(reqUrl, paramMap, REQUEST_METHOD_DELETE, recvEncoding);
|
||||
}
|
||||
|
||||
private static String doRequest(String reqUrl, Map<String, String> paramMap, String reqMethod, String recvEncoding) {
|
||||
private static String doRequest(String reqUrl, Map<String, String> paramMap, String reqMethod,
|
||||
String recvEncoding) {
|
||||
|
||||
return doExecute(reqUrl, paramMap, reqMethod, recvEncoding);
|
||||
}
|
||||
|
||||
private static String doExecute(String reqUrl, Map<String, String> paramMap, String reqMethod, String recvEncoding) {
|
||||
private static String doExecute(String reqUrl, Map<String, String> paramMap, String reqMethod,
|
||||
String recvEncoding) {
|
||||
HttpURLConnection urlCon = null;
|
||||
String responseContent = null;
|
||||
try {
|
||||
@ -139,8 +133,8 @@ public class SimpleHttpTestUtils {
|
||||
params = params.deleteCharAt(params.length() - 1);
|
||||
}
|
||||
|
||||
if (params.length() > 0 &&
|
||||
(REQUEST_METHOD_GET.equals(reqMethod) || REQUEST_METHOD_DELETE.equals(reqMethod))) {
|
||||
if (params.length() > 0 && (REQUEST_METHOD_GET.equals(reqMethod) || REQUEST_METHOD_DELETE
|
||||
.equals(reqMethod))) {
|
||||
reqUrl = reqUrl + "?" + params.toString();
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.3.1-BETA</version>
|
||||
<version>1.3.1</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -154,4 +154,10 @@ public class NacosException extends Exception {
|
||||
public static final int OVER_THRESHOLD = 503;
|
||||
|
||||
public static final int RESOURCE_NOT_FOUND = -404;
|
||||
|
||||
/**
|
||||
* http client error code,
|
||||
* ome exceptions that occurred when the use the Nacos RestTemplate and Nacos AsyncRestTemplate.
|
||||
*/
|
||||
public static final int HTTP_CLIENT_ERROR_CODE = -500;
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.api.naming.pojo.healthcheck;
|
||||
|
||||
import com.alibaba.nacos.api.exception.runtime.NacosDeserializationException;
|
||||
import com.alibaba.nacos.api.exception.runtime.NacosSerializationException;
|
||||
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker.None;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
@ -76,8 +78,7 @@ public class HealthCheckerFactory {
|
||||
try {
|
||||
return MAPPER.readValue(jsonString, AbstractHealthChecker.class);
|
||||
} catch (IOException e) {
|
||||
// TODO replace with NacosDeserializeException.
|
||||
throw new RuntimeException("Deserialize health checker from json failed", e);
|
||||
throw new NacosDeserializationException(AbstractHealthChecker.class, e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,8 +92,7 @@ public class HealthCheckerFactory {
|
||||
try {
|
||||
return MAPPER.writeValueAsString(healthChecker);
|
||||
} catch (JsonProcessingException e) {
|
||||
// TODO replace with NacosSerializeException.
|
||||
throw new RuntimeException("Serialize health checker to json failed", e);
|
||||
throw new NacosSerializationException(healthChecker.getClass(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.3.1-BETA</version>
|
||||
<version>1.3.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@ -49,6 +49,12 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
@ -131,8 +137,8 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>7</source>
|
||||
<target>7</target>
|
||||
<source>6</source>
|
||||
<target>6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
@ -45,7 +46,7 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Config Impl
|
||||
* Config Impl.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@ -57,16 +58,20 @@ public class NacosConfigService implements ConfigService {
|
||||
private static final long POST_TIMEOUT = 3000L;
|
||||
|
||||
/**
|
||||
* http agent
|
||||
* http agent.
|
||||
*/
|
||||
private HttpAgent agent;
|
||||
private final HttpAgent agent;
|
||||
|
||||
/**
|
||||
* longpolling
|
||||
* long polling.
|
||||
*/
|
||||
private ClientWorker worker;
|
||||
private final ClientWorker worker;
|
||||
|
||||
private String namespace;
|
||||
private String encode;
|
||||
private ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager();
|
||||
|
||||
private final String encode;
|
||||
|
||||
private final ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager();
|
||||
|
||||
public NacosConfigService(Properties properties) throws NacosException {
|
||||
ValidatorUtils.checkInitParam(properties);
|
||||
@ -94,7 +99,8 @@ public class NacosConfigService implements ConfigService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) throws NacosException {
|
||||
public String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener)
|
||||
throws NacosException {
|
||||
String content = getConfig(dataId, group, timeoutMs);
|
||||
worker.addTenantListenersWithContent(dataId, group, content, Arrays.asList(listener));
|
||||
return content;
|
||||
@ -252,8 +258,8 @@ public class NacosConfigService implements ConfigService {
|
||||
try {
|
||||
result = agent.httpPost(url, headers, params, encode, POST_TIMEOUT);
|
||||
} catch (IOException ioe) {
|
||||
LOGGER.warn("[{}] [publish-single] exception, dataId={}, group={}, msg={}", agent.getName(), dataId,
|
||||
group, ioe.toString());
|
||||
LOGGER.warn("[{}] [publish-single] exception, dataId={}, group={}, msg={}", agent.getName(), dataId, group,
|
||||
ioe.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -283,7 +289,7 @@ public class NacosConfigService implements ConfigService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() throws NacosException{
|
||||
public void shutDown() throws NacosException {
|
||||
agent.shutdown();
|
||||
worker.shutdown();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.common;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
@ -25,17 +26,17 @@ import com.alibaba.nacos.common.utils.StringUtils;
|
||||
public class GroupKey {
|
||||
|
||||
public static String getKey(String dataId, String group) {
|
||||
return doGetKey(dataId, group, "");
|
||||
}
|
||||
|
||||
public static String getKeyTenant(String dataId, String group, String tenant) {
|
||||
return doGetKey(dataId, group, tenant);
|
||||
return getKey(dataId, group, "");
|
||||
}
|
||||
|
||||
public static String getKey(String dataId, String group, String datumStr) {
|
||||
return doGetKey(dataId, group, datumStr);
|
||||
}
|
||||
|
||||
public static String getKeyTenant(String dataId, String group, String tenant) {
|
||||
return doGetKey(dataId, group, tenant);
|
||||
}
|
||||
|
||||
private static String doGetKey(String dataId, String group, String datumStr) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
urlEncode(dataId, sb);
|
||||
@ -49,7 +50,13 @@ public class GroupKey {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static public String[] parseKey(String groupKey) {
|
||||
/**
|
||||
* Parse key.
|
||||
*
|
||||
* @param groupKey group key
|
||||
* @return parsed key
|
||||
*/
|
||||
public static String[] parseKey(String groupKey) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String dataId = null;
|
||||
String group = null;
|
||||
@ -98,7 +105,7 @@ public class GroupKey {
|
||||
}
|
||||
|
||||
/**
|
||||
* + -> %2B % -> %25
|
||||
* + -> %2B % -> %25.
|
||||
*/
|
||||
static void urlEncode(String str, StringBuilder sb) {
|
||||
for (int idx = 0; idx < str.length(); ++idx) {
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.filter.impl;
|
||||
|
||||
import com.alibaba.nacos.api.config.filter.IConfigContext;
|
||||
@ -21,13 +22,13 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Config Context
|
||||
* Config Context.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ConfigContext implements IConfigContext {
|
||||
|
||||
private Map<String, Object> param = new HashMap<String, Object>();
|
||||
private final Map<String, Object> param = new HashMap<String, Object>();
|
||||
|
||||
@Override
|
||||
public Object getParameter(String key) {
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.filter.impl;
|
||||
|
||||
import com.alibaba.nacos.api.config.filter.IConfigFilter;
|
||||
@ -25,14 +26,20 @@ import com.google.common.collect.Lists;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Config Filter Chain Management
|
||||
* Config Filter Chain Management.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ConfigFilterChainManager implements IConfigFilterChain {
|
||||
|
||||
private List<IConfigFilter> filters = Lists.newArrayList();
|
||||
private final List<IConfigFilter> filters = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* Add filter.
|
||||
*
|
||||
* @param filter filter
|
||||
* @return this
|
||||
*/
|
||||
public synchronized ConfigFilterChainManager addFilter(IConfigFilter filter) {
|
||||
// 根据order大小顺序插入
|
||||
int i = 0;
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.filter.impl;
|
||||
|
||||
import com.alibaba.nacos.api.config.filter.IConfigContext;
|
||||
@ -22,18 +23,18 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Config Request
|
||||
* Config Request.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ConfigRequest implements IConfigRequest {
|
||||
|
||||
private Map<String, Object> param = new HashMap<String, Object>();
|
||||
private final Map<String, Object> param = new HashMap<String, Object>();
|
||||
|
||||
private IConfigContext configContext = new ConfigContext();
|
||||
private final IConfigContext configContext = new ConfigContext();
|
||||
|
||||
public String getTenant() {
|
||||
return (String)param.get("tenant");
|
||||
return (String) param.get("tenant");
|
||||
}
|
||||
|
||||
public void setTenant(String tenant) {
|
||||
@ -41,7 +42,7 @@ public class ConfigRequest implements IConfigRequest {
|
||||
}
|
||||
|
||||
public String getDataId() {
|
||||
return (String)param.get("dataId");
|
||||
return (String) param.get("dataId");
|
||||
}
|
||||
|
||||
public void setDataId(String dataId) {
|
||||
@ -49,7 +50,7 @@ public class ConfigRequest implements IConfigRequest {
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return (String)param.get("group");
|
||||
return (String) param.get("group");
|
||||
}
|
||||
|
||||
public void setGroup(String group) {
|
||||
@ -57,7 +58,7 @@ public class ConfigRequest implements IConfigRequest {
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return (String)param.get("content");
|
||||
return (String) param.get("content");
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.filter.impl;
|
||||
|
||||
import com.alibaba.nacos.api.config.filter.IConfigContext;
|
||||
@ -22,18 +23,18 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Config Response
|
||||
* Config Response.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ConfigResponse implements IConfigResponse {
|
||||
|
||||
private Map<String, Object> param = new HashMap<String, Object>();
|
||||
private final Map<String, Object> param = new HashMap<String, Object>();
|
||||
|
||||
private IConfigContext configContext = new ConfigContext();
|
||||
private final IConfigContext configContext = new ConfigContext();
|
||||
|
||||
public String getTenant() {
|
||||
return (String)param.get("tenant");
|
||||
return (String) param.get("tenant");
|
||||
}
|
||||
|
||||
public void setTenant(String tenant) {
|
||||
@ -41,7 +42,7 @@ public class ConfigResponse implements IConfigResponse {
|
||||
}
|
||||
|
||||
public String getDataId() {
|
||||
return (String)param.get("dataId");
|
||||
return (String) param.get("dataId");
|
||||
}
|
||||
|
||||
public void setDataId(String dataId) {
|
||||
@ -49,7 +50,7 @@ public class ConfigResponse implements IConfigResponse {
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return (String)param.get("group");
|
||||
return (String) param.get("group");
|
||||
}
|
||||
|
||||
public void setGroup(String group) {
|
||||
@ -57,7 +58,7 @@ public class ConfigResponse implements IConfigResponse {
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return (String)param.get("content");
|
||||
return (String) param.get("content");
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.http;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
@ -22,23 +23,23 @@ import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* HttpAgent
|
||||
* HttpAgent.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public interface HttpAgent extends Closeable {
|
||||
|
||||
/**
|
||||
* start to get nacos ip list
|
||||
* @return Nothing.
|
||||
* start to get nacos ip list.
|
||||
*
|
||||
* @throws NacosException on get ip list error.
|
||||
*/
|
||||
void start() throws NacosException;
|
||||
|
||||
/**
|
||||
* invoke http get method
|
||||
* invoke http get method.
|
||||
*
|
||||
* @param path http path
|
||||
* @param headers http headers
|
||||
* @param paramValues http paramValues http
|
||||
@ -48,10 +49,12 @@ public interface HttpAgent extends Closeable {
|
||||
* @throws IOException If an input or output exception occurred
|
||||
*/
|
||||
|
||||
HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException;
|
||||
HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* invoke http post method
|
||||
* invoke http post method.
|
||||
*
|
||||
* @param path http path
|
||||
* @param headers http headers
|
||||
* @param paramValues http paramValues http
|
||||
@ -60,10 +63,12 @@ public interface HttpAgent extends Closeable {
|
||||
* @return HttpResult http response
|
||||
* @throws IOException If an input or output exception occurred
|
||||
*/
|
||||
HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException;
|
||||
HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException;
|
||||
|
||||
/**
|
||||
* invoke http delete method
|
||||
* invoke http delete method.
|
||||
*
|
||||
* @param path http path
|
||||
* @param headers http headers
|
||||
* @param paramValues http paramValues http
|
||||
@ -72,28 +77,33 @@ public interface HttpAgent extends Closeable {
|
||||
* @return HttpResult http response
|
||||
* @throws IOException If an input or output exception occurred
|
||||
*/
|
||||
HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException;
|
||||
HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException;
|
||||
|
||||
/**
|
||||
* get name
|
||||
* get name.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* get namespace
|
||||
* get namespace.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
String getNamespace();
|
||||
|
||||
/**
|
||||
* get tenant
|
||||
* get tenant.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
String getTenant();
|
||||
|
||||
/**
|
||||
* get encode
|
||||
* get encode.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
String getEncode();
|
||||
|
@ -13,11 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* MetricsHttpAgent
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.http;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
@ -29,13 +25,13 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MetricsHttpAgent
|
||||
* MetricsHttpAgent.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class MetricsHttpAgent implements HttpAgent {
|
||||
|
||||
private HttpAgent httpAgent;
|
||||
private final HttpAgent httpAgent;
|
||||
|
||||
public MetricsHttpAgent(HttpAgent httpAgent) {
|
||||
this.httpAgent = httpAgent;
|
||||
@ -47,7 +43,8 @@ public class MetricsHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
|
||||
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("GET", path, "NA");
|
||||
HttpResult result;
|
||||
try {
|
||||
@ -63,7 +60,8 @@ public class MetricsHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
|
||||
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("POST", path, "NA");
|
||||
HttpResult result;
|
||||
try {
|
||||
@ -79,7 +77,8 @@ public class MetricsHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
|
||||
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("DELETE", path, "NA");
|
||||
HttpResult result;
|
||||
try {
|
||||
@ -116,7 +115,7 @@ public class MetricsHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
public void shutdown() throws NacosException {
|
||||
httpAgent.shutdown();
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.http;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
@ -22,7 +23,7 @@ import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
|
||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
||||
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.identify.StsConfig;
|
||||
import com.alibaba.nacos.client.security.SecurityProxy;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
@ -45,14 +46,14 @@ import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Server Agent
|
||||
* Server Agent.
|
||||
*
|
||||
* @author water.lyl
|
||||
*/
|
||||
@ -64,24 +65,26 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
|
||||
private String namespaceId;
|
||||
|
||||
private long securityInfoRefreshIntervalMills = TimeUnit.SECONDS.toMillis(5);
|
||||
private final long securityInfoRefreshIntervalMills = TimeUnit.SECONDS.toMillis(5);
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
/**
|
||||
* Invoke http get method.
|
||||
*
|
||||
* @param path 相对于web应用根,以/开头
|
||||
* @param headers
|
||||
* @param paramValues
|
||||
* @param encoding
|
||||
* @param readTimeoutMs
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @param headers headers
|
||||
* @param paramValues parameters
|
||||
* @param encoding encoding
|
||||
* @param readTimeoutMs time out milliseconds
|
||||
* @return http result
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
@Override
|
||||
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||
final boolean isSSL = false;
|
||||
final boolean isSsl = false;
|
||||
injectSecurityInfo(paramValues);
|
||||
String currentServerAddr = serverListMgr.getCurrentServerAddr();
|
||||
int maxRetry = this.maxRetry;
|
||||
@ -92,9 +95,9 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
HttpResult result = HttpSimpleClient.httpGet(
|
||||
getUrl(currentServerAddr, path), newHeaders, paramValues, encoding,
|
||||
readTimeoutMs, isSSL);
|
||||
HttpResult result = HttpSimpleClient
|
||||
.httpGet(getUrl(currentServerAddr, path), newHeaders, paramValues, encoding, readTimeoutMs,
|
||||
isSsl);
|
||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
@ -105,13 +108,16 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
serverListMgr.updateCurrentServerAddr(currentServerAddr);
|
||||
return result;
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
LOGGER.error("[NACOS ConnectException httpGet] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), ce.getMessage());
|
||||
} catch (SocketTimeoutException stoe) {
|
||||
LOGGER.error("[NACOS SocketTimeoutException httpGet] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), stoe.getMessage());
|
||||
} catch (IOException ioe) {
|
||||
LOGGER.error("[NACOS IOException httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);
|
||||
throw ioe;
|
||||
} catch (ConnectException connectException) {
|
||||
LOGGER.error("[NACOS ConnectException httpGet] currentServerAddr:{}, err : {}",
|
||||
serverListMgr.getCurrentServerAddr(), connectException.getMessage());
|
||||
} catch (SocketTimeoutException socketTimeoutException) {
|
||||
LOGGER.error("[NACOS SocketTimeoutException httpGet] currentServerAddr:{}, err : {}",
|
||||
serverListMgr.getCurrentServerAddr(), socketTimeoutException.getMessage());
|
||||
} catch (IOException ioException) {
|
||||
LOGGER.error("[NACOS IOException httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(),
|
||||
ioException);
|
||||
throw ioException;
|
||||
}
|
||||
|
||||
if (serverListMgr.getIterator().hasNext()) {
|
||||
@ -119,7 +125,8 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
} else {
|
||||
maxRetry--;
|
||||
if (maxRetry < 0) {
|
||||
throw new ConnectException("[NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached");
|
||||
throw new ConnectException(
|
||||
"[NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached");
|
||||
}
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
}
|
||||
@ -134,7 +141,7 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||
boolean isSSL = false;
|
||||
boolean isSsl = false;
|
||||
injectSecurityInfo(paramValues);
|
||||
String currentServerAddr = serverListMgr.getCurrentServerAddr();
|
||||
int maxRetry = this.maxRetry;
|
||||
@ -147,23 +154,25 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
|
||||
HttpResult result = HttpSimpleClient.httpPost(
|
||||
getUrl(currentServerAddr, path), newHeaders, paramValues, encoding,
|
||||
readTimeoutMs, isSSL);
|
||||
HttpResult result = HttpSimpleClient
|
||||
.httpPost(getUrl(currentServerAddr, path), newHeaders, paramValues, encoding, readTimeoutMs,
|
||||
isSsl);
|
||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
|
||||
currentServerAddr, result.code);
|
||||
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", currentServerAddr,
|
||||
result.code);
|
||||
} else {
|
||||
// Update the currently available server addr
|
||||
serverListMgr.updateCurrentServerAddr(currentServerAddr);
|
||||
return result;
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
LOGGER.error("[NACOS ConnectException httpPost] currentServerAddr: {}, err : {}", currentServerAddr, ce.getMessage());
|
||||
} catch (SocketTimeoutException stoe) {
|
||||
LOGGER.error("[NACOS SocketTimeoutException httpPost] currentServerAddr: {}, err : {}", currentServerAddr, stoe.getMessage());
|
||||
} catch (ConnectException connectException) {
|
||||
LOGGER.error("[NACOS ConnectException httpPost] currentServerAddr: {}, err : {}", currentServerAddr,
|
||||
connectException.getMessage());
|
||||
} catch (SocketTimeoutException socketTimeoutException) {
|
||||
LOGGER.error("[NACOS SocketTimeoutException httpPost] currentServerAddr: {}, err : {}",
|
||||
currentServerAddr, socketTimeoutException.getMessage());
|
||||
} catch (IOException ioe) {
|
||||
LOGGER.error("[NACOS IOException httpPost] currentServerAddr: " + currentServerAddr, ioe);
|
||||
throw ioe;
|
||||
@ -174,7 +183,8 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
} else {
|
||||
maxRetry--;
|
||||
if (maxRetry < 0) {
|
||||
throw new ConnectException("[NACOS HTTP-POST] The maximum number of tolerable server reconnection errors has been reached");
|
||||
throw new ConnectException(
|
||||
"[NACOS HTTP-POST] The maximum number of tolerable server reconnection errors has been reached");
|
||||
}
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
}
|
||||
@ -189,7 +199,7 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||
boolean isSSL = false;
|
||||
boolean isSsl = false;
|
||||
injectSecurityInfo(paramValues);
|
||||
String currentServerAddr = serverListMgr.getCurrentServerAddr();
|
||||
int maxRetry = this.maxRetry;
|
||||
@ -200,9 +210,9 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
HttpResult result = HttpSimpleClient.httpDelete(
|
||||
getUrl(currentServerAddr, path), newHeaders, paramValues, encoding,
|
||||
readTimeoutMs, isSSL);
|
||||
HttpResult result = HttpSimpleClient
|
||||
.httpDelete(getUrl(currentServerAddr, path), newHeaders, paramValues, encoding, readTimeoutMs,
|
||||
isSsl);
|
||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
@ -213,14 +223,18 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
serverListMgr.updateCurrentServerAddr(currentServerAddr);
|
||||
return result;
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
ce.printStackTrace();
|
||||
LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), ce.getMessage());
|
||||
} catch (ConnectException connectException) {
|
||||
connectException.printStackTrace();
|
||||
LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}, err : {}",
|
||||
serverListMgr.getCurrentServerAddr(), connectException.getMessage());
|
||||
} catch (SocketTimeoutException stoe) {
|
||||
stoe.printStackTrace();
|
||||
LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), stoe.getMessage());
|
||||
LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{}, err : {}",
|
||||
serverListMgr.getCurrentServerAddr(), stoe.getMessage());
|
||||
} catch (IOException ioe) {
|
||||
LOGGER.error("[NACOS IOException httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);
|
||||
LOGGER.error(
|
||||
"[NACOS IOException httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(),
|
||||
ioe);
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
@ -229,7 +243,8 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
} else {
|
||||
maxRetry--;
|
||||
if (maxRetry < 0) {
|
||||
throw new ConnectException("[NACOS HTTP-DELETE] The maximum number of tolerable server reconnection errors has been reached");
|
||||
throw new ConnectException(
|
||||
"[NACOS HTTP-DELETE] The maximum number of tolerable server reconnection errors has been reached");
|
||||
}
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
}
|
||||
@ -241,8 +256,8 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
private String getUrl(String serverAddr, String relativePath) {
|
||||
String contextPath = serverListMgr.getContentPath().startsWith("/") ?
|
||||
serverListMgr.getContentPath() : "/" + serverListMgr.getContentPath();
|
||||
String contextPath = serverListMgr.getContentPath().startsWith("/") ? serverListMgr.getContentPath()
|
||||
: "/" + serverListMgr.getContentPath();
|
||||
return serverAddr + contextPath + relativePath;
|
||||
}
|
||||
|
||||
@ -266,7 +281,6 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
init(properties);
|
||||
this.securityProxy.login(this.serverListMgr.getServerUrls());
|
||||
|
||||
|
||||
// init executorService
|
||||
this.executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||
@Override
|
||||
@ -305,7 +319,8 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
private void initEncode(Properties properties) {
|
||||
encode = TemplateUtils.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.ENCODE), new Callable<String>() {
|
||||
encode = TemplateUtils
|
||||
.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.ENCODE), new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return Constants.ENCODE;
|
||||
@ -316,7 +331,7 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
private void initAkSk(Properties properties) {
|
||||
String ramRoleName = properties.getProperty(PropertyKeyConst.RAM_ROLE_NAME);
|
||||
if (!StringUtils.isBlank(ramRoleName)) {
|
||||
STSConfig.getInstance().setRamRoleName(ramRoleName);
|
||||
StsConfig.getInstance().setRamRoleName(ramRoleName);
|
||||
}
|
||||
|
||||
String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
|
||||
@ -346,12 +361,12 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
private List<String> getSpasHeaders(List<String> paramValues) throws IOException {
|
||||
List<String> newHeaders = new ArrayList<String>();
|
||||
// STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
|
||||
if (STSConfig.getInstance().isSTSOn()) {
|
||||
STSCredential sTSCredential = getSTSCredential();
|
||||
accessKey = sTSCredential.accessKeyId;
|
||||
secretKey = sTSCredential.accessKeySecret;
|
||||
if (StsConfig.getInstance().isStsOn()) {
|
||||
StsCredential stsCredential = getStsCredential();
|
||||
accessKey = stsCredential.accessKeyId;
|
||||
secretKey = stsCredential.accessKeySecret;
|
||||
newHeaders.add("Spas-SecurityToken");
|
||||
newHeaders.add(sTSCredential.securityToken);
|
||||
newHeaders.add(stsCredential.securityToken);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) {
|
||||
@ -365,31 +380,32 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
return newHeaders;
|
||||
}
|
||||
|
||||
private STSCredential getSTSCredential() throws IOException {
|
||||
boolean cacheSecurityCredentials = STSConfig.getInstance().isCacheSecurityCredentials();
|
||||
if (cacheSecurityCredentials && sTSCredential != null) {
|
||||
private StsCredential getStsCredential() throws IOException {
|
||||
boolean cacheSecurityCredentials = StsConfig.getInstance().isCacheSecurityCredentials();
|
||||
if (cacheSecurityCredentials && stsCredential != null) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long expirationTime = sTSCredential.expiration.getTime();
|
||||
int timeToRefreshInMillisecond = STSConfig.getInstance().getTimeToRefreshInMillisecond();
|
||||
long expirationTime = stsCredential.expiration.getTime();
|
||||
int timeToRefreshInMillisecond = StsConfig.getInstance().getTimeToRefreshInMillisecond();
|
||||
if (expirationTime - currentTime > timeToRefreshInMillisecond) {
|
||||
return sTSCredential;
|
||||
return stsCredential;
|
||||
}
|
||||
}
|
||||
String stsResponse = getSTSResponse();
|
||||
STSCredential stsCredentialTmp = JacksonUtils.toObj(stsResponse, new TypeReference<STSCredential>() {
|
||||
String stsResponse = getStsResponse();
|
||||
StsCredential stsCredentialTmp = JacksonUtils.toObj(stsResponse, new TypeReference<StsCredential>() {
|
||||
});
|
||||
sTSCredential = stsCredentialTmp;
|
||||
LOGGER.info("[getSTSCredential] code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}", sTSCredential.getCode(),
|
||||
sTSCredential.getAccessKeyId(), sTSCredential.getLastUpdated(), sTSCredential.getExpiration());
|
||||
return sTSCredential;
|
||||
stsCredential = stsCredentialTmp;
|
||||
LOGGER.info("[getSTSCredential] code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}",
|
||||
stsCredential.getCode(), stsCredential.getAccessKeyId(), stsCredential.getLastUpdated(),
|
||||
stsCredential.getExpiration());
|
||||
return stsCredential;
|
||||
}
|
||||
|
||||
private static String getSTSResponse() throws IOException {
|
||||
String securityCredentials = STSConfig.getInstance().getSecurityCredentials();
|
||||
private static String getStsResponse() throws IOException {
|
||||
String securityCredentials = StsConfig.getInstance().getSecurityCredentials();
|
||||
if (securityCredentials != null) {
|
||||
return securityCredentials;
|
||||
}
|
||||
String securityCredentialsUrl = STSConfig.getInstance().getSecurityCredentialsUrl();
|
||||
String securityCredentialsUrl = StsConfig.getInstance().getSecurityCredentialsUrl();
|
||||
HttpURLConnection conn = null;
|
||||
int respCode;
|
||||
String response;
|
||||
@ -441,25 +457,30 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, LOGGER);
|
||||
LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
private static class STSCredential {
|
||||
private static class StsCredential {
|
||||
|
||||
@JsonProperty(value = "AccessKeyId")
|
||||
private String accessKeyId;
|
||||
|
||||
@JsonProperty(value = "AccessKeySecret")
|
||||
private String accessKeySecret;
|
||||
|
||||
@JsonProperty(value = "Expiration")
|
||||
private Date expiration;
|
||||
|
||||
@JsonProperty(value = "SecurityToken")
|
||||
private String securityToken;
|
||||
|
||||
@JsonProperty(value = "LastUpdated")
|
||||
private Date lastUpdated;
|
||||
|
||||
@JsonProperty(value = "Code")
|
||||
private String code;
|
||||
|
||||
@ -481,22 +502,22 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "STSCredential{" +
|
||||
"accessKeyId='" + accessKeyId + '\'' +
|
||||
", accessKeySecret='" + accessKeySecret + '\'' +
|
||||
", expiration=" + expiration +
|
||||
", securityToken='" + securityToken + '\'' +
|
||||
", lastUpdated=" + lastUpdated +
|
||||
", code='" + code + '\'' +
|
||||
'}';
|
||||
return "STSCredential{" + "accessKeyId='" + accessKeyId + '\'' + ", accessKeySecret='" + accessKeySecret
|
||||
+ '\'' + ", expiration=" + expiration + ", securityToken='" + securityToken + '\''
|
||||
+ ", lastUpdated=" + lastUpdated + ", code='" + code + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
private String accessKey;
|
||||
|
||||
private String secretKey;
|
||||
|
||||
private String encode;
|
||||
|
||||
private int maxRetry = 3;
|
||||
private volatile STSCredential sTSCredential;
|
||||
|
||||
private volatile StsCredential stsCredential;
|
||||
|
||||
final ServerListManager serverListMgr;
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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.config.ConfigChangeItem;
|
||||
@ -20,16 +21,16 @@ import com.alibaba.nacos.api.config.PropertyChangeType;
|
||||
import com.alibaba.nacos.api.config.listener.ConfigChangeParser;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* AbstractConfigChangeParser
|
||||
* AbstractConfigChangeParser.
|
||||
*
|
||||
* @author rushsky518
|
||||
*/
|
||||
public abstract class AbstractConfigChangeParser implements ConfigChangeParser {
|
||||
private String configType;
|
||||
|
||||
private final String configType;
|
||||
|
||||
public AbstractConfigChangeParser(String configType) {
|
||||
this.configType = configType;
|
||||
@ -42,8 +43,7 @@ public abstract class AbstractConfigChangeParser implements ConfigChangeParser {
|
||||
|
||||
protected Map<String, ConfigChangeItem> filterChangeData(Map oldMap, Map newMap) {
|
||||
Map<String, ConfigChangeItem> result = new HashMap<String, ConfigChangeItem>(16);
|
||||
for (Iterator<Map.Entry<String, Object>> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) {
|
||||
Map.Entry<String, Object> e = entryItr.next();
|
||||
for (Map.Entry<String, Object> e : (Iterable<Map.Entry<String, Object>>) oldMap.entrySet()) {
|
||||
ConfigChangeItem cci;
|
||||
if (newMap.containsKey(e.getKey())) {
|
||||
if (e.getValue().equals(newMap.get(e.getKey()))) {
|
||||
@ -59,8 +59,7 @@ public abstract class AbstractConfigChangeParser implements ConfigChangeParser {
|
||||
result.put(e.getKey(), cci);
|
||||
}
|
||||
|
||||
for (Iterator<Map.Entry<String, Object>> entryItr = newMap.entrySet().iterator(); entryItr.hasNext();) {
|
||||
Map.Entry<String, Object> e = entryItr.next();
|
||||
for (Map.Entry<String, Object> e : (Iterable<Map.Entry<String, Object>>) newMap.entrySet()) {
|
||||
if (!oldMap.containsKey(e.getKey())) {
|
||||
ConfigChangeItem cci = new ConfigChangeItem(e.getKey(), null, e.getValue().toString());
|
||||
cci.setType(PropertyChangeType.ADDED);
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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;
|
||||
@ -23,9 +24,9 @@ import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
|
||||
import com.alibaba.nacos.client.config.filter.impl.ConfigResponse;
|
||||
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
|
||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.utils.TenantUtil;
|
||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -34,7 +35,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Listner Management
|
||||
* Listener Management.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@ -76,8 +77,7 @@ public class CacheData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add listener
|
||||
* if CacheData already set new content, Listener should init lastCallMd5 by CacheData.md5
|
||||
* Add listener if CacheData already set new content, Listener should init lastCallMd5 by CacheData.md5
|
||||
*
|
||||
* @param listener listener
|
||||
*/
|
||||
@ -85,8 +85,9 @@ public class CacheData {
|
||||
if (null == listener) {
|
||||
throw new IllegalArgumentException("listener is null");
|
||||
}
|
||||
ManagerListenerWrap wrap = (listener instanceof AbstractConfigChangeListener) ?
|
||||
new ManagerListenerWrap(listener, md5, content) : new ManagerListenerWrap(listener, md5);
|
||||
ManagerListenerWrap wrap =
|
||||
(listener instanceof AbstractConfigChangeListener) ? new ManagerListenerWrap(listener, md5, content)
|
||||
: new ManagerListenerWrap(listener, md5);
|
||||
|
||||
if (listeners.addIfAbsent(wrap)) {
|
||||
LOGGER.info("[{}] [add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", name, tenant, dataId, group,
|
||||
@ -94,18 +95,24 @@ public class CacheData {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove listener.
|
||||
*
|
||||
* @param listener listener
|
||||
*/
|
||||
public void removeListener(Listener listener) {
|
||||
if (null == listener) {
|
||||
throw new IllegalArgumentException("listener is null");
|
||||
}
|
||||
ManagerListenerWrap wrap = new ManagerListenerWrap(listener);
|
||||
if (listeners.remove(wrap)) {
|
||||
LOGGER.info("[{}] [remove-listener] ok, dataId={}, group={}, cnt={}", name, dataId, group, listeners.size());
|
||||
LOGGER.info("[{}] [remove-listener] ok, dataId={}, group={}, cnt={}", name, dataId, group,
|
||||
listeners.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回监听器列表上的迭代器,只读。保证不返回NULL。
|
||||
* 返回监听器列表上的迭代器,只读。保证不返回NULL.
|
||||
*/
|
||||
public List<Listener> getListeners() {
|
||||
List<Listener> result = new ArrayList<Listener>();
|
||||
@ -204,21 +211,22 @@ public class CacheData {
|
||||
|
||||
// compare lastContent and content
|
||||
if (listener instanceof AbstractConfigChangeListener) {
|
||||
Map data = ConfigChangeHandler.getInstance().parseChangeData(listenerWrap.lastContent, content, type);
|
||||
Map data = ConfigChangeHandler.getInstance()
|
||||
.parseChangeData(listenerWrap.lastContent, content, type);
|
||||
ConfigChangeEvent event = new ConfigChangeEvent(data);
|
||||
((AbstractConfigChangeListener)listener).receiveConfigChange(event);
|
||||
((AbstractConfigChangeListener) listener).receiveConfigChange(event);
|
||||
listenerWrap.lastContent = content;
|
||||
}
|
||||
|
||||
listenerWrap.lastCallMd5 = md5;
|
||||
LOGGER.info("[{}] [notify-ok] dataId={}, group={}, md5={}, listener={} ", name, dataId, group, md5,
|
||||
listener);
|
||||
} catch (NacosException de) {
|
||||
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} errCode={} errMsg={}", name,
|
||||
dataId, group, md5, listener, de.getErrCode(), de.getErrMsg());
|
||||
} catch (NacosException ex) {
|
||||
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} errCode={} errMsg={}",
|
||||
name, dataId, group, md5, listener, ex.getErrCode(), ex.getErrMsg());
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} tx={}", name, dataId, group,
|
||||
md5, listener, t.getCause());
|
||||
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} tx={}", name, dataId,
|
||||
group, md5, listener, t.getCause());
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(myClassLoader);
|
||||
}
|
||||
@ -233,22 +241,21 @@ public class CacheData {
|
||||
job.run();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} throwable={}", name, dataId, group,
|
||||
md5, listener, t.getCause());
|
||||
LOGGER.error("[{}] [notify-error] dataId={}, group={}, md5={}, listener={} throwable={}", name, dataId,
|
||||
group, md5, listener, t.getCause());
|
||||
}
|
||||
final long finishNotify = System.currentTimeMillis();
|
||||
LOGGER.info("[{}] [notify-listener] time cost={}ms in ClientWorker, dataId={}, group={}, md5={}, listener={} ",
|
||||
name, (finishNotify - startNotify), dataId, group, md5, listener);
|
||||
}
|
||||
|
||||
static public String getMd5String(String config) {
|
||||
public static String getMd5String(String config) {
|
||||
return (null == config) ? Constants.NULL : MD5Utils.md5Hex(config, Constants.ENCODE);
|
||||
}
|
||||
|
||||
private String loadCacheContentFromDiskLocal(String name, String dataId, String group, String tenant) {
|
||||
String content = LocalConfigInfoProcessor.getFailover(name, dataId, group, tenant);
|
||||
content = (null != content) ? content
|
||||
: LocalConfigInfoProcessor.getSnapshot(name, dataId, group, tenant);
|
||||
content = (null != content) ? content : LocalConfigInfoProcessor.getSnapshot(name, dataId, group, tenant);
|
||||
return content;
|
||||
}
|
||||
|
||||
@ -286,30 +293,43 @@ public class CacheData {
|
||||
// ==================
|
||||
|
||||
private final String name;
|
||||
|
||||
private final ConfigFilterChainManager configFilterChainManager;
|
||||
|
||||
public final String dataId;
|
||||
|
||||
public final String group;
|
||||
|
||||
public final String tenant;
|
||||
|
||||
private final CopyOnWriteArrayList<ManagerListenerWrap> listeners;
|
||||
|
||||
private volatile String md5;
|
||||
|
||||
/**
|
||||
* whether use local config
|
||||
* whether use local config.
|
||||
*/
|
||||
private volatile boolean isUseLocalConfig = false;
|
||||
|
||||
/**
|
||||
* last modify time
|
||||
* last modify time.
|
||||
*/
|
||||
private volatile long localConfigLastModified;
|
||||
private volatile String content;
|
||||
private int taskId;
|
||||
private volatile boolean isInitializing = true;
|
||||
private String type;
|
||||
}
|
||||
|
||||
class ManagerListenerWrap {
|
||||
private volatile String content;
|
||||
|
||||
private int taskId;
|
||||
|
||||
private volatile boolean isInitializing = true;
|
||||
|
||||
private String type;
|
||||
|
||||
private static class ManagerListenerWrap {
|
||||
|
||||
final Listener listener;
|
||||
|
||||
String lastCallMd5 = CacheData.getMd5String(null);
|
||||
|
||||
String lastContent = null;
|
||||
|
||||
ManagerListenerWrap(Listener listener) {
|
||||
@ -344,4 +364,5 @@ class ManagerListenerWrap {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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.PropertyKeyConst;
|
||||
@ -25,14 +26,14 @@ import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
|
||||
import com.alibaba.nacos.client.config.http.HttpAgent;
|
||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
||||
import com.alibaba.nacos.client.config.utils.ContentUtils;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import com.alibaba.nacos.client.monitor.MetricsMonitor;
|
||||
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.client.utils.TenantUtil;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.slf4j.Logger;
|
||||
@ -41,13 +42,13 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@ -55,12 +56,12 @@ 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;
|
||||
import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR;
|
||||
import static com.alibaba.nacos.api.common.Constants.CONFIG_TYPE;
|
||||
|
||||
/**
|
||||
* Longpolling
|
||||
* Long polling.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@ -68,6 +69,13 @@ public class ClientWorker implements Closeable {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.logger(ClientWorker.class);
|
||||
|
||||
/**
|
||||
* Add listeners for data.
|
||||
*
|
||||
* @param dataId dataId of data
|
||||
* @param group group of data
|
||||
* @param listeners listeners
|
||||
*/
|
||||
public void addListeners(String dataId, String group, List<? extends Listener> listeners) {
|
||||
group = null2defaultGroup(group);
|
||||
CacheData cache = addCacheDataIfAbsent(dataId, group);
|
||||
@ -76,6 +84,13 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove listener.
|
||||
*
|
||||
* @param dataId dataId of data
|
||||
* @param group group of data
|
||||
* @param listener listener
|
||||
*/
|
||||
public void removeListener(String dataId, String group, Listener listener) {
|
||||
group = null2defaultGroup(group);
|
||||
CacheData cache = getCache(dataId, group);
|
||||
@ -87,7 +102,16 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public void addTenantListeners(String dataId, String group, List<? extends Listener> listeners) throws NacosException {
|
||||
/**
|
||||
* Add listeners for tenant.
|
||||
*
|
||||
* @param dataId dataId of data
|
||||
* @param group group of data
|
||||
* @param listeners listeners
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public void addTenantListeners(String dataId, String group, List<? extends Listener> listeners)
|
||||
throws NacosException {
|
||||
group = null2defaultGroup(group);
|
||||
String tenant = agent.getTenant();
|
||||
CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
|
||||
@ -96,7 +120,17 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public void addTenantListenersWithContent(String dataId, String group, String content, List<? extends Listener> listeners) throws NacosException {
|
||||
/**
|
||||
* Add listeners for tenant with content.
|
||||
*
|
||||
* @param dataId dataId of data
|
||||
* @param group group of data
|
||||
* @param content content
|
||||
* @param listeners listeners
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public void addTenantListenersWithContent(String dataId, String group, String content,
|
||||
List<? extends Listener> listeners) throws NacosException {
|
||||
group = null2defaultGroup(group);
|
||||
String tenant = agent.getTenant();
|
||||
CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
|
||||
@ -106,6 +140,13 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove listeners for tenant.
|
||||
*
|
||||
* @param dataId dataId of data
|
||||
* @param group group of data
|
||||
* @param listener listener
|
||||
*/
|
||||
public void removeTenantListener(String dataId, String group, Listener listener) {
|
||||
group = null2defaultGroup(group);
|
||||
String tenant = agent.getTenant();
|
||||
@ -118,7 +159,7 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
void removeCache(String dataId, String group) {
|
||||
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());
|
||||
@ -142,6 +183,13 @@ public class ClientWorker implements Closeable {
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add cache data if absent.
|
||||
*
|
||||
* @param dataId data id if data
|
||||
* @param group group of data
|
||||
* @return cache data
|
||||
*/
|
||||
public CacheData addCacheDataIfAbsent(String dataId, String group) {
|
||||
CacheData cache = getCache(dataId, group);
|
||||
if (null != cache) {
|
||||
@ -176,6 +224,14 @@ public class ClientWorker implements Closeable {
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add cache data if absent.
|
||||
*
|
||||
* @param dataId data id if data
|
||||
* @param group group of data
|
||||
* @param tenant tenant of data
|
||||
* @return cache data
|
||||
*/
|
||||
public CacheData addCacheDataIfAbsent(String dataId, String group, String tenant) throws NacosException {
|
||||
CacheData cache = getCache(dataId, group, tenant);
|
||||
if (null != cache) {
|
||||
@ -239,9 +295,9 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
|
||||
} catch (IOException e) {
|
||||
String message = String.format(
|
||||
"[%s] [sub-server] get server config exception, dataId=%s, group=%s, tenant=%s", agent.getName(),
|
||||
dataId, group, tenant);
|
||||
String message = String
|
||||
.format("[%s] [sub-server] get server config exception, dataId=%s, group=%s, tenant=%s",
|
||||
agent.getName(), dataId, group, tenant);
|
||||
LOGGER.error(message, e);
|
||||
throw new NacosException(NacosException.SERVER_ERROR, e);
|
||||
}
|
||||
@ -267,15 +323,16 @@ public class ClientWorker implements Closeable {
|
||||
"data being modified, dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
|
||||
}
|
||||
case HttpURLConnection.HTTP_FORBIDDEN: {
|
||||
LOGGER.error("[{}] [sub-server-error] no right, dataId={}, group={}, tenant={}", agent.getName(), dataId,
|
||||
group, tenant);
|
||||
LOGGER.error("[{}] [sub-server-error] no right, dataId={}, group={}, tenant={}", agent.getName(),
|
||||
dataId, group, tenant);
|
||||
throw new NacosException(result.code, result.content);
|
||||
}
|
||||
default: {
|
||||
LOGGER.error("[{}] [sub-server-error] dataId={}, group={}, tenant={}, code={}", agent.getName(), dataId,
|
||||
group, tenant, result.code);
|
||||
LOGGER.error("[{}] [sub-server-error] dataId={}, group={}, tenant={}, code={}", agent.getName(),
|
||||
dataId, group, tenant, result.code);
|
||||
throw new NacosException(result.code,
|
||||
"http error, code=" + result.code + ",dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
|
||||
"http error, code=" + result.code + ",dataId=" + dataId + ",group=" + group + ",tenant="
|
||||
+ tenant);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -288,12 +345,13 @@ public class ClientWorker implements Closeable {
|
||||
|
||||
if (!cacheData.isUseLocalConfigInfo() && path.exists()) {
|
||||
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
|
||||
String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
|
||||
final String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
|
||||
cacheData.setUseLocalConfigInfo(true);
|
||||
cacheData.setLocalConfigInfoVersion(path.lastModified());
|
||||
cacheData.setContent(content);
|
||||
|
||||
LOGGER.warn("[{}] [failover-change] failover file created. dataId={}, group={}, tenant={}, md5={}, content={}",
|
||||
LOGGER.warn(
|
||||
"[{}] [failover-change] failover file created. dataId={}, group={}, tenant={}, md5={}, content={}",
|
||||
agent.getName(), dataId, group, tenant, md5, ContentUtils.truncateContent(content));
|
||||
return;
|
||||
}
|
||||
@ -307,14 +365,15 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
|
||||
// When it changed.
|
||||
if (cacheData.isUseLocalConfigInfo() && path.exists()
|
||||
&& cacheData.getLocalConfigInfoVersion() != path.lastModified()) {
|
||||
if (cacheData.isUseLocalConfigInfo() && path.exists() && cacheData.getLocalConfigInfoVersion() != path
|
||||
.lastModified()) {
|
||||
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
|
||||
String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
|
||||
final String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
|
||||
cacheData.setUseLocalConfigInfo(true);
|
||||
cacheData.setLocalConfigInfoVersion(path.lastModified());
|
||||
cacheData.setContent(content);
|
||||
LOGGER.warn("[{}] [failover-change] failover file changed. dataId={}, group={}, tenant={}, md5={}, content={}",
|
||||
LOGGER.warn(
|
||||
"[{}] [failover-change] failover file changed. dataId={}, group={}, tenant={}, md5={}, content={}",
|
||||
agent.getName(), dataId, group, tenant, md5, ContentUtils.truncateContent(content));
|
||||
}
|
||||
}
|
||||
@ -323,6 +382,9 @@ public class ClientWorker implements Closeable {
|
||||
return (null == group) ? Constants.DEFAULT_GROUP : group.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check config info.
|
||||
*/
|
||||
public void checkConfigInfo() {
|
||||
// Dispatch taskes.
|
||||
int listenerSize = cacheMap.get().size();
|
||||
@ -343,10 +405,10 @@ public class ClientWorker implements Closeable {
|
||||
* @param cacheDatas CacheDatas for config infomations.
|
||||
* @param inInitializingCacheList initial cache lists.
|
||||
* @return String include dataId and group (ps: it maybe null).
|
||||
*
|
||||
* @throws IOException Exception.
|
||||
*/
|
||||
List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> inInitializingCacheList) throws IOException {
|
||||
List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> inInitializingCacheList)
|
||||
throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (CacheData cacheData : cacheDatas) {
|
||||
if (!cacheData.isUseLocalConfigInfo()) {
|
||||
@ -372,7 +434,6 @@ public class ClientWorker implements Closeable {
|
||||
/**
|
||||
* Fetch the updated dataId list from server.
|
||||
*
|
||||
*
|
||||
* @param probeUpdateString updated attribute string value.
|
||||
* @param isInitializingCacheList initial cache lists.
|
||||
* @return The updated dataId list(ps: it maybe null).
|
||||
@ -380,7 +441,6 @@ public class ClientWorker implements Closeable {
|
||||
*/
|
||||
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException {
|
||||
|
||||
|
||||
List<String> params = new ArrayList<String>(2);
|
||||
params.add(Constants.PROBE_MODIFY_REQUEST);
|
||||
params.add(probeUpdateString);
|
||||
@ -404,8 +464,9 @@ public class ClientWorker implements Closeable {
|
||||
// increase the client's read timeout to avoid this problem.
|
||||
|
||||
long readTimeoutMs = timeout + (long) Math.round(timeout >> 1);
|
||||
HttpResult result = agent.httpPost(Constants.CONFIG_CONTROLLER_PATH + "/listener", headers, params,
|
||||
agent.getEncode(), readTimeoutMs);
|
||||
HttpResult result = agent
|
||||
.httpPost(Constants.CONFIG_CONTROLLER_PATH + "/listener", headers, params, agent.getEncode(),
|
||||
readTimeoutMs);
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == result.code) {
|
||||
setHealthServer(true);
|
||||
@ -448,14 +509,16 @@ public class ClientWorker implements Closeable {
|
||||
String group = keyArr[1];
|
||||
if (keyArr.length == 2) {
|
||||
updateList.add(GroupKey.getKey(dataId, group));
|
||||
LOGGER.info("[{}] [polling-resp] config changed. dataId={}, group={}", agent.getName(), dataId, group);
|
||||
LOGGER.info("[{}] [polling-resp] config changed. dataId={}, group={}", agent.getName(), dataId,
|
||||
group);
|
||||
} else if (keyArr.length == 3) {
|
||||
String tenant = keyArr[2];
|
||||
updateList.add(GroupKey.getKeyTenant(dataId, group, tenant));
|
||||
LOGGER.info("[{}] [polling-resp] config changed. dataId={}, group={}, tenant={}", agent.getName(),
|
||||
dataId, group, tenant);
|
||||
} else {
|
||||
LOGGER.error("[{}] [polling-resp] invalid dataIdAndGroup error {}", agent.getName(), dataIdAndGroup);
|
||||
LOGGER.error("[{}] [polling-resp] invalid dataIdAndGroup error {}", agent.getName(),
|
||||
dataIdAndGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -463,7 +526,8 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
||||
public ClientWorker(final HttpAgent agent, final ConfigFilterChainManager configFilterChainManager, final Properties properties) {
|
||||
public ClientWorker(final HttpAgent agent, final ConfigFilterChainManager configFilterChainManager,
|
||||
final Properties properties) {
|
||||
this.agent = agent;
|
||||
this.configFilterChainManager = configFilterChainManager;
|
||||
|
||||
@ -481,7 +545,8 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
});
|
||||
|
||||
this.executorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
|
||||
this.executorService = Executors
|
||||
.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
@ -508,9 +573,11 @@ public class ClientWorker implements Closeable {
|
||||
timeout = Math.max(ConvertUtils.toInt(properties.getProperty(PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT),
|
||||
Constants.CONFIG_LONG_POLL_TIMEOUT), Constants.MIN_CONFIG_LONG_POLL_TIMEOUT);
|
||||
|
||||
taskPenaltyTime = ConvertUtils.toInt(properties.getProperty(PropertyKeyConst.CONFIG_RETRY_TIME), Constants.CONFIG_RETRY_TIME);
|
||||
taskPenaltyTime = ConvertUtils
|
||||
.toInt(properties.getProperty(PropertyKeyConst.CONFIG_RETRY_TIME), Constants.CONFIG_RETRY_TIME);
|
||||
|
||||
this.enableRemoteSyncConfig = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG));
|
||||
this.enableRemoteSyncConfig = Boolean
|
||||
.parseBoolean(properties.getProperty(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -523,7 +590,8 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
|
||||
class LongPollingRunnable implements Runnable {
|
||||
private int taskId;
|
||||
|
||||
private final int taskId;
|
||||
|
||||
public LongPollingRunnable(int taskId) {
|
||||
this.taskId = taskId;
|
||||
@ -556,7 +624,6 @@ public class ClientWorker implements Closeable {
|
||||
LOGGER.info("get changedGroupKeys:" + changedGroupKeys);
|
||||
}
|
||||
|
||||
|
||||
for (String groupKey : changedGroupKeys) {
|
||||
String[] key = GroupKey.parseKey(groupKey);
|
||||
String dataId = key[0];
|
||||
@ -576,8 +643,8 @@ public class ClientWorker implements Closeable {
|
||||
agent.getName(), dataId, group, tenant, cache.getMd5(),
|
||||
ContentUtils.truncateContent(ct[0]), ct[1]);
|
||||
} catch (NacosException ioe) {
|
||||
String message = String.format(
|
||||
"[%s] [get-update] get changed config exception. dataId=%s, group=%s, tenant=%s",
|
||||
String message = String
|
||||
.format("[%s] [get-update] get changed config exception. dataId=%s, group=%s, tenant=%s",
|
||||
agent.getName(), dataId, group, tenant);
|
||||
LOGGER.error(message, ioe);
|
||||
}
|
||||
@ -611,19 +678,26 @@ public class ClientWorker implements Closeable {
|
||||
}
|
||||
|
||||
final ScheduledExecutorService executor;
|
||||
|
||||
final ScheduledExecutorService executorService;
|
||||
|
||||
/**
|
||||
* groupKey -> cacheData
|
||||
* groupKey -> cacheData.
|
||||
*/
|
||||
private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
|
||||
new HashMap<String, CacheData>());
|
||||
|
||||
private final HttpAgent agent;
|
||||
|
||||
private final ConfigFilterChainManager configFilterChainManager;
|
||||
|
||||
private boolean isHealthServer = true;
|
||||
|
||||
private long timeout;
|
||||
|
||||
private double currentLongingTaskCount = 0;
|
||||
|
||||
private int taskPenaltyTime;
|
||||
|
||||
private boolean enableRemoteSyncConfig = false;
|
||||
}
|
||||
|
@ -13,26 +13,29 @@
|
||||
* 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.config.listener.ConfigChangeParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* ConfigChangeHandler
|
||||
* ConfigChangeHandler.
|
||||
*
|
||||
* @author rushsky518
|
||||
*/
|
||||
public class ConfigChangeHandler {
|
||||
|
||||
private static class ConfigChangeHandlerHolder {
|
||||
private final static ConfigChangeHandler INSTANCE = new ConfigChangeHandler();
|
||||
|
||||
private static final ConfigChangeHandler INSTANCE = new ConfigChangeHandler();
|
||||
}
|
||||
|
||||
private ConfigChangeHandler() {
|
||||
@ -52,8 +55,17 @@ public class ConfigChangeHandler {
|
||||
return ConfigChangeHandlerHolder.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse changed data.
|
||||
*
|
||||
* @param oldContent old data
|
||||
* @param newContent new data
|
||||
* @param type data type
|
||||
* @return change data map
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
public Map parseChangeData(String oldContent, String newContent, String type) throws IOException {
|
||||
for (ConfigChangeParser changeParser: this.parserList) {
|
||||
for (ConfigChangeParser changeParser : this.parserList) {
|
||||
if (changeParser.isResponsibleFor(type)) {
|
||||
return changeParser.doParse(oldContent, newContent, type);
|
||||
}
|
||||
@ -62,6 +74,6 @@ public class ConfigChangeHandler {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
private List<ConfigChangeParser> parserList;
|
||||
private final List<ConfigChangeParser> parserList;
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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.client.utils.LogUtils;
|
||||
@ -34,18 +35,18 @@ public class EventDispatcher {
|
||||
private static final Logger LOGGER = LogUtils.logger(EventDispatcher.class);
|
||||
|
||||
/**
|
||||
* 添加事件监听器
|
||||
* 添加事件监听器.
|
||||
*/
|
||||
static public void addEventListener(AbstractEventListener listener) {
|
||||
public static void addEventListener(AbstractEventListener listener) {
|
||||
for (Class<? extends AbstractEvent> type : listener.interest()) {
|
||||
getListenerList(type).addIfAbsent(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布事件,首先发布该事件暗示的其他事件,最后通知所有对应的监听器。
|
||||
* 发布事件,首先发布该事件暗示的其他事件,最后通知所有对应的监听器.
|
||||
*/
|
||||
static public void fireEvent(AbstractEvent abstractEvent) {
|
||||
public static void fireEvent(AbstractEvent abstractEvent) {
|
||||
if (null == abstractEvent) {
|
||||
return;
|
||||
}
|
||||
@ -81,17 +82,13 @@ public class EventDispatcher {
|
||||
return listeners;
|
||||
}
|
||||
|
||||
// ========================
|
||||
|
||||
static final Map<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>> LISTENER_MAP
|
||||
= new HashMap<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>>();
|
||||
|
||||
// ========================
|
||||
@SuppressWarnings("checkstyle:linelength")
|
||||
static final Map<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>> LISTENER_MAP = new HashMap<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>>();
|
||||
|
||||
/**
|
||||
* Client事件。
|
||||
* Client事件.
|
||||
*/
|
||||
static public abstract class AbstractEvent {
|
||||
public abstract static class AbstractEvent {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<AbstractEvent> implyEvents() {
|
||||
@ -100,34 +97,32 @@ public class EventDispatcher {
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件监听器。
|
||||
* 事件监听器.
|
||||
*/
|
||||
static public abstract class AbstractEventListener {
|
||||
public abstract static class AbstractEventListener {
|
||||
|
||||
public AbstractEventListener() {
|
||||
/**
|
||||
* 自动注册给EventDispatcher
|
||||
*/
|
||||
EventDispatcher.addEventListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 感兴趣的事件列表
|
||||
* 感兴趣的事件列表.
|
||||
*
|
||||
* @return event list
|
||||
*/
|
||||
abstract public List<Class<? extends AbstractEvent>> interest();
|
||||
public abstract List<Class<? extends AbstractEvent>> interest();
|
||||
|
||||
/**
|
||||
* 处理事件
|
||||
* 处理事件.
|
||||
*
|
||||
* @param abstractEvent event to do
|
||||
*/
|
||||
abstract public void onEvent(AbstractEvent abstractEvent);
|
||||
public abstract void onEvent(AbstractEvent abstractEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* serverList has changed
|
||||
* serverList has changed.
|
||||
*/
|
||||
static public class ServerlistChangeEvent extends AbstractEvent {
|
||||
public static class ServerlistChangeEvent extends AbstractEvent {
|
||||
}
|
||||
}
|
||||
|
@ -13,14 +13,15 @@
|
||||
* 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.common.utils.MD5Utils;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
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;
|
||||
|
||||
@ -29,21 +30,36 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Http tool
|
||||
* Http tool.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class HttpSimpleClient {
|
||||
|
||||
static public HttpResult httpGet(String url, List<String> headers, List<String> paramValues,
|
||||
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
|
||||
/**
|
||||
* 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))) {
|
||||
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");
|
||||
}
|
||||
@ -75,31 +91,31 @@ public class HttpSimpleClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送GET请求。
|
||||
* 发送GET请求.
|
||||
*/
|
||||
static public HttpResult httpGet(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
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请求。
|
||||
* 发送POST请求.
|
||||
*
|
||||
* @param url
|
||||
* @param url url
|
||||
* @param headers 请求Header,可以为null
|
||||
* @param paramValues 参数,可以为null
|
||||
* @param encoding URL编码使用的字符集
|
||||
* @param readTimeoutMs 响应超时
|
||||
* @param isSSL 是否https
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @param isSsl 是否https
|
||||
* @return result
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
static public HttpResult httpPost(String url, List<String> headers, List<String> paramValues,
|
||||
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
|
||||
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))) {
|
||||
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");
|
||||
}
|
||||
@ -131,27 +147,39 @@ public class HttpSimpleClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送POST请求。
|
||||
* 发送POST请求.
|
||||
*
|
||||
* @param url
|
||||
* @param url url
|
||||
* @param headers 请求Header,可以为null
|
||||
* @param paramValues 参数,可以为null
|
||||
* @param encoding URL编码使用的字符集
|
||||
* @param readTimeoutMs 响应超时
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @return result
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
static public HttpResult httpPost(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
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);
|
||||
}
|
||||
|
||||
static public HttpResult httpDelete(String url, List<String> headers, List<String> paramValues,
|
||||
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
|
||||
/**
|
||||
* 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))) {
|
||||
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");
|
||||
}
|
||||
@ -182,12 +210,23 @@ public class HttpSimpleClient {
|
||||
}
|
||||
}
|
||||
|
||||
static public HttpResult httpDelete(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
static private void setHeaders(HttpURLConnection conn, List<String> headers, String encoding) {
|
||||
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());
|
||||
@ -217,7 +256,7 @@ public class HttpSimpleClient {
|
||||
return newHeaders;
|
||||
}
|
||||
|
||||
static private String encodingParams(List<String> paramValues, String encoding)
|
||||
private static String encodingParams(List<String> paramValues, String encoding)
|
||||
throws UnsupportedEncodingException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (null == paramValues) {
|
||||
@ -234,10 +273,13 @@ public class HttpSimpleClient {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static public class HttpResult {
|
||||
final public int code;
|
||||
final public Map<String, List<String>> headers;
|
||||
final public String content;
|
||||
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;
|
||||
@ -253,8 +295,7 @@ public class HttpSimpleClient {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HttpResult{" + "code=" + code + ", headers=" + headers + ", content='"
|
||||
+ content + '\'' + '}';
|
||||
return "HttpResult{" + "code=" + code + ", headers=" + headers + ", content='" + content + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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.client.utils.LogUtils;
|
||||
@ -26,7 +27,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Limiter
|
||||
* Limiter.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@ -35,20 +36,20 @@ public class Limiter {
|
||||
private static final Logger LOGGER = LogUtils.logger(Limiter.class);
|
||||
|
||||
private static final int CAPACITY_SIZE = 1000;
|
||||
|
||||
private static final int LIMIT_TIME = 1000;
|
||||
private static Cache<String, RateLimiter> cache = CacheBuilder.newBuilder()
|
||||
.initialCapacity(CAPACITY_SIZE).expireAfterAccess(1, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
private static final Cache<String, RateLimiter> CACHE = CacheBuilder.newBuilder().initialCapacity(CAPACITY_SIZE)
|
||||
.expireAfterAccess(1, TimeUnit.MINUTES).build();
|
||||
|
||||
/**
|
||||
* qps 5
|
||||
* qps 5.
|
||||
*/
|
||||
private static double limit = 5;
|
||||
|
||||
static {
|
||||
try {
|
||||
String limitTimeStr = System
|
||||
.getProperty("limitTime", String.valueOf(limit));
|
||||
String limitTimeStr = System.getProperty("limitTime", String.valueOf(limit));
|
||||
limit = Double.parseDouble(limitTimeStr);
|
||||
LOGGER.info("limitTime:{}", limit);
|
||||
} catch (Exception e) {
|
||||
@ -56,10 +57,16 @@ public class Limiter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge whether access key is limited.
|
||||
*
|
||||
* @param accessKeyID access key
|
||||
* @return true if is limited, otherwise false
|
||||
*/
|
||||
public static boolean isLimit(String accessKeyID) {
|
||||
RateLimiter rateLimiter = null;
|
||||
try {
|
||||
rateLimiter = cache.get(accessKeyID, new Callable<RateLimiter>() {
|
||||
rateLimiter = CACHE.get(accessKeyID, new Callable<RateLimiter>() {
|
||||
@Override
|
||||
public RateLimiter call() throws Exception {
|
||||
return RateLimiter.create(limit);
|
||||
|
@ -13,11 +13,12 @@
|
||||
* 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.client.config.utils.ConcurrentDiskUtil;
|
||||
import com.alibaba.nacos.client.config.utils.JVMUtil;
|
||||
import com.alibaba.nacos.client.config.utils.JvmUtil;
|
||||
import com.alibaba.nacos.client.config.utils.SnapShotSwitch;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
@ -30,7 +31,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Local Disaster Recovery Directory Tool
|
||||
* Local Disaster Recovery Directory Tool.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@ -38,7 +39,7 @@ public class LocalConfigInfoProcessor {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.logger(LocalConfigInfoProcessor.class);
|
||||
|
||||
static public String getFailover(String serverName, String dataId, String group, String tenant) {
|
||||
public static String getFailover(String serverName, String dataId, String group, String tenant) {
|
||||
File localPath = getFailoverFile(serverName, dataId, group, tenant);
|
||||
if (!localPath.exists() || !localPath.isFile()) {
|
||||
return null;
|
||||
@ -53,9 +54,9 @@ public class LocalConfigInfoProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地缓存文件内容。NULL表示没有本地文件或抛出异常。
|
||||
* 获取本地缓存文件内容。NULL表示没有本地文件或抛出异常.
|
||||
*/
|
||||
static public String getSnapshot(String name, String dataId, String group, String tenant) {
|
||||
public static String getSnapshot(String name, String dataId, String group, String tenant) {
|
||||
if (!SnapShotSwitch.getIsSnapShot()) {
|
||||
return null;
|
||||
}
|
||||
@ -72,12 +73,12 @@ public class LocalConfigInfoProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
static private String readFile(File file) throws IOException {
|
||||
private static String readFile(File file) throws IOException {
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (JVMUtil.isMultiInstance()) {
|
||||
if (JvmUtil.isMultiInstance()) {
|
||||
return ConcurrentDiskUtil.getFileContent(file, Constants.ENCODE);
|
||||
} else {
|
||||
InputStream is = null;
|
||||
@ -89,13 +90,22 @@ public class LocalConfigInfoProcessor {
|
||||
if (null != is) {
|
||||
is.close();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public void saveSnapshot(String envName, String dataId, String group, String tenant, String config) {
|
||||
/**
|
||||
* Save snapshot.
|
||||
*
|
||||
* @param envName env name
|
||||
* @param dataId data id
|
||||
* @param group group
|
||||
* @param tenant tenant
|
||||
* @param config config
|
||||
*/
|
||||
public static void saveSnapshot(String envName, String dataId, String group, String tenant, String config) {
|
||||
if (!SnapShotSwitch.getIsSnapShot()) {
|
||||
return;
|
||||
}
|
||||
@ -116,9 +126,8 @@ public class LocalConfigInfoProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
if (JVMUtil.isMultiInstance()) {
|
||||
ConcurrentDiskUtil.writeFileContent(file, config,
|
||||
Constants.ENCODE);
|
||||
if (JvmUtil.isMultiInstance()) {
|
||||
ConcurrentDiskUtil.writeFileContent(file, config, Constants.ENCODE);
|
||||
} else {
|
||||
IoUtils.writeStringToFile(file, config, Constants.ENCODE);
|
||||
}
|
||||
@ -129,9 +138,9 @@ public class LocalConfigInfoProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除snapshot目录下所有缓存文件。
|
||||
* 清除snapshot目录下所有缓存文件.
|
||||
*/
|
||||
static public void cleanAllSnapshot() {
|
||||
public static void cleanAllSnapshot() {
|
||||
try {
|
||||
File rootFile = new File(LOCAL_SNAPSHOT_PATH);
|
||||
File[] files = rootFile.listFiles();
|
||||
@ -148,7 +157,12 @@ public class LocalConfigInfoProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
static public void cleanEnvSnapshot(String envName) {
|
||||
/**
|
||||
* Clean snapshot.
|
||||
*
|
||||
* @param envName env name
|
||||
*/
|
||||
public static void cleanEnvSnapshot(String envName) {
|
||||
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
|
||||
tmp = new File(tmp, "snapshot");
|
||||
try {
|
||||
@ -185,13 +199,16 @@ public class LocalConfigInfoProcessor {
|
||||
}
|
||||
|
||||
public static final String LOCAL_FILEROOT_PATH;
|
||||
|
||||
public static final String LOCAL_SNAPSHOT_PATH;
|
||||
|
||||
static {
|
||||
LOCAL_FILEROOT_PATH = System.getProperty("JM.LOG.PATH", System.getProperty("user.home")) + File.separator
|
||||
+ "nacos" + File.separator + "config";
|
||||
LOCAL_SNAPSHOT_PATH = System.getProperty("JM.SNAPSHOT.PATH", System.getProperty("user.home")) + File.separator
|
||||
+ "nacos" + File.separator + "config";
|
||||
LOCAL_FILEROOT_PATH =
|
||||
System.getProperty("JM.LOG.PATH", System.getProperty("user.home")) + File.separator + "nacos"
|
||||
+ File.separator + "config";
|
||||
LOCAL_SNAPSHOT_PATH =
|
||||
System.getProperty("JM.SNAPSHOT.PATH", System.getProperty("user.home")) + File.separator + "nacos"
|
||||
+ File.separator + "config";
|
||||
LOGGER.info("LOCAL_SNAPSHOT_PATH:{}", LOCAL_SNAPSHOT_PATH);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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.config.ConfigChangeItem;
|
||||
@ -24,11 +25,12 @@ import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* PropertiesChangeParser
|
||||
* PropertiesChangeParser.
|
||||
*
|
||||
* @author rushsky518
|
||||
*/
|
||||
public class PropertiesChangeParser extends AbstractConfigChangeParser {
|
||||
|
||||
public PropertiesChangeParser() {
|
||||
super("properties");
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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.PropertyKeyConst;
|
||||
@ -33,30 +34,32 @@ import org.slf4j.Logger;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Properties;
|
||||
import java.util.Iterator;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Serverlist Manager
|
||||
* Serverlist Manager.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ServerListManager implements Closeable {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.logger(ServerListManager.class);
|
||||
|
||||
private static final String HTTPS = "https://";
|
||||
|
||||
private static final String HTTP = "http://";
|
||||
private ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||
|
||||
private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
@ -121,8 +124,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, this.contentPath, this.serverListName);
|
||||
} else {
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
@ -130,13 +133,12 @@ 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.addressServerUrl = String
|
||||
.format("http://%s:%d/%s/%s?namespace=%s", endpoint, this.endpointPort, this.contentPath,
|
||||
this.serverListName, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ServerListManager(Properties properties) throws NacosException {
|
||||
this.isStarted = false;
|
||||
this.serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
|
||||
@ -147,7 +149,7 @@ public class ServerListManager implements Closeable {
|
||||
this.isFixed = true;
|
||||
List<String> serverAddrs = new ArrayList<String>();
|
||||
String[] serverAddrsArr = this.serverAddrsStr.split(",");
|
||||
for (String serverAddr: serverAddrsArr) {
|
||||
for (String serverAddr : serverAddrsArr) {
|
||||
if (serverAddr.startsWith(HTTPS) || serverAddr.startsWith(HTTP)) {
|
||||
serverAddrs.add(serverAddr);
|
||||
} else {
|
||||
@ -161,12 +163,13 @@ public class ServerListManager implements Closeable {
|
||||
}
|
||||
this.serverUrls = serverAddrs;
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
this.name = FIXED_NAME + "-" + getFixedNameSuffix(this.serverUrls.toArray(new String[this.serverUrls.size()]));
|
||||
this.name = FIXED_NAME + "-" + getFixedNameSuffix(
|
||||
this.serverUrls.toArray(new String[this.serverUrls.size()]));
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
this.name = FIXED_NAME + "-" + getFixedNameSuffix(this.serverUrls.toArray(new String[this.serverUrls.size()])) + "-"
|
||||
+ namespace;
|
||||
this.name = FIXED_NAME + "-" + getFixedNameSuffix(
|
||||
this.serverUrls.toArray(new String[this.serverUrls.size()])) + "-" + namespace;
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
@ -175,14 +178,16 @@ 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.addressServerUrl = String
|
||||
.format("http://%s:%d/%s/%s", this.endpoint, this.endpointPort, 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);
|
||||
this.addressServerUrl = String
|
||||
.format("http://%s:%d/%s/%s?namespace=%s", this.endpoint, this.endpointPort, this.contentPath,
|
||||
this.serverListName, namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,7 +207,9 @@ public class ServerListManager implements Closeable {
|
||||
|
||||
private String initEndpoint(final Properties properties) {
|
||||
|
||||
String endpointPortTmp = TemplateUtils.stringEmptyAndThenExecute(System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT), new Callable<String>() {
|
||||
String endpointPortTmp = TemplateUtils
|
||||
.stringEmptyAndThenExecute(System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT),
|
||||
new Callable<String>() {
|
||||
@Override
|
||||
public String call() {
|
||||
return properties.getProperty(PropertyKeyConst.ENDPOINT_PORT);
|
||||
@ -216,8 +223,7 @@ public class ServerListManager implements Closeable {
|
||||
String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT);
|
||||
|
||||
// Whether to enable domain name resolution rules
|
||||
String isUseEndpointRuleParsing =
|
||||
properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
|
||||
String isUseEndpointRuleParsing = properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
|
||||
System.getProperty(SystemPropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
|
||||
String.valueOf(ParamUtil.USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE)));
|
||||
if (Boolean.parseBoolean(isUseEndpointRuleParsing)) {
|
||||
@ -231,6 +237,11 @@ public class ServerListManager implements Closeable {
|
||||
return StringUtils.isNotBlank(endpointTmp) ? endpointTmp : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Start.
|
||||
*
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public synchronized void start() throws NacosException {
|
||||
|
||||
if (isStarted || isFixed) {
|
||||
@ -255,7 +266,7 @@ public class ServerListManager implements Closeable {
|
||||
}
|
||||
|
||||
// executor schedules the timer task
|
||||
this.executorService.scheduleWithFixedDelay(getServersTask,0L, 30L, TimeUnit.SECONDS);
|
||||
this.executorService.scheduleWithFixedDelay(getServersTask, 0L, 30L, TimeUnit.SECONDS);
|
||||
isStarted = true;
|
||||
}
|
||||
|
||||
@ -271,7 +282,7 @@ public class ServerListManager implements Closeable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, LOGGER);
|
||||
@ -279,6 +290,7 @@ public class ServerListManager implements Closeable {
|
||||
}
|
||||
|
||||
class GetServerListTask implements Runnable {
|
||||
|
||||
final String url;
|
||||
|
||||
GetServerListTask(String url) {
|
||||
@ -287,14 +299,13 @@ public class ServerListManager implements Closeable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
/**
|
||||
* get serverlist from nameserver
|
||||
/*
|
||||
get serverlist from nameserver
|
||||
*/
|
||||
try {
|
||||
updateIfChanged(getApacheServerList(url, name));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("[" + name + "][update-serverlist] failed to update serverlist from address server!",
|
||||
e);
|
||||
LOGGER.error("[" + name + "][update-serverlist] failed to update serverlist from address server!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -314,8 +325,8 @@ public class ServerListManager implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* no change
|
||||
/*
|
||||
no change
|
||||
*/
|
||||
if (newServerAddrList.equals(serverUrls)) {
|
||||
return;
|
||||
@ -425,56 +436,71 @@ public class ServerListManager implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the different environment
|
||||
* The name of the different environment.
|
||||
*/
|
||||
private String name;
|
||||
private final String name;
|
||||
|
||||
private String namespace = "";
|
||||
|
||||
private String tenant = "";
|
||||
static public final String DEFAULT_NAME = "default";
|
||||
static public final String CUSTOM_NAME = "custom";
|
||||
static public final String FIXED_NAME = "fixed";
|
||||
private int initServerlistRetryTimes = 5;
|
||||
|
||||
public static final String DEFAULT_NAME = "default";
|
||||
|
||||
public static final String CUSTOM_NAME = "custom";
|
||||
|
||||
public static final String FIXED_NAME = "fixed";
|
||||
|
||||
private final int initServerlistRetryTimes = 5;
|
||||
|
||||
/**
|
||||
* Connection timeout and socket timeout with other servers
|
||||
* Connection timeout and socket timeout with other servers.
|
||||
*/
|
||||
static final int TIMEOUT = 5000;
|
||||
|
||||
final boolean isFixed;
|
||||
|
||||
boolean isStarted = false;
|
||||
|
||||
private String endpoint;
|
||||
|
||||
private int endpointPort = 8080;
|
||||
|
||||
private String contentPath = ParamUtil.getDefaultContextPath();
|
||||
|
||||
private String serverListName = ParamUtil.getDefaultNodesPath();
|
||||
|
||||
volatile List<String> serverUrls = new ArrayList<String>();
|
||||
|
||||
private volatile String currentServerAddr;
|
||||
|
||||
private Iterator<String> iterator;
|
||||
|
||||
public String serverPort = ParamUtil.getDefaultServerPort();
|
||||
|
||||
public String addressServerUrl;
|
||||
|
||||
private String serverAddrsStr;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Sort the address list, with the same room priority.
|
||||
*/
|
||||
class ServerAddressIterator implements Iterator<String> {
|
||||
private static class ServerAddressIterator implements Iterator<String> {
|
||||
|
||||
static class RandomizedServerAddress implements Comparable<RandomizedServerAddress> {
|
||||
|
||||
static Random random = new Random();
|
||||
|
||||
String serverIp;
|
||||
|
||||
int priority = 0;
|
||||
|
||||
int seed;
|
||||
|
||||
public RandomizedServerAddress(String ip) {
|
||||
try {
|
||||
this.serverIp = ip;
|
||||
/**
|
||||
* change random scope from 32 to Integer.MAX_VALUE to fix load balance issue
|
||||
/*
|
||||
change random scope from 32 to Integer.MAX_VALUE to fix load balance issue
|
||||
*/
|
||||
this.seed = random.nextInt(Integer.MAX_VALUE);
|
||||
} catch (Exception e) {
|
||||
@ -517,6 +543,7 @@ class ServerAddressIterator implements Iterator<String> {
|
||||
}
|
||||
|
||||
final List<RandomizedServerAddress> sorted;
|
||||
final Iterator<RandomizedServerAddress> iter;
|
||||
}
|
||||
|
||||
final Iterator<RandomizedServerAddress> iter;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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;
|
||||
@ -23,10 +24,15 @@ import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 适配spas接口
|
||||
* 适配spas接口.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@ -41,9 +47,9 @@ public class SpasAdapter {
|
||||
header.add("Spas-Signature");
|
||||
String signature = "";
|
||||
if (StringUtils.isBlank(resource)) {
|
||||
signature = signWithhmacSHA1Encrypt(timeStamp, secretKey);
|
||||
signature = signWithHmacSha1Encrypt(timeStamp, secretKey);
|
||||
} else {
|
||||
signature = signWithhmacSHA1Encrypt(resource + "+" + timeStamp, secretKey);
|
||||
signature = signWithHmacSha1Encrypt(resource + "+" + timeStamp, secretKey);
|
||||
}
|
||||
header.add(signature);
|
||||
}
|
||||
@ -82,16 +88,23 @@ public class SpasAdapter {
|
||||
return CredentialService.getInstance().getCredential().getAccessKey();
|
||||
}
|
||||
|
||||
public static String signWithhmacSHA1Encrypt(String encryptText, String encryptKey) {
|
||||
/**
|
||||
* Sign with hmac SHA1 encrtpt.
|
||||
*
|
||||
* @param encryptText encrypt text
|
||||
* @param encryptKey encrypt key
|
||||
* @return base64 string
|
||||
*/
|
||||
public static String signWithHmacSha1Encrypt(String encryptText, String encryptKey) {
|
||||
try {
|
||||
byte[] data = encryptKey.getBytes("UTF-8");
|
||||
byte[] data = encryptKey.getBytes(StandardCharsets.UTF_8);
|
||||
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
|
||||
SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
|
||||
// 生成一个指定 Mac 算法 的 Mac 对象
|
||||
Mac mac = Mac.getInstance("HmacSHA1");
|
||||
// 用给定密钥初始化 Mac 对象
|
||||
mac.init(secretKey);
|
||||
byte[] text = encryptText.getBytes("UTF-8");
|
||||
byte[] text = encryptText.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] textFinal = mac.doFinal(text);
|
||||
// 完成 Mac 操作, base64编码,将byte数组转换为字符串
|
||||
return new String(Base64.encodeBase64(textFinal), Constants.ENCODE);
|
||||
@ -101,5 +114,6 @@ public class SpasAdapter {
|
||||
}
|
||||
|
||||
private static final String GROUP_KEY = "group";
|
||||
|
||||
public static final String TENANT_KEY = "tenant";
|
||||
}
|
||||
|
@ -13,19 +13,26 @@
|
||||
* 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.config.ConfigChangeItem;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import java.util.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* YmlChangeParser
|
||||
* YmlChangeParser.
|
||||
*
|
||||
* @author rushsky518
|
||||
*/
|
||||
public class YmlChangeParser extends AbstractConfigChangeParser {
|
||||
|
||||
public YmlChangeParser() {
|
||||
super("yaml");
|
||||
}
|
||||
@ -67,12 +74,10 @@ public class YmlChangeParser extends AbstractConfigChangeParser {
|
||||
if (e.getValue() instanceof String) {
|
||||
result.put(key, e.getValue());
|
||||
} else if (e.getValue() instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = (Map<String, Object>) e.getValue();
|
||||
@SuppressWarnings("unchecked") Map<String, Object> map = (Map<String, Object>) e.getValue();
|
||||
buildFlattenedMap(result, map, key);
|
||||
} else if (e.getValue() instanceof Collection) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<Object> collection = (Collection<Object>) e.getValue();
|
||||
@SuppressWarnings("unchecked") Collection<Object> collection = (Collection<Object>) e.getValue();
|
||||
if (collection.isEmpty()) {
|
||||
result.put(key, "");
|
||||
} else {
|
||||
|
@ -13,24 +13,28 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.listener.impl;
|
||||
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.api.config.ConfigChangeEvent;
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
|
||||
/**
|
||||
* AbstractConfigChangeListener
|
||||
* AbstractConfigChangeListener.
|
||||
*
|
||||
* @author rushsky518
|
||||
*/
|
||||
public abstract class AbstractConfigChangeListener extends AbstractListener {
|
||||
|
||||
/**
|
||||
* handle config change
|
||||
* @param event
|
||||
* handle config change.
|
||||
*
|
||||
* @param event config change event
|
||||
*/
|
||||
public abstract void receiveConfigChange(final ConfigChangeEvent event);
|
||||
|
||||
@Override
|
||||
public void receiveConfigInfo(final String configInfo) {}
|
||||
public void receiveConfigInfo(final String configInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.listener.impl;
|
||||
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
@ -25,7 +26,7 @@ import java.io.StringReader;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Properties Listener
|
||||
* Properties Listener.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@ -51,7 +52,7 @@ public abstract class PropertiesListener extends AbstractListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* properties type for receiver
|
||||
* properties type for receiver.
|
||||
*
|
||||
* @param properties properties
|
||||
*/
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@ -30,36 +31,34 @@ import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
|
||||
/**
|
||||
* concurrent disk util;op file with file lock
|
||||
* concurrent disk util;op file with file lock.
|
||||
*
|
||||
* @author configCenter
|
||||
*/
|
||||
public class ConcurrentDiskUtil {
|
||||
|
||||
/**
|
||||
* get file content
|
||||
* get file content.
|
||||
*
|
||||
* @param path file path
|
||||
* @param charsetName charsetName
|
||||
* @return content
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static String getFileContent(String path, String charsetName)
|
||||
throws IOException {
|
||||
public static String getFileContent(String path, String charsetName) throws IOException {
|
||||
File file = new File(path);
|
||||
return getFileContent(file, charsetName);
|
||||
}
|
||||
|
||||
/**
|
||||
* get file content
|
||||
* get file content.
|
||||
*
|
||||
* @param file file
|
||||
* @param charsetName charsetName
|
||||
* @return content
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static String getFileContent(File file, String charsetName)
|
||||
throws IOException {
|
||||
public static String getFileContent(File file, String charsetName) throws IOException {
|
||||
RandomAccessFile fis = null;
|
||||
FileLock rlock = null;
|
||||
try {
|
||||
@ -72,17 +71,14 @@ public class ConcurrentDiskUtil {
|
||||
} catch (Exception e) {
|
||||
++i;
|
||||
if (i > RETRY_COUNT) {
|
||||
LOGGER.error("read {} fail;retryed time:{}",
|
||||
file.getName(), i);
|
||||
throw new IOException("read " + file.getAbsolutePath()
|
||||
+ " conflict");
|
||||
LOGGER.error("read {} fail;retryed time:{}", file.getName(), i);
|
||||
throw new IOException("read " + file.getAbsolutePath() + " conflict");
|
||||
}
|
||||
sleep(SLEEP_BASETIME * i);
|
||||
LOGGER.warn("read {} conflict;retry time:{}", file.getName(),
|
||||
i);
|
||||
LOGGER.warn("read {} conflict;retry time:{}", file.getName(), i);
|
||||
}
|
||||
} while (null == rlock);
|
||||
int fileSize = (int)fcin.size();
|
||||
int fileSize = (int) fcin.size();
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(fileSize);
|
||||
fcin.read(byteBuffer);
|
||||
byteBuffer.flip();
|
||||
@ -100,7 +96,7 @@ public class ConcurrentDiskUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* write file content
|
||||
* write file content.
|
||||
*
|
||||
* @param path file path
|
||||
* @param content content
|
||||
@ -108,14 +104,13 @@ public class ConcurrentDiskUtil {
|
||||
* @return whether write ok
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static Boolean writeFileContent(String path, String content,
|
||||
String charsetName) throws IOException {
|
||||
public static Boolean writeFileContent(String path, String content, String charsetName) throws IOException {
|
||||
File file = new File(path);
|
||||
return writeFileContent(file, content, charsetName);
|
||||
}
|
||||
|
||||
/**
|
||||
* write file content
|
||||
* write file content.
|
||||
*
|
||||
* @param file file
|
||||
* @param content content
|
||||
@ -123,8 +118,7 @@ public class ConcurrentDiskUtil {
|
||||
* @return whether write ok
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static Boolean writeFileContent(File file, String content,
|
||||
String charsetName) throws IOException {
|
||||
public static Boolean writeFileContent(File file, String content, String charsetName) throws IOException {
|
||||
if (!file.exists()) {
|
||||
boolean isCreateOk = file.createNewFile();
|
||||
if (!isCreateOk) {
|
||||
@ -144,19 +138,15 @@ public class ConcurrentDiskUtil {
|
||||
} catch (Exception e) {
|
||||
++i;
|
||||
if (i > RETRY_COUNT) {
|
||||
LOGGER.error("write {} fail;retryed time:{}",
|
||||
file.getName(), i);
|
||||
throw new IOException("write " + file.getAbsolutePath()
|
||||
+ " conflict");
|
||||
LOGGER.error("write {} fail;retryed time:{}", file.getName(), i);
|
||||
throw new IOException("write " + file.getAbsolutePath() + " conflict");
|
||||
}
|
||||
sleep(SLEEP_BASETIME * i);
|
||||
LOGGER.warn("write {} conflict;retry time:{}", file.getName(),
|
||||
i);
|
||||
LOGGER.warn("write {} conflict;retry time:{}", file.getName(), i);
|
||||
}
|
||||
} while (null == lock);
|
||||
|
||||
ByteBuffer sendBuffer = ByteBuffer.wrap(content
|
||||
.getBytes(charsetName));
|
||||
ByteBuffer sendBuffer = ByteBuffer.wrap(content.getBytes(charsetName));
|
||||
while (sendBuffer.hasRemaining()) {
|
||||
channel.write(sendBuffer);
|
||||
}
|
||||
@ -194,15 +184,14 @@ public class ConcurrentDiskUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* transfer ByteBuffer to String
|
||||
* transfer ByteBuffer to String.
|
||||
*
|
||||
* @param buffer buffer
|
||||
* @param charsetName charsetName
|
||||
* @return String
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static String byteBufferToString(ByteBuffer buffer,
|
||||
String charsetName) throws IOException {
|
||||
public static String byteBufferToString(ByteBuffer buffer, String charsetName) throws IOException {
|
||||
Charset charset = null;
|
||||
CharsetDecoder decoder = null;
|
||||
CharBuffer charBuffer = null;
|
||||
@ -221,9 +210,11 @@ public class ConcurrentDiskUtil {
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ConcurrentDiskUtil.class);
|
||||
|
||||
static final int RETRY_COUNT = 10;
|
||||
|
||||
/**
|
||||
* ms
|
||||
* ms.
|
||||
*/
|
||||
static final int SLEEP_BASETIME = 10;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.utils;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
@ -20,12 +21,18 @@ import com.alibaba.nacos.api.common.Constants;
|
||||
import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Content Util
|
||||
* Content Util.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ContentUtils {
|
||||
|
||||
/**
|
||||
* Verify increment pub content.
|
||||
*
|
||||
* @param content content
|
||||
* @throws IllegalArgumentException if content is not valid
|
||||
*/
|
||||
public static void verifyIncrementPubContent(String content) {
|
||||
|
||||
if (content == null || content.length() == 0) {
|
||||
@ -58,6 +65,12 @@ public class ContentUtils {
|
||||
return content.substring(index + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate content.
|
||||
*
|
||||
* @param content content
|
||||
* @return truncated content
|
||||
*/
|
||||
public static String truncateContent(String content) {
|
||||
if (content == null) {
|
||||
return "";
|
||||
@ -68,5 +81,5 @@ public class ContentUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static int SHOW_CONTENT_SIZE = 100;
|
||||
private static final int SHOW_CONTENT_SIZE = 100;
|
||||
}
|
||||
|
@ -13,21 +13,21 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.utils;
|
||||
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
* Get jvm config
|
||||
* Get jvm config.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public class JVMUtil {
|
||||
public class JvmUtil {
|
||||
|
||||
/**
|
||||
* whether is multi instance
|
||||
* whether is multi instance.
|
||||
*
|
||||
* @return whether multi
|
||||
*/
|
||||
@ -36,8 +36,10 @@ public class JVMUtil {
|
||||
}
|
||||
|
||||
private static Boolean isMultiInstance = false;
|
||||
|
||||
private static final String TRUE = "true";
|
||||
private static final Logger LOGGER = LogUtils.logger(JVMUtil.class);
|
||||
|
||||
private static final Logger LOGGER = LogUtils.logger(JvmUtil.class);
|
||||
|
||||
static {
|
||||
String multiDeploy = System.getProperty("isMultiInstance", "false");
|
@ -13,28 +13,29 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.utils;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.client.utils.IPUtil;
|
||||
import com.alibaba.nacos.client.utils.IpUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Param check util
|
||||
* Param check util.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ParamUtils {
|
||||
|
||||
private static char[] validChars = new char[] {'_', '-', '.', ':'};
|
||||
private static final char[] VALID_CHARS = new char[] {'_', '-', '.', ':'};
|
||||
|
||||
/**
|
||||
* 白名单的方式检查, 合法的参数只能包含字母、数字、以及validChars中的字符, 并且不能为空
|
||||
* 白名单的方式检查, 合法的参数只能包含字母、数字、以及validChars中的字符, 并且不能为空.
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
* @param param parameter
|
||||
* @return true if valid
|
||||
*/
|
||||
public static boolean isValid(String param) {
|
||||
if (param == null) {
|
||||
@ -51,7 +52,7 @@ public class ParamUtils {
|
||||
}
|
||||
|
||||
private static boolean isValidChar(char ch) {
|
||||
for (char c : validChars) {
|
||||
for (char c : VALID_CHARS) {
|
||||
if (c == ch) {
|
||||
return true;
|
||||
}
|
||||
@ -59,16 +60,15 @@ public class ParamUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void checkKeyParam(String dataId, String group) throws NacosException {
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkTDG(String tenant, String dataId, String group) throws NacosException {
|
||||
/**
|
||||
* Check Tenant, dataId and group.
|
||||
*
|
||||
* @param tenant tenant
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public static void checkTdg(String tenant, String dataId, String group) throws NacosException {
|
||||
checkTenant(tenant);
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
@ -78,8 +78,31 @@ public class ParamUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkKeyParam(String dataId, String group, String datumId)
|
||||
throws NacosException {
|
||||
/**
|
||||
* Check key param.
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public static void checkKeyParam(String dataId, String group) throws NacosException {
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check key param.
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param datumId datumId
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public static void checkKeyParam(String dataId, String group, String datumId) throws NacosException {
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
@ -91,6 +114,13 @@ public class ParamUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check key param.
|
||||
*
|
||||
* @param dataIds dataIds
|
||||
* @param group group
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public static void checkKeyParam(List<String> dataIds, String group) throws NacosException {
|
||||
if (dataIds == null || dataIds.size() == 0) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataIds invalid");
|
||||
@ -105,6 +135,14 @@ public class ParamUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check parameter.
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param content content
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public static void checkParam(String dataId, String group, String content) throws NacosException {
|
||||
checkKeyParam(dataId, group);
|
||||
if (StringUtils.isBlank(content)) {
|
||||
@ -112,6 +150,15 @@ public class ParamUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check parameter.
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param datumId datumId
|
||||
* @param content content
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public static void checkParam(String dataId, String group, String datumId, String content) throws NacosException {
|
||||
checkKeyParam(dataId, group, datumId);
|
||||
if (StringUtils.isBlank(content)) {
|
||||
@ -119,24 +166,42 @@ public class ParamUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Tenant.
|
||||
*
|
||||
* @param tenant tenant
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public static void checkTenant(String tenant) throws NacosException {
|
||||
if (StringUtils.isBlank(tenant) || !ParamUtils.isValid(tenant)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "tenant invalid");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check beta ips.
|
||||
*
|
||||
* @param betaIps beta ips
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public static void checkBetaIps(String betaIps) throws NacosException {
|
||||
if (StringUtils.isBlank(betaIps)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
|
||||
}
|
||||
String[] ipsArr = betaIps.split(",");
|
||||
for (String ip : ipsArr) {
|
||||
if (!IPUtil.isIPV4(ip)) {
|
||||
if (!IpUtil.isIpv4(ip)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check content.
|
||||
*
|
||||
* @param content content
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public static void checkContent(String content) throws NacosException {
|
||||
if (StringUtils.isBlank(content)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
|
||||
|
@ -13,19 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.config.utils;
|
||||
|
||||
import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
|
||||
|
||||
/**
|
||||
* Snapshot switch
|
||||
* Snapshot switch.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class SnapShotSwitch {
|
||||
|
||||
/**
|
||||
* whether use local cache
|
||||
* whether use local cache.
|
||||
*/
|
||||
private static Boolean isSnapShot = true;
|
||||
|
||||
|
@ -13,14 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Provides Base64 encoding and decoding as defined by <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>.
|
||||
* <p>
|
||||
* <p> This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose
|
||||
*
|
||||
* <p>This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045
|
||||
*
|
||||
* <cite>Multipurpose
|
||||
* Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein. </p> <p>
|
||||
* The class can be parameterized in the following manner with various constructors: <ul> <li>URL-safe mode: Default
|
||||
* off.</li> <li>Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being
|
||||
@ -41,13 +44,15 @@ public class Base64 {
|
||||
* which is converted into 4 BASE64 characters.
|
||||
*/
|
||||
private static final int BITS_PER_ENCODED_BYTE = 6;
|
||||
|
||||
private static final int BYTES_PER_UNENCODED_BLOCK = 3;
|
||||
|
||||
private static final int BYTES_PER_ENCODED_BLOCK = 4;
|
||||
|
||||
/**
|
||||
* Chunk separator per RFC 2045 section 2.1.
|
||||
* <p>
|
||||
* <p> N.B. The next major release may break compatibility and make this field private. </p>
|
||||
*
|
||||
* <p>N.B. The next major release may break compatibility and make this field private. </p>
|
||||
*
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
|
||||
*/
|
||||
@ -56,56 +61,45 @@ public class Base64 {
|
||||
/**
|
||||
* This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet"
|
||||
* equivalents as specified in Table 1 of RFC 2045.
|
||||
* <p>
|
||||
* Thanks to "commons" project in ws.apache.org for this code. http://svn.apache
|
||||
* .org/repos/asf/webservices/commons/trunk/modules/util/
|
||||
*
|
||||
* <p>Thanks to "commons" project in ws.apache.org for this code.
|
||||
*
|
||||
* <p>http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
|
||||
*/
|
||||
private static final byte[] STANDARD_ENCODE_TABLE = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
private static final byte[] STANDARD_ENCODE_TABLE = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
|
||||
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
|
||||
'2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
|
||||
|
||||
/**
|
||||
* This is a copy of the STANDARD_ENCODE_TABLE above, but with + and / changed to - and _ to make the encoded Base64
|
||||
* results more URL-SAFE. This table is only used when the Base64's mode is set to URL-SAFE.
|
||||
*/
|
||||
private static final byte[] URL_SAFE_ENCODE_TABLE = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
|
||||
};
|
||||
private static final byte[] URL_SAFE_ENCODE_TABLE = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
|
||||
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
|
||||
'2', '3', '4', '5', '6', '7', '8', '9', '-', '_'};
|
||||
|
||||
/**
|
||||
* This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified in
|
||||
* Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64
|
||||
* alphabet but fall within the bounds of the array are translated to -1.
|
||||
* <p>
|
||||
* Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both
|
||||
* URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit).
|
||||
* <p>
|
||||
* Thanks to "commons" project in ws.apache.org for this code. http://svn.apache
|
||||
* .org/repos/asf/webservices/commons/trunk/modules/util/
|
||||
*
|
||||
* <p>Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles
|
||||
* both URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit).
|
||||
*
|
||||
* <p>Thanks to "commons" project in ws.apache.org for this code.
|
||||
*
|
||||
* <p>http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
|
||||
*/
|
||||
private static final byte[] DECODE_TABLE = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54,
|
||||
55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
|
||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
|
||||
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
||||
};
|
||||
private static final byte[] DECODE_TABLE = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1,
|
||||
62, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
|
||||
|
||||
/**
|
||||
* Base64 uses 6-bit fields.
|
||||
*/
|
||||
/**
|
||||
* Mask used to extract 6 bits, used when encoding
|
||||
* Base64 uses 6-bit fields. Mask used to extract 6 bits, used when encoding
|
||||
*/
|
||||
private static final int MASK_6BITS = 0x3f;
|
||||
|
||||
@ -121,7 +115,7 @@ public class Base64 {
|
||||
private final byte[] encodeTable;
|
||||
|
||||
/**
|
||||
* Only one decode table currently; keep for consistency with Base32 code
|
||||
* Only one decode table currently; keep for consistency with Base32 code.
|
||||
*/
|
||||
private final byte[] decodeTable = DECODE_TABLE;
|
||||
|
||||
@ -151,8 +145,8 @@ public class Base64 {
|
||||
/**
|
||||
* Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. <p> When encoding the line
|
||||
* length is 0 (no chunking), and the encoding table is STANDARD_ENCODE_TABLE. </p>
|
||||
* <p>
|
||||
* <p> When decoding all variants are supported. </p>
|
||||
*
|
||||
* <p>When decoding all variants are supported. </p>
|
||||
*/
|
||||
public Base64() {
|
||||
this(0, CHUNK_SEPARATOR, false);
|
||||
@ -178,17 +172,14 @@ public class Base64 {
|
||||
chunkSeparatorLength = lineSeparator == null ? 0 : lineSeparator.length;
|
||||
unencodedBlockSize = BYTES_PER_UNENCODED_BLOCK;
|
||||
encodedBlockSize = BYTES_PER_ENCODED_BLOCK;
|
||||
this.lineLength = (lineLength > 0 && chunkSeparatorLength > 0) ? (lineLength / encodedBlockSize)
|
||||
* encodedBlockSize : 0;
|
||||
this.lineLength =
|
||||
(lineLength > 0 && chunkSeparatorLength > 0) ? (lineLength / encodedBlockSize) * encodedBlockSize : 0;
|
||||
// TODO could be simplified if there is no requirement to reject invalid line sep when length <=0
|
||||
// @see test case Base64Test.testConstructors()
|
||||
if (lineSeparator != null) {
|
||||
if (containsAlphabetOrPad(lineSeparator)) {
|
||||
String sep = null;
|
||||
try {
|
||||
sep = new String(lineSeparator, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
}
|
||||
sep = new String(lineSeparator, StandardCharsets.UTF_8);
|
||||
throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]");
|
||||
}
|
||||
if (lineLength > 0) {
|
||||
@ -207,6 +198,24 @@ public class Base64 {
|
||||
this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a byte[] containing binary data, into a byte[] containing characters in the alphabet.
|
||||
*
|
||||
* @param pArray a byte array containing binary data
|
||||
* @return A byte array containing only the basen alphabetic character data
|
||||
*/
|
||||
private byte[] encode(byte[] pArray) {
|
||||
reset();
|
||||
if (pArray == null || pArray.length == 0) {
|
||||
return pArray;
|
||||
}
|
||||
encode(pArray, 0, pArray.length);
|
||||
encode(pArray, 0, -1);
|
||||
byte[] buf = new byte[pos - readPos];
|
||||
readResults(buf, 0, buf.length);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once
|
||||
* with the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush
|
||||
@ -253,8 +262,8 @@ public class Base64 {
|
||||
break;
|
||||
}
|
||||
currentLinePos += pos - savedPos;
|
||||
/**
|
||||
* if currentPos == 0 we are at the start of a line, so don't add CRLF
|
||||
/*
|
||||
if currentPos == 0 we are at the start of a line, so don't add CRLF
|
||||
*/
|
||||
if (lineLength > 0 && currentLinePos > 0) {
|
||||
System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length);
|
||||
@ -286,12 +295,30 @@ public class Base64 {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once
|
||||
* with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1"
|
||||
* call is not necessary when decoding, but it doesn't hurt, either. </p> <p> Ignores all non-base64 characters.
|
||||
* This is how chunked (e.g. 76 character) data is handled, since CR and LF are silently ignored, but has
|
||||
* implications for other bytes, too. This method subscribes to the garbage-in, garbage-out philosophy: it will not
|
||||
* check the provided data for validity. </p> <p> Thanks to "commons" project in ws.apache.org for the bitwise
|
||||
* Decodes a byte[] containing characters in the Base-N alphabet.
|
||||
*
|
||||
* @param pArray A byte array containing Base-N character data
|
||||
* @return a byte array containing binary data
|
||||
*/
|
||||
private byte[] decode(byte[] pArray) {
|
||||
reset();
|
||||
if (pArray == null || pArray.length == 0) {
|
||||
return pArray;
|
||||
}
|
||||
decode(pArray, 0, pArray.length);
|
||||
decode(pArray, 0, -1);
|
||||
byte[] result = new byte[pos];
|
||||
readResults(result, 0, result.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice:
|
||||
* once with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The
|
||||
* "-1" call is not necessary when decoding, but it doesn't hurt, either. </p> <p> Ignores all non-base64
|
||||
* characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are silently ignored, but
|
||||
* has implications for other bytes, too. This method subscribes to the garbage-in, garbage-out philosophy: it will
|
||||
* not check the provided data for validity. </p> <p> Thanks to "commons" project in ws.apache.org for the bitwise
|
||||
* operations, and general approach. http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ </p>
|
||||
*
|
||||
* @param in byte[] array of ascii data to base64 decode.
|
||||
@ -319,9 +346,9 @@ public class Base64 {
|
||||
modulus = (modulus + 1) % BYTES_PER_ENCODED_BLOCK;
|
||||
bitWorkArea = (bitWorkArea << BITS_PER_ENCODED_BYTE) + result;
|
||||
if (modulus == 0) {
|
||||
buffer[pos++] = (byte)((bitWorkArea >> 16) & MASK_8BITS);
|
||||
buffer[pos++] = (byte)((bitWorkArea >> 8) & MASK_8BITS);
|
||||
buffer[pos++] = (byte)(bitWorkArea & MASK_8BITS);
|
||||
buffer[pos++] = (byte) ((bitWorkArea >> 16) & MASK_8BITS);
|
||||
buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS);
|
||||
buffer[pos++] = (byte) (bitWorkArea & MASK_8BITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -341,12 +368,12 @@ public class Base64 {
|
||||
// break;
|
||||
case 2:
|
||||
bitWorkArea = bitWorkArea >> 4;
|
||||
buffer[pos++] = (byte)((bitWorkArea) & MASK_8BITS);
|
||||
buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS);
|
||||
break;
|
||||
case 3:
|
||||
bitWorkArea = bitWorkArea >> 2;
|
||||
buffer[pos++] = (byte)((bitWorkArea >> 8) & MASK_8BITS);
|
||||
buffer[pos++] = (byte)((bitWorkArea) & MASK_8BITS);
|
||||
buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS);
|
||||
buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -383,21 +410,19 @@ public class Base64 {
|
||||
|
||||
// Create this so can use the super-class method
|
||||
// Also ensures that the same roundings are performed by the ctor and the code
|
||||
Base64 b64 = isChunked ? new Base64(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe) : new Base64(0, CHUNK_SEPARATOR,
|
||||
urlSafe);
|
||||
Base64 b64 = isChunked ? new Base64(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe)
|
||||
: new Base64(0, CHUNK_SEPARATOR, urlSafe);
|
||||
long len = b64.getEncodedLength(binaryData);
|
||||
if (len > maxResultSize) {
|
||||
throw new IllegalArgumentException("Input array too big, the output array would be bigger (" +
|
||||
len +
|
||||
") than the specified maximum size of " +
|
||||
maxResultSize);
|
||||
throw new IllegalArgumentException("Input array too big, the output array would be bigger (" + len
|
||||
+ ") than the specified maximum size of " + maxResultSize);
|
||||
}
|
||||
|
||||
return b64.encode(binaryData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes Base64 data into octets
|
||||
* Decodes Base64 data into octets.
|
||||
*
|
||||
* @param base64Data Byte array containing Base64 data
|
||||
* @return Array containing decoded data.
|
||||
@ -416,15 +441,11 @@ public class Base64 {
|
||||
return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Below from base class
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIME chunk size per RFC 2045 section 6.8.
|
||||
* <p>
|
||||
* <p> The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
|
||||
* equal signs. </p>
|
||||
*
|
||||
* <p> The {@value} character limit does not count the trailing CRLF, but counts all other characters, including
|
||||
* any equal signs. </p>
|
||||
*
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a>
|
||||
*/
|
||||
@ -434,12 +455,12 @@ public class Base64 {
|
||||
|
||||
/**
|
||||
* Defines the default buffer size - currently {@value} - must be large enough for at least one encoded
|
||||
* block+separator
|
||||
* block+separator.
|
||||
*/
|
||||
private static final int DEFAULT_BUFFER_SIZE = 8192;
|
||||
|
||||
/**
|
||||
* Mask used to extract 8 bits, used in decoding bytes
|
||||
* Mask used to extract 8 bits, used in decoding bytes.
|
||||
*/
|
||||
private static final int MASK_8BITS = 0xff;
|
||||
|
||||
@ -505,7 +526,7 @@ public class Base64 {
|
||||
private int modulus;
|
||||
|
||||
/**
|
||||
* Ensure that the buffer has room for <code>size</code> bytes
|
||||
* Ensure that the buffer has room for <code>size</code> bytes.
|
||||
*
|
||||
* @param size minimum spare space required
|
||||
*/
|
||||
@ -557,46 +578,10 @@ public class Base64 {
|
||||
eof = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a byte[] containing characters in the Base-N alphabet.
|
||||
*
|
||||
* @param pArray A byte array containing Base-N character data
|
||||
* @return a byte array containing binary data
|
||||
*/
|
||||
private byte[] decode(byte[] pArray) {
|
||||
reset();
|
||||
if (pArray == null || pArray.length == 0) {
|
||||
return pArray;
|
||||
}
|
||||
decode(pArray, 0, pArray.length);
|
||||
decode(pArray, 0, -1);
|
||||
byte[] result = new byte[pos];
|
||||
readResults(result, 0, result.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a byte[] containing binary data, into a byte[] containing characters in the alphabet.
|
||||
*
|
||||
* @param pArray a byte array containing binary data
|
||||
* @return A byte array containing only the basen alphabetic character data
|
||||
*/
|
||||
private byte[] encode(byte[] pArray) {
|
||||
reset();
|
||||
if (pArray == null || pArray.length == 0) {
|
||||
return pArray;
|
||||
}
|
||||
encode(pArray, 0, pArray.length);
|
||||
encode(pArray, 0, -1);
|
||||
byte[] buf = new byte[pos - readPos];
|
||||
readResults(buf, 0, buf.length);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a given byte array to see if it contains any characters within the alphabet or PAD.
|
||||
* <p>
|
||||
* Intended for use in checking line-ending arrays
|
||||
*
|
||||
* <p>Intended for use in checking line-ending arrays
|
||||
*
|
||||
* @param arrayOctet byte array to test
|
||||
* @return <code>true</code> if any byte is a valid character in the alphabet or PAD; <code>false</code> otherwise
|
||||
@ -623,10 +608,10 @@ public class Base64 {
|
||||
private long getEncodedLength(byte[] pArray) {
|
||||
// Calculate non-chunked size - rounded up to allow for padding
|
||||
// cast to long is needed to avoid possibility of overflow
|
||||
long len = ((pArray.length + unencodedBlockSize - 1) / unencodedBlockSize) * (long)encodedBlockSize;
|
||||
long len = ((pArray.length + unencodedBlockSize - 1) / unencodedBlockSize) * (long) encodedBlockSize;
|
||||
if (lineLength > 0) {
|
||||
/**
|
||||
* Round up to nearest multiple
|
||||
/*
|
||||
Round up to nearest multiple
|
||||
*/
|
||||
len += ((len + lineLength - 1) / lineLength) * chunkSeparatorLength;
|
||||
}
|
||||
|
@ -13,16 +13,18 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
/**
|
||||
* Credential Listener
|
||||
* Credential Listener.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public interface CredentialListener {
|
||||
|
||||
/**
|
||||
* update Credential
|
||||
* update Credential.
|
||||
*/
|
||||
void onUpdateCredential();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
@ -22,19 +23,22 @@ import org.slf4j.Logger;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Credential Service
|
||||
* Credential Service.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public final class CredentialService implements SpasCredentialLoader {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.logger(CredentialService.class);
|
||||
|
||||
private static ConcurrentHashMap<String, CredentialService> instances
|
||||
= new ConcurrentHashMap<String, CredentialService>();
|
||||
private static final ConcurrentHashMap<String, CredentialService> INSTANCES = new ConcurrentHashMap<String, CredentialService>();
|
||||
|
||||
private final String appName;
|
||||
|
||||
private String appName;
|
||||
private Credentials credentials = new Credentials();
|
||||
private CredentialWatcher watcher;
|
||||
|
||||
private final CredentialWatcher watcher;
|
||||
|
||||
private CredentialListener listener;
|
||||
|
||||
private CredentialService(String appName) {
|
||||
@ -54,10 +58,10 @@ public final class CredentialService implements SpasCredentialLoader {
|
||||
|
||||
public static CredentialService getInstance(String appName) {
|
||||
String key = appName != null ? appName : IdentifyConstants.NO_APP_NAME;
|
||||
CredentialService instance = instances.get(key);
|
||||
CredentialService instance = INSTANCES.get(key);
|
||||
if (instance == null) {
|
||||
instance = new CredentialService(appName);
|
||||
CredentialService previous = instances.putIfAbsent(key, instance);
|
||||
CredentialService previous = INSTANCES.putIfAbsent(key, instance);
|
||||
if (previous != null) {
|
||||
instance = previous;
|
||||
}
|
||||
@ -69,15 +73,24 @@ public final class CredentialService implements SpasCredentialLoader {
|
||||
return freeInstance(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free instance.
|
||||
*
|
||||
* @param appName app name
|
||||
* @return {@link CredentialService}
|
||||
*/
|
||||
public static CredentialService freeInstance(String appName) {
|
||||
String key = appName != null ? appName : IdentifyConstants.NO_APP_NAME;
|
||||
CredentialService instance = instances.remove(key);
|
||||
CredentialService instance = INSTANCES.remove(key);
|
||||
if (instance != null) {
|
||||
instance.free();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free service.
|
||||
*/
|
||||
public void free() {
|
||||
if (watcher != null) {
|
||||
watcher.stop();
|
||||
|
@ -13,31 +13,42 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* Credential Watcher
|
||||
* Credential Watcher.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class CredentialWatcher {
|
||||
private static final Logger SpasLogger = LogUtils.logger(CredentialWatcher.class);
|
||||
|
||||
private static final Logger SPAS_LOGGER = LogUtils.logger(CredentialWatcher.class);
|
||||
|
||||
private static final long REFRESH_INTERVAL = 10 * 1000;
|
||||
|
||||
private CredentialService serviceInstance;
|
||||
private String appName;
|
||||
private final CredentialService serviceInstance;
|
||||
|
||||
private final String appName;
|
||||
|
||||
private String propertyPath;
|
||||
private TimerTask watcher;
|
||||
|
||||
private final TimerTask watcher;
|
||||
|
||||
private boolean stopped;
|
||||
|
||||
@SuppressWarnings("PMD.AvoidUseTimerRule")
|
||||
@ -46,7 +57,8 @@ public class CredentialWatcher {
|
||||
this.serviceInstance = serviceInstance;
|
||||
loadCredential(true);
|
||||
watcher = new TimerTask() {
|
||||
private Timer timer = new Timer(true);
|
||||
private final Timer timer = new Timer(true);
|
||||
|
||||
private long modified = 0;
|
||||
|
||||
{
|
||||
@ -78,6 +90,9 @@ public class CredentialWatcher {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop watcher.
|
||||
*/
|
||||
public void stop() {
|
||||
if (stopped) {
|
||||
return;
|
||||
@ -88,7 +103,7 @@ public class CredentialWatcher {
|
||||
stopped = true;
|
||||
}
|
||||
}
|
||||
SpasLogger.info("[{}] {} is stopped", appName, this.getClass().getSimpleName());
|
||||
SPAS_LOGGER.info("[{}] {} is stopped", appName, this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
private void loadCredential(boolean init) {
|
||||
@ -105,16 +120,17 @@ public class CredentialWatcher {
|
||||
propertyPath = value;
|
||||
}
|
||||
if (propertyPath == null || propertyPath.isEmpty()) {
|
||||
propertyPath = IdentifyConstants.CREDENTIAL_PATH + (appName == null ? IdentifyConstants.CREDENTIAL_DEFAULT
|
||||
propertyPath =
|
||||
IdentifyConstants.CREDENTIAL_PATH + (appName == null ? IdentifyConstants.CREDENTIAL_DEFAULT
|
||||
: appName);
|
||||
} else {
|
||||
if (logWarn) {
|
||||
SpasLogger.info("[{}] Defined credential file: -Dspas.identity={}", appName, propertyPath);
|
||||
SPAS_LOGGER.info("[{}] Defined credential file: -Dspas.identity={}", appName, propertyPath);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (logWarn) {
|
||||
SpasLogger.info("[{}] Load credential file from classpath: {}", appName,
|
||||
SPAS_LOGGER.info("[{}] Load credential file from classpath: {}", appName,
|
||||
IdentifyConstants.PROPERTIES_FILENAME);
|
||||
}
|
||||
}
|
||||
@ -125,8 +141,8 @@ public class CredentialWatcher {
|
||||
try {
|
||||
propertiesIS = new FileInputStream(propertyPath);
|
||||
} catch (FileNotFoundException e) {
|
||||
if (appName != null && !appName.equals(IdentifyConstants.CREDENTIAL_DEFAULT) && propertyPath.equals(
|
||||
IdentifyConstants.CREDENTIAL_PATH + appName)) {
|
||||
if (appName != null && !appName.equals(IdentifyConstants.CREDENTIAL_DEFAULT) && propertyPath
|
||||
.equals(IdentifyConstants.CREDENTIAL_PATH + appName)) {
|
||||
propertyPath = IdentifyConstants.CREDENTIAL_PATH + IdentifyConstants.CREDENTIAL_DEFAULT;
|
||||
continue;
|
||||
}
|
||||
@ -147,7 +163,7 @@ public class CredentialWatcher {
|
||||
secretKey = System.getenv(IdentifyConstants.ENV_SECRET_KEY);
|
||||
if (accessKey == null && secretKey == null) {
|
||||
if (logWarn) {
|
||||
SpasLogger.info("{} No credential found", appName);
|
||||
SPAS_LOGGER.info("{} No credential found", appName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -156,7 +172,7 @@ public class CredentialWatcher {
|
||||
try {
|
||||
properties.load(propertiesIS);
|
||||
} catch (IOException e) {
|
||||
SpasLogger.error("[26] Unable to load credential file, appName:" + appName
|
||||
SPAS_LOGGER.error("[26] Unable to load credential file, appName:" + appName
|
||||
+ "Unable to load credential file " + propertyPath, e);
|
||||
propertyPath = null;
|
||||
return;
|
||||
@ -164,13 +180,13 @@ public class CredentialWatcher {
|
||||
try {
|
||||
propertiesIS.close();
|
||||
} catch (IOException e) {
|
||||
SpasLogger.error("[27] Unable to close credential file, appName:" + appName
|
||||
SPAS_LOGGER.error("[27] Unable to close credential file, appName:" + appName
|
||||
+ "Unable to close credential file " + propertyPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (logWarn) {
|
||||
SpasLogger.info("[{}] Load credential file {}", appName, propertyPath);
|
||||
SPAS_LOGGER.info("[{}] Load credential file {}", appName, propertyPath);
|
||||
}
|
||||
|
||||
if (!IdentifyConstants.DOCKER_CREDENTIAL_PATH.equals(propertyPath)) {
|
||||
@ -210,8 +226,9 @@ public class CredentialWatcher {
|
||||
|
||||
Credentials credential = new Credentials(accessKey, secretKey, tenantId);
|
||||
if (!credential.valid()) {
|
||||
SpasLogger.warn("[1] Credential file missing required property {} Credential file missing {} or {}",
|
||||
appName, IdentifyConstants.ACCESS_KEY, IdentifyConstants.SECRET_KEY);
|
||||
SPAS_LOGGER
|
||||
.warn("[1] Credential file missing required property {} Credential file missing {} or {}", appName,
|
||||
IdentifyConstants.ACCESS_KEY, IdentifyConstants.SECRET_KEY);
|
||||
propertyPath = null;
|
||||
// return;
|
||||
}
|
||||
|
@ -13,10 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
/**
|
||||
* Credentials
|
||||
* Credentials.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@ -65,15 +66,19 @@ public class Credentials implements SpasCredential {
|
||||
}
|
||||
|
||||
public boolean valid() {
|
||||
return accessKey != null && !accessKey.isEmpty() && secretKey != null
|
||||
&& !secretKey.isEmpty();
|
||||
return accessKey != null && !accessKey.isEmpty() && secretKey != null && !secretKey.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Identical.
|
||||
*
|
||||
* @param other other
|
||||
* @return true if identical
|
||||
*/
|
||||
public boolean identical(Credentials other) {
|
||||
return this == other || (other != null
|
||||
&& (accessKey == null && other.accessKey == null
|
||||
|| accessKey != null && accessKey.equals(other.accessKey))
|
||||
&& (secretKey == null && other.secretKey == null
|
||||
|| secretKey != null && secretKey.equals(other.secretKey)));
|
||||
return this == other || (other != null && (accessKey == null && other.accessKey == null
|
||||
|| accessKey != null && accessKey.equals(other.accessKey)) && (
|
||||
secretKey == null && other.secretKey == null || secretKey != null && secretKey
|
||||
.equals(other.secretKey)));
|
||||
}
|
||||
}
|
||||
|
@ -13,14 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
/**
|
||||
* Identify Constants
|
||||
* Identify Constants.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class IdentifyConstants {
|
||||
|
||||
public static final String ACCESS_KEY = "accessKey";
|
||||
|
||||
public static final String SECRET_KEY = "secretKey";
|
||||
|
@ -13,23 +13,25 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
/**
|
||||
* Spas Credential Interface
|
||||
* Spas Credential Interface.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public interface SpasCredential {
|
||||
|
||||
/**
|
||||
* get AccessKey
|
||||
* get AccessKey.
|
||||
*
|
||||
* @return AccessKey
|
||||
*/
|
||||
String getAccessKey();
|
||||
|
||||
/**
|
||||
* get SecretKey
|
||||
* get SecretKey.
|
||||
*
|
||||
* @return SecretKey
|
||||
*/
|
||||
|
@ -13,16 +13,18 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
/**
|
||||
* Spas Credential Loader
|
||||
* Spas Credential Loader.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public interface SpasCredentialLoader {
|
||||
|
||||
/**
|
||||
* get Credential
|
||||
* get Credential.
|
||||
*
|
||||
* @return Credential
|
||||
*/
|
||||
|
@ -13,43 +13,48 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Sts config
|
||||
* Sts config.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public class STSConfig {
|
||||
private static final String RAM_SECURITY_CREDENTIALS_URL
|
||||
= "http://100.100.100.200/latest/meta-data/ram/security-credentials/";
|
||||
public class StsConfig {
|
||||
|
||||
private static final String RAM_SECURITY_CREDENTIALS_URL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/";
|
||||
|
||||
private String ramRoleName;
|
||||
|
||||
/**
|
||||
* STS 临时凭证有效期剩余多少时开始刷新(允许本地时间比 STS 服务时间最多慢多久)
|
||||
* STS 临时凭证有效期剩余多少时开始刷新(允许本地时间比 STS 服务时间最多慢多久).
|
||||
*/
|
||||
private int timeToRefreshInMillisecond = 3 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* 获取 STS 临时凭证的元数据接口(包含角色名称)
|
||||
* 获取 STS 临时凭证的元数据接口(包含角色名称).
|
||||
*/
|
||||
private String securityCredentialsUrl;
|
||||
|
||||
/**
|
||||
* 设定 STS 临时凭证,不再通过元数据接口获取
|
||||
* 设定 STS 临时凭证,不再通过元数据接口获取.
|
||||
*/
|
||||
private String securityCredentials;
|
||||
|
||||
/**
|
||||
* 是否缓存
|
||||
* 是否缓存.
|
||||
*/
|
||||
private boolean cacheSecurityCredentials = true;
|
||||
|
||||
private static class Singleton {
|
||||
private static final STSConfig INSTANCE = new STSConfig();
|
||||
|
||||
private static final StsConfig INSTANCE = new StsConfig();
|
||||
}
|
||||
|
||||
private STSConfig() {
|
||||
private StsConfig() {
|
||||
String ramRoleName = System.getProperty("ram.role.name");
|
||||
if (!StringUtils.isBlank(ramRoleName)) {
|
||||
setRamRoleName(ramRoleName);
|
||||
@ -76,7 +81,7 @@ public class STSConfig {
|
||||
}
|
||||
}
|
||||
|
||||
public static STSConfig getInstance() {
|
||||
public static StsConfig getInstance() {
|
||||
return Singleton.INSTANCE;
|
||||
}
|
||||
|
||||
@ -115,7 +120,7 @@ public class STSConfig {
|
||||
this.securityCredentials = securityCredentials;
|
||||
}
|
||||
|
||||
public boolean isSTSOn() {
|
||||
public boolean isStsOn() {
|
||||
return StringUtils.isNotEmpty(getSecurityCredentials()) || StringUtils.isNotEmpty(getSecurityCredentialsUrl());
|
||||
}
|
||||
|
@ -13,13 +13,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.nacos.client.logging;
|
||||
|
||||
package com.alibaba.nacos.client.logging;
|
||||
|
||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Abstract nacos logging.
|
||||
*
|
||||
* @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
|
||||
* @since 0.9.0
|
||||
*/
|
||||
@ -57,7 +59,7 @@ public abstract class AbstractNacosLogging {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load logging configuration
|
||||
* Load logging configuration.
|
||||
*/
|
||||
public abstract void loadConfiguration();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.logging.log4j2;
|
||||
|
||||
import com.alibaba.nacos.client.logging.AbstractNacosLogging;
|
||||
@ -44,11 +45,11 @@ public class Log4J2NacosLogging extends AbstractNacosLogging {
|
||||
|
||||
private static final String NACOS_LOGGER_PREFIX = "com.alibaba.nacos";
|
||||
|
||||
private String location = getLocation(NACOS_LOG4J2_LOCATION);
|
||||
private final String location = getLocation(NACOS_LOG4J2_LOCATION);
|
||||
|
||||
@Override
|
||||
public void loadConfiguration() {
|
||||
final LoggerContext loggerContext = (LoggerContext)LogManager.getContext(false);
|
||||
final LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
|
||||
final Configuration contextConfiguration = loggerContext.getConfiguration();
|
||||
|
||||
// load and start nacos configuration
|
||||
@ -57,7 +58,7 @@ public class Log4J2NacosLogging extends AbstractNacosLogging {
|
||||
|
||||
// append loggers and appenders to contextConfiguration
|
||||
Map<String, Appender> appenders = configuration.getAppenders();
|
||||
for (Appender appender: appenders.values()) {
|
||||
for (Appender appender : appenders.values()) {
|
||||
contextConfiguration.addAppender(appender);
|
||||
}
|
||||
Map<String, LoggerConfig> loggers = configuration.getLoggers();
|
||||
@ -77,8 +78,7 @@ public class Log4J2NacosLogging extends AbstractNacosLogging {
|
||||
// since log4j 2.7 getConfiguration(LoggerContext loggerContext, ConfigurationSource source)
|
||||
return ConfigurationFactory.getInstance().getConfiguration(loggerContext, source);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize Log4J2 logging from " + location, e);
|
||||
throw new IllegalStateException("Could not initialize Log4J2 logging from " + location, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.logging.logback;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
@ -40,7 +41,7 @@ public class LogbackNacosLogging extends AbstractNacosLogging {
|
||||
}
|
||||
|
||||
try {
|
||||
LoggerContext loggerContext = (LoggerContext)StaticLoggerBinder.getSingleton().getLoggerFactory();
|
||||
LoggerContext loggerContext = (LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory();
|
||||
new ContextInitializer(loggerContext).configureByResource(ResourceUtils.getResourceUrl(location));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Could not initialize Logback Nacos logging from " + location, e);
|
||||
|
@ -13,44 +13,44 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.monitor;
|
||||
|
||||
import io.prometheus.client.Gauge;
|
||||
import io.prometheus.client.Histogram;
|
||||
|
||||
/**
|
||||
* Metrics Monitor
|
||||
* Metrics Monitor.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class MetricsMonitor {
|
||||
private static Gauge nacosMonitor = Gauge.build()
|
||||
.name("nacos_monitor").labelNames("module", "name")
|
||||
|
||||
private static final Gauge NACOS_MONITOR = Gauge.build().name("nacos_monitor").labelNames("module", "name")
|
||||
.help("nacos_monitor").register();
|
||||
|
||||
private static Histogram nacosClientRequestHistogram = Histogram.build().labelNames("module", "method", "url", "code")
|
||||
.name("nacos_client_request").help("nacos_client_request")
|
||||
private static final Histogram NACOS_CLIENT_REQUEST_HISTOGRAM = Histogram.build()
|
||||
.labelNames("module", "method", "url", "code").name("nacos_client_request").help("nacos_client_request")
|
||||
.register();
|
||||
|
||||
|
||||
public static Gauge.Child getServiceInfoMapSizeMonitor() {
|
||||
return nacosMonitor.labels("naming", "serviceInfoMapSize");
|
||||
return NACOS_MONITOR.labels("naming", "serviceInfoMapSize");
|
||||
}
|
||||
|
||||
public static Gauge.Child getDom2BeatSizeMonitor() {
|
||||
return nacosMonitor.labels("naming", "dom2BeatSize");
|
||||
return NACOS_MONITOR.labels("naming", "dom2BeatSize");
|
||||
}
|
||||
|
||||
public static Gauge.Child getListenConfigCountMonitor() {
|
||||
return nacosMonitor.labels("naming", "listenConfigCount");
|
||||
return NACOS_MONITOR.labels("naming", "listenConfigCount");
|
||||
}
|
||||
|
||||
public static Histogram.Timer getConfigRequestMonitor(String method, String url, String code) {
|
||||
return nacosClientRequestHistogram.labels("config", method, url, code).startTimer();
|
||||
return NACOS_CLIENT_REQUEST_HISTOGRAM.labels("config", method, url, code).startTimer();
|
||||
}
|
||||
|
||||
public static Histogram.Child getNamingRequestMonitor(String method, String url, String code) {
|
||||
return nacosClientRequestHistogram.labels("naming", method, url, code);
|
||||
return NACOS_CLIENT_REQUEST_HISTOGRAM.labels("naming", method, url, code);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,8 @@ import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Nacos naming maintain service.
|
||||
*
|
||||
* @author liaochuntao
|
||||
* @since 1.0.1
|
||||
*/
|
||||
@ -107,17 +109,17 @@ public class NacosNamingMaintainService implements NamingMaintainService {
|
||||
|
||||
@Override
|
||||
public void createService(String serviceName, String groupName, float protectThreshold) throws NacosException {
|
||||
NoneSelector selector = new NoneSelector();
|
||||
Service service = new Service();
|
||||
service.setName(serviceName);
|
||||
service.setGroupName(groupName);
|
||||
service.setProtectThreshold(protectThreshold);
|
||||
|
||||
createService(service, selector);
|
||||
createService(service, new NoneSelector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createService(String serviceName, String groupName, float protectThreshold, String expression) throws NacosException {
|
||||
public void createService(String serviceName, String groupName, float protectThreshold, String expression)
|
||||
throws NacosException {
|
||||
Service service = new Service();
|
||||
service.setName(serviceName);
|
||||
service.setGroupName(groupName);
|
||||
@ -155,7 +157,8 @@ public class NacosNamingMaintainService implements NamingMaintainService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateService(String serviceName, String groupName, float protectThreshold, Map<String, String> metadata) throws NacosException {
|
||||
public void updateService(String serviceName, String groupName, float protectThreshold,
|
||||
Map<String, String> metadata) throws NacosException {
|
||||
Service service = new Service();
|
||||
service.setName(serviceName);
|
||||
service.setGroupName(groupName);
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
@ -44,7 +45,7 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Nacos Naming Service
|
||||
* Nacos Naming Service.
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
@ -119,9 +120,10 @@ public class NacosNamingService implements NamingService {
|
||||
|
||||
private boolean isLoadCacheAtStart(Properties properties) {
|
||||
boolean loadCacheAtStart = false;
|
||||
if (properties != null && StringUtils.isNotEmpty(properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START))) {
|
||||
loadCacheAtStart = ConvertUtils.toBoolean(
|
||||
properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START));
|
||||
if (properties != null && StringUtils
|
||||
.isNotEmpty(properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START))) {
|
||||
loadCacheAtStart = ConvertUtils
|
||||
.toBoolean(properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START));
|
||||
}
|
||||
|
||||
return loadCacheAtStart;
|
||||
@ -139,7 +141,8 @@ public class NacosNamingService implements NamingService {
|
||||
logName = System.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME);
|
||||
if (StringUtils.isEmpty(logName)) {
|
||||
|
||||
if (properties != null && StringUtils.isNotEmpty(properties.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME))) {
|
||||
if (properties != null && StringUtils
|
||||
.isNotEmpty(properties.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME))) {
|
||||
logName = properties.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME);
|
||||
} else {
|
||||
logName = "naming.log";
|
||||
@ -170,7 +173,8 @@ public class NacosNamingService implements NamingService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException {
|
||||
public void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName)
|
||||
throws NacosException {
|
||||
|
||||
Instance instance = new Instance();
|
||||
instance.setIp(ip);
|
||||
@ -188,11 +192,12 @@ public class NacosNamingService implements NamingService {
|
||||
|
||||
@Override
|
||||
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
|
||||
if (instance.isEphemeral()) {
|
||||
BeatInfo beatInfo = beatReactor.buildBeatInfo(instance);
|
||||
beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
|
||||
BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
|
||||
beatReactor.addBeatInfo(groupedServiceName, beatInfo);
|
||||
}
|
||||
serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
|
||||
serverProxy.registerService(groupedServiceName, groupName, instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -211,7 +216,8 @@ public class NacosNamingService implements NamingService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException {
|
||||
public void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName)
|
||||
throws NacosException {
|
||||
Instance instance = new Instance();
|
||||
instance.setIp(ip);
|
||||
instance.setPort(port);
|
||||
@ -228,7 +234,8 @@ public class NacosNamingService implements NamingService {
|
||||
@Override
|
||||
public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
if (instance.isEphemeral()) {
|
||||
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), instance.getIp(), instance.getPort());
|
||||
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), instance.getIp(),
|
||||
instance.getPort());
|
||||
}
|
||||
serverProxy.deregisterService(NamingUtils.getGroupedName(serviceName, groupName), instance);
|
||||
}
|
||||
@ -249,7 +256,8 @@ public class NacosNamingService implements NamingService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Instance> getAllInstances(String serviceName, String groupName, boolean subscribe) throws NacosException {
|
||||
public List<Instance> getAllInstances(String serviceName, String groupName, boolean subscribe)
|
||||
throws NacosException {
|
||||
return getAllInstances(serviceName, groupName, new ArrayList<String>(), subscribe);
|
||||
}
|
||||
|
||||
@ -259,7 +267,8 @@ public class NacosNamingService implements NamingService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters) throws NacosException {
|
||||
public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters)
|
||||
throws NacosException {
|
||||
return getAllInstances(serviceName, groupName, clusters, true);
|
||||
}
|
||||
|
||||
@ -270,13 +279,17 @@ public class NacosNamingService implements NamingService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException {
|
||||
public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters,
|
||||
boolean subscribe) throws NacosException {
|
||||
|
||||
ServiceInfo serviceInfo;
|
||||
if (subscribe) {
|
||||
serviceInfo = hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));
|
||||
serviceInfo = hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName),
|
||||
StringUtils.join(clusters, ","));
|
||||
} else {
|
||||
serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));
|
||||
serviceInfo = hostReactor
|
||||
.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName),
|
||||
StringUtils.join(clusters, ","));
|
||||
}
|
||||
List<Instance> list;
|
||||
if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
|
||||
@ -302,7 +315,8 @@ public class NacosNamingService implements NamingService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Instance> selectInstances(String serviceName, String groupName, boolean healthy, boolean subscribe) throws NacosException {
|
||||
public List<Instance> selectInstances(String serviceName, String groupName, boolean healthy, boolean subscribe)
|
||||
throws NacosException {
|
||||
return selectInstances(serviceName, groupName, new ArrayList<String>(), healthy, subscribe);
|
||||
}
|
||||
|
||||
@ -313,148 +327,33 @@ public class NacosNamingService implements NamingService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy) throws NacosException {
|
||||
public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy)
|
||||
throws NacosException {
|
||||
return selectInstances(serviceName, groupName, clusters, healthy, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy,
|
||||
boolean subscribe) throws NacosException {
|
||||
public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy, boolean subscribe)
|
||||
throws NacosException {
|
||||
return selectInstances(serviceName, Constants.DEFAULT_GROUP, clusters, healthy, subscribe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy, boolean subscribe) throws NacosException {
|
||||
public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy,
|
||||
boolean subscribe) throws NacosException {
|
||||
|
||||
ServiceInfo serviceInfo;
|
||||
if (subscribe) {
|
||||
serviceInfo = hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));
|
||||
serviceInfo = hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName),
|
||||
StringUtils.join(clusters, ","));
|
||||
} else {
|
||||
serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));
|
||||
serviceInfo = hostReactor
|
||||
.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName),
|
||||
StringUtils.join(clusters, ","));
|
||||
}
|
||||
return selectInstances(serviceInfo, healthy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, new ArrayList<String>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, groupName, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, new ArrayList<String>(), subscribe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, String groupName, boolean subscribe) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, groupName, new ArrayList<String>(), subscribe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, clusters, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, groupName, clusters, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters, boolean subscribe)
|
||||
throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, Constants.DEFAULT_GROUP, clusters, subscribe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException {
|
||||
|
||||
if (subscribe) {
|
||||
return Balancer.RandomByWeight.selectHost(
|
||||
hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ",")));
|
||||
} else {
|
||||
return Balancer.RandomByWeight.selectHost(
|
||||
hostReactor.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ",")));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(String serviceName, EventListener listener) throws NacosException {
|
||||
subscribe(serviceName, new ArrayList<String>(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(String serviceName, String groupName, EventListener listener) throws NacosException {
|
||||
subscribe(serviceName, groupName, new ArrayList<String>(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException {
|
||||
subscribe(serviceName, Constants.DEFAULT_GROUP, clusters, listener);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(String serviceName, EventListener listener) throws NacosException {
|
||||
unsubscribe(serviceName, new ArrayList<String>(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(String serviceName, String groupName, EventListener listener) throws NacosException {
|
||||
unsubscribe(serviceName, groupName, new ArrayList<String>(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException {
|
||||
unsubscribe(serviceName, Constants.DEFAULT_GROUP, clusters, listener);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException {
|
||||
return serverProxy.getServiceList(pageNo, pageSize, Constants.DEFAULT_GROUP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName) throws NacosException {
|
||||
return getServicesOfServer(pageNo, pageSize, groupName, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector)
|
||||
throws NacosException {
|
||||
return getServicesOfServer(pageNo, pageSize, Constants.DEFAULT_GROUP, selector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException {
|
||||
return serverProxy.getServiceList(pageNo, pageSize, groupName, selector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInfo> getSubscribeServices() {
|
||||
return eventDispatcher.getSubscribeServices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerStatus() {
|
||||
return serverProxy.serverHealthy() ? "UP" : "DOWN";
|
||||
}
|
||||
|
||||
private List<Instance> selectInstances(ServiceInfo serviceInfo, boolean healthy) {
|
||||
List<Instance> list;
|
||||
if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
|
||||
@ -472,6 +371,137 @@ public class NacosNamingService implements NamingService {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, new ArrayList<String>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, groupName, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, new ArrayList<String>(), subscribe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, String groupName, boolean subscribe)
|
||||
throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, groupName, new ArrayList<String>(), subscribe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, clusters, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters)
|
||||
throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, groupName, clusters, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters, boolean subscribe)
|
||||
throws NacosException {
|
||||
return selectOneHealthyInstance(serviceName, Constants.DEFAULT_GROUP, clusters, subscribe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters,
|
||||
boolean subscribe) throws NacosException {
|
||||
|
||||
if (subscribe) {
|
||||
return Balancer.RandomByWeight.selectHost(hostReactor
|
||||
.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName),
|
||||
StringUtils.join(clusters, ",")));
|
||||
} else {
|
||||
return Balancer.RandomByWeight.selectHost(hostReactor
|
||||
.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName),
|
||||
StringUtils.join(clusters, ",")));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(String serviceName, EventListener listener) throws NacosException {
|
||||
subscribe(serviceName, new ArrayList<String>(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(String serviceName, String groupName, EventListener listener) throws NacosException {
|
||||
subscribe(serviceName, groupName, new ArrayList<String>(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException {
|
||||
subscribe(serviceName, Constants.DEFAULT_GROUP, clusters, listener);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(String serviceName, EventListener listener) throws NacosException {
|
||||
unsubscribe(serviceName, new ArrayList<String>(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(String serviceName, String groupName, EventListener listener) throws NacosException {
|
||||
unsubscribe(serviceName, groupName, new ArrayList<String>(), listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException {
|
||||
unsubscribe(serviceName, Constants.DEFAULT_GROUP, clusters, listener);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException {
|
||||
return serverProxy.getServiceList(pageNo, pageSize, Constants.DEFAULT_GROUP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName) throws NacosException {
|
||||
return getServicesOfServer(pageNo, pageSize, groupName, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector)
|
||||
throws NacosException {
|
||||
return getServicesOfServer(pageNo, pageSize, Constants.DEFAULT_GROUP, selector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName, AbstractSelector selector)
|
||||
throws NacosException {
|
||||
return serverProxy.getServiceList(pageNo, pageSize, groupName, selector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInfo> getSubscribeServices() {
|
||||
return eventDispatcher.getSubscribeServices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerStatus() {
|
||||
return serverProxy.serverHealthy() ? "UP" : "DOWN";
|
||||
}
|
||||
|
||||
public BeatReactor getBeatReactor() {
|
||||
return beatReactor;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.backups;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
@ -24,7 +25,6 @@ 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.utils.JacksonUtils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
|
||||
@ -32,27 +32,31 @@ import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
import java.util.Date;
|
||||
import java.util.Calendar;
|
||||
import java.util.TimerTask;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.Map;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Failover reactor.
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
public class FailoverReactor implements Closeable {
|
||||
|
||||
private String failoverDir;
|
||||
private final String failoverDir;
|
||||
|
||||
private HostReactor hostReactor;
|
||||
private final HostReactor hostReactor;
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
private final ScheduledExecutorService executorService;
|
||||
|
||||
public FailoverReactor(HostReactor hostReactor, String cacheDir) {
|
||||
this.hostReactor = hostReactor;
|
||||
@ -71,9 +75,14 @@ public class FailoverReactor implements Closeable {
|
||||
}
|
||||
|
||||
private Map<String, ServiceInfo> serviceMap = new ConcurrentHashMap<String, ServiceInfo>();
|
||||
private Map<String, String> switchParams = new ConcurrentHashMap<String, String>();
|
||||
|
||||
private final Map<String, String> switchParams = new ConcurrentHashMap<String, String>();
|
||||
|
||||
private static final long DAY_PERIOD_MINUTES = 24 * 60;
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*/
|
||||
public void init() {
|
||||
|
||||
executorService.scheduleWithFixedDelay(new SwitchRefresher(), 0L, 5000L, TimeUnit.MILLISECONDS);
|
||||
@ -103,6 +112,13 @@ public class FailoverReactor implements Closeable {
|
||||
}, 10000L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add day.
|
||||
*
|
||||
* @param date start time
|
||||
* @param num add day number
|
||||
* @return new date
|
||||
*/
|
||||
public Date addDay(Date date, int num) {
|
||||
Calendar startDT = Calendar.getInstance();
|
||||
startDT.setTime(date);
|
||||
@ -119,6 +135,7 @@ public class FailoverReactor implements Closeable {
|
||||
}
|
||||
|
||||
class SwitchRefresher implements Runnable {
|
||||
|
||||
long lastModifiedMillis = 0L;
|
||||
|
||||
@Override
|
||||
@ -138,7 +155,7 @@ public class FailoverReactor implements Closeable {
|
||||
String failover = ConcurrentDiskUtil.getFileContent(failoverDir + UtilAndComs.FAILOVER_SWITCH,
|
||||
Charset.defaultCharset().toString());
|
||||
if (!StringUtils.isEmpty(failover)) {
|
||||
List<String> lines = Arrays.asList(failover.split(DiskCache.getLineSeparator()));
|
||||
String[] lines = failover.split(DiskCache.getLineSeparator());
|
||||
|
||||
for (String line : lines) {
|
||||
String line1 = line.trim();
|
||||
@ -193,8 +210,8 @@ public class FailoverReactor implements Closeable {
|
||||
ServiceInfo dom = new ServiceInfo(file.getName());
|
||||
|
||||
try {
|
||||
String dataString = ConcurrentDiskUtil.getFileContent(file,
|
||||
Charset.defaultCharset().toString());
|
||||
String dataString = ConcurrentDiskUtil
|
||||
.getFileContent(file, Charset.defaultCharset().toString());
|
||||
reader = new BufferedReader(new StringReader(dataString));
|
||||
|
||||
String json;
|
||||
@ -232,16 +249,17 @@ public class FailoverReactor implements Closeable {
|
||||
}
|
||||
|
||||
class DiskFileWriter extends TimerTask {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Map<String, ServiceInfo> map = hostReactor.getServiceInfoMap();
|
||||
for (Map.Entry<String, ServiceInfo> entry : map.entrySet()) {
|
||||
ServiceInfo serviceInfo = entry.getValue();
|
||||
if (StringUtils.equals(serviceInfo.getKey(), UtilAndComs.ALL_IPS) || StringUtils.equals(
|
||||
serviceInfo.getName(), UtilAndComs.ENV_LIST_KEY)
|
||||
|| StringUtils.equals(serviceInfo.getName(), "00-00---000-ENV_CONFIGS-000---00-00")
|
||||
|| StringUtils.equals(serviceInfo.getName(), "vipclient.properties")
|
||||
|| StringUtils.equals(serviceInfo.getName(), "00-00---000-ALL_HOSTS-000---00-00")) {
|
||||
if (StringUtils.equals(serviceInfo.getKey(), UtilAndComs.ALL_IPS) || StringUtils
|
||||
.equals(serviceInfo.getName(), UtilAndComs.ENV_LIST_KEY) || StringUtils
|
||||
.equals(serviceInfo.getName(), "00-00---000-ENV_CONFIGS-000---00-00") || StringUtils
|
||||
.equals(serviceInfo.getName(), "vipclient.properties") || StringUtils
|
||||
.equals(serviceInfo.getName(), "00-00---000-ALL_HOSTS-000---00-00")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -13,38 +13,41 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.beat;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Beat information.
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
public class BeatInfo {
|
||||
|
||||
private int port;
|
||||
|
||||
private String ip;
|
||||
|
||||
private double weight;
|
||||
|
||||
private String serviceName;
|
||||
|
||||
private String cluster;
|
||||
|
||||
private Map<String, String> metadata;
|
||||
|
||||
private volatile boolean scheduled;
|
||||
|
||||
private volatile long period;
|
||||
|
||||
private volatile boolean stopped;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BeatInfo{" +
|
||||
"port=" + port +
|
||||
", ip='" + ip + '\'' +
|
||||
", weight=" + weight +
|
||||
", serviceName='" + serviceName + '\'' +
|
||||
", cluster='" + cluster + '\'' +
|
||||
", metadata=" + metadata +
|
||||
", scheduled=" + scheduled +
|
||||
", period=" + period +
|
||||
", stopped=" + stopped +
|
||||
'}';
|
||||
return "BeatInfo{" + "port=" + port + ", ip='" + ip + '\'' + ", weight=" + weight + ", serviceName='"
|
||||
+ serviceName + '\'' + ", cluster='" + cluster + '\'' + ", metadata=" + metadata + ", scheduled="
|
||||
+ scheduled + ", period=" + period + ", stopped=" + stopped + '}';
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.beat;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
@ -30,22 +31,28 @@ import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Beat reactor.
|
||||
*
|
||||
* @author harold
|
||||
*/
|
||||
public class BeatReactor implements Closeable {
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
private final ScheduledExecutorService executorService;
|
||||
|
||||
private NamingProxy serverProxy;
|
||||
private final NamingProxy serverProxy;
|
||||
|
||||
private boolean lightBeatEnabled = false;
|
||||
|
||||
public final Map<String, BeatInfo> dom2Beat = new ConcurrentHashMap<>();
|
||||
public final Map<String, BeatInfo> dom2Beat = new ConcurrentHashMap<String, BeatInfo>();
|
||||
|
||||
public BeatReactor(NamingProxy serverProxy) {
|
||||
this(serverProxy, UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT);
|
||||
@ -64,6 +71,12 @@ public class BeatReactor implements Closeable {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add beat information.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param beatInfo beat information
|
||||
*/
|
||||
public void addBeatInfo(String serviceName, BeatInfo beatInfo) {
|
||||
NAMING_LOGGER.info("[BEAT] adding beat: {} to beat map.", beatInfo);
|
||||
String key = buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort());
|
||||
@ -77,6 +90,13 @@ public class BeatReactor implements Closeable {
|
||||
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove beat information.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param ip ip of beat information
|
||||
* @param port port of beat information
|
||||
*/
|
||||
public void removeBeatInfo(String serviceName, String ip, int port) {
|
||||
NAMING_LOGGER.info("[BEAT] removing beat: {}:{}:{} from beat map.", serviceName, ip, port);
|
||||
BeatInfo beatInfo = dom2Beat.remove(buildKey(serviceName, ip, port));
|
||||
@ -87,9 +107,26 @@ public class BeatReactor implements Closeable {
|
||||
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Build new beat information.
|
||||
*
|
||||
* @param instance instance
|
||||
* @return new beat information
|
||||
*/
|
||||
public BeatInfo buildBeatInfo(Instance instance) {
|
||||
return buildBeatInfo(instance.getServiceName(), instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build new beat information.
|
||||
*
|
||||
* @param groupedServiceName service name with group name, format: ${groupName}@@${serviceName}
|
||||
* @param instance instance
|
||||
* @return new beat information
|
||||
*/
|
||||
public BeatInfo buildBeatInfo(String groupedServiceName, Instance instance) {
|
||||
BeatInfo beatInfo = new BeatInfo();
|
||||
beatInfo.setServiceName(instance.getServiceName());
|
||||
beatInfo.setServiceName(groupedServiceName);
|
||||
beatInfo.setIp(instance.getIp());
|
||||
beatInfo.setPort(instance.getPort());
|
||||
beatInfo.setCluster(instance.getClusterName());
|
||||
@ -101,12 +138,11 @@ public class BeatReactor implements Closeable {
|
||||
}
|
||||
|
||||
public String buildKey(String serviceName, String ip, int port) {
|
||||
return serviceName + Constants.NAMING_INSTANCE_ID_SPLITTER
|
||||
+ ip + Constants.NAMING_INSTANCE_ID_SPLITTER + port;
|
||||
return serviceName + Constants.NAMING_INSTANCE_ID_SPLITTER + ip + Constants.NAMING_INSTANCE_ID_SPLITTER + port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
||||
@ -129,7 +165,7 @@ public class BeatReactor implements Closeable {
|
||||
long nextTime = beatInfo.getPeriod();
|
||||
try {
|
||||
JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
|
||||
long interval = result.get("clientBeatInterval").asInt();
|
||||
long interval = result.get("clientBeatInterval").asLong();
|
||||
boolean lightBeatEnabled = false;
|
||||
if (result.has(CommonParams.LIGHT_BEAT_ENABLED)) {
|
||||
lightBeatEnabled = result.get(CommonParams.LIGHT_BEAT_ENABLED).asBoolean();
|
||||
@ -158,9 +194,9 @@ public class BeatReactor implements Closeable {
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
} catch (NacosException ne) {
|
||||
} catch (NacosException ex) {
|
||||
NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: {}, code: {}, msg: {}",
|
||||
JacksonUtils.toJson(beatInfo), ne.getErrCode(), ne.getErrMsg());
|
||||
JacksonUtils.toJson(beatInfo), ex.getErrCode(), ex.getErrMsg());
|
||||
|
||||
}
|
||||
executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.cache;
|
||||
|
||||
import java.io.File;
|
||||
@ -29,34 +30,34 @@ import java.nio.charset.CharsetDecoder;
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Concurrent Disk util.
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
public class ConcurrentDiskUtil {
|
||||
|
||||
/**
|
||||
* get file content
|
||||
* get file content.
|
||||
*
|
||||
* @param path file path
|
||||
* @param charsetName charsetName
|
||||
* @return content
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static String getFileContent(String path, String charsetName)
|
||||
throws IOException {
|
||||
public static String getFileContent(String path, String charsetName) throws IOException {
|
||||
File file = new File(path);
|
||||
return getFileContent(file, charsetName);
|
||||
}
|
||||
|
||||
/**
|
||||
* get file content
|
||||
* get file content.
|
||||
*
|
||||
* @param file file
|
||||
* @param charsetName charsetName
|
||||
* @return content
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static String getFileContent(File file, String charsetName)
|
||||
throws IOException {
|
||||
public static String getFileContent(File file, String charsetName) throws IOException {
|
||||
RandomAccessFile fis = null;
|
||||
FileLock rlock = null;
|
||||
try {
|
||||
@ -70,14 +71,13 @@ public class ConcurrentDiskUtil {
|
||||
++i;
|
||||
if (i > RETRY_COUNT) {
|
||||
NAMING_LOGGER.error("[NA] read " + file.getName() + " fail;retryed time: " + i, e);
|
||||
throw new IOException("read " + file.getAbsolutePath()
|
||||
+ " conflict");
|
||||
throw new IOException("read " + file.getAbsolutePath() + " conflict");
|
||||
}
|
||||
sleep(SLEEP_BASETIME * i);
|
||||
NAMING_LOGGER.warn("read " + file.getName() + " conflict;retry time: " + i);
|
||||
}
|
||||
} while (null == rlock);
|
||||
int fileSize = (int)fcin.size();
|
||||
int fileSize = (int) fcin.size();
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(fileSize);
|
||||
fcin.read(byteBuffer);
|
||||
byteBuffer.flip();
|
||||
@ -95,7 +95,7 @@ public class ConcurrentDiskUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* write file content
|
||||
* write file content.
|
||||
*
|
||||
* @param path file path
|
||||
* @param content content
|
||||
@ -103,14 +103,13 @@ public class ConcurrentDiskUtil {
|
||||
* @return whether write ok
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static Boolean writeFileContent(String path, String content,
|
||||
String charsetName) throws IOException {
|
||||
public static Boolean writeFileContent(String path, String content, String charsetName) throws IOException {
|
||||
File file = new File(path);
|
||||
return writeFileContent(file, content, charsetName);
|
||||
}
|
||||
|
||||
/**
|
||||
* write file content
|
||||
* write file content.
|
||||
*
|
||||
* @param file file
|
||||
* @param content content
|
||||
@ -118,8 +117,7 @@ public class ConcurrentDiskUtil {
|
||||
* @return whether write ok
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static Boolean writeFileContent(File file, String content,
|
||||
String charsetName) throws IOException {
|
||||
public static Boolean writeFileContent(File file, String content, String charsetName) throws IOException {
|
||||
|
||||
if (!file.exists() && !file.createNewFile()) {
|
||||
return false;
|
||||
@ -138,16 +136,14 @@ public class ConcurrentDiskUtil {
|
||||
++i;
|
||||
if (i > RETRY_COUNT) {
|
||||
NAMING_LOGGER.error("[NA] write {} fail;retryed time:{}", file.getName(), i);
|
||||
throw new IOException("write " + file.getAbsolutePath()
|
||||
+ " conflict", e);
|
||||
throw new IOException("write " + file.getAbsolutePath() + " conflict", e);
|
||||
}
|
||||
sleep(SLEEP_BASETIME * i);
|
||||
NAMING_LOGGER.warn("write " + file.getName() + " conflict;retry time: " + i);
|
||||
}
|
||||
} while (null == lock);
|
||||
|
||||
ByteBuffer sendBuffer = ByteBuffer.wrap(content
|
||||
.getBytes(charsetName));
|
||||
ByteBuffer sendBuffer = ByteBuffer.wrap(content.getBytes(charsetName));
|
||||
while (sendBuffer.hasRemaining()) {
|
||||
channel.write(sendBuffer);
|
||||
}
|
||||
@ -185,15 +181,14 @@ public class ConcurrentDiskUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* transfer ByteBuffer to String
|
||||
* transfer ByteBuffer to String.
|
||||
*
|
||||
* @param buffer buffer
|
||||
* @param charsetName charsetName
|
||||
* @return String
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static String byteBufferToString(ByteBuffer buffer,
|
||||
String charsetName) throws IOException {
|
||||
public static String byteBufferToString(ByteBuffer buffer, String charsetName) throws IOException {
|
||||
Charset charset = null;
|
||||
CharsetDecoder decoder = null;
|
||||
CharBuffer charBuffer = null;
|
||||
@ -212,5 +207,6 @@ public class ConcurrentDiskUtil {
|
||||
}
|
||||
|
||||
private static final int RETRY_COUNT = 10;
|
||||
|
||||
private static final int SLEEP_BASETIME = 10;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.cache;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
@ -35,16 +36,23 @@ import java.util.Map;
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Disk cache.
|
||||
*
|
||||
* @author xuanyin
|
||||
*/
|
||||
public class DiskCache {
|
||||
|
||||
/**
|
||||
* Write service info to dir.
|
||||
*
|
||||
* @param dom service info
|
||||
* @param dir directory
|
||||
*/
|
||||
public static void write(ServiceInfo dom, String dir) {
|
||||
|
||||
try {
|
||||
makeSureCacheDirExists(dir);
|
||||
|
||||
|
||||
File file = new File(dir, dom.getKeyEncoded());
|
||||
if (!file.exists()) {
|
||||
// add another !file.exists() to avoid conflicted creating-new-file from multi-instances
|
||||
@ -53,7 +61,7 @@ public class DiskCache {
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder keyContentBuffer = new StringBuilder("");
|
||||
StringBuilder keyContentBuffer = new StringBuilder();
|
||||
|
||||
String json = dom.getJsonFromServer();
|
||||
|
||||
@ -75,6 +83,12 @@ public class DiskCache {
|
||||
return System.getProperty("line.separator");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read service info from disk.
|
||||
*
|
||||
* @param cacheDir cache file dir
|
||||
* @return service infos
|
||||
*/
|
||||
public static Map<String, ServiceInfo> read(String cacheDir) {
|
||||
Map<String, ServiceInfo> domMap = new HashMap<String, ServiceInfo>(16);
|
||||
|
||||
@ -92,8 +106,8 @@ public class DiskCache {
|
||||
|
||||
String fileName = URLDecoder.decode(file.getName(), "UTF-8");
|
||||
|
||||
if (!(fileName.endsWith(Constants.SERVICE_INFO_SPLITER + "meta") || fileName.endsWith(
|
||||
Constants.SERVICE_INFO_SPLITER + "special-url"))) {
|
||||
if (!(fileName.endsWith(Constants.SERVICE_INFO_SPLITER + "meta") || fileName
|
||||
.endsWith(Constants.SERVICE_INFO_SPLITER + "special-url"))) {
|
||||
ServiceInfo dom = new ServiceInfo(fileName);
|
||||
List<Instance> ips = new ArrayList<Instance>();
|
||||
dom.setHosts(ips);
|
||||
@ -101,8 +115,8 @@ public class DiskCache {
|
||||
ServiceInfo newFormat = null;
|
||||
|
||||
try {
|
||||
String dataString = ConcurrentDiskUtil.getFileContent(file,
|
||||
Charset.defaultCharset().toString());
|
||||
String dataString = ConcurrentDiskUtil
|
||||
.getFileContent(file, Charset.defaultCharset().toString());
|
||||
reader = new BufferedReader(new StringReader(dataString));
|
||||
|
||||
String json;
|
||||
@ -132,8 +146,8 @@ public class DiskCache {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
if (newFormat != null && !StringUtils.isEmpty(newFormat.getName()) && !CollectionUtils.isEmpty(
|
||||
newFormat.getHosts())) {
|
||||
if (newFormat != null && !StringUtils.isEmpty(newFormat.getName()) && !CollectionUtils
|
||||
.isEmpty(newFormat.getHosts())) {
|
||||
domMap.put(dom.getKey(), newFormat);
|
||||
} else if (!CollectionUtils.isEmpty(dom.getHosts())) {
|
||||
domMap.put(dom.getKey(), dom);
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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.naming.pojo.Instance;
|
||||
@ -27,12 +28,20 @@ import java.util.List;
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Balancer.
|
||||
*
|
||||
* @author xuanyin
|
||||
*/
|
||||
public class Balancer {
|
||||
|
||||
public static class RandomByWeight {
|
||||
|
||||
/**
|
||||
* Select all instance.
|
||||
*
|
||||
* @param serviceInfo service information
|
||||
* @return all instance of services
|
||||
*/
|
||||
public static List<Instance> selectAll(ServiceInfo serviceInfo) {
|
||||
List<Instance> hosts = serviceInfo.getHosts();
|
||||
|
||||
@ -43,6 +52,12 @@ public class Balancer {
|
||||
return hosts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Random select one instance from service.
|
||||
*
|
||||
* @param dom service
|
||||
* @return random instance
|
||||
*/
|
||||
public static Instance selectHost(ServiceInfo dom) {
|
||||
|
||||
List<Instance> hosts = selectAll(dom);
|
||||
@ -67,11 +82,7 @@ public class Balancer {
|
||||
NAMING_LOGGER.debug("hosts == null || hosts.size() == 0");
|
||||
return null;
|
||||
}
|
||||
|
||||
Chooser<String, Instance> vipChooser = new Chooser<String, Instance>("www.taobao.com");
|
||||
|
||||
NAMING_LOGGER.debug("new Chooser");
|
||||
|
||||
List<Pair<Instance>> hostsWithWeight = new ArrayList<Pair<Instance>>();
|
||||
for (Instance host : hosts) {
|
||||
if (host.isHealthy()) {
|
||||
@ -79,6 +90,7 @@ public class Balancer {
|
||||
}
|
||||
}
|
||||
NAMING_LOGGER.debug("for (Host host : hosts)");
|
||||
Chooser<String, Instance> vipChooser = new Chooser<String, Instance>("www.taobao.com");
|
||||
vipChooser.refresh(hostsWithWeight);
|
||||
NAMING_LOGGER.debug("vipChooser.refresh");
|
||||
return vipChooser.randomWithWeight();
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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;
|
||||
@ -28,21 +29,32 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
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 BlockingQueue<ServiceInfo> changedServices = new LinkedBlockingQueue<ServiceInfo>();
|
||||
private final BlockingQueue<ServiceInfo> changedServices = new LinkedBlockingQueue<ServiceInfo>();
|
||||
|
||||
private ConcurrentMap<String, List<EventListener>> observerMap
|
||||
= new ConcurrentHashMap<String, List<EventListener>>();
|
||||
private final ConcurrentMap<String, List<EventListener>> observerMap = new ConcurrentHashMap<String, List<EventListener>>();
|
||||
|
||||
private volatile boolean closed = false;
|
||||
|
||||
public EventDispatcher() {
|
||||
|
||||
@ -59,6 +71,13 @@ public class EventDispatcher implements Closeable {
|
||||
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");
|
||||
@ -73,6 +92,13 @@ public class EventDispatcher implements Closeable {
|
||||
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");
|
||||
@ -104,6 +130,11 @@ public class EventDispatcher implements Closeable {
|
||||
return serviceInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Service changed.
|
||||
*
|
||||
* @param serviceInfo service info
|
||||
*/
|
||||
public void serviceChanged(ServiceInfo serviceInfo) {
|
||||
if (serviceInfo == null) {
|
||||
return;
|
||||
@ -117,13 +148,16 @@ public class EventDispatcher implements Closeable {
|
||||
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 (true) {
|
||||
while (!closed) {
|
||||
|
||||
ServiceInfo serviceInfo = null;
|
||||
try {
|
||||
serviceInfo = changedServices.poll(5, TimeUnit.MINUTES);
|
||||
@ -140,13 +174,14 @@ public class EventDispatcher implements Closeable {
|
||||
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));
|
||||
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);
|
||||
NAMING_LOGGER.error("[NA] notify error for service: " + serviceInfo.getName() + ", clusters: "
|
||||
+ serviceInfo.getClusters(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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;
|
||||
@ -30,23 +31,24 @@ import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Host reactor.
|
||||
*
|
||||
* @author xuanyin
|
||||
*/
|
||||
public class HostReactor implements Closeable {
|
||||
@ -57,30 +59,31 @@ public class HostReactor implements Closeable {
|
||||
|
||||
private final Map<String, ScheduledFuture<?>> futureMap = new HashMap<String, ScheduledFuture<?>>();
|
||||
|
||||
private Map<String, ServiceInfo> serviceInfoMap;
|
||||
private final Map<String, ServiceInfo> serviceInfoMap;
|
||||
|
||||
private Map<String, Object> updatingMap;
|
||||
private final Map<String, Object> updatingMap;
|
||||
|
||||
private PushReceiver pushReceiver;
|
||||
private final PushReceiver pushReceiver;
|
||||
|
||||
private EventDispatcher eventDispatcher;
|
||||
private final EventDispatcher eventDispatcher;
|
||||
|
||||
private BeatReactor beatReactor;
|
||||
private final BeatReactor beatReactor;
|
||||
|
||||
private NamingProxy serverProxy;
|
||||
private final NamingProxy serverProxy;
|
||||
|
||||
private FailoverReactor failoverReactor;
|
||||
private final FailoverReactor failoverReactor;
|
||||
|
||||
private String cacheDir;
|
||||
private final String cacheDir;
|
||||
|
||||
private ScheduledExecutorService executor;
|
||||
private final ScheduledExecutorService executor;
|
||||
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, BeatReactor beatReactor, String cacheDir) {
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, BeatReactor beatReactor,
|
||||
String cacheDir) {
|
||||
this(eventDispatcher, serverProxy, beatReactor, cacheDir, false, UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
|
||||
}
|
||||
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, BeatReactor beatReactor, String cacheDir,
|
||||
boolean loadCacheAtStart, int pollingThreadCount) {
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, BeatReactor beatReactor,
|
||||
String cacheDir, boolean loadCacheAtStart, int pollingThreadCount) {
|
||||
// init executorService
|
||||
this.executor = new ScheduledThreadPoolExecutor(pollingThreadCount, new ThreadFactory() {
|
||||
@Override
|
||||
@ -114,7 +117,13 @@ public class HostReactor implements Closeable {
|
||||
return executor.schedule(task, DEFAULT_DELAY, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public ServiceInfo processServiceJSON(String json) {
|
||||
/**
|
||||
* Process service json.
|
||||
*
|
||||
* @param json service json
|
||||
* @return service info
|
||||
*/
|
||||
public ServiceInfo processServiceJson(String json) {
|
||||
ServiceInfo serviceInfo = JacksonUtils.toObj(json, ServiceInfo.class);
|
||||
ServiceInfo oldService = serviceInfoMap.get(serviceInfo.getKey());
|
||||
if (serviceInfo.getHosts() == null || !serviceInfo.validate()) {
|
||||
@ -127,8 +136,8 @@ public class HostReactor implements Closeable {
|
||||
if (oldService != null) {
|
||||
|
||||
if (oldService.getLastRefTime() > serviceInfo.getLastRefTime()) {
|
||||
NAMING_LOGGER.warn("out of date data received, old-t: " + oldService.getLastRefTime()
|
||||
+ ", new-t: " + serviceInfo.getLastRefTime());
|
||||
NAMING_LOGGER.warn("out of date data received, old-t: " + oldService.getLastRefTime() + ", new-t: "
|
||||
+ serviceInfo.getLastRefTime());
|
||||
}
|
||||
|
||||
serviceInfoMap.put(serviceInfo.getKey(), serviceInfo);
|
||||
@ -152,8 +161,8 @@ public class HostReactor implements Closeable {
|
||||
for (Map.Entry<String, Instance> entry : newServiceHosts) {
|
||||
Instance host = entry.getValue();
|
||||
String key = entry.getKey();
|
||||
if (oldHostMap.containsKey(key) && !StringUtils.equals(host.toString(),
|
||||
oldHostMap.get(key).toString())) {
|
||||
if (oldHostMap.containsKey(key) && !StringUtils
|
||||
.equals(host.toString(), oldHostMap.get(key).toString())) {
|
||||
modHosts.add(host);
|
||||
continue;
|
||||
}
|
||||
@ -178,21 +187,21 @@ public class HostReactor implements Closeable {
|
||||
|
||||
if (newHosts.size() > 0) {
|
||||
changed = true;
|
||||
NAMING_LOGGER.info("new ips(" + newHosts.size() + ") service: "
|
||||
+ serviceInfo.getKey() + " -> " + JacksonUtils.toJson(newHosts));
|
||||
NAMING_LOGGER.info("new ips(" + newHosts.size() + ") service: " + serviceInfo.getKey() + " -> "
|
||||
+ JacksonUtils.toJson(newHosts));
|
||||
}
|
||||
|
||||
if (remvHosts.size() > 0) {
|
||||
changed = true;
|
||||
NAMING_LOGGER.info("removed ips(" + remvHosts.size() + ") service: "
|
||||
+ serviceInfo.getKey() + " -> " + JacksonUtils.toJson(remvHosts));
|
||||
NAMING_LOGGER.info("removed ips(" + remvHosts.size() + ") service: " + serviceInfo.getKey() + " -> "
|
||||
+ JacksonUtils.toJson(remvHosts));
|
||||
}
|
||||
|
||||
if (modHosts.size() > 0) {
|
||||
changed = true;
|
||||
updateBeatInfo(modHosts);
|
||||
NAMING_LOGGER.info("modified ips(" + modHosts.size() + ") service: "
|
||||
+ serviceInfo.getKey() + " -> " + JacksonUtils.toJson(modHosts));
|
||||
NAMING_LOGGER.info("modified ips(" + modHosts.size() + ") service: " + serviceInfo.getKey() + " -> "
|
||||
+ JacksonUtils.toJson(modHosts));
|
||||
}
|
||||
|
||||
serviceInfo.setJsonFromServer(json);
|
||||
@ -204,8 +213,8 @@ public class HostReactor implements Closeable {
|
||||
|
||||
} else {
|
||||
changed = true;
|
||||
NAMING_LOGGER.info("init new ips(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() + " -> " +
|
||||
JacksonUtils.toJson(serviceInfo.getHosts()));
|
||||
NAMING_LOGGER.info("init new ips(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() + " -> "
|
||||
+ JacksonUtils.toJson(serviceInfo.getHosts()));
|
||||
serviceInfoMap.put(serviceInfo.getKey(), serviceInfo);
|
||||
eventDispatcher.serviceChanged(serviceInfo);
|
||||
serviceInfo.setJsonFromServer(json);
|
||||
@ -215,8 +224,8 @@ public class HostReactor implements Closeable {
|
||||
MetricsMonitor.getServiceInfoMapSizeMonitor().set(serviceInfoMap.size());
|
||||
|
||||
if (changed) {
|
||||
NAMING_LOGGER.info("current ips:(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() +
|
||||
" -> " + JacksonUtils.toJson(serviceInfo.getHosts()));
|
||||
NAMING_LOGGER.info("current ips:(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() + " -> "
|
||||
+ JacksonUtils.toJson(serviceInfo.getHosts()));
|
||||
}
|
||||
|
||||
return serviceInfo;
|
||||
@ -239,7 +248,8 @@ public class HostReactor implements Closeable {
|
||||
return serviceInfoMap.get(key);
|
||||
}
|
||||
|
||||
public ServiceInfo getServiceInfoDirectlyFromServer(final String serviceName, final String clusters) throws NacosException {
|
||||
public ServiceInfo getServiceInfoDirectlyFromServer(final String serviceName, final String clusters)
|
||||
throws NacosException {
|
||||
String result = serverProxy.queryList(serviceName, clusters, 0, false);
|
||||
if (StringUtils.isNotEmpty(result)) {
|
||||
return JacksonUtils.toObj(result, ServiceInfo.class);
|
||||
@ -274,7 +284,8 @@ public class HostReactor implements Closeable {
|
||||
try {
|
||||
serviceObj.wait(UPDATE_HOLD_INTERVAL);
|
||||
} catch (InterruptedException e) {
|
||||
NAMING_LOGGER.error("[getServiceInfo] serviceName:" + serviceName + ", clusters:" + clusters, e);
|
||||
NAMING_LOGGER
|
||||
.error("[getServiceInfo] serviceName:" + serviceName + ", clusters:" + clusters, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -285,7 +296,12 @@ public class HostReactor implements Closeable {
|
||||
return serviceInfoMap.get(serviceObj.getKey());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Schedule update if absent.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param clusters clusters
|
||||
*/
|
||||
public void scheduleUpdateIfAbsent(String serviceName, String clusters) {
|
||||
if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) != null) {
|
||||
return;
|
||||
@ -301,14 +317,20 @@ public class HostReactor implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update service now.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param clusters clusters
|
||||
*/
|
||||
public void updateServiceNow(String serviceName, String clusters) {
|
||||
ServiceInfo oldService = getServiceInfo0(serviceName, clusters);
|
||||
try {
|
||||
|
||||
String result = serverProxy.queryList(serviceName, clusters, pushReceiver.getUDPPort(), false);
|
||||
String result = serverProxy.queryList(serviceName, clusters, pushReceiver.getUdpPort(), false);
|
||||
|
||||
if (StringUtils.isNotEmpty(result)) {
|
||||
processServiceJSON(result);
|
||||
processServiceJson(result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NAMING_LOGGER.error("[NA] failed to update serviceName: " + serviceName, e);
|
||||
@ -321,9 +343,15 @@ public class HostReactor implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh only.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param clusters cluster
|
||||
*/
|
||||
public void refreshOnly(String serviceName, String clusters) {
|
||||
try {
|
||||
serverProxy.queryList(serviceName, clusters, pushReceiver.getUDPPort(), false);
|
||||
serverProxy.queryList(serviceName, clusters, pushReceiver.getUdpPort(), false);
|
||||
} catch (Exception e) {
|
||||
NAMING_LOGGER.error("[NA] failed to update serviceName: " + serviceName, e);
|
||||
}
|
||||
@ -334,13 +362,18 @@ public class HostReactor implements Closeable {
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executor, NAMING_LOGGER);
|
||||
pushReceiver.shutdown();
|
||||
failoverReactor.shutdown();
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
public class UpdateTask implements Runnable {
|
||||
|
||||
long lastRefTime = Long.MAX_VALUE;
|
||||
private String clusters;
|
||||
private String serviceName;
|
||||
|
||||
private final String clusters;
|
||||
|
||||
private final String serviceName;
|
||||
|
||||
public UpdateTask(String serviceName, String clusters) {
|
||||
this.serviceName = serviceName;
|
||||
@ -371,16 +404,15 @@ public class HostReactor implements Closeable {
|
||||
|
||||
lastRefTime = serviceObj.getLastRefTime();
|
||||
|
||||
if (!eventDispatcher.isSubscribed(serviceName, clusters) &&
|
||||
!futureMap.containsKey(ServiceInfo.getKey(serviceName, clusters))) {
|
||||
// abort the update task:
|
||||
if (!eventDispatcher.isSubscribed(serviceName, clusters) && !futureMap
|
||||
.containsKey(ServiceInfo.getKey(serviceName, clusters))) {
|
||||
// abort the update task
|
||||
NAMING_LOGGER.info("update task is stopped, service:" + serviceName + ", clusters:" + clusters);
|
||||
return;
|
||||
}
|
||||
|
||||
delayTime = serviceObj.getCacheMillis();
|
||||
|
||||
|
||||
} catch (Throwable e) {
|
||||
NAMING_LOGGER.warn("[NA] failed to update serviceName: " + serviceName, e);
|
||||
} finally {
|
||||
|
@ -13,9 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.core;
|
||||
|
||||
/**
|
||||
* Protect mode.
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
public class ProtectMode {
|
||||
|
@ -13,18 +13,19 @@
|
||||
* 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.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
@ -32,6 +33,8 @@ import java.util.concurrent.ThreadFactory;
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Push receiver.
|
||||
*
|
||||
* @author xuanyin
|
||||
*/
|
||||
public class PushReceiver implements Runnable, Closeable {
|
||||
@ -44,11 +47,12 @@ public class PushReceiver implements Runnable, Closeable {
|
||||
|
||||
private HostReactor hostReactor;
|
||||
|
||||
private volatile boolean closed = false;
|
||||
|
||||
public PushReceiver(HostReactor hostReactor) {
|
||||
try {
|
||||
this.hostReactor = hostReactor;
|
||||
this.udpSocket = new DatagramSocket();
|
||||
|
||||
this.executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
@ -67,42 +71,39 @@ public class PushReceiver implements Runnable, Closeable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
while (!closed) {
|
||||
try {
|
||||
|
||||
// byte[] is initialized with 0 full filled by default
|
||||
byte[] buffer = new byte[UDP_MSS];
|
||||
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
|
||||
|
||||
udpSocket.receive(packet);
|
||||
|
||||
String json = new String(IoUtils.tryDecompress(packet.getData()), "UTF-8").trim();
|
||||
String json = new String(IoUtils.tryDecompress(packet.getData()), StandardCharsets.UTF_8).trim();
|
||||
NAMING_LOGGER.info("received push data: " + json + " from " + packet.getAddress().toString());
|
||||
|
||||
PushPacket pushPacket = JacksonUtils.toObj(json, PushPacket.class);
|
||||
String ack;
|
||||
if ("dom".equals(pushPacket.type) || "service".equals(pushPacket.type)) {
|
||||
hostReactor.processServiceJSON(pushPacket.data);
|
||||
hostReactor.processServiceJson(pushPacket.data);
|
||||
|
||||
// send ack to server
|
||||
ack = "{\"type\": \"push-ack\""
|
||||
+ ", \"lastRefTime\":\"" + pushPacket.lastRefTime
|
||||
+ "\", \"data\":" + "\"\"}";
|
||||
ack = "{\"type\": \"push-ack\"" + ", \"lastRefTime\":\"" + pushPacket.lastRefTime + "\", \"data\":"
|
||||
+ "\"\"}";
|
||||
} else if ("dump".equals(pushPacket.type)) {
|
||||
// dump data to server
|
||||
ack = "{\"type\": \"dump-ack\""
|
||||
+ ", \"lastRefTime\": \"" + pushPacket.lastRefTime
|
||||
+ "\", \"data\":" + "\""
|
||||
+ StringUtils.escapeJavaScript(JacksonUtils.toJson(hostReactor.getServiceInfoMap()))
|
||||
ack = "{\"type\": \"dump-ack\"" + ", \"lastRefTime\": \"" + pushPacket.lastRefTime + "\", \"data\":"
|
||||
+ "\"" + StringUtils.escapeJavaScript(JacksonUtils.toJson(hostReactor.getServiceInfoMap()))
|
||||
+ "\"}";
|
||||
} else {
|
||||
// do nothing send ack only
|
||||
ack = "{\"type\": \"unknown-ack\""
|
||||
+ ", \"lastRefTime\":\"" + pushPacket.lastRefTime
|
||||
ack = "{\"type\": \"unknown-ack\"" + ", \"lastRefTime\":\"" + pushPacket.lastRefTime
|
||||
+ "\", \"data\":" + "\"\"}";
|
||||
}
|
||||
|
||||
udpSocket.send(new DatagramPacket(ack.getBytes(Charset.forName("UTF-8")),
|
||||
ack.getBytes(Charset.forName("UTF-8")).length, packet.getSocketAddress()));
|
||||
udpSocket.send(new DatagramPacket(ack.getBytes(StandardCharsets.UTF_8),
|
||||
ack.getBytes(StandardCharsets.UTF_8).length, packet.getSocketAddress()));
|
||||
} catch (Exception e) {
|
||||
NAMING_LOGGER.error("[NA] error while receiving push data", e);
|
||||
}
|
||||
@ -114,16 +115,21 @@ public class PushReceiver implements Runnable, Closeable {
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
||||
closed = true;
|
||||
udpSocket.close();
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
public static class PushPacket {
|
||||
|
||||
public String type;
|
||||
|
||||
public long lastRefTime;
|
||||
|
||||
public String data;
|
||||
}
|
||||
|
||||
public int getUDPPort() {
|
||||
public int getUdpPort() {
|
||||
return this.udpSocket.getLocalPort();
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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;
|
||||
@ -29,12 +30,18 @@ import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
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
|
||||
*/
|
||||
@ -43,10 +50,10 @@ 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("com.alibaba.nacos.client.naming.tls.enable");
|
||||
|
||||
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("com.alibaba.nacos.client.naming.tls.enable");
|
||||
|
||||
static {
|
||||
// limit max redirection
|
||||
@ -62,11 +69,24 @@ public class HttpClient {
|
||||
|
||||
}
|
||||
|
||||
public static HttpResult httpGet(String url, List<String> headers, Map<String, String> paramValues, String encoding) {
|
||||
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);
|
||||
}
|
||||
|
||||
public static HttpResult request(String url, List<String> headers, Map<String, String> paramValues, String body, String encoding, String method) {
|
||||
/**
|
||||
* 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);
|
||||
@ -94,11 +114,11 @@ public class HttpClient {
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
if (conn != null) {
|
||||
NAMING_LOGGER.warn("failed to request " + conn.getURL() + " from "
|
||||
+ InetAddress.getByName(conn.getURL().getHost()).getHostAddress());
|
||||
NAMING_LOGGER.warn("failed to request " + conn.getURL() + " from " + InetAddress
|
||||
.getByName(conn.getURL().getHost()).getHostAddress());
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
NAMING_LOGGER.error("[NA] failed to request ", e1);
|
||||
} catch (Exception ex) {
|
||||
NAMING_LOGGER.error("[NA] failed to request ", ex);
|
||||
//ignore
|
||||
}
|
||||
|
||||
@ -114,8 +134,7 @@ public class HttpClient {
|
||||
int respCode = conn.getResponseCode();
|
||||
|
||||
InputStream inputStream;
|
||||
if (HttpURLConnection.HTTP_OK == respCode
|
||||
|| HttpURLConnection.HTTP_NOT_MODIFIED == respCode
|
||||
if (HttpURLConnection.HTTP_OK == respCode || HttpURLConnection.HTTP_NOT_MODIFIED == respCode
|
||||
|| Constants.WRITE_REDIRECT_CODE == respCode) {
|
||||
inputStream = conn.getInputStream();
|
||||
} else {
|
||||
@ -172,8 +191,7 @@ public class HttpClient {
|
||||
}
|
||||
}
|
||||
|
||||
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset="
|
||||
+ encoding);
|
||||
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding);
|
||||
conn.addRequestProperty("Accept-Charset", encoding);
|
||||
}
|
||||
|
||||
@ -203,9 +221,12 @@ public class HttpClient {
|
||||
}
|
||||
|
||||
public static class HttpResult {
|
||||
final public int code;
|
||||
final public String content;
|
||||
final private Map<String, String> respHeaders;
|
||||
|
||||
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;
|
||||
@ -219,8 +240,8 @@ public class HttpClient {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HttpResult{" + "code=" + code + ", content='" + content + '\''
|
||||
+ ", respHeaders=" + respHeaders + '}';
|
||||
return "HttpResult{" + "code=" + code + ", content='" + content + '\'' + ", respHeaders=" + respHeaders
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,48 +16,79 @@
|
||||
|
||||
package com.alibaba.nacos.client.naming.net;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.http.AbstractHttpClientFactory;
|
||||
import com.alibaba.nacos.common.http.HttpClientBeanHolder;
|
||||
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||
import com.alibaba.nacos.common.http.HttpClientFactory;
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* http Manager
|
||||
* http Manager.
|
||||
*
|
||||
* @author mai.jh
|
||||
*/
|
||||
public class NamingHttpClientManager {
|
||||
public class NamingHttpClientManager implements Closeable {
|
||||
|
||||
private static final int READ_TIME_OUT_MILLIS = Integer
|
||||
.getInteger("com.alibaba.nacos.client.naming.rtimeout", 50000);
|
||||
private static final int CON_TIME_OUT_MILLIS = Integer
|
||||
.getInteger("com.alibaba.nacos.client.naming.ctimeout", 3000);
|
||||
private static final boolean ENABLE_HTTPS = Boolean
|
||||
.getBoolean("com.alibaba.nacos.client.naming.tls.enable");
|
||||
|
||||
private static final int CON_TIME_OUT_MILLIS = Integer.getInteger("com.alibaba.nacos.client.naming.ctimeout", 3000);
|
||||
|
||||
private static final boolean ENABLE_HTTPS = Boolean.getBoolean("com.alibaba.nacos.client.naming.tls.enable");
|
||||
|
||||
private static final int MAX_REDIRECTS = 5;
|
||||
|
||||
private static final HttpClientFactory HTTP_CLIENT_FACTORY = new NamingHttpClientFactory();
|
||||
|
||||
public static String getPrefix() {
|
||||
private static class NamingHttpClientManagerInstance {
|
||||
|
||||
private static final NamingHttpClientManager INSTANCE = new NamingHttpClientManager();
|
||||
}
|
||||
|
||||
public static NamingHttpClientManager getInstance() {
|
||||
return NamingHttpClientManagerInstance.INSTANCE;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
if (ENABLE_HTTPS) {
|
||||
return "https://";
|
||||
}
|
||||
return "http://";
|
||||
}
|
||||
|
||||
public static NacosRestTemplate getNacosRestTemplate() {
|
||||
public NacosRestTemplate getNacosRestTemplate() {
|
||||
return HttpClientBeanHolder.getNacosRestTemplate(HTTP_CLIENT_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
NAMING_LOGGER.warn("[NamingHttpClientManager] Start destroying NacosRestTemplate");
|
||||
try {
|
||||
HttpClientBeanHolder.shutdownNacostSyncRest(HTTP_CLIENT_FACTORY.getClass().getName());
|
||||
} catch (Exception ex) {
|
||||
NAMING_LOGGER.error("[NamingHttpClientManager] An exception occurred when the HTTP client was closed : {}",
|
||||
ExceptionUtil.getStackTrace(ex));
|
||||
}
|
||||
NAMING_LOGGER.warn("[NamingHttpClientManager] Destruction of the end");
|
||||
}
|
||||
|
||||
private static class NamingHttpClientFactory extends AbstractHttpClientFactory {
|
||||
|
||||
@Override
|
||||
protected HttpClientConfig buildHttpClientConfig() {
|
||||
return HttpClientConfig.builder()
|
||||
.setConTimeOutMillis(CON_TIME_OUT_MILLIS)
|
||||
.setReadTimeOutMillis(READ_TIME_OUT_MILLIS)
|
||||
.setMaxRedirects(MAX_REDIRECTS).build();
|
||||
return HttpClientConfig.builder().setConTimeOutMillis(CON_TIME_OUT_MILLIS)
|
||||
.setReadTimeOutMillis(READ_TIME_OUT_MILLIS).setMaxRedirects(MAX_REDIRECTS).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Logger assignLogger() {
|
||||
return NAMING_LOGGER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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.PropertyKeyConst;
|
||||
@ -42,45 +43,51 @@ 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.*;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||
import com.alibaba.nacos.common.utils.VersionUtils;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* Naming proxy.
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
public class NamingProxy implements Closeable {
|
||||
|
||||
private NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getNacosRestTemplate();
|
||||
private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getInstance().getNacosRestTemplate();
|
||||
|
||||
private static final int DEFAULT_SERVER_PORT = 8848;
|
||||
|
||||
private int serverPort = DEFAULT_SERVER_PORT;
|
||||
|
||||
private String namespaceId;
|
||||
private final String namespaceId;
|
||||
|
||||
private String endpoint;
|
||||
private final String endpoint;
|
||||
|
||||
private String nacosDomain;
|
||||
|
||||
@ -88,13 +95,13 @@ public class NamingProxy implements Closeable {
|
||||
|
||||
private List<String> serversFromEndpoint = new ArrayList<String>();
|
||||
|
||||
private SecurityProxy securityProxy;
|
||||
private final SecurityProxy securityProxy;
|
||||
|
||||
private long lastSrvRefTime = 0L;
|
||||
|
||||
private long vipSrvRefInterMillis = TimeUnit.SECONDS.toMillis(30);
|
||||
private final long vipSrvRefInterMillis = TimeUnit.SECONDS.toMillis(30);
|
||||
|
||||
private long securityInfoRefreshIntervalMills = TimeUnit.SECONDS.toMillis(5);
|
||||
private final long securityInfoRefreshIntervalMills = TimeUnit.SECONDS.toMillis(5);
|
||||
|
||||
private Properties properties;
|
||||
|
||||
@ -135,7 +142,6 @@ public class NamingProxy implements Closeable {
|
||||
}
|
||||
}, 0, vipSrvRefInterMillis, TimeUnit.MILLISECONDS);
|
||||
|
||||
|
||||
this.executorService.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -154,8 +160,8 @@ public class NamingProxy implements Closeable {
|
||||
Header header = builderHeader();
|
||||
HttpRestResult<String> restResult = nacosRestTemplate.get(urlString, header, Query.EMPTY, String.class);
|
||||
if (!restResult.ok()) {
|
||||
throw new IOException("Error while requesting: " + urlString + "'. Server returned: "
|
||||
+ restResult.getCode());
|
||||
throw new IOException(
|
||||
"Error while requesting: " + urlString + "'. Server returned: " + restResult.getCode());
|
||||
}
|
||||
|
||||
String content = restResult.getData();
|
||||
@ -204,10 +210,18 @@ public class NamingProxy implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* register a instance to service with specified instance properties.
|
||||
*
|
||||
* @param serviceName name of service
|
||||
* @param groupName group of service
|
||||
* @param instance instance to register
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
|
||||
NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}",
|
||||
namespaceId, serviceName, instance);
|
||||
NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}", namespaceId, serviceName,
|
||||
instance);
|
||||
|
||||
final Map<String, String> params = new HashMap<String, String>(16);
|
||||
params.put(CommonParams.NAMESPACE_ID, namespaceId);
|
||||
@ -222,14 +236,22 @@ public class NamingProxy implements Closeable {
|
||||
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
|
||||
params.put("metadata", JacksonUtils.toJson(instance.getMetadata()));
|
||||
|
||||
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.POST);
|
||||
reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.POST);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* deregister instance from a service.
|
||||
*
|
||||
* @param serviceName name of service
|
||||
* @param instance instance
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public void deregisterService(String serviceName, Instance instance) throws NacosException {
|
||||
|
||||
NAMING_LOGGER.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}",
|
||||
namespaceId, serviceName, instance);
|
||||
NAMING_LOGGER
|
||||
.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}", namespaceId, serviceName,
|
||||
instance);
|
||||
|
||||
final Map<String, String> params = new HashMap<String, String>(8);
|
||||
params.put(CommonParams.NAMESPACE_ID, namespaceId);
|
||||
@ -239,12 +261,20 @@ public class NamingProxy implements Closeable {
|
||||
params.put("port", String.valueOf(instance.getPort()));
|
||||
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
|
||||
|
||||
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.DELETE);
|
||||
reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.DELETE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update instance to service.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param groupName group name
|
||||
* @param instance instance
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public void updateInstance(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
NAMING_LOGGER.info("[UPDATE-SERVICE] {} update service {} with instance: {}",
|
||||
namespaceId, serviceName, instance);
|
||||
NAMING_LOGGER
|
||||
.info("[UPDATE-SERVICE] {} update service {} with instance: {}", namespaceId, serviceName, instance);
|
||||
|
||||
final Map<String, String> params = new HashMap<String, String>(8);
|
||||
params.put(CommonParams.NAMESPACE_ID, namespaceId);
|
||||
@ -258,26 +288,39 @@ public class NamingProxy implements Closeable {
|
||||
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
|
||||
params.put("metadata", JacksonUtils.toJson(instance.getMetadata()));
|
||||
|
||||
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.PUT);
|
||||
reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.PUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query Service.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param groupName group name
|
||||
* @return service
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public Service queryService(String serviceName, String groupName) throws NacosException {
|
||||
NAMING_LOGGER.info("[QUERY-SERVICE] {} query service : {}, {}",
|
||||
namespaceId, serviceName, groupName);
|
||||
NAMING_LOGGER.info("[QUERY-SERVICE] {} query service : {}, {}", namespaceId, serviceName, groupName);
|
||||
|
||||
final Map<String, String> params = new HashMap<String, String>(3);
|
||||
params.put(CommonParams.NAMESPACE_ID, namespaceId);
|
||||
params.put(CommonParams.SERVICE_NAME, serviceName);
|
||||
params.put(CommonParams.GROUP_NAME, groupName);
|
||||
|
||||
String result = reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.GET);
|
||||
String result = reqApi(UtilAndComs.nacosUrlService, params, HttpMethod.GET);
|
||||
return JacksonUtils.toObj(result, Service.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create service.
|
||||
*
|
||||
* @param service service
|
||||
* @param selector selector
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public void createService(Service service, AbstractSelector selector) throws NacosException {
|
||||
|
||||
NAMING_LOGGER.info("[CREATE-SERVICE] {} creating service : {}",
|
||||
namespaceId, service);
|
||||
NAMING_LOGGER.info("[CREATE-SERVICE] {} creating service : {}", namespaceId, service);
|
||||
|
||||
final Map<String, String> params = new HashMap<String, String>(6);
|
||||
params.put(CommonParams.NAMESPACE_ID, namespaceId);
|
||||
@ -287,26 +330,40 @@ public class NamingProxy implements Closeable {
|
||||
params.put("metadata", JacksonUtils.toJson(service.getMetadata()));
|
||||
params.put("selector", JacksonUtils.toJson(selector));
|
||||
|
||||
reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.POST);
|
||||
reqApi(UtilAndComs.nacosUrlService, params, HttpMethod.POST);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete service.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param groupName group name
|
||||
* @return true if delete ok
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public boolean deleteService(String serviceName, String groupName) throws NacosException {
|
||||
NAMING_LOGGER.info("[DELETE-SERVICE] {} deleting service : {} with groupName : {}",
|
||||
namespaceId, serviceName, groupName);
|
||||
NAMING_LOGGER.info("[DELETE-SERVICE] {} deleting service : {} with groupName : {}", namespaceId, serviceName,
|
||||
groupName);
|
||||
|
||||
final Map<String, String> params = new HashMap<String, String>(6);
|
||||
params.put(CommonParams.NAMESPACE_ID, namespaceId);
|
||||
params.put(CommonParams.SERVICE_NAME, serviceName);
|
||||
params.put(CommonParams.GROUP_NAME, groupName);
|
||||
|
||||
String result = reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.DELETE);
|
||||
String result = reqApi(UtilAndComs.nacosUrlService, params, HttpMethod.DELETE);
|
||||
return "ok".equals(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update service.
|
||||
*
|
||||
* @param service service
|
||||
* @param selector selector
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public void updateService(Service service, AbstractSelector selector) throws NacosException {
|
||||
NAMING_LOGGER.info("[UPDATE-SERVICE] {} updating service : {}",
|
||||
namespaceId, service);
|
||||
NAMING_LOGGER.info("[UPDATE-SERVICE] {} updating service : {}", namespaceId, service);
|
||||
|
||||
final Map<String, String> params = new HashMap<String, String>(6);
|
||||
params.put(CommonParams.NAMESPACE_ID, namespaceId);
|
||||
@ -316,9 +373,19 @@ public class NamingProxy implements Closeable {
|
||||
params.put("metadata", JacksonUtils.toJson(service.getMetadata()));
|
||||
params.put("selector", JacksonUtils.toJson(selector));
|
||||
|
||||
reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.PUT);
|
||||
reqApi(UtilAndComs.nacosUrlService, params, HttpMethod.PUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query instance list.
|
||||
*
|
||||
* @param serviceName service name
|
||||
* @param clusters clusters
|
||||
* @param udpPort udp port
|
||||
* @param healthyOnly healthy only
|
||||
* @return instance list
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public String queryList(String serviceName, String clusters, int udpPort, boolean healthyOnly)
|
||||
throws NacosException {
|
||||
|
||||
@ -330,9 +397,17 @@ public class NamingProxy implements Closeable {
|
||||
params.put("clientIP", NetUtils.localIP());
|
||||
params.put("healthyOnly", String.valueOf(healthyOnly));
|
||||
|
||||
return reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/list", params, HttpMethod.GET);
|
||||
return reqApi(UtilAndComs.nacosUrlBase + "/instance/list", params, HttpMethod.GET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send beat.
|
||||
*
|
||||
* @param beatInfo beat info
|
||||
* @param lightBeatEnabled light beat
|
||||
* @return beat result
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public JsonNode sendBeat(BeatInfo beatInfo, boolean lightBeatEnabled) throws NacosException {
|
||||
|
||||
if (NAMING_LOGGER.isDebugEnabled()) {
|
||||
@ -341,26 +416,27 @@ public class NamingProxy implements Closeable {
|
||||
Map<String, String> params = new HashMap<String, String>(8);
|
||||
Map<String, String> bodyMap = new HashMap<String, String>(2);
|
||||
if (!lightBeatEnabled) {
|
||||
try {
|
||||
bodyMap.put("beat", URLEncoder.encode(JacksonUtils.toJson(beatInfo), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new NacosException(NacosException.SERVER_ERROR, "encode beatInfo error", e);
|
||||
}
|
||||
bodyMap.put("beat", JacksonUtils.toJson(beatInfo));
|
||||
}
|
||||
params.put(CommonParams.NAMESPACE_ID, namespaceId);
|
||||
params.put(CommonParams.SERVICE_NAME, beatInfo.getServiceName());
|
||||
params.put(CommonParams.CLUSTER_NAME, beatInfo.getCluster());
|
||||
params.put("ip", beatInfo.getIp());
|
||||
params.put("port", String.valueOf(beatInfo.getPort()));
|
||||
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/beat", params, bodyMap, HttpMethod.PUT);
|
||||
String result = reqApi(UtilAndComs.nacosUrlBase + "/instance/beat", params, bodyMap, HttpMethod.PUT);
|
||||
return JacksonUtils.toObj(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Server healthy.
|
||||
*
|
||||
* @return true if server is healthy
|
||||
*/
|
||||
public boolean serverHealthy() {
|
||||
|
||||
try {
|
||||
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/operator/metrics",
|
||||
new HashMap<String, String>(2), HttpMethod.GET);
|
||||
String result = reqApi(UtilAndComs.nacosUrlBase + "/operator/metrics", new HashMap<String, String>(2),
|
||||
HttpMethod.GET);
|
||||
JsonNode json = JacksonUtils.toObj(result);
|
||||
String serverStatus = json.get("status").asText();
|
||||
return "UP".equals(serverStatus);
|
||||
@ -373,7 +449,8 @@ public class NamingProxy implements Closeable {
|
||||
return getServiceList(pageNo, pageSize, groupName, null);
|
||||
}
|
||||
|
||||
public ListView<String> getServiceList(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException {
|
||||
public ListView<String> getServiceList(int pageNo, int pageSize, String groupName, AbstractSelector selector)
|
||||
throws NacosException {
|
||||
|
||||
Map<String, String> params = new HashMap<String, String>(4);
|
||||
params.put("pageNo", String.valueOf(pageNo));
|
||||
@ -394,74 +471,39 @@ public class NamingProxy implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/service/list", params, HttpMethod.GET);
|
||||
String result = reqApi(UtilAndComs.nacosUrlBase + "/service/list", params, HttpMethod.GET);
|
||||
|
||||
JsonNode json = JacksonUtils.toObj(result);
|
||||
ListView<String> listView = new ListView<>();
|
||||
ListView<String> listView = new ListView<String>();
|
||||
listView.setCount(json.get("count").asInt());
|
||||
listView.setData(JacksonUtils.toObj(json.get("doms").toString(), new TypeReference<List<String>>() {}));
|
||||
listView.setData(JacksonUtils.toObj(json.get("doms").toString(), new TypeReference<List<String>>() {
|
||||
}));
|
||||
|
||||
return listView;
|
||||
}
|
||||
|
||||
public String reqAPI(String api, Map<String, String> params, String method) throws NacosException {
|
||||
return reqAPI(api, params, Collections.EMPTY_MAP, method);
|
||||
public String reqApi(String api, Map<String, String> params, String method) throws NacosException {
|
||||
return reqApi(api, params, Collections.EMPTY_MAP, method);
|
||||
}
|
||||
|
||||
public String reqAPI(String api, Map<String, String> params, Map<String, String> body, String method) throws NacosException {
|
||||
return reqAPI(api, params, body, getServerList(), method);
|
||||
}
|
||||
|
||||
private List<String> getServerList() {
|
||||
List<String> snapshot = serversFromEndpoint;
|
||||
if (!CollectionUtils.isEmpty(serverList)) {
|
||||
snapshot = serverList;
|
||||
}
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
public String callServer(String api, Map<String, String> params, Map<String, String> body, String curServer) throws NacosException {
|
||||
return callServer(api, params, body, curServer, HttpMethod.GET);
|
||||
}
|
||||
|
||||
public String callServer(String api, Map<String, String> params, Map<String, String> body, String curServer, String method)
|
||||
public String reqApi(String api, Map<String, String> params, Map<String, String> body, String method)
|
||||
throws NacosException {
|
||||
long start = System.currentTimeMillis();
|
||||
long end = 0;
|
||||
injectSecurityInfo(params);
|
||||
Header header = builderHeader();
|
||||
|
||||
String url;
|
||||
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;
|
||||
}
|
||||
url = NamingHttpClientManager.getPrefix() + curServer + api;
|
||||
return reqApi(api, params, body, getServerList(), method);
|
||||
}
|
||||
|
||||
try {
|
||||
HttpRestResult<String> restResult = nacosRestTemplate.exchangeForm(url, header, params, body, method, String.class);
|
||||
end = System.currentTimeMillis();
|
||||
|
||||
MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(restResult.getCode()))
|
||||
.observe(end - start);
|
||||
|
||||
if (restResult.ok()) {
|
||||
return restResult.getData();
|
||||
}
|
||||
if (HttpStatus.SC_NOT_MODIFIED == restResult.getCode()) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
throw new NacosException(restResult.getCode(), restResult.getData());
|
||||
} catch (Exception e) {
|
||||
NAMING_LOGGER.error("[NA] failed to request", e);
|
||||
throw new NacosException(NacosException.SERVER_ERROR, e);
|
||||
}
|
||||
}
|
||||
|
||||
public String reqAPI(String api, Map<String, String> params, Map<String, String> body, List<String> servers, String method) throws NacosException {
|
||||
/**
|
||||
* Request api.
|
||||
*
|
||||
* @param api api
|
||||
* @param params parameters
|
||||
* @param body body
|
||||
* @param servers servers
|
||||
* @param method http method
|
||||
* @return result
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public String reqApi(String api, Map<String, String> params, Map<String, String> body, List<String> servers,
|
||||
String method) throws NacosException {
|
||||
|
||||
params.put(CommonParams.NAMESPACE_ID, getNamespaceId());
|
||||
|
||||
@ -503,14 +545,76 @@ public class NamingProxy implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
NAMING_LOGGER.error("request: {} failed, servers: {}, code: {}, msg: {}",
|
||||
api, servers, exception.getErrCode(), exception.getErrMsg());
|
||||
NAMING_LOGGER.error("request: {} failed, servers: {}, code: {}, msg: {}", api, servers, exception.getErrCode(),
|
||||
exception.getErrMsg());
|
||||
|
||||
throw new NacosException(exception.getErrCode(), "failed to req API:" + api + " after all servers(" + servers + ") tried: "
|
||||
+ exception.getMessage());
|
||||
throw new NacosException(exception.getErrCode(),
|
||||
"failed to req API:" + api + " after all servers(" + servers + ") tried: " + exception.getMessage());
|
||||
|
||||
}
|
||||
|
||||
private List<String> getServerList() {
|
||||
List<String> snapshot = serversFromEndpoint;
|
||||
if (!CollectionUtils.isEmpty(serverList)) {
|
||||
snapshot = serverList;
|
||||
}
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
public String callServer(String api, Map<String, String> params, Map<String, String> body, String curServer)
|
||||
throws NacosException {
|
||||
return callServer(api, params, body, curServer, HttpMethod.GET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call server.
|
||||
*
|
||||
* @param api api
|
||||
* @param params parameters
|
||||
* @param body body
|
||||
* @param curServer ?
|
||||
* @param method http method
|
||||
* @return result
|
||||
* @throws NacosException nacos exception
|
||||
*/
|
||||
public String callServer(String api, Map<String, String> params, Map<String, String> body, String curServer,
|
||||
String method) throws NacosException {
|
||||
long start = System.currentTimeMillis();
|
||||
long end = 0;
|
||||
injectSecurityInfo(params);
|
||||
Header header = builderHeader();
|
||||
|
||||
String url;
|
||||
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;
|
||||
}
|
||||
url = NamingHttpClientManager.getInstance().getPrefix() + curServer + api;
|
||||
}
|
||||
|
||||
try {
|
||||
HttpRestResult<String> restResult = nacosRestTemplate
|
||||
.exchangeForm(url, header, params, body, method, String.class);
|
||||
end = System.currentTimeMillis();
|
||||
|
||||
MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(restResult.getCode()))
|
||||
.observe(end - start);
|
||||
|
||||
if (restResult.ok()) {
|
||||
return restResult.getData();
|
||||
}
|
||||
if (HttpStatus.SC_NOT_MODIFIED == restResult.getCode()) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
throw new NacosException(restResult.getCode(), restResult.getData());
|
||||
} catch (Exception e) {
|
||||
NAMING_LOGGER.error("[NA] failed to request", e);
|
||||
throw new NacosException(NacosException.SERVER_ERROR, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void injectSecurityInfo(Map<String, String> params) {
|
||||
|
||||
// Inject token if exist:
|
||||
@ -535,6 +639,11 @@ public class NamingProxy implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build header.
|
||||
*
|
||||
* @return header
|
||||
*/
|
||||
public Header builderHeader() {
|
||||
Header header = Header.newInstance();
|
||||
header.addParam(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version);
|
||||
@ -547,8 +656,7 @@ public class NamingProxy implements Closeable {
|
||||
}
|
||||
|
||||
private static String getSignData(String serviceName) {
|
||||
return StringUtils.isNotEmpty(serviceName)
|
||||
? System.currentTimeMillis() + "@@" + serviceName
|
||||
return StringUtils.isNotEmpty(serviceName) ? System.currentTimeMillis() + "@@" + serviceName
|
||||
: String.valueOf(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@ -558,7 +666,8 @@ public class NamingProxy implements Closeable {
|
||||
return SpasAdapter.getAk();
|
||||
}
|
||||
|
||||
return TemplateUtils.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.ACCESS_KEY), new Callable<String>() {
|
||||
return TemplateUtils
|
||||
.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.ACCESS_KEY), new Callable<String>() {
|
||||
|
||||
@Override
|
||||
public String call() {
|
||||
@ -573,7 +682,8 @@ public class NamingProxy implements Closeable {
|
||||
return SpasAdapter.getSk();
|
||||
}
|
||||
|
||||
return TemplateUtils.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.SECRET_KEY), new Callable<String>() {
|
||||
return TemplateUtils
|
||||
.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.SECRET_KEY), new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return SpasAdapter.getSk();
|
||||
@ -600,10 +710,11 @@ public class NamingProxy implements Closeable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
||||
NamingHttpClientManager.getInstance().shutdown();
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -20,14 +21,21 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Chooser.
|
||||
*
|
||||
* @author alibaba
|
||||
*/
|
||||
public class Chooser<K, T> {
|
||||
|
||||
private K uniqueKey;
|
||||
private final K uniqueKey;
|
||||
|
||||
private volatile Ref<T> ref;
|
||||
|
||||
/**
|
||||
* Random get one item.
|
||||
*
|
||||
* @return item
|
||||
*/
|
||||
public T random() {
|
||||
List<T> items = ref.items;
|
||||
if (items.size() == 0) {
|
||||
@ -39,6 +47,11 @@ public class Chooser<K, T> {
|
||||
return items.get(ThreadLocalRandom.current().nextInt(items.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Random get one item with weight.
|
||||
*
|
||||
* @return item
|
||||
*/
|
||||
public T randomWithWeight() {
|
||||
Ref<T> ref = this.ref;
|
||||
double random = ThreadLocalRandom.current().nextDouble(0, 1);
|
||||
@ -80,6 +93,11 @@ public class Chooser<K, T> {
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* refresh items.
|
||||
*
|
||||
* @param itemsWithWeight items with weight
|
||||
*/
|
||||
public void refresh(List<Pair<T>> itemsWithWeight) {
|
||||
Ref<T> newRef = new Ref<T>(itemsWithWeight);
|
||||
newRef.refresh();
|
||||
@ -88,16 +106,22 @@ public class Chooser<K, T> {
|
||||
}
|
||||
|
||||
public class Ref<T> {
|
||||
|
||||
private List<Pair<T>> itemsWithWeight = new ArrayList<Pair<T>>();
|
||||
private List<T> items = new ArrayList<T>();
|
||||
|
||||
private final List<T> items = new ArrayList<T>();
|
||||
|
||||
private Poller<T> poller = new GenericPoller<T>(items);
|
||||
|
||||
private double[] weights;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Ref(List<Pair<T>> itemsWithWeight) {
|
||||
this.itemsWithWeight = itemsWithWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh.
|
||||
*/
|
||||
public void refresh() {
|
||||
Double originWeightSum = (double) 0;
|
||||
|
||||
@ -142,7 +166,8 @@ public class Chooser<K, T> {
|
||||
if (index == 0 || (Math.abs(weights[index - 1] - 1) < doublePrecisionDelta)) {
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException("Cumulative Weight caculate wrong , the sum of probabilities does not equals 1.");
|
||||
throw new IllegalStateException(
|
||||
"Cumulative Weight caculate wrong , the sum of probabilities does not equals 1.");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -167,9 +192,7 @@ public class Chooser<K, T> {
|
||||
}
|
||||
Ref<T> otherRef = (Ref<T>) other;
|
||||
if (itemsWithWeight == null) {
|
||||
if (otherRef.itemsWithWeight != null) {
|
||||
return false;
|
||||
}
|
||||
return otherRef.itemsWithWeight == null;
|
||||
} else {
|
||||
if (otherRef.itemsWithWeight == null) {
|
||||
return false;
|
||||
@ -177,7 +200,6 @@ public class Chooser<K, T> {
|
||||
return this.itemsWithWeight.equals(otherRef.itemsWithWeight);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,18 +235,13 @@ public class Chooser<K, T> {
|
||||
}
|
||||
|
||||
if (this.ref == null) {
|
||||
if (otherChooser.getRef() != null) {
|
||||
return false;
|
||||
}
|
||||
return otherChooser.getRef() == null;
|
||||
} else {
|
||||
if (otherChooser.getRef() == null) {
|
||||
return false;
|
||||
} else if (!this.ref.equals(otherChooser.getRef())) {
|
||||
return false;
|
||||
} else {
|
||||
return this.ref.equals(otherChooser.getRef());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -13,13 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
/**
|
||||
* Created by harold on 2015/12/7.
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides utility methods and decorators for {@link Collection} instances.
|
||||
@ -43,7 +44,7 @@ import java.util.*;
|
||||
public class CollectionUtils {
|
||||
|
||||
/**
|
||||
* Constant to avoid repeated object creation
|
||||
* Constant to avoid repeated object creation.
|
||||
*/
|
||||
private static final Integer INTEGER_ONE = 1;
|
||||
|
||||
@ -55,8 +56,8 @@ public class CollectionUtils {
|
||||
|
||||
/**
|
||||
* Returns a new {@link Collection} containing <tt><i>a</i> - <i>b</i></tt>. The cardinality of each element
|
||||
* <i>e</i> in the returned {@link Collection} will be the cardinality of <i>e</i> in <i>a</i> minus the cardinality
|
||||
* of <i>e</i> in <i>b</i>, or zero, whichever is greater.
|
||||
* <i>e</i> in the returned {@link Collection} will be the cardinality of <i>e</i> in <i>a</i> minus the
|
||||
* cardinality of <i>e</i> in <i>b</i>, or zero, whichever is greater.
|
||||
*
|
||||
* @param a the collection to subtract from, must not be null
|
||||
* @param b the collection to subtract, must not be null
|
||||
@ -74,8 +75,8 @@ public class CollectionUtils {
|
||||
/**
|
||||
* Returns a {@link Map} mapping each unique element in the given {@link Collection} to an {@link Integer}
|
||||
* representing the number of occurrences of that element in the {@link Collection}.
|
||||
* <p>
|
||||
* Only those elements present in the collection will appear as keys in the map.
|
||||
*
|
||||
* <p>Only those elements present in the collection will appear as keys in the map.
|
||||
*
|
||||
* @param coll the collection to get the cardinality map for, must not be null
|
||||
* @return the populated cardinality map
|
||||
@ -84,7 +85,7 @@ public class CollectionUtils {
|
||||
Map count = new HashMap(coll.size());
|
||||
for (Iterator it = coll.iterator(); it.hasNext(); ) {
|
||||
Object obj = it.next();
|
||||
Integer c = (Integer)(count.get(obj));
|
||||
Integer c = (Integer) (count.get(obj));
|
||||
if (c == null) {
|
||||
count.put(obj, INTEGER_ONE);
|
||||
} else {
|
||||
@ -97,8 +98,8 @@ public class CollectionUtils {
|
||||
/**
|
||||
* Returns <tt>true</tt> iff the given {@link Collection}s contain exactly the same elements with exactly the same
|
||||
* cardinalities.
|
||||
* <p>
|
||||
* That is, iff the cardinality of <i>e</i> in <i>a</i> is equal to the cardinality of <i>e</i> in <i>b</i>, for
|
||||
*
|
||||
* <p>That is, iff the cardinality of <i>e</i> in <i>a</i> is equal to the cardinality of <i>e</i> in <i>b</i>, for
|
||||
* each element <i>e</i> in <i>a</i> or <i>b</i>.
|
||||
*
|
||||
* @param a the first collection, must not be null
|
||||
@ -130,8 +131,8 @@ public class CollectionUtils {
|
||||
|
||||
/**
|
||||
* Null-safe check if the specified collection is empty.
|
||||
* <p>
|
||||
* Null returns true.
|
||||
*
|
||||
* <p>Null returns true.
|
||||
*
|
||||
* @param coll the collection to check, may be null
|
||||
* @return true if empty or null
|
||||
@ -142,7 +143,7 @@ public class CollectionUtils {
|
||||
}
|
||||
|
||||
private static int getFreq(final Object obj, final Map freqMap) {
|
||||
Integer count = (Integer)freqMap.get(obj);
|
||||
Integer count = (Integer) freqMap.get(obj);
|
||||
if (count != null) {
|
||||
return count.intValue();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -20,11 +21,14 @@ import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Generic Poller.
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
public class GenericPoller<T> implements Poller<T> {
|
||||
|
||||
private AtomicInteger index = new AtomicInteger(0);
|
||||
private final AtomicInteger index = new AtomicInteger(0);
|
||||
|
||||
private List<T> items = new ArrayList<T>();
|
||||
|
||||
public GenericPoller(List<T> items) {
|
||||
|
@ -22,7 +22,10 @@ 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.*;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.client.utils.TemplateUtils;
|
||||
import com.alibaba.nacos.client.utils.TenantUtil;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
@ -30,24 +33,24 @@ import java.util.Properties;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Init utils.
|
||||
*
|
||||
* @author liaochuntao
|
||||
* @author deshao
|
||||
*/
|
||||
public class InitUtils {
|
||||
|
||||
/**
|
||||
* Add a difference to the name naming. This method simply initializes the namespace for Naming.
|
||||
* Config initialization is not the same, so it cannot be reused directly.
|
||||
* Add a difference to the name naming. This method simply initializes the namespace for Naming. Config
|
||||
* initialization is not the same, so it cannot be reused directly.
|
||||
*
|
||||
* @param properties
|
||||
* @return
|
||||
* @param properties properties
|
||||
* @return namespace
|
||||
*/
|
||||
public static String initNamespaceForNaming(Properties properties) {
|
||||
String tmpNamespace = null;
|
||||
|
||||
|
||||
String isUseCloudNamespaceParsing =
|
||||
properties.getProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
|
||||
String isUseCloudNamespaceParsing = properties.getProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
|
||||
System.getProperty(SystemPropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
|
||||
String.valueOf(Constants.DEFAULT_USE_CLOUD_NAMESPACE_PARSING)));
|
||||
|
||||
@ -95,29 +98,36 @@ public class InitUtils {
|
||||
return tmpNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init web root context.
|
||||
*/
|
||||
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.WEB_CONTEXT = webContext.indexOf("/") > -1 ? webContext
|
||||
: "/" + webContext;
|
||||
UtilAndComs.webContext = webContext.indexOf("/") > -1 ? webContext : "/" + webContext;
|
||||
|
||||
UtilAndComs.NACOS_URL_BASE = UtilAndComs.WEB_CONTEXT + "/v1/ns";
|
||||
UtilAndComs.NACOS_URL_INSTANCE = UtilAndComs.NACOS_URL_BASE + "/instance";
|
||||
UtilAndComs.nacosUrlBase = UtilAndComs.webContext + "/v1/ns";
|
||||
UtilAndComs.nacosUrlInstance = UtilAndComs.nacosUrlBase + "/instance";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Init end point.
|
||||
*
|
||||
* @param properties properties
|
||||
* @return end point
|
||||
*/
|
||||
public static String initEndpoint(final Properties properties) {
|
||||
if (properties == null) {
|
||||
|
||||
return "";
|
||||
}
|
||||
// Whether to enable domain name resolution rules
|
||||
String isUseEndpointRuleParsing =
|
||||
properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
|
||||
String isUseEndpointRuleParsing = properties.getProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
|
||||
System.getProperty(SystemPropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE,
|
||||
String.valueOf(ParamUtil.USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE)));
|
||||
|
||||
@ -137,7 +147,9 @@ public class InitUtils {
|
||||
return "";
|
||||
}
|
||||
|
||||
String endpointPort = TemplateUtils.stringEmptyAndThenExecute(System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT), new Callable<String>() {
|
||||
String endpointPort = TemplateUtils
|
||||
.stringEmptyAndThenExecute(System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT),
|
||||
new Callable<String>() {
|
||||
@Override
|
||||
public String call() {
|
||||
|
||||
@ -156,16 +168,16 @@ public class InitUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register subType for serialization
|
||||
* Register subType for serialization.
|
||||
*
|
||||
* Now these subType implementation class has registered in static code.
|
||||
* But there are some problem for classloader. The implementation class
|
||||
* will be loaded when they are used, which will make deserialize
|
||||
* before register.
|
||||
* <p>
|
||||
* Now these subType implementation class has registered in static code. But there are some problem for classloader.
|
||||
* The implementation class will be loaded when they are used, which will make deserialize before register.
|
||||
* </p>
|
||||
*
|
||||
* 子类实现类中的静态代码串中已经向Jackson进行了注册,但是由于classloader的原因,只有当
|
||||
* 该子类被使用的时候,才会加载该类。这可能会导致Jackson先进性反序列化,再注册子类,从而导致
|
||||
* 反序列化失败。
|
||||
* <p>
|
||||
* 子类实现类中的静态代码串中已经向Jackson进行了注册,但是由于classloader的原因,只有当 该子类被使用的时候,才会加载该类。这可能会导致Jackson先进性反序列化,再注册子类,从而导致 反序列化失败。
|
||||
* </p>
|
||||
*/
|
||||
public static void initSerialization() {
|
||||
// TODO register in implementation class or remove subType
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import java.util.Random;
|
||||
@ -22,11 +23,11 @@ import java.util.Random;
|
||||
* java.lang.Math#random()} method and its system-wide {@link Random} object.</p>
|
||||
* <p>
|
||||
* It does this to allow for a Random class in which the seed is shared between all members of the class - a better name
|
||||
* would have been SharedSeedRandom.
|
||||
* would have been SharedSeedRandom.</p>
|
||||
* <p>
|
||||
* <b>N.B.</b> the current implementation overrides the methods {@link Random#nextInt(int)} and {@link
|
||||
* Random#nextLong()} to produce positive numbers ranging from 0 (inclusive) to MAX_VALUE (exclusive).
|
||||
*
|
||||
* </p>
|
||||
* @author unknown
|
||||
* @version $Id: JVMRandom.java 911986 2010-02-19 21:19:05Z niallp $
|
||||
* @since 2.0
|
||||
@ -58,7 +59,7 @@ public final class JvmRandom extends Random {
|
||||
* Unsupported in 2.0.
|
||||
*
|
||||
* @param seed ignored
|
||||
* @throws UnsupportedOperationException
|
||||
* @throws UnsupportedOperationException unsupported operation exception
|
||||
*/
|
||||
@Override
|
||||
public synchronized void setSeed(long seed) {
|
||||
@ -71,7 +72,7 @@ public final class JvmRandom extends Random {
|
||||
* Unsupported in 2.0.
|
||||
*
|
||||
* @return Nothing, this method always throws an UnsupportedOperationException.
|
||||
* @throws UnsupportedOperationException
|
||||
* @throws UnsupportedOperationException unsupported operation exception
|
||||
*/
|
||||
@Override
|
||||
public synchronized double nextGaussian() {
|
||||
@ -82,7 +83,7 @@ public final class JvmRandom extends Random {
|
||||
* Unsupported in 2.0.
|
||||
*
|
||||
* @param byteArray ignored
|
||||
* @throws UnsupportedOperationException
|
||||
* @throws UnsupportedOperationException unsupported operation exception
|
||||
*/
|
||||
@Override
|
||||
public void nextBytes(byte[] byteArray) {
|
||||
@ -91,7 +92,7 @@ public final class JvmRandom extends Random {
|
||||
|
||||
/**
|
||||
* <p>Returns the next pseudorandom, uniformly distributed int value from the Math.random() sequence.</p> Identical
|
||||
* to <code>nextInt(Integer.MAX_VALUE)</code> <p> <b>N.B. All values are >= 0.<b> </p>
|
||||
* to <code>nextInt(Integer.MAX_VALUE)</code> <p> <b>N.B. All values are >= 0.</b> </p>
|
||||
*
|
||||
* @return the random int
|
||||
*/
|
||||
@ -114,8 +115,9 @@ public final class JvmRandom extends Random {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the next pseudorandom, uniformly distributed long value from the Math.random() sequence.</p> Identical
|
||||
* to <code>nextLong(Long.MAX_VALUE)</code> <p> <b>N.B. All values are >= 0.<b> </p>
|
||||
* <p>Returns the next pseudorandom, uniformly distributed long value from the Math.random() sequence.</p>
|
||||
* Identical
|
||||
* to <code>nextLong(Long.MAX_VALUE)</code> <p> <b>N.B. All values are >= 0.</b> </p>
|
||||
*
|
||||
* @return the random long
|
||||
*/
|
||||
@ -134,16 +136,13 @@ public final class JvmRandom extends Random {
|
||||
*/
|
||||
public static long nextLong(long n) {
|
||||
if (n <= 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Upper bound for nextInt must be positive"
|
||||
);
|
||||
throw new IllegalArgumentException("Upper bound for nextInt must be positive");
|
||||
}
|
||||
// Code adapted from Harmony Random#nextInt(int)
|
||||
// n is power of 2
|
||||
if ((n & -n) == n) {
|
||||
// dropping lower order bits improves behaviour for low values of n
|
||||
return next63bits() >> 63
|
||||
- bitsRequired(n - 1);
|
||||
return next63bits() >> 63 - bitsRequired(n - 1);
|
||||
}
|
||||
// Not a power of two
|
||||
long val;
|
||||
@ -167,7 +166,8 @@ public final class JvmRandom extends Random {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and <code>1.0</code>
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and
|
||||
* <code>1.0</code>
|
||||
* from the Math.random() sequence.</p>
|
||||
*
|
||||
* @return the random float
|
||||
@ -188,7 +188,7 @@ public final class JvmRandom extends Random {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next unsigned random long
|
||||
* Get the next unsigned random long.
|
||||
*
|
||||
* @return unsigned random long
|
||||
*/
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
@ -21,20 +22,29 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* Net utils.
|
||||
*
|
||||
* @author xuanyin.zy
|
||||
*/
|
||||
public class NetUtils {
|
||||
private static String LOCAL_IP;
|
||||
|
||||
private static String localIp;
|
||||
|
||||
/**
|
||||
* Get local ip.
|
||||
*
|
||||
* @return local ip
|
||||
*/
|
||||
public static String localIP() {
|
||||
try {
|
||||
if (!StringUtils.isEmpty(LOCAL_IP)) {
|
||||
return LOCAL_IP;
|
||||
if (!StringUtils.isEmpty(localIp)) {
|
||||
return localIp;
|
||||
}
|
||||
|
||||
String ip = System.getProperty("com.alibaba.nacos.client.naming.local.ip", InetAddress.getLocalHost().getHostAddress());
|
||||
String ip = System.getProperty("com.alibaba.nacos.client.naming.local.ip",
|
||||
InetAddress.getLocalHost().getHostAddress());
|
||||
|
||||
return LOCAL_IP = ip;
|
||||
return localIp = ip;
|
||||
} catch (UnknownHostException e) {
|
||||
return "resolve_failed";
|
||||
}
|
||||
|
@ -13,15 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
/**
|
||||
* Pair.
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
public class Pair<T> {
|
||||
|
||||
private T item;
|
||||
private double weight;
|
||||
private final T item;
|
||||
|
||||
private final double weight;
|
||||
|
||||
public Pair(T item, double weight) {
|
||||
this.item = item;
|
||||
|
@ -13,23 +13,27 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Poller.
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
public interface Poller<T> {
|
||||
|
||||
/**
|
||||
* Get next element selected by poller
|
||||
* Get next element selected by poller.
|
||||
*
|
||||
* @return next element
|
||||
*/
|
||||
T next();
|
||||
|
||||
/**
|
||||
* Update items stored in poller
|
||||
* Update items stored in poller.
|
||||
*
|
||||
* @param items new item list
|
||||
* @return new poller instance
|
||||
|
@ -13,12 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* <p><code>RandomUtils</code> is a wrapper that supports all possible {@link java.util.Random} methods via the {@link
|
||||
* <code>RandomUtils</code> is a wrapper that supports all possible {@link java.util.Random} methods via the {@link
|
||||
* java.lang.Math#random()} method and its system-wide <code>Random</code> object.
|
||||
*
|
||||
* @author Gary D. Gregory
|
||||
@ -39,7 +40,7 @@ public class RandomUtils {
|
||||
|
||||
/**
|
||||
* <p>Returns the next pseudorandom, uniformly distributed int value from the Math.random() sequence.</p> <b>N.B.
|
||||
* All values are >= 0.<b>
|
||||
* All values are >= 0.</b>
|
||||
*
|
||||
* @return the random int
|
||||
*/
|
||||
@ -84,7 +85,7 @@ public class RandomUtils {
|
||||
|
||||
/**
|
||||
* <p>Returns the next pseudorandom, uniformly distributed long value from the Math.random() sequence.</p> <b>N.B.
|
||||
* All values are >= 0.<b>
|
||||
* All values are >= 0.</b>
|
||||
*
|
||||
* @return the random long
|
||||
*/
|
||||
@ -122,7 +123,8 @@ public class RandomUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and <code>1.0</code>
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and
|
||||
* <code>1.0</code>
|
||||
* from the Math.random() sequence.</p>
|
||||
*
|
||||
* @return the random float
|
||||
@ -132,7 +134,8 @@ public class RandomUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and <code>1.0</code>
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and
|
||||
* <code>1.0</code>
|
||||
* from the given Random sequence.</p>
|
||||
*
|
||||
* @param random the Random sequence generator.
|
||||
@ -143,7 +146,8 @@ public class RandomUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and <code>1.0</code>
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and
|
||||
* <code>1.0</code>
|
||||
* from the Math.random() sequence.</p>
|
||||
*
|
||||
* @return the random double
|
||||
@ -153,7 +157,8 @@ public class RandomUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and <code>1.0</code>
|
||||
* <p>Returns the next pseudorandom, uniformly distributed float value between <code>0.0</code> and
|
||||
* <code>1.0</code>
|
||||
* from the given Random sequence.</p>
|
||||
*
|
||||
* @param random the Random sequence generator.
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import com.alibaba.nacos.client.identify.Base64;
|
||||
@ -20,39 +21,45 @@ import com.alibaba.nacos.client.identify.Base64;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Sign util.
|
||||
*
|
||||
* @author pbting
|
||||
* @date 2019-01-22 10:20 PM
|
||||
*/
|
||||
public class SignUtil {
|
||||
public static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
public static final Charset UTF8 = StandardCharsets.UTF_8;
|
||||
|
||||
public SignUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign.
|
||||
*
|
||||
* @param data data
|
||||
* @param key key
|
||||
* @return signature
|
||||
* @throws Exception exception
|
||||
*/
|
||||
public static String sign(String data, String key) throws Exception {
|
||||
try {
|
||||
byte[] signature = sign(data.getBytes(UTF8), key.getBytes(UTF8),
|
||||
SignUtil.SigningAlgorithm.HmacSHA1);
|
||||
byte[] signature = sign(data.getBytes(UTF8), key.getBytes(UTF8), SignUtil.SigningAlgorithm.HmacSHA1);
|
||||
return new String(Base64.encodeBase64(signature));
|
||||
} catch (Exception var3) {
|
||||
throw new Exception(
|
||||
"Unable to calculate a request signature: " + var3.getMessage(),
|
||||
var3);
|
||||
} catch (Exception ex) {
|
||||
throw new Exception("Unable to calculate a request signature: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] sign(byte[] data, byte[] key,
|
||||
SignUtil.SigningAlgorithm algorithm) throws Exception {
|
||||
private static byte[] sign(byte[] data, byte[] key, SignUtil.SigningAlgorithm algorithm) throws Exception {
|
||||
try {
|
||||
Mac mac = Mac.getInstance(algorithm.toString());
|
||||
mac.init(new SecretKeySpec(key, algorithm.toString()));
|
||||
return mac.doFinal(data);
|
||||
} catch (Exception var4) {
|
||||
throw new Exception(
|
||||
"Unable to calculate a request signature: " + var4.getMessage(),
|
||||
var4);
|
||||
} catch (Exception ex) {
|
||||
throw new Exception("Unable to calculate a request signature: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
@ -30,14 +31,13 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
* ThreadLocalRandom} is particularly appropriate when multiple tasks (for example, each a {@link
|
||||
* io.netty.util.internal.chmv8.ForkJoinTask}) use random numbers in parallel in thread pools.
|
||||
* <p>
|
||||
* <p>
|
||||
* Usages of this class should typically be of the form: {@code ThreadLocalRandom.current().nextX(...)} (where {@code X}
|
||||
* is {@code Int}, {@code Long}, etc). When all usages are of this form, it is never possible to accidently share a
|
||||
* {@code ThreadLocalRandom} across multiple threads.
|
||||
* <p>
|
||||
* </p>
|
||||
* <p>
|
||||
* This class also provides additional commonly used bounded random generation methods.
|
||||
* <p>
|
||||
* </p>
|
||||
* //since 1.7 //author Doug Lea
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
@ -114,7 +114,9 @@ public class ThreadLocalRandom extends Random {
|
||||
|
||||
// same constants as Random, but must be redeclared because private
|
||||
private static final long multiplier = 0x5DEECE66DL;
|
||||
|
||||
private static final long addend = 0xBL;
|
||||
|
||||
private static final long mask = (1L << 48) - 1;
|
||||
|
||||
/**
|
||||
@ -177,7 +179,7 @@ public class ThreadLocalRandom extends Random {
|
||||
@Override
|
||||
protected int next(int bits) {
|
||||
rnd = (rnd * multiplier + addend) & mask;
|
||||
return (int)(rnd >>> (48 - bits));
|
||||
return (int) (rnd >>> (48 - bits));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -223,7 +225,7 @@ public class ThreadLocalRandom extends Random {
|
||||
}
|
||||
n = nextn;
|
||||
}
|
||||
return offset + nextInt((int)n);
|
||||
return offset + nextInt((int) n);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,24 +13,27 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.VersionUtils;
|
||||
|
||||
/**
|
||||
* Util and constants.
|
||||
*
|
||||
* @author xuanyin.zy
|
||||
*/
|
||||
public class UtilAndComs {
|
||||
|
||||
public static final String VERSION = "Nacos-Java-Client:v" + VersionUtils.version;
|
||||
|
||||
public static String WEB_CONTEXT = "/nacos";
|
||||
public static String webContext = "/nacos";
|
||||
|
||||
public static String NACOS_URL_BASE = WEB_CONTEXT + "/v1/ns";
|
||||
public static String nacosUrlBase = webContext + "/v1/ns";
|
||||
|
||||
public static String NACOS_URL_INSTANCE = NACOS_URL_BASE + "/instance";
|
||||
public static String nacosUrlInstance = nacosUrlBase + "/instance";
|
||||
|
||||
public static String NACOS_URL_SERVICE = NACOS_URL_BASE + "/service";
|
||||
public static String nacosUrlService = nacosUrlBase + "/service";
|
||||
|
||||
public static final String ENCODING = "UTF-8";
|
||||
|
||||
@ -50,13 +53,11 @@ public class UtilAndComs {
|
||||
|
||||
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;
|
||||
public static final int DEFAULT_CLIENT_BEAT_THREAD_COUNT =
|
||||
Runtime.getRuntime().availableProcessors() > 1 ? Runtime.getRuntime().availableProcessors() / 2 : 1;
|
||||
|
||||
public static final int DEFAULT_POLLING_THREAD_COUNT = Runtime.getRuntime()
|
||||
.availableProcessors() > 1 ? Runtime.getRuntime().availableProcessors() / 2
|
||||
: 1;
|
||||
public static final int DEFAULT_POLLING_THREAD_COUNT =
|
||||
Runtime.getRuntime().availableProcessors() > 1 ? Runtime.getRuntime().availableProcessors() / 2 : 1;
|
||||
|
||||
public static final String HTTP = "http://";
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.security;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
@ -24,7 +25,6 @@ import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -35,7 +35,7 @@ import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Security proxy to update security information
|
||||
* Security proxy to update security information.
|
||||
*
|
||||
* @author nkorange
|
||||
* @since 1.2.0
|
||||
@ -46,42 +46,42 @@ public class SecurityProxy {
|
||||
|
||||
private static final String LOGIN_URL = "/v1/auth/users/login";
|
||||
|
||||
private NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getNacosRestTemplate();
|
||||
private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getInstance().getNacosRestTemplate();
|
||||
|
||||
private String contextPath;
|
||||
|
||||
/**
|
||||
* User's name
|
||||
* User's name.
|
||||
*/
|
||||
private String username;
|
||||
private final String username;
|
||||
|
||||
/**
|
||||
* User's password
|
||||
* User's password.
|
||||
*/
|
||||
private String password;
|
||||
private final String password;
|
||||
|
||||
/**
|
||||
* A token to take with when sending request to Nacos server
|
||||
* A token to take with when sending request to Nacos server.
|
||||
*/
|
||||
private String accessToken;
|
||||
|
||||
/**
|
||||
* TTL of token in seconds
|
||||
* TTL of token in seconds.
|
||||
*/
|
||||
private long tokenTtl;
|
||||
|
||||
/**
|
||||
* Last timestamp refresh security info from server
|
||||
* Last timestamp refresh security info from server.
|
||||
*/
|
||||
private long lastRefreshTime;
|
||||
|
||||
/**
|
||||
* time window to refresh security info in seconds
|
||||
* time window to refresh security info in seconds.
|
||||
*/
|
||||
private long tokenRefreshWindow;
|
||||
|
||||
/**
|
||||
* Construct from properties, keeping flexibility
|
||||
* Construct from properties, keeping flexibility.
|
||||
*
|
||||
* @param properties a bunch of properties to read
|
||||
*/
|
||||
@ -92,10 +92,17 @@ public class SecurityProxy {
|
||||
contextPath = contextPath.startsWith("/") ? contextPath : "/" + contextPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login to servers.
|
||||
*
|
||||
* @param servers server list
|
||||
* @return true if login successfully
|
||||
*/
|
||||
public boolean login(List<String> servers) {
|
||||
|
||||
try {
|
||||
if ((System.currentTimeMillis() - lastRefreshTime) < TimeUnit.SECONDS.toMillis(tokenTtl - tokenRefreshWindow)) {
|
||||
if ((System.currentTimeMillis() - lastRefreshTime) < TimeUnit.SECONDS
|
||||
.toMillis(tokenTtl - tokenRefreshWindow)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -111,11 +118,17 @@ public class SecurityProxy {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login to server.
|
||||
*
|
||||
* @param server server address
|
||||
* @return true if login successfully
|
||||
*/
|
||||
public boolean login(String server) {
|
||||
|
||||
if (StringUtils.isNotBlank(username)) {
|
||||
Map<String, String> params = new HashMap<String, String>(2);
|
||||
Map<String, String> bodyMap = new HashMap<>(2);
|
||||
Map<String, String> bodyMap = new HashMap<String, String>(2);
|
||||
params.put("username", username);
|
||||
bodyMap.put("password", password);
|
||||
String url = "http://" + server + contextPath + LOGIN_URL;
|
||||
@ -124,7 +137,8 @@ public class SecurityProxy {
|
||||
url = server + contextPath + LOGIN_URL;
|
||||
}
|
||||
try {
|
||||
HttpRestResult<String> restResult = nacosRestTemplate.postForm(url, Header.EMPTY, params, bodyMap, String.class);
|
||||
HttpRestResult<String> restResult = nacosRestTemplate
|
||||
.postForm(url, Header.EMPTY, params, bodyMap, String.class);
|
||||
if (!restResult.ok()) {
|
||||
SECURITY_LOGGER.error("login failed: {}", JacksonUtils.toJson(restResult));
|
||||
return false;
|
||||
@ -136,8 +150,8 @@ public class SecurityProxy {
|
||||
tokenRefreshWindow = tokenTtl / 10;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SECURITY_LOGGER.error("[SecurityProxy] login http request failed" +
|
||||
" url: {}, params: {}, bodyMap: {}, errorMsg: {}", url, params, bodyMap, e.getMessage());
|
||||
SECURITY_LOGGER.error("[SecurityProxy] login http request failed"
|
||||
+ " url: {}, params: {}, bodyMap: {}, errorMsg: {}", url, params, bodyMap, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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;
|
||||
@ -20,21 +21,28 @@ import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* appName util
|
||||
* appName util.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class AppNameUtils {
|
||||
|
||||
private static final String PARAM_MARKING_PROJECT = "project.name";
|
||||
|
||||
private static final String PARAM_MARKING_JBOSS = "jboss.server.home.dir";
|
||||
|
||||
private static final String PARAM_MARKING_JETTY = "jetty.home";
|
||||
|
||||
private static final String PARAM_MARKING_TOMCAT = "catalina.base";
|
||||
|
||||
private static final String LINUX_ADMIN_HOME = "/home/admin/";
|
||||
|
||||
private static final String SERVER_JBOSS = "jboss";
|
||||
|
||||
private static final String SERVER_JETTY = "jetty";
|
||||
|
||||
private static final String SERVER_TOMCAT = "tomcat";
|
||||
|
||||
private static final String SERVER_UNKNOWN = "unknown server";
|
||||
|
||||
public static String getAppName() {
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@ -27,7 +28,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class EnvUtil {
|
||||
|
||||
final static public Logger LOGGER = LogUtils.logger(EnvUtil.class);
|
||||
public static final Logger LOGGER = LogUtils.logger(EnvUtil.class);
|
||||
|
||||
public static void setSelfEnv(Map<String, List<String>> headers) {
|
||||
if (headers != null) {
|
||||
@ -99,9 +100,14 @@ public class EnvUtil {
|
||||
}
|
||||
|
||||
private static String selfAmorayTag;
|
||||
|
||||
private static String selfVipserverTag;
|
||||
|
||||
private static String selfLocationTag;
|
||||
private final static String AMORY_TAG = "Amory-Tag";
|
||||
private final static String VIPSERVER_TAG = "Vipserver-Tag";
|
||||
private final static String LOCATION_TAG = "Location-Tag";
|
||||
|
||||
private static final String AMORY_TAG = "Amory-Tag";
|
||||
|
||||
private static final String VIPSERVER_TAG = "Vipserver-Tag";
|
||||
|
||||
private static final String LOCATION_TAG = "Location-Tag";
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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;
|
||||
@ -21,21 +22,22 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* ip tool
|
||||
* ip tool.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public class IPUtil {
|
||||
public class IpUtil {
|
||||
|
||||
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 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) {
|
||||
public static boolean isIpv4(String addr) {
|
||||
return isMatch(addr, IPV4_PATTERN);
|
||||
}
|
||||
|
||||
public static boolean isIPV6(String addr) {
|
||||
public static boolean isIpv6(String addr) {
|
||||
return isMatch(addr, IPV6_PATTERN);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.client.logging.AbstractNacosLogging;
|
||||
@ -23,6 +24,8 @@ import org.slf4j.Logger;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
/**
|
||||
* Log utils.
|
||||
*
|
||||
* @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
|
||||
* @since 0.9.0
|
||||
*/
|
||||
@ -47,15 +50,15 @@ public class LogUtils {
|
||||
nacosLogging.loadConfiguration();
|
||||
} catch (Throwable t) {
|
||||
if (isLogback) {
|
||||
getLogger(LogUtils.class).warn("Load Logback Configuration of Nacos fail, message: {}",
|
||||
t.getMessage());
|
||||
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());
|
||||
getLogger(LogUtils.class)
|
||||
.warn("Load Log4j Configuration of Nacos fail, message: {}", t.getMessage());
|
||||
}
|
||||
}
|
||||
} catch (Throwable t1) {
|
||||
getLogger(LogUtils.class).warn("Init Nacos Logging fail, message: {}", t1.getMessage());
|
||||
} catch (Throwable ex) {
|
||||
getLogger(LogUtils.class).warn("Init Nacos Logging fail, message: {}", ex.getMessage());
|
||||
}
|
||||
|
||||
NAMING_LOGGER = getLogger("com.alibaba.nacos.client.naming");
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
@ -28,24 +29,32 @@ import java.util.concurrent.Callable;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* manage param tool
|
||||
* manage param tool.
|
||||
*
|
||||
* @author nacos
|
||||
*/
|
||||
public class ParamUtil {
|
||||
|
||||
private final static Logger LOGGER = LogUtils.logger(ParamUtil.class);
|
||||
private static final Logger LOGGER = LogUtils.logger(ParamUtil.class);
|
||||
|
||||
public final static boolean USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE = true;
|
||||
public static final boolean USE_ENDPOINT_PARSING_RULE_DEFAULT_VALUE = true;
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("\\$\\{[^}]+\\}");
|
||||
|
||||
private static String defaultContextPath;
|
||||
|
||||
private static String defaultNodesPath = "serverlist";
|
||||
|
||||
private static String appKey;
|
||||
|
||||
private static String appName;
|
||||
private static String defaultServerPort;
|
||||
|
||||
private static final String DEFAULT_SERVER_PORT;
|
||||
|
||||
private static String clientVersion = "unknown";
|
||||
|
||||
private static int connectTimeout;
|
||||
|
||||
private static double perTaskConfigSize = 3000;
|
||||
|
||||
static {
|
||||
@ -58,8 +67,8 @@ public class ParamUtil {
|
||||
|
||||
String defaultServerPortTmp = "8848";
|
||||
|
||||
defaultServerPort = System.getProperty("nacos.server.port", defaultServerPortTmp);
|
||||
LOGGER.info("[settings] [req-serv] nacos-server port:{}", defaultServerPort);
|
||||
DEFAULT_SERVER_PORT = System.getProperty("nacos.server.port", defaultServerPortTmp);
|
||||
LOGGER.info("[settings] [req-serv] nacos-server port:{}", DEFAULT_SERVER_PORT);
|
||||
|
||||
String tmp = "1000";
|
||||
try {
|
||||
@ -73,8 +82,7 @@ public class ParamUtil {
|
||||
LOGGER.info("[settings] [http-client] connect timeout:{}", connectTimeout);
|
||||
|
||||
try {
|
||||
InputStream in = HttpSimpleClient.class.getClassLoader()
|
||||
.getResourceAsStream("application.properties");
|
||||
InputStream in = HttpSimpleClient.class.getClassLoader().getResourceAsStream("application.properties");
|
||||
Properties props = new Properties();
|
||||
props.load(in);
|
||||
String val = null;
|
||||
@ -144,7 +152,7 @@ public class ParamUtil {
|
||||
}
|
||||
|
||||
public static String getDefaultServerPort() {
|
||||
return defaultServerPort;
|
||||
return DEFAULT_SERVER_PORT;
|
||||
}
|
||||
|
||||
public static String getDefaultNodesPath() {
|
||||
@ -155,11 +163,16 @@ public class ParamUtil {
|
||||
ParamUtil.defaultNodesPath = defaultNodesPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse namespace from properties and environment.
|
||||
*
|
||||
* @param properties properties
|
||||
* @return namespace
|
||||
*/
|
||||
public static String parseNamespace(Properties properties) {
|
||||
String namespaceTmp = null;
|
||||
|
||||
String isUseCloudNamespaceParsing =
|
||||
properties.getProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
|
||||
String isUseCloudNamespaceParsing = properties.getProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
|
||||
System.getProperty(SystemPropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
|
||||
String.valueOf(Constants.DEFAULT_USE_CLOUD_NAMESPACE_PARSING)));
|
||||
|
||||
@ -186,10 +199,15 @@ public class ParamUtil {
|
||||
return StringUtils.isNotBlank(namespaceTmp) ? namespaceTmp.trim() : StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse end point rule.
|
||||
*
|
||||
* @param endpointUrl endpoint url
|
||||
* @return end point rule
|
||||
*/
|
||||
public static String parsingEndpointRule(String endpointUrl) {
|
||||
// 配置文件中输入的话,以 ENV 中的优先,
|
||||
if (endpointUrl == null
|
||||
|| !PATTERN.matcher(endpointUrl).find()) {
|
||||
if (endpointUrl == null || !PATTERN.matcher(endpointUrl).find()) {
|
||||
// skip retrieve from system property and retrieve directly from system env
|
||||
String endpointUrlSource = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_URL);
|
||||
if (StringUtils.isNotBlank(endpointUrlSource)) {
|
||||
@ -199,8 +217,7 @@ public class ParamUtil {
|
||||
return StringUtils.isNotBlank(endpointUrl) ? endpointUrl : "";
|
||||
}
|
||||
|
||||
endpointUrl = endpointUrl.substring(endpointUrl.indexOf("${") + 2,
|
||||
endpointUrl.lastIndexOf("}"));
|
||||
endpointUrl = endpointUrl.substring(endpointUrl.indexOf("${") + 2, endpointUrl.lastIndexOf("}"));
|
||||
int defStartOf = endpointUrl.indexOf(":");
|
||||
String defaultEndpointUrl = null;
|
||||
if (defStartOf != -1) {
|
||||
@ -208,15 +225,15 @@ public class ParamUtil {
|
||||
endpointUrl = endpointUrl.substring(0, defStartOf);
|
||||
}
|
||||
|
||||
String endpointUrlSource = TemplateUtils.stringBlankAndThenExecute(System.getProperty(endpointUrl,
|
||||
System.getenv(endpointUrl)), new Callable<String>() {
|
||||
String endpointUrlSource = TemplateUtils
|
||||
.stringBlankAndThenExecute(System.getProperty(endpointUrl, System.getenv(endpointUrl)),
|
||||
new Callable<String>() {
|
||||
@Override
|
||||
public String call() {
|
||||
return System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_URL);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (StringUtils.isBlank(endpointUrlSource)) {
|
||||
if (StringUtils.isNotBlank(defaultEndpointUrl)) {
|
||||
endpointUrl = defaultEndpointUrl;
|
||||
|
@ -13,6 +13,7 @@
|
||||
* 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;
|
||||
@ -20,11 +21,19 @@ import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Template Utils.
|
||||
*
|
||||
* @author pbting
|
||||
* @date 2019-03-04 1:31 PM
|
||||
*/
|
||||
public class TemplateUtils {
|
||||
|
||||
/**
|
||||
* Execute if string not empty.
|
||||
*
|
||||
* @param source source
|
||||
* @param runnable execute runnable
|
||||
*/
|
||||
public static void stringNotEmptyAndThenExecute(String source, Runnable runnable) {
|
||||
|
||||
if (StringUtils.isNotEmpty(source)) {
|
||||
@ -37,6 +46,13 @@ public class TemplateUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute if string empty.
|
||||
*
|
||||
* @param source empty source
|
||||
* @param callable execute callable
|
||||
* @return result
|
||||
*/
|
||||
public static String stringEmptyAndThenExecute(String source, Callable<String> callable) {
|
||||
|
||||
if (StringUtils.isEmpty(source)) {
|
||||
@ -51,6 +67,13 @@ public class TemplateUtils {
|
||||
return source.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute if string blank.
|
||||
*
|
||||
* @param source empty source
|
||||
* @param callable execute callable
|
||||
* @return result
|
||||
*/
|
||||
public static String stringBlankAndThenExecute(String source, Callable<String> callable) {
|
||||
|
||||
if (StringUtils.isBlank(source)) {
|
||||
|
@ -13,36 +13,37 @@
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Tenant Util
|
||||
* Tenant Util.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class TenantUtil {
|
||||
|
||||
private static String userTenant;
|
||||
private static final String USER_TENANT;
|
||||
|
||||
static {
|
||||
userTenant = System.getProperty("tenant.id", "");
|
||||
USER_TENANT = System.getProperty("tenant.id", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt the way ACM gets tenant on the cloud.
|
||||
* <p>
|
||||
* Note the difference between getting and getting ANS.
|
||||
* Since the processing logic on the server side is different, the default value returns differently.
|
||||
* Note the difference between getting and getting ANS. Since the processing logic on the server side is different,
|
||||
* the default value returns differently.
|
||||
* </p>
|
||||
*
|
||||
* @return
|
||||
* @return user tenant for acm
|
||||
*/
|
||||
public static String getUserTenantForAcm() {
|
||||
String tmp = userTenant;
|
||||
String tmp = USER_TENANT;
|
||||
|
||||
if (StringUtils.isBlank(userTenant)) {
|
||||
if (StringUtils.isBlank(USER_TENANT)) {
|
||||
tmp = System.getProperty("acm.namespace", "");
|
||||
}
|
||||
|
||||
@ -52,12 +53,12 @@ public class TenantUtil {
|
||||
/**
|
||||
* Adapt the way ANS gets tenant on the cloud.
|
||||
*
|
||||
* @return
|
||||
* @return user tenant for ans
|
||||
*/
|
||||
public static String getUserTenantForAns() {
|
||||
String tmp = userTenant;
|
||||
String tmp = USER_TENANT;
|
||||
|
||||
if (StringUtils.isBlank(userTenant)) {
|
||||
if (StringUtils.isBlank(USER_TENANT)) {
|
||||
tmp = System.getProperty("ans.namespace");
|
||||
}
|
||||
return tmp;
|
||||
|
@ -18,18 +18,16 @@ package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* All parameter validation tools
|
||||
* All parameter validation tools.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public final class ValidatorUtils {
|
||||
|
||||
private static final Pattern CONTEXT_PATH_MATCH = Pattern.compile("(\\/)\\1+");
|
||||
@ -38,6 +36,11 @@ public final class ValidatorUtils {
|
||||
checkContextPath(properties.getProperty(PropertyKeyConst.CONTEXT_PATH));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check context path.
|
||||
*
|
||||
* @param contextPath context path
|
||||
*/
|
||||
public static void checkContextPath(String contextPath) {
|
||||
if (contextPath == null) {
|
||||
return;
|
||||
|
@ -13,5 +13,4 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
version=${project.version}
|
||||
|
@ -13,36 +13,23 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class AppTest
|
||||
extends TestCase {
|
||||
/**
|
||||
* Create the test case
|
||||
*
|
||||
* @param testName name of the test case
|
||||
*/
|
||||
public class AppTest extends TestCase {
|
||||
|
||||
public AppTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the suite of tests being tested
|
||||
*/
|
||||
public static Test suite() {
|
||||
return new TestSuite(AppTest.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rigourous Test :-)
|
||||
*/
|
||||
public void testApp() {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
@ -30,9 +30,6 @@ import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* @author caoyixiong
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class BeatReactorTest {
|
||||
|
||||
@ -41,8 +38,6 @@ public class BeatReactorTest {
|
||||
|
||||
@Test
|
||||
public void test() throws NoSuchFieldException, IllegalAccessException, InterruptedException, NacosException {
|
||||
BeatReactor beatReactor = new BeatReactor(namingProxy);
|
||||
|
||||
BeatInfo beatInfo = new BeatInfo();
|
||||
beatInfo.setServiceName("test");
|
||||
beatInfo.setIp("11.11.11.11");
|
||||
@ -53,6 +48,7 @@ public class BeatReactorTest {
|
||||
beatInfo.setScheduled(false);
|
||||
beatInfo.setPeriod(1000L);
|
||||
|
||||
BeatReactor beatReactor = new BeatReactor(namingProxy);
|
||||
beatReactor.addBeatInfo("testService", beatInfo);
|
||||
|
||||
Assert.assertEquals(1, getActiveThread(beatReactor));
|
||||
|
@ -21,25 +21,21 @@ import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.junit.*;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Ignore
|
||||
public class ConfigTest {
|
||||
|
||||
private static ConfigService configService;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
before();
|
||||
test();
|
||||
}
|
||||
|
||||
@Before
|
||||
public static void before() throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
|
||||
@ -59,7 +55,7 @@ public class ConfigTest {
|
||||
boolean result = configService.publishConfig(dataId, group, content);
|
||||
Assert.assertTrue(result);
|
||||
|
||||
ThreadUtils.sleep(10_000);
|
||||
ThreadUtils.sleep(10000L);
|
||||
|
||||
String response = configService.getConfigAndSignListener(dataId, group, 5000, new AbstractListener() {
|
||||
@Override
|
||||
@ -71,9 +67,9 @@ public class ConfigTest {
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
System.out.println("input content");
|
||||
while (scanner.hasNextLine()){
|
||||
while (scanner.hasNextLine()) {
|
||||
String s = scanner.next();
|
||||
if (Objects.equals("exit", s)) {
|
||||
if ("exit".equals(s)) {
|
||||
scanner.close();
|
||||
return;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client;
|
||||
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
@ -27,11 +28,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* @author nkorange
|
||||
*/
|
||||
@Ignore
|
||||
public class NamingTest {
|
||||
|
||||
@ -43,8 +40,6 @@ public class NamingTest {
|
||||
properties.put(PropertyKeyConst.USERNAME, "nacos");
|
||||
properties.put(PropertyKeyConst.PASSWORD, "nacos");
|
||||
|
||||
NamingService namingService = NacosFactory.createNamingService(properties);
|
||||
|
||||
Instance instance = new Instance();
|
||||
instance.setIp("1.1.1.1");
|
||||
instance.setPort(800);
|
||||
@ -54,20 +49,19 @@ public class NamingTest {
|
||||
map.put("version", "2.0");
|
||||
instance.setMetadata(map);
|
||||
|
||||
NamingService namingService = NacosFactory.createNamingService(properties);
|
||||
namingService.registerInstance("nacos.test.1", instance);
|
||||
|
||||
ThreadUtils.sleep(5_000L);
|
||||
ThreadUtils.sleep(5000L);
|
||||
|
||||
List<Instance> list = namingService.getAllInstances("nacos.test.1");
|
||||
|
||||
System.out.println(list);
|
||||
|
||||
ThreadUtils.sleep(30_000L);
|
||||
// ExpressionSelector expressionSelector = new ExpressionSelector();
|
||||
// expressionSelector.setExpression("INSTANCE.metadata.registerSource = 'dubbo'");
|
||||
// ListView<String> serviceList = namingService.getServicesOfServer(1, 10, expressionSelector);
|
||||
ThreadUtils.sleep(30000L);
|
||||
// ExpressionSelector expressionSelector = new ExpressionSelector();
|
||||
// expressionSelector.setExpression("INSTANCE.metadata.registerSource = 'dubbo'");
|
||||
// ListView<String> serviceList = namingService.getServicesOfServer(1, 10, expressionSelector);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user