commit
c0ffb1d7e3
23
.github/workflows/maven.yml
vendored
Normal file
23
.github/workflows/maven.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
name: Java CI
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-18.04]
|
||||
java: [8, 8.0.192, 11, 11.0.9]
|
||||
fail-fast: false
|
||||
max-parallel: 2
|
||||
name: Test JDK ${{ matrix.java }}, ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- name: Test with Maven
|
||||
run: mvn test -B --file pom.xml
|
28
README.md
28
README.md
@ -1,5 +1,5 @@
|
||||
|
||||
<img src="doc/Nacos_Logo.png" width="50%" height="50%" />
|
||||
<img src="doc/Nacos_Logo.png" width="50%" syt height="50%" />
|
||||
|
||||
# Nacos: Dynamic *Na*ming and *Co*nfiguration *S*ervice
|
||||
|
||||
@ -12,25 +12,25 @@
|
||||
|
||||
Nacos (official site: [http://nacos.io](http://nacos.io)) is an easy-to-use platform designed for dynamic service discovery and configuration and service management. It helps you to build cloud native applications and microservices platform easily.
|
||||
|
||||
Service is a first-class citizen in Nacos. Nacos supports almost all type of services,for example,[Dubbo/gRPC service](https://nacos.io/en-us/docs/use-nacos-with-dubbo.html)、[Spring Cloud RESTFul service](https://nacos.io/en-us/docs/use-nacos-with-springcloud.html) or [Kubernetes service](https://nacos.io/en-us/docs/use-nacos-with-kubernetes.html).
|
||||
Service is a first-class citizen in Nacos. Nacos supports almost all type of services,for example,[Dubbo/gRPC service](https://nacos.io/en-us/docs/use-nacos-with-dubbo.html), [Spring Cloud RESTFul service](https://nacos.io/en-us/docs/use-nacos-with-springcloud.html) or [Kubernetes service](https://nacos.io/en-us/docs/use-nacos-with-kubernetes.html).
|
||||
|
||||
Nacos provides four major functions.
|
||||
|
||||
* **Service Discovery and Service Health Check**
|
||||
|
||||
Nacos makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. Nacos also provides real-time healthchecks of services to prevent sending requests to unhealthy hosts or service instance.
|
||||
Nacos makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. Nacos also provides real-time health checks of services to prevent sending requests to unhealthy hosts or service instances.
|
||||
|
||||
* **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**
|
||||
|
||||
Nacos supports weighted routing, making it easier for you to implement mid-tier load balancing, flexible routing policies, flow control, and simple DNS resolution services in the production environment within your data center. It helps you to implement DNS-based service discovery easily and prevent applications from coupling to vendor-specific service discovery APIs.
|
||||
|
||||
Nacos supports weighted routing, making it easier for you to implement mid-tier load balancing, flexible routing policies, flow control, and simple DNS resolution services in the production environment within your data center. It helps you to implement DNS-based service discovery easily and prevent applications from coupling to vendor-specific service discovery APIs.
|
||||
|
||||
* **Service and MetaData Management**
|
||||
|
||||
Nacos provides an easy-to-use service dashboard to help you manage your services metadata, configuration, kubernetes DNS, service health and metrics statistics.
|
||||
Nacos provides an easy-to-use service dashboard to help you manage your services metadata, configuration, kubernetes DNS, service health and metrics statistics.
|
||||
|
||||
|
||||
## Quick Start
|
||||
@ -38,10 +38,10 @@ It is super easy to get started with your first project.
|
||||
|
||||
#### Step 1: Download the binary package
|
||||
|
||||
You can download the package from the [latest stable release](https://github.com/alibaba/nacos/releases).
|
||||
You can download the package from the [latest stable release](https://github.com/alibaba/nacos/releases).
|
||||
|
||||
Take release nacos-server-1.0.0.zip for example.
|
||||
```
|
||||
Take release `nacos-server-1.0.0.zip` for example:
|
||||
```sh
|
||||
unzip nacos-server-1.0.0.zip
|
||||
cd nacos/bin
|
||||
```
|
||||
@ -49,11 +49,11 @@ cd nacos/bin
|
||||
#### Step 2: Start Server
|
||||
|
||||
On the **Linux/Unix/Mac** platform, run the following command to start server with standalone mode:
|
||||
```
|
||||
```sh
|
||||
sh startup.sh -m standalone
|
||||
```
|
||||
|
||||
On the **Windows** platform, run the following command to start server with standalone mode. Alternatively, you can also double-click the startup.cmd to run NacosServer.
|
||||
On the **Windows** platform, run the following command to start server with standalone mode. Alternatively, you can also double-click the `startup.cmd` to run NacosServer.
|
||||
```
|
||||
cmd startup.cmd -m standalone
|
||||
```
|
||||
@ -74,7 +74,7 @@ For more details, see [quick-start.](https://nacos.io/en-us/docs/quick-start.htm
|
||||
|
||||
You can view the full documentation from the [Nacos website](https://nacos.io/en-us/docs/what-is-nacos.html).
|
||||
|
||||
All the latest and long-term notice can also be found here from [Github notice issue](https://github.com/alibaba/nacos/labels/notice)
|
||||
All the latest and long-term notice can also be found here from [Github notice issue](https://github.com/alibaba/nacos/labels/notice).
|
||||
|
||||
|
||||
## Contributing
|
||||
@ -84,7 +84,7 @@ Contributors are welcomed to join Nacos project. Please check [CONTRIBUTING](./C
|
||||
## Other Related Project Repositories
|
||||
|
||||
* [nacos-spring-project](https://github.com/nacos-group/nacos-spring-project) provides the integration functionality for Spring.
|
||||
* [nacos-group](https://github.com/nacos-group) is the reposity that hosts the eco tools for Nacos, such as SDK, synchronization tool, etc.
|
||||
* [nacos-group](https://github.com/nacos-group) is the repository that hosts the eco tools for Nacos, such as SDK, synchronization tool, etc.
|
||||
* [spring-cloud-alibaba](https://github.com/spring-cloud-incubator/spring-cloud-alibaba) provides the one-stop solution for application development over Alibaba middleware which includes Nacos.
|
||||
|
||||
## Contact
|
||||
|
@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.4.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -16,10 +16,10 @@
|
||||
|
||||
package com.alibaba.nacos.address.auth;
|
||||
|
||||
import com.alibaba.nacos.core.auth.AccessException;
|
||||
import com.alibaba.nacos.core.auth.AuthManager;
|
||||
import com.alibaba.nacos.core.auth.Permission;
|
||||
import com.alibaba.nacos.core.auth.User;
|
||||
import com.alibaba.nacos.auth.AuthManager;
|
||||
import com.alibaba.nacos.auth.exception.AccessException;
|
||||
import com.alibaba.nacos.auth.model.Permission;
|
||||
import com.alibaba.nacos.auth.model.User;
|
||||
|
||||
/**
|
||||
* Address server auth manager.
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.nacos.address.configuration;
|
||||
|
||||
import com.alibaba.nacos.address.auth.AddressServerAuthManager;
|
||||
import com.alibaba.nacos.core.auth.AuthManager;
|
||||
import com.alibaba.nacos.auth.AuthManager;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.4.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -24,6 +24,7 @@ package com.alibaba.nacos.api.common;
|
||||
* <li> Global and common code starts with 10001.
|
||||
* <li> Naming module code starts with 20001.
|
||||
* <li> Config module code starts with 30001.
|
||||
* <li> Core module code starts with 40001.
|
||||
*
|
||||
* @author nkorange
|
||||
* @since 1.2.0
|
||||
|
@ -167,4 +167,10 @@ public interface NamingMaintainService {
|
||||
*/
|
||||
void updateService(Service service, AbstractSelector selector) throws NacosException;
|
||||
|
||||
/**
|
||||
* Shutdown the resource service.
|
||||
*
|
||||
* @throws NacosException exception.
|
||||
*/
|
||||
void shutDown() throws NacosException;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package com.alibaba.nacos.api.naming.pojo;
|
||||
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
|
||||
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Tcp;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -31,7 +32,9 @@ import java.util.Map;
|
||||
* @author nkorange
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:abbreviationaswordinname")
|
||||
public class Cluster {
|
||||
public class Cluster implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7196138840047197271L;
|
||||
|
||||
/**
|
||||
* Name of belonging service.
|
||||
|
@ -22,6 +22,7 @@ import com.alibaba.nacos.api.utils.StringUtils;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -33,7 +34,9 @@ import static com.alibaba.nacos.api.common.Constants.NUMBER_PATTERN;
|
||||
* @author nkorange
|
||||
*/
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class Instance {
|
||||
public class Instance implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -742906310567291979L;
|
||||
|
||||
/**
|
||||
* unique id of this instance.
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.api.naming.pojo;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -29,7 +30,9 @@ import java.util.Map;
|
||||
*
|
||||
* @author nkorange
|
||||
*/
|
||||
public class Service {
|
||||
public class Service implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3470985546826874460L;
|
||||
|
||||
/**
|
||||
* service name.
|
||||
|
@ -25,6 +25,8 @@ import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Abstract health checker.
|
||||
*
|
||||
@ -34,7 +36,9 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
|
||||
@JsonSubTypes({@JsonSubTypes.Type(name = Http.TYPE, value = Http.class),
|
||||
@JsonSubTypes.Type(name = Mysql.TYPE, value = Mysql.class),
|
||||
@JsonSubTypes.Type(name = Tcp.TYPE, value = Tcp.class)})
|
||||
public abstract class AbstractHealthChecker implements Cloneable {
|
||||
public abstract class AbstractHealthChecker implements Cloneable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3848305577423336421L;
|
||||
|
||||
@JsonIgnore
|
||||
protected final String type;
|
||||
|
@ -28,6 +28,9 @@ import com.alibaba.nacos.api.utils.StringUtils;
|
||||
public class NamingUtils {
|
||||
|
||||
public static String getGroupedName(final String serviceName, final String groupName) {
|
||||
if (StringUtils.isBlank(serviceName)) {
|
||||
throw new IllegalArgumentException("Param 'serviceName' is illegal, serviceName is blank");
|
||||
}
|
||||
final String resultGroupedName = groupName + Constants.SERVICE_INFO_SPLITER + serviceName;
|
||||
return resultGroupedName.intern();
|
||||
}
|
||||
@ -51,4 +54,25 @@ public class NamingUtils {
|
||||
}
|
||||
return serviceNameWithGroup.split(Constants.SERVICE_INFO_SPLITER)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* check combineServiceName format. the serviceName can't be blank. some relational logic in {@link
|
||||
* com.alibaba.nacos.naming.web.DistroFilter#doFilter}, it will handle combineServiceName in some case, you should
|
||||
* know it.
|
||||
* <pre>
|
||||
* serviceName = "@@"; the length = 0; illegal
|
||||
* serviceName = "group@@"; the length = 1; illegal
|
||||
* serviceName = "@@serviceName"; the length = 2; legal
|
||||
* serviceName = "group@@serviceName"; the length = 2; legal
|
||||
* </pre>
|
||||
*
|
||||
* @param combineServiceName such as: groupName@@serviceName
|
||||
*/
|
||||
public static void checkServiceNameFormat(String combineServiceName) {
|
||||
String[] split = combineServiceName.split(Constants.SERVICE_INFO_SPLITER);
|
||||
if (split.length <= 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"Param 'serviceName' is illegal, it should be format as 'groupName@@serviceName'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Abstract selector that only contains a type.
|
||||
*
|
||||
@ -27,7 +29,9 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
|
||||
* @since 0.7.0
|
||||
*/
|
||||
@JsonTypeInfo(use = Id.NAME, property = "type", defaultImpl = NoneSelector.class)
|
||||
public abstract class AbstractSelector {
|
||||
public abstract class AbstractSelector implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4530233098102379229L;
|
||||
|
||||
/**
|
||||
* The type of this selector, each child class should announce its own unique type.
|
||||
|
87
auth/pom.xml
Normal file
87
auth/pom.xml
Normal file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>nacos-auth</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>nacos-auth ${project.version}</name>
|
||||
<url>http://nacos.io</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>nacos-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>nacos-sys</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-impl</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -14,12 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth;
|
||||
|
||||
import com.alibaba.nacos.auth.exception.AccessException;
|
||||
import com.alibaba.nacos.auth.model.Permission;
|
||||
import com.alibaba.nacos.auth.model.User;
|
||||
|
||||
/**
|
||||
* Access control entry. Can be extended by 3rd party implementations.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public interface AuthManager {
|
@ -14,8 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.annotation;
|
||||
|
||||
import com.alibaba.nacos.auth.common.ActionTypes;
|
||||
import com.alibaba.nacos.auth.parser.DefaultResourceParser;
|
||||
import com.alibaba.nacos.auth.parser.ResourceParser;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@ -25,6 +28,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* Annotation indicating that the annotated request should be authorized.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
@ -14,12 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.common;
|
||||
|
||||
/**
|
||||
* Resource action type definitions.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public enum ActionTypes {
|
@ -14,18 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.common;
|
||||
|
||||
import com.alibaba.nacos.common.JustForTest;
|
||||
import com.alibaba.nacos.core.env.ReloadableConfigs;
|
||||
import com.alibaba.nacos.sys.utils.ApplicationUtils;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -33,24 +30,26 @@ import java.util.Objects;
|
||||
* Auth related configurations.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Component
|
||||
@Configuration
|
||||
public class AuthConfigs {
|
||||
|
||||
@JustForTest
|
||||
private static Boolean cachingEnabled = null;
|
||||
|
||||
@Autowired
|
||||
private ReloadableConfigs reloadableConfigs;
|
||||
|
||||
/**
|
||||
* secret key.
|
||||
*/
|
||||
@Value("${nacos.core.auth.default.token.secret.key:}")
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* secret key byte array.
|
||||
*/
|
||||
private byte[] secretKeyBytes;
|
||||
|
||||
/**
|
||||
* Token validity time(seconds).
|
||||
*/
|
||||
@ -63,8 +62,11 @@ public class AuthConfigs {
|
||||
@Value("${nacos.core.auth.system.type:}")
|
||||
private String nacosAuthSystemType;
|
||||
|
||||
public String getSecretKey() {
|
||||
return secretKey;
|
||||
public byte[] getSecretKeyBytes() {
|
||||
if (secretKeyBytes == null) {
|
||||
secretKeyBytes = Decoders.BASE64.decode(secretKey);
|
||||
}
|
||||
return secretKeyBytes;
|
||||
}
|
||||
|
||||
public long getTokenValidityInSeconds() {
|
||||
@ -87,7 +89,7 @@ public class AuthConfigs {
|
||||
return BooleanUtils.toBoolean(enabled);
|
||||
}
|
||||
return BooleanUtils
|
||||
.toBoolean(reloadableConfigs.getProperties().getProperty("nacos.core.auth.enabled", "false"));
|
||||
.toBoolean(ApplicationUtils.getProperty("nacos.core.auth.enabled", "false"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,28 +102,11 @@ public class AuthConfigs {
|
||||
return cachingEnabled;
|
||||
}
|
||||
return BooleanUtils
|
||||
.toBoolean(reloadableConfigs.getProperties().getProperty("nacos.core.auth.caching.enabled", "true"));
|
||||
.toBoolean(ApplicationUtils.getProperty("nacos.core.auth.caching.enabled", "true"));
|
||||
}
|
||||
|
||||
@JustForTest
|
||||
public static void setCachingEnabled(boolean cachingEnabled) {
|
||||
AuthConfigs.cachingEnabled = cachingEnabled;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean authFilterRegistration() {
|
||||
FilterRegistrationBean<AuthFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(authFilter());
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setName("authFilter");
|
||||
registration.setOrder(6);
|
||||
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthFilter authFilter() {
|
||||
return new AuthFilter();
|
||||
}
|
||||
|
||||
}
|
@ -14,12 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.common;
|
||||
|
||||
/**
|
||||
* Types of all auth implementations.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public enum AuthSystemTypes {
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.exception;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
|
||||
@ -22,6 +22,7 @@ import com.alibaba.nacos.api.exception.NacosException;
|
||||
* Exception to be thrown if authorization is failed.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class AccessException extends NacosException {
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -22,6 +22,7 @@ import java.io.Serializable;
|
||||
* Permission to auth.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class Permission implements Serializable {
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -22,6 +22,7 @@ import java.io.Serializable;
|
||||
* Resource used in authorization.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class Resource implements Serializable {
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -22,6 +22,7 @@ import java.io.Serializable;
|
||||
* User information in authorization.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class User implements Serializable {
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.parser;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@ -22,6 +22,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
* Default resource parser.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class DefaultResourceParser implements ResourceParser {
|
@ -14,12 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
package com.alibaba.nacos.auth.parser;
|
||||
|
||||
/**
|
||||
* Resource parser.
|
||||
*
|
||||
* @author nkorange
|
||||
* @author mai.jh
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public interface ResourceParser {
|
@ -19,7 +19,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.4.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -49,14 +49,13 @@ import java.net.ConnectException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
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.
|
||||
@ -94,9 +93,9 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
|
||||
Query query = Query.newInstance().initParams(paramValues);
|
||||
HttpRestResult<String> result = NACOS_RESTTEMPLATE
|
||||
.get(getUrl(currentServerAddr, path), httpConfig, newHeaders, paramValues, String.class);
|
||||
.get(getUrl(currentServerAddr, path), httpConfig, newHeaders, query, String.class);
|
||||
if (isFail(result)) {
|
||||
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
|
||||
serverListMgr.getCurrentServerAddr(), result.getCode());
|
||||
@ -152,8 +151,7 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
HttpRestResult<String> result = NACOS_RESTTEMPLATE
|
||||
.postForm(getUrl(currentServerAddr, path), httpConfig, newHeaders,
|
||||
new HashMap<String, String>(0), paramValues, String.class);
|
||||
.postForm(getUrl(currentServerAddr, path), httpConfig, newHeaders, paramValues, String.class);
|
||||
|
||||
if (isFail(result)) {
|
||||
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", currentServerAddr,
|
||||
@ -207,8 +205,9 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
Query query = Query.newInstance().initParams(paramValues);
|
||||
HttpRestResult<String> result = NACOS_RESTTEMPLATE
|
||||
.delete(getUrl(currentServerAddr, path), httpConfig, newHeaders, paramValues, String.class);
|
||||
.delete(getUrl(currentServerAddr, path), httpConfig, newHeaders, query, String.class);
|
||||
if (isFail(result)) {
|
||||
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
|
||||
serverListMgr.getCurrentServerAddr(), result.getCode());
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.nacos.client.config.impl;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.client.identify.Base64;
|
||||
import com.alibaba.nacos.common.codec.Base64;
|
||||
import com.alibaba.nacos.client.identify.CredentialService;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
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.common.utils.IpUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
@ -190,7 +190,7 @@ public class ParamUtils {
|
||||
}
|
||||
String[] ipsArr = betaIps.split(",");
|
||||
for (String ip : ipsArr) {
|
||||
if (!IpUtil.isIpv4(ip)) {
|
||||
if (!IpUtils.isIpv4(ip)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ package com.alibaba.nacos.client.logging;
|
||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Abstract nacos logging.
|
||||
*
|
||||
@ -31,13 +33,13 @@ public abstract class AbstractNacosLogging {
|
||||
|
||||
private static final String NACOS_LOGGING_DEFAULT_CONFIG_ENABLED_PROPERTY = "nacos.logging.default.config.enabled";
|
||||
|
||||
private static final String NACOS_LOGGING_PATH_PROPERTY = "nacos.logging.path";
|
||||
private static final String NACOS_LOGGING_PATH_PROPERTY = "JM.LOG.PATH";
|
||||
|
||||
static {
|
||||
String loggingPath = System.getProperty(NACOS_LOGGING_PATH_PROPERTY);
|
||||
if (StringUtils.isBlank(loggingPath)) {
|
||||
String userHome = System.getProperty("user.home");
|
||||
System.setProperty(NACOS_LOGGING_PATH_PROPERTY, userHome + "/logs/nacos");
|
||||
System.setProperty(NACOS_LOGGING_PATH_PROPERTY, userHome + File.separator + "logs");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,4 +173,8 @@ public class NacosNamingMaintainService implements NamingMaintainService {
|
||||
serverProxy.updateService(service, selector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() throws NacosException {
|
||||
serverProxy.shutdown();
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import com.alibaba.nacos.client.utils.ValidatorUtils;
|
||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -151,9 +152,13 @@ public class NacosNamingService implements NamingService {
|
||||
}
|
||||
|
||||
private void initCacheDir() {
|
||||
cacheDir = System.getProperty("com.alibaba.nacos.naming.cache.dir");
|
||||
if (StringUtils.isEmpty(cacheDir)) {
|
||||
cacheDir = System.getProperty("user.home") + "/nacos/naming/" + namespace;
|
||||
String jmSnapshotPath = System.getProperty("JM.SNAPSHOT.PATH");
|
||||
if (!StringUtils.isBlank(jmSnapshotPath)) {
|
||||
cacheDir = jmSnapshotPath + File.separator + "nacos" + File.separator + "naming"
|
||||
+ File.separator + namespace;
|
||||
} else {
|
||||
cacheDir = System.getProperty("user.home") + File.separator + "nacos" + File.separator + "naming"
|
||||
+ File.separator + namespace;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,11 +143,12 @@ public class ConcurrentDiskUtil {
|
||||
}
|
||||
} while (null == lock);
|
||||
|
||||
ByteBuffer sendBuffer = ByteBuffer.wrap(content.getBytes(charsetName));
|
||||
byte[] contentBytes = content.getBytes(charsetName);
|
||||
ByteBuffer sendBuffer = ByteBuffer.wrap(contentBytes);
|
||||
while (sendBuffer.hasRemaining()) {
|
||||
channel.write(sendBuffer);
|
||||
}
|
||||
channel.truncate(content.length());
|
||||
channel.truncate(contentBytes.length);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IOException("file not exist");
|
||||
} finally {
|
||||
|
@ -25,6 +25,7 @@ import com.alibaba.nacos.client.naming.beat.BeatInfo;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatReactor;
|
||||
import com.alibaba.nacos.client.naming.cache.DiskCache;
|
||||
import com.alibaba.nacos.client.naming.net.NamingProxy;
|
||||
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
@ -296,6 +297,14 @@ public class HostReactor implements Closeable {
|
||||
return serviceInfoMap.get(serviceObj.getKey());
|
||||
}
|
||||
|
||||
private void updateServiceNow(String serviceName, String clusters) {
|
||||
try {
|
||||
updateService(serviceName, clusters);
|
||||
} catch (NacosException e) {
|
||||
NAMING_LOGGER.error("[NA] failed to update serviceName: " + serviceName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule update if absent.
|
||||
*
|
||||
@ -323,7 +332,7 @@ public class HostReactor implements Closeable {
|
||||
* @param serviceName service name
|
||||
* @param clusters clusters
|
||||
*/
|
||||
public void updateServiceNow(String serviceName, String clusters) {
|
||||
public void updateService(String serviceName, String clusters) throws NacosException {
|
||||
ServiceInfo oldService = getServiceInfo0(serviceName, clusters);
|
||||
try {
|
||||
|
||||
@ -332,8 +341,6 @@ public class HostReactor implements Closeable {
|
||||
if (StringUtils.isNotEmpty(result)) {
|
||||
processServiceJson(result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NAMING_LOGGER.error("[NA] failed to update serviceName: " + serviceName, e);
|
||||
} finally {
|
||||
if (oldService != null) {
|
||||
synchronized (oldService) {
|
||||
@ -375,26 +382,42 @@ public class HostReactor implements Closeable {
|
||||
|
||||
private final String serviceName;
|
||||
|
||||
/**
|
||||
* the fail situation. 1:can't connect to server 2:serviceInfo's hosts is empty
|
||||
*/
|
||||
private int failCount = 0;
|
||||
|
||||
public UpdateTask(String serviceName, String clusters) {
|
||||
this.serviceName = serviceName;
|
||||
this.clusters = clusters;
|
||||
}
|
||||
|
||||
private void incFailCount() {
|
||||
int limit = 6;
|
||||
if (failCount == limit) {
|
||||
return;
|
||||
}
|
||||
failCount++;
|
||||
}
|
||||
|
||||
private void resetFailCount() {
|
||||
failCount = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long delayTime = -1;
|
||||
long delayTime = DEFAULT_DELAY;
|
||||
|
||||
try {
|
||||
ServiceInfo serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters));
|
||||
|
||||
if (serviceObj == null) {
|
||||
updateServiceNow(serviceName, clusters);
|
||||
delayTime = DEFAULT_DELAY;
|
||||
updateService(serviceName, clusters);
|
||||
return;
|
||||
}
|
||||
|
||||
if (serviceObj.getLastRefTime() <= lastRefTime) {
|
||||
updateServiceNow(serviceName, clusters);
|
||||
updateService(serviceName, clusters);
|
||||
serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters));
|
||||
} else {
|
||||
// if serviceName already updated by push, we should not override it
|
||||
@ -410,17 +433,18 @@ public class HostReactor implements Closeable {
|
||||
NAMING_LOGGER.info("update task is stopped, service:" + serviceName + ", clusters:" + clusters);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(serviceObj.getHosts())) {
|
||||
incFailCount();
|
||||
return;
|
||||
}
|
||||
delayTime = serviceObj.getCacheMillis();
|
||||
|
||||
resetFailCount();
|
||||
} catch (Throwable e) {
|
||||
incFailCount();
|
||||
NAMING_LOGGER.warn("[NA] failed to update serviceName: " + serviceName, e);
|
||||
} finally {
|
||||
if (delayTime > 0) {
|
||||
executor.schedule(this, delayTime, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
executor.schedule(this, Math.min(delayTime << failCount, DEFAULT_DELAY * 60), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,9 @@ public class PushReceiver implements Runnable, Closeable {
|
||||
udpSocket.send(new DatagramPacket(ack.getBytes(UTF_8), ack.getBytes(UTF_8).length,
|
||||
packet.getSocketAddress()));
|
||||
} catch (Exception e) {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
NAMING_LOGGER.error("[NA] error while receiving push data", e);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package com.alibaba.nacos.client.naming.net;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.tls.TlsSystemConfig;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
@ -53,7 +54,7 @@ public class HttpClient {
|
||||
|
||||
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");
|
||||
private static final boolean ENABLE_HTTPS = Boolean.getBoolean(TlsSystemConfig.TLS_ENABLE);
|
||||
|
||||
static {
|
||||
// limit max redirection
|
||||
|
@ -23,6 +23,7 @@ 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.tls.TlsSystemConfig;
|
||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@ -40,7 +41,7 @@ public class NamingHttpClientManager implements Closeable {
|
||||
|
||||
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 boolean ENABLE_HTTPS = Boolean.getBoolean(TlsSystemConfig.TLS_ENABLE);
|
||||
|
||||
private static final int MAX_REDIRECTS = 5;
|
||||
|
||||
@ -85,7 +86,7 @@ public class NamingHttpClientManager implements Closeable {
|
||||
return HttpClientConfig.builder().setConTimeOutMillis(CON_TIME_OUT_MILLIS)
|
||||
.setReadTimeOutMillis(READ_TIME_OUT_MILLIS).setMaxRedirects(MAX_REDIRECTS).build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Logger assignLogger() {
|
||||
return NAMING_LOGGER;
|
||||
|
@ -596,7 +596,7 @@ public class NamingProxy implements Closeable {
|
||||
|
||||
try {
|
||||
HttpRestResult<String> restResult = nacosRestTemplate
|
||||
.exchangeForm(url, header, params, body, method, String.class);
|
||||
.exchangeForm(url, header, Query.newInstance().initParams(params), body, method, String.class);
|
||||
end = System.currentTimeMillis();
|
||||
|
||||
MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(restResult.getCode()))
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.client.naming.utils;
|
||||
|
||||
import com.alibaba.nacos.client.identify.Base64;
|
||||
import com.alibaba.nacos.common.codec.Base64;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
@ -21,6 +21,7 @@ import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||
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.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
@ -138,7 +139,7 @@ public class SecurityProxy {
|
||||
}
|
||||
try {
|
||||
HttpRestResult<String> restResult = nacosRestTemplate
|
||||
.postForm(url, Header.EMPTY, params, bodyMap, String.class);
|
||||
.postForm(url, Header.EMPTY, Query.newInstance().initParams(params), bodyMap, String.class);
|
||||
if (!restResult.ok()) {
|
||||
SECURITY_LOGGER.error("login failed: {}", JacksonUtils.toJson(restResult));
|
||||
return false;
|
||||
|
@ -20,9 +20,9 @@ import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.SystemPropertyKeyConst;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.VersionUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.regex.Pattern;
|
||||
@ -80,19 +80,7 @@ public class ParamUtil {
|
||||
}
|
||||
LOGGER.info("[settings] [http-client] connect timeout:{}", connectTimeout);
|
||||
|
||||
try {
|
||||
InputStream in = ValidatorUtils.class.getClassLoader().getResourceAsStream("application.properties");
|
||||
Properties props = new Properties();
|
||||
props.load(in);
|
||||
String val = null;
|
||||
val = props.getProperty("version");
|
||||
if (val != null) {
|
||||
clientVersion = val;
|
||||
}
|
||||
LOGGER.info("NACOS_CLIENT_VERSION: {}", clientVersion);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("[500] read application.properties", e);
|
||||
}
|
||||
clientVersion = VersionUtils.version;
|
||||
|
||||
try {
|
||||
perTaskConfigSize = Double.valueOf(System.getProperty("PER_TASK_CONFIG_SIZE", "3000"));
|
||||
|
@ -1,16 +0,0 @@
|
||||
#
|
||||
# Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
version=${project.version}
|
@ -17,8 +17,8 @@
|
||||
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<RollingFile name="CONFIG_LOG_FILE" fileName="${sys:nacos.logging.path}/config.log"
|
||||
filePattern="${sys:nacos.logging.path}/config.log.%d{yyyy-MM-dd}.%i">
|
||||
<RollingFile name="CONFIG_LOG_FILE" fileName="${sys:JM.LOG.PATH}/nacos/config.log"
|
||||
filePattern="${sys:JM.LOG.PATH}/nacos/config.log.%d{yyyy-MM-dd}.%i">
|
||||
<PatternLayout>
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n</Pattern>
|
||||
</PatternLayout>
|
||||
@ -31,8 +31,8 @@
|
||||
<DefaultRolloverStrategy max="${sys:JM.LOG.RETAIN.COUNT:-7}"/>
|
||||
</RollingFile>
|
||||
|
||||
<RollingFile name="NAMING_LOG_FILE" fileName="${sys:nacos.logging.path}/naming.log"
|
||||
filePattern="${sys:nacos.logging.path}/naming.log.%d{yyyy-MM-dd}.%i">
|
||||
<RollingFile name="NAMING_LOG_FILE" fileName="${sys:JM.LOG.PATH}/nacos/naming.log"
|
||||
filePattern="${sys:JM.LOG.PATH}/nacos/naming.log.%d{yyyy-MM-dd}.%i">
|
||||
<PatternLayout>
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n</Pattern>
|
||||
</PatternLayout>
|
||||
|
@ -19,10 +19,10 @@
|
||||
<contextName>nacos</contextName>
|
||||
|
||||
<appender name="CONFIG_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${nacos.logging.path}/config.log</file>
|
||||
<file>${JM.LOG.PATH}/nacos/config.log</file>
|
||||
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
|
||||
<fileNamePattern>${nacos.logging.path}/config.log.%i</fileNamePattern>
|
||||
<fileNamePattern>${JM.LOG.PATH}/nacos/config.log.%i</fileNamePattern>
|
||||
<maxIndex>${JM.LOG.RETAIN.COUNT:-7}</maxIndex>
|
||||
</rollingPolicy>
|
||||
|
||||
@ -36,10 +36,10 @@
|
||||
</appender>
|
||||
|
||||
<appender name="NAMING_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${nacos.logging.path}/naming.log</file>
|
||||
<file>${JM.LOG.PATH}/nacos/naming.log</file>
|
||||
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
|
||||
<fileNamePattern>${nacos.logging.path}/naming.log.%i</fileNamePattern>
|
||||
<fileNamePattern>${JM.LOG.PATH}/nacos/naming.log.%i</fileNamePattern>
|
||||
<maxIndex>${JM.LOG.RETAIN.COUNT:-7}</maxIndex>
|
||||
</rollingPolicy>
|
||||
|
||||
|
@ -20,6 +20,7 @@ import com.alibaba.nacos.api.NacosFactory;
|
||||
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.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
@ -28,7 +29,7 @@ import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@Ignore
|
||||
public class ConfigTest {
|
||||
@ -36,7 +37,7 @@ public class ConfigTest {
|
||||
private static ConfigService configService;
|
||||
|
||||
@Before
|
||||
public static void before() throws Exception {
|
||||
public void before() throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
|
||||
configService = NacosFactory.createConfigService(properties);
|
||||
@ -48,7 +49,8 @@ public class ConfigTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void test() throws Exception {
|
||||
public void test() throws Exception {
|
||||
// set config
|
||||
final String dataId = "lessspring";
|
||||
final String group = "lessspring";
|
||||
final String content = "lessspring-" + System.currentTimeMillis();
|
||||
@ -57,24 +59,46 @@ public class ConfigTest {
|
||||
|
||||
ThreadUtils.sleep(10000L);
|
||||
|
||||
// set change listener
|
||||
final AtomicBoolean hasListener = new AtomicBoolean(false);
|
||||
final AtomicBoolean hasChangedCallback = new AtomicBoolean(false);
|
||||
final String[] changedTmpContent = {""};
|
||||
String response = configService.getConfigAndSignListener(dataId, group, 5000, new AbstractListener() {
|
||||
@Override
|
||||
public void receiveConfigInfo(String configInfo) {
|
||||
System.err.println(configInfo);
|
||||
System.out.println("receiveConfigInfo:" + configInfo);
|
||||
changedTmpContent[0] = configInfo;
|
||||
hasChangedCallback.set(true);
|
||||
}
|
||||
});
|
||||
hasListener.set(true);
|
||||
Assert.assertEquals(content, response);
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
System.out.println("input content");
|
||||
while (scanner.hasNextLine()) {
|
||||
String s = scanner.next();
|
||||
if ("exit".equals(s)) {
|
||||
scanner.close();
|
||||
return;
|
||||
// new thread to publish config
|
||||
final String newRawContent = "nacosnewconfig-" + System.currentTimeMillis();
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (hasListener.get()) {
|
||||
try {
|
||||
configService.publishConfig(dataId, group, newRawContent);
|
||||
hasListener.set(false);
|
||||
break;
|
||||
} catch (NacosException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
configService.publishConfig(dataId, group, s);
|
||||
}
|
||||
}).start();
|
||||
|
||||
// spin
|
||||
do {
|
||||
if (hasChangedCallback.get()) {
|
||||
System.out.println(newRawContent + "==> " + changedTmpContent[0]);
|
||||
Assert.assertEquals(newRawContent, changedTmpContent[0]);
|
||||
break;
|
||||
}
|
||||
} while (!hasChangedCallback.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ public class DiskCacheTest {
|
||||
instance.setIp("1.1.1.1");
|
||||
instance.setPort(1234);
|
||||
instance.setServiceName("testName");
|
||||
instance.addMetadata("chinese", "中文");
|
||||
serviceInfo.setHosts(Collections.singletonList(instance));
|
||||
}
|
||||
|
||||
@ -87,9 +88,10 @@ public class DiskCacheTest {
|
||||
}
|
||||
|
||||
private void assertInstance(Instance actual, Instance expected) {
|
||||
assertEquals(actual.getServiceName(), actual.getServiceName());
|
||||
assertEquals(actual.getClusterName(), actual.getClusterName());
|
||||
assertEquals(actual.getIp(), actual.getIp());
|
||||
assertEquals(actual.getPort(), actual.getPort());
|
||||
assertEquals(actual.getServiceName(), expected.getServiceName());
|
||||
assertEquals(actual.getClusterName(), expected.getClusterName());
|
||||
assertEquals(actual.getIp(), expected.getIp());
|
||||
assertEquals(actual.getPort(), expected.getPort());
|
||||
assertEquals(actual.getMetadata(), expected.getMetadata());
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.4.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.4.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.identify;
|
||||
package com.alibaba.nacos.common.codec;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.http.client.request.DefaultHttpClientRequest;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
|
||||
/**
|
||||
* apache http client factory implements.
|
||||
*
|
||||
* @author mai.jh
|
||||
*/
|
||||
public abstract class AbstractApacheHttpClientFactory extends AbstractHttpClientFactory {
|
||||
|
||||
@Override
|
||||
public final NacosRestTemplate createNacosRestTemplate() {
|
||||
final HttpClientConfig originalRequestConfig = buildHttpClientConfig();
|
||||
final RequestConfig requestConfig = getRequestConfig();
|
||||
return new NacosRestTemplate(assignLogger(), new DefaultHttpClientRequest(
|
||||
HttpClients.custom().setDefaultRequestConfig(requestConfig)
|
||||
.setUserAgent(originalRequestConfig.getUserAgent())
|
||||
.setMaxConnTotal(originalRequestConfig.getMaxConnTotal())
|
||||
.setMaxConnPerRoute(originalRequestConfig.getMaxConnPerRoute())
|
||||
.setConnectionTimeToLive(originalRequestConfig.getConnTimeToLive(),
|
||||
originalRequestConfig.getConnTimeToLiveTimeUnit()).build()));
|
||||
}
|
||||
|
||||
}
|
@ -20,10 +20,22 @@ import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.http.client.request.DefaultAsyncHttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.client.request.JdkHttpClientRequest;
|
||||
import com.alibaba.nacos.common.tls.SelfHostnameVerifier;
|
||||
import com.alibaba.nacos.common.tls.TlsFileWatcher;
|
||||
import com.alibaba.nacos.common.tls.TlsHelper;
|
||||
import com.alibaba.nacos.common.tls.TlsSystemConfig;
|
||||
import com.alibaba.nacos.common.utils.BiConsumer;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* AbstractHttpClientFactory Let the creator only specify the http client config.
|
||||
*
|
||||
@ -32,25 +44,83 @@ import org.slf4j.Logger;
|
||||
public abstract class AbstractHttpClientFactory implements HttpClientFactory {
|
||||
|
||||
@Override
|
||||
public final NacosRestTemplate createNacosRestTemplate() {
|
||||
public NacosRestTemplate createNacosRestTemplate() {
|
||||
HttpClientConfig httpClientConfig = buildHttpClientConfig();
|
||||
return new NacosRestTemplate(assignLogger(), new JdkHttpClientRequest(httpClientConfig));
|
||||
final JdkHttpClientRequest clientRequest = new JdkHttpClientRequest(httpClientConfig);
|
||||
|
||||
// enable ssl
|
||||
initTls(new BiConsumer<SSLContext, HostnameVerifier>() {
|
||||
@Override
|
||||
public void accept(SSLContext sslContext, HostnameVerifier hostnameVerifier) {
|
||||
clientRequest.setSSLContext(loadSSLContext());
|
||||
clientRequest.replaceSSLHostnameVerifier(hostnameVerifier);
|
||||
}
|
||||
}, new TlsFileWatcher.FileChangeListener() {
|
||||
@Override
|
||||
public void onChanged(String filePath) {
|
||||
clientRequest.setSSLContext(loadSSLContext());
|
||||
}
|
||||
});
|
||||
|
||||
return new NacosRestTemplate(assignLogger(), clientRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final NacosAsyncRestTemplate createNacosAsyncRestTemplate() {
|
||||
RequestConfig requestConfig = getRequestConfig();
|
||||
public NacosAsyncRestTemplate createNacosAsyncRestTemplate() {
|
||||
final HttpClientConfig originalRequestConfig = buildHttpClientConfig();
|
||||
final RequestConfig requestConfig = getRequestConfig();
|
||||
return new NacosAsyncRestTemplate(assignLogger(), new DefaultAsyncHttpClientRequest(
|
||||
HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig).build()));
|
||||
HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig)
|
||||
.setMaxConnTotal(originalRequestConfig.getMaxConnTotal())
|
||||
.setMaxConnPerRoute(originalRequestConfig.getMaxConnPerRoute())
|
||||
.setUserAgent(originalRequestConfig.getUserAgent()).build()));
|
||||
}
|
||||
|
||||
private RequestConfig getRequestConfig() {
|
||||
protected RequestConfig getRequestConfig() {
|
||||
HttpClientConfig httpClientConfig = buildHttpClientConfig();
|
||||
return RequestConfig.custom().setConnectTimeout(httpClientConfig.getConTimeOutMillis())
|
||||
.setSocketTimeout(httpClientConfig.getReadTimeOutMillis())
|
||||
.setConnectionRequestTimeout(httpClientConfig.getConnectionRequestTimeout())
|
||||
.setMaxRedirects(httpClientConfig.getMaxRedirects()).build();
|
||||
}
|
||||
|
||||
protected void initTls(BiConsumer<SSLContext, HostnameVerifier> initTlsBiFunc,
|
||||
TlsFileWatcher.FileChangeListener tlsChangeListener) {
|
||||
if (!TlsSystemConfig.tlsEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
final HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
|
||||
final SelfHostnameVerifier selfHostnameVerifier = new SelfHostnameVerifier(hv);
|
||||
|
||||
initTlsBiFunc.accept(loadSSLContext(), selfHostnameVerifier);
|
||||
|
||||
if (tlsChangeListener != null) {
|
||||
try {
|
||||
TlsFileWatcher.getInstance()
|
||||
.addFileChangeListener(tlsChangeListener, TlsSystemConfig.tlsClientTrustCertPath,
|
||||
TlsSystemConfig.tlsClientKeyPath);
|
||||
} catch (IOException e) {
|
||||
assignLogger().error("add tls file listener fail", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:abbreviationaswordinname")
|
||||
protected synchronized SSLContext loadSSLContext() {
|
||||
if (!TlsSystemConfig.tlsEnable) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return TlsHelper.buildSslContext(true);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
assignLogger().error("Failed to create SSLContext", e);
|
||||
} catch (KeyManagementException e) {
|
||||
assignLogger().error("Failed to create SSLContext", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* build http client config.
|
||||
*
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.http.handler.ResponseHandler;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
@ -39,7 +38,9 @@ import java.net.URI;
|
||||
* Base http client.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.request.HttpClientRequest}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class BaseHttpClient {
|
||||
|
||||
protected <T> RestResult<T> execute(CloseableHttpClient httpClient, final Type type, HttpUriRequest request)
|
||||
@ -101,7 +102,7 @@ public abstract class BaseHttpClient {
|
||||
final BaseHttpMethod httpMethod = BaseHttpMethod.sourceOf(method);
|
||||
final HttpRequestBase httpRequestBase = httpMethod.init(url);
|
||||
HttpUtils.initRequestHeader(httpRequestBase, header);
|
||||
HttpUtils.initRequestEntity(httpRequestBase, body, header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
HttpUtils.initRequestEntity(httpRequestBase, body, header);
|
||||
return httpRequestBase;
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,9 @@
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpHead;
|
||||
import org.apache.http.client.methods.HttpPatch;
|
||||
@ -28,6 +28,8 @@ import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.client.methods.HttpTrace;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Base http method.
|
||||
*
|
||||
@ -48,7 +50,7 @@ public enum BaseHttpMethod {
|
||||
GET_LARGE(HttpMethod.GET_LARGE) {
|
||||
@Override
|
||||
protected HttpRequestBase createRequest(String url) {
|
||||
return new BaseHttpClient.HttpGetWithEntity(url);
|
||||
return new HttpGetWithEntity(url);
|
||||
}
|
||||
},
|
||||
|
||||
@ -82,6 +84,16 @@ public enum BaseHttpMethod {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* delete Large request.
|
||||
*/
|
||||
DELETE_LARGE(HttpMethod.DELETE_LARGE) {
|
||||
@Override
|
||||
protected HttpRequestBase createRequest(String url) {
|
||||
return new HttpDeleteWithEntity(url);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* head request.
|
||||
*/
|
||||
@ -151,4 +163,48 @@ public enum BaseHttpMethod {
|
||||
throw new IllegalArgumentException("Unsupported http method : " + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* get Large implemented.
|
||||
* <p>
|
||||
* Mainly used for GET request parameters are relatively large, can not be placed on the URL, so it needs to be
|
||||
* placed in the body.
|
||||
* </p>
|
||||
*/
|
||||
public static class HttpGetWithEntity extends HttpEntityEnclosingRequestBase {
|
||||
|
||||
public static final String METHOD_NAME = "GET";
|
||||
|
||||
public HttpGetWithEntity(String url) {
|
||||
super();
|
||||
setURI(URI.create(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* delete Large implemented.
|
||||
* <p>
|
||||
* Mainly used for DELETE request parameters are relatively large, can not be placed on the URL, so it needs to be
|
||||
* placed in the body.
|
||||
* </p>
|
||||
*/
|
||||
public static class HttpDeleteWithEntity extends HttpEntityEnclosingRequestBase {
|
||||
|
||||
public static final String METHOD_NAME = "DELETE";
|
||||
|
||||
public HttpDeleteWithEntity(String url) {
|
||||
super();
|
||||
setURI(URI.create(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* http client config build.
|
||||
*
|
||||
@ -23,16 +25,62 @@ package com.alibaba.nacos.common.http;
|
||||
*/
|
||||
public class HttpClientConfig {
|
||||
|
||||
/**
|
||||
* connect time out.
|
||||
*/
|
||||
private final int conTimeOutMillis;
|
||||
|
||||
/**
|
||||
* read time out.
|
||||
*/
|
||||
private final int readTimeOutMillis;
|
||||
|
||||
/**
|
||||
* connTimeToLive.
|
||||
*/
|
||||
private final long connTimeToLive;
|
||||
|
||||
/**
|
||||
* connTimeToLiveTimeUnit.
|
||||
*/
|
||||
private final TimeUnit connTimeToLiveTimeUnit;
|
||||
|
||||
/**
|
||||
* connectionRequestTimeout.
|
||||
*/
|
||||
private final int connectionRequestTimeout;
|
||||
|
||||
/**
|
||||
* max redirect.
|
||||
*/
|
||||
private final int maxRedirects;
|
||||
|
||||
public HttpClientConfig(int conTimeOutMillis, int readTimeOutMillis, int maxRedirects) {
|
||||
/**
|
||||
* max connect total.
|
||||
*/
|
||||
private final int maxConnTotal;
|
||||
|
||||
/**
|
||||
* Assigns maximum connection per route value.
|
||||
*/
|
||||
private final int maxConnPerRoute;
|
||||
|
||||
/**
|
||||
* user agent.
|
||||
*/
|
||||
private final String userAgent;
|
||||
|
||||
public HttpClientConfig(int conTimeOutMillis, int readTimeOutMillis, long connTimeToLive, TimeUnit timeUnit,
|
||||
int connectionRequestTimeout, int maxRedirects, int maxConnTotal, int maxConnPerRoute, String userAgent) {
|
||||
this.conTimeOutMillis = conTimeOutMillis;
|
||||
this.readTimeOutMillis = readTimeOutMillis;
|
||||
this.connTimeToLive = connTimeToLive;
|
||||
this.connTimeToLiveTimeUnit = timeUnit;
|
||||
this.connectionRequestTimeout = connectionRequestTimeout;
|
||||
this.maxRedirects = maxRedirects;
|
||||
this.maxConnTotal = maxConnTotal;
|
||||
this.maxConnPerRoute = maxConnPerRoute;
|
||||
this.userAgent = userAgent;
|
||||
}
|
||||
|
||||
public int getConTimeOutMillis() {
|
||||
@ -43,10 +91,34 @@ public class HttpClientConfig {
|
||||
return readTimeOutMillis;
|
||||
}
|
||||
|
||||
public long getConnTimeToLive() {
|
||||
return connTimeToLive;
|
||||
}
|
||||
|
||||
public TimeUnit getConnTimeToLiveTimeUnit() {
|
||||
return connTimeToLiveTimeUnit;
|
||||
}
|
||||
|
||||
public int getConnectionRequestTimeout() {
|
||||
return connectionRequestTimeout;
|
||||
}
|
||||
|
||||
public int getMaxRedirects() {
|
||||
return maxRedirects;
|
||||
}
|
||||
|
||||
public int getMaxConnTotal() {
|
||||
return maxConnTotal;
|
||||
}
|
||||
|
||||
public int getMaxConnPerRoute() {
|
||||
return maxConnPerRoute;
|
||||
}
|
||||
|
||||
public String getUserAgent() {
|
||||
return userAgent;
|
||||
}
|
||||
|
||||
public static HttpClientConfigBuilder builder() {
|
||||
return new HttpClientConfigBuilder();
|
||||
}
|
||||
@ -57,8 +129,20 @@ public class HttpClientConfig {
|
||||
|
||||
private int readTimeOutMillis = -1;
|
||||
|
||||
private long connTimeToLive = -1;
|
||||
|
||||
private TimeUnit connTimeToLiveTimeUnit = TimeUnit.MILLISECONDS;
|
||||
|
||||
private int connectionRequestTimeout = -1;
|
||||
|
||||
private int maxRedirects = 50;
|
||||
|
||||
private int maxConnTotal = 0;
|
||||
|
||||
private int maxConnPerRoute = 0;
|
||||
|
||||
private String userAgent;
|
||||
|
||||
public HttpClientConfigBuilder setConTimeOutMillis(int conTimeOutMillis) {
|
||||
this.conTimeOutMillis = conTimeOutMillis;
|
||||
return this;
|
||||
@ -69,13 +153,40 @@ public class HttpClientConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfigBuilder setConnectionTimeToLive(long connTimeToLive, TimeUnit connTimeToLiveTimeUnit) {
|
||||
this.connTimeToLive = connTimeToLive;
|
||||
this.connTimeToLiveTimeUnit = connTimeToLiveTimeUnit;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfigBuilder setConnectionRequestTimeout(int connectionRequestTimeout) {
|
||||
this.connectionRequestTimeout = connectionRequestTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfigBuilder setMaxRedirects(int maxRedirects) {
|
||||
this.maxRedirects = maxRedirects;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfigBuilder setMaxConnTotal(int maxConnTotal) {
|
||||
this.maxConnTotal = maxConnTotal;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfigBuilder setMaxConnPerRoute(int maxConnPerRoute) {
|
||||
this.maxConnPerRoute = maxConnPerRoute;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfigBuilder setUserAgent(String userAgent) {
|
||||
this.userAgent = userAgent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpClientConfig build() {
|
||||
return new HttpClientConfig(conTimeOutMillis, readTimeOutMillis, maxRedirects);
|
||||
return new HttpClientConfig(conTimeOutMillis, readTimeOutMillis, connTimeToLive, connTimeToLiveTimeUnit,
|
||||
connectionRequestTimeout, maxRedirects, maxConnTotal, maxConnPerRoute, userAgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
* Use the same HttpClient object in the same space.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link HttpClientBeanHolder}
|
||||
*/
|
||||
@Deprecated
|
||||
public class HttpClientManager {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientManager.class);
|
||||
|
@ -16,15 +16,18 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.http.handler.RequestHandler;
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
@ -70,17 +73,23 @@ public final class HttpUtils {
|
||||
*
|
||||
* @param requestBase requestBase {@link HttpRequestBase}
|
||||
* @param body body
|
||||
* @param mediaType mediaType {@link ContentType}
|
||||
* @param header request header
|
||||
* @throws Exception exception
|
||||
*/
|
||||
public static void initRequestEntity(HttpRequestBase requestBase, Object body, String mediaType) throws Exception {
|
||||
public static void initRequestEntity(HttpRequestBase requestBase, Object body, Header header) throws Exception {
|
||||
if (body == null) {
|
||||
return;
|
||||
}
|
||||
if (requestBase instanceof HttpEntityEnclosingRequest) {
|
||||
HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) requestBase;
|
||||
ContentType contentType = ContentType.create(mediaType);
|
||||
StringEntity entity = new StringEntity(RequestHandler.parse(body), contentType);
|
||||
MediaType mediaType = MediaType.valueOf(header.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
ContentType contentType = ContentType.create(mediaType.getType(), mediaType.getCharset());
|
||||
HttpEntity entity;
|
||||
if (body instanceof byte[]) {
|
||||
entity = new ByteArrayEntity((byte[]) body, contentType);
|
||||
} else {
|
||||
entity = new StringEntity(body instanceof String ? (String) body : JacksonUtils.toJson(body), contentType);
|
||||
}
|
||||
request.setEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -229,7 +238,7 @@ public final class HttpUtils {
|
||||
* @return {@link URI}
|
||||
*/
|
||||
public static URI buildUri(String url, Query query) throws URISyntaxException {
|
||||
if (!query.isEmpty()) {
|
||||
if (query != null && !query.isEmpty()) {
|
||||
url = url + "?" + query.toQueryUrl();
|
||||
}
|
||||
return new URI(url);
|
||||
|
@ -25,7 +25,9 @@ import java.lang.reflect.Type;
|
||||
* Nacos async http client interface.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("all")
|
||||
public interface NAsyncHttpClient extends NHttpClient {
|
||||
|
||||
|
@ -22,7 +22,9 @@ import java.io.Closeable;
|
||||
* Nacos http client interface.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.request.HttpClientRequest}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public interface NHttpClient extends Closeable {
|
||||
|
||||
|
@ -26,7 +26,9 @@ import java.lang.reflect.Type;
|
||||
* Nacos sync http client.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.NacosRestTemplate}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("all")
|
||||
public interface NSyncHttpClient extends NHttpClient {
|
||||
|
||||
|
@ -29,7 +29,9 @@ import java.lang.reflect.Type;
|
||||
* Nacos async http client.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.request.DefaultAsyncHttpClientRequest}
|
||||
*/
|
||||
@Deprecated
|
||||
class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpClient {
|
||||
|
||||
private CloseableHttpAsyncClient asyncClient;
|
||||
|
@ -30,7 +30,9 @@ import java.lang.reflect.Type;
|
||||
* Nacos sync http client.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* @deprecated Refer to the new {@link com.alibaba.nacos.common.http.client.request.JdkHttpClientRequest}
|
||||
*/
|
||||
@Deprecated
|
||||
class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClient {
|
||||
|
||||
private CloseableHttpClient client;
|
||||
|
@ -61,34 +61,11 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void get(String url, Header header, Query query, Type responseType, Callback<T> callback)
|
||||
throws Exception {
|
||||
public <T> void get(String url, Header header, Query query, Type responseType, Callback<T> callback) {
|
||||
execute(url, HttpMethod.GET, new RequestHttpEntity(header, query), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http get URL request params are expanded using the given map {@code paramValues}.
|
||||
*
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
*
|
||||
* <p>{@code callback} Result callback execution
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header headers
|
||||
* @param paramValues paramValues
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void get(String url, Header header, Map<String, String> paramValues, Type responseType,
|
||||
Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.GET, new RequestHttpEntity(header, Query.newInstance().initParams(paramValues)),
|
||||
responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async get request, may be pulling a lot of data URL request params are expanded using the given query {@link
|
||||
* Query}, More request parameters can be set via body.
|
||||
@ -104,10 +81,9 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param body get with body
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void getLarge(String url, Header header, Query query, Object body, Type responseType,
|
||||
Callback<T> callback) throws Exception {
|
||||
Callback<T> callback) {
|
||||
execute(url, HttpMethod.GET_LARGE, new RequestHttpEntity(header, query, body), responseType, callback);
|
||||
}
|
||||
|
||||
@ -124,13 +100,32 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param query http query param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void delete(String url, Header header, Query query, Type responseType, Callback<T> callback)
|
||||
throws Exception {
|
||||
public <T> void delete(String url, Header header, Query query, Type responseType, Callback<T> callback) {
|
||||
execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http delete large request, when the parameter exceeds the URL limit, you can use this method to put the
|
||||
* parameter into the body pass.
|
||||
*
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type
|
||||
*
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param body body
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
public <T> void delete(String url, Header header, String body, Type responseType, Callback<T> callback) {
|
||||
execute(url, HttpMethod.DELETE_LARGE,
|
||||
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), Query.EMPTY, body),
|
||||
responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http put Create a new resource by PUTting the given body to http request.
|
||||
*
|
||||
@ -147,10 +142,8 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void put(String url, Header header, Query query, Object body, Type responseType, Callback<T> callback)
|
||||
throws Exception {
|
||||
public <T> void put(String url, Header header, Query query, Object body, Type responseType, Callback<T> callback) {
|
||||
execute(url, HttpMethod.PUT, new RequestHttpEntity(header, query, body), responseType, callback);
|
||||
}
|
||||
|
||||
@ -158,7 +151,7 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* async http put Json Create a new resource by PUTting the given body to http request, http header contentType
|
||||
* default 'application/json;charset=UTF-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
*
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type
|
||||
*
|
||||
@ -167,16 +160,36 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void putJson(String url, Header header, Map<String, String> paramValues, String body, Type responseType,
|
||||
Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.PUT, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON),
|
||||
Query.newInstance().initParams(paramValues), body), responseType, callback);
|
||||
public <T> void putJson(String url, Header header, Query query, String body, Type responseType,
|
||||
Callback<T> callback) {
|
||||
execute(url, HttpMethod.PUT,
|
||||
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), query, body), responseType,
|
||||
callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http put Json Create a new resource by PUTting the given body to http request, http header contentType
|
||||
* default 'application/json;charset=UTF-8'.
|
||||
*
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type
|
||||
*
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
public <T> void putJson(String url, Header header, String body, Type responseType, Callback<T> callback) {
|
||||
execute(url, HttpMethod.PUT, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), body),
|
||||
responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,10 +209,9 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void putForm(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType,
|
||||
Callback<T> callback) throws Exception {
|
||||
Callback<T> callback) {
|
||||
execute(url, HttpMethod.PUT,
|
||||
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues),
|
||||
responseType, callback);
|
||||
@ -209,8 +221,6 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* async http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http
|
||||
* header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
*
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
*
|
||||
* <p>{@code callback} Result callback execution,
|
||||
@ -218,16 +228,15 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void putForm(String url, Header header, Map<String, String> paramValues, Map<String, String> bodyValues,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.PUT, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues), bodyValues), responseType, callback);
|
||||
public <T> void putForm(String url, Header header, Map<String, String> bodyValues, Type responseType,
|
||||
Callback<T> callback) {
|
||||
execute(url, HttpMethod.PUT,
|
||||
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues),
|
||||
responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,10 +255,8 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void post(String url, Header header, Query query, Object body, Type responseType, Callback<T> callback)
|
||||
throws Exception {
|
||||
public <T> void post(String url, Header header, Query query, Object body, Type responseType, Callback<T> callback) {
|
||||
execute(url, HttpMethod.POST, new RequestHttpEntity(header, query, body), responseType, callback);
|
||||
}
|
||||
|
||||
@ -257,7 +264,7 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* async http post Json Create a new resource by POSTing the given object to the http request, http header
|
||||
* contentType default 'application/json;charset=UTF-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
*
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
*
|
||||
@ -266,16 +273,36 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void postJson(String url, Header header, Map<String, String> paramValues, String body, Type responseType,
|
||||
Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.POST, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON),
|
||||
Query.newInstance().initParams(paramValues), body), responseType, callback);
|
||||
public <T> void postJson(String url, Header header, Query query, String body, Type responseType,
|
||||
Callback<T> callback) {
|
||||
execute(url, HttpMethod.POST,
|
||||
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), query, body), responseType,
|
||||
callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http post Json Create a new resource by POSTing the given object to the http request, http header
|
||||
* contentType default 'application/json;charset=UTF-8'.
|
||||
*
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
*
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
*/
|
||||
public <T> void postJson(String url, Header header, String body, Type responseType, Callback<T> callback) {
|
||||
execute(url, HttpMethod.POST, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), body),
|
||||
responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -295,10 +322,9 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void postForm(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType,
|
||||
Callback<T> callback) throws Exception {
|
||||
Callback<T> callback) {
|
||||
execute(url, HttpMethod.POST,
|
||||
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues),
|
||||
responseType, callback);
|
||||
@ -308,8 +334,6 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
* async http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http
|
||||
* header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
*
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
*
|
||||
* <p>{@code callback} Result callback execution,
|
||||
@ -317,29 +341,31 @@ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void postForm(String url, Header header, Map<String, String> paramValues, Map<String, String> bodyValues,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
public <T> void postForm(String url, Header header, Map<String, String> bodyValues, Type responseType,
|
||||
Callback<T> callback) {
|
||||
execute(url, HttpMethod.POST,
|
||||
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues), bodyValues), responseType, callback);
|
||||
|
||||
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues),
|
||||
responseType, callback);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type type,
|
||||
Callback<T> callback) throws Exception {
|
||||
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody());
|
||||
Callback<T> callback) {
|
||||
try {
|
||||
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody());
|
||||
}
|
||||
ResponseHandler<T> responseHandler = super.selectResponseHandler(type);
|
||||
clientRequest.execute(uri, httpMethod, requestEntity, responseHandler, callback);
|
||||
} catch (Exception e) {
|
||||
// When an exception occurs, use Callback to pass it instead of throw it directly.
|
||||
callback.onError(e);
|
||||
}
|
||||
ResponseHandler<T> responseHandler = super.selectResponseHandler(type);
|
||||
clientRequest.execute(uri, httpMethod, requestEntity, responseHandler, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,9 @@ import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||
import com.alibaba.nacos.common.http.HttpUtils;
|
||||
import com.alibaba.nacos.common.http.client.handler.ResponseHandler;
|
||||
import com.alibaba.nacos.common.http.client.request.DefaultHttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.client.request.HttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.client.request.JdkHttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.client.response.HttpClientResponse;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
@ -70,25 +72,6 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
return execute(url, HttpMethod.GET, new RequestHttpEntity(header, query), responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http get URL request params are expanded using the given query {@link Query}.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header headers
|
||||
* @param paramValues paramValues
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> get(String url, Header header, Map<String, String> paramValues, Type responseType)
|
||||
throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header,
|
||||
Query.newInstance().initParams(paramValues));
|
||||
return execute(url, HttpMethod.GET, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http get URL request params are expanded using the given query {@link Query}.
|
||||
*
|
||||
@ -99,15 +82,14 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param url url
|
||||
* @param config http config
|
||||
* @param header headers
|
||||
* @param paramValues paramValues
|
||||
* @param query http query param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> get(String url, HttpClientConfig config, Header header,
|
||||
Map<String, String> paramValues, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header,
|
||||
Query.newInstance().initParams(paramValues));
|
||||
public <T> HttpRestResult<T> get(String url, HttpClientConfig config, Header header, Query query, Type responseType)
|
||||
throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header, query);
|
||||
return execute(url, HttpMethod.GET, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
@ -115,6 +97,9 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* get request, may be pulling a lot of data URL request params are expanded using the given query {@link Query},
|
||||
* More request parameters can be set via body.
|
||||
*
|
||||
* <p>This method can only be used when HttpClientRequest is implemented by {@link DefaultHttpClientRequest}, note:
|
||||
* {@link JdkHttpClientRequest} Implementation does not support this method.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
@ -156,15 +141,14 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param url url
|
||||
* @param config http config
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param query http query param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> delete(String url, HttpClientConfig config, Header header,
|
||||
Map<String, String> paramValues, Type responseType) throws Exception {
|
||||
return execute(url, HttpMethod.DELETE,
|
||||
new RequestHttpEntity(config, header, Query.newInstance().initParams(paramValues)), responseType);
|
||||
public <T> HttpRestResult<T> delete(String url, HttpClientConfig config, Header header, Query query,
|
||||
Type responseType) throws Exception {
|
||||
return execute(url, HttpMethod.DELETE, new RequestHttpEntity(config, header, query), responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,22 +175,41 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* http put json Create a new resource by PUTting the given body to http request, http header contentType default
|
||||
* 'application/json;charset=UTF-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> putJson(String url, Header header, Map<String, String> paramValues, String body,
|
||||
Type responseType) throws Exception {
|
||||
public <T> HttpRestResult<T> putJson(String url, Header header, Query query, String body, Type responseType)
|
||||
throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON),
|
||||
Query.newInstance().initParams(paramValues), body);
|
||||
query, body);
|
||||
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http put json Create a new resource by PUTting the given body to http request, http header contentType default
|
||||
* 'application/json;charset=UTF-8'.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> putJson(String url, Header header, String body, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON),
|
||||
body);
|
||||
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
@ -237,23 +240,19 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header
|
||||
* contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> putForm(String url, Header header, Map<String, String> paramValues,
|
||||
Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
public <T> HttpRestResult<T> putForm(String url, Header header, Map<String, String> bodyValues, Type responseType)
|
||||
throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues), bodyValues);
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues);
|
||||
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
@ -261,8 +260,6 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header
|
||||
* contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
|
||||
@ -270,17 +267,15 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param url url
|
||||
* @param config http config
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> putForm(String url, HttpClientConfig config, Header header,
|
||||
Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config,
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues), bodyValues);
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues);
|
||||
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
@ -308,22 +303,41 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* http post json Create a new resource by POSTing the given object to the http request, http header contentType
|
||||
* default 'application/json;charset=UTF-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> postJson(String url, Header header, Map<String, String> paramValues, String body,
|
||||
Type responseType) throws Exception {
|
||||
public <T> HttpRestResult<T> postJson(String url, Header header, Query query, String body, Type responseType)
|
||||
throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON),
|
||||
Query.newInstance().initParams(paramValues), body);
|
||||
query, body);
|
||||
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http post json Create a new resource by POSTing the given object to the http request, http header contentType
|
||||
* default 'application/json;charset=UTF-8'.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> postJson(String url, Header header, String body, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON),
|
||||
body);
|
||||
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
@ -354,23 +368,19 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header
|
||||
* contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> postForm(String url, Header header, Map<String, String> paramValues,
|
||||
Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
public <T> HttpRestResult<T> postForm(String url, Header header, Map<String, String> bodyValues, Type responseType)
|
||||
throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues), bodyValues);
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues);
|
||||
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
@ -378,8 +388,6 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header
|
||||
* contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
*
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
*
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
|
||||
@ -387,17 +395,15 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
* @param url url
|
||||
* @param config http config
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> postForm(String url, HttpClientConfig config, Header header,
|
||||
Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config,
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues), bodyValues);
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues);
|
||||
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
@ -407,18 +413,37 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param query http query param
|
||||
* @param bodyValues http body param
|
||||
* @param httpMethod http method
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> exchangeForm(String url, Header header, Map<String, String> paramValues,
|
||||
Map<String, String> bodyValues, String httpMethod, Type responseType) throws Exception {
|
||||
public <T> HttpRestResult<T> exchangeForm(String url, Header header, Query query, Map<String, String> bodyValues,
|
||||
String httpMethod, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues), bodyValues);
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues);
|
||||
return execute(url, httpMethod, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the HTTP method to the given URI template, writing the given request entity to the request, and returns
|
||||
* the response as {@link HttpRestResult}.
|
||||
*
|
||||
* @param url url
|
||||
* @param config HttpClientConfig
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param httpMethod http method
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> exchange(String url, HttpClientConfig config, Header header, Query query,
|
||||
Object body, String httpMethod, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header, query, body);
|
||||
return execute(url, httpMethod, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
@ -450,7 +475,7 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody());
|
||||
}
|
||||
|
||||
|
||||
ResponseHandler<T> responseHandler = super.selectResponseHandler(responseType);
|
||||
HttpClientResponse response = null;
|
||||
try {
|
||||
|
@ -65,7 +65,7 @@ public class DefaultHttpClientRequest implements HttpClientRequest {
|
||||
&& requestHttpEntity.getBody() instanceof Map) {
|
||||
HttpUtils.initRequestFromEntity(httpRequestBase, (Map<String, String>) requestHttpEntity.getBody(), headers.getCharset());
|
||||
} else {
|
||||
HttpUtils.initRequestEntity(httpRequestBase, requestHttpEntity.getBody(), headers.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
HttpUtils.initRequestEntity(httpRequestBase, requestHttpEntity.getBody(), headers);
|
||||
}
|
||||
replaceDefaultConfig(httpRequestBase, requestHttpEntity.getHttpClientConfig());
|
||||
return httpRequestBase;
|
||||
|
@ -26,6 +26,9 @@ import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
@ -45,6 +48,30 @@ public class JdkHttpClientRequest implements HttpClientRequest {
|
||||
this.httpClientConfig = httpClientConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use specified {@link SSLContext}.
|
||||
*
|
||||
* @param sslContext ssl context
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:abbreviationaswordinname")
|
||||
public void setSSLContext(SSLContext sslContext) {
|
||||
if (sslContext != null) {
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the default HostnameVerifier.
|
||||
*
|
||||
* @param hostnameVerifier custom hostnameVerifier
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:abbreviationaswordinname")
|
||||
public void replaceSSLHostnameVerifier(HostnameVerifier hostnameVerifier) {
|
||||
if (hostnameVerifier != null) {
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity)
|
||||
throws Exception {
|
||||
@ -63,7 +90,7 @@ public class JdkHttpClientRequest implements HttpClientRequest {
|
||||
conn.setConnectTimeout(this.httpClientConfig.getConTimeOutMillis());
|
||||
conn.setReadTimeout(this.httpClientConfig.getReadTimeOutMillis());
|
||||
conn.setRequestMethod(httpMethod);
|
||||
if (body != null) {
|
||||
if (body != null && !"".equals(body)) {
|
||||
String contentType = headers.getValue(HttpHeaderConsts.CONTENT_TYPE);
|
||||
String bodyStr = JacksonUtils.toJson(body);
|
||||
if (MediaType.APPLICATION_FORM_URLENCODED.equals(contentType)) {
|
||||
|
@ -16,9 +16,11 @@
|
||||
|
||||
package com.alibaba.nacos.common.http.client.response;
|
||||
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
@ -36,6 +38,8 @@ public class JdkHttpClientResponse implements HttpClientResponse {
|
||||
|
||||
private Header responseHeader;
|
||||
|
||||
private static final String CONTENT_ENCODING = "gzip";
|
||||
|
||||
public JdkHttpClientResponse(HttpURLConnection conn) {
|
||||
this.conn = conn;
|
||||
}
|
||||
@ -51,8 +55,18 @@ public class JdkHttpClientResponse implements HttpClientResponse {
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
Header headers = getHeaders();
|
||||
InputStream errorStream = this.conn.getErrorStream();
|
||||
this.responseStream = (errorStream != null ? errorStream : this.conn.getInputStream());
|
||||
String contentEncoding = headers.getValue(HttpHeaderConsts.CONTENT_ENCODING);
|
||||
// Used to process http content_encoding, when content_encoding is GZIP, use GZIPInputStream
|
||||
if (CONTENT_ENCODING.equals(contentEncoding)) {
|
||||
byte[] bytes = IoUtils.tryDecompress(this.responseStream);
|
||||
if (bytes == null) {
|
||||
throw new IOException("decompress http response error");
|
||||
}
|
||||
return new ByteArrayInputStream(bytes);
|
||||
}
|
||||
return this.responseStream;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ package com.alibaba.nacos.common.http.param;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.utils.MapUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -45,15 +46,23 @@ public class Header {
|
||||
addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_JSON);
|
||||
addParam(HttpHeaderConsts.ACCEPT_CHARSET, "UTF-8");
|
||||
addParam(HttpHeaderConsts.ACCEPT_ENCODING, "gzip");
|
||||
addParam(HttpHeaderConsts.CONTENT_ENCODING, "gzip");
|
||||
}
|
||||
|
||||
public static Header newInstance() {
|
||||
return new Header();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the key and value to the header.
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @return header
|
||||
*/
|
||||
public Header addParam(String key, String value) {
|
||||
header.put(key, value);
|
||||
if (StringUtils.isNotEmpty(key)) {
|
||||
header.put(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -107,7 +116,10 @@ public class Header {
|
||||
throw new IllegalArgumentException("list size must be a multiple of 2");
|
||||
}
|
||||
for (int i = 0; i < list.size(); ) {
|
||||
header.put(list.get(i++), list.get(i++));
|
||||
String key = list.get(i++);
|
||||
if (StringUtils.isNotEmpty(key)) {
|
||||
header.put(key, list.get(i++));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -118,8 +130,10 @@ public class Header {
|
||||
* @param params parameters
|
||||
*/
|
||||
public void addAll(Map<String, String> params) {
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
addParam(entry.getKey(), entry.getValue());
|
||||
if (MapUtils.isNotEmpty(params)) {
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
addParam(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,9 +145,11 @@ public class Header {
|
||||
* @param headers original response header
|
||||
*/
|
||||
public void setOriginalResponseHeader(Map<String, List<String>> headers) {
|
||||
this.originalResponseHeader.putAll(headers);
|
||||
for (Map.Entry<String, List<String>> entry : this.originalResponseHeader.entrySet()) {
|
||||
addParam(entry.getKey(), entry.getValue().get(0));
|
||||
if (MapUtils.isNotEmpty(headers)) {
|
||||
this.originalResponseHeader.putAll(headers);
|
||||
for (Map.Entry<String, List<String>> entry : this.originalResponseHeader.entrySet()) {
|
||||
addParam(entry.getKey(), entry.getValue().get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
package com.alibaba.nacos.common.http.param;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Http Media type.
|
||||
*
|
||||
@ -23,12 +26,9 @@ package com.alibaba.nacos.common.http.param;
|
||||
*/
|
||||
public final class MediaType {
|
||||
|
||||
private MediaType() {
|
||||
}
|
||||
|
||||
public static final String APPLICATION_ATOM_XML = "application/atom+xml";
|
||||
|
||||
public static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded";
|
||||
public static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded;charset=UTF-8";
|
||||
|
||||
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
|
||||
|
||||
@ -36,14 +36,76 @@ public final class MediaType {
|
||||
|
||||
public static final String APPLICATION_XHTML_XML = "application/xhtml+xml";
|
||||
|
||||
public static final String APPLICATION_XML = "application/xml";
|
||||
public static final String APPLICATION_XML = "application/xml;charset=UTF-8";
|
||||
|
||||
public static final String APPLICATION_JSON = "application/json";
|
||||
public static final String APPLICATION_JSON = "application/json;charset=UTF-8";
|
||||
|
||||
public static final String MULTIPART_FORM_DATA = "multipart/form-data";
|
||||
public static final String MULTIPART_FORM_DATA = "multipart/form-data;charset=UTF-8";
|
||||
|
||||
public static final String TEXT_HTML = "text/html";
|
||||
public static final String TEXT_HTML = "text/html;charset=UTF-8";
|
||||
|
||||
public static final String TEXT_PLAIN = "text/plain";
|
||||
public static final String TEXT_PLAIN = "text/plain;charset=UTF-8";
|
||||
|
||||
private MediaType(String type, String charset) {
|
||||
this.type = type;
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* content type.
|
||||
*/
|
||||
private final String type;
|
||||
|
||||
/**
|
||||
* content type charset.
|
||||
*/
|
||||
private final String charset;
|
||||
|
||||
/**
|
||||
* Parse the given String contentType into a {@code MediaType} object.
|
||||
*
|
||||
* @param contentType mediaType
|
||||
* @return MediaType
|
||||
*/
|
||||
public static MediaType valueOf(String contentType) {
|
||||
if (StringUtils.isEmpty(contentType)) {
|
||||
throw new IllegalArgumentException("MediaType must not be empty");
|
||||
}
|
||||
String[] values = contentType.split(";");
|
||||
String charset = Constants.ENCODE;
|
||||
for (String value : values) {
|
||||
if (value.startsWith("charset=")) {
|
||||
charset = value.substring("charset=".length());
|
||||
}
|
||||
}
|
||||
return new MediaType(values[0], charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the given contentType and charset to assemble into a {@code MediaType} object.
|
||||
*
|
||||
* @param contentType contentType
|
||||
* @param charset charset
|
||||
* @return MediaType
|
||||
*/
|
||||
public static MediaType valueOf(String contentType, String charset) {
|
||||
if (StringUtils.isEmpty(contentType)) {
|
||||
throw new IllegalArgumentException("MediaType must not be empty");
|
||||
}
|
||||
String[] values = contentType.split(";");
|
||||
return new MediaType(values[0], StringUtils.isEmpty(charset) ? Constants.ENCODE : charset);
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
return charset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type + ";charset=" + charset;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.common.http.param;
|
||||
|
||||
import com.alibaba.nacos.common.utils.MapUtils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -68,8 +70,10 @@ public class Query {
|
||||
* @return this query
|
||||
*/
|
||||
public Query initParams(Map<String, String> params) {
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
addParam(entry.getKey(), entry.getValue());
|
||||
if (MapUtils.isNotEmpty(params)) {
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
addParam(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ import java.util.Map;
|
||||
* Represents an HTTP request , consisting of headers and body.
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/23
|
||||
*/
|
||||
public class RequestHttpEntity {
|
||||
|
||||
@ -36,18 +35,26 @@ public class RequestHttpEntity {
|
||||
|
||||
private final Query query;
|
||||
|
||||
private Object body;
|
||||
private final Object body;
|
||||
|
||||
public RequestHttpEntity(Header header, Query query) {
|
||||
this(null, header, query);
|
||||
}
|
||||
|
||||
public RequestHttpEntity(Header header, Object body) {
|
||||
this(null, header, null, body);
|
||||
}
|
||||
|
||||
public RequestHttpEntity(Header header, Query query, Object body) {
|
||||
this(null, header, query, body);
|
||||
}
|
||||
|
||||
public RequestHttpEntity(HttpClientConfig httpClientConfig, Header header, Query query) {
|
||||
this(httpClientConfig, header, query, null);
|
||||
}
|
||||
|
||||
public RequestHttpEntity(Header header, Query query, Object body) {
|
||||
this(null, header, query, body);
|
||||
public RequestHttpEntity(HttpClientConfig httpClientConfig, Header header, Object body) {
|
||||
this(httpClientConfig, header, null, body);
|
||||
}
|
||||
|
||||
public RequestHttpEntity(HttpClientConfig httpClientConfig, Header header, Query query, Object body) {
|
||||
|
@ -56,7 +56,7 @@ public class DefaultPublisher extends Thread implements EventPublisher {
|
||||
|
||||
protected volatile Long lastEventSequence = -1L;
|
||||
|
||||
private final AtomicReferenceFieldUpdater<DefaultPublisher, Long> updater = AtomicReferenceFieldUpdater
|
||||
private static final AtomicReferenceFieldUpdater<DefaultPublisher, Long> UPDATER = AtomicReferenceFieldUpdater
|
||||
.newUpdater(DefaultPublisher.class, Long.class, "lastEventSequence");
|
||||
|
||||
@Override
|
||||
@ -115,7 +115,7 @@ public class DefaultPublisher extends Thread implements EventPublisher {
|
||||
}
|
||||
final Event event = queue.take();
|
||||
receiveEvent(event);
|
||||
updater.compareAndSet(this, lastEventSequence, Math.max(lastEventSequence, event.sequence()));
|
||||
UPDATER.compareAndSet(this, lastEventSequence, Math.max(lastEventSequence, event.sequence()));
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.error("Event listener exception : {}", ex);
|
||||
|
@ -96,6 +96,10 @@ public class DefaultSharePublisher extends DefaultPublisher {
|
||||
|
||||
// Get for Map, the algorithm is O(1).
|
||||
Set<Subscriber> subscribers = subMappings.get(slowEventType);
|
||||
if (null == subscribers) {
|
||||
LOGGER.debug("[NotifyCenter] No subscribers for slow event {}", slowEventType.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
// Notification single event subscriber
|
||||
for (Subscriber subscriber : subscribers) {
|
||||
|
@ -14,14 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.manager;
|
||||
package com.alibaba.nacos.common.task;
|
||||
|
||||
/**
|
||||
* AbstractTask.
|
||||
* Abstract task which can delay and merge.
|
||||
*
|
||||
* @author huali
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public abstract class AbstractTask {
|
||||
public abstract class AbstractDelayTask implements NacosTask {
|
||||
|
||||
/**
|
||||
* Task time interval between twice processing, unit is millisecond.
|
||||
@ -38,7 +39,7 @@ public abstract class AbstractTask {
|
||||
*
|
||||
* @param task task
|
||||
*/
|
||||
public abstract void merge(AbstractTask task);
|
||||
public abstract void merge(AbstractDelayTask task);
|
||||
|
||||
public void setTaskInterval(long interval) {
|
||||
this.taskInterval = interval;
|
||||
@ -56,11 +57,7 @@ public abstract class AbstractTask {
|
||||
return this.lastProcessTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* TaskManager judge whether to process current this task, subclass could override and implement the logical codes.
|
||||
*
|
||||
* @return the result whether to process.
|
||||
*/
|
||||
@Override
|
||||
public boolean shouldProcess() {
|
||||
return (System.currentTimeMillis() - this.lastProcessTime >= this.taskInterval);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.task;
|
||||
|
||||
/**
|
||||
* Abstract task which should be executed immediately.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public abstract class AbstractExecuteTask implements NacosTask, Runnable {
|
||||
|
||||
@Override
|
||||
public boolean shouldProcess() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.task;
|
||||
|
||||
/**
|
||||
* Nacos task.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface NacosTask {
|
||||
|
||||
/**
|
||||
* Judge Whether this nacos task should do.
|
||||
*
|
||||
* @return true means the nacos task should be done, otherwise false
|
||||
*/
|
||||
boolean shouldProcess();
|
||||
}
|
@ -14,21 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.config.server.manager;
|
||||
package com.alibaba.nacos.common.task;
|
||||
|
||||
/**
|
||||
* Task processor.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public interface TaskProcessor {
|
||||
public interface NacosTaskProcessor {
|
||||
|
||||
/**
|
||||
* Process task.
|
||||
*
|
||||
* @param taskType task type.
|
||||
* @param task task.
|
||||
* @return process task result.
|
||||
*/
|
||||
boolean process(String taskType, AbstractTask task);
|
||||
boolean process(NacosTask task);
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.task.engine;
|
||||
|
||||
import com.alibaba.nacos.common.task.NacosTask;
|
||||
import com.alibaba.nacos.common.task.NacosTaskProcessor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Abstract nacos task execute engine.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public abstract class AbstractNacosTaskExecuteEngine<T extends NacosTask> implements NacosTaskExecuteEngine<T> {
|
||||
|
||||
private final Logger log;
|
||||
|
||||
private final ConcurrentHashMap<Object, NacosTaskProcessor> taskProcessors = new ConcurrentHashMap<Object, NacosTaskProcessor>();
|
||||
|
||||
private NacosTaskProcessor defaultTaskProcessor;
|
||||
|
||||
public AbstractNacosTaskExecuteEngine(Logger logger) {
|
||||
this.log = null != logger ? logger : LoggerFactory.getLogger(AbstractNacosTaskExecuteEngine.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProcessor(Object key, NacosTaskProcessor taskProcessor) {
|
||||
taskProcessors.putIfAbsent(key, taskProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProcessor(Object key) {
|
||||
taskProcessors.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NacosTaskProcessor getProcessor(Object key) {
|
||||
return taskProcessors.containsKey(key) ? taskProcessors.get(key) : defaultTaskProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> getAllProcessorKey() {
|
||||
return taskProcessors.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultTaskProcessor(NacosTaskProcessor defaultTaskProcessor) {
|
||||
this.defaultTaskProcessor = defaultTaskProcessor;
|
||||
}
|
||||
|
||||
protected Logger getEngineLog() {
|
||||
return log;
|
||||
}
|
||||
}
|
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.task.engine;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||
import com.alibaba.nacos.common.task.AbstractDelayTask;
|
||||
import com.alibaba.nacos.common.task.NacosTaskProcessor;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* Nacos delay task execute engine.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class NacosDelayTaskExecuteEngine extends AbstractNacosTaskExecuteEngine<AbstractDelayTask> {
|
||||
|
||||
private final ScheduledExecutorService processingExecutor;
|
||||
|
||||
protected final ConcurrentHashMap<Object, AbstractDelayTask> tasks;
|
||||
|
||||
protected final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
public NacosDelayTaskExecuteEngine(String name) {
|
||||
this(name, null);
|
||||
}
|
||||
|
||||
public NacosDelayTaskExecuteEngine(String name, Logger logger) {
|
||||
this(name, 32, logger, 100L);
|
||||
}
|
||||
|
||||
public NacosDelayTaskExecuteEngine(String name, Logger logger, long processInterval) {
|
||||
this(name, 32, logger, processInterval);
|
||||
}
|
||||
|
||||
public NacosDelayTaskExecuteEngine(String name, int initCapacity, Logger logger) {
|
||||
this(name, initCapacity, logger, 100L);
|
||||
}
|
||||
|
||||
public NacosDelayTaskExecuteEngine(String name, int initCapacity, Logger logger, long processInterval) {
|
||||
super(logger);
|
||||
tasks = new ConcurrentHashMap<Object, AbstractDelayTask>(initCapacity);
|
||||
processingExecutor = ExecutorFactory.newSingleScheduledExecutorService(new NameThreadFactory(name));
|
||||
processingExecutor
|
||||
.scheduleWithFixedDelay(new ProcessRunnable(), processInterval, processInterval, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
lock.lock();
|
||||
try {
|
||||
return tasks.size();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
lock.lock();
|
||||
try {
|
||||
return tasks.isEmpty();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDelayTask removeTask(Object key) {
|
||||
lock.lock();
|
||||
try {
|
||||
AbstractDelayTask task = tasks.get(key);
|
||||
if (null != task && task.shouldProcess()) {
|
||||
return tasks.remove(key);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> getAllTaskKeys() {
|
||||
Collection<Object> keys = new HashSet<Object>();
|
||||
lock.lock();
|
||||
try {
|
||||
keys.addAll(tasks.keySet());
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
processingExecutor.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTask(Object key, AbstractDelayTask newTask) {
|
||||
lock.lock();
|
||||
try {
|
||||
AbstractDelayTask existTask = tasks.get(key);
|
||||
if (null != existTask) {
|
||||
newTask.merge(existTask);
|
||||
}
|
||||
tasks.put(key, newTask);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* process tasks in execute engine.
|
||||
*/
|
||||
protected void processTasks() {
|
||||
Collection<Object> keys = getAllTaskKeys();
|
||||
for (Object taskKey : keys) {
|
||||
AbstractDelayTask task = removeTask(taskKey);
|
||||
if (null == task) {
|
||||
continue;
|
||||
}
|
||||
NacosTaskProcessor processor = getProcessor(taskKey);
|
||||
if (null == processor) {
|
||||
getEngineLog().error("processor not found for task, so discarded. " + task);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
// ReAdd task if process failed
|
||||
if (!processor.process(task)) {
|
||||
retryFailedTask(taskKey, task);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
getEngineLog().error("Nacos task execute error : " + e.toString(), e);
|
||||
retryFailedTask(taskKey, task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void retryFailedTask(Object key, AbstractDelayTask task) {
|
||||
task.setLastProcessTime(System.currentTimeMillis());
|
||||
addTask(key, task);
|
||||
}
|
||||
|
||||
private class ProcessRunnable implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
processTasks();
|
||||
} catch (Throwable e) {
|
||||
getEngineLog().error(e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.task.engine;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.task.AbstractExecuteTask;
|
||||
import com.alibaba.nacos.common.task.NacosTaskProcessor;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Nacos execute task execute engine.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class NacosExecuteTaskExecuteEngine extends AbstractNacosTaskExecuteEngine<AbstractExecuteTask> {
|
||||
|
||||
private final TaskExecuteWorker[] executeWorkers;
|
||||
|
||||
public NacosExecuteTaskExecuteEngine(String name, Logger logger) {
|
||||
this(name, logger, ThreadUtils.getSuitableThreadCount(1));
|
||||
}
|
||||
|
||||
public NacosExecuteTaskExecuteEngine(String name, Logger logger, int dispatchWorkerCount) {
|
||||
super(logger);
|
||||
executeWorkers = new TaskExecuteWorker[dispatchWorkerCount];
|
||||
for (int mod = 0; mod < dispatchWorkerCount; ++mod) {
|
||||
executeWorkers[mod] = new TaskExecuteWorker(name, mod, dispatchWorkerCount, getEngineLog());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
int result = 0;
|
||||
for (TaskExecuteWorker each : executeWorkers) {
|
||||
result += each.pendingTaskCount();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return 0 == size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTask(Object tag, AbstractExecuteTask task) {
|
||||
NacosTaskProcessor processor = getProcessor(tag);
|
||||
if (null != processor) {
|
||||
processor.process(task);
|
||||
return;
|
||||
}
|
||||
TaskExecuteWorker worker = getWorker(tag);
|
||||
worker.process(task);
|
||||
}
|
||||
|
||||
private TaskExecuteWorker getWorker(Object tag) {
|
||||
int idx = (tag.hashCode() & Integer.MAX_VALUE) % workersCount();
|
||||
return executeWorkers[idx];
|
||||
}
|
||||
|
||||
private int workersCount() {
|
||||
return executeWorkers.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractExecuteTask removeTask(Object key) {
|
||||
throw new UnsupportedOperationException("ExecuteTaskEngine do not support remove task");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> getAllTaskKeys() {
|
||||
throw new UnsupportedOperationException("ExecuteTaskEngine do not support get all task keys");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
for (TaskExecuteWorker each : executeWorkers) {
|
||||
each.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get workers status.
|
||||
*
|
||||
* @return workers status string
|
||||
*/
|
||||
public String workersStatus() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (TaskExecuteWorker worker : executeWorkers) {
|
||||
sb.append(worker.status()).append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.task.engine;
|
||||
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.task.NacosTask;
|
||||
import com.alibaba.nacos.common.task.NacosTaskProcessor;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Nacos task execute engine.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface NacosTaskExecuteEngine<T extends NacosTask> extends Closeable {
|
||||
|
||||
/**
|
||||
* Get Task size in execute engine.
|
||||
*
|
||||
* @return size of task
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Whether the execute engine is empty.
|
||||
*
|
||||
* @return true if the execute engine has no task to do, otherwise false
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Add task processor {@link NacosTaskProcessor} for execute engine.
|
||||
*
|
||||
* @param key key of task
|
||||
* @param taskProcessor task processor
|
||||
*/
|
||||
void addProcessor(Object key, NacosTaskProcessor taskProcessor);
|
||||
|
||||
/**
|
||||
* Remove task processor {@link NacosTaskProcessor} form execute engine for key.
|
||||
*
|
||||
* @param key key of task
|
||||
*/
|
||||
void removeProcessor(Object key);
|
||||
|
||||
/**
|
||||
* Try to get {@link NacosTaskProcessor} by key, if non-exist, will return default processor.
|
||||
*
|
||||
* @param key key of task
|
||||
* @return task processor for task key or default processor if task processor for task key non-exist
|
||||
*/
|
||||
NacosTaskProcessor getProcessor(Object key);
|
||||
|
||||
/**
|
||||
* Get all processor key.
|
||||
*
|
||||
* @return collection of processors
|
||||
*/
|
||||
Collection<Object> getAllProcessorKey();
|
||||
|
||||
/**
|
||||
* Set default task processor. If do not find task processor by task key, use this default processor to process
|
||||
* task.
|
||||
*
|
||||
* @param defaultTaskProcessor default task processor
|
||||
*/
|
||||
void setDefaultTaskProcessor(NacosTaskProcessor defaultTaskProcessor);
|
||||
|
||||
/**
|
||||
* Add task into execute pool.
|
||||
*
|
||||
* @param key key of task
|
||||
* @param task task
|
||||
*/
|
||||
void addTask(Object key, T task);
|
||||
|
||||
/**
|
||||
* Remove task.
|
||||
*
|
||||
* @param key key of task
|
||||
* @return nacos task
|
||||
*/
|
||||
T removeTask(Object key);
|
||||
|
||||
/**
|
||||
* Get all task keys.
|
||||
*
|
||||
* @return collection of task keys.
|
||||
*/
|
||||
Collection<Object> getAllTaskKeys();
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.task.engine;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.task.AbstractExecuteTask;
|
||||
import com.alibaba.nacos.common.task.NacosTask;
|
||||
import com.alibaba.nacos.common.task.NacosTaskProcessor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Nacos execute task execute worker.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public final class TaskExecuteWorker implements NacosTaskProcessor, Closeable {
|
||||
|
||||
/**
|
||||
* Max task queue size 32768.
|
||||
*/
|
||||
private static final int QUEUE_CAPACITY = 1 << 15;
|
||||
|
||||
private final Logger log;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final BlockingQueue<Runnable> queue;
|
||||
|
||||
private final AtomicBoolean closed;
|
||||
|
||||
public TaskExecuteWorker(final String name, final int mod, final int total) {
|
||||
this(name, mod, total, null);
|
||||
}
|
||||
|
||||
public TaskExecuteWorker(final String name, final int mod, final int total, final Logger logger) {
|
||||
this.name = name + "_" + mod + "%" + total;
|
||||
this.queue = new ArrayBlockingQueue<Runnable>(QUEUE_CAPACITY);
|
||||
this.closed = new AtomicBoolean(false);
|
||||
this.log = null == logger ? LoggerFactory.getLogger(TaskExecuteWorker.class) : logger;
|
||||
new InnerWorker(name).start();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(NacosTask task) {
|
||||
if (task instanceof AbstractExecuteTask) {
|
||||
putTask((Runnable) task);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void putTask(Runnable task) {
|
||||
try {
|
||||
queue.put(task);
|
||||
} catch (InterruptedException ire) {
|
||||
log.error(ire.toString(), ire);
|
||||
}
|
||||
}
|
||||
|
||||
public int pendingTaskCount() {
|
||||
return queue.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Worker status.
|
||||
*/
|
||||
public String status() {
|
||||
return name + ", pending tasks: " + pendingTaskCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
queue.clear();
|
||||
closed.compareAndSet(false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner execute worker.
|
||||
*/
|
||||
private class InnerWorker extends Thread {
|
||||
|
||||
InnerWorker(String name) {
|
||||
setDaemon(false);
|
||||
setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!closed.get()) {
|
||||
try {
|
||||
Runnable task = queue.take();
|
||||
long begin = System.currentTimeMillis();
|
||||
task.run();
|
||||
long duration = System.currentTimeMillis() - begin;
|
||||
if (duration > 1000L) {
|
||||
log.warn("distro task {} takes {}ms", task, duration);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
log.error("[DISTRO-FAILED] " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.tls;
|
||||
|
||||
import com.alibaba.nacos.common.utils.IpUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* A HostnameVerifier verify ipv4 and localhost.
|
||||
*
|
||||
* @author wangwei
|
||||
*/
|
||||
|
||||
public final class SelfHostnameVerifier implements HostnameVerifier {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SelfHostnameVerifier.class);
|
||||
|
||||
private final HostnameVerifier hv;
|
||||
|
||||
private static ConcurrentHashMap<String, Boolean> hosts = new ConcurrentHashMap<String, Boolean>();
|
||||
|
||||
private static final String[] LOCALHOST_HOSTNAME = new String[] {"localhost", "127.0.0.1"};
|
||||
|
||||
public SelfHostnameVerifier(HostnameVerifier hv) {
|
||||
this.hv = hv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
if (LOCALHOST_HOSTNAME[0].equalsIgnoreCase(hostname) || LOCALHOST_HOSTNAME[1].equals(hostname)) {
|
||||
return true;
|
||||
}
|
||||
if (isIpv4(hostname)) {
|
||||
return true;
|
||||
}
|
||||
return hv.verify(hostname, session);
|
||||
}
|
||||
|
||||
private static boolean isIpv4(String host) {
|
||||
if (host == null || host.isEmpty()) {
|
||||
LOGGER.warn("host is empty, isIPv4 = false");
|
||||
return false;
|
||||
}
|
||||
Boolean cacheHostVerify = hosts.get(host);
|
||||
if (cacheHostVerify != null) {
|
||||
return cacheHostVerify;
|
||||
}
|
||||
boolean isIp = IpUtils.isIpv4(host);
|
||||
hosts.putIfAbsent(host, isIp);
|
||||
return isIp;
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.tls;
|
||||
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A TrustManager tool returns the specified TrustManager.
|
||||
*
|
||||
* @author wangwei
|
||||
*/
|
||||
public final class SelfTrustManager {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SelfTrustManager.class);
|
||||
|
||||
@SuppressWarnings("checkstyle:WhitespaceAround")
|
||||
static TrustManager[] trustAll = new TrustManager[] {new X509TrustManager() {
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
}};
|
||||
|
||||
/**
|
||||
* Returns the result of calling {@link #buildSecureTrustManager} if {@code needAuth} is enable and {@code
|
||||
* trustCertPath} exists. Returns the {@link trustAll} otherwise.
|
||||
*
|
||||
* @param needAuth whether need client auth
|
||||
* @param trustCertPath trust certificate path
|
||||
* @return Array of {@link TrustManager }
|
||||
*/
|
||||
public static TrustManager[] trustManager(boolean needAuth, String trustCertPath) {
|
||||
if (needAuth) {
|
||||
try {
|
||||
return trustCertPath == null ? null : buildSecureTrustManager(trustCertPath);
|
||||
} catch (SSLException e) {
|
||||
LOGGER.warn("degrade trust manager as build failed, " + "will trust all certs.");
|
||||
return trustAll;
|
||||
}
|
||||
} else {
|
||||
return trustAll;
|
||||
}
|
||||
}
|
||||
|
||||
private static TrustManager[] buildSecureTrustManager(String trustCertPath) throws SSLException {
|
||||
TrustManagerFactory selfTmf;
|
||||
InputStream in = null;
|
||||
|
||||
try {
|
||||
String algorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||
selfTmf = TrustManagerFactory.getInstance(algorithm);
|
||||
|
||||
KeyStore trustKeyStore = KeyStore.getInstance("JKS");
|
||||
trustKeyStore.load(null, null);
|
||||
|
||||
in = new FileInputStream(trustCertPath);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
|
||||
Collection<X509Certificate> certs = (Collection<X509Certificate>) cf.generateCertificates(in);
|
||||
int count = 0;
|
||||
for (Certificate cert : certs) {
|
||||
trustKeyStore.setCertificateEntry("cert-" + (count++), cert);
|
||||
}
|
||||
|
||||
selfTmf.init(trustKeyStore);
|
||||
return selfTmf.getTrustManagers();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("build client trustManagerFactory failed", e);
|
||||
throw new SSLException(e);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.tls;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||
import com.alibaba.nacos.common.utils.ClassUtils;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Certificate file update monitoring
|
||||
*
|
||||
* <p>Considering that the current client needs to support jdk 1.6 and module dependencies ,
|
||||
* the WatchFileCenter in the core module is not used
|
||||
*
|
||||
* @author wangwei
|
||||
*/
|
||||
public final class TlsFileWatcher {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TlsFileWatcher.class);
|
||||
|
||||
private AtomicBoolean started = new AtomicBoolean(false);
|
||||
|
||||
private final int checkInterval = TlsSystemConfig.tlsFileCheckInterval;
|
||||
|
||||
private Map<String, String> fileMd5Map = new HashMap<String, String>();
|
||||
|
||||
private ConcurrentHashMap<String, FileChangeListener> watchFilesMap = new ConcurrentHashMap<String, FileChangeListener>();
|
||||
|
||||
private final ScheduledExecutorService service = ExecutorFactory.Managed
|
||||
.newSingleScheduledExecutorService(ClassUtils.getCanonicalName(TlsFileWatcher.class),
|
||||
new NameThreadFactory("com.alibaba.nacos.core.common.tls"));
|
||||
|
||||
private static TlsFileWatcher tlsFileWatcher = new TlsFileWatcher();
|
||||
|
||||
private TlsFileWatcher() {
|
||||
start();
|
||||
}
|
||||
|
||||
public static TlsFileWatcher getInstance() {
|
||||
return tlsFileWatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add file change listener for specified path.
|
||||
*
|
||||
* @param fileChangeListener listener
|
||||
* @param filePaths file paths
|
||||
* @throws IOException If an I/O error occurs
|
||||
*/
|
||||
public void addFileChangeListener(FileChangeListener fileChangeListener, String... filePaths) throws IOException {
|
||||
for (String filePath : filePaths) {
|
||||
if (filePath != null && new File(filePath).exists()) {
|
||||
watchFilesMap.put(filePath, fileChangeListener);
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(filePath);
|
||||
fileMd5Map.put(filePath, MD5Utils.md5Hex(IoUtils.toString(in, Constants.ENCODE), Constants.ENCODE));
|
||||
} finally {
|
||||
IoUtils.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* start file watch task. Notify when the MD5 of file changed
|
||||
*/
|
||||
public void start() {
|
||||
if (started.compareAndSet(false, true)) {
|
||||
service.scheduleAtFixedRate(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Map.Entry<String, FileChangeListener> item : watchFilesMap.entrySet()) {
|
||||
String filePath = item.getKey();
|
||||
String newHash;
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(filePath);
|
||||
newHash = MD5Utils.md5Hex(IoUtils.toString(in, Constants.ENCODE), Constants.ENCODE);
|
||||
} catch (Exception ignored) {
|
||||
LOGGER.warn(" service has exception when calculate the file MD5. " + ignored);
|
||||
continue;
|
||||
} finally {
|
||||
IoUtils.closeQuietly(in);
|
||||
}
|
||||
if (!newHash.equals(fileMd5Map.get(filePath))) {
|
||||
LOGGER.info(filePath + " file hash changed,need reload sslcontext");
|
||||
fileMd5Map.put(filePath, newHash);
|
||||
item.getValue().onChanged(filePath);
|
||||
LOGGER.info(filePath + " onChanged success!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1, checkInterval, TimeUnit.MINUTES);
|
||||
}
|
||||
}
|
||||
|
||||
public interface FileChangeListener {
|
||||
|
||||
/**
|
||||
* listener onChanged event.
|
||||
*
|
||||
* @param filePath Path of changed file
|
||||
*/
|
||||
void onChanged(String filePath);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.tls;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* Utils for build {@link SSLContext}.
|
||||
*
|
||||
* <p>Currently only supports client-side
|
||||
*
|
||||
* <h3>Making your client support TLS without authentication</h3>
|
||||
* <pre>
|
||||
* System.setProperty({@link TlsSystemConfig#TLS_ENABLE}, "true");
|
||||
* </pre>
|
||||
*
|
||||
* <h3>Making your client support TLS one-way authentication</h3>
|
||||
*
|
||||
* <pre>
|
||||
* System.setProperty({@link TlsSystemConfig#TLS_ENABLE}, "true");
|
||||
* System.setProperty({@link TlsSystemConfig#CLIENT_AUTH}, "true");
|
||||
* System.setProperty({@link TlsSystemConfig#CLIENT_TRUST_CERT}, "trustCert");
|
||||
* </pre>
|
||||
*
|
||||
* @author wangwei
|
||||
* @date 2020/8/19 2:59 PM
|
||||
*/
|
||||
public final class TlsHelper {
|
||||
|
||||
/**
|
||||
* Returns a {@link org.apache.http.ssl.SSLContexts}.
|
||||
*
|
||||
* <p>For example</p>
|
||||
* <code>HttpsURLConnection.setDefaultSSLSocketFactory(TlsHelper.buildSslContext(true).getSocketFactory());</code>
|
||||
*
|
||||
* @param forClient whether for client
|
||||
* @return {@link SSLContext}
|
||||
* @throws NoSuchAlgorithmException Not support the specified algorithm
|
||||
* @throws KeyManagementException KeyManagement exception
|
||||
*/
|
||||
public static SSLContext buildSslContext(boolean forClient)
|
||||
throws NoSuchAlgorithmException, KeyManagementException {
|
||||
|
||||
SSLContext sslcontext = SSLContext.getInstance("TLS");
|
||||
sslcontext.init(null, SelfTrustManager
|
||||
.trustManager(TlsSystemConfig.tlsClientAuthServer, TlsSystemConfig.tlsClientTrustCertPath),
|
||||
new java.security.SecureRandom());
|
||||
return sslcontext;
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.tls;
|
||||
|
||||
/**
|
||||
* tls system config.
|
||||
*
|
||||
* @author wangwei
|
||||
*/
|
||||
public final class TlsSystemConfig {
|
||||
|
||||
public static final String TLS_TEST_MODE_ENABLE = "tls.test";
|
||||
|
||||
public static final String TLS_ENABLE = "tls.enable";
|
||||
|
||||
public static final String CLIENT_AUTH = "tls.client.authServer";
|
||||
|
||||
public static final String CLIENT_KEYPATH = "tls.client.keyPath";
|
||||
|
||||
public static final String CLIENT_KEYPASSWORD = "tls.client.keyPassword";
|
||||
|
||||
public static final String CLIENT_CERTPATH = "tls.client.certPath";
|
||||
|
||||
public static final String CLIENT_TRUST_CERT = "tls.client.trustCertPath";
|
||||
|
||||
public static final String SERVER_AUTH = "tls.server.authClient";
|
||||
|
||||
public static final String SERVER_KEYPATH = "tls.server.keyPath";
|
||||
|
||||
public static final String SERVER_KEYPASSWORD = "tls.server.keyPassword";
|
||||
|
||||
public static final String SERVER_CERTPATH = "tls.server.certPath";
|
||||
|
||||
public static final String SERVER_TRUST_CERT = "tls.server.trustCertPath";
|
||||
|
||||
public static final String CHECK_INTERVAL = "checkIntervalTlsFile";
|
||||
|
||||
/**
|
||||
* To determine whether use SSL in client-side.
|
||||
*/
|
||||
public static boolean tlsEnable = Boolean.parseBoolean(System.getProperty(TLS_ENABLE, "false"));
|
||||
|
||||
/**
|
||||
* To determine whether use test mode when initialize TLS context.
|
||||
*/
|
||||
public static boolean tlsTestModeEnable = Boolean.parseBoolean(System.getProperty(TLS_TEST_MODE_ENABLE, "false"));
|
||||
|
||||
/**
|
||||
* To determine whether verify the server endpoint's certificate strictly.
|
||||
*/
|
||||
public static boolean tlsClientAuthServer = Boolean.parseBoolean(System.getProperty(CLIENT_AUTH, "false"));
|
||||
|
||||
/**
|
||||
* To determine whether verify the client endpoint's certificate strictly.
|
||||
*/
|
||||
public static boolean tlsServerAuthClient = Boolean.parseBoolean(System.getProperty(SERVER_AUTH, "false"));
|
||||
|
||||
/**
|
||||
* The store path of client-side private key.
|
||||
*/
|
||||
public static String tlsClientKeyPath = System.getProperty(CLIENT_KEYPATH, null);
|
||||
|
||||
/**
|
||||
* The password of the client-side private key.
|
||||
*/
|
||||
public static String tlsClientKeyPassword = System.getProperty(CLIENT_KEYPASSWORD, null);
|
||||
|
||||
/**
|
||||
* The store path of client-side X.509 certificate chain in PEM format.
|
||||
*/
|
||||
public static String tlsClientCertPath = System.getProperty(CLIENT_CERTPATH, null);
|
||||
|
||||
/**
|
||||
* The store path of trusted certificates for verifying the server endpoint's certificate.
|
||||
*/
|
||||
public static String tlsClientTrustCertPath = System.getProperty(CLIENT_TRUST_CERT, null);
|
||||
|
||||
/**
|
||||
* The store path of server-side private key.
|
||||
*/
|
||||
public static String tlsServerKeyPath = System.getProperty(SERVER_KEYPATH, null);
|
||||
|
||||
/**
|
||||
* The password of the server-side private key.
|
||||
*/
|
||||
public static String tlsServerKeyPassword = System.getProperty(SERVER_KEYPASSWORD, null);
|
||||
|
||||
/**
|
||||
* The store path of server-side X.509 certificate chain in PEM format.
|
||||
*/
|
||||
public static String tlsServerCertPath = System.getProperty(SERVER_CERTPATH, null);
|
||||
|
||||
/**
|
||||
* The store path of trusted certificates for verifying the client endpoint's certificate.
|
||||
*/
|
||||
public static String tlsServerTrustCertPath = System.getProperty(SERVER_TRUST_CERT, null);
|
||||
|
||||
/**
|
||||
* tls file check interval , default is 10 min.
|
||||
*/
|
||||
public static int tlsFileCheckInterval = Integer.parseInt(System.getProperty(CHECK_INTERVAL, "10"));
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
/**
|
||||
* Represents an operation that accepts two input arguments and returns no result.
|
||||
*
|
||||
* @author wangwei
|
||||
*/
|
||||
public interface BiConsumer<T, U> {
|
||||
|
||||
/**
|
||||
* Performs this operation on the given arguments.
|
||||
*
|
||||
* @param t the first input argument
|
||||
* @param u the second input argument
|
||||
*/
|
||||
void accept(T t, U u);
|
||||
}
|
@ -51,7 +51,11 @@ public final class ConvertUtils {
|
||||
if (StringUtils.isBlank(val)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Integer.parseInt(val);
|
||||
try {
|
||||
return Integer.parseInt(val);
|
||||
} catch (NumberFormatException exception) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +81,11 @@ public final class ConvertUtils {
|
||||
if (StringUtils.isBlank(val)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Long.parseLong(val);
|
||||
try {
|
||||
return Long.parseLong(val);
|
||||
} catch (NumberFormatException exception) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,7 +100,11 @@ public final class ConvertUtils {
|
||||
if (StringUtils.isBlank(val)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Boolean.parseBoolean(val);
|
||||
try {
|
||||
return Boolean.parseBoolean(val);
|
||||
} catch (NumberFormatException exception) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
// The following utility functions are extracted from <link>org.apache.commons.lang3</link>
|
||||
@ -126,7 +138,7 @@ public final class ConvertUtils {
|
||||
* @return the boolean value of the string, {@code false} if no match or the String is null
|
||||
*/
|
||||
public static boolean toBoolean(final String str) {
|
||||
return toBooleanObject(str) == Boolean.TRUE;
|
||||
return Boolean.TRUE.equals(toBooleanObject(str));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,8 +26,10 @@ public class HttpMethod {
|
||||
|
||||
public static final String GET = "GET";
|
||||
|
||||
// this is only use in nacos, Custom request type, essentially a get request
|
||||
|
||||
/**
|
||||
* this is only use in nacos, Custom request type, essentially a GET request, Mainly used for GET request parameters
|
||||
* are relatively large,can not be placed on the URL, so it needs to be placed in the body.
|
||||
*/
|
||||
public static final String GET_LARGE = "GET-LARGE";
|
||||
|
||||
public static final String HEAD = "HEAD";
|
||||
@ -40,6 +42,12 @@ public class HttpMethod {
|
||||
|
||||
public static final String DELETE = "DELETE";
|
||||
|
||||
/**
|
||||
* this is only use in nacos, Custom request type, essentially a DELETE request, Mainly used for DELETE request
|
||||
* parameters are relatively large, can not be placed on the URL, so it needs to be placed in the body.
|
||||
*/
|
||||
public static final String DELETE_LARGE = "DELETE_LARGE";
|
||||
|
||||
public static final String OPTIONS = "OPTIONS";
|
||||
|
||||
public static final String TRACE = "TRACE";
|
||||
|
@ -50,9 +50,9 @@ public class IoUtils {
|
||||
*
|
||||
* @param raw compress stream
|
||||
* @return byte array after decompress
|
||||
* @throws Exception exception
|
||||
* @throws IOException exception
|
||||
*/
|
||||
public static byte[] tryDecompress(InputStream raw) throws Exception {
|
||||
public static byte[] tryDecompress(InputStream raw) throws IOException {
|
||||
GZIPInputStream gis = null;
|
||||
ByteArrayOutputStream out = null;
|
||||
try {
|
||||
@ -60,7 +60,7 @@ public class IoUtils {
|
||||
out = new ByteArrayOutputStream();
|
||||
copy(gis, out);
|
||||
return out.toByteArray();
|
||||
} catch (Exception e) {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
|
@ -14,9 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -26,7 +24,7 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class IpUtil {
|
||||
public class IpUtils {
|
||||
|
||||
private static final Pattern IPV4_PATTERN = Pattern
|
||||
.compile("^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$");
|
||||
@ -48,4 +46,4 @@ public class IpUtil {
|
||||
Matcher mat = pattern.matcher(data);
|
||||
return mat.find();
|
||||
}
|
||||
}
|
||||
}
|
@ -129,11 +129,11 @@ public class MapUtils {
|
||||
/**
|
||||
* ComputeIfAbsent lazy load.
|
||||
*
|
||||
* @param target target Map data.
|
||||
* @param key map key.
|
||||
* @param target target Map data.
|
||||
* @param key map key.
|
||||
* @param mappingFunction funtion which is need to be executed.
|
||||
* @param param1 function's parameter value1.
|
||||
* @param param2 function's parameter value1.
|
||||
* @param param1 function's parameter value1.
|
||||
* @param param2 function's parameter value1.
|
||||
* @return
|
||||
*/
|
||||
@NotThreadSafe
|
||||
@ -153,5 +153,4 @@ public class MapUtils {
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,9 +94,19 @@ public final class ThreadUtils {
|
||||
* @return thread count
|
||||
*/
|
||||
public static int getSuitableThreadCount() {
|
||||
return getSuitableThreadCount(THREAD_MULTIPLER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Through the number of cores, calculate the appropriate number of threads.
|
||||
*
|
||||
* @param threadMultiple multiple time of cores
|
||||
* @return thread count
|
||||
*/
|
||||
public static int getSuitableThreadCount(int threadMultiple) {
|
||||
final int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
int workerCount = 1;
|
||||
while (workerCount < coreCount * THREAD_MULTIPLER) {
|
||||
while (workerCount < coreCount * threadMultiple) {
|
||||
workerCount <<= 1;
|
||||
}
|
||||
return workerCount;
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Comparator;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
@ -55,4 +56,36 @@ public class VersionUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final Comparator<String> STRING_COMPARATOR = new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return o1.compareTo(o2);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* compare two version who is latest.
|
||||
*
|
||||
* @param versionA version A, like x.y.z(-beta)
|
||||
* @param versionB version B, like x.y.z(-beta)
|
||||
* @return compare result
|
||||
*/
|
||||
public static int compareVersion(final String versionA, final String versionB) {
|
||||
final String[] sA = versionA.split("\\.");
|
||||
final String[] sB = versionB.split("\\.");
|
||||
int expectSize = 3;
|
||||
if (sA.length != expectSize || sB.length != expectSize) {
|
||||
throw new IllegalArgumentException("version must be like x.y.z(-beta)");
|
||||
}
|
||||
int first = Objects.compare(sA[0], sB[0], STRING_COMPARATOR);
|
||||
if (first != 0) {
|
||||
return first;
|
||||
}
|
||||
int second = Objects.compare(sA[1], sB[1], STRING_COMPARATOR);
|
||||
if (second != 0) {
|
||||
return second;
|
||||
}
|
||||
return Objects.compare(sA[2].split("-")[0], sB[2].split("-")[0], STRING_COMPARATOR);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.param;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* MediaTypeTest.
|
||||
*
|
||||
* @author mai.jh
|
||||
*/
|
||||
public class MediaTypeTest {
|
||||
|
||||
@Test
|
||||
public void testValueOf() {
|
||||
MediaType mediaType = MediaType.valueOf(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
String type = "application/x-www-form-urlencoded";
|
||||
String charset = "UTF-8";
|
||||
assertEquals(type, mediaType.getType());
|
||||
assertEquals(charset, mediaType.getCharset());
|
||||
assertEquals(MediaType.APPLICATION_FORM_URLENCODED, mediaType.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueOf2() {
|
||||
MediaType mediaType = MediaType.valueOf(MediaType.APPLICATION_FORM_URLENCODED, "ISO-8859-1");
|
||||
String type = "application/x-www-form-urlencoded";
|
||||
String charset = "ISO-8859-1";
|
||||
String excepted = "application/x-www-form-urlencoded;charset=ISO-8859-1";
|
||||
assertEquals(type, mediaType.getType());
|
||||
assertEquals(charset, mediaType.getCharset());
|
||||
assertEquals(excepted, mediaType.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueOf3() {
|
||||
MediaType mediaType = MediaType.valueOf("application/x-www-form-urlencoded", "ISO-8859-1");
|
||||
String type = "application/x-www-form-urlencoded";
|
||||
String charset = "ISO-8859-1";
|
||||
String excepted = "application/x-www-form-urlencoded;charset=ISO-8859-1";
|
||||
assertEquals(type, mediaType.getType());
|
||||
assertEquals(charset, mediaType.getCharset());
|
||||
assertEquals(excepted, mediaType.toString());
|
||||
}
|
||||
|
||||
}
|
@ -132,6 +132,7 @@ public class NotifyCenterTest {
|
||||
return ExpireEvent.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoreExpireEvent() {
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.task.engine;
|
||||
|
||||
import com.alibaba.nacos.common.task.AbstractDelayTask;
|
||||
import com.alibaba.nacos.common.task.NacosTaskProcessor;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.internal.verification.Times;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NacosDelayTaskExecuteEngineTest {
|
||||
|
||||
private NacosDelayTaskExecuteEngine nacosDelayTaskExecuteEngine;
|
||||
|
||||
@Mock
|
||||
private NacosTaskProcessor taskProcessor;
|
||||
|
||||
@Mock
|
||||
private NacosTaskProcessor testTaskProcessor;
|
||||
|
||||
private AbstractDelayTask abstractTask;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
nacosDelayTaskExecuteEngine = new NacosDelayTaskExecuteEngine(NacosDelayTaskExecuteEngineTest.class.getName());
|
||||
nacosDelayTaskExecuteEngine.setDefaultTaskProcessor(taskProcessor);
|
||||
abstractTask = new AbstractDelayTask() {
|
||||
@Override
|
||||
public void merge(AbstractDelayTask task) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
nacosDelayTaskExecuteEngine.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSize() {
|
||||
assertEquals(0, nacosDelayTaskExecuteEngine.size());
|
||||
nacosDelayTaskExecuteEngine.addTask("test", abstractTask);
|
||||
assertEquals(1, nacosDelayTaskExecuteEngine.size());
|
||||
nacosDelayTaskExecuteEngine.removeTask("test");
|
||||
assertEquals(0, nacosDelayTaskExecuteEngine.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsEmpty() {
|
||||
assertTrue(nacosDelayTaskExecuteEngine.isEmpty());
|
||||
nacosDelayTaskExecuteEngine.addTask("test", abstractTask);
|
||||
assertFalse(nacosDelayTaskExecuteEngine.isEmpty());
|
||||
nacosDelayTaskExecuteEngine.removeTask("test");
|
||||
assertTrue(nacosDelayTaskExecuteEngine.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddProcessor() throws InterruptedException {
|
||||
when(testTaskProcessor.process(abstractTask)).thenReturn(true);
|
||||
nacosDelayTaskExecuteEngine.addProcessor("test", testTaskProcessor);
|
||||
nacosDelayTaskExecuteEngine.addTask("test", abstractTask);
|
||||
TimeUnit.MILLISECONDS.sleep(200);
|
||||
verify(testTaskProcessor).process(abstractTask);
|
||||
verify(taskProcessor, never()).process(abstractTask);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveProcessor() throws InterruptedException {
|
||||
when(taskProcessor.process(abstractTask)).thenReturn(true);
|
||||
nacosDelayTaskExecuteEngine.addProcessor("test", testTaskProcessor);
|
||||
nacosDelayTaskExecuteEngine.removeProcessor("test");
|
||||
nacosDelayTaskExecuteEngine.addTask("test", abstractTask);
|
||||
TimeUnit.MILLISECONDS.sleep(200);
|
||||
verify(testTaskProcessor, never()).process(abstractTask);
|
||||
verify(taskProcessor).process(abstractTask);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetryTaskAfterFail() throws InterruptedException {
|
||||
when(taskProcessor.process(abstractTask)).thenReturn(false, true);
|
||||
nacosDelayTaskExecuteEngine.addTask("test", abstractTask);
|
||||
TimeUnit.MILLISECONDS.sleep(300);
|
||||
verify(taskProcessor, new Times(2)).process(abstractTask);
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.task.engine;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.task.AbstractExecuteTask;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NacosExecuteTaskExecuteEngineTest {
|
||||
|
||||
private NacosExecuteTaskExecuteEngine executeTaskExecuteEngine;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
executeTaskExecuteEngine = new NacosExecuteTaskExecuteEngine("TEST", null);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws NacosException {
|
||||
executeTaskExecuteEngine.shutdown();
|
||||
}
|
||||
|
||||
@Mock
|
||||
private AbstractExecuteTask task;
|
||||
|
||||
@Test
|
||||
public void testAddTask() throws InterruptedException {
|
||||
executeTaskExecuteEngine.addTask("test", task);
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
verify(task).run();
|
||||
assertTrue(executeTaskExecuteEngine.isEmpty());
|
||||
assertEquals(0, executeTaskExecuteEngine.size());
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.utils;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class VersionUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testVersionCompareLt() {
|
||||
final String versionA = "1.2.0";
|
||||
final String versionB = "1.2.1";
|
||||
Assert.assertTrue(VersionUtils.compareVersion(versionA, versionB) < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionCompareGt() {
|
||||
final String versionA = "1.2.2";
|
||||
final String versionB = "1.2.1";
|
||||
Assert.assertTrue(VersionUtils.compareVersion(versionA, versionB) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionCompareEt() {
|
||||
final String versionA = "1.2.1";
|
||||
final String versionB = "1.2.1";
|
||||
Assert.assertEquals(0, VersionUtils.compareVersion(versionA, versionB));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionCompareLtWithChar() {
|
||||
final String versionA = "1.2.0-beta";
|
||||
final String versionB = "1.2.1";
|
||||
Assert.assertTrue(VersionUtils.compareVersion(versionA, versionB) < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionCompareGtWithChar() {
|
||||
final String versionA = "1.2.2-beta";
|
||||
final String versionB = "1.2.1-beta";
|
||||
Assert.assertTrue(VersionUtils.compareVersion(versionA, versionB) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionCompareEtWithChar() {
|
||||
final String versionA = "1.2.1";
|
||||
final String versionB = "1.2.1-beta";
|
||||
Assert.assertEquals(0, VersionUtils.compareVersion(versionA, versionB));
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user