[ISSUE #2992] use new code style for nacos-common (#3106)

* use new code style for nacos-common

* Fix code style file can't set java import problem.
This commit is contained in:
杨翊 SionYang 2020-06-18 17:05:15 +08:00 committed by GitHub
parent 38d0b6bdbe
commit f864880136
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
77 changed files with 2619 additions and 2347 deletions

View File

@ -193,7 +193,7 @@ public class HttpSimpleClient {
conn.addRequestProperty(iter.next(), iter.next());
}
}
conn.addRequestProperty(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.VERSION);
conn.addRequestProperty(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version);
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding);
String ts = String.valueOf(System.currentTimeMillis());

View File

@ -72,7 +72,7 @@ public class Log4J2NacosLogging extends AbstractNacosLogging {
private Configuration loadConfiguration(LoggerContext loggerContext, String location) {
try {
URL url = ResourceUtils.getResourceURL(location);
URL url = ResourceUtils.getResourceUrl(location);
ConfigurationSource source = getConfigurationSource(url);
// since log4j 2.7 getConfiguration(LoggerContext loggerContext, ConfigurationSource source)
return ConfigurationFactory.getInstance().getConfiguration(loggerContext, source);

View File

@ -41,7 +41,7 @@ public class LogbackNacosLogging extends AbstractNacosLogging {
try {
LoggerContext loggerContext = (LoggerContext)StaticLoggerBinder.getSingleton().getLoggerFactory();
new ContextInitializer(loggerContext).configureByResource(ResourceUtils.getResourceURL(location));
new ContextInitializer(loggerContext).configureByResource(ResourceUtils.getResourceUrl(location));
} catch (Exception e) {
throw new IllegalStateException("Could not initialize Logback Nacos logging from " + location, e);
}

View File

@ -528,7 +528,7 @@ public class NamingProxy implements Closeable {
public List<String> builderHeaders() {
List<String> headers = Arrays.asList(
HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.VERSION,
HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version,
HttpHeaderConsts.USER_AGENT_HEADER, UtilAndComs.VERSION,
"Accept-Encoding", "gzip,deflate,sdch",
"Connection", "Keep-Alive",

View File

@ -22,7 +22,7 @@ import com.alibaba.nacos.common.utils.VersionUtils;
*/
public class UtilAndComs {
public static final String VERSION = "Nacos-Java-Client:v" + VersionUtils.VERSION;
public static final String VERSION = "Nacos-Java-Client:v" + VersionUtils.version;
public static String WEB_CONTEXT = "/nacos";

View File

@ -15,9 +15,9 @@
~ 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">
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>
@ -25,38 +25,38 @@
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos-common</artifactId>
<packaging>jar</packaging>
<name>nacos-common ${project.version}</name>
<url>http://nacos.io</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
@ -65,14 +65,14 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -17,7 +17,10 @@
package com.alibaba.nacos.common;
/**
* Just for test.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public @interface JustForTest {
}

View File

@ -13,15 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.constant;
/**
* Nacos header constants
* Nacos header constants.
*
* @author ly
*/
public interface HttpHeaderConsts {
String CLIENT_VERSION_HEADER = "Client-Version";
String USER_AGENT_HEADER = "User-Agent";
String REQUEST_SOURCE_HEADER = "Request-Source";
@ -33,5 +34,5 @@ public interface HttpHeaderConsts {
String CONNECTION = "Connection";
String REQUEST_ID = "RequestId";
String REQUEST_MODULE = "REQUEST_MODULE";
}

View File

@ -25,58 +25,54 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Unified thread pool creation factory, and actively create thread
* pool resources by ThreadPoolManager for unified life cycle management
* {@link ExecutorFactory.Managed}
* Unified thread pool creation factory, and actively create thread pool resources by ThreadPoolManager for unified life
* cycle management {@link ExecutorFactory.Managed}.
*
* Unified thread pool creation factory without life cycle management
* {@link ExecutorFactory}
* <p>Unified thread pool creation factory without life cycle management {@link ExecutorFactory}.
*
* <p>two check style ignore will be removed after issue#2856 finished.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("PMD.ThreadPoolCreationRule")
@SuppressWarnings({"PMD.ThreadPoolCreationRule", "checkstyle:overloadmethodsdeclarationorder",
"checkstyle:missingjavadocmethod"})
public final class ExecutorFactory {
private static final String DEFAULT_NAMESPACE = "nacos";
private static final ThreadPoolManager THREAD_POOL_MANAGER = ThreadPoolManager.getInstance();
public static ExecutorService newSingleExecutorService() {
return Executors.newFixedThreadPool(1);
}
public static ExecutorService newSingleExecutorService(final ThreadFactory threadFactory) {
return Executors.newFixedThreadPool(1, threadFactory);
}
public static ExecutorService newFixExecutorService(final int nThreads) {
public static ExecutorService newFixedExecutorService(final int nThreads) {
return Executors.newFixedThreadPool(nThreads);
}
public static ExecutorService newFixExecutorService(final int nThreads,
final ThreadFactory threadFactory) {
public static ExecutorService newFixedExecutorService(final int nThreads, final ThreadFactory threadFactory) {
return Executors.newFixedThreadPool(nThreads, threadFactory);
}
public static ScheduledExecutorService newSingleScheduledExecutorService(final ThreadFactory threadFactory) {
return Executors.newScheduledThreadPool(1, threadFactory);
}
public static ScheduledExecutorService newScheduledExecutorService( final int nThreads,
final ThreadFactory threadFactory) {
public static ScheduledExecutorService newScheduledExecutorService(final int nThreads,
final ThreadFactory threadFactory) {
return Executors.newScheduledThreadPool(nThreads, threadFactory);
}
public static ThreadPoolExecutor newCustomerThreadExecutor(
final int coreThreads,
final int maxThreads,
final long keepAliveTimeMs,
final ThreadFactory threadFactory) {
return new ThreadPoolExecutor(coreThreads, maxThreads,
keepAliveTimeMs, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
public static ThreadPoolExecutor newCustomerThreadExecutor(final int coreThreads, final int maxThreads,
final long keepAliveTimeMs, final ThreadFactory threadFactory) {
return new ThreadPoolExecutor(coreThreads, maxThreads, keepAliveTimeMs, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(), threadFactory);
}
//TODO remove Deprecated function after replace all module
@Deprecated
public static ExecutorService newSingleExecutorService(final String group) {
@ -84,114 +80,156 @@ public final class ExecutorFactory {
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
@Deprecated
public static ExecutorService newSingleExecutorService(final String group,
final ThreadFactory threadFactory) {
public static ExecutorService newSingleExecutorService(final String group, final ThreadFactory threadFactory) {
ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
@Deprecated
public static ExecutorService newFixExecutorService(final String group,
final int nThreads) {
public static ExecutorService newFixedExecutorService(final String group, final int nThreads) {
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
@Deprecated
public static ExecutorService newFixExecutorService(final String group,
final int nThreads,
final ThreadFactory threadFactory) {
public static ExecutorService newFixedExecutorService(final String group, final int nThreads,
final ThreadFactory threadFactory) {
ExecutorService executorService = Executors.newFixedThreadPool(nThreads, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
@Deprecated
public static ScheduledExecutorService newSingleScheduledExecutorService(final String group,
final ThreadFactory threadFactory) {
final ThreadFactory threadFactory) {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
@Deprecated
public static ScheduledExecutorService newScheduledExecutorService(final String group,
final int nThreads,
final ThreadFactory threadFactory) {
public static ScheduledExecutorService newScheduledExecutorService(final String group, final int nThreads,
final ThreadFactory threadFactory) {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(nThreads, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
@Deprecated
public static ThreadPoolExecutor newCustomerThreadExecutor(final String group,
final int coreThreads,
final int maxThreads,
final long keepAliveTimeMs,
final ThreadFactory threadFactory) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(coreThreads, maxThreads,
keepAliveTimeMs, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
public static ThreadPoolExecutor newCustomerThreadExecutor(final String group, final int coreThreads,
final int maxThreads, final long keepAliveTimeMs, final ThreadFactory threadFactory) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(coreThreads, maxThreads, keepAliveTimeMs,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executor);
return executor;
}
public final static class Managed{
public static final class Managed {
private static final String DEFAULT_NAMESPACE = "nacos";
private static final ThreadPoolManager THREAD_POOL_MANAGER = ThreadPoolManager.getInstance();
/**
* Create a new single executor service with default thread factory and register to manager.
*
* @param group group name
* @return new single executor service
*/
public static ExecutorService newSingleExecutorService(final String group) {
ExecutorService executorService = Executors.newFixedThreadPool(1);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ExecutorService newSingleExecutorService(final String group,
final ThreadFactory threadFactory) {
/**
* Create a new single executor service with input thread factory and register to manager.
*
* @param group group name
* @param threadFactory thread factory
* @return new single executor service
*/
public static ExecutorService newSingleExecutorService(final String group, final ThreadFactory threadFactory) {
ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ExecutorService newFixExecutorService(final String group,
final int nThreads) {
/**
* Create a new fixed executor service with default thread factory and register to manager.
*
* @param group group name
* @param nThreads thread number
* @return new fixed executor service
*/
public static ExecutorService newFixedExecutorService(final String group, final int nThreads) {
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ExecutorService newFixExecutorService(final String group,
final int nThreads,
final ThreadFactory threadFactory) {
/**
* Create a new fixed executor service with input thread factory and register to manager.
*
* @param group group name
* @param nThreads thread number
* @param threadFactory thread factory
* @return new fixed executor service
*/
public static ExecutorService newFixedExecutorService(final String group, final int nThreads,
final ThreadFactory threadFactory) {
ExecutorService executorService = Executors.newFixedThreadPool(nThreads, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
/**
* Create a new single scheduled executor service with input thread factory and register to manager.
*
* @param group group name
* @param threadFactory thread factory
* @return new single scheduled executor service
*/
public static ScheduledExecutorService newSingleScheduledExecutorService(final String group,
final ThreadFactory threadFactory) {
final ThreadFactory threadFactory) {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ScheduledExecutorService newScheduledExecutorService(final String group,
final int nThreads,
final ThreadFactory threadFactory) {
/**
* Create a new scheduled executor service with input thread factory and register to manager.
*
* @param group group name
* @param nThreads thread number
* @param threadFactory thread factory
* @return new scheduled executor service
*/
public static ScheduledExecutorService newScheduledExecutorService(final String group, final int nThreads,
final ThreadFactory threadFactory) {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(nThreads, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ThreadPoolExecutor newCustomerThreadExecutor(final String group,
final int coreThreads,
final int maxThreads,
final long keepAliveTimeMs,
final ThreadFactory threadFactory) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(coreThreads, maxThreads,
keepAliveTimeMs, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
/**
* Create a new custom executor service and register to manager.
*
* @param group group name
* @param coreThreads core thread number
* @param maxThreads max thread number
* @param keepAliveTimeMs keep alive time milliseconds
* @param threadFactory thread facotry
* @return new custom executor service
*/
public static ThreadPoolExecutor newCustomerThreadExecutor(final String group, final int coreThreads,
final int maxThreads, final long keepAliveTimeMs, final ThreadFactory threadFactory) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(coreThreads, maxThreads, keepAliveTimeMs,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executor);
return executor;
}

View File

@ -22,26 +22,28 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Name thread factory.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class NameThreadFactory implements ThreadFactory {
private final AtomicInteger id = new AtomicInteger(0);
private String name;
public NameThreadFactory(String name) {
if (!name.endsWith(StringUtils.DOT)) {
name += StringUtils.DOT;
}
this.name = name;
}
@Override
private final AtomicInteger id = new AtomicInteger(0);
private String name;
public NameThreadFactory(String name) {
if (!name.endsWith(StringUtils.DOT)) {
name += StringUtils.DOT;
}
this.name = name;
}
@Override
public Thread newThread(Runnable r) {
String threadName = name + id.getAndDecrement();
Thread thread = new Thread(r, threadName);
thread.setDaemon(true);
return thread;
}
String threadName = name + id.getAndDecrement();
Thread thread = new Thread(r, threadName);
thread.setDaemon(true);
return thread;
}
}

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.executor;
package com.alibaba.nacos.common.executor;
import com.alibaba.nacos.common.utils.ThreadUtils;
import org.slf4j.Logger;
@ -29,58 +29,59 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* // TODO Access Metric
* // TODO Access Metric.
*
* For unified management of thread pool resources, the consumer can simply call
* the register method to {@link ThreadPoolManager#register(String, String, ExecutorService)}
* the thread pool that needs to be included in the life cycle management of the resource
* <p>For unified management of thread pool resources, the consumer can simply call the register method to {@link
* ThreadPoolManager#register(String, String, ExecutorService)} the thread pool that needs to be included in the life
* cycle management of the resource
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class ThreadPoolManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolManager.class);
private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolManager.class);
private Map<String, Map<String, Set<ExecutorService>>> resourcesManager;
private Map<String, Object> lockers = new ConcurrentHashMap<String, Object>(8);
private static final ThreadPoolManager INSTANCE = new ThreadPoolManager();
private static final AtomicBoolean CLOSED = new AtomicBoolean(false);
static {
INSTANCE.init();
ThreadUtils.addShutdownHook(new Thread(new Runnable() {
ThreadUtils.addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
LOGGER.warn("[ThreadPoolManager] Start destroying ThreadPool");
LOGGER.warn("[ThreadPoolManager] Start destroying ThreadPool");
shutdown();
LOGGER.warn("[ThreadPoolManager] Destruction of the end");
LOGGER.warn("[ThreadPoolManager] Destruction of the end");
}
}));
}
public static ThreadPoolManager getInstance() {
return INSTANCE;
}
private ThreadPoolManager() {}
private ThreadPoolManager() {
}
private void init() {
resourcesManager = new ConcurrentHashMap<String, Map<String, Set<ExecutorService>>>(8);
}
/**
* Register the thread pool resources with the resource manager
*
* Register the thread pool resources with the resource manager.
*
* @param namespace namespace name
* @param group group name
* @param executor {@link ExecutorService}
*/
public void register(String namespace, String group, ExecutorService executor) {
if (!resourcesManager.containsKey(namespace)) {
synchronized(this) {
* @param group group name
* @param executor {@link ExecutorService}
*/
public void register(String namespace, String group, ExecutorService executor) {
if (!resourcesManager.containsKey(namespace)) {
synchronized (this) {
lockers.put(namespace, new Object());
}
}
@ -88,26 +89,26 @@ public final class ThreadPoolManager {
synchronized (monitor) {
Map<String, Set<ExecutorService>> map = resourcesManager.get(namespace);
if (map == null) {
map = new HashMap<String, Set<ExecutorService>>(8);
map.put(group, new HashSet<ExecutorService>());
map.get(group).add(executor);
resourcesManager.put(namespace, map);
return;
}
map = new HashMap<String, Set<ExecutorService>>(8);
map.put(group, new HashSet<ExecutorService>());
map.get(group).add(executor);
resourcesManager.put(namespace, map);
return;
}
if (!map.containsKey(group)) {
map.put(group, new HashSet<ExecutorService>());
}
map.get(group).add(executor);
}
}
/**
* Cancel the uniform lifecycle management for all threads under this resource
*
/**
* Cancel the uniform lifecycle management for all threads under this resource.
*
* @param namespace namespace name
* @param group group name
*/
public void deregister(String namespace, String group) {
* @param group group name
*/
public void deregister(String namespace, String group) {
if (resourcesManager.containsKey(namespace)) {
final Object monitor = lockers.get(namespace);
synchronized (monitor) {
@ -115,83 +116,83 @@ public final class ThreadPoolManager {
}
}
}
/**
* Undoing the uniform lifecycle management of {@link ExecutorService} under this resource
*
* @param namespace namespace name
* @param group group name
* @param executor {@link ExecutorService}
*/
public void deregister(String namespace, String group, ExecutorService executor) {
/**
* Undoing the uniform lifecycle management of {@link ExecutorService} under this resource.
*
* @param namespace namespace name
* @param group group name
* @param executor {@link ExecutorService}
*/
public void deregister(String namespace, String group, ExecutorService executor) {
if (resourcesManager.containsKey(namespace)) {
final Object monitor = lockers.get(namespace);
synchronized (monitor) {
final Map<String, Set<ExecutorService>> subResourceMap = resourcesManager.get(namespace);
if (subResourceMap.containsKey(group)) {
subResourceMap.get(group).remove(executor);
}
}
final Map<String, Set<ExecutorService>> subResourceMap = resourcesManager.get(namespace);
if (subResourceMap.containsKey(group)) {
subResourceMap.get(group).remove(executor);
}
}
}
}
/**
* Destroys all thread pool resources under this namespace
*
* @param namespace namespace
*/
public void destroy(final String namespace) {
final Object monitor = lockers.get(namespace);
if (monitor == null) {
return;
/**
* Destroys all thread pool resources under this namespace.
*
* @param namespace namespace
*/
public void destroy(final String namespace) {
final Object monitor = lockers.get(namespace);
if (monitor == null) {
return;
}
synchronized (monitor) {
Map<String, Set<ExecutorService>> subResource = resourcesManager.get(namespace);
if (subResource == null) {
return;
}
for (Map.Entry<String, Set<ExecutorService>> entry : subResource.entrySet()) {
for (ExecutorService executor : entry.getValue()) {
ThreadUtils.shutdownThreadPool(executor);
}
synchronized (monitor) {
Map<String, Set<ExecutorService>> subResource = resourcesManager.get(namespace);
if (subResource == null) {
return;
}
for (Map.Entry<String, Set<ExecutorService>> entry : subResource.entrySet()) {
for (ExecutorService executor : entry.getValue()) {
ThreadUtils.shutdownThreadPool(executor);
}
}
resourcesManager.get(namespace).clear();
resourcesManager.remove(namespace);
resourcesManager.remove(namespace);
}
}
/**
* This namespace destroys all thread pool resources under the grouping
*
* @param namespace namespace
* @param group group
*/
public void destroy(final String namespace, final String group) {
final Object monitor = lockers.get(namespace);
if (monitor == null) {
return;
}
synchronized (monitor) {
Map<String, Set<ExecutorService>> subResource = resourcesManager.get(namespace);
if (subResource == null) {
return;
}
Set<ExecutorService> waitDestroy = subResource.get(group);
for (ExecutorService executor : waitDestroy) {
ThreadUtils.shutdownThreadPool(executor);
}
resourcesManager.get(namespace).remove(group);
}
}
/**
* This namespace destroys all thread pool resources under the grouping.
*
* @param namespace namespace
* @param group group
*/
public void destroy(final String namespace, final String group) {
final Object monitor = lockers.get(namespace);
if (monitor == null) {
return;
}
synchronized (monitor) {
Map<String, Set<ExecutorService>> subResource = resourcesManager.get(namespace);
if (subResource == null) {
return;
}
Set<ExecutorService> waitDestroy = subResource.get(group);
for (ExecutorService executor : waitDestroy) {
ThreadUtils.shutdownThreadPool(executor);
}
resourcesManager.get(namespace).remove(group);
}
}
public static void shutdown() {
if (!CLOSED.compareAndSet(false, true)) {
return;
}
Set<String> namespaces = INSTANCE.resourcesManager.keySet();
for (String namespace : namespaces) {
INSTANCE.destroy(namespace);
if (!CLOSED.compareAndSet(false, true)) {
return;
}
Set<String> namespaces = INSTANCE.resourcesManager.keySet();
for (String namespace : namespaces) {
INSTANCE.destroy(namespace);
}
}
}

View File

@ -25,43 +25,36 @@ import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.nio.client.HttpAsyncClients;
/**
* AbstractHttpClientFactory
* Let the creator only specify the http client config
* AbstractHttpClientFactory Let the creator only specify the http client config.
*
* @author mai.jh
* @date 2020/6/15
*/
public abstract class AbstractHttpClientFactory implements HttpClientFactory {
@Override
public final NacosRestTemplate createNacosRestTemplate() {
RequestConfig requestConfig = getRequestConfig();
return new NacosRestTemplate(
new DefaultHttpClientRequest(
HttpClients.custom()
.setDefaultRequestConfig(requestConfig).build()));
new DefaultHttpClientRequest(HttpClients.custom().setDefaultRequestConfig(requestConfig).build()));
}
@Override
public final NacosAsyncRestTemplate createNacosAsyncRestTemplate() {
RequestConfig requestConfig = getRequestConfig();
return new NacosAsyncRestTemplate(
new DefaultAsyncHttpClientRequest(
HttpAsyncClients.custom()
.setDefaultRequestConfig(requestConfig).build()));
return new NacosAsyncRestTemplate(new DefaultAsyncHttpClientRequest(
HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig).build()));
}
private RequestConfig getRequestConfig() {
HttpClientConfig httpClientConfig = buildHttpClientConfig();
return RequestConfig.custom()
.setConnectTimeout(httpClientConfig.getConTimeOutMillis())
.setSocketTimeout(httpClientConfig.getReadTimeOutMillis())
.setMaxRedirects(httpClientConfig.getMaxRedirects())
.build();
return RequestConfig.custom().setConnectTimeout(httpClientConfig.getConTimeOutMillis())
.setSocketTimeout(httpClientConfig.getReadTimeOutMillis())
.setMaxRedirects(httpClientConfig.getMaxRedirects()).build();
}
/**
* build http client config
* build http client config.
*
* @return HttpClientConfig
*/
protected abstract HttpClientConfig buildHttpClientConfig();

View File

@ -31,102 +31,100 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
/**
* Base http client.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public abstract class BaseHttpClient {
protected <T> RestResult<T> execute(CloseableHttpClient httpClient,
final Type type, HttpUriRequest request) throws Exception {
CloseableHttpResponse response = httpClient.execute(request);
try {
final String body = EntityUtils.toString(response.getEntity());
RestResult<T> data = ResponseHandler.convert(body, type);
return data;
}
finally {
HttpClientUtils.closeQuietly(response);
}
}
protected <T> void execute(CloseableHttpAsyncClient httpAsyncClient, final Type type,
final Callback<T> callback, final HttpUriRequest request) {
if (!httpAsyncClient.isRunning()) {
throw new IllegalArgumentException("httpAsyncClient already shutdown");
}
httpAsyncClient.execute(request, new FutureCallback<HttpResponse>() {
@Override
public void completed(HttpResponse response) {
try {
final String body = EntityUtils.toString(response.getEntity());
RestResult<T> data = ResponseHandler.convert(body, type);
data.setCode(response.getStatusLine().getStatusCode());
callback.onReceive(data);
}
catch (Throwable e) {
callback.onError(e);
}
}
@Override
public void failed(Exception ex) {
callback.onError(ex);
}
@Override
public void cancelled() {
}
});
}
protected String buildUrl(String baseUrl, Query query) {
if (query.isEmpty()) {
return baseUrl;
}
return baseUrl + "?" + query.toQueryUrl();
}
protected HttpRequestBase build(String url, Header header, String method) throws Exception {
return build(url, header, null, method);
}
protected HttpRequestBase build(String url, Header header, Object body,
String method) throws Exception {
BaseHttpMethod httpMethod = BaseHttpMethod.sourceOf(method);
httpMethod.init(url);
httpMethod.initHeader(header);
httpMethod.initEntity(body, header.getValue("Content-Type"));
return httpMethod.getRequestBase();
}
private Header convertHeader(org.apache.http.Header[] headers) {
final Header nHeader = Header.newInstance();
for (org.apache.http.Header header : headers) {
nHeader.addParam(header.getName(), header.getValue());
}
return nHeader;
}
public static class HttpGetWithEntity extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "GET";
public HttpGetWithEntity(String url) {
super();
setURI(URI.create(url));
}
@Override
public String getMethod() {
return METHOD_NAME;
}
}
protected <T> RestResult<T> execute(CloseableHttpClient httpClient, final Type type, HttpUriRequest request)
throws Exception {
CloseableHttpResponse response = httpClient.execute(request);
try {
final String body = EntityUtils.toString(response.getEntity());
RestResult<T> data = ResponseHandler.convert(body, type);
return data;
} finally {
HttpClientUtils.closeQuietly(response);
}
}
protected <T> void execute(CloseableHttpAsyncClient httpAsyncClient, final Type type, final Callback<T> callback,
final HttpUriRequest request) {
if (!httpAsyncClient.isRunning()) {
throw new IllegalArgumentException("httpAsyncClient already shutdown");
}
httpAsyncClient.execute(request, new FutureCallback<HttpResponse>() {
@Override
public void completed(HttpResponse response) {
try {
final String body = EntityUtils.toString(response.getEntity());
RestResult<T> data = ResponseHandler.convert(body, type);
data.setCode(response.getStatusLine().getStatusCode());
callback.onReceive(data);
} catch (Throwable e) {
callback.onError(e);
}
}
@Override
public void failed(Exception ex) {
callback.onError(ex);
}
@Override
public void cancelled() {
}
});
}
protected String buildUrl(String baseUrl, Query query) {
if (query.isEmpty()) {
return baseUrl;
}
return baseUrl + "?" + query.toQueryUrl();
}
protected HttpRequestBase build(String url, Header header, String method) throws Exception {
return build(url, header, null, method);
}
protected HttpRequestBase build(String url, Header header, Object body, String method) throws Exception {
BaseHttpMethod httpMethod = BaseHttpMethod.sourceOf(method);
httpMethod.init(url);
httpMethod.initHeader(header);
httpMethod.initEntity(body, header.getValue("Content-Type"));
return httpMethod.getRequestBase();
}
private Header convertHeader(org.apache.http.Header[] headers) {
final Header nHeader = Header.newInstance();
for (org.apache.http.Header header : headers) {
nHeader.addParam(header.getName(), header.getValue());
}
return nHeader;
}
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;
}
}
}

View File

@ -44,12 +44,14 @@ import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;
/**
* Base http method.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public enum BaseHttpMethod {
/**
* get request
* get request.
*/
GET(HttpMethod.GET) {
@Override
@ -57,16 +59,16 @@ public enum BaseHttpMethod {
return new HttpGet(url);
}
},
GET_LARGE(HttpMethod.GET_LARGE) {
@Override
protected HttpRequestBase createRequest(String url) {
return new BaseHttpClient.HttpGetWithEntity(url);
}
},
/**
* post request
* post request.
*/
POST(HttpMethod.POST) {
@Override
@ -74,9 +76,9 @@ public enum BaseHttpMethod {
return new HttpPost(url);
}
},
/**
* put request
* put request.
*/
PUT(HttpMethod.PUT) {
@Override
@ -84,9 +86,9 @@ public enum BaseHttpMethod {
return new HttpPut(url);
}
},
/**
* delete request
* delete request.
*/
DELETE(HttpMethod.DELETE) {
@Override
@ -94,9 +96,9 @@ public enum BaseHttpMethod {
return new HttpDelete(url);
}
},
/**
* head request
* head request.
*/
HEAD(HttpMethod.HEAD) {
@Override
@ -104,9 +106,9 @@ public enum BaseHttpMethod {
return new HttpHead(url);
}
},
/**
* trace request
* trace request.
*/
TRACE(HttpMethod.TRACE) {
@Override
@ -114,9 +116,9 @@ public enum BaseHttpMethod {
return new HttpTrace(url);
}
},
/**
* patch request
* patch request.
*/
PATCH(HttpMethod.PATCH) {
@Override
@ -124,35 +126,38 @@ public enum BaseHttpMethod {
return new HttpPatch(url);
}
},
/**
* options request
* options request.
*/
OPTIONS(HttpMethod.OPTIONS) {
@Override
protected HttpRequestBase createRequest(String url) {
return new HttpTrace(url);
}
},
;
};
private String name;
private HttpRequest requestBase;
BaseHttpMethod(String name) {
this.name = name;
}
public void init(String url) {
requestBase = createRequest(url);
}
protected HttpRequestBase createRequest(String url) {
throw new UnsupportedOperationException();
}
/**
* Init http header.
*
* @param header header
*/
public void initHeader(Header header) {
Iterator<Map.Entry<String, String>> iterator = header.iterator();
while (iterator.hasNext()) {
@ -160,7 +165,14 @@ public enum BaseHttpMethod {
requestBase.setHeader(entry.getKey(), entry.getValue());
}
}
/**
* Init http entity.
*
* @param body body
* @param mediaType mediaType {@link ContentType}
* @throws Exception exception
*/
public void initEntity(Object body, String mediaType) throws Exception {
if (body == null) {
return;
@ -172,8 +184,15 @@ public enum BaseHttpMethod {
request.setEntity(entity);
}
}
public void initFromEntity(Map<String, String> body, String charset) throws Exception{
/**
* Init request from entity map.
*
* @param body body map
* @param charset charset of entity
* @throws Exception exception
*/
public void initFromEntity(Map<String, String> body, String charset) throws Exception {
if (body.isEmpty()) {
return;
}
@ -187,11 +206,17 @@ public enum BaseHttpMethod {
request.setEntity(entity);
}
}
public HttpRequestBase getRequestBase() {
return (HttpRequestBase) requestBase;
}
/**
* Value of {@link BaseHttpMethod}.
*
* @param name method name
* @return {@link BaseHttpMethod}
*/
public static BaseHttpMethod sourceOf(String name) {
for (BaseHttpMethod method : BaseHttpMethod.values()) {
if (StringUtils.equalsIgnoreCase(name, method.name)) {
@ -200,5 +225,5 @@ public enum BaseHttpMethod {
}
throw new IllegalArgumentException("Unsupported http method : " + name);
}
}

View File

@ -19,22 +19,24 @@ package com.alibaba.nacos.common.http;
import com.alibaba.nacos.common.model.RestResult;
/**
* Http callback.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface Callback<T> {
/**
* Callback after the request is responded
* Callback after the request is responded.
*
* @param result {@link RestResult}
*/
void onReceive(RestResult<T> result);
/**
* An error occurred during the request
* An error occurred during the request.
*
* @param throwable {@link Throwable}
*/
void onError(Throwable throwable);
}

View File

@ -17,20 +17,16 @@
package com.alibaba.nacos.common.http;
/**
* default http client factory
* default http client factory.
*
* @author mai.jh
* @date 2020/6/15
*/
public class DefaultHttpClientFactory extends AbstractHttpClientFactory {
private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000);
@Override
protected HttpClientConfig buildHttpClientConfig() {
return HttpClientConfig.builder()
.setConTimeOutMillis(TIMEOUT)
.setReadTimeOutMillis(TIMEOUT >> 1)
.build();
return HttpClientConfig.builder().setConTimeOutMillis(TIMEOUT).setReadTimeOutMillis(TIMEOUT >> 1).build();
}
}

View File

@ -29,27 +29,26 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Create a rest template
* to ensure that each custom client config and rest template are in one-to-one correspondence
* Create a rest template to ensure that each custom client config and rest template are in one-to-one correspondence.
*
* @author mai.jh
* @date 2020/6/16
*/
@SuppressWarnings("all")
public final class HttpClientBeanHolder {
private static final Logger logger = LoggerFactory.getLogger(HttpClientManager.class);
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientManager.class);
private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000);
private static HttpClientConfig HTTP_CLIENT_CONFIG = HttpClientConfig.builder()
.setConTimeOutMillis(TIMEOUT).setReadTimeOutMillis(TIMEOUT >> 1).build();
private static final Map<String, NacosRestTemplate> singletonRest = new HashMap<String, NacosRestTemplate>(10);
private static final Map<String, NacosAsyncRestTemplate> singletonAsyncRest = new HashMap<String, NacosAsyncRestTemplate>(10);
private static final AtomicBoolean alreadyShutdown = new AtomicBoolean(false);
private static final HttpClientConfig HTTP_CLIENT_CONFIG = HttpClientConfig.builder().setConTimeOutMillis(TIMEOUT)
.setReadTimeOutMillis(TIMEOUT >> 1).build();
private static final Map<String, NacosRestTemplate> SINGLETON_REST = new HashMap<String, NacosRestTemplate>(10);
private static final Map<String, NacosAsyncRestTemplate> SINGLETON_ASYNC_REST = new HashMap<String, NacosAsyncRestTemplate>(
10);
private static final AtomicBoolean ALREADY_SHUTDOWN = new AtomicBoolean(false);
static {
ThreadUtils.addShutdownHook(new Runnable() {
@Override
@ -58,86 +57,88 @@ public final class HttpClientBeanHolder {
}
});
}
public static NacosRestTemplate getNacosRestTemplate() {
return getNacosRestTemplate(new DefaultHttpClientFactory());
}
public static NacosRestTemplate getNacosRestTemplate(HttpClientFactory httpClientFactory) {
if (httpClientFactory == null) {
throw new NullPointerException("httpClientFactory is null");
}
String factoryName = httpClientFactory.getClass().getName();
NacosRestTemplate nacosRestTemplate = singletonRest.get(factoryName);
NacosRestTemplate nacosRestTemplate = SINGLETON_REST.get(factoryName);
if (nacosRestTemplate == null) {
synchronized (singletonRest) {
nacosRestTemplate = singletonRest.get(factoryName);
synchronized (SINGLETON_REST) {
nacosRestTemplate = SINGLETON_REST.get(factoryName);
if (nacosRestTemplate != null) {
return nacosRestTemplate;
}
nacosRestTemplate = httpClientFactory.createNacosRestTemplate();
singletonRest.put(factoryName, nacosRestTemplate);
SINGLETON_REST.put(factoryName, nacosRestTemplate);
}
}
return nacosRestTemplate;
}
public static NacosAsyncRestTemplate getNacosAsyncRestTemplate() {
return getNacosAsyncRestTemplate(new DefaultHttpClientFactory());
}
public static NacosAsyncRestTemplate getNacosAsyncRestTemplate(HttpClientFactory httpClientFactory) {
if (httpClientFactory == null) {
throw new NullPointerException("httpClientFactory is null");
}
String factoryName = httpClientFactory.getClass().getName();
NacosAsyncRestTemplate nacosAsyncRestTemplate = singletonAsyncRest.get(factoryName);
NacosAsyncRestTemplate nacosAsyncRestTemplate = SINGLETON_ASYNC_REST.get(factoryName);
if (nacosAsyncRestTemplate == null) {
synchronized (singletonAsyncRest) {
nacosAsyncRestTemplate = singletonAsyncRest.get(factoryName);
synchronized (SINGLETON_ASYNC_REST) {
nacosAsyncRestTemplate = SINGLETON_ASYNC_REST.get(factoryName);
if (nacosAsyncRestTemplate != null) {
return nacosAsyncRestTemplate;
}
nacosAsyncRestTemplate = httpClientFactory.createNacosAsyncRestTemplate();
singletonAsyncRest.put(factoryName, nacosAsyncRestTemplate);
SINGLETON_ASYNC_REST.put(factoryName, nacosAsyncRestTemplate);
}
}
return nacosAsyncRestTemplate;
}
/**
* Shutdown http client holder and close all template.
*/
public static void shutdown() {
if (!alreadyShutdown.compareAndSet(false, true)) {
if (!ALREADY_SHUTDOWN.compareAndSet(false, true)) {
return;
}
logger.warn("[HttpClientBeanFactory] Start destroying NacosRestTemplate");
LOGGER.warn("[HttpClientBeanFactory] Start destroying NacosRestTemplate");
try {
nacostRestTemplateShutdown();
nacosAsyncRestTemplateShutdown();
} catch (Exception ex) {
LOGGER.error("[HttpClientBeanFactory] An exception occurred when the HTTP client was closed : {}",
ExceptionUtil.getStackTrace(ex));
}
catch (Exception ex) {
logger.error("[HttpClientBeanFactory] An exception occurred when the HTTP client was closed : {}",
ExceptionUtil.getStackTrace(ex));
}
logger.warn("[HttpClientBeanFactory] Destruction of the end");
LOGGER.warn("[HttpClientBeanFactory] Destruction of the end");
}
private static void nacostRestTemplateShutdown() throws Exception{
if (!singletonRest.isEmpty()) {
Collection<NacosRestTemplate> nacosRestTemplates = singletonRest.values();
private static void nacostRestTemplateShutdown() throws Exception {
if (!SINGLETON_REST.isEmpty()) {
Collection<NacosRestTemplate> nacosRestTemplates = SINGLETON_REST.values();
for (NacosRestTemplate nacosRestTemplate : nacosRestTemplates) {
nacosRestTemplate.close();
}
singletonRest.clear();
SINGLETON_REST.clear();
}
}
private static void nacosAsyncRestTemplateShutdown() throws Exception{
if (!singletonAsyncRest.isEmpty()) {
Collection<NacosAsyncRestTemplate> nacosAsyncRestTemplates = singletonAsyncRest.values();
private static void nacosAsyncRestTemplateShutdown() throws Exception {
if (!SINGLETON_ASYNC_REST.isEmpty()) {
Collection<NacosAsyncRestTemplate> nacosAsyncRestTemplates = SINGLETON_ASYNC_REST.values();
for (NacosAsyncRestTemplate nacosAsyncRestTemplate : nacosAsyncRestTemplates) {
nacosAsyncRestTemplate.close();
}
singletonAsyncRest.clear();
SINGLETON_ASYNC_REST.clear();
}
}
}

View File

@ -17,61 +17,63 @@
package com.alibaba.nacos.common.http;
/**
* http client config build
* http client config build.
*
* @author mai.jh
* @date 2020/6/14
*/
public class HttpClientConfig {
private int conTimeOutMillis;
private int readTimeOutMillis;
private int maxRedirects;
private final int conTimeOutMillis;
private final int readTimeOutMillis;
private final int maxRedirects;
public HttpClientConfig(int conTimeOutMillis, int readTimeOutMillis, int maxRedirects) {
this.conTimeOutMillis = conTimeOutMillis;
this.readTimeOutMillis = readTimeOutMillis;
this.maxRedirects = maxRedirects;
}
public int getConTimeOutMillis() {
return conTimeOutMillis;
}
public int getReadTimeOutMillis() {
return readTimeOutMillis;
}
public int getMaxRedirects() {
return maxRedirects;
}
public static HttpClientConfigBuilder builder() {
return new HttpClientConfigBuilder();
}
public static final class HttpClientConfigBuilder {
private int conTimeOutMillis = -1;
private int readTimeOutMillis = -1;
private int maxRedirects = 50;
public HttpClientConfigBuilder setConTimeOutMillis(int conTimeOutMillis) {
this.conTimeOutMillis = conTimeOutMillis;
return this;
}
public HttpClientConfigBuilder setReadTimeOutMillis(int readTimeOutMillis) {
this.readTimeOutMillis = readTimeOutMillis;
return this;
}
public HttpClientConfigBuilder setMaxRedirects(int maxRedirects) {
this.maxRedirects = maxRedirects;
return this;
}
public HttpClientConfig build() {
return new HttpClientConfig(conTimeOutMillis, readTimeOutMillis, maxRedirects);
}

View File

@ -20,23 +20,24 @@ import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
/**
* http Client Factory
* http Client Factory.
*
* @author mai.jh
* @date 2020/6/15
*/
public interface HttpClientFactory {
/**
* create new nacost rest
* create new nacost rest.
*
* @return NacosRestTemplate
*/
NacosRestTemplate createNacosRestTemplate();
/**
* create new nacos async rest
* create new nacos async rest.
*
* @return NacosAsyncRestTemplate
*/
NacosAsyncRestTemplate createNacosAsyncRestTemplate();
}

View File

@ -27,60 +27,60 @@ import org.slf4j.LoggerFactory;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Use the same HttpClient object in the same space
* Use the same HttpClient object in the same space.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public class HttpClientManager {
private static final Logger logger = LoggerFactory.getLogger(HttpClientManager.class);
private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000);
private static final RequestConfig DEFAULT_CONFIG = RequestConfig.custom()
.setConnectTimeout(TIMEOUT).setSocketTimeout(TIMEOUT << 1).build();
private static final NSyncHttpClient SYNC_HTTP_CLIENT = new NacosSyncHttpClient(
HttpClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
private static final NAsyncHttpClient ASYNC_HTTP_CLIENT = new NacosAsyncHttpClient(
HttpAsyncClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
private static final AtomicBoolean alreadyShutdown = new AtomicBoolean(false);
static {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientManager.class);
private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000);
private static final RequestConfig DEFAULT_CONFIG = RequestConfig.custom().setConnectTimeout(TIMEOUT)
.setSocketTimeout(TIMEOUT << 1).build();
private static final NSyncHttpClient SYNC_HTTP_CLIENT = new NacosSyncHttpClient(
HttpClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
private static final NAsyncHttpClient ASYNC_HTTP_CLIENT = new NacosAsyncHttpClient(
HttpAsyncClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
private static final AtomicBoolean ALREADY_SHUTDOWN = new AtomicBoolean(false);
static {
ThreadUtils.addShutdownHook(new Runnable() {
@Override
public void run() {
shutdown();
}
});
}
public static NSyncHttpClient getSyncHttpClient() {
return SYNC_HTTP_CLIENT;
}
public static NAsyncHttpClient getAsyncHttpClient() {
return ASYNC_HTTP_CLIENT;
}
public static void shutdown() {
if (!alreadyShutdown.compareAndSet(false, true)) {
return;
}
logger.warn("[HttpClientManager] Start destroying HttpClient");
try {
SYNC_HTTP_CLIENT.close();
ASYNC_HTTP_CLIENT.close();
}
catch (Exception ex) {
logger.error("An exception occurred when the HTTP client was closed : {}",
ExceptionUtil.getStackTrace(ex));
}
logger.warn("[HttpClientManager] Destruction of the end");
}
@Override
public void run() {
shutdown();
}
});
}
public static NSyncHttpClient getSyncHttpClient() {
return SYNC_HTTP_CLIENT;
}
public static NAsyncHttpClient getAsyncHttpClient() {
return ASYNC_HTTP_CLIENT;
}
/**
* Shutdown http client manager and close http client.
*/
public static void shutdown() {
if (!ALREADY_SHUTDOWN.compareAndSet(false, true)) {
return;
}
LOGGER.warn("[HttpClientManager] Start destroying HttpClient");
try {
SYNC_HTTP_CLIENT.close();
ASYNC_HTTP_CLIENT.close();
} catch (Exception ex) {
LOGGER.error("An exception occurred when the HTTP client was closed : {}", ExceptionUtil.getStackTrace(ex));
}
LOGGER.warn("[HttpClientManager] Destruction of the end");
}
}

View File

@ -20,28 +20,28 @@ import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.model.RestResult;
/**
* http RestResult
* Http RestResult.
*
* @author mai.jh
* @date 2020/5/31
*/
public class HttpRestResult<T> extends RestResult<T> {
private static final long serialVersionUID = 3766947816720175947L;
private Header header;
public HttpRestResult() {
}
public HttpRestResult(Header header, int code, T data) {
super(code, data);
this.header = header;
}
public Header getHeader() {
return header;
}
public void setHeader(Header header) {
this.header = header;
}

View File

@ -32,12 +32,22 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Http utils.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class HttpUtils {
private static final Pattern CONTEXT_PATH_MATCH = Pattern.compile("(\\/)\\1+");
/**
* Build URL.
*
* @param isHttps whether is https
* @param serverAddr server ip/address
* @param subPaths api path
* @return URL string
*/
public static String buildUrl(boolean isHttps, String serverAddr, String... subPaths) {
StringBuilder sb = new StringBuilder();
if (isHttps) {
@ -58,15 +68,13 @@ public final class HttpUtils {
if (pre == null || !pre.endsWith("/")) {
if (subPath.startsWith("/")) {
sb.append(subPath);
}
else {
} else {
sb.append("/").append(subPath);
}
} else {
if (subPath.startsWith("/")) {
sb.append(subPath.replaceFirst("\\/", ""));
}
else {
} else {
sb.append(subPath);
}
}
@ -74,7 +82,14 @@ public final class HttpUtils {
}
return sb.toString();
}
/**
* Translate parameter map.
*
* @param parameterMap parameter map
* @return parameter map
* @throws Exception exception
*/
public static Map<String, String> translateParameterMap(Map<String, String[]> parameterMap) throws Exception {
Map<String, String> map = new HashMap<String, String>(16);
for (String key : parameterMap.keySet()) {
@ -82,7 +97,15 @@ public final class HttpUtils {
}
return map;
}
/**
* Encoding parameters to url string.
*
* @param params parameters
* @param encoding encoding charset
* @return url string
* @throws UnsupportedEncodingException if encoding string is illegal
*/
public static String encodingParams(Map<String, String> params, String encoding)
throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
@ -93,22 +116,29 @@ public final class HttpUtils {
if (StringUtils.isEmpty(entry.getValue())) {
continue;
}
sb.append(entry.getKey()).append("=");
sb.append(URLEncoder.encode(entry.getValue(), encoding));
sb.append("&");
}
return sb.toString();
}
public static String encodingParams(List<String> paramValues, String encoding)
throws UnsupportedEncodingException {
/**
* Encoding KV list to url string.
*
* @param paramValues parameters
* @param encoding encoding charset
* @return url string
* @throws UnsupportedEncodingException if encoding string is illegal
*/
public static String encodingParams(List<String> paramValues, String encoding) throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
if (null == paramValues) {
return null;
}
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext(); ) {
sb.append(iter.next()).append("=");
sb.append(URLEncoder.encode(iter.next(), encoding));
@ -118,16 +148,17 @@ public final class HttpUtils {
}
return sb.toString();
}
public static String decode(String str, String encode) throws UnsupportedEncodingException {
return innerDecode(null, str, encode);
}
/**
* build URI By url and query
* @param url url
* build URI By url and query.
*
* @param url url
* @param query query param {@link Query}
* @return
* @return {@link URI}
*/
public static URI buildUri(String url, Query query) throws URISyntaxException {
if (!query.isEmpty()) {
@ -135,7 +166,7 @@ public final class HttpUtils {
}
return new URI(url);
}
private static String innerDecode(String pre, String now, String encode) throws UnsupportedEncodingException {
// Because the data may be encoded by the URL more than once,
// it needs to be decoded recursively until it is fully successful
@ -146,6 +177,4 @@ public final class HttpUtils {
now = URLDecoder.decode(now, encode);
return innerDecode(pre, now, encode);
}
}

View File

@ -22,73 +22,72 @@ import com.alibaba.nacos.common.http.param.Query;
import java.lang.reflect.Type;
/**
* Nacos async http client interface.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public interface NAsyncHttpClient extends NHttpClient {
/**
* http get
*
* @param url url
* @param header http header param
* @param query http query param
* @param token return type
* @param url url
* @param header http header param
* @param query http query param
* @param token return type
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
*/
<T> void get(String url, Header header, Query query,
Type token, Callback<T> callback) throws Exception;
<T> void get(String url, Header header, Query query, Type token, Callback<T> callback) throws Exception;
/**
* get request, may be pulling a lot of data
*
* @param url url
* @param header http header param
* @param query http query param
* @param body get with body
* @param token return type
* @param url url
* @param header http header param
* @param query http query param
* @param body get with body
* @param token return type
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
*/
<T> void getLarge(String url, Header header, Query query, Object body,
Type token,
Callback<T> callback) throws Exception;
<T> void getLarge(String url, Header header, Query query, Object body, Type token, Callback<T> callback)
throws Exception;
/**
* http delete
*
* @param url url
* @param header http header param
* @param query http query param
* @param token return type
* @param url url
* @param header http header param
* @param query http query param
* @param token return type
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
*/
<T> void delete(String url, Header header, Query query,
Type token, Callback<T> callback) throws Exception;
<T> void delete(String url, Header header, Query query, Type token, Callback<T> callback) throws Exception;
/**
* http put
*
* @param url url
* @param header http header param
* @param query http query param
* @param body http body param
* @param token return type
* @param url url
* @param header http header param
* @param query http query param
* @param body http body param
* @param token return type
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
*/
<T> void put(String url, Header header, Query query, Object body,
Type token, Callback<T> callback) throws Exception;
<T> void put(String url, Header header, Query query, Object body, Type token, Callback<T> callback)
throws Exception;
/**
* http post
*
* @param url url
* @param header http header param
* @param query http query param
* @param body http body param
* @param token return type
* @param url url
* @param header http header param
* @param query http query param
* @param body http body param
* @param token return type
* @param callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
*/
<T> void post(String url, Header header, Query query, Object body,
Type token, Callback<T> callback) throws Exception;
<T> void post(String url, Header header, Query query, Object body, Type token, Callback<T> callback)
throws Exception;
}

View File

@ -19,6 +19,8 @@ package com.alibaba.nacos.common.http;
import java.io.Closeable;
/**
* Nacos http client interface.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")

View File

@ -23,77 +23,74 @@ import com.alibaba.nacos.common.model.RestResult;
import java.lang.reflect.Type;
/**
* Nacos sync http client.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public interface NSyncHttpClient extends NHttpClient {
/**
* http get
*
* @param url url
* @param url url
* @param header http header param
* @param query http query param
* @param token return type
* @param query http query param
* @param token return type
* @return {@link RestResult <T>}
* @throws Exception
*/
<T> RestResult<T> get(String url, Header header, Query query,
Type token) throws Exception;
<T> RestResult<T> get(String url, Header header, Query query, Type token) throws Exception;
/**
* get request, may be pulling a lot of data
*
* @param url url
* @param url url
* @param header http header param
* @param query http query param
* @param body get with body
* @param token return type
* @param query http query param
* @param body get with body
* @param token return type
* @return {@link RestResult <T>}
* @throws Exception
*/
<T> RestResult<T> getLarge(String url, Header header, Query query, Object body,
Type token) throws Exception;
<T> RestResult<T> getLarge(String url, Header header, Query query, Object body, Type token) throws Exception;
/**
* http delete
*
* @param url url
* @param url url
* @param header http header param
* @param query http query param
* @param token return type
* @param query http query param
* @param token return type
* @return {@link RestResult <T>}
* @throws Exception
*/
<T> RestResult<T> delete(String url, Header header, Query query,
Type token) throws Exception;
<T> RestResult<T> delete(String url, Header header, Query query, Type token) throws Exception;
/**
* http put
*
* @param url url
* @param url url
* @param header http header param
* @param query http query param
* @param body http body param
* @param token return type
* @param query http query param
* @param body http body param
* @param token return type
* @return {@link RestResult}
* @throws Exception
*/
<T> RestResult<T> put(String url, Header header, Query query, Object body,
Type token) throws Exception;
<T> RestResult<T> put(String url, Header header, Query query, Object body, Type token) throws Exception;
/**
* http post
*
* @param url url
* @param url url
* @param header http header param
* @param query http query param
* @param body http body param
* @param token return type
* @param query http query param
* @param body http body param
* @param token return type
* @return {@link RestResult}
* @throws Exception
*/
<T> RestResult<T> post(String url, Header header, Query query, Object body,
Type token) throws Exception;
<T> RestResult<T> post(String url, Header header, Query query, Object body, Type token) throws Exception;
}

View File

@ -26,70 +26,54 @@ import java.io.IOException;
import java.lang.reflect.Type;
/**
* Nacos async http client.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpClient {
private CloseableHttpAsyncClient asyncClient;
NacosAsyncHttpClient(CloseableHttpAsyncClient asyncClient) {
this.asyncClient = asyncClient;
this.asyncClient.start();
}
@Override
public <T> void get(final String url,
final Header header,
final Query query,
final Type token,
final Callback<T> callback) throws Exception {
public <T> void get(final String url, final Header header, final Query query, final Type token,
final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.GET);
execute(asyncClient, token, callback, requestBase);
}
@Override
public <T> void getLarge(final String url,
final Header header,
final Query query,
final Object body,
final Type token,
final Callback<T> callback) throws Exception {
public <T> void getLarge(final String url, final Header header, final Query query, final Object body,
final Type token, final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.GET_LARGE);
execute(asyncClient, token, callback, requestBase);
}
@Override
public <T> void delete(final String url,
final Header header,
final Query query,
final Type token,
final Callback<T> callback) throws Exception {
public <T> void delete(final String url, final Header header, final Query query, final Type token,
final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.DELETE);
execute(asyncClient, token, callback, requestBase);
}
@Override
public <T> void put(final String url,
final Header header,
final Query query,
final Object body,
final Type token,
final Callback<T> callback) throws Exception {
public <T> void put(final String url, final Header header, final Query query, final Object body, final Type token,
final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.PUT);
execute(asyncClient, token, callback, requestBase);
}
@Override
public <T> void post(final String url,
final Header header,
final Query query,
final Object body,
final Type token,
final Callback<T> callback) throws Exception {
public <T> void post(final String url, final Header header, final Query query, final Object body, final Type token,
final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.POST);
execute(asyncClient, token, callback, requestBase);
}
@Override
public void close() throws IOException {
asyncClient.close();

View File

@ -27,60 +27,53 @@ import java.io.IOException;
import java.lang.reflect.Type;
/**
* Nacos sync http client.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClient {
private CloseableHttpClient client;
NacosSyncHttpClient(CloseableHttpClient client) {
this.client = client;
}
@Override
public <T> RestResult<T> get(final String url,
final Header header,
final Query query,
final Type token) throws Exception {
public <T> RestResult<T> get(final String url, final Header header, final Query query, final Type token)
throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.GET);
return execute(client, token, requestBase);
}
@Override
public <T> RestResult<T> getLarge(String url, Header header, Query query, Object body, Type token) throws Exception {
public <T> RestResult<T> getLarge(String url, Header header, Query query, Object body, Type token)
throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.GET_LARGE);
return execute(client, token, requestBase);
}
@Override
public <T> RestResult<T> delete(final String url,
final Header header,
final Query query,
final Type token) throws Exception {
public <T> RestResult<T> delete(final String url, final Header header, final Query query, final Type token)
throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.DELETE);
return execute(client, token, requestBase);
}
@Override
public <T> RestResult<T> put(final String url,
final Header header,
final Query query,
final Object body,
final Type token) throws Exception {
public <T> RestResult<T> put(final String url, final Header header, final Query query, final Object body,
final Type token) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.PUT);
return execute(client, token, requestBase);
}
@Override
public <T> RestResult<T> post(final String url,
final Header header,
final Query query,
final Object body,
final Type token) throws Exception {
public <T> RestResult<T> post(final String url, final Header header, final Query query, final Object body,
final Type token) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.POST);
return execute(client, token, requestBase);
}
@Override
public void close() throws IOException {
client.close();

View File

@ -24,17 +24,15 @@ import java.lang.reflect.Type;
import java.net.URI;
/**
* Represents a client-side Async HTTP request.
* Created via an implementation execute.
* Represents a client-side Async HTTP request. Created via an implementation execute.
*
* @author mai.jh
* @date 2020/5/29
*/
public interface AsyncHttpClientRequest extends Closeable {
/**
* execute async http request
* execute async http request.
*
* @param uri http url
* @param httpMethod http request method
@ -43,6 +41,6 @@ public interface AsyncHttpClientRequest extends Closeable {
* @param callback http response callback
* @throws Exception ex
*/
<T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity,
final Type responseType, final Callback<T> callback) throws Exception;
<T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType,
final Callback<T> callback) throws Exception;
}

View File

@ -30,25 +30,24 @@ import java.lang.reflect.Type;
import java.net.URI;
/**
* {@link AsyncHttpClientRequest} implementation that uses apache async http client to
* execute streaming requests
* {@link AsyncHttpClientRequest} implementation that uses apache async http client to execute streaming requests.
*
* @author mai.jh
* @date 2020/5/29
*/
public class DefaultAsyncHttpClientRequest implements AsyncHttpClientRequest {
private final CloseableHttpAsyncClient asyncClient;
public DefaultAsyncHttpClientRequest(CloseableHttpAsyncClient asyncClient) {
this.asyncClient = asyncClient;
if (!this.asyncClient.isRunning()) {
this.asyncClient.start();
}
}
@Override
public <T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType, final Callback<T> callback) throws Exception {
public <T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType,
final Callback<T> callback) throws Exception {
HttpRequestBase httpRequestBase = DefaultHttpClientRequest.build(uri, httpMethod, requestHttpEntity);
asyncClient.execute(httpRequestBase, new FutureCallback<HttpResponse>() {
@Override
@ -61,20 +60,20 @@ public class DefaultAsyncHttpClientRequest implements AsyncHttpClientRequest {
callback.onError(e);
}
}
@Override
public void failed(Exception ex) {
callback.onError(ex);
}
@Override
public void cancelled() {
}
});
}
@Override
public void close() throws IOException {
this.asyncClient.close();

View File

@ -24,31 +24,30 @@ import java.io.IOException;
import java.io.InputStream;
/**
* ApacheClientHttpResponse implementation {@link HttpClientResponse}
* ApacheClientHttpResponse implementation {@link HttpClientResponse}.
*
* @author mai.jh
* @date 2020/5/25
*/
public class DefaultClientHttpResponse implements HttpClientResponse {
private HttpResponse response;
private Header responseHeader;
public DefaultClientHttpResponse(HttpResponse response) {
this.response = response;
}
@Override
public int getStatusCode() {
return this.response.getStatusLine().getStatusCode();
}
@Override
public String getStatusText() {
return this.response.getStatusLine().getReasonPhrase();
}
@Override
public Header getHeaders() {
if (this.responseHeader == null) {
@ -60,12 +59,12 @@ public class DefaultClientHttpResponse implements HttpClientResponse {
}
return this.responseHeader;
}
@Override
public InputStream getBody() throws IOException{
public InputStream getBody() throws IOException {
return response.getEntity().getContent();
}
@Override
public void close() {
try {

View File

@ -32,47 +32,46 @@ import java.net.URI;
import java.util.Map;
/**
* {@link HttpClientRequest} implementation that uses apache http client to
* execute streaming requests
* {@link HttpClientRequest} implementation that uses apache http client to execute streaming requests.
*
* @author mai.jh
* @date 2020/5/24
*/
@SuppressWarnings({"unchecked", "rawtypes", "resource"})
@SuppressWarnings({"unchecked", "resource"})
public class DefaultHttpClientRequest implements HttpClientRequest {
private static final Logger logger = LoggerFactory.getLogger(DefaultHttpClientRequest.class);
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultHttpClientRequest.class);
private final CloseableHttpClient client;
public DefaultHttpClientRequest(CloseableHttpClient client) {
this.client = client;
}
@Override
public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) throws Exception {
public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity)
throws Exception {
HttpRequestBase request = build(uri, httpMethod, requestHttpEntity);
CloseableHttpResponse response = client.execute(request);
if (logger.isDebugEnabled()) {
logger.debug("Request from server: " + request.getURI().toString());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Request from server: " + request.getURI().toString());
}
return new DefaultClientHttpResponse(response);
}
static HttpRequestBase build(URI uri, String method, RequestHttpEntity requestHttpEntity) throws Exception {
Header headers = requestHttpEntity.getHeaders();
BaseHttpMethod httpMethod = BaseHttpMethod.sourceOf(method);
httpMethod.init(uri.toString());
httpMethod.initHeader(headers);
if (MediaType.APPLICATION_FORM_URLENCODED.equals(headers.getValue(HttpHeaderConsts.CONTENT_TYPE))
&& requestHttpEntity.getBody() instanceof Map) {
&& requestHttpEntity.getBody() instanceof Map) {
httpMethod.initFromEntity((Map<String, String>) requestHttpEntity.getBody(), headers.getCharset());
} else {
httpMethod.initEntity(requestHttpEntity.getBody(), headers.getValue(HttpHeaderConsts.CONTENT_TYPE));
}
return httpMethod.getRequestBase();
}
@Override
public void close() throws IOException {
client.close();

View File

@ -22,18 +22,17 @@ import java.io.Closeable;
import java.net.URI;
/**
* Represents a client-side HTTP request.
* Created via an implementation execute.
* Represents a client-side HTTP request. Created via an implementation execute.
*
* @author mai.jh
* @date 2020/5/23
*/
public interface HttpClientRequest extends Closeable {
/**
* execute http request
* @param uri http url
* @param httpMethod http request method
* execute http request.
*
* @param uri http url
* @param httpMethod http request method
* @param requestHttpEntity http request entity
* @return HttpClientResponse
* @throws Exception ex

View File

@ -17,12 +17,10 @@
package com.alibaba.nacos.common.http.client;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.model.RequestHttpEntity;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
/**
* Represents a client-side HTTP response.
@ -31,34 +29,39 @@ import java.net.URI;
* @date 2020/5/23
*/
public interface HttpClientResponse extends Closeable {
/**
* Return the headers of this message.
*
* @return a corresponding HttpHeaders object (never {@code null})
*/
Header getHeaders();
/**
* Return the body of the message as an input stream.
*
* @return String response body
* @throws IOException IOException
*/
InputStream getBody() throws IOException;
/**
* Return the HTTP status code
* Return the HTTP status code.
*
* @return the HTTP status as an integer
*/
int getStatusCode();
/**
* Return the HTTP status text of the response.
*
* @return the HTTP status text
*/
String getStatusText();
/**
* close response InputStream
* close response InputStream.
*
* @throws IOException ex
*/
@Override

View File

@ -31,27 +31,27 @@ import java.net.URI;
import java.util.Map;
/**
* NacosAsyncRestTemplate async
* Nacos async rest template.
*
* @author mai.jh
* @date 2020/5/29
* @see AsyncHttpClientRequest
* @see HttpClientResponse
*/
public class NacosAsyncRestTemplate {
private static final Logger logger = LoggerFactory.getLogger(NacosAsyncRestTemplate.class);
private static final Logger LOGGER = LoggerFactory.getLogger(NacosAsyncRestTemplate.class);
private AsyncHttpClientRequest clientRequest;
public NacosAsyncRestTemplate(AsyncHttpClientRequest clientRequest) {
this.clientRequest = clientRequest;
}
/**
* async http get
* URL request params are expanded using the given query {@link Query}.
* async http get URL request params are expanded using the given query {@link Query}.
*
* <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.
*
@ -62,15 +62,17 @@ public class NacosAsyncRestTemplate {
* @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)
throws Exception {
execute(url, HttpMethod.GET, new RequestHttpEntity(header, query), responseType, callback);
}
/**
* async http get
* URL request params are expanded using the given map {@code paramValues}.
* 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,
*
* <p>{@code callback} Result callback execution
* if you need response headers, you can convert the received RestResult to HttpRestResult.
*
* @param url url
@ -80,17 +82,18 @@ public class NacosAsyncRestTemplate {
* @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);
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.
* 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.
*
* <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.
*
@ -102,16 +105,16 @@ public class NacosAsyncRestTemplate {
* @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 {
execute(url, HttpMethod.GET_LARGE,
new RequestHttpEntity(header, query, body), responseType, callback);
public <T> void getLarge(String url, Header header, Query query, Object body, Type responseType,
Callback<T> callback) throws Exception {
execute(url, HttpMethod.GET_LARGE, new RequestHttpEntity(header, query, body), responseType, callback);
}
/**
* async http delete
* URL request params are expanded using the given query {@link Query},
* async http delete URL request params are expanded using the given query {@link Query},
*
* <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.
*
@ -122,17 +125,18 @@ public class NacosAsyncRestTemplate {
* @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 {
execute(url, HttpMethod.DELETE,
new RequestHttpEntity(header, query), responseType, callback);
public <T> void delete(String url, Header header, Query query, Type responseType, Callback<T> callback)
throws Exception {
execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType, callback);
}
/**
* async http put
* Create a new resource by PUTting the given body to http request.
* async http put Create a new resource by PUTting the given body to http request.
*
* <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
*
* <p>{@code callback} Result callback execution,
* if you need response headers, you can convert the received RestResult to HttpRestResult.
*
@ -144,67 +148,70 @@ public class NacosAsyncRestTemplate {
* @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)
throws Exception {
execute(url, HttpMethod.PUT, new RequestHttpEntity(header, 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>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 http header param
* @param paramValues 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);
}
/**
* 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 query {@link Query}.
*
* <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 query 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 putFrom(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType,
Callback<T> callback) throws Exception {
execute(url, HttpMethod.PUT,
new RequestHttpEntity(header, query, body), responseType, callback);
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues),
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>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.
* 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'.
*
* @param url url
* @param header http header param
* @param paramValues 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);
}
/**
* 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 query {@link Query}.
* <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 query 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 putFrom(String url, Header header, Query query, Map<String, String> bodyValues,
Type responseType, Callback<T> callback) throws Exception {
execute(url, HttpMethod.PUT, new RequestHttpEntity(
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
query, bodyValues), responseType, callback);
}
/**
* 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,
* if you need response headers, you can convert the received RestResult to HttpRestResult.
*
@ -216,18 +223,19 @@ public class NacosAsyncRestTemplate {
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
* @throws Exception ex
*/
public <T> void putFrom(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 putFrom(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);
}
/**
* async http post
* Create a new resource by POSTing the given object to the http request.
* async http post Create a new resource by POSTing the given object to the http request.
*
* <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.
*
* <p>{@code callback} Result callback execution,
* if you need response headers, you can convert the received RestResult to HttpRestResult.
*
@ -239,18 +247,19 @@ public class NacosAsyncRestTemplate {
* @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 {
execute(url, HttpMethod.POST, new RequestHttpEntity(
header, query, body), responseType, callback);
public <T> void post(String url, Header header, Query query, Object body, Type responseType, Callback<T> callback)
throws Exception {
execute(url, HttpMethod.POST, new RequestHttpEntity(header, 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'.
* 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>{@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.
*
@ -262,20 +271,20 @@ public class NacosAsyncRestTemplate {
* @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, 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);
}
/**
* 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'.
* 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 query {@link Query}.
*
* <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.
*
@ -287,19 +296,21 @@ public class NacosAsyncRestTemplate {
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
* @throws Exception ex
*/
public <T> void postFrom(String url, Header header, Query query, Map<String, String> bodyValues,
Type responseType, Callback<T> callback) throws Exception {
execute(url, HttpMethod.POST, new RequestHttpEntity(
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues),
responseType, callback);
public <T> void postFrom(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType,
Callback<T> callback) throws Exception {
execute(url, HttpMethod.POST,
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues),
responseType, callback);
}
/**
* 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'.
* 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,
* if you need response headers, you can convert the received RestResult to HttpRestResult.
*
@ -311,26 +322,25 @@ public class NacosAsyncRestTemplate {
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
* @throws Exception ex
*/
public <T> void postFrom(String url, Header header, Map<String, String> paramValues,
Map<String, String> bodyValues, Type responseType, Callback<T> callback) throws Exception {
execute(url, HttpMethod.POST, new RequestHttpEntity(
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
Query.newInstance().initParams(paramValues),
bodyValues), responseType, callback);
public <T> void postFrom(String url, Header header, Map<String, String> paramValues, Map<String, String> bodyValues,
Type responseType, Callback<T> callback) throws Exception {
execute(url, HttpMethod.POST,
new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
Query.newInstance().initParams(paramValues), bodyValues), responseType, callback);
}
private <T> void execute(String url, String httpMethod, RequestHttpEntity requestEntity,
Type responseType, Callback<T> callback) throws Exception {
private <T> void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type responseType,
Callback<T> callback) throws Exception {
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
if (logger.isDebugEnabled()) {
logger.debug("HTTP " + httpMethod + " " + url);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("HTTP " + httpMethod + " " + url);
}
clientRequest.execute(uri, httpMethod, requestEntity, responseType, callback);
}
/**
* close request client
* close request client.
*/
public void close() throws Exception {
clientRequest.close();

View File

@ -32,8 +32,7 @@ import java.net.URI;
import java.util.Map;
/**
* NacosRestTemplate
* Interface specifying a basic set of RESTful operations.
* Nacos rest template Interface specifying a basic set of RESTful operations.
*
* @author mai.jh
* @date 2020/5/24
@ -41,18 +40,18 @@ import java.util.Map;
* @see HttpClientResponse
*/
public class NacosRestTemplate {
private static final Logger logger = LoggerFactory.getLogger(NacosRestTemplate.class);
private static final Logger LOGGER = LoggerFactory.getLogger(NacosRestTemplate.class);
private HttpClientRequest requestClient;
public NacosRestTemplate(HttpClientRequest requestClient) {
this.requestClient = requestClient;
}
/**
* http get
* URL request params are expanded using the given query {@link Query}.
* 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
@ -65,10 +64,10 @@ public class NacosRestTemplate {
public <T> HttpRestResult<T> get(String url, Header header, Query query, Type responseType) throws Exception {
return execute(url, HttpMethod.GET, new RequestHttpEntity(header, query), responseType);
}
/**
* http get
* URL request params are expanded using the given query {@link Query}.
* 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
@ -78,15 +77,17 @@ public class NacosRestTemplate {
* @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));
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);
}
/**
* get request, may be pulling a lot of data
* URL request params are expanded using the given query {@link Query},
* 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>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
*
* @param url url
@ -97,13 +98,14 @@ public class NacosRestTemplate {
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> getLarge(String url, Header header, Query query, Object body, Type responseType) throws Exception {
public <T> HttpRestResult<T> getLarge(String url, Header header, Query query, Object body, Type responseType)
throws Exception {
return execute(url, HttpMethod.GET_LARGE, new RequestHttpEntity(header, query, body), responseType);
}
/**
* http delete
* URL request params are expanded using the given query {@link Query}.
* http delete 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
@ -116,11 +118,12 @@ public class NacosRestTemplate {
public <T> HttpRestResult<T> delete(String url, Header header, Query query, Type responseType) throws Exception {
return execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType);
}
/**
* http put
* Create a new resource by PUTting the given body to http request.
* http put Create a new resource by PUTting the given body to http request.
*
* <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
@ -131,15 +134,17 @@ public class NacosRestTemplate {
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> put(String url, Header header, Query query, Object body, Type responseType) throws Exception {
public <T> HttpRestResult<T> put(String url, Header header, Query query, Object body, Type responseType)
throws Exception {
return execute(url, HttpMethod.PUT, new RequestHttpEntity(header, query, body), 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'.
* 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>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
*
* @param url url
@ -150,40 +155,42 @@ public class NacosRestTemplate {
* @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 {
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
header.setContentType(MediaType.APPLICATION_JSON),
Query.newInstance().initParams(paramValues),
body);
public <T> HttpRestResult<T> putJson(String url, Header header, Map<String, String> paramValues, String body,
Type responseType) throws Exception {
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON),
Query.newInstance().initParams(paramValues), body);
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
}
/**
* 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'.
* 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 query {@code Query}.
*
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
*
* @param url url
* @param header http header param
* @param query http query param
* @param query http query param
* @param bodyValues http body param
* @param responseType return type
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> putFrom(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType) throws Exception {
public <T> HttpRestResult<T> putFrom(String url, Header header, Query query, Map<String, String> bodyValues,
Type responseType) throws Exception {
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues);
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues);
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
}
/**
* 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'.
* 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
@ -194,18 +201,19 @@ public class NacosRestTemplate {
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> putFrom(String url, Header header, Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
public <T> HttpRestResult<T> putFrom(String url, Header header, Map<String, String> paramValues,
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),
Query.newInstance().initParams(paramValues), bodyValues);
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
}
/**
* http post
* Create a new resource by POSTing the given object to the http request.
* http post Create a new resource by POSTing the given object to the http request.
*
* <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
@ -216,16 +224,17 @@ public class NacosRestTemplate {
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> post(String url, Header header, Query query, Object body, Type responseType) throws Exception {
return execute(url, HttpMethod.POST, new RequestHttpEntity(header, query, body),
responseType);
public <T> HttpRestResult<T> post(String url, Header header, Query query, Object body, Type responseType)
throws Exception {
return execute(url, HttpMethod.POST, new RequestHttpEntity(header, query, body), 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'.
* 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>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
*
* @param url url
@ -236,40 +245,42 @@ public class NacosRestTemplate {
* @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 {
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
header.setContentType(MediaType.APPLICATION_JSON),
Query.newInstance().initParams(paramValues),
body);
public <T> HttpRestResult<T> postJson(String url, Header header, Map<String, String> paramValues, String body,
Type responseType) throws Exception {
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON),
Query.newInstance().initParams(paramValues), body);
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
}
/**
* 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'.
* 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 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 query http query param
* @param query http query param
* @param bodyValues http body param
* @param responseType return type
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> postFrom(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType) throws Exception {
public <T> HttpRestResult<T> postFrom(String url, Header header, Query query, Map<String, String> bodyValues,
Type responseType) throws Exception {
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues);
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues);
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
}
/**
* 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'.
* 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
@ -280,19 +291,19 @@ public class NacosRestTemplate {
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> postFrom(String url, Header header, Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
public <T> HttpRestResult<T> postFrom(String url, Header header, Map<String, String> paramValues,
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),
Query.newInstance().initParams(paramValues), bodyValues);
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
}
private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttpEntity requestEntity,
Type responseType) throws Exception {
Type responseType) throws Exception {
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
if (logger.isDebugEnabled()) {
logger.debug("HTTP " + httpMethod + " " + url);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("HTTP " + httpMethod + " " + url);
}
HttpClientResponse response = null;
try {
@ -304,12 +315,12 @@ public class NacosRestTemplate {
}
}
}
/**
* close request client
* close request client.
*/
public void close() throws Exception{
public void close() throws Exception {
requestClient.close();
}
}

View File

@ -19,12 +19,14 @@ package com.alibaba.nacos.common.http.handler;
import com.alibaba.nacos.common.utils.JacksonUtils;
/**
* Request handler.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class RequestHandler {
public static String parse(Object object) throws Exception {
return JacksonUtils.toJson(object);
}
}

View File

@ -34,40 +34,52 @@ import java.lang.reflect.Type;
import org.slf4j.Logger;
/**
* Response handler.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class ResponseHandler {
private static final Logger logger = LoggerFactory.getLogger(ResponseHandler.class);
private static final Logger LOGGER = LoggerFactory.getLogger(ResponseHandler.class);
public static <T> T convert(String s, Class<T> cls) throws Exception {
return JacksonUtils.toObj(s, cls);
}
public static <T> T convert(String s, Type type) throws Exception {
return JacksonUtils.toObj(s, type);
}
public static <T> T convert(InputStream inputStream, Type type) throws Exception {
return JacksonUtils.toObj(inputStream, type);
}
private static <T> HttpRestResult<T> convert(RestResult<T> restResult) {
HttpRestResult<T> httpRestResult = new HttpRestResult<T>();
httpRestResult.setCode(restResult.getCode());
httpRestResult.setData(restResult.getData());
httpRestResult.setMessage(restResult.getMessage());
return httpRestResult;
}
@SuppressWarnings({"unchecked", "rawtypes", "resource"})
public static <T> HttpRestResult<T> responseEntityExtractor(HttpClientResponse response, Type type) throws Exception {
public static <T> HttpRestResult<T> responseEntityExtractor(HttpClientResponse response, Type type)
throws Exception {
Header headers = response.getHeaders();
String contentType = headers.getValue(HttpHeaderConsts.CONTENT_TYPE);
InputStream body = response.getBody();
T extractBody = null;
if (contentType != null && contentType.startsWith(MediaType.APPLICATION_JSON) && HttpStatus.SC_OK == response.getStatusCode()) {
if (contentType != null && contentType.startsWith(MediaType.APPLICATION_JSON) && HttpStatus.SC_OK == response
.getStatusCode()) {
extractBody = convert(body, type);
}
if (extractBody == null) {
if (!String.class.toString().equals(type.toString())) {
logger.error("if the response contentType is not [application/json]," +
" only support to java.lang.String");
LOGGER.error(
"if the response contentType is not [application/json]," + " only support to java.lang.String");
throw new NacosDeserializationException(type);
}
extractBody = (T)IoUtils.toString(body, headers.getCharset());
extractBody = (T) IoUtils.toString(body, headers.getCharset());
}
if (extractBody instanceof RestResult) {
HttpRestResult<T> httpRestResult = convert((RestResult<T>) extractBody);
@ -76,13 +88,4 @@ public final class ResponseHandler {
}
return new HttpRestResult<T>(response.getHeaders(), response.getStatusCode(), extractBody);
}
private static <T> HttpRestResult<T> convert(RestResult<T> restResult) {
HttpRestResult<T> httpRestResult = new HttpRestResult<T>();
httpRestResult.setCode(restResult.getCode());
httpRestResult.setData(restResult.getData());
httpRestResult.setMessage(restResult.getMessage());
return httpRestResult;
}
}

View File

@ -16,7 +16,6 @@
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.StringUtils;
@ -28,14 +27,16 @@ import java.util.List;
import java.util.Map;
/**
* Http header.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class Header {
public static final Header EMPTY = Header.newInstance();
private final Map<String, String> header;
private Header() {
header = new LinkedHashMap<String, String>();
addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_JSON);
@ -43,39 +44,44 @@ public class Header {
addParam(HttpHeaderConsts.ACCEPT_ENCODING, "gzip");
addParam(HttpHeaderConsts.CONTENT_ENCODING, "gzip");
}
public static Header newInstance() {
return new Header();
}
public Header addParam(String key, String value) {
header.put(key, value);
return this;
}
public Header setContentType(String contentType) {
if (contentType == null) {
contentType = MediaType.APPLICATION_JSON;
}
return addParam(HttpHeaderConsts.CONTENT_TYPE, contentType);
}
public Header build() {
return this;
}
public String getValue(String key) {
return header.get(key);
}
public Map<String, String> getHeader() {
return header;
}
public Iterator<Map.Entry<String, String>> iterator() {
return header.entrySet().iterator();
}
/**
* Transfer to KV part list. The odd index is key and the even index is value.
*
* @return KV string list
*/
public List<String> toList() {
List<String> list = new ArrayList<String>(header.size() * 2);
Iterator<Map.Entry<String, String>> iterator = iterator();
@ -86,32 +92,43 @@ public class Header {
}
return list;
}
/**
* Add all KV list to header. The odd index is key and the even index is value.
*
* @param list KV list
* @return header
*/
public Header addAll(List<String> list) {
if ((list.size() & 1) != 0) {
throw new IllegalArgumentException("list size must be a multiple of 2");
}
for (int i = 0; i < list.size();) {
for (int i = 0; i < list.size(); ) {
header.put(list.get(i++), list.get(i++));
}
return this;
}
/**
* Add all parameters to header.
*
* @param params parameters
*/
public void addAll(Map<String, String> params) {
for (Map.Entry<String, String> entry : params.entrySet()) {
addParam(entry.getKey(), entry.getValue());
}
}
public String getCharset() {
String acceptCharset = getValue(HttpHeaderConsts.ACCEPT_CHARSET);
if (acceptCharset == null) {
String contentType = getValue(HttpHeaderConsts.CONTENT_TYPE);
acceptCharset = StringUtils.isNotBlank(contentType) ? analysisCharset(contentType) : Constants.ENCODE;
acceptCharset = StringUtils.isNotBlank(contentType) ? analysisCharset(contentType) : Constants.ENCODE;
}
return acceptCharset;
}
private String analysisCharset(String contentType) {
String[] values = contentType.split(";");
String charset = Constants.ENCODE;
@ -125,16 +142,14 @@ public class Header {
}
return charset;
}
public void clear() {
header.clear();
}
@Override
public String toString() {
return "Header{" +
"headerToMap=" + header +
'}';
return "Header{" + "headerToMap=" + header + '}';
}
}

View File

@ -17,30 +17,33 @@
package com.alibaba.nacos.common.http.param;
/**
* Http Media type.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class MediaType {
private 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_OCTET_STREAM = "application/octet-stream";
public static final String APPLICATION_SVG_XML = "application/svg+xml";
public static final String APPLICATION_XHTML_XML = "application/xhtml+xml";
public static final String APPLICATION_XML = "application/xml";
public static final String APPLICATION_JSON = "application/json";
public static final String MULTIPART_FORM_DATA = "multipart/form-data";
public static final String TEXT_HTML = "text/html";
public static final String TEXT_PLAIN = "text/xml";
}

View File

@ -27,75 +27,74 @@ import java.util.Set;
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class Query {
private boolean isEmpty = true;
public static final Query EMPTY = Query.newInstance();
private Map<String, Object> params;
public Query() {
params = new LinkedHashMap<String, Object>();
}
public static Query newInstance() {
return new Query();
}
public Query addParam(String key, Object value) {
isEmpty = false;
params.put(key, value);
return this;
}
public Object getValue(String key) {
return params.get(key);
}
public Query initParams(Map<String, String> params) {
for (Map.Entry<String, String> entry : params.entrySet()) {
addParam(entry.getKey(), entry.getValue());
}
return this;
}
public void initParams(List<String> list) {
if ((list.size() & 1) != 0) {
throw new IllegalArgumentException("list size must be a multiple of 2");
}
for (int i = 0; i < list.size();) {
for (int i = 0; i < list.size(); ) {
addParam(list.get(i++), list.get(i++));
}
}
public String toQueryUrl() {
StringBuilder urlBuilder = new StringBuilder();
Set<Map.Entry<String, Object>> entrySet = params.entrySet();
int i = entrySet.size();
for (Map.Entry<String, Object> entry : entrySet) {
try {
urlBuilder.append(entry.getKey()).append("=").append(
URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8"));
urlBuilder.append(entry.getKey()).append("=")
.append(URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8"));
if (i > 1) {
urlBuilder.append("&");
}
i--;
}
catch (UnsupportedEncodingException e) {
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
return urlBuilder.toString();
}
public void clear() {
isEmpty = false;
params.clear();
}
public boolean isEmpty() {
return isEmpty;
}
}

View File

@ -13,25 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.lifecycle;
package com.alibaba.nacos.common.lifecycle;
import com.alibaba.nacos.api.exception.NacosException;
/**
* An interface is used to define the resource's close and shutdown,
* such as IO Connection and ThreadPool.
* An interface is used to define the resource's close and shutdown, such as IO Connection and ThreadPool.
*
* @author zongtanghu
*
*/
public interface Closeable {
/**
* Shutdown the Resources, such as Thread Pool.
*
* @throws NacosException exception.
*/
public void shutdown() throws NacosException;
}

View File

@ -22,52 +22,51 @@ import com.alibaba.nacos.common.http.param.Query;
import java.util.Map;
/**
*
* Represents an HTTP request , consisting of headers and body.
*
* @author mai.jh
* @date 2020/5/23
*/
public class RequestHttpEntity {
private final Header headers = Header.newInstance();
private final Query query;
private Object body;
public RequestHttpEntity(Header header, Query query) {
handleHeader(header);
this.query = query;
}
public RequestHttpEntity(Header header, Query query, Object body) {
handleHeader(header);
this.query = query;
this.body = body;
}
private void handleHeader(Header header) {
if (header != null && !header.getHeader().isEmpty()) {
Map<String, String> headerMap = header.getHeader();
headers.addAll(headerMap);
}
}
public Header getHeaders() {
return headers;
}
public Query getQuery() {
return query;
}
public Object getBody() {
return body;
}
public boolean isEmptyBody() {
return body == null;
}
}

View File

@ -22,96 +22,97 @@ import java.io.Serializable;
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class RestResult<T> implements Serializable {
private static final long serialVersionUID = 6095433538316185017L;
private int code;
private String message;
private T data;
public RestResult() {
}
public RestResult(int code, String message, T data) {
this.code = code;
this.setMessage(message);
this.data = data;
}
public RestResult(int code, T data) {
this.code = code;
this.data = data;
}
public RestResult(int code, String message) {
this.code = code;
this.setMessage(message);
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public boolean ok() {
return this.code == 0 || this.code == 200;
}
@Override
public String toString() {
return "RestResult{" +
"code=" + code +
", message='" + message + '\'' +
", data=" + data +
'}';
return "RestResult{" + "code=" + code + ", message='" + message + '\'' + ", data=" + data + '}';
}
public static <T> ResResultBuilder<T> builder() {
return new ResResultBuilder<T>();
}
public static final class ResResultBuilder<T> {
private int code;
private String errMsg;
private T data;
private ResResultBuilder() {
}
public ResResultBuilder<T> withCode(int code) {
this.code = code;
return this;
}
public ResResultBuilder<T> withMsg(String errMsg) {
this.errMsg = errMsg;
return this;
}
public ResResultBuilder<T> withData(T data) {
this.data = data;
return this;
}
public RestResult<T> build() {
RestResult<T> restResult = new RestResult<T>();
restResult.setCode(code);

View File

@ -20,60 +20,37 @@ package com.alibaba.nacos.common.model;
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class RestResultUtils {
public static <T> RestResult<T> success() {
return RestResult.<T>builder()
.withCode(200)
.build();
}
public static <T> RestResult<T> success(T data) {
return RestResult.<T>builder()
.withCode(200)
.withData(data)
.build();
}
public static <T> RestResult<T> success(int code, T data) {
return RestResult.<T>builder()
.withCode(code)
.withData(data)
.build();
}
public static <T> RestResult<T> failed() {
return RestResult.<T>builder()
.withCode(500)
.build();
}
public static <T> RestResult<T> failed(String errMsg) {
return RestResult.<T>builder()
.withCode(500)
.withMsg(errMsg)
.build();
}
public static <T> RestResult<T> failed(int code, T data) {
return RestResult.<T>builder()
.withCode(code)
.withData(data)
.build();
}
public static <T> RestResult<T> failed(int code, T data, String errMsg) {
return RestResult.<T>builder()
.withCode(code)
.withData(data)
.withMsg(errMsg)
.build();
}
public static <T> RestResult<T> failedWithMsg(int code, String errMsg) {
return RestResult.<T>builder()
.withCode(code)
.withMsg(errMsg)
.build();
}
}
public static <T> RestResult<T> success() {
return RestResult.<T>builder().withCode(200).build();
}
public static <T> RestResult<T> success(T data) {
return RestResult.<T>builder().withCode(200).withData(data).build();
}
public static <T> RestResult<T> success(int code, T data) {
return RestResult.<T>builder().withCode(code).withData(data).build();
}
public static <T> RestResult<T> failed() {
return RestResult.<T>builder().withCode(500).build();
}
public static <T> RestResult<T> failed(String errMsg) {
return RestResult.<T>builder().withCode(500).withMsg(errMsg).build();
}
public static <T> RestResult<T> failed(int code, T data) {
return RestResult.<T>builder().withCode(code).withData(data).build();
}
public static <T> RestResult<T> failed(int code, T data, String errMsg) {
return RestResult.<T>builder().withCode(code).withData(data).withMsg(errMsg).build();
}
public static <T> RestResult<T> failedWithMsg(int code, String errMsg) {
return RestResult.<T>builder().withCode(code).withMsg(errMsg).build();
}
}

View File

@ -21,40 +21,59 @@ import java.nio.charset.Charset;
import com.alibaba.nacos.api.common.Constants;
/**
* ByteUtils.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public final class ByteUtils {
public static final byte[] EMPTY = new byte[0];
public static byte[] toBytes(String s) {
if (s == null) {
/**
* String to byte array.
*
* @param input input string
* @return byte array of string
*/
public static byte[] toBytes(String input) {
if (input == null) {
return EMPTY;
}
return s.getBytes(Charset.forName(Constants.ENCODE));
return input.getBytes(Charset.forName(Constants.ENCODE));
}
public static byte[] toBytes(Object s) {
if (s == null) {
/**
* Object to byte array.
*
* @param obj input obj
* @return byte array of object
*/
public static byte[] toBytes(Object obj) {
if (obj == null) {
return EMPTY;
}
return toBytes(String.valueOf(s));
return toBytes(String.valueOf(obj));
}
/**
* Byte array to string.
*
* @param bytes byte array
* @return string
*/
public static String toString(byte[] bytes) {
if (bytes == null) {
return StringUtils.EMPTY;
}
return new String(bytes, Charset.forName(Constants.ENCODE));
}
public static boolean isEmpty(byte[] data) {
return data == null || data.length == 0;
}
public static boolean isNotEmpty(byte[] data) {
return !isEmpty(data);
}
}

View File

@ -24,211 +24,223 @@ import java.util.List;
import java.util.Map;
/**
* copy from <link>org.apache.commons.collections</link>
* Copy from {@link org.apache.commons.collections}.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class CollectionUtils {
/**
* Returns the <code>index</code>-th value in <code>object</code>, throwing
* <code>IndexOutOfBoundsException</code> if there is no such element or
* <code>IllegalArgumentException</code> if <code>object</code> is not an
* instance of one of the supported types.
* <p>
* The supported types, and associated semantics are:
* <ul>
* <li> Map -- the value returned is the <code>Map.Entry</code> in position
* <code>index</code> in the map's <code>entrySet</code> iterator,
* if there is such an entry.</li>
* <li> List -- this method is equivalent to the list's get method.</li>
* <li> Array -- the <code>index</code>-th array entry is returned,
* if there is such an entry; otherwise an <code>IndexOutOfBoundsException</code>
* is thrown.</li>
* <li> Collection -- the value returned is the <code>index</code>-th object
* returned by the collection's default iterator, if there is such an element.</li>
* <li> Iterator or Enumeration -- the value returned is the
* <code>index</code>-th object in the Iterator/Enumeration, if there
* is such an element. The Iterator/Enumeration is advanced to
* <code>index</code> (or to the end, if <code>index</code> exceeds the
* number of entries) as a side effect of this method.</li>
* </ul>
*
* @param object the object to get a value from
* @param index the index to get
* @return the object at the specified index
* @throws IndexOutOfBoundsException if the index is invalid
* @throws IllegalArgumentException if the object type is invalid
*/
public static Object get(Object object, int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
}
if (object instanceof Map) {
Map map = (Map) object;
Iterator iterator = map.entrySet().iterator();
return get(iterator, index);
} else if (object instanceof List) {
return ((List) object).get(index);
} else if (object instanceof Object[]) {
return ((Object[]) object)[index];
} else if (object instanceof Iterator) {
Iterator it = (Iterator) object;
while (it.hasNext()) {
index--;
if (index == -1) {
return it.next();
} else {
it.next();
}
}
throw new IndexOutOfBoundsException("Entry does not exist: " + index);
} else if (object instanceof Collection) {
Iterator iterator = ((Collection) object).iterator();
return get(iterator, index);
} else if (object instanceof Enumeration) {
Enumeration it = (Enumeration) object;
while (it.hasMoreElements()) {
index--;
if (index == -1) {
return it.nextElement();
} else {
it.nextElement();
}
}
throw new IndexOutOfBoundsException("Entry does not exist: " + index);
} else if (object == null) {
throw new IllegalArgumentException("Unsupported object type: null");
} else {
try {
return Array.get(object, index);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
}
}
}
/**
* Gets the size of the collection/iterator specified.
* <p>
* This method can handles objects as follows
* <ul>
* <li>Collection - the collection size
* <li>Map - the map size
* <li>Array - the array size
* <li>Iterator - the number of elements remaining in the iterator
* <li>Enumeration - the number of elements remaining in the enumeration
* </ul>
*
* @param object the object to get the size of
* @return the size of the specified collection
* @throws IllegalArgumentException thrown if object is not recognised or null
* @since Commons Collections 3.1
*/
public static int size(Object object) {
int total = 0;
if (object instanceof Map) {
total = ((Map) object).size();
} else if (object instanceof Collection) {
total = ((Collection) object).size();
} else if (object instanceof Object[]) {
total = ((Object[]) object).length;
} else if (object instanceof Iterator) {
Iterator it = (Iterator) object;
while (it.hasNext()) {
total++;
it.next();
}
} else if (object instanceof Enumeration) {
Enumeration it = (Enumeration) object;
while (it.hasMoreElements()) {
total++;
it.nextElement();
}
} else if (object == null) {
throw new IllegalArgumentException("Unsupported object type: null");
} else {
try {
total = Array.getLength(object);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
}
}
return total;
}
public static boolean sizeIsEmpty(Object object) {
if (object instanceof Collection) {
return ((Collection) object).isEmpty();
} else if (object instanceof Map) {
return ((Map) object).isEmpty();
} else if (object instanceof Object[]) {
return ((Object[]) object).length == 0;
} else if (object instanceof Iterator) {
return ((Iterator) object).hasNext() == false;
} else if (object instanceof Enumeration) {
return ((Enumeration) object).hasMoreElements() == false;
} else if (object == null) {
throw new IllegalArgumentException("Unsupported object type: null");
} else {
try {
return Array.getLength(object) == 0;
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
}
}
}
public static <T> boolean contains(Collection<T> coll, T target) {
if (isEmpty(coll)) {
return false;
}
return coll.contains(target);
}
/**
* Null-safe check if the specified collection is empty.
* <p>
* Null returns true.
*
* @param coll the collection to check, may be null
* @return true if empty or null
* @since Commons Collections 3.2
*/
public static boolean isEmpty(Collection coll) {
return (coll == null || coll.isEmpty());
}
/**
* Null-safe check if the specified collection is not empty.
* <p>
* Null returns false.
*
* @param coll the collection to check, may be null
* @return true if non-null and non-empty
* @since Commons Collections 3.2
*/
public static boolean isNotEmpty(Collection coll) {
return !CollectionUtils.isEmpty(coll);
}
/**
* Returns the <code>index</code>-th value in <code>object</code>, throwing
* <code>IndexOutOfBoundsException</code> if there is no such element or
* <code>IllegalArgumentException</code> if <code>object</code> is not an
* instance of one of the supported types.
*
* <p>The supported types, and associated semantics are:
* <ul>
* <li> Map -- the value returned is the <code>Map.Entry</code> in position
* <code>index</code> in the map's <code>entrySet</code> iterator,
* if there is such an entry.</li>
* <li> List -- this method is equivalent to the list's get method.</li>
* <li> Array -- the <code>index</code>-th array entry is returned,
* if there is such an entry; otherwise an <code>IndexOutOfBoundsException</code>
* is thrown.</li>
* <li> Collection -- the value returned is the <code>index</code>-th object
* returned by the collection's default iterator, if there is such an element.</li>
* <li> Iterator or Enumeration -- the value returned is the
* <code>index</code>-th object in the Iterator/Enumeration, if there
* is such an element. The Iterator/Enumeration is advanced to
* <code>index</code> (or to the end, if <code>index</code> exceeds the
* number of entries) as a side effect of this method.</li>
* </ul>
*
* @param object the object to get a value from
* @param index the index to get
* @return the object at the specified index
* @throws IndexOutOfBoundsException if the index is invalid
* @throws IllegalArgumentException if the object type is invalid
*/
public static Object get(Object object, int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
}
if (object instanceof Map) {
Map map = (Map) object;
Iterator iterator = map.entrySet().iterator();
return get(iterator, index);
} else if (object instanceof List) {
return ((List) object).get(index);
} else if (object instanceof Object[]) {
return ((Object[]) object)[index];
} else if (object instanceof Iterator) {
Iterator it = (Iterator) object;
while (it.hasNext()) {
index--;
if (index == -1) {
return it.next();
} else {
it.next();
}
}
throw new IndexOutOfBoundsException("Entry does not exist: " + index);
} else if (object instanceof Collection) {
Iterator iterator = ((Collection) object).iterator();
return get(iterator, index);
} else if (object instanceof Enumeration) {
Enumeration it = (Enumeration) object;
while (it.hasMoreElements()) {
index--;
if (index == -1) {
return it.nextElement();
} else {
it.nextElement();
}
}
throw new IndexOutOfBoundsException("Entry does not exist: " + index);
} else if (object == null) {
throw new IllegalArgumentException("Unsupported object type: null");
} else {
try {
return Array.get(object, index);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
}
}
}
/**
* Gets the size of the collection/iterator specified.
*
* <p>This method can handles objects as follows
* <ul>
* <li>Collection - the collection size
* <li>Map - the map size
* <li>Array - the array size
* <li>Iterator - the number of elements remaining in the iterator
* <li>Enumeration - the number of elements remaining in the enumeration
* </ul>
*
* @param object the object to get the size of
* @return the size of the specified collection
* @throws IllegalArgumentException thrown if object is not recognised or null
* @since Commons Collections 3.1
*/
public static int size(Object object) {
int total = 0;
if (object instanceof Map) {
total = ((Map) object).size();
} else if (object instanceof Collection) {
total = ((Collection) object).size();
} else if (object instanceof Object[]) {
total = ((Object[]) object).length;
} else if (object instanceof Iterator) {
Iterator it = (Iterator) object;
while (it.hasNext()) {
total++;
it.next();
}
} else if (object instanceof Enumeration) {
Enumeration it = (Enumeration) object;
while (it.hasMoreElements()) {
total++;
it.nextElement();
}
} else if (object == null) {
throw new IllegalArgumentException("Unsupported object type: null");
} else {
try {
total = Array.getLength(object);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
}
}
return total;
}
/**
* Judge whether object is empty.
*
* @param object object
* @return true if object is empty, otherwise false
* @throws IllegalArgumentException if object has no length or size
*/
public static boolean sizeIsEmpty(Object object) {
if (object instanceof Collection) {
return ((Collection) object).isEmpty();
} else if (object instanceof Map) {
return ((Map) object).isEmpty();
} else if (object instanceof Object[]) {
return ((Object[]) object).length == 0;
} else if (object instanceof Iterator) {
return ((Iterator) object).hasNext() == false;
} else if (object instanceof Enumeration) {
return ((Enumeration) object).hasMoreElements() == false;
} else if (object == null) {
throw new IllegalArgumentException("Unsupported object type: null");
} else {
try {
return Array.getLength(object) == 0;
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
}
}
}
/**
* Whether contain item in collection.
*
* @param coll collection
* @param target target value
* @param <T> Genreal Type
* @return true if contain, otherwise false
*/
public static <T> boolean contains(Collection<T> coll, T target) {
if (isEmpty(coll)) {
return false;
}
return coll.contains(target);
}
/**
* Null-safe check if the specified collection is empty.
*
* <p>Null returns true.
*
* @param coll the collection to check, may be null
* @return true if empty or null
* @since Commons Collections 3.2
*/
public static boolean isEmpty(Collection coll) {
return (coll == null || coll.isEmpty());
}
/**
* Null-safe check if the specified collection is not empty.
*
* <p>Null returns false.
*
* @param coll the collection to check, may be null
* @return true if non-null and non-empty
* @since Commons Collections 3.2
*/
public static boolean isNotEmpty(Collection coll) {
return !CollectionUtils.isEmpty(coll);
}
/**
* Returns the value to which the specified index , or {@code defaultValue} if this collection contains no value for
* the index.
*
* @param coll
* the collection to get a value from
* @param index
* the index to get
* @param defaultValue
* @param <T>
* @param coll the collection to get a value from
* @param index the index to get
* @param defaultValue default value
* @param <T> General Type
* @return the value to which the specified index , or {@code defaultValue} if this collection contains no value for
* the index.
* the index.
*/
public static <T> T getOrDefault(Collection<T> coll, int index, T defaultValue) {
try {
return (T)get(coll, index);
return (T) get(coll, index);
} catch (IndexOutOfBoundsException e) {
return defaultValue;
}

View File

@ -21,68 +21,44 @@ import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
/**
* Concurrent Hash Set implement by {@link ConcurrentHashMap}.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ConcurrentHashSet<E> extends AbstractSet<E> {
private ConcurrentHashMap<E, Boolean> map;
/**
* constructor
*/
public ConcurrentHashSet() {
super();
map = new ConcurrentHashMap<E, Boolean>();
}
/**
* return the size of the map
*
* @see java.util.AbstractCollection#size()
*/
@Override
public int size() {
return map.size();
}
/**
* @see java.util.AbstractCollection#contains(java.lang.Object)
*/
@Override
public boolean contains(Object o) {
return map.containsKey(o);
}
/**
* @see java.util.AbstractCollection#iterator()
*/
@Override
public Iterator<E> iterator() {
return map.keySet().iterator();
}
/**
* add an obj to set, if exist, return false, else return true
*
* @see java.util.AbstractCollection#add(java.lang.Object)
*/
@Override
public boolean add(E o) {
return map.putIfAbsent(o, Boolean.TRUE) == null;
}
/**
* @see java.util.AbstractCollection#remove(java.lang.Object)
*/
@Override
public boolean remove(Object o) {
return map.remove(o) != null;
}
/**
* clear the set
*
* @see java.util.AbstractCollection#clear()
*/
@Override
public void clear() {
map.clear();

View File

@ -17,15 +17,17 @@
package com.alibaba.nacos.common.utils;
/**
* Value Convert Utils.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class ConvertUtils {
private static final String NULL_STR = "null";
/**
* Convert String value to int value if parameter value is legal.
* And it automatically defaults to 0 if parameter value is null or blank str.
* Convert String value to int value if parameter value is legal. And it automatically defaults to 0 if parameter
* value is null or blank str.
*
* @param val String value which need to be converted to int value.
* @return Converted int value and its default value is 0.
@ -33,7 +35,15 @@ public final class ConvertUtils {
public static int toInt(String val) {
return toInt(val, 0);
}
/**
* Convert String value to int value if parameter value is legal. And return default value if parameter value is
* null or blank str.
*
* @param val value
* @param defaultValue default value
* @return int value if input value is legal, otherwise default value
*/
public static int toInt(String val, int defaultValue) {
if (StringUtils.equalsIgnoreCase(val, NULL_STR)) {
return defaultValue;
@ -43,38 +53,59 @@ public final class ConvertUtils {
}
return Integer.parseInt(val);
}
/**
* Convert String value to long value if parameter value is legal. And it automatically defaults to 0 if parameter
* value is null or blank str.
*
* @param val String value which need to be converted to int value.
* @return Converted long value and its default value is 0.
*/
public static long toLong(String val) {
return toLong(val);
return toLong(val, 0L);
}
/**
* Convert String value to long value if parameter value is legal. And return default value if parameter value is
* null or blank str.
*
* @param val value
* @param defaultValue default value
* @return long value if input value is legal, otherwise default value
*/
public static long toLong(String val, long defaultValue) {
if (StringUtils.isBlank(val)) {
return defaultValue;
}
return Long.parseLong(val);
}
/**
* Convert String value to boolean value if parameter value is legal. And return default value if parameter value is
* null or blank str.
*
* @param val value
* @param defaultValue default value
* @return boolean value if input value is legal, otherwise default value
*/
public static boolean toBoolean(String val, boolean defaultValue) {
if (StringUtils.isBlank(val)) {
return defaultValue;
}
return Boolean.parseBoolean(val);
}
// The following utility functions are extracted from <link>org.apache.commons.lang3</link>
// start
/**
* <p>Converts a String to a boolean (optimised for performance).</p>
*
* <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'} or {@code 'yes'}
* (case insensitive) will return {@code true}. Otherwise,
* {@code false} is returned.</p>
* (case insensitive) will return {@code true}. Otherwise, {@code false} is returned.</p>
*
* <p>This method performs 4 times faster (JDK1.4) than
* {@code Boolean.valueOf(String)}. However, this method accepts
* 'on' and 'yes', 't', 'y' as true values.
* {@code Boolean.valueOf(String)}. However, this method accepts 'on' and 'yes', 't', 'y' as true values.
*
* <pre>
* BooleanUtils.toBoolean(null) = false
@ -91,21 +122,19 @@ public final class ConvertUtils {
* BooleanUtils.toBooleanObject("f") = false
* </pre>
*
* @param str the String to check
* @param str the String to check
* @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;
}
/**
* <p>Converts a String to a Boolean.</p>
*
* <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'} or {@code 'yes'}
* (case insensitive) will return {@code true}.
* {@code 'false'}, {@code 'off'}, {@code 'n'}, {@code 'f'} or {@code 'no'}
* (case insensitive) will return {@code false}.
* Otherwise, {@code null} is returned.</p>
* (case insensitive) will return {@code true}. {@code 'false'}, {@code 'off'}, {@code 'n'}, {@code 'f'} or {@code
* 'no'} (case insensitive) will return {@code false}. Otherwise, {@code null} is returned.</p>
*
* <p>NOTE: This returns null and will throw a NullPointerException if autoboxed to a boolean. </p>
*
@ -129,7 +158,7 @@ public final class ConvertUtils {
* BooleanUtils.toBooleanObject("ono") = null // does not match on or no
* </pre>
*
* @param str the String to check; upper and lower case are treated as the same
* @param str the String to check; upper and lower case are treated as the same
* @return the Boolean value of the string, {@code null} if no match or {@code null} input
*/
@SuppressWarnings("all")
@ -143,17 +172,17 @@ public final class ConvertUtils {
char ch1;
char ch2;
char ch3;
switch(str.length()) {
switch (str.length()) {
case 1:
ch0 = str.charAt(0);
if (ch0 == 'y' || ch0 == 'Y' || ch0 == 't' || ch0 == 'T') {
return Boolean.TRUE;
}
if (ch0 != 'n' && ch0 != 'N' && ch0 != 'f' && ch0 != 'F') {
break;
}
return Boolean.FALSE;
case 2:
ch0 = str.charAt(0);
@ -161,7 +190,7 @@ public final class ConvertUtils {
if ((ch0 == 'o' || ch0 == 'O') && (ch1 == 'n' || ch1 == 'N')) {
return Boolean.TRUE;
}
if ((ch0 == 'n' || ch0 == 'N') && (ch1 == 'o' || ch1 == 'O')) {
return Boolean.FALSE;
}
@ -173,7 +202,7 @@ public final class ConvertUtils {
if ((ch0 == 'y' || ch0 == 'Y') && (ch1 == 'e' || ch1 == 'E') && (ch2 == 's' || ch2 == 'S')) {
return Boolean.TRUE;
}
if ((ch0 == 'o' || ch0 == 'O') && (ch1 == 'f' || ch1 == 'F') && (ch2 == 'f' || ch2 == 'F')) {
return Boolean.FALSE;
}
@ -183,7 +212,8 @@ public final class ConvertUtils {
ch1 = str.charAt(1);
ch2 = str.charAt(2);
ch3 = str.charAt(3);
if ((ch0 == 't' || ch0 == 'T') && (ch1 == 'r' || ch1 == 'R') && (ch2 == 'u' || ch2 == 'U') && (ch3 == 'e' || ch3 == 'E')) {
if ((ch0 == 't' || ch0 == 'T') && (ch1 == 'r' || ch1 == 'R') && (ch2 == 'u' || ch2 == 'U') && (
ch3 == 'e' || ch3 == 'E')) {
return Boolean.TRUE;
}
break;
@ -193,15 +223,16 @@ public final class ConvertUtils {
ch2 = str.charAt(2);
ch3 = str.charAt(3);
char ch4 = str.charAt(4);
if ((ch0 == 'f' || ch0 == 'F') && (ch1 == 'a' || ch1 == 'A') && (ch2 == 'l' || ch2 == 'L') && (ch3 == 's' || ch3 == 'S') && (ch4 == 'e' || ch4 == 'E')) {
if ((ch0 == 'f' || ch0 == 'F') && (ch1 == 'a' || ch1 == 'A') && (ch2 == 'l' || ch2 == 'L') && (
ch3 == 's' || ch3 == 'S') && (ch4 == 'e' || ch4 == 'E')) {
return Boolean.FALSE;
}
}
return null;
}
}
// end
}

View File

@ -13,31 +13,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
/**
* Common methods for exception
* Common methods for exception.
*
* @author nkorange
* @since 1.2.0
*/
public class ExceptionUtil {
public static String getAllExceptionMsg(Throwable e) {
Throwable cause = e;
StringBuilder strBuilder = new StringBuilder();
while (cause != null && !StringUtils.isEmpty(cause.getMessage())) {
strBuilder.append("caused: ").append(cause.getMessage()).append(";");
cause = cause.getCause();
}
return strBuilder.toString();
}
public static Throwable getCause(final Throwable t) {
final Throwable cause = t.getCause();
if (Objects.isNull(cause)) {
@ -45,12 +46,12 @@ public class ExceptionUtil {
}
return cause;
}
public static String getStackTrace(final Throwable t) {
if (t == null) {
return "";
}
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final PrintStream ps = new PrintStream(out);
t.printStackTrace(ps);

View File

@ -13,31 +13,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
/**
* Http method constants.
*
* @author nkorange
* @since 0.8.0
*/
public class HttpMethod {
public static final String GET = "GET";
// this is only use in nacos, Custom request type, essentially a get request
public static final String GET_LARGE = "GET-LARGE";
public static final String HEAD = "HEAD";
public static final String POST = "POST";
public static final String PUT = "PUT";
public static final String PATCH = "PATCH";
public static final String DELETE = "DELETE";
public static final String OPTIONS = "OPTIONS";
public static final String TRACE = "TRACE";
}

View File

@ -13,11 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import com.alibaba.nacos.api.common.Constants;
import java.io.*;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.CharArrayWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
@ -25,12 +39,12 @@ import java.util.List;
import java.util.zip.GZIPInputStream;
/**
* IO related tool methods
* IO related tool methods.
*
* @author nacos
*/
public class IoUtils {
public static byte[] tryDecompress(InputStream raw) throws Exception {
GZIPInputStream gis = null;
ByteArrayOutputStream out = null;
@ -49,17 +63,37 @@ public class IoUtils {
gis.close();
}
}
return null;
}
static private BufferedReader toBufferedReader(Reader reader) {
return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(
reader);
public static byte[] tryDecompress(byte[] raw) throws Exception {
if (!isGzipStream(raw)) {
return raw;
}
GZIPInputStream gis = null;
ByteArrayOutputStream out = null;
try {
gis = new GZIPInputStream(new ByteArrayInputStream(raw));
out = new ByteArrayOutputStream();
IoUtils.copy(gis, out);
return out.toByteArray();
} finally {
if (out != null) {
out.close();
}
if (gis != null) {
gis.close();
}
}
}
public static void writeStringToFile(File file, String data, String encoding)
throws IOException {
private static BufferedReader toBufferedReader(Reader reader) {
return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
}
public static void writeStringToFile(File file, String data, String encoding) throws IOException {
OutputStream os = null;
try {
os = new FileOutputStream(file);
@ -71,8 +105,8 @@ public class IoUtils {
}
}
}
static public List<String> readLines(Reader input) throws IOException {
public static List<String> readLines(Reader input) throws IOException {
BufferedReader reader = toBufferedReader(input);
List<String> list = new ArrayList<String>();
String line = null;
@ -88,22 +122,22 @@ public class IoUtils {
}
return list;
}
static public String toString(InputStream input, String encoding) throws IOException {
public static String toString(InputStream input, String encoding) throws IOException {
if (input == null) {
return StringUtils.EMPTY;
}
return (null == encoding) ? toString(new InputStreamReader(input, Constants.ENCODE))
: toString(new InputStreamReader(input, encoding));
: toString(new InputStreamReader(input, encoding));
}
static public String toString(Reader reader) throws IOException {
public static String toString(Reader reader) throws IOException {
CharArrayWriter sw = new CharArrayWriter();
copy(reader, sw);
return sw.toString();
}
static public long copy(Reader input, Writer output) throws IOException {
public static long copy(Reader input, Writer output) throws IOException {
char[] buffer = new char[1 << 12];
long count = 0;
for (int n = 0; (n = input.read(buffer)) >= 0; ) {
@ -112,12 +146,25 @@ public class IoUtils {
}
return count;
}
public static long copy(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[1024];
int bytesRead;
int totalBytes = 0;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
totalBytes += bytesRead;
}
return totalBytes;
}
public static void delete(File fileOrDir) throws IOException {
if (fileOrDir == null) {
return;
}
if (fileOrDir.isDirectory()) {
cleanDirectory(fileOrDir);
} else {
@ -129,29 +176,27 @@ public class IoUtils {
}
}
}
/**
* 清理目录下的内容
* 清理目录下的内容.
*/
public static void cleanDirectory(File directory) throws IOException {
if (!directory.exists()) {
String message = directory + " does not exist";
throw new IllegalArgumentException(message);
}
if (!directory.isDirectory()) {
String message = directory + " is not a directory";
throw new IllegalArgumentException(message);
}
File[] files = directory.listFiles();
/**
* null if security restricted
*/
// null if security restricted
if (files == null) {
throw new IOException("Failed to list contents of " + directory);
}
IOException exception = null;
for (File file : files) {
try {
@ -160,26 +205,13 @@ public class IoUtils {
exception = ioe;
}
}
if (null != exception) {
throw exception;
}
}
static public long copy(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[1024];
int bytesRead;
int totalBytes = 0;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
totalBytes += bytesRead;
}
return totalBytes;
}
static public void copyFile(String source, String target) throws IOException {
public static void copyFile(String source, String target) throws IOException {
File sf = new File(source);
if (!sf.exists()) {
throw new IllegalArgumentException("source file does not exist.");
@ -191,7 +223,7 @@ public class IoUtils {
if (!tf.exists() && !tf.createNewFile()) {
throw new RuntimeException("failed to create target file.");
}
FileChannel sc = null;
FileChannel tc = null;
try {
@ -207,39 +239,17 @@ public class IoUtils {
}
}
}
public static boolean isGzipStream(byte[] bytes) {
int minByteArraySize = 2;
if (bytes == null || bytes.length < minByteArraySize) {
return false;
}
return GZIPInputStream.GZIP_MAGIC == ((bytes[1] << 8 | bytes[0]) & 0xFFFF);
}
public static byte[] tryDecompress(byte[] raw) throws Exception {
if (!isGzipStream(raw)) {
return raw;
}
GZIPInputStream gis = null;
ByteArrayOutputStream out = null;
try {
gis = new GZIPInputStream(new ByteArrayInputStream(raw));
out = new ByteArrayOutputStream();
IoUtils.copy(gis, out);
return out.toByteArray();
} finally {
if (out != null) {
out.close();
}
if (gis != null) {
gis.close();
}
}
}
public static void closeQuietly(HttpURLConnection connection) {
if (connection != null) {
try {
@ -248,25 +258,22 @@ public class IoUtils {
}
}
}
public static void closeQuietly(InputStream input) {
closeQuietly((Closeable)input);
closeQuietly((Closeable) input);
}
public static void closeQuietly(OutputStream output) {
closeQuietly((Closeable)output);
closeQuietly((Closeable) output);
}
public static void closeQuietly(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (IOException ioe) {
// ignore
} catch (IOException ignored) {
}
}
}

View File

@ -33,118 +33,235 @@ import java.io.IOException;
import java.lang.reflect.Type;
/**
* Json utils implement by Jackson.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class JacksonUtils {
static ObjectMapper mapper = new ObjectMapper();
static {
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.setSerializationInclusion(Include.NON_NULL);
}
public static String toJson(Object obj) {
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new NacosSerializationException(obj.getClass(), e);
}
}
public static byte[] toJsonBytes(Object obj) {
try {
return ByteUtils.toBytes(mapper.writeValueAsString(obj));
} catch (JsonProcessingException e) {
throw new NacosSerializationException(obj.getClass(), e);
}
}
public static <T> T toObj(byte[] json, Class<T> cls) {
try {
return toObj(StringUtils.newString4UTF8(json), cls);
} catch (Exception e) {
throw new NacosDeserializationException(cls, e);
}
}
public static <T> T toObj(byte[] json, Type cls) {
static ObjectMapper mapper = new ObjectMapper();
static {
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.setSerializationInclusion(Include.NON_NULL);
}
/**
* Object to json string.
*
* @param obj obj
* @return json string
* @throws NacosSerializationException if transfer failed
*/
public static String toJson(Object obj) {
try {
return toObj(StringUtils.newString4UTF8(json), cls);
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new NacosSerializationException(obj.getClass(), e);
}
}
/**
* Object to json string byte array.
*
* @param obj obj
* @return json string byte array
* @throws NacosSerializationException if transfer failed
*/
public static byte[] toJsonBytes(Object obj) {
try {
return ByteUtils.toBytes(mapper.writeValueAsString(obj));
} catch (JsonProcessingException e) {
throw new NacosSerializationException(obj.getClass(), e);
}
}
/**
* Json string deserialize to Object.
*
* @param json json string
* @param cls class of object
* @param <T> General type
* @return object
* @throws NacosDeserializationException if deserialize failed
*/
public static <T> T toObj(byte[] json, Class<T> cls) {
try {
return toObj(StringUtils.newStringForUtf8(json), cls);
} catch (Exception e) {
throw new NacosDeserializationException(cls, e);
}
}
/**
* Json string deserialize to Object.
*
* @param json json string
* @param cls {@link Type} of object
* @param <T> General type
* @return object
* @throws NacosDeserializationException if deserialize failed
*/
public static <T> T toObj(byte[] json, Type cls) {
try {
return toObj(StringUtils.newStringForUtf8(json), cls);
} catch (Exception e) {
throw new NacosDeserializationException(e);
}
}
public static <T> T toObj(InputStream inputStream, Class<T> tClass) {
/**
* Json string deserialize to Object.
*
* @param inputStream json string input stream
* @param cls class of object
* @param <T> General type
* @return object
* @throws NacosDeserializationException if deserialize failed
*/
public static <T> T toObj(InputStream inputStream, Class<T> cls) {
try {
return mapper.readValue(inputStream, tClass);
return mapper.readValue(inputStream, cls);
} catch (IOException e) {
throw new NacosDeserializationException(e);
}
}
/**
* Json string deserialize to Object.
*
* @param json json string byte array
* @param typeReference {@link TypeReference} of object
* @param <T> General type
* @return object
* @throws NacosDeserializationException if deserialize failed
*/
public static <T> T toObj(byte[] json, TypeReference<T> typeReference) {
try {
return toObj(StringUtils.newString4UTF8(json), typeReference);
return toObj(StringUtils.newStringForUtf8(json), typeReference);
} catch (Exception e) {
throw new NacosDeserializationException(e);
}
}
public static <T> T toObj(String json, Class<T> cls) {
try {
return mapper.readValue(json, cls);
} catch (IOException e) {
throw new NacosDeserializationException(cls, e);
}
}
public static <T> T toObj(String json, Type type) {
try {
return mapper.readValue(json, mapper.constructType(type));
} catch (IOException e) {
throw new NacosDeserializationException(e);
}
}
public static <T> T toObj(String json, TypeReference<T> typeReference) {
try {
return mapper.readValue(json, typeReference);
} catch (IOException e) {
throw new NacosDeserializationException(typeReference.getClass(), e);
}
}
public static <T> T toObj(InputStream inputStream, Type type) {
/**
* Json string deserialize to Object.
*
* @param json json string
* @param cls class of object
* @param <T> General type
* @return object
* @throws NacosDeserializationException if deserialize failed
*/
public static <T> T toObj(String json, Class<T> cls) {
try {
return mapper.readValue(json, cls);
} catch (IOException e) {
throw new NacosDeserializationException(cls, e);
}
}
/**
* Json string deserialize to Object.
*
* @param json json string
* @param type {@link Type} of object
* @param <T> General type
* @return object
* @throws NacosDeserializationException if deserialize failed
*/
public static <T> T toObj(String json, Type type) {
try {
return mapper.readValue(json, mapper.constructType(type));
} catch (IOException e) {
throw new NacosDeserializationException(e);
}
}
/**
* Json string deserialize to Object.
*
* @param json json string
* @param typeReference {@link TypeReference} of object
* @param <T> General type
* @return object
* @throws NacosDeserializationException if deserialize failed
*/
public static <T> T toObj(String json, TypeReference<T> typeReference) {
try {
return mapper.readValue(json, typeReference);
} catch (IOException e) {
throw new NacosDeserializationException(typeReference.getClass(), e);
}
}
/**
* Json string deserialize to Object.
*
* @param inputStream json string input stream
* @param type {@link Type} of object
* @param <T> General type
* @return object
* @throws NacosDeserializationException if deserialize failed
*/
public static <T> T toObj(InputStream inputStream, Type type) {
try {
return mapper.readValue(inputStream, mapper.constructType(type));
} catch (IOException e) {
throw new NacosDeserializationException(type, e);
}
}
public static JsonNode toObj(String json) {
try {
return mapper.readTree(json);
} catch (IOException e) {
throw new NacosDeserializationException(e);
}
}
public static void registerSubtype(Class<?> clz, String type) {
mapper.registerSubtypes(new NamedType(clz, type));
}
public static ObjectNode createEmptyJsonNode() {
return new ObjectNode(mapper.getNodeFactory());
}
public static ArrayNode createEmptyArrayNode() {
return new ArrayNode(mapper.getNodeFactory());
}
public static JsonNode transferToJsonNode(Object obj) {
return mapper.valueToTree(obj);
}
/**
* Json string deserialize to Jackson {@link JsonNode}.
*
* @param json json string
* @return {@link JsonNode}
* @throws NacosDeserializationException if deserialize failed
*/
public static JsonNode toObj(String json) {
try {
return mapper.readTree(json);
} catch (IOException e) {
throw new NacosDeserializationException(e);
}
}
/**
* Register sub type for child class.
*
* @param clz child class
* @param type type name of child class
*/
public static void registerSubtype(Class<?> clz, String type) {
mapper.registerSubtypes(new NamedType(clz, type));
}
/**
* Create a new empty Jackson {@link ObjectNode}.
*
* @return {@link ObjectNode}
*/
public static ObjectNode createEmptyJsonNode() {
return new ObjectNode(mapper.getNodeFactory());
}
/**
* Create a new empty Jackson {@link ArrayNode}.
*
* @return {@link ArrayNode}
*/
public static ArrayNode createEmptyArrayNode() {
return new ArrayNode(mapper.getNodeFactory());
}
/**
* Parse object to Jackson {@link JsonNode}.
*
* @param obj object
* @return {@link JsonNode}
*/
public static JsonNode transferToJsonNode(Object obj) {
return mapper.valueToTree(obj);
}
}

View File

@ -19,48 +19,85 @@ package com.alibaba.nacos.common.utils;
import org.slf4j.Logger;
/**
* Logger utils.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class LoggerUtils {
public static final String TRACE = "TRACE";
public static final String INFO = "INFO";
public static final String DEBUG = "DEBUG";
public static final String WARN = "WARN";
public static final String ERROR = "ERROR";
public static void printIfDebugEnabled(Logger logger, String s, Object... args) {
if (logger.isDebugEnabled()) {
logger.debug(s, args);
}
}
public static void printIfInfoEnabled(Logger logger, String s, Object... args) {
if (logger.isInfoEnabled()) {
logger.info(s, args);
}
}
public static void printIfTraceEnabled(Logger logger, String s, Object... args) {
if (logger.isTraceEnabled()) {
logger.trace(s, args);
}
}
public static void printIfWarnEnabled(Logger logger, String s, Object... args) {
if (logger.isWarnEnabled()) {
logger.warn(s, args);
}
}
public static void printIfErrorEnabled(Logger logger, String s, Object... args) {
if (logger.isErrorEnabled()) {
logger.error(s, args);
}
}
public static final String TRACE = "TRACE";
public static final String INFO = "INFO";
public static final String DEBUG = "DEBUG";
public static final String WARN = "WARN";
public static final String ERROR = "ERROR";
/**
* Print if log debug level is enabled.
*
* @param logger logger
* @param s log message
* @param args arguments
*/
public static void printIfDebugEnabled(Logger logger, String s, Object... args) {
if (logger.isDebugEnabled()) {
logger.debug(s, args);
}
}
/**
* Print if log info level is enabled.
*
* @param logger logger
* @param s log message
* @param args arguments
*/
public static void printIfInfoEnabled(Logger logger, String s, Object... args) {
if (logger.isInfoEnabled()) {
logger.info(s, args);
}
}
/**
* Print if log trace level is enabled.
*
* @param logger logger
* @param s log message
* @param args arguments
*/
public static void printIfTraceEnabled(Logger logger, String s, Object... args) {
if (logger.isTraceEnabled()) {
logger.trace(s, args);
}
}
/**
* Print if log warn level is enabled.
*
* @param logger logger
* @param s log message
* @param args arguments
*/
public static void printIfWarnEnabled(Logger logger, String s, Object... args) {
if (logger.isWarnEnabled()) {
logger.warn(s, args);
}
}
/**
* Print if log error level is enabled.
*
* @param logger logger
* @param s log message
* @param args arguments
*/
public static void printIfErrorEnabled(Logger logger, String s, Object... args) {
if (logger.isErrorEnabled()) {
logger.error(s, args);
}
}
}

View File

@ -13,22 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* MD5 util
* MD5 util.
*
*@author nacos
* @author nacos
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class MD5Utils {
private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static ThreadLocal<MessageDigest> MESSAGE_DIGEST_LOCAL = new ThreadLocal<MessageDigest>() {
private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
'e', 'f'};
private static final ThreadLocal<MessageDigest> MESSAGE_DIGEST_LOCAL = new ThreadLocal<MessageDigest>() {
@Override
protected MessageDigest initialValue() {
try {
@ -38,7 +40,14 @@ public class MD5Utils {
}
}
};
/**
* Calculate MD5 hex string.
*
* @param bytes byte arrays
* @return MD5 hex string of input
* @throws NoSuchAlgorithmException if can't load md5 digest spi.
*/
public static String md5Hex(byte[] bytes) throws NoSuchAlgorithmException {
try {
MessageDigest messageDigest = MESSAGE_DIGEST_LOCAL.get();
@ -50,29 +59,36 @@ public class MD5Utils {
MESSAGE_DIGEST_LOCAL.remove();
}
}
public static String md5Hex(String value,String encode) {
/**
* Calculate MD5 hex string with encode charset.
*
* @param value value
* @param encode encode charset of input
* @return MD5 hex string of input
*/
public static String md5Hex(String value, String encode) {
try {
return md5Hex(value.getBytes(encode));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 将一个字节数组转化为可见的字符串
* 将一个字节数组转化为可见的字符串.
*/
public static String encodeHexString(byte[] bytes) {
public static String encodeHexString(byte[] bytes) {
int l = bytes.length;
char[] out = new char[l << 1];
for (int i = 0, j = 0; i < l; i++) {
out[j++] = DIGITS_LOWER[(0xF0 & bytes[i]) >>> 4];
out[j++] = DIGITS_LOWER[0x0F & bytes[i]];
}
return new String(out);
}
}

View File

@ -21,92 +21,107 @@ import java.util.Dictionary;
import java.util.Map;
/**
* Map utils.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public class MapUtils {
/**
* Null-safe check if the specified Dictionary is empty.
* <p>
* Null returns true.
*
* @param map the collection to check, may be null
* @return true if empty or null
*/
public static boolean isEmpty(Map map) {
return (map == null || map.isEmpty());
}
/**
* Null-safe check if the specified Dictionary is not empty.
* <p>
* Null returns false.
*
* @param map the collection to check, may be null
* @return true if non-null and non-empty
*/
public static boolean isNotEmpty(Map map) {
return !isEmpty(map);
}
/**
* Null-safe check if the specified Dictionary is empty.
* <p>
* Null returns true.
*
* @param coll the collection to check, may be null
* @return true if empty or null
*/
public static boolean isEmpty(Dictionary coll) {
return (coll == null || coll.isEmpty());
}
/**
* Null-safe check if the specified Dictionary is not empty.
* <p>
* Null returns false.
*
* @param coll the collection to check, may be null
* @return true if non-null and non-empty
*/
public static boolean isNotEmpty(Dictionary coll) {
return !isEmpty(coll);
}
public static void putIfValNoNull(Map target, Object key, Object value) {
Objects.requireNonNull(key, "key");
if (value != null) {
target.put(key, value);
}
}
public static void putIfValNoEmpty(Map target, Object key, Object value) {
Objects.requireNonNull(key, "key");
if (value instanceof String) {
if (StringUtils.isNotEmpty((String) value)) {
target.put(key, value);
}
return;
}
if (value instanceof Collection) {
if (CollectionUtils.isNotEmpty((Collection) value)) {
target.put(key, value);
}
return;
}
if (value instanceof Map) {
if (isNotEmpty((Map) value)) {
target.put(key, value);
}
return;
}
if (value instanceof Dictionary) {
if (isNotEmpty((Dictionary) value)) {
target.put(key, value);
}
return;
}
}
/**
* Null-safe check if the specified Dictionary is empty.
*
* <p>Null returns true.
*
* @param map the collection to check, may be null
* @return true if empty or null
*/
public static boolean isEmpty(Map map) {
return (map == null || map.isEmpty());
}
/**
* Null-safe check if the specified Dictionary is empty.
*
* <p>Null returns true.
*
* @param coll the collection to check, may be null
* @return true if empty or null
*/
public static boolean isEmpty(Dictionary coll) {
return (coll == null || coll.isEmpty());
}
/**
* Null-safe check if the specified Dictionary is not empty.
*
* <p>Null returns false.
*
* @param map the collection to check, may be null
* @return true if non-null and non-empty
*/
public static boolean isNotEmpty(Map map) {
return !isEmpty(map);
}
/**
* Null-safe check if the specified Dictionary is not empty.
*
* <p>Null returns false.
*
* @param coll the collection to check, may be null
* @return true if non-null and non-empty
*/
public static boolean isNotEmpty(Dictionary coll) {
return !isEmpty(coll);
}
/**
* Put into map if value is not null.
*
* @param target target map
* @param key key
* @param value value
*/
public static void putIfValNoNull(Map target, Object key, Object value) {
Objects.requireNonNull(key, "key");
if (value != null) {
target.put(key, value);
}
}
/**
* Put into map if value is not empty.
*
* @param target target map
* @param key key
* @param value value
*/
public static void putIfValNoEmpty(Map target, Object key, Object value) {
Objects.requireNonNull(key, "key");
if (value instanceof String) {
if (StringUtils.isNotEmpty((String) value)) {
target.put(key, value);
}
return;
}
if (value instanceof Collection) {
if (CollectionUtils.isNotEmpty((Collection) value)) {
target.put(key, value);
}
return;
}
if (value instanceof Map) {
if (isNotEmpty((Map) value)) {
target.put(key, value);
}
return;
}
if (value instanceof Dictionary) {
if (isNotEmpty((Dictionary) value)) {
target.put(key, value);
}
return;
}
}
}

View File

@ -21,220 +21,194 @@ import java.util.Comparator;
import java.util.List;
/**
* Objects utils.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
@SuppressWarnings("PMD.RemoveCommentedCodeRule")
public class Objects {
/**
* Returns {@code true} if the arguments are equal to each other
* and {@code false} otherwise.
* Consequently, if both arguments are {@code null}, {@code true}
* is returned and if exactly one argument is {@code null}, {@code
* false} is returned. Otherwise, equality is determined by using
* the {@link Object#equals equals} method of the first
* argument.
*
* @param a an object
* @param b an object to be compared with {@code a} for equality
* @return {@code true} if the arguments are equal to each other
* and {@code false} otherwise
* @see Object#equals(Object)
*/
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
/**
* Returns the hash code of a non-{@code null} argument and 0 for
* a {@code null} argument.
*
* @param o an object
* @return the hash code of a non-{@code null} argument and 0 for
* a {@code null} argument
* @see Object#hashCode
*/
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
/**
* Generates a hash code for a sequence of input values. The hash
* code is generated as if all the input values were placed into an
* array, and that array were hashed by calling {@link
* Arrays#hashCode(Object[])}.
*
* <p>This method is useful for implementing {@link
* Object#hashCode()} on objects containing multiple fields. For
* example, if an object that has three fields, {@code x}, {@code
* y}, and {@code z}, one could write:
*
* <blockquote><pre>
* &#064;Override public int hashCode() {
* return Objects.hash(x, y, z);
* }
* </pre></blockquote>
*
* <b>Warning: When a single object reference is supplied, the returned
* value does not equal the hash code of that object reference.</b> This
* value can be computed by calling {@link #hashCode(Object)}.
*
* @param values the values to be hashed
* @return a hash value of the sequence of input values
* @see Arrays#hashCode(Object[])
* @see List#hashCode
*/
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
/**
* Returns the result of calling {@code toString} for a non-{@code
* null} argument and {@code "null"} for a {@code null} argument.
*
* @param o an object
* @return the result of calling {@code toString} for a non-{@code
* null} argument and {@code "null"} for a {@code null} argument
* @see Object#toString
* @see String#valueOf(Object)
*/
public static String toString(Object o) {
return String.valueOf(o);
}
/**
* Returns the result of calling {@code toString} on the first
* argument if the first argument is not {@code null} and returns
* the second argument otherwise.
*
* @param o an object
* @param nullDefault string to return if the first argument is
* {@code null}
* @return the result of calling {@code toString} on the first
* argument if it is not {@code null} and the second argument
* otherwise.
*/
public static String toString(Object o, String nullDefault) {
return (o != null) ? o.toString() : nullDefault;
}
/**
* Returns 0 if the arguments are identical and {@code
* c.compare(a, b)} otherwise.
* Consequently, if both arguments are {@code null} 0
* is returned.
*
* <p>Note that if one of the arguments is {@code null}, a {@code
* NullPointerException} may or may not be thrown depending on
* what ordering policy, if any, the {@link Comparator Comparator}
* chooses to have for {@code null} values.
*
* @param <T> the type of the objects being compared
* @param a an object
* @param b an object to be compared with {@code a}
* @param c the {@code Comparator} to compare the first two arguments
* @return 0 if the arguments are identical and {@code
* c.compare(a, b)} otherwise.
* @see Comparable
* @see Comparator
*/
public static <T> int compare(T a, T b, Comparator<? super T> c) {
return (a == b) ? 0 : c.compare(a, b);
}
/**
* Checks that the specified object reference is not {@code null}. This
* method is designed primarily for doing parameter validation in methods
* and constructors, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar) {
* this.bar = Objects.requireNonNull(bar);
* }
* </pre></blockquote>
*
* @param obj the object reference to check for nullity
* @param <T> the type of the reference
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
/**
* Checks that the specified object reference is not {@code null} and
* throws a customized {@link NullPointerException} if it is. This method
* is designed primarily for doing parameter validation in methods and
* constructors with multiple parameters, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar, Baz baz) {
* this.bar = Objects.requireNonNull(bar, "bar must not be null");
* this.baz = Objects.requireNonNull(baz, "baz must not be null");
* }
* </pre></blockquote>
*
* @param obj the object reference to check for nullity
* @param message detail message to be used in the event that a {@code
* NullPointerException} is thrown
* @param <T> the type of the reference
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
/**
* Returns {@code true} if the provided reference is {@code null} otherwise
* returns {@code false}.
*
* @apiNote This method exists to be used as a
*
* @param obj a reference to be checked against {@code null}
* @return {@code true} if the provided reference is {@code null} otherwise
* {@code false}
*
* @since 1.8
*/
public static boolean isNull(Object obj) {
return obj == null;
}
/**
* Returns {@code true} if the provided reference is non-{@code null}
* otherwise returns {@code false}.
*
* @apiNote This method exists to be used as a
*
* @param obj a reference to be checked against {@code null}
* @return {@code true} if the provided reference is non-{@code null}
* otherwise {@code false}
*
* @since 1.8
*/
public static boolean nonNull(Object obj) {
return obj != null;
}
/**
* Returns the first argument if it is non-{@code null} and
* otherwise returns the non-{@code null} second argument.
*
* @param obj an object
* @param defaultObj a non-{@code null} object to return if the first argument
* is {@code null}
* @param <T> the type of the reference
* @return the first argument if it is non-{@code null} and
* otherwise the second argument if it is non-{@code null}
* @throws NullPointerException if both {@code obj} is null and
* {@code defaultObj} is {@code null}
* @since 9
*/
public static <T> T requireNonNullElse(T obj, T defaultObj) {
return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}
/**
* Returns {@code true} if the arguments are equal to each other and {@code false} otherwise. Consequently, if both
* arguments are {@code null}, {@code true} is returned and if exactly one argument is {@code null}, {@code false}
* is returned. Otherwise, equality is determined by using the {@link Object#equals equals} method of the first
* argument.
*
* @param a an object
* @param b an object to be compared with {@code a} for equality
* @return {@code true} if the arguments are equal to each other and {@code false} otherwise
* @see Object#equals(Object)
*/
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
/**
* Returns the hash code of a non-{@code null} argument and 0 for a {@code null} argument.
*
* @param o an object
* @return the hash code of a non-{@code null} argument and 0 for a {@code null} argument
* @see Object#hashCode
*/
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
/**
* Generates a hash code for a sequence of input values. The hash code is generated as if all the input values were
* placed into an array, and that array were hashed by calling {@link Arrays#hashCode(Object[])}.
*
* <p>This method is useful for implementing {@link
* Object#hashCode()} on objects containing multiple fields. For example, if an object that has three fields, {@code
* x}, {@code y}, and {@code z}, one could write:
*
* <blockquote><pre>
* &#064;Override
* public int hashCode() {
* return Objects.hash(x, y, z);
* }
* </pre></blockquote>
*
* <b>Warning: When a single object reference is supplied, the returned
* value does not equal the hash code of that object reference.</b> This value can be computed by calling {@link
* #hashCode(Object)}.
*
* @param values the values to be hashed
* @return a hash value of the sequence of input values
* @see Arrays#hashCode(Object[])
* @see List#hashCode
*/
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
/**
* Returns the result of calling {@code toString} for a non-{@code null} argument and {@code "null"} for a {@code
* null} argument.
*
* @param o an object
* @return the result of calling {@code toString} for a non-{@code null} argument and {@code "null"} for a {@code
* null} argument
* @see Object#toString
* @see String#valueOf(Object)
*/
public static String toString(Object o) {
return String.valueOf(o);
}
/**
* Returns the result of calling {@code toString} on the first argument if the first argument is not {@code null}
* and returns the second argument otherwise.
*
* @param o an object
* @param nullDefault string to return if the first argument is {@code null}
* @return the result of calling {@code toString} on the first argument if it is not {@code null} and the second
* argument otherwise.
*/
public static String toString(Object o, String nullDefault) {
return (o != null) ? o.toString() : nullDefault;
}
/**
* Returns 0 if the arguments are identical and {@code c.compare(a, b)} otherwise. Consequently, if both arguments
* are {@code null} 0 is returned.
*
* <p>Note that if one of the arguments is {@code null}, a {@code
* NullPointerException} may or may not be thrown depending on what ordering policy, if any, the {@link Comparator
* Comparator} chooses to have for {@code null} values.
*
* @param <T> the type of the objects being compared
* @param a an object
* @param b an object to be compared with {@code a}
* @param c the {@code Comparator} to compare the first two arguments
* @return 0 if the arguments are identical and {@code c.compare(a, b)} otherwise.
* @see Comparable
* @see Comparator
*/
public static <T> int compare(T a, T b, Comparator<? super T> c) {
return (a == b) ? 0 : c.compare(a, b);
}
/**
* Checks that the specified object reference is not {@code null}. This method is designed primarily for doing
* parameter validation in methods and constructors, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar) {
* this.bar = Objects.requireNonNull(bar);
* }
* </pre></blockquote>
*
* @param obj the object reference to check for nullity
* @param <T> the type of the reference
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
public static <T> T requireNonNull(T obj) {
if (obj == null) {
throw new NullPointerException();
}
return obj;
}
/**
* Checks that the specified object reference is not {@code null} and throws a customized {@link
* NullPointerException} if it is. This method is designed primarily for doing parameter validation in methods and
* constructors with multiple parameters, as demonstrated below:
* <blockquote><pre>
* public Foo(Bar bar, Baz baz) {
* this.bar = Objects.requireNonNull(bar, "bar must not be null");
* this.baz = Objects.requireNonNull(baz, "baz must not be null");
* }
* </pre></blockquote>
*
* @param obj the object reference to check for nullity
* @param message detail message to be used in the event that a {@code NullPointerException} is thrown
* @param <T> the type of the reference
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
*/
public static <T> T requireNonNull(T obj, String message) {
if (obj == null) {
throw new NullPointerException(message);
}
return obj;
}
/**
* Returns {@code true} if the provided reference is {@code null} otherwise returns {@code false}.
*
* @param obj a reference to be checked against {@code null}
* @return {@code true} if the provided reference is {@code null} otherwise {@code false}
* @apiNote This method exists to be used as a
* @since 1.8
*/
public static boolean isNull(Object obj) {
return obj == null;
}
/**
* Returns {@code true} if the provided reference is non-{@code null} otherwise returns {@code false}.
*
* @param obj a reference to be checked against {@code null}
* @return {@code true} if the provided reference is non-{@code null} otherwise {@code false}
* @apiNote This method exists to be used as a
* @since 1.8
*/
public static boolean nonNull(Object obj) {
return obj != null;
}
/**
* Returns the first argument if it is non-{@code null} and otherwise returns the non-{@code null} second argument.
*
* @param obj an object
* @param defaultObj a non-{@code null} object to return if the first argument is {@code null}
* @param <T> the type of the reference
* @return the first argument if it is non-{@code null} and otherwise the second argument if it is non-{@code null}
* @throws NullPointerException if both {@code obj} is null and {@code defaultObj} is {@code null}
* @since 9
*/
public static <T> T requireNonNullElse(T obj, T defaultObj) {
return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}
}

View File

@ -19,148 +19,142 @@ package com.alibaba.nacos.common.utils;
import java.util.Set;
/**
* Observable utils.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class Observable {
private transient boolean changed = false;
private transient Set<Observer> obs = new ConcurrentHashSet<Observer>();
private volatile int observerCnt = 0;
private boolean alreadyAddObserver = false;
/**
* Adds an observer to the set of observers for this object, provided
* that it is not the same as some observer already in the set.
* The order in which notifications will be delivered to multiple
* observers is not specified. See the class comment.
*
* @param o an observer to be added.
* @throws NullPointerException if the parameter o is null.
*/
public synchronized void addObserver(Observer o) {
Objects.requireNonNull(o, "Observer");
obs.add(o);
observerCnt ++;
if (!alreadyAddObserver) {
notifyAll();
}
alreadyAddObserver = true;
}
/**
* Deletes an observer from the set of observers of this object.
* Passing {@code null} to this method will have no effect.
* @param o the observer to be deleted.
*/
public synchronized void deleteObserver(Observer o) {
obs.remove(o);
observerCnt --;
}
/**
* If this object has changed, as indicated by the
* {@code hasChanged} method, then notify all of its observers
* and then call the {@code clearChanged} method to
* indicate that this object has no longer changed.
* <p>
* Each observer has its {@code update} method called with two
* arguments: this observable object and {@code null}. In other
* words, this method is equivalent to:
* <blockquote>{@code
* notifyObservers(null)}</blockquote>
*/
public void notifyObservers() {
notifyObservers(null);
}
/**
* If this object has changed, as indicated by the
* {@code hasChanged} method, then notify all of its observers
* and then call the {@code clearChanged} method to indicate
* that this object has no longer changed.
* <p>
* Each observer has its {@code update} method called with two
* arguments: this observable object and the {@code arg} argument.
*
* @param arg any object.
*/
public void notifyObservers(Object arg) {
synchronized (this) {
/* We don't want the Observer doing callbacks into
* arbitrary code while holding its own Monitor.
* The code where we extract each Observable from
* the Vector and store the state of the Observer
* needs synchronization, but notifying observers
* does not (should not). The worst result of any
* potential race-condition here is that:
* 1) a newly-added Observer will miss a
* notification in progress
* 2) a recently unregistered Observer will be
* wrongly notified when it doesn't care
*/
if (!changed) {
return;
}
clearChanged();
if (!alreadyAddObserver) {
ThreadUtils.objectWait(this);
}
}
for (Observer observer : obs) {
observer.update(this, arg);
}
}
/**
* Clears the observer list so that this object no longer has any observers.
*/
public void deleteObservers() {
obs.clear();
}
/**
* Marks this {@code Observable} object as having been changed; the
* {@code hasChanged} method will now return {@code true}.
*/
protected synchronized void setChanged() {
changed = true;
}
/**
* Indicates that this object has no longer changed, or that it has
* already notified all of its observers of its most recent change,
* so that the {@code hasChanged} method will now return {@code false}.
* This method is called automatically by the
* {@code notifyObservers} methods.
*
* @see java.util.Observable#notifyObservers()
* @see java.util.Observable#notifyObservers(java.lang.Object)
*/
protected synchronized void clearChanged() {
changed = false;
}
/**
* Tests if this object has changed.
*
* @return {@code true} if and only if the {@code setChanged}
* method has been called more recently than the
* {@code clearChanged} method on this object;
* {@code false} otherwise.
*/
public synchronized boolean hasChanged() {
return changed;
}
/**
* Returns the number of observers of this {@code Observable} object.
*
* @return the number of observers of this object.
*/
public int countObservers() {
return observerCnt;
}
}
private transient boolean changed = false;
private transient Set<Observer> obs = new ConcurrentHashSet<Observer>();
private volatile int observerCnt = 0;
private boolean alreadyAddObserver = false;
/**
* Adds an observer to the set of observers for this object, provided that it is not the same as some observer
* already in the set. The order in which notifications will be delivered to multiple observers is not specified.
* See the class comment.
*
* @param o an observer to be added.
* @throws NullPointerException if the parameter o is null.
*/
public synchronized void addObserver(Observer o) {
Objects.requireNonNull(o, "Observer");
obs.add(o);
observerCnt++;
if (!alreadyAddObserver) {
notifyAll();
}
alreadyAddObserver = true;
}
/**
* Deletes an observer from the set of observers of this object. Passing {@code null} to this method will have no
* effect.
*
* @param o the observer to be deleted.
*/
public synchronized void deleteObserver(Observer o) {
obs.remove(o);
observerCnt--;
}
/**
* If this object has changed, as indicated by the {@code hasChanged} method, then notify all of its observers and
* then call the {@code clearChanged} method to indicate that this object has no longer changed.
*
* <p>Each observer has its {@code update} method called with two arguments: this observable object and {@code
* null}. In other words, this method is equivalent to:
* <blockquote>{@code
* notifyObservers(null)}</blockquote>
*/
public void notifyObservers() {
notifyObservers(null);
}
/**
* If this object has changed, as indicated by the {@code hasChanged} method, then notify all of its observers and
* then call the {@code clearChanged} method to indicate that this object has no longer changed.
*
* <p>Each observer has its {@code update} method called with two arguments: this observable object and the {@code
* arg} argument.
*
* @param arg any object.
*/
public void notifyObservers(Object arg) {
synchronized (this) {
/* We don't want the Observer doing callbacks into
* arbitrary code while holding its own Monitor.
* The code where we extract each Observable from
* the Vector and store the state of the Observer
* needs synchronization, but notifying observers
* does not (should not). The worst result of any
* potential race-condition here is that:
* 1) a newly-added Observer will miss a
* notification in progress
* 2) a recently unregistered Observer will be
* wrongly notified when it doesn't care
*/
if (!changed) {
return;
}
clearChanged();
if (!alreadyAddObserver) {
ThreadUtils.objectWait(this);
}
}
for (Observer observer : obs) {
observer.update(this, arg);
}
}
/**
* Clears the observer list so that this object no longer has any observers.
*/
public void deleteObservers() {
obs.clear();
}
/**
* Marks this {@code Observable} object as having been changed; the {@code hasChanged} method will now return {@code
* true}.
*/
protected synchronized void setChanged() {
changed = true;
}
/**
* Indicates that this object has no longer changed, or that it has already notified all of its observers of its
* most recent change, so that the {@code hasChanged} method will now return {@code false}. This method is called
* automatically by the {@code notifyObservers} methods.
*
* @see java.util.Observable#notifyObservers()
* @see java.util.Observable#notifyObservers(java.lang.Object)
*/
protected synchronized void clearChanged() {
changed = false;
}
/**
* Tests if this object has changed.
*
* @return {@code true} if and only if the {@code setChanged} method has been called more recently than the {@code
* clearChanged} method on this object; {@code false} otherwise.
*/
public synchronized boolean hasChanged() {
return changed;
}
/**
* Returns the number of observers of this {@code Observable} object.
*
* @return the number of observers of this object.
*/
public int countObservers() {
return observerCnt;
}
}

View File

@ -17,20 +17,19 @@
package com.alibaba.nacos.common.utils;
/**
* Obeserver.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface Observer {
/**
* This method is called whenever the observed object is changed. An
* application calls an {@code Observable} object's
* {@code notifyObservers} method to have all the object's
* observers notified of the change.
*
* @param o the observable object.
* @param arg an argument passed to the {@code notifyObservers}
* method.
*/
void update(Observable o, Object arg);
/**
* This method is called whenever the observed object is changed. An application calls an {@code Observable}
* object's {@code notifyObservers} method to have all the object's observers notified of the change.
*
* @param o the observable object.
* @param arg an argument passed to the {@code notifyObservers} method.
*/
void update(Observable o, Object arg);
}

View File

@ -13,28 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
/**
* Pair.
*
* @author nacos
*/
public class Pair<A, B> {
private final A first;
private final B second;
Pair(A first, B second) {
this.first = first;
this.second = second;
}
public static <A, B> Pair<A, B> with(A first, B second) {
return new Pair<A, B>(first, second);
}
public A getFirst() {
return first;
}
public B getSecond() {
return second;
}

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.io.File;
@ -26,52 +27,51 @@ import java.net.URL;
import java.util.Properties;
/**
* resource util
* resource util.
*
* @author boyan
* @date 2010-5-4
*/
public class ResourceUtils {
private static final String CLASSPATH_PREFIX = "classpath:";
/**
* Returns the URL of the resource on the classpath
* Returns the URL of the resource on the classpath.
*
* @param resource The resource to find
* @return The resource
* @throws IOException If the resource cannot be found or read
*/
public static URL getResourceURL(String resource) throws IOException {
public static URL getResourceUrl(String resource) throws IOException {
if (resource.startsWith(CLASSPATH_PREFIX)) {
String path = resource.substring(CLASSPATH_PREFIX.length());
ClassLoader classLoader = ResourceUtils.class.getClassLoader();
URL url = (classLoader != null ? classLoader.getResource(path) : ClassLoader.getSystemResource(path));
if (url == null) {
throw new FileNotFoundException("Resource [" + resource + "] does not exist");
}
return url;
}
try {
return new URL(resource);
} catch (MalformedURLException ex) {
return new File(resource).toURI().toURL();
}
}
/**
* Returns the URL of the resource on the classpath
* Returns the URL of the resource on the classpath.
*
* @param loader The classloader used to load the resource
* @param resource The resource to find
* @return The resource
* @throws IOException If the resource cannot be found or read
*/
public static URL getResourceURL(ClassLoader loader, String resource) throws IOException {
public static URL getResourceUrl(ClassLoader loader, String resource) throws IOException {
URL url = null;
if (loader != null) {
url = loader.getResource(resource);
@ -84,9 +84,9 @@ public class ResourceUtils {
}
return url;
}
/**
* Returns a resource on the classpath as a Stream object
* Returns a resource on the classpath as a Stream object.
*
* @param resource The resource to find
* @return The resource
@ -96,9 +96,9 @@ public class ResourceUtils {
ClassLoader loader = ResourceUtils.class.getClassLoader();
return getResourceAsStream(loader, resource);
}
/**
* Returns a resource on the classpath as a Stream object
* Returns a resource on the classpath as a Stream object.
*
* @param loader The classloader used to load the resource
* @param resource The resource to find
@ -118,9 +118,9 @@ public class ResourceUtils {
}
return in;
}
/**
* Returns a resource on the classpath as a Properties object
* Returns a resource on the classpath as a Properties object.
*
* @param resource The resource to find
* @return The resource
@ -130,9 +130,9 @@ public class ResourceUtils {
ClassLoader loader = ResourceUtils.class.getClassLoader();
return getResourceAsProperties(loader, resource);
}
/**
* Returns a resource on the classpath as a Properties object
* Returns a resource on the classpath as a Properties object.
*
* @param loader The classloader used to load the resource
* @param resource The resource to find
@ -146,9 +146,9 @@ public class ResourceUtils {
in.close();
return props;
}
/**
* Returns a resource on the classpath as a Reader object
* Returns a resource on the classpath as a Reader object.
*
* @param resource The resource to find
* @return The resource
@ -157,9 +157,9 @@ public class ResourceUtils {
public static InputStreamReader getResourceAsReader(String resource, String charsetName) throws IOException {
return new InputStreamReader(getResourceAsStream(resource), charsetName);
}
/**
* Returns a resource on the classpath as a Reader object
* Returns a resource on the classpath as a Reader object.
*
* @param loader The classloader used to load the resource
* @param resource The resource to find
@ -167,23 +167,23 @@ public class ResourceUtils {
* @throws IOException If the resource cannot be found or read
*/
public static Reader getResourceAsReader(ClassLoader loader, String resource, String charsetName)
throws IOException {
throws IOException {
return new InputStreamReader(getResourceAsStream(loader, resource), charsetName);
}
/**
* Returns a resource on the classpath as a File object
* Returns a resource on the classpath as a File object.
*
* @param resource The resource to find
* @return The resource
* @throws IOException If the resource cannot be found or read
*/
public static File getResourceAsFile(String resource) throws IOException {
return new File(getResourceURL(resource).getFile());
return new File(getResourceUrl(resource).getFile());
}
/**
* Returns a resource on the classpath as a File object
* Returns a resource on the classpath as a File object.
*
* @param url The resource url to find
* @return The resource
@ -191,9 +191,9 @@ public class ResourceUtils {
public static File getResourceAsFile(URL url) {
return new File(url.getFile());
}
/**
* Returns a resource on the classpath as a File object
* Returns a resource on the classpath as a File object.
*
* @param loader The classloader used to load the resource
* @param resource The resource to find
@ -201,7 +201,7 @@ public class ResourceUtils {
* @throws IOException If the resource cannot be found or read
*/
public static File getResourceAsFile(ClassLoader loader, String resource) throws IOException {
return new File(getResourceURL(loader, resource).getFile());
return new File(getResourceUrl(loader, resource).getFile());
}
}

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import com.alibaba.nacos.api.common.Constants;
@ -25,24 +26,24 @@ import java.util.Collection;
import java.util.Locale;
/**
* string util
* string util.
*
* @author Nacos
*/
public class StringUtils {
public static final String DOT = ".";
private static final int INDEX_NOT_FOUND = -1;
public static final String COMMA = ",";
public static final String EMPTY = "";
public static String newString4UTF8(byte[] bytes) {
public static String newStringForUtf8(byte[] bytes) {
return new String(bytes, Charset.forName(Constants.ENCODE));
}
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
@ -55,7 +56,7 @@ public class StringUtils {
}
return true;
}
public static boolean isAllBlank(String... strs) {
for (String str : strs) {
if (isNotBlank(str)) {
@ -64,31 +65,31 @@ public class StringUtils {
}
return true;
}
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
public static boolean isNotEmpty(String str) {
return !StringUtils.isEmpty(str);
}
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
public static String defaultIfEmpty(String str, String defaultStr) {
return StringUtils.isEmpty(str) ? defaultStr : str;
}
public static boolean equals(String str1, String str2) {
return str1 == null ? str2 == null : str1.equals(str2);
}
public static String trim(final String str) {
return str == null ? null : str.trim();
}
public static String substringBetween(String str, String open, String close) {
if (str == null || open == null || close == null) {
return null;
@ -102,31 +103,30 @@ public class StringUtils {
}
return null;
}
public static String join(Collection collection, String separator) {
if (collection == null) {
return null;
}
StringBuilder stringBuilder = new StringBuilder();
Object[] objects = collection.toArray();
for (int i = 0; i < collection.size() - 1; i++) {
stringBuilder.append(objects[i].toString()).append(separator);
}
if (collection.size() > 0) {
stringBuilder.append(objects[collection.size() - 1]);
}
return stringBuilder.toString();
}
public static String escapeJavaScript(String str) {
return escapeJavaStyleString(str, true, true);
}
private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes, boolean escapeForwardSlash) {
if (str == null) {
return null;
@ -140,13 +140,9 @@ public class StringUtils {
return null;
}
}
private static String hex(char ch) {
return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
}
private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote,
boolean escapeForwardSlash) throws IOException {
boolean escapeForwardSlash) throws IOException {
if (out == null) {
throw new IllegalArgumentException("The Writer must not be null");
}
@ -157,7 +153,7 @@ public class StringUtils {
sz = str.length();
for (int i = 0; i < sz; i++) {
char ch = str.charAt(i);
// handle unicode
if (ch > 0xfff) {
out.write("\\u" + hex(ch));
@ -224,14 +220,17 @@ public class StringUtils {
}
}
}
private static String hex(char ch) {
return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
}
// The following utility functions are extracted from <link>org.apache.commons.lang3</link>
// start
/**
* <p>Checks if CharSequence contains a search CharSequence irrespective of case,
* handling {@code null}. Case-insensitivity is defined as by
* {@link String#equalsIgnoreCase(String)}.
* Checks if CharSequence contains a search CharSequence irrespective of case, handling {@code null}.
* Case-insensitivity is defined as by {@link String#equalsIgnoreCase(String)}.
*
* <p>A {@code null} CharSequence will return {@code false}.</p>
*
@ -246,11 +245,12 @@ public class StringUtils {
* StringUtils.contains("abc", "Z") = false
* </pre>
*
* @param str the CharSequence to check, may be null
* @param searchStr the CharSequence to find, may be null
* @return true if the CharSequence contains the search CharSequence irrespective of
* case or false if not or {@code null} string input
* @since 3.0 Changed signature from containsIgnoreCase(String, String) to containsIgnoreCase(CharSequence, CharSequence)
* @param str the CharSequence to check, may be null
* @param searchStr the CharSequence to find, may be null
* @return true if the CharSequence contains the search CharSequence irrespective of case or false if not or {@code
* null} string input
* @since 3.0 Changed signature from containsIgnoreCase(String, String) to containsIgnoreCase(CharSequence,
* CharSequence)
*/
public static boolean containsIgnoreCase(final CharSequence str, final CharSequence searchStr) {
if (str == null || searchStr == null) {
@ -265,49 +265,49 @@ public class StringUtils {
}
return false;
}
/**
* Green implementation of regionMatches.
*
* @param cs the {@code CharSequence} to be processed
* @param cs the {@code CharSequence} to be processed
* @param ignoreCase whether or not to be case insensitive
* @param thisStart the index to start on the {@code cs} CharSequence
* @param substring the {@code CharSequence} to be looked for
* @param start the index to start on the {@code substring} CharSequence
* @param length character length of the region
* @param thisStart the index to start on the {@code cs} CharSequence
* @param substring the {@code CharSequence} to be looked for
* @param start the index to start on the {@code substring} CharSequence
* @param length character length of the region
* @return whether the region matched
*/
static boolean regionMatches(final CharSequence cs, final boolean ignoreCase, final int thisStart,
final CharSequence substring, final int start, final int length) {
final CharSequence substring, final int start, final int length) {
if (cs instanceof String && substring instanceof String) {
return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length);
}
int index1 = thisStart;
int index2 = start;
int tmpLen = length;
while (tmpLen-- > 0) {
final char c1 = cs.charAt(index1++);
final char c2 = substring.charAt(index2++);
if (c1 == c2) {
continue;
}
if (!ignoreCase) {
return false;
}
// The same check as in String.regionMatches():
if (Character.toUpperCase(c1) != Character.toUpperCase(c2)
&& Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
if (Character.toUpperCase(c1) != Character.toUpperCase(c2) && Character.toLowerCase(c1) != Character
.toLowerCase(c2)) {
return false;
}
}
return true;
}
/**
* <p>Compares two CharSequences, returning {@code true} if they represent
* equal sequences of characters, ignoring case.</p>
@ -323,11 +323,11 @@ public class StringUtils {
* StringUtils.equalsIgnoreCase("abc", "ABC") = true
* </pre>
*
* @param str1 the first CharSequence, may be null
* @param str2 the second CharSequence, may be null
* @return {@code true} if the CharSequence are equal, case insensitive, or
* both {@code null}
* @since 3.0 Changed signature from equalsIgnoreCase(String, String) to equalsIgnoreCase(CharSequence, CharSequence)
* @param str1 the first CharSequence, may be null
* @param str2 the second CharSequence, may be null
* @return {@code true} if the CharSequence are equal, case insensitive, or both {@code null}
* @since 3.0 Changed signature from equalsIgnoreCase(String, String) to equalsIgnoreCase(CharSequence,
* CharSequence)
*/
public static boolean equalsIgnoreCase(final CharSequence str1, final CharSequence str2) {
if (str1 == null || str2 == null) {
@ -340,52 +340,52 @@ public class StringUtils {
return CharSequenceUtils.regionMatches(str1, true, 0, str2, 0, str1.length());
}
}
static class CharSequenceUtils {
/**
* Green implementation of regionMatches.
*
* @param cs the {@code CharSequence} to be processed
* @param cs the {@code CharSequence} to be processed
* @param ignoreCase whether or not to be case insensitive
* @param thisStart the index to start on the {@code cs} CharSequence
* @param substring the {@code CharSequence} to be looked for
* @param start the index to start on the {@code substring} CharSequence
* @param length character length of the region
* @param thisStart the index to start on the {@code cs} CharSequence
* @param substring the {@code CharSequence} to be looked for
* @param start the index to start on the {@code substring} CharSequence
* @param length character length of the region
* @return whether the region matched
*/
static boolean regionMatches(final CharSequence cs, final boolean ignoreCase, final int thisStart,
final CharSequence substring, final int start, final int length) {
final CharSequence substring, final int start, final int length) {
if (cs instanceof String && substring instanceof String) {
return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length);
}
int index1 = thisStart;
int index2 = start;
int tmpLen = length;
while (tmpLen-- > 0) {
final char c1 = cs.charAt(index1++);
final char c2 = substring.charAt(index2++);
if (c1 == c2) {
continue;
}
if (!ignoreCase) {
return false;
}
// The same check as in String.regionMatches():
if (Character.toUpperCase(c1) != Character.toUpperCase(c2)
&& Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
if (Character.toUpperCase(c1) != Character.toUpperCase(c2) && Character.toLowerCase(c1) != Character
.toLowerCase(c2)) {
return false;
}
}
return true;
}
}
// end
}

View File

@ -26,7 +26,7 @@ import java.util.concurrent.TimeUnit;
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class ThreadUtils {
public static void objectWait(Object object) {
try {
object.wait();
@ -34,7 +34,7 @@ public final class ThreadUtils {
Thread.interrupted();
}
}
public static void sleep(long millis) {
try {
Thread.sleep(millis);
@ -42,12 +42,12 @@ public final class ThreadUtils {
Thread.currentThread().interrupt();
}
}
public static void countDown(CountDownLatch latch) {
Objects.requireNonNull(latch, "latch");
latch.countDown();
}
public static void latchAwait(CountDownLatch latch) {
try {
latch.await();
@ -55,7 +55,7 @@ public final class ThreadUtils {
Thread.currentThread().interrupt();
}
}
public static void latchAwait(CountDownLatch latch, long time, TimeUnit unit) {
try {
latch.await(time, unit);
@ -63,10 +63,9 @@ public final class ThreadUtils {
Thread.currentThread().interrupt();
}
}
/**
* Through the number of cores, calculate the appropriate number of threads;
* 1.5-2 times the number of CPU cores
* Through the number of cores, calculate the appropriate number of threads; 1.5-2 times the number of CPU cores
*
* @return thread count
*/
@ -78,16 +77,16 @@ public final class ThreadUtils {
}
return workerCount;
}
public static void shutdownThreadPool(ExecutorService executor) {
shutdownThreadPool(executor, null);
}
public static void shutdownThreadPool(ExecutorService executor, Logger logger) {
executor.shutdown();
int retry = 3;
while (retry > 0) {
retry --;
retry--;
try {
if (executor.awaitTermination(10, TimeUnit.SECONDS)) {
return;
@ -103,11 +102,11 @@ public final class ThreadUtils {
}
executor.shutdownNow();
}
public static void addShutdownHook(Runnable runnable) {
Runtime.getRuntime().addShutdownHook(new Thread(runnable));
}
private final static int THREAD_MULTIPLER = 2;
private static final int THREAD_MULTIPLER = 2;
}

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.util.UUID;
@ -21,7 +22,7 @@ import java.util.UUID;
* @author nkorange
*/
public class UuidUtils {
public static String generateUuid() {
return UUID.randomUUID().toString();
}

View File

@ -13,34 +13,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.io.InputStream;
import java.util.Properties;
/**
* @author xingxuechao
* on:2019/2/27 12:32 PM
* Version utils.
*
* @author xingxuechao on:2019/2/27 12:32 PM
*/
public class VersionUtils {
public static String VERSION;
public static String version;
/**
* 获取当前version
* 获取当前version.
*/
public static final String VERSION_PLACEHOLDER = "${project.version}";
static {
InputStream in = null;
try {
in = VersionUtils.class.getClassLoader()
.getResourceAsStream("nacos-version.txt");
in = VersionUtils.class.getClassLoader().getResourceAsStream("nacos-version.txt");
Properties props = new Properties();
props.load(in);
String val = props.getProperty("version");
if (val != null && !VERSION_PLACEHOLDER.equals(val)) {
VERSION = val;
version = val;
}
} catch (Exception e) {
e.printStackTrace();

View File

@ -13,36 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase {
/**
* Create the test case
*
* @param testName name of the test case
*/
public class AppTest extends TestCase {
public AppTest(String testName) {
super(testName);
}
/**
* @return the suite of tests being tested
*/
public static Test suite() {
return new TestSuite(AppTest.class);
}
/**
* Rigourous Test :-)
*/
public void testApp() {
assertTrue(true);
}

View File

@ -13,36 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import com.alibaba.nacos.api.common.Constants;
import java.security.NoSuchAlgorithmException;
import org.junit.Assert;
import org.junit.Test;
public class MD5UtilsTest {
@Test
public void testMd5Hex() throws NoSuchAlgorithmException {
Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e",
MD5Utils.md5Hex("", Constants.ENCODE));
Assert.assertEquals("acbd18db4cc2f85cedef654fccc4a4d8",
MD5Utils.md5Hex("foo",Constants.ENCODE));
Assert.assertEquals("02f463eb799797e2a978fb1a2ae2991e",
MD5Utils.md5Hex("38c5ee9532f037a20b93d0f804cf111fca4003e451d09a692d9dea8032308d9c64eda9047fcd5e850284a49b1a0cfb2ecd45",Constants.ENCODE));
Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e",
MD5Utils.md5Hex(new byte[0]));
Assert.assertEquals("5289df737df57326fcdd22597afb1fac",
MD5Utils.md5Hex(new byte[]{1, 2, 3}));
Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e", MD5Utils.md5Hex("", Constants.ENCODE));
Assert.assertEquals("acbd18db4cc2f85cedef654fccc4a4d8", MD5Utils.md5Hex("foo", Constants.ENCODE));
Assert.assertEquals("02f463eb799797e2a978fb1a2ae2991e", MD5Utils.md5Hex(
"38c5ee9532f037a20b93d0f804cf111fca4003e451d09a692d9dea8032308d9c64eda9047fcd5e850284a49b1a0cfb2ecd45",
Constants.ENCODE));
Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e", MD5Utils.md5Hex(new byte[0]));
Assert.assertEquals("5289df737df57326fcdd22597afb1fac", MD5Utils.md5Hex(new byte[] {1, 2, 3}));
}
@Test
public void testEncodeHexString() {
Assert.assertEquals("", MD5Utils.encodeHexString(new byte[0]));
Assert.assertEquals("010203",
MD5Utils.encodeHexString(new byte[]{1, 2, 3}));
Assert.assertEquals("010203", MD5Utils.encodeHexString(new byte[] {1, 2, 3}));
}
}

View File

@ -24,43 +24,43 @@ import java.util.HashMap;
import java.util.Map;
public class MapUtilsTest {
@Test
public void test_map() {
Map<Object, Object> map = new HashMap<Object, Object>();
MapUtils.putIfValNoNull(map, "key-1", null);
Assert.assertFalse(map.containsKey("key-1"));
MapUtils.putIfValNoEmpty(map, "key-str", null);
Assert.assertFalse(map.containsKey("key-str"));
MapUtils.putIfValNoEmpty(map, "key-str", "");
Assert.assertFalse(map.containsKey("key-str"));
MapUtils.putIfValNoEmpty(map, "key-str", "1");
Assert.assertTrue(map.containsKey("key-str"));
MapUtils.putIfValNoEmpty(map, "key-list", null);
Assert.assertFalse(map.containsKey("key-list"));
MapUtils.putIfValNoEmpty(map, "key-list", Collections.emptyList());
Assert.assertFalse(map.containsKey("key-list"));
MapUtils.putIfValNoEmpty(map, "key-list", Collections.singletonList(1));
Assert.assertTrue(map.containsKey("key-list"));
MapUtils.putIfValNoEmpty(map, "key-map", null);
Assert.assertFalse(map.containsKey("key-map"));
MapUtils.putIfValNoEmpty(map, "key-map", Collections.emptyMap());
Assert.assertFalse(map.containsKey("key-map"));
Map<String, String> map1 = new HashMap<String, String>();
map1.put("1123", "123");
MapUtils.putIfValNoEmpty(map, "key-map", map1);
Assert.assertTrue(map.containsKey("key-map"));
}
@Test
public void testMap() {
Map<Object, Object> map = new HashMap<Object, Object>();
MapUtils.putIfValNoNull(map, "key-1", null);
Assert.assertFalse(map.containsKey("key-1"));
MapUtils.putIfValNoEmpty(map, "key-str", null);
Assert.assertFalse(map.containsKey("key-str"));
MapUtils.putIfValNoEmpty(map, "key-str", "");
Assert.assertFalse(map.containsKey("key-str"));
MapUtils.putIfValNoEmpty(map, "key-str", "1");
Assert.assertTrue(map.containsKey("key-str"));
MapUtils.putIfValNoEmpty(map, "key-list", null);
Assert.assertFalse(map.containsKey("key-list"));
MapUtils.putIfValNoEmpty(map, "key-list", Collections.emptyList());
Assert.assertFalse(map.containsKey("key-list"));
MapUtils.putIfValNoEmpty(map, "key-list", Collections.singletonList(1));
Assert.assertTrue(map.containsKey("key-list"));
MapUtils.putIfValNoEmpty(map, "key-map", null);
Assert.assertFalse(map.containsKey("key-map"));
MapUtils.putIfValNoEmpty(map, "key-map", Collections.emptyMap());
Assert.assertFalse(map.containsKey("key-map"));
Map<String, String> map1 = new HashMap<String, String>();
map1.put("1123", "123");
MapUtils.putIfValNoEmpty(map, "key-map", map1);
Assert.assertTrue(map.containsKey("key-map"));
}
}

View File

@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
*/
public final class ConfigExecutor {
private static final Executor DUMP_EXECUTOR = ExecutorFactory.newFixExecutorService(
private static final Executor DUMP_EXECUTOR = ExecutorFactory.newFixedExecutorService(
Config.class.getCanonicalName(),
1,
new NameThreadFactory("nacos.config.embedded.dump"));

View File

@ -40,7 +40,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
@SuppressWarnings("PMD.Rule:CollectionInitShouldAssignCapacityRule")
public final class ProtocolMetaData {
private static final Executor EXECUTOR = ExecutorFactory.Managed.newFixExecutorService(
private static final Executor EXECUTOR = ExecutorFactory.Managed.newFixedExecutorService(
ProtocolMetaData.class.getCanonicalName(),
4,
new NameThreadFactory("com.alibaba.nacos.consistency.protocol.metadata"));

View File

@ -41,7 +41,7 @@ public class ServerStateController {
ApplicationUtils.STANDALONE_MODE_ALONE : ApplicationUtils.STANDALONE_MODE_CLUSTER);
serverState.put("function_mode", ApplicationUtils.getFunctionMode());
serverState.put("version", VersionUtils.VERSION);
serverState.put("version", VersionUtils.version);
return ResponseEntity.ok().body(serverState);
}

View File

@ -45,7 +45,6 @@ import org.springframework.context.ApplicationListener;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.servlet.ServletContext;
import java.util.ArrayList;
@ -139,7 +138,7 @@ public class ServerMemberManager
this.port = ApplicationUtils.getProperty("server.port", Integer.class, 8848);
this.localAddress = InetUtils.getSelfIp() + ":" + port;
this.self = MemberUtils.singleParse(this.localAddress);
this.self.setExtendVal(MemberMetaDataConstants.VERSION, VersionUtils.VERSION);
this.self.setExtendVal(MemberMetaDataConstants.VERSION, VersionUtils.version);
serverList.put(self.getAddress(), self);
// register NodeChangeEvent publisher to NotifyManager
@ -414,12 +413,12 @@ public class ServerMemberManager
try {
asyncHttpClient.post(url, Header.newInstance().addParam(Constants.NACOS_SERVER_HEADER,
VersionUtils.VERSION), Query.EMPTY, getSelf(),
VersionUtils.version), Query.EMPTY, getSelf(),
reference.getType(), new Callback<String>() {
@Override
public void onReceive(RestResult<String> result) {
if (result.getCode() == HttpStatus.NOT_IMPLEMENTED.value() || result.getCode() == HttpStatus.NOT_FOUND.value()) {
Loggers.CLUSTER.warn("{} version is too low, it is recommended to upgrade the version : {}", target, VersionUtils.VERSION);
Loggers.CLUSTER.warn("{} version is too low, it is recommended to upgrade the version : {}", target, VersionUtils.version);
return;
}
if (result.ok()) {

View File

@ -51,11 +51,11 @@ public final class RaftExecutor {
"4"));
raftCoreExecutor = ExecutorFactory.Managed
.newFixExecutorService(OWNER, raftCoreThreadNum,
.newFixedExecutorService(OWNER, raftCoreThreadNum,
new NameThreadFactory("com.alibaba.naocs.core.raft-core"));
raftCliServiceExecutor = ExecutorFactory.Managed
.newFixExecutorService(OWNER, raftCliServiceThreadNum,
.newFixedExecutorService(OWNER, raftCliServiceThreadNum,
new NameThreadFactory("com.alibaba.naocs.core.raft-cli-service"));
raftCommonExecutor = ExecutorFactory.Managed
@ -66,7 +66,7 @@ public final class RaftExecutor {
snapshotNum = snapshotNum == 0 ? raftCoreThreadNum : snapshotNum;
raftSnapshotExecutor = ExecutorFactory.Managed.
newFixExecutorService(OWNER, snapshotNum,
newFixedExecutorService(OWNER, snapshotNum,
new NameThreadFactory("com.alibaba.naocs.core.raft-snapshot"));
}

View File

@ -617,7 +617,7 @@ public class HttpClient {
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding);
conn.addRequestProperty("Accept-Charset", encoding);
conn.addRequestProperty(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.VERSION);
conn.addRequestProperty(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version);
conn.addRequestProperty(HttpHeaderConsts.USER_AGENT_HEADER, UtilsAndCommons.SERVER_VERSION);
conn.addRequestProperty(HttpHeaderConsts.REQUEST_SOURCE_HEADER, ApplicationUtils.getLocalAddress());
}

View File

@ -58,7 +58,7 @@ public class NamingProxy {
try {
Map<String, String> headers = new HashMap<>(128);
headers.put(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.VERSION);
headers.put(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version);
headers.put(HttpHeaderConsts.USER_AGENT_HEADER, UtilsAndCommons.SERVER_VERSION);
headers.put("Connection", "Keep-Alive");
@ -147,7 +147,7 @@ public class NamingProxy {
public static boolean syncData(byte[] data, String curServer) {
Map<String, String> headers = new HashMap<>(128);
headers.put(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.VERSION);
headers.put(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version);
headers.put(HttpHeaderConsts.USER_AGENT_HEADER, UtilsAndCommons.SERVER_VERSION);
headers.put("Accept-Encoding", "gzip,deflate,sdch");
headers.put("Connection", "Keep-Alive");
@ -183,7 +183,7 @@ public class NamingProxy {
*/
public static String reqApi(String api, Map<String, String> params, String curServer) throws Exception {
try {
List<String> headers = Arrays.asList(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.VERSION,
List<String> headers = Arrays.asList(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version,
HttpHeaderConsts.USER_AGENT_HEADER, UtilsAndCommons.SERVER_VERSION, "Accept-Encoding",
"gzip,deflate,sdch", "Connection", "Keep-Alive", "Content-Encoding", "gzip");
@ -225,7 +225,7 @@ public class NamingProxy {
public static String reqApi(String api, Map<String, String> params, String curServer, boolean isPost)
throws Exception {
try {
List<String> headers = Arrays.asList(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.VERSION,
List<String> headers = Arrays.asList(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version,
HttpHeaderConsts.USER_AGENT_HEADER, UtilsAndCommons.SERVER_VERSION, "Accept-Encoding",
"gzip,deflate,sdch", "Connection", "Keep-Alive", "Content-Encoding", "gzip");

View File

@ -74,7 +74,7 @@ public class UtilsAndCommons {
public static final String NACOS_SERVER_HEADER = "Nacos-Server";
public static final String NACOS_VERSION = VersionUtils.VERSION;
public static final String NACOS_VERSION = VersionUtils.version;
public static final String SUPER_TOKEN = "xy";

View File

@ -106,7 +106,6 @@
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
</module>
<module name="JavadocParagraph"/>
<module name="JavadocTagContinuationIndentation"/>
<module name="NonEmptyAtclauseDescription"/>
<!-- Coding Checker -->
@ -134,7 +133,9 @@
<property name="allowByTailComment" value="true"/>
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<module name="Indentation"/>
<module name="Indentation">
<property name="arrayInitIndent" value="8"/>
</module>
<module name="CommentsIndentation">
<property name="tokens" value="SINGLE_LINE_COMMENT, BLOCK_COMMENT_BEGIN"/>
</module>

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 1999-2018 Alibaba Group Holding Ltd.
~
@ -14,7 +15,7 @@
~ limitations under the License.
-->
<code_scheme name="NacoStyle" version="1">
<code_scheme name="NacoStyle">
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="2"/>
@ -22,6 +23,8 @@
<option name="TAB_SIZE" value="2"/>
</value>
</option>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
<option name="LINE_SEPARATOR" value="&#xA;"/>
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true"/>
@ -34,10 +37,6 @@
<JSCodeStyleSettings version="0">
<option name="INDENT_CHAINED_CALLS" value="false"/>
</JSCodeStyleSettings>
<JavaCodeStyleSettings>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
</JavaCodeStyleSettings>
<Objective-C>
<option name="INDENT_NAMESPACE_MEMBERS" value="0"/>
<option name="INDENT_C_STRUCT_MEMBERS" value="2"/>