Merge branch 'upstream-develop' into feature_support_grpc_core
# Conflicts: # client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java # client/src/main/java/com/alibaba/nacos/client/config/http/HttpAgent.java # client/src/main/java/com/alibaba/nacos/client/config/http/MetricsHttpAgent.java # client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java # config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java
This commit is contained in:
commit
79c8521bde
@ -154,4 +154,10 @@ public class NacosException extends Exception {
|
|||||||
public static final int OVER_THRESHOLD = 503;
|
public static final int OVER_THRESHOLD = 503;
|
||||||
|
|
||||||
public static final int RESOURCE_NOT_FOUND = -404;
|
public static final int RESOURCE_NOT_FOUND = -404;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http client error code,
|
||||||
|
* ome exceptions that occurred when the use the Nacos RestTemplate and Nacos AsyncRestTemplate.
|
||||||
|
*/
|
||||||
|
public static final int HTTP_CLIENT_ERROR_CODE = -500;
|
||||||
}
|
}
|
||||||
|
@ -30,21 +30,20 @@ import com.alibaba.nacos.client.config.http.HttpAgent;
|
|||||||
import com.alibaba.nacos.client.config.http.MetricsHttpAgent;
|
import com.alibaba.nacos.client.config.http.MetricsHttpAgent;
|
||||||
import com.alibaba.nacos.client.config.http.ServerHttpAgent;
|
import com.alibaba.nacos.client.config.http.ServerHttpAgent;
|
||||||
import com.alibaba.nacos.client.config.impl.ClientWorker;
|
import com.alibaba.nacos.client.config.impl.ClientWorker;
|
||||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
|
||||||
import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
|
import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
|
||||||
import com.alibaba.nacos.client.config.utils.ContentUtils;
|
import com.alibaba.nacos.client.config.utils.ContentUtils;
|
||||||
import com.alibaba.nacos.client.config.utils.ParamUtils;
|
import com.alibaba.nacos.client.config.utils.ParamUtils;
|
||||||
import com.alibaba.nacos.client.utils.LogUtils;
|
import com.alibaba.nacos.client.utils.LogUtils;
|
||||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||||
import com.alibaba.nacos.client.utils.ValidatorUtils;
|
import com.alibaba.nacos.client.utils.ValidatorUtils;
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -181,42 +180,39 @@ public class NacosConfigService implements ConfigService {
|
|||||||
group = null2defaultGroup(group);
|
group = null2defaultGroup(group);
|
||||||
ParamUtils.checkKeyParam(dataId, group);
|
ParamUtils.checkKeyParam(dataId, group);
|
||||||
String url = Constants.CONFIG_CONTROLLER_PATH;
|
String url = Constants.CONFIG_CONTROLLER_PATH;
|
||||||
List<String> params = new ArrayList<String>();
|
Map<String, String> params = new HashMap<String, String>(4);
|
||||||
params.add("dataId");
|
params.put("dataId", dataId);
|
||||||
params.add(dataId);
|
params.put("group", group);
|
||||||
params.add("group");
|
|
||||||
params.add(group);
|
|
||||||
if (StringUtils.isNotEmpty(tenant)) {
|
if (StringUtils.isNotEmpty(tenant)) {
|
||||||
params.add("tenant");
|
params.put("tenant", tenant);
|
||||||
params.add(tenant);
|
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(tag)) {
|
if (StringUtils.isNotEmpty(tag)) {
|
||||||
params.add("tag");
|
params.put("tag", tag);
|
||||||
params.add(tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ParamUtils.useHttpSwitch()) {
|
if (!ParamUtils.useHttpSwitch()) {
|
||||||
return removeConfigInRpc(tenant, dataId, group, tag);
|
return removeConfigInRpc(tenant, dataId, group, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResult result = null;
|
HttpRestResult<String> result = null;
|
||||||
try {
|
try {
|
||||||
result = agent.httpDelete(url, null, params, encode, POST_TIMEOUT);
|
result = agent.httpDelete(url, null, params, encode, POST_TIMEOUT);
|
||||||
} catch (IOException ioe) {
|
} catch (Exception ex) {
|
||||||
LOGGER.warn("[remove] error, " + dataId + ", " + group + ", " + tenant + ", msg: " + ioe.toString());
|
LOGGER.warn("[remove] error, " + dataId + ", " + group + ", " + tenant + ", msg: " + ex.toString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HttpURLConnection.HTTP_OK == result.code) {
|
if (result.ok()) {
|
||||||
LOGGER.info("[{}] [remove] ok, dataId={}, group={}, tenant={}", agent.getName(), dataId, group, tenant);
|
LOGGER.info("[{}] [remove] ok, dataId={}, group={}, tenant={}", agent.getName(), dataId, group, tenant);
|
||||||
return true;
|
return true;
|
||||||
} else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) {
|
} else if (HttpURLConnection.HTTP_FORBIDDEN == result.getCode()) {
|
||||||
LOGGER.warn("[{}] [remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(), dataId,
|
LOGGER.warn("[{}] [remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(), dataId,
|
||||||
group, tenant, result.code, result.content);
|
group, tenant, result.getCode(), result.getMessage());
|
||||||
throw new NacosException(result.code, result.content);
|
throw new NacosException(result.getCode(), result.getMessage());
|
||||||
} else {
|
} else {
|
||||||
LOGGER.warn("[{}] [remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(), dataId,
|
LOGGER.warn("[{}] [remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(), dataId,
|
||||||
group, tenant, result.code, result.content);
|
group, tenant, result.getCode(), result.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,56 +244,48 @@ public class NacosConfigService implements ConfigService {
|
|||||||
content = cr.getContent();
|
content = cr.getContent();
|
||||||
|
|
||||||
String url = Constants.CONFIG_CONTROLLER_PATH;
|
String url = Constants.CONFIG_CONTROLLER_PATH;
|
||||||
List<String> params = new ArrayList<String>();
|
Map<String, String> params = new HashMap<String, String>(6);
|
||||||
params.add("dataId");
|
params.put("dataId", dataId);
|
||||||
params.add(dataId);
|
params.put("group", group);
|
||||||
params.add("group");
|
params.put("content", content);
|
||||||
params.add(group);
|
|
||||||
params.add("content");
|
|
||||||
params.add(content);
|
|
||||||
if (StringUtils.isNotEmpty(tenant)) {
|
if (StringUtils.isNotEmpty(tenant)) {
|
||||||
params.add("tenant");
|
params.put("tenant", tenant);
|
||||||
params.add(tenant);
|
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(appName)) {
|
if (StringUtils.isNotEmpty(appName)) {
|
||||||
params.add("appName");
|
params.put("appName", appName);
|
||||||
params.add(appName);
|
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(tag)) {
|
if (StringUtils.isNotEmpty(tag)) {
|
||||||
params.add("tag");
|
params.put("tag", tag);
|
||||||
params.add(tag);
|
|
||||||
}
|
}
|
||||||
|
Map<String, String> headers = new HashMap<String, String>(1);
|
||||||
List<String> headers = new ArrayList<String>();
|
|
||||||
if (StringUtils.isNotEmpty(betaIps)) {
|
if (StringUtils.isNotEmpty(betaIps)) {
|
||||||
headers.add("betaIps");
|
headers.put("betaIps", betaIps);
|
||||||
headers.add(betaIps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ParamUtils.useHttpSwitch()) {
|
if (!ParamUtils.useHttpSwitch()) {
|
||||||
return publishConfigWithRpc(dataId, group, tenant, content);
|
return publishConfigWithRpc(dataId, group, tenant, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResult result = null;
|
HttpRestResult<String> result = null;
|
||||||
try {
|
try {
|
||||||
result = agent.httpPost(url, headers, params, encode, POST_TIMEOUT);
|
result = agent.httpPost(url, headers, params, encode, POST_TIMEOUT);
|
||||||
} catch (IOException ioe) {
|
} catch (Exception ex) {
|
||||||
LOGGER.warn("[{}] [publish-single] exception, dataId={}, group={}, msg={}", agent.getName(), dataId, group,
|
LOGGER.warn("[{}] [publish-single] exception, dataId={}, group={}, msg={}", agent.getName(), dataId, group,
|
||||||
ioe.toString());
|
ex.toString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HttpURLConnection.HTTP_OK == result.code) {
|
if (result.ok()) {
|
||||||
LOGGER.info("[{}] [publish-single] ok, dataId={}, group={}, tenant={}, config={}", agent.getName(), dataId,
|
LOGGER.info("[{}] [publish-single] ok, dataId={}, group={}, tenant={}, config={}", agent.getName(), dataId,
|
||||||
group, tenant, ContentUtils.truncateContent(content));
|
group, tenant, ContentUtils.truncateContent(content));
|
||||||
return true;
|
return true;
|
||||||
} else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) {
|
} else if (HttpURLConnection.HTTP_FORBIDDEN == result.getCode()) {
|
||||||
LOGGER.warn("[{}] [publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(),
|
LOGGER.warn("[{}] [publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(),
|
||||||
dataId, group, tenant, result.code, result.content);
|
dataId, group, tenant, result.getCode(), result.getMessage());
|
||||||
throw new NacosException(result.code, result.content);
|
throw new NacosException(result.getCode(), result.getMessage());
|
||||||
} else {
|
} else {
|
||||||
LOGGER.warn("[{}] [publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(),
|
LOGGER.warn("[{}] [publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", agent.getName(),
|
||||||
dataId, group, tenant, result.code, result.content);
|
dataId, group, tenant, result.getCode(), result.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,12 +17,11 @@
|
|||||||
package com.alibaba.nacos.client.config.http;
|
package com.alibaba.nacos.client.config.http;
|
||||||
|
|
||||||
import com.alibaba.nacos.api.exception.NacosException;
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
import com.alibaba.nacos.client.config.impl.ServerListManager;
|
import com.alibaba.nacos.client.config.impl.ServerListManager;
|
||||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.util.Map;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HttpAgent.
|
* HttpAgent.
|
||||||
@ -54,11 +53,11 @@ public interface HttpAgent extends Closeable {
|
|||||||
* @param encoding http encode
|
* @param encoding http encode
|
||||||
* @param readTimeoutMs http timeout
|
* @param readTimeoutMs http timeout
|
||||||
* @return HttpResult http response
|
* @return HttpResult http response
|
||||||
* @throws IOException If an input or output exception occurred
|
* @throws Exception If an input or output exception occurred
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs)
|
HttpRestResult<String> httpGet(String path, Map<String, String> headers, Map<String, String> paramValues,
|
||||||
throws IOException;
|
String encoding, long readTimeoutMs) throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* invoke http post method.
|
* invoke http post method.
|
||||||
@ -69,10 +68,10 @@ public interface HttpAgent extends Closeable {
|
|||||||
* @param encoding http encode
|
* @param encoding http encode
|
||||||
* @param readTimeoutMs http timeout
|
* @param readTimeoutMs http timeout
|
||||||
* @return HttpResult http response
|
* @return HttpResult http response
|
||||||
* @throws IOException If an input or output exception occurred
|
* @throws Exception If an input or output exception occurred
|
||||||
*/
|
*/
|
||||||
HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
|
HttpRestResult<String> httpPost(String path, Map<String, String> headers, Map<String, String> paramValues,
|
||||||
long readTimeoutMs) throws IOException;
|
String encoding, long readTimeoutMs) throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* invoke http delete method.
|
* invoke http delete method.
|
||||||
@ -83,10 +82,10 @@ public interface HttpAgent extends Closeable {
|
|||||||
* @param encoding http encode
|
* @param encoding http encode
|
||||||
* @param readTimeoutMs http timeout
|
* @param readTimeoutMs http timeout
|
||||||
* @return HttpResult http response
|
* @return HttpResult http response
|
||||||
* @throws IOException If an input or output exception occurred
|
* @throws Exception If an input or output exception occurred
|
||||||
*/
|
*/
|
||||||
HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
|
HttpRestResult<String> httpDelete(String path, Map<String, String> headers, Map<String, String> paramValues,
|
||||||
long readTimeoutMs) throws IOException;
|
String encoding, long readTimeoutMs) throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get name.
|
* get name.
|
||||||
|
@ -17,13 +17,13 @@
|
|||||||
package com.alibaba.nacos.client.config.http;
|
package com.alibaba.nacos.client.config.http;
|
||||||
|
|
||||||
import com.alibaba.nacos.api.exception.NacosException;
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
|
||||||
import com.alibaba.nacos.client.config.impl.ServerListManager;
|
import com.alibaba.nacos.client.config.impl.ServerListManager;
|
||||||
import com.alibaba.nacos.client.monitor.MetricsMonitor;
|
import com.alibaba.nacos.client.monitor.MetricsMonitor;
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
import io.prometheus.client.Histogram;
|
import io.prometheus.client.Histogram;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MetricsHttpAgent.
|
* MetricsHttpAgent.
|
||||||
@ -49,12 +49,12 @@ public class MetricsHttpAgent implements HttpAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
|
public HttpRestResult<String> httpGet(String path, Map<String, String> headers, Map<String, String> paramValues,
|
||||||
long readTimeoutMs) throws IOException {
|
String encode, long readTimeoutMs) throws Exception {
|
||||||
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("GET", path, "NA");
|
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("GET", path, "NA");
|
||||||
HttpResult result;
|
HttpRestResult<String> result;
|
||||||
try {
|
try {
|
||||||
result = httpAgent.httpGet(path, headers, paramValues, encoding, readTimeoutMs);
|
result = httpAgent.httpGet(path, headers, paramValues, encode, readTimeoutMs);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
@ -66,12 +66,12 @@ public class MetricsHttpAgent implements HttpAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
|
public HttpRestResult<String> httpPost(String path, Map<String, String> headers, Map<String, String> paramValues,
|
||||||
long readTimeoutMs) throws IOException {
|
String encode, long readTimeoutMs) throws Exception {
|
||||||
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("POST", path, "NA");
|
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("POST", path, "NA");
|
||||||
HttpResult result;
|
HttpRestResult<String> result;
|
||||||
try {
|
try {
|
||||||
result = httpAgent.httpPost(path, headers, paramValues, encoding, readTimeoutMs);
|
result = httpAgent.httpPost(path, headers, paramValues, encode, readTimeoutMs);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
@ -83,12 +83,12 @@ public class MetricsHttpAgent implements HttpAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
|
public HttpRestResult<String> httpDelete(String path, Map<String, String> headers, Map<String, String> paramValues,
|
||||||
long readTimeoutMs) throws IOException {
|
String encode, long readTimeoutMs) throws Exception {
|
||||||
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("DELETE", path, "NA");
|
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("DELETE", path, "NA");
|
||||||
HttpResult result;
|
HttpRestResult<String> result;
|
||||||
try {
|
try {
|
||||||
result = httpAgent.httpDelete(path, headers, paramValues, encoding, readTimeoutMs);
|
result = httpAgent.httpDelete(path, headers, paramValues, encode, readTimeoutMs);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -19,8 +19,7 @@ package com.alibaba.nacos.client.config.http;
|
|||||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||||
import com.alibaba.nacos.api.common.Constants;
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
import com.alibaba.nacos.api.exception.NacosException;
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
|
import com.alibaba.nacos.client.config.impl.ConfigHttpClientManager;
|
||||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
|
||||||
import com.alibaba.nacos.client.config.impl.ServerListManager;
|
import com.alibaba.nacos.client.config.impl.ServerListManager;
|
||||||
import com.alibaba.nacos.client.config.impl.SpasAdapter;
|
import com.alibaba.nacos.client.config.impl.SpasAdapter;
|
||||||
import com.alibaba.nacos.client.identify.StsConfig;
|
import com.alibaba.nacos.client.identify.StsConfig;
|
||||||
@ -28,29 +27,36 @@ import com.alibaba.nacos.client.security.SecurityProxy;
|
|||||||
import com.alibaba.nacos.client.utils.LogUtils;
|
import com.alibaba.nacos.client.utils.LogUtils;
|
||||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||||
import com.alibaba.nacos.client.utils.TemplateUtils;
|
import com.alibaba.nacos.client.utils.TemplateUtils;
|
||||||
|
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||||
|
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
|
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||||
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
|
import com.alibaba.nacos.common.http.param.Query;
|
||||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||||
import com.alibaba.nacos.common.utils.IoUtils;
|
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
|
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||||
|
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||||
|
import com.alibaba.nacos.common.utils.VersionUtils;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server Agent.
|
* Server Agent.
|
||||||
@ -61,6 +67,9 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LogUtils.logger(ServerHttpAgent.class);
|
private static final Logger LOGGER = LogUtils.logger(ServerHttpAgent.class);
|
||||||
|
|
||||||
|
private static final NacosRestTemplate NACOS_RESTTEMPLATE = ConfigHttpClientManager.getInstance()
|
||||||
|
.getNacosRestTemplate();
|
||||||
|
|
||||||
private SecurityProxy securityProxy;
|
private SecurityProxy securityProxy;
|
||||||
|
|
||||||
private String namespaceId;
|
private String namespaceId;
|
||||||
@ -69,40 +78,28 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
|
|
||||||
private ScheduledExecutorService executorService;
|
private ScheduledExecutorService executorService;
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoke http get method.
|
|
||||||
*
|
|
||||||
* @param path 相对于web应用根,以/开头
|
|
||||||
* @param headers headers
|
|
||||||
* @param paramValues parameters
|
|
||||||
* @param encoding encoding
|
|
||||||
* @param readTimeoutMs time out milliseconds
|
|
||||||
* @return http result
|
|
||||||
* @throws IOException io exception
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
|
public HttpRestResult<String> httpGet(String path, Map<String, String> headers, Map<String, String> paramValues,
|
||||||
long readTimeoutMs) throws IOException {
|
String encode, long readTimeoutMs) throws Exception {
|
||||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||||
final boolean isSsl = false;
|
|
||||||
injectSecurityInfo(paramValues);
|
injectSecurityInfo(paramValues);
|
||||||
String currentServerAddr = serverListMgr.getCurrentServerAddr();
|
String currentServerAddr = serverListMgr.getCurrentServerAddr();
|
||||||
int maxRetry = this.maxRetry;
|
int maxRetry = this.maxRetry;
|
||||||
|
HttpClientConfig httpConfig = HttpClientConfig.builder()
|
||||||
|
.setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue())
|
||||||
|
.setConTimeOutMillis(ConfigHttpClientManager.getInstance().getConnectTimeoutOrDefault(100)).build();
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
List<String> newHeaders = getSpasHeaders(paramValues);
|
Header newHeaders = getSpasHeaders(paramValues, encode);
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
newHeaders.addAll(headers);
|
newHeaders.addAll(headers);
|
||||||
}
|
}
|
||||||
HttpResult result = HttpSimpleClient
|
|
||||||
.httpGet(getUrl(currentServerAddr, path), newHeaders, paramValues, encoding, readTimeoutMs,
|
HttpRestResult<String> result = NACOS_RESTTEMPLATE
|
||||||
isSsl);
|
.get(getUrl(currentServerAddr, path), httpConfig, newHeaders, paramValues, String.class);
|
||||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
if (isFail(result)) {
|
||||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
|
||||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
|
||||||
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
|
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
|
||||||
serverListMgr.getCurrentServerAddr(), result.code);
|
serverListMgr.getCurrentServerAddr(), result.getCode());
|
||||||
} else {
|
} else {
|
||||||
// Update the currently available server addr
|
// Update the currently available server addr
|
||||||
serverListMgr.updateCurrentServerAddr(currentServerAddr);
|
serverListMgr.updateCurrentServerAddr(currentServerAddr);
|
||||||
@ -114,10 +111,10 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
} catch (SocketTimeoutException socketTimeoutException) {
|
} catch (SocketTimeoutException socketTimeoutException) {
|
||||||
LOGGER.error("[NACOS SocketTimeoutException httpGet] currentServerAddr:{}, err : {}",
|
LOGGER.error("[NACOS SocketTimeoutException httpGet] currentServerAddr:{}, err : {}",
|
||||||
serverListMgr.getCurrentServerAddr(), socketTimeoutException.getMessage());
|
serverListMgr.getCurrentServerAddr(), socketTimeoutException.getMessage());
|
||||||
} catch (IOException ioException) {
|
} catch (Exception ex) {
|
||||||
LOGGER.error("[NACOS IOException httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(),
|
LOGGER.error("[NACOS Exception httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(),
|
||||||
ioException);
|
ex);
|
||||||
throw ioException;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverListMgr.getIterator().hasNext()) {
|
if (serverListMgr.getIterator().hasNext()) {
|
||||||
@ -138,30 +135,29 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
|
public HttpRestResult<String> httpPost(String path, Map<String, String> headers, Map<String, String> paramValues,
|
||||||
long readTimeoutMs) throws IOException {
|
String encode, long readTimeoutMs) throws Exception {
|
||||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||||
boolean isSsl = false;
|
|
||||||
injectSecurityInfo(paramValues);
|
injectSecurityInfo(paramValues);
|
||||||
String currentServerAddr = serverListMgr.getCurrentServerAddr();
|
String currentServerAddr = serverListMgr.getCurrentServerAddr();
|
||||||
int maxRetry = this.maxRetry;
|
int maxRetry = this.maxRetry;
|
||||||
|
HttpClientConfig httpConfig = HttpClientConfig.builder()
|
||||||
|
.setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue())
|
||||||
|
.setConTimeOutMillis(ConfigHttpClientManager.getInstance().getConnectTimeoutOrDefault(3000)).build();
|
||||||
do {
|
do {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<String> newHeaders = getSpasHeaders(paramValues);
|
Header newHeaders = getSpasHeaders(paramValues, encode);
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
newHeaders.addAll(headers);
|
newHeaders.addAll(headers);
|
||||||
}
|
}
|
||||||
|
HttpRestResult<String> result = NACOS_RESTTEMPLATE
|
||||||
|
.postForm(getUrl(currentServerAddr, path), httpConfig, newHeaders,
|
||||||
|
new HashMap<String, String>(0), paramValues, String.class);
|
||||||
|
|
||||||
HttpResult result = HttpSimpleClient
|
if (isFail(result)) {
|
||||||
.httpPost(getUrl(currentServerAddr, path), newHeaders, paramValues, encoding, readTimeoutMs,
|
|
||||||
isSsl);
|
|
||||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
|
||||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
|
||||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
|
||||||
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", currentServerAddr,
|
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", currentServerAddr,
|
||||||
result.code);
|
result.getCode());
|
||||||
} else {
|
} else {
|
||||||
// Update the currently available server addr
|
// Update the currently available server addr
|
||||||
serverListMgr.updateCurrentServerAddr(currentServerAddr);
|
serverListMgr.updateCurrentServerAddr(currentServerAddr);
|
||||||
@ -173,9 +169,9 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
} catch (SocketTimeoutException socketTimeoutException) {
|
} catch (SocketTimeoutException socketTimeoutException) {
|
||||||
LOGGER.error("[NACOS SocketTimeoutException httpPost] currentServerAddr: {}, err : {}",
|
LOGGER.error("[NACOS SocketTimeoutException httpPost] currentServerAddr: {}, err : {}",
|
||||||
currentServerAddr, socketTimeoutException.getMessage());
|
currentServerAddr, socketTimeoutException.getMessage());
|
||||||
} catch (IOException ioe) {
|
} catch (Exception ex) {
|
||||||
LOGGER.error("[NACOS IOException httpPost] currentServerAddr: " + currentServerAddr, ioe);
|
LOGGER.error("[NACOS Exception httpPost] currentServerAddr: " + currentServerAddr, ex);
|
||||||
throw ioe;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverListMgr.getIterator().hasNext()) {
|
if (serverListMgr.getIterator().hasNext()) {
|
||||||
@ -196,46 +192,42 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
|
public HttpRestResult<String> httpDelete(String path, Map<String, String> headers, Map<String, String> paramValues,
|
||||||
long readTimeoutMs) throws IOException {
|
String encode, long readTimeoutMs) throws Exception {
|
||||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||||
boolean isSsl = false;
|
|
||||||
injectSecurityInfo(paramValues);
|
injectSecurityInfo(paramValues);
|
||||||
String currentServerAddr = serverListMgr.getCurrentServerAddr();
|
String currentServerAddr = serverListMgr.getCurrentServerAddr();
|
||||||
int maxRetry = this.maxRetry;
|
int maxRetry = this.maxRetry;
|
||||||
|
HttpClientConfig httpConfig = HttpClientConfig.builder()
|
||||||
|
.setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue())
|
||||||
|
.setConTimeOutMillis(ConfigHttpClientManager.getInstance().getConnectTimeoutOrDefault(100)).build();
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
List<String> newHeaders = getSpasHeaders(paramValues);
|
Header newHeaders = getSpasHeaders(paramValues, encode);
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
newHeaders.addAll(headers);
|
newHeaders.addAll(headers);
|
||||||
}
|
}
|
||||||
HttpResult result = HttpSimpleClient
|
HttpRestResult<String> result = NACOS_RESTTEMPLATE
|
||||||
.httpDelete(getUrl(currentServerAddr, path), newHeaders, paramValues, encoding, readTimeoutMs,
|
.delete(getUrl(currentServerAddr, path), httpConfig, newHeaders, paramValues, String.class);
|
||||||
isSsl);
|
if (isFail(result)) {
|
||||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
|
||||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
|
||||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
|
||||||
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
|
LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}",
|
||||||
serverListMgr.getCurrentServerAddr(), result.code);
|
serverListMgr.getCurrentServerAddr(), result.getCode());
|
||||||
} else {
|
} else {
|
||||||
// Update the currently available server addr
|
// Update the currently available server addr
|
||||||
serverListMgr.updateCurrentServerAddr(currentServerAddr);
|
serverListMgr.updateCurrentServerAddr(currentServerAddr);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} catch (ConnectException connectException) {
|
} catch (ConnectException connectException) {
|
||||||
connectException.printStackTrace();
|
|
||||||
LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}, err : {}",
|
LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}, err : {}",
|
||||||
serverListMgr.getCurrentServerAddr(), connectException.getMessage());
|
serverListMgr.getCurrentServerAddr(), ExceptionUtil.getStackTrace(connectException));
|
||||||
} catch (SocketTimeoutException stoe) {
|
} catch (SocketTimeoutException stoe) {
|
||||||
stoe.printStackTrace();
|
|
||||||
LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{}, err : {}",
|
LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{}, err : {}",
|
||||||
serverListMgr.getCurrentServerAddr(), stoe.getMessage());
|
serverListMgr.getCurrentServerAddr(), ExceptionUtil.getStackTrace(stoe));
|
||||||
} catch (IOException ioe) {
|
} catch (Exception ex) {
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
"[NACOS IOException httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(),
|
"[NACOS Exception httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(),
|
||||||
ioe);
|
ex);
|
||||||
throw ioe;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverListMgr.getIterator().hasNext()) {
|
if (serverListMgr.getIterator().hasNext()) {
|
||||||
@ -261,6 +253,12 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
return serverAddr + contextPath + relativePath;
|
return serverAddr + contextPath + relativePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isFail(HttpRestResult<String> result) {
|
||||||
|
return result.getCode() == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||||
|
|| result.getCode() == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||||
|
|| result.getCode() == HttpURLConnection.HTTP_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
public static String getAppname() {
|
public static String getAppname() {
|
||||||
return ParamUtil.getAppName();
|
return ParamUtil.getAppName();
|
||||||
}
|
}
|
||||||
@ -276,7 +274,7 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
|
|
||||||
public ServerHttpAgent(Properties properties) throws NacosException {
|
public ServerHttpAgent(Properties properties) throws NacosException {
|
||||||
this.serverListMgr = new ServerListManager(properties);
|
this.serverListMgr = new ServerListManager(properties);
|
||||||
this.securityProxy = new SecurityProxy(properties);
|
this.securityProxy = new SecurityProxy(properties, NACOS_RESTTEMPLATE);
|
||||||
this.namespaceId = properties.getProperty(PropertyKeyConst.NAMESPACE);
|
this.namespaceId = properties.getProperty(PropertyKeyConst.NAMESPACE);
|
||||||
init(properties);
|
init(properties);
|
||||||
this.securityProxy.login(this.serverListMgr.getServerUrls());
|
this.securityProxy.login(this.serverListMgr.getServerUrls());
|
||||||
@ -301,14 +299,12 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectSecurityInfo(List<String> params) {
|
private void injectSecurityInfo(Map<String, String> params) {
|
||||||
if (StringUtils.isNotBlank(securityProxy.getAccessToken())) {
|
if (StringUtils.isNotBlank(securityProxy.getAccessToken())) {
|
||||||
params.add(Constants.ACCESS_TOKEN);
|
params.put(Constants.ACCESS_TOKEN, securityProxy.getAccessToken());
|
||||||
params.add(securityProxy.getAccessToken());
|
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(namespaceId) && !params.contains(SpasAdapter.TENANT_KEY)) {
|
if (StringUtils.isNotBlank(namespaceId) && !params.containsKey(SpasAdapter.TENANT_KEY)) {
|
||||||
params.add(SpasAdapter.TENANT_KEY);
|
params.put(SpasAdapter.TENANT_KEY, namespaceId);
|
||||||
params.add(namespaceId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,29 +359,37 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
serverListMgr.start();
|
serverListMgr.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getSpasHeaders(List<String> paramValues) throws IOException {
|
private Header getSpasHeaders(Map<String, String> paramValues, String encode) throws Exception {
|
||||||
List<String> newHeaders = new ArrayList<String>();
|
Header header = Header.newInstance();
|
||||||
// STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
|
// STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
|
||||||
if (StsConfig.getInstance().isStsOn()) {
|
if (StsConfig.getInstance().isStsOn()) {
|
||||||
StsCredential stsCredential = getStsCredential();
|
StsCredential stsCredential = getStsCredential();
|
||||||
accessKey = stsCredential.accessKeyId;
|
accessKey = stsCredential.accessKeyId;
|
||||||
secretKey = stsCredential.accessKeySecret;
|
secretKey = stsCredential.accessKeySecret;
|
||||||
newHeaders.add("Spas-SecurityToken");
|
header.addParam("Spas-SecurityToken", stsCredential.securityToken);
|
||||||
newHeaders.add(stsCredential.securityToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) {
|
if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) {
|
||||||
newHeaders.add("Spas-AccessKey");
|
header.addParam("Spas-AccessKey", accessKey);
|
||||||
newHeaders.add(accessKey);
|
Map<String, String> signHeaders = SpasAdapter.getSignHeaders(paramValues, secretKey);
|
||||||
List<String> signHeaders = SpasAdapter.getSignHeaders(paramValues, secretKey);
|
|
||||||
if (signHeaders != null) {
|
if (signHeaders != null) {
|
||||||
newHeaders.addAll(signHeaders);
|
header.addAll(signHeaders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newHeaders;
|
String ts = String.valueOf(System.currentTimeMillis());
|
||||||
|
String token = MD5Utils.md5Hex(ts + ParamUtil.getAppKey(), Constants.ENCODE);
|
||||||
|
|
||||||
|
header.addParam(Constants.CLIENT_APPNAME_HEADER, ParamUtil.getAppName());
|
||||||
|
header.addParam(Constants.CLIENT_REQUEST_TS_HEADER, ts);
|
||||||
|
header.addParam(Constants.CLIENT_REQUEST_TOKEN_HEADER, token);
|
||||||
|
header.addParam(HttpHeaderConsts.CLIENT_VERSION_HEADER, VersionUtils.version);
|
||||||
|
header.addParam("exConfigInfo", "true");
|
||||||
|
header.addParam(HttpHeaderConsts.REQUEST_ID, UuidUtils.generateUuid());
|
||||||
|
header.addParam(HttpHeaderConsts.ACCEPT_CHARSET, encode);
|
||||||
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StsCredential getStsCredential() throws IOException {
|
private StsCredential getStsCredential() throws Exception {
|
||||||
boolean cacheSecurityCredentials = StsConfig.getInstance().isCacheSecurityCredentials();
|
boolean cacheSecurityCredentials = StsConfig.getInstance().isCacheSecurityCredentials();
|
||||||
if (cacheSecurityCredentials && stsCredential != null) {
|
if (cacheSecurityCredentials && stsCredential != null) {
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
@ -405,40 +409,29 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
return stsCredential;
|
return stsCredential;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getStsResponse() throws IOException {
|
private static String getStsResponse() throws Exception {
|
||||||
String securityCredentials = StsConfig.getInstance().getSecurityCredentials();
|
String securityCredentials = StsConfig.getInstance().getSecurityCredentials();
|
||||||
if (securityCredentials != null) {
|
if (securityCredentials != null) {
|
||||||
return securityCredentials;
|
return securityCredentials;
|
||||||
}
|
}
|
||||||
String securityCredentialsUrl = StsConfig.getInstance().getSecurityCredentialsUrl();
|
String securityCredentialsUrl = StsConfig.getInstance().getSecurityCredentialsUrl();
|
||||||
HttpURLConnection conn = null;
|
|
||||||
int respCode;
|
|
||||||
String response;
|
|
||||||
try {
|
try {
|
||||||
conn = (HttpURLConnection) new URL(securityCredentialsUrl).openConnection();
|
HttpRestResult<String> result = NACOS_RESTTEMPLATE
|
||||||
conn.setRequestMethod("GET");
|
.get(securityCredentialsUrl, Header.EMPTY, Query.EMPTY, String.class);
|
||||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
|
|
||||||
conn.setReadTimeout(1000);
|
if (!result.ok()) {
|
||||||
conn.connect();
|
LOGGER.error(
|
||||||
respCode = conn.getResponseCode();
|
"can not get security credentials, securityCredentialsUrl: {}, responseCode: {}, response: {}",
|
||||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
securityCredentialsUrl, result.getCode(), result.getMessage());
|
||||||
response = IoUtils.toString(conn.getInputStream(), Constants.ENCODE);
|
throw new NacosException(NacosException.SERVER_ERROR,
|
||||||
} else {
|
"can not get security credentials, responseCode: " + result.getCode() + ", response: " + result
|
||||||
response = IoUtils.toString(conn.getErrorStream(), Constants.ENCODE);
|
.getMessage());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
return result.getData();
|
||||||
|
} catch (Exception e) {
|
||||||
LOGGER.error("can not get security credentials", e);
|
LOGGER.error("can not get security credentials", e);
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
|
||||||
IoUtils.closeQuietly(conn);
|
|
||||||
}
|
}
|
||||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
LOGGER.error("can not get security credentials, securityCredentialsUrl: {}, responseCode: {}, response: {}",
|
|
||||||
securityCredentialsUrl, respCode, response);
|
|
||||||
throw new IOException(
|
|
||||||
"can not get security credentials, responseCode: " + respCode + ", response: " + response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -466,6 +459,7 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
String className = this.getClass().getName();
|
String className = this.getClass().getName();
|
||||||
LOGGER.info("{} do shutdown begin", className);
|
LOGGER.info("{} do shutdown begin", className);
|
||||||
ThreadUtils.shutdownThreadPool(executorService, LOGGER);
|
ThreadUtils.shutdownThreadPool(executorService, LOGGER);
|
||||||
|
ConfigHttpClientManager.getInstance().shutdown();
|
||||||
LOGGER.info("{} do shutdown stop", className);
|
LOGGER.info("{} do shutdown stop", className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ import com.alibaba.nacos.api.PropertyKeyConst;
|
|||||||
import com.alibaba.nacos.api.common.Constants;
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
import com.alibaba.nacos.api.config.ConfigType;
|
import com.alibaba.nacos.api.config.ConfigType;
|
||||||
import com.alibaba.nacos.api.config.listener.Listener;
|
import com.alibaba.nacos.api.config.listener.Listener;
|
||||||
import com.alibaba.nacos.api.config.remote.request.ConfigChangeListenRequest;
|
|
||||||
import com.alibaba.nacos.api.config.remote.response.ConfigChangeNotifyResponse;
|
import com.alibaba.nacos.api.config.remote.response.ConfigChangeNotifyResponse;
|
||||||
import com.alibaba.nacos.api.config.remote.response.ConfigQueryResponse;
|
import com.alibaba.nacos.api.config.remote.response.ConfigQueryResponse;
|
||||||
import com.alibaba.nacos.api.exception.NacosException;
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
@ -28,7 +27,6 @@ import com.alibaba.nacos.api.remote.response.Response;
|
|||||||
import com.alibaba.nacos.client.config.common.GroupKey;
|
import com.alibaba.nacos.client.config.common.GroupKey;
|
||||||
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
|
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
|
||||||
import com.alibaba.nacos.client.config.http.HttpAgent;
|
import com.alibaba.nacos.client.config.http.HttpAgent;
|
||||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
|
||||||
import com.alibaba.nacos.client.config.remote.ConfigGrpcClientProxy;
|
import com.alibaba.nacos.client.config.remote.ConfigGrpcClientProxy;
|
||||||
import com.alibaba.nacos.client.config.utils.ContentUtils;
|
import com.alibaba.nacos.client.config.utils.ContentUtils;
|
||||||
import com.alibaba.nacos.client.config.utils.ParamUtils;
|
import com.alibaba.nacos.client.config.utils.ParamUtils;
|
||||||
@ -40,6 +38,7 @@ import com.alibaba.nacos.client.remote.ServerListFactory;
|
|||||||
import com.alibaba.nacos.client.utils.LogUtils;
|
import com.alibaba.nacos.client.utils.LogUtils;
|
||||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||||
import com.alibaba.nacos.client.utils.TenantUtil;
|
import com.alibaba.nacos.client.utils.TenantUtil;
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||||
@ -52,7 +51,6 @@ import java.io.IOException;
|
|||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -330,29 +328,32 @@ public class ClientWorker implements Closeable {
|
|||||||
return getServerConfigInRpc(dataId, group, tenant, readTimeout);
|
return getServerConfigInRpc(dataId, group, tenant, readTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResult result = null;
|
HttpRestResult<String> result = null;
|
||||||
try {
|
try {
|
||||||
List<String> params = null;
|
Map<String, String> params = new HashMap<String, String>(3);
|
||||||
if (StringUtils.isBlank(tenant)) {
|
if (StringUtils.isBlank(tenant)) {
|
||||||
params = new ArrayList<String>(Arrays.asList("dataId", dataId, "group", group));
|
params.put("dataId", dataId);
|
||||||
|
params.put("group", group);
|
||||||
} else {
|
} else {
|
||||||
params = new ArrayList<String>(Arrays.asList("dataId", dataId, "group", group, "tenant", tenant));
|
params.put("dataId", dataId);
|
||||||
|
params.put("group", group);
|
||||||
|
params.put("tenant", tenant);
|
||||||
}
|
}
|
||||||
result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
|
result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
|
||||||
} catch (IOException e) {
|
} catch (Exception ex) {
|
||||||
String message = String
|
String message = String
|
||||||
.format("[%s] [sub-server] get server config exception, dataId=%s, group=%s, tenant=%s",
|
.format("[%s] [sub-server] get server config exception, dataId=%s, group=%s, tenant=%s",
|
||||||
agent.getName(), dataId, group, tenant);
|
agent.getName(), dataId, group, tenant);
|
||||||
LOGGER.error(message, e);
|
LOGGER.error(message, ex);
|
||||||
throw new NacosException(NacosException.SERVER_ERROR, e);
|
throw new NacosException(NacosException.SERVER_ERROR, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (result.code) {
|
switch (result.getCode()) {
|
||||||
case HttpURLConnection.HTTP_OK:
|
case HttpURLConnection.HTTP_OK:
|
||||||
LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content);
|
LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.getData());
|
||||||
ct[0] = result.content;
|
ct[0] = result.getData();
|
||||||
if (result.headers.containsKey(CONFIG_TYPE)) {
|
if (result.getHeader().getValue(CONFIG_TYPE) != null) {
|
||||||
ct[1] = result.headers.get(CONFIG_TYPE).get(0);
|
ct[1] = result.getHeader().getValue(CONFIG_TYPE);
|
||||||
} else {
|
} else {
|
||||||
ct[1] = ConfigType.TEXT.getType();
|
ct[1] = ConfigType.TEXT.getType();
|
||||||
}
|
}
|
||||||
@ -370,13 +371,13 @@ public class ClientWorker implements Closeable {
|
|||||||
case HttpURLConnection.HTTP_FORBIDDEN: {
|
case HttpURLConnection.HTTP_FORBIDDEN: {
|
||||||
LOGGER.error("[{}] [sub-server-error] no right, dataId={}, group={}, tenant={}", agent.getName(),
|
LOGGER.error("[{}] [sub-server-error] no right, dataId={}, group={}, tenant={}", agent.getName(),
|
||||||
dataId, group, tenant);
|
dataId, group, tenant);
|
||||||
throw new NacosException(result.code, result.content);
|
throw new NacosException(result.getCode(), result.getMessage());
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
LOGGER.error("[{}] [sub-server-error] dataId={}, group={}, tenant={}, code={}", agent.getName(),
|
LOGGER.error("[{}] [sub-server-error] dataId={}, group={}, tenant={}, code={}", agent.getName(),
|
||||||
dataId, group, tenant, result.code);
|
dataId, group, tenant, result.getCode());
|
||||||
throw new NacosException(result.code,
|
throw new NacosException(result.getCode(),
|
||||||
"http error, code=" + result.code + ",dataId=" + dataId + ",group=" + group + ",tenant="
|
"http error, code=" + result.getCode() + ",dataId=" + dataId + ",group=" + group + ",tenant="
|
||||||
+ tenant);
|
+ tenant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -481,10 +482,9 @@ public class ClientWorker implements Closeable {
|
|||||||
* @param cacheDatas CacheDatas for config infomations.
|
* @param cacheDatas CacheDatas for config infomations.
|
||||||
* @param inInitializingCacheList initial cache lists.
|
* @param inInitializingCacheList initial cache lists.
|
||||||
* @return String include dataId and group (ps: it maybe null).
|
* @return String include dataId and group (ps: it maybe null).
|
||||||
* @throws IOException Exception.
|
* @throws Exception Exception.
|
||||||
*/
|
*/
|
||||||
List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> inInitializingCacheList)
|
List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> inInitializingCacheList) throws Exception {
|
||||||
throws IOException {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (CacheData cacheData : cacheDatas) {
|
for (CacheData cacheData : cacheDatas) {
|
||||||
if (!cacheData.isUseLocalConfigInfo()) {
|
if (!cacheData.isUseLocalConfigInfo()) {
|
||||||
@ -515,20 +515,16 @@ public class ClientWorker implements Closeable {
|
|||||||
* @return The updated dataId list(ps: it maybe null).
|
* @return The updated dataId list(ps: it maybe null).
|
||||||
* @throws IOException Exception.
|
* @throws IOException Exception.
|
||||||
*/
|
*/
|
||||||
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException {
|
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws Exception {
|
||||||
|
|
||||||
List<String> params = new ArrayList<String>(2);
|
Map<String, String> params = new HashMap<String, String>(2);
|
||||||
params.add(Constants.PROBE_MODIFY_REQUEST);
|
params.put(Constants.PROBE_MODIFY_REQUEST, probeUpdateString);
|
||||||
params.add(probeUpdateString);
|
Map<String, String> headers = new HashMap<String, String>(2);
|
||||||
|
headers.put("Long-Pulling-Timeout", "" + timeout);
|
||||||
List<String> headers = new ArrayList<String>(2);
|
|
||||||
headers.add("Long-Pulling-Timeout");
|
|
||||||
headers.add("" + timeout);
|
|
||||||
|
|
||||||
// told server do not hang me up if new initializing cacheData added in
|
// told server do not hang me up if new initializing cacheData added in
|
||||||
if (isInitializingCacheList) {
|
if (isInitializingCacheList) {
|
||||||
headers.add("Long-Pulling-Timeout-No-Hangup");
|
headers.put("Long-Pulling-Timeout-No-Hangup", "true");
|
||||||
headers.add("true");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isBlank(probeUpdateString)) {
|
if (StringUtils.isBlank(probeUpdateString)) {
|
||||||
@ -540,18 +536,19 @@ public class ClientWorker implements Closeable {
|
|||||||
// increase the client's read timeout to avoid this problem.
|
// increase the client's read timeout to avoid this problem.
|
||||||
|
|
||||||
long readTimeoutMs = timeout + (long) Math.round(timeout >> 1);
|
long readTimeoutMs = timeout + (long) Math.round(timeout >> 1);
|
||||||
HttpResult result = agent
|
HttpRestResult<String> result = agent
|
||||||
.httpPost(Constants.CONFIG_CONTROLLER_PATH + "/listener", headers, params, agent.getEncode(),
|
.httpPost(Constants.CONFIG_CONTROLLER_PATH + "/listener", headers, params, agent.getEncode(),
|
||||||
readTimeoutMs);
|
readTimeoutMs);
|
||||||
|
|
||||||
if (HttpURLConnection.HTTP_OK == result.code) {
|
if (result.ok()) {
|
||||||
setHealthServer(true);
|
setHealthServer(true);
|
||||||
return parseUpdateDataIdResponse(result.content);
|
return parseUpdateDataIdResponse(result.getData());
|
||||||
} else {
|
} else {
|
||||||
setHealthServer(false);
|
setHealthServer(false);
|
||||||
LOGGER.error("[{}] [check-update] get changed dataId error, code: {}", agent.getName(), result.code);
|
LOGGER.error("[{}] [check-update] get changed dataId error, code: {}", agent.getName(),
|
||||||
|
result.getCode());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
setHealthServer(false);
|
setHealthServer(false);
|
||||||
LOGGER.error("[" + agent.getName() + "] [check-update] get changed dataId exception", e);
|
LOGGER.error("[" + agent.getName() + "] [check-update] get changed dataId exception", e);
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.client.config.impl;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
|
import com.alibaba.nacos.client.utils.LogUtils;
|
||||||
|
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||||
|
import com.alibaba.nacos.common.http.AbstractHttpClientFactory;
|
||||||
|
import com.alibaba.nacos.common.http.HttpClientBeanHolder;
|
||||||
|
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||||
|
import com.alibaba.nacos.common.http.HttpClientFactory;
|
||||||
|
import com.alibaba.nacos.common.http.client.HttpClientRequestInterceptor;
|
||||||
|
import com.alibaba.nacos.common.http.client.HttpClientResponse;
|
||||||
|
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||||
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
|
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||||
|
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||||
|
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||||
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
|
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* config http Manager.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public class ConfigHttpClientManager implements Closeable {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogUtils.logger(ConfigHttpClientManager.class);
|
||||||
|
|
||||||
|
private static final HttpClientFactory HTTP_CLIENT_FACTORY = new ConfigHttpClientFactory();
|
||||||
|
|
||||||
|
private static final int CON_TIME_OUT_MILLIS = ParamUtil.getConnectTimeout();
|
||||||
|
|
||||||
|
private static final int READ_TIME_OUT_MILLIS = 3000;
|
||||||
|
|
||||||
|
private static final NacosRestTemplate NACOS_REST_TEMPLATE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
NACOS_REST_TEMPLATE = HttpClientBeanHolder.getNacosRestTemplate(HTTP_CLIENT_FACTORY);
|
||||||
|
NACOS_REST_TEMPLATE.getInterceptors().add(new LimiterHttpClientRequestInterceptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ConfigHttpClientManagerInstance {
|
||||||
|
|
||||||
|
private static final ConfigHttpClientManager INSTANCE = new ConfigHttpClientManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConfigHttpClientManager getInstance() {
|
||||||
|
return ConfigHttpClientManagerInstance.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() throws NacosException {
|
||||||
|
NAMING_LOGGER.warn("[ConfigHttpClientManager] Start destroying NacosRestTemplate");
|
||||||
|
try {
|
||||||
|
HttpClientBeanHolder.shutdownNacostSyncRest(HTTP_CLIENT_FACTORY.getClass().getName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
NAMING_LOGGER.error("[ConfigHttpClientManager] An exception occurred when the HTTP client was closed : {}",
|
||||||
|
ExceptionUtil.getStackTrace(ex));
|
||||||
|
}
|
||||||
|
NAMING_LOGGER.warn("[ConfigHttpClientManager] Destruction of the end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get connectTimeout.
|
||||||
|
*
|
||||||
|
* @param connectTimeout connectTimeout
|
||||||
|
* @return int return max timeout
|
||||||
|
*/
|
||||||
|
public int getConnectTimeoutOrDefault(int connectTimeout) {
|
||||||
|
return Math.max(CON_TIME_OUT_MILLIS, connectTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get NacosRestTemplate Instance.
|
||||||
|
*
|
||||||
|
* @return NacosRestTemplate
|
||||||
|
*/
|
||||||
|
public NacosRestTemplate getNacosRestTemplate() {
|
||||||
|
return NACOS_REST_TEMPLATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfigHttpClientFactory.
|
||||||
|
*/
|
||||||
|
private static class ConfigHttpClientFactory extends AbstractHttpClientFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HttpClientConfig buildHttpClientConfig() {
|
||||||
|
return HttpClientConfig.builder().setConTimeOutMillis(CON_TIME_OUT_MILLIS)
|
||||||
|
.setReadTimeOutMillis(READ_TIME_OUT_MILLIS).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Logger assignLogger() {
|
||||||
|
return LOGGER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* config Limiter implement.
|
||||||
|
*/
|
||||||
|
private static class LimiterHttpClientRequestInterceptor implements HttpClientRequestInterceptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIntercept(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) {
|
||||||
|
final String body = requestHttpEntity.getBody() == null ? "" : JacksonUtils.toJson(requestHttpEntity.getBody());
|
||||||
|
return Limiter.isLimit(MD5Utils.md5Hex(uri + body, Constants.ENCODE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpClientResponse intercept() {
|
||||||
|
return new LimitResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit Interrupt response.
|
||||||
|
*/
|
||||||
|
private static class LimitResponse implements HttpClientResponse {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Header getHeaders() {
|
||||||
|
return Header.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getBody() throws IOException {
|
||||||
|
return new ByteArrayInputStream("More than client-side current limit threshold".getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStatusCode() {
|
||||||
|
return NacosException.CLIENT_OVER_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStatusText() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.alibaba.nacos.client.config.impl;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.client.utils.LogUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event subscription and publishing tools.
|
|
||||||
*
|
|
||||||
* @author Nacos
|
|
||||||
*/
|
|
||||||
public class EventDispatcher {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LogUtils.logger(EventDispatcher.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加事件监听器.
|
|
||||||
*/
|
|
||||||
public static void addEventListener(AbstractEventListener listener) {
|
|
||||||
for (Class<? extends AbstractEvent> type : listener.interest()) {
|
|
||||||
getListenerList(type).addIfAbsent(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发布事件,首先发布该事件暗示的其他事件,最后通知所有对应的监听器.
|
|
||||||
*/
|
|
||||||
public static void fireEvent(AbstractEvent abstractEvent) {
|
|
||||||
if (null == abstractEvent) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发布该事件暗示的其他事件
|
|
||||||
for (AbstractEvent implyEvent : abstractEvent.implyEvents()) {
|
|
||||||
try {
|
|
||||||
// 避免死循环
|
|
||||||
if (abstractEvent != implyEvent) {
|
|
||||||
fireEvent(implyEvent);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.warn(e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (AbstractEventListener listener : getListenerList(abstractEvent.getClass())) {
|
|
||||||
try {
|
|
||||||
listener.onEvent(abstractEvent);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.warn(e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static synchronized CopyOnWriteArrayList<AbstractEventListener> getListenerList(
|
|
||||||
Class<? extends AbstractEvent> eventType) {
|
|
||||||
CopyOnWriteArrayList<AbstractEventListener> listeners = LISTENER_MAP.get(eventType);
|
|
||||||
if (null == listeners) {
|
|
||||||
listeners = new CopyOnWriteArrayList<AbstractEventListener>();
|
|
||||||
LISTENER_MAP.put(eventType, listeners);
|
|
||||||
}
|
|
||||||
return listeners;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("checkstyle:linelength")
|
|
||||||
static final Map<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>> LISTENER_MAP = new HashMap<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Client事件.
|
|
||||||
*/
|
|
||||||
public abstract static class AbstractEvent {
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected List<AbstractEvent> implyEvents() {
|
|
||||||
return Collections.EMPTY_LIST;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 事件监听器.
|
|
||||||
*/
|
|
||||||
public abstract static class AbstractEventListener {
|
|
||||||
|
|
||||||
public AbstractEventListener() {
|
|
||||||
EventDispatcher.addEventListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 感兴趣的事件列表.
|
|
||||||
*
|
|
||||||
* @return event list
|
|
||||||
*/
|
|
||||||
public abstract List<Class<? extends AbstractEvent>> interest();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理事件.
|
|
||||||
*
|
|
||||||
* @param abstractEvent event to do
|
|
||||||
*/
|
|
||||||
public abstract void onEvent(AbstractEvent abstractEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* serverList has changed.
|
|
||||||
*/
|
|
||||||
public static class ServerlistChangeEvent extends AbstractEvent {
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,6 +20,7 @@ import com.alibaba.nacos.api.common.Constants;
|
|||||||
import com.alibaba.nacos.api.exception.NacosException;
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||||
|
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||||
import com.alibaba.nacos.common.utils.IoUtils;
|
import com.alibaba.nacos.common.utils.IoUtils;
|
||||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||||
@ -39,7 +40,9 @@ import java.util.Map;
|
|||||||
* Http tool.
|
* Http tool.
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
|
* @deprecated Use NacosRestTemplate{@link NacosRestTemplate} unified http client
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class HttpSimpleClient {
|
public class HttpSimpleClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,21 +19,22 @@ package com.alibaba.nacos.client.config.impl;
|
|||||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||||
import com.alibaba.nacos.api.SystemPropertyKeyConst;
|
import com.alibaba.nacos.api.SystemPropertyKeyConst;
|
||||||
import com.alibaba.nacos.api.exception.NacosException;
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
import com.alibaba.nacos.client.config.impl.EventDispatcher.ServerlistChangeEvent;
|
|
||||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
|
||||||
import com.alibaba.nacos.client.utils.EnvUtil;
|
import com.alibaba.nacos.client.utils.EnvUtil;
|
||||||
import com.alibaba.nacos.client.utils.LogUtils;
|
import com.alibaba.nacos.client.utils.LogUtils;
|
||||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||||
import com.alibaba.nacos.client.utils.TemplateUtils;
|
import com.alibaba.nacos.client.utils.TemplateUtils;
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
|
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||||
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
|
import com.alibaba.nacos.common.http.param.Query;
|
||||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.common.utils.IoUtils;
|
import com.alibaba.nacos.common.utils.IoUtils;
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -59,6 +60,8 @@ public class ServerListManager implements Closeable {
|
|||||||
|
|
||||||
private static final String HTTP = "http://";
|
private static final String HTTP = "http://";
|
||||||
|
|
||||||
|
private final NacosRestTemplate nacosRestTemplate = ConfigHttpClientManager.getInstance().getNacosRestTemplate();
|
||||||
|
|
||||||
private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||||
@Override
|
@Override
|
||||||
public Thread newThread(Runnable r) {
|
public Thread newThread(Runnable r) {
|
||||||
@ -335,19 +338,20 @@ public class ServerListManager implements Closeable {
|
|||||||
iterator = iterator();
|
iterator = iterator();
|
||||||
currentServerAddr = iterator.next();
|
currentServerAddr = iterator.next();
|
||||||
|
|
||||||
EventDispatcher.fireEvent(new ServerlistChangeEvent());
|
// Using unified event processor, NotifyCenter
|
||||||
|
NotifyCenter.publishEvent(new ServerlistChangeEvent());
|
||||||
LOGGER.info("[{}] [update-serverlist] serverlist updated to {}", name, serverUrls);
|
LOGGER.info("[{}] [update-serverlist] serverlist updated to {}", name, serverUrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getApacheServerList(String url, String name) {
|
private List<String> getApacheServerList(String url, String name) {
|
||||||
try {
|
try {
|
||||||
HttpResult httpResult = HttpSimpleClient.httpGet(url, null, null, null, 3000);
|
HttpRestResult<String> httpResult = nacosRestTemplate.get(url, Header.EMPTY, Query.EMPTY, String.class);
|
||||||
|
|
||||||
if (HttpURLConnection.HTTP_OK == httpResult.code) {
|
if (httpResult.ok()) {
|
||||||
if (DEFAULT_NAME.equals(name)) {
|
if (DEFAULT_NAME.equals(name)) {
|
||||||
EnvUtil.setSelfEnv(httpResult.headers);
|
EnvUtil.setSelfEnv(httpResult.getHeader().getOriginalResponseHeader());
|
||||||
}
|
}
|
||||||
List<String> lines = IoUtils.readLines(new StringReader(httpResult.content));
|
List<String> lines = IoUtils.readLines(new StringReader(httpResult.getData()));
|
||||||
List<String> result = new ArrayList<String>(lines.size());
|
List<String> result = new ArrayList<String>(lines.size());
|
||||||
for (String serverAddr : lines) {
|
for (String serverAddr : lines) {
|
||||||
if (StringUtils.isNotBlank(serverAddr)) {
|
if (StringUtils.isNotBlank(serverAddr)) {
|
||||||
@ -363,10 +367,10 @@ public class ServerListManager implements Closeable {
|
|||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("[check-serverlist] error. addressServerUrl: {}, code: {}", addressServerUrl,
|
LOGGER.error("[check-serverlist] error. addressServerUrl: {}, code: {}", addressServerUrl,
|
||||||
httpResult.code);
|
httpResult.getCode());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("[check-serverlist] exception. url: " + url, e);
|
LOGGER.error("[check-serverlist] exception. url: " + url, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.alibaba.nacos.core.notify;
|
package com.alibaba.nacos.client.config.impl;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.SlowEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this event share one event-queue.
|
* Server List Change Event.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author zongtanghu
|
||||||
*/
|
*/
|
||||||
public interface SlowEvent extends Event {
|
public class ServerlistChangeEvent extends SlowEvent {
|
||||||
|
|
||||||
}
|
}
|
@ -24,11 +24,7 @@ import com.alibaba.nacos.common.utils.StringUtils;
|
|||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,44 +33,34 @@ import java.util.Map;
|
|||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
public class SpasAdapter {
|
public class SpasAdapter {
|
||||||
|
|
||||||
public static List<String> getSignHeaders(String resource, String secretKey) {
|
public static Map<String, String> getSignHeaders(String resource, String secretKey) {
|
||||||
List<String> header = new ArrayList<String>();
|
Map<String, String> header = new HashMap<String, String>(2);
|
||||||
String timeStamp = String.valueOf(System.currentTimeMillis());
|
String timeStamp = String.valueOf(System.currentTimeMillis());
|
||||||
header.add("Timestamp");
|
header.put("Timestamp", timeStamp);
|
||||||
header.add(timeStamp);
|
|
||||||
if (secretKey != null) {
|
if (secretKey != null) {
|
||||||
header.add("Spas-Signature");
|
|
||||||
String signature = "";
|
String signature = "";
|
||||||
if (StringUtils.isBlank(resource)) {
|
if (StringUtils.isBlank(resource)) {
|
||||||
signature = signWithHmacSha1Encrypt(timeStamp, secretKey);
|
signature = signWithHmacSha1Encrypt(timeStamp, secretKey);
|
||||||
} else {
|
} else {
|
||||||
signature = signWithHmacSha1Encrypt(resource + "+" + timeStamp, secretKey);
|
signature = signWithHmacSha1Encrypt(resource + "+" + timeStamp, secretKey);
|
||||||
}
|
}
|
||||||
header.add(signature);
|
header.put("Spas-Signature", signature);
|
||||||
}
|
}
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getSignHeaders(List<String> paramValues, String secretKey) {
|
public static Map<String, String> getSignHeaders(Map<String, String> paramValues, String secretKey) {
|
||||||
if (null == paramValues) {
|
if (null == paramValues) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Map<String, String> signMap = new HashMap<String, String>(5);
|
|
||||||
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext(); ) {
|
|
||||||
String key = iter.next();
|
|
||||||
if (TENANT_KEY.equals(key) || GROUP_KEY.equals(key)) {
|
|
||||||
signMap.put(key, iter.next());
|
|
||||||
} else {
|
|
||||||
iter.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String resource = "";
|
String resource = "";
|
||||||
if (signMap.size() > 1) {
|
if (paramValues.containsKey(TENANT_KEY) && paramValues.containsKey(GROUP_KEY)) {
|
||||||
resource = signMap.get(TENANT_KEY) + "+" + signMap.get(GROUP_KEY);
|
resource = paramValues.get(TENANT_KEY) + "+" + paramValues.get(GROUP_KEY);
|
||||||
} else {
|
} else {
|
||||||
if (!StringUtils.isBlank(signMap.get(GROUP_KEY))) {
|
if (!StringUtils.isBlank(paramValues.get(GROUP_KEY))) {
|
||||||
resource = signMap.get(GROUP_KEY);
|
resource = paramValues.get(GROUP_KEY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getSignHeaders(resource, secretKey);
|
return getSignHeaders(resource, secretKey);
|
||||||
@ -97,14 +83,14 @@ public class SpasAdapter {
|
|||||||
*/
|
*/
|
||||||
public static String signWithHmacSha1Encrypt(String encryptText, String encryptKey) {
|
public static String signWithHmacSha1Encrypt(String encryptText, String encryptKey) {
|
||||||
try {
|
try {
|
||||||
byte[] data = encryptKey.getBytes(StandardCharsets.UTF_8);
|
byte[] data = encryptKey.getBytes(Constants.ENCODE);
|
||||||
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
|
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
|
||||||
SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
|
SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
|
||||||
// 生成一个指定 Mac 算法 的 Mac 对象
|
// 生成一个指定 Mac 算法 的 Mac 对象
|
||||||
Mac mac = Mac.getInstance("HmacSHA1");
|
Mac mac = Mac.getInstance("HmacSHA1");
|
||||||
// 用给定密钥初始化 Mac 对象
|
// 用给定密钥初始化 Mac 对象
|
||||||
mac.init(secretKey);
|
mac.init(secretKey);
|
||||||
byte[] text = encryptText.getBytes(StandardCharsets.UTF_8);
|
byte[] text = encryptText.getBytes(Constants.ENCODE);
|
||||||
byte[] textFinal = mac.doFinal(text);
|
byte[] textFinal = mac.doFinal(text);
|
||||||
// 完成 Mac 操作, base64编码,将byte数组转换为字符串
|
// 完成 Mac 操作, base64编码,将byte数组转换为字符串
|
||||||
return new String(Base64.encodeBase64(textFinal), Constants.ENCODE);
|
return new String(Base64.encodeBase64(textFinal), Constants.ENCODE);
|
||||||
|
@ -165,7 +165,7 @@ public class BeatReactor implements Closeable {
|
|||||||
long nextTime = beatInfo.getPeriod();
|
long nextTime = beatInfo.getPeriod();
|
||||||
try {
|
try {
|
||||||
JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
|
JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
|
||||||
long interval = result.get("clientBeatInterval").asInt();
|
long interval = result.get("clientBeatInterval").asLong();
|
||||||
boolean lightBeatEnabled = false;
|
boolean lightBeatEnabled = false;
|
||||||
if (result.has(CommonParams.LIGHT_BEAT_ENABLED)) {
|
if (result.has(CommonParams.LIGHT_BEAT_ENABLED)) {
|
||||||
lightBeatEnabled = result.get(CommonParams.LIGHT_BEAT_ENABLED).asBoolean();
|
lightBeatEnabled = result.get(CommonParams.LIGHT_BEAT_ENABLED).asBoolean();
|
||||||
|
@ -16,18 +16,24 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.client.naming.net;
|
package com.alibaba.nacos.client.naming.net;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
import com.alibaba.nacos.common.http.AbstractHttpClientFactory;
|
import com.alibaba.nacos.common.http.AbstractHttpClientFactory;
|
||||||
import com.alibaba.nacos.common.http.HttpClientBeanHolder;
|
import com.alibaba.nacos.common.http.HttpClientBeanHolder;
|
||||||
import com.alibaba.nacos.common.http.HttpClientConfig;
|
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||||
import com.alibaba.nacos.common.http.HttpClientFactory;
|
import com.alibaba.nacos.common.http.HttpClientFactory;
|
||||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||||
|
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||||
|
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* http Manager.
|
* http Manager.
|
||||||
*
|
*
|
||||||
* @author mai.jh
|
* @author mai.jh
|
||||||
*/
|
*/
|
||||||
public class NamingHttpClientManager {
|
public class NamingHttpClientManager implements Closeable {
|
||||||
|
|
||||||
private static final int READ_TIME_OUT_MILLIS = Integer
|
private static final int READ_TIME_OUT_MILLIS = Integer
|
||||||
.getInteger("com.alibaba.nacos.client.naming.rtimeout", 50000);
|
.getInteger("com.alibaba.nacos.client.naming.rtimeout", 50000);
|
||||||
@ -40,17 +46,38 @@ public class NamingHttpClientManager {
|
|||||||
|
|
||||||
private static final HttpClientFactory HTTP_CLIENT_FACTORY = new NamingHttpClientFactory();
|
private static final HttpClientFactory HTTP_CLIENT_FACTORY = new NamingHttpClientFactory();
|
||||||
|
|
||||||
public static String getPrefix() {
|
private static class NamingHttpClientManagerInstance {
|
||||||
|
|
||||||
|
private static final NamingHttpClientManager INSTANCE = new NamingHttpClientManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NamingHttpClientManager getInstance() {
|
||||||
|
return NamingHttpClientManagerInstance.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix() {
|
||||||
if (ENABLE_HTTPS) {
|
if (ENABLE_HTTPS) {
|
||||||
return "https://";
|
return "https://";
|
||||||
}
|
}
|
||||||
return "http://";
|
return "http://";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NacosRestTemplate getNacosRestTemplate() {
|
public NacosRestTemplate getNacosRestTemplate() {
|
||||||
return HttpClientBeanHolder.getNacosRestTemplate(HTTP_CLIENT_FACTORY);
|
return HttpClientBeanHolder.getNacosRestTemplate(HTTP_CLIENT_FACTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() throws NacosException {
|
||||||
|
NAMING_LOGGER.warn("[NamingHttpClientManager] Start destroying NacosRestTemplate");
|
||||||
|
try {
|
||||||
|
HttpClientBeanHolder.shutdownNacostSyncRest(HTTP_CLIENT_FACTORY.getClass().getName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
NAMING_LOGGER.error("[NamingHttpClientManager] An exception occurred when the HTTP client was closed : {}",
|
||||||
|
ExceptionUtil.getStackTrace(ex));
|
||||||
|
}
|
||||||
|
NAMING_LOGGER.warn("[NamingHttpClientManager] Destruction of the end");
|
||||||
|
}
|
||||||
|
|
||||||
private static class NamingHttpClientFactory extends AbstractHttpClientFactory {
|
private static class NamingHttpClientFactory extends AbstractHttpClientFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -58,5 +85,10 @@ public class NamingHttpClientManager {
|
|||||||
return HttpClientConfig.builder().setConTimeOutMillis(CON_TIME_OUT_MILLIS)
|
return HttpClientConfig.builder().setConTimeOutMillis(CON_TIME_OUT_MILLIS)
|
||||||
.setReadTimeOutMillis(READ_TIME_OUT_MILLIS).setMaxRedirects(MAX_REDIRECTS).build();
|
.setReadTimeOutMillis(READ_TIME_OUT_MILLIS).setMaxRedirects(MAX_REDIRECTS).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Logger assignLogger() {
|
||||||
|
return NAMING_LOGGER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
|||||||
*/
|
*/
|
||||||
public class NamingProxy implements Closeable {
|
public class NamingProxy implements Closeable {
|
||||||
|
|
||||||
private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getNacosRestTemplate();
|
private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getInstance().getNacosRestTemplate();
|
||||||
|
|
||||||
private static final int DEFAULT_SERVER_PORT = 8848;
|
private static final int DEFAULT_SERVER_PORT = 8848;
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ public class NamingProxy implements Closeable {
|
|||||||
|
|
||||||
public NamingProxy(String namespaceId, String endpoint, String serverList, Properties properties) {
|
public NamingProxy(String namespaceId, String endpoint, String serverList, Properties properties) {
|
||||||
|
|
||||||
this.securityProxy = new SecurityProxy(properties);
|
this.securityProxy = new SecurityProxy(properties, nacosRestTemplate);
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.setServerPort(DEFAULT_SERVER_PORT);
|
this.setServerPort(DEFAULT_SERVER_PORT);
|
||||||
this.namespaceId = namespaceId;
|
this.namespaceId = namespaceId;
|
||||||
@ -592,7 +592,7 @@ public class NamingProxy implements Closeable {
|
|||||||
if (!curServer.contains(UtilAndComs.SERVER_ADDR_IP_SPLITER)) {
|
if (!curServer.contains(UtilAndComs.SERVER_ADDR_IP_SPLITER)) {
|
||||||
curServer = curServer + UtilAndComs.SERVER_ADDR_IP_SPLITER + serverPort;
|
curServer = curServer + UtilAndComs.SERVER_ADDR_IP_SPLITER + serverPort;
|
||||||
}
|
}
|
||||||
url = NamingHttpClientManager.getPrefix() + curServer + api;
|
url = NamingHttpClientManager.getInstance().getPrefix() + curServer + api;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -609,7 +609,7 @@ public class NamingProxy implements Closeable {
|
|||||||
if (HttpStatus.SC_NOT_MODIFIED == restResult.getCode()) {
|
if (HttpStatus.SC_NOT_MODIFIED == restResult.getCode()) {
|
||||||
return StringUtils.EMPTY;
|
return StringUtils.EMPTY;
|
||||||
}
|
}
|
||||||
throw new NacosException(restResult.getCode(), restResult.getData());
|
throw new NacosException(restResult.getCode(), restResult.getMessage());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
NAMING_LOGGER.error("[NA] failed to request", e);
|
NAMING_LOGGER.error("[NA] failed to request", e);
|
||||||
throw new NacosException(NacosException.SERVER_ERROR, e);
|
throw new NacosException(NacosException.SERVER_ERROR, e);
|
||||||
@ -715,6 +715,7 @@ public class NamingProxy implements Closeable {
|
|||||||
String className = this.getClass().getName();
|
String className = this.getClass().getName();
|
||||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||||
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
||||||
|
NamingHttpClientManager.getInstance().shutdown();
|
||||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ package com.alibaba.nacos.client.security;
|
|||||||
|
|
||||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||||
import com.alibaba.nacos.api.common.Constants;
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
import com.alibaba.nacos.client.naming.net.NamingHttpClientManager;
|
|
||||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||||
import com.alibaba.nacos.common.http.param.Header;
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
@ -46,7 +45,7 @@ public class SecurityProxy {
|
|||||||
|
|
||||||
private static final String LOGIN_URL = "/v1/auth/users/login";
|
private static final String LOGIN_URL = "/v1/auth/users/login";
|
||||||
|
|
||||||
private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getNacosRestTemplate();
|
private final NacosRestTemplate nacosRestTemplate;
|
||||||
|
|
||||||
private String contextPath;
|
private String contextPath;
|
||||||
|
|
||||||
@ -85,11 +84,12 @@ public class SecurityProxy {
|
|||||||
*
|
*
|
||||||
* @param properties a bunch of properties to read
|
* @param properties a bunch of properties to read
|
||||||
*/
|
*/
|
||||||
public SecurityProxy(Properties properties) {
|
public SecurityProxy(Properties properties, NacosRestTemplate nacosRestTemplate) {
|
||||||
username = properties.getProperty(PropertyKeyConst.USERNAME, StringUtils.EMPTY);
|
username = properties.getProperty(PropertyKeyConst.USERNAME, StringUtils.EMPTY);
|
||||||
password = properties.getProperty(PropertyKeyConst.PASSWORD, StringUtils.EMPTY);
|
password = properties.getProperty(PropertyKeyConst.PASSWORD, StringUtils.EMPTY);
|
||||||
contextPath = properties.getProperty(PropertyKeyConst.CONTEXT_PATH, "/nacos");
|
contextPath = properties.getProperty(PropertyKeyConst.CONTEXT_PATH, "/nacos");
|
||||||
contextPath = contextPath.startsWith("/") ? contextPath : "/" + contextPath;
|
contextPath = contextPath.startsWith("/") ? contextPath : "/" + contextPath;
|
||||||
|
this.nacosRestTemplate = nacosRestTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,6 @@ package com.alibaba.nacos.client.utils;
|
|||||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||||
import com.alibaba.nacos.api.SystemPropertyKeyConst;
|
import com.alibaba.nacos.api.SystemPropertyKeyConst;
|
||||||
import com.alibaba.nacos.api.common.Constants;
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
|
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
@ -82,7 +81,7 @@ public class ParamUtil {
|
|||||||
LOGGER.info("[settings] [http-client] connect timeout:{}", connectTimeout);
|
LOGGER.info("[settings] [http-client] connect timeout:{}", connectTimeout);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
InputStream in = HttpSimpleClient.class.getClassLoader().getResourceAsStream("application.properties");
|
InputStream in = ValidatorUtils.class.getClassLoader().getResourceAsStream("application.properties");
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.load(in);
|
props.load(in);
|
||||||
String val = null;
|
String val = null;
|
||||||
|
@ -24,8 +24,8 @@ import com.alibaba.nacos.api.exception.NacosException;
|
|||||||
import com.alibaba.nacos.cmdb.core.SwitchAndOptions;
|
import com.alibaba.nacos.cmdb.core.SwitchAndOptions;
|
||||||
import com.alibaba.nacos.cmdb.service.CmdbReader;
|
import com.alibaba.nacos.cmdb.service.CmdbReader;
|
||||||
import com.alibaba.nacos.cmdb.service.CmdbWriter;
|
import com.alibaba.nacos.cmdb.service.CmdbWriter;
|
||||||
|
import com.alibaba.nacos.cmdb.utils.CmdbExecutor;
|
||||||
import com.alibaba.nacos.cmdb.utils.Loggers;
|
import com.alibaba.nacos.cmdb.utils.Loggers;
|
||||||
import com.alibaba.nacos.cmdb.utils.UtilsAndCommons;
|
|
||||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -117,11 +117,9 @@ public class CmdbProvider implements CmdbReader, CmdbWriter {
|
|||||||
initCmdbService();
|
initCmdbService();
|
||||||
load();
|
load();
|
||||||
|
|
||||||
UtilsAndCommons.GLOBAL_EXECUTOR.schedule(new CmdbDumpTask(), switches.getDumpTaskInterval(), TimeUnit.SECONDS);
|
CmdbExecutor.scheduleCmdbTask(new CmdbDumpTask(), switches.getDumpTaskInterval(), TimeUnit.SECONDS);
|
||||||
UtilsAndCommons.GLOBAL_EXECUTOR
|
CmdbExecutor.scheduleCmdbTask(new CmdbLabelTask(), switches.getLabelTaskInterval(), TimeUnit.SECONDS);
|
||||||
.schedule(new CmdbLabelTask(), switches.getLabelTaskInterval(), TimeUnit.SECONDS);
|
CmdbExecutor.scheduleCmdbTask(new CmdbEventTask(), switches.getEventTaskInterval(), TimeUnit.SECONDS);
|
||||||
UtilsAndCommons.GLOBAL_EXECUTOR
|
|
||||||
.schedule(new CmdbEventTask(), switches.getEventTaskInterval(), TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -205,7 +203,7 @@ public class CmdbProvider implements CmdbReader, CmdbWriter {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Loggers.MAIN.error("CMDB-LABEL-TASK {}", "dump failed!", e);
|
Loggers.MAIN.error("CMDB-LABEL-TASK {}", "dump failed!", e);
|
||||||
} finally {
|
} finally {
|
||||||
UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getLabelTaskInterval(), TimeUnit.SECONDS);
|
CmdbExecutor.scheduleCmdbTask(this, switches.getLabelTaskInterval(), TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,7 +225,7 @@ public class CmdbProvider implements CmdbReader, CmdbWriter {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Loggers.MAIN.error("DUMP-TASK {}", "dump failed!", e);
|
Loggers.MAIN.error("DUMP-TASK {}", "dump failed!", e);
|
||||||
} finally {
|
} finally {
|
||||||
UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getDumpTaskInterval(), TimeUnit.SECONDS);
|
CmdbExecutor.scheduleCmdbTask(this, switches.getDumpTaskInterval(), TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -271,7 +269,7 @@ public class CmdbProvider implements CmdbReader, CmdbWriter {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Loggers.MAIN.error("CMDB-EVENT {}", "event task failed!", e);
|
Loggers.MAIN.error("CMDB-EVENT {}", "event task failed!", e);
|
||||||
} finally {
|
} finally {
|
||||||
UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getEventTaskInterval(), TimeUnit.SECONDS);
|
CmdbExecutor.scheduleCmdbTask(this, switches.getEventTaskInterval(), TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.cmdb.utils;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.cmdb.CmdbApp;
|
||||||
|
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||||
|
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||||
|
import com.alibaba.nacos.core.utils.ClassUtils;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cmdb executor.
|
||||||
|
*
|
||||||
|
* @author wangweizZZ
|
||||||
|
* @date 2020/7/13 1:54 PM
|
||||||
|
*/
|
||||||
|
public class CmdbExecutor {
|
||||||
|
|
||||||
|
private static final ScheduledExecutorService GLOBAL_EXECUTOR = ExecutorFactory.Managed
|
||||||
|
.newScheduledExecutorService(ClassUtils.getCanonicalName(CmdbApp.class),
|
||||||
|
Runtime.getRuntime().availableProcessors(),
|
||||||
|
new NameThreadFactory("com.alibaba.nacos.cmdb.global.executor"));
|
||||||
|
|
||||||
|
public static void scheduleCmdbTask(Runnable runnable, long delay, TimeUnit unit) {
|
||||||
|
GLOBAL_EXECUTOR.schedule(runnable, delay, unit);
|
||||||
|
}
|
||||||
|
}
|
@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.cmdb.utils;
|
package com.alibaba.nacos.cmdb.utils;
|
||||||
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utils and constants.
|
* Utils and constants.
|
||||||
*
|
*
|
||||||
@ -32,19 +28,4 @@ public class UtilsAndCommons {
|
|||||||
|
|
||||||
public static final String NACOS_CMDB_CONTEXT = NACOS_SERVER_VERSION + "/cmdb";
|
public static final String NACOS_CMDB_CONTEXT = NACOS_SERVER_VERSION + "/cmdb";
|
||||||
|
|
||||||
public static final ScheduledExecutorService GLOBAL_EXECUTOR;
|
|
||||||
|
|
||||||
static {
|
|
||||||
|
|
||||||
GLOBAL_EXECUTOR = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
|
|
||||||
new ThreadFactory() {
|
|
||||||
@Override
|
|
||||||
public Thread newThread(Runnable r) {
|
|
||||||
Thread t = new Thread(r);
|
|
||||||
t.setName("nacos.cmdb.global.executor");
|
|
||||||
t.setDaemon(true);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -14,24 +14,19 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.alibaba.nacos.core.notify;
|
package com.alibaba.nacos.common.constant;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event.
|
* Response Handler Type.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author mai.jh
|
||||||
*/
|
*/
|
||||||
public interface Event extends Serializable {
|
public final class ResponseHandlerType {
|
||||||
|
|
||||||
/**
|
public static final String STRING_TYPE = "java.lang.String";
|
||||||
* Event sequence number, which can be used to handle the sequence of events.
|
|
||||||
*
|
public static final String RESTRESULT_TYPE = "com.alibaba.nacos.common.model.RestResult";
|
||||||
* @return sequence num, It's best to make sure it's monotone
|
|
||||||
*/
|
public static final String DEFAULT_BEAN_TYPE = "default_bean_handler";
|
||||||
default long sequence() {
|
|
||||||
return System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -38,10 +38,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
"checkstyle:missingjavadocmethod"})
|
"checkstyle:missingjavadocmethod"})
|
||||||
public final class ExecutorFactory {
|
public final class ExecutorFactory {
|
||||||
|
|
||||||
private static final String DEFAULT_NAMESPACE = "nacos";
|
|
||||||
|
|
||||||
private static final ThreadPoolManager THREAD_POOL_MANAGER = ThreadPoolManager.getInstance();
|
|
||||||
|
|
||||||
public static ExecutorService newSingleExecutorService() {
|
public static ExecutorService newSingleExecutorService() {
|
||||||
return Executors.newFixedThreadPool(1);
|
return Executors.newFixedThreadPool(1);
|
||||||
}
|
}
|
||||||
@ -73,61 +69,6 @@ public final class ExecutorFactory {
|
|||||||
new LinkedBlockingQueue<Runnable>(), threadFactory);
|
new LinkedBlockingQueue<Runnable>(), threadFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO remove Deprecated function after replace all module
|
|
||||||
@Deprecated
|
|
||||||
public static ExecutorService newSingleExecutorService(final String group) {
|
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
|
||||||
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
|
|
||||||
return executorService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
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 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 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) {
|
|
||||||
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) {
|
|
||||||
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);
|
|
||||||
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executor);
|
|
||||||
return executor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Managed {
|
public static final class Managed {
|
||||||
|
|
||||||
private static final String DEFAULT_NAMESPACE = "nacos";
|
private static final String DEFAULT_NAMESPACE = "nacos";
|
||||||
|
@ -17,12 +17,12 @@
|
|||||||
package com.alibaba.nacos.common.http;
|
package com.alibaba.nacos.common.http;
|
||||||
|
|
||||||
import com.alibaba.nacos.common.http.client.DefaultAsyncHttpClientRequest;
|
import com.alibaba.nacos.common.http.client.DefaultAsyncHttpClientRequest;
|
||||||
import com.alibaba.nacos.common.http.client.DefaultHttpClientRequest;
|
import com.alibaba.nacos.common.http.client.JdkHttpClientRequest;
|
||||||
import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
|
import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
|
||||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||||
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.config.RequestConfig;
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AbstractHttpClientFactory Let the creator only specify the http client config.
|
* AbstractHttpClientFactory Let the creator only specify the http client config.
|
||||||
@ -33,15 +33,14 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final NacosRestTemplate createNacosRestTemplate() {
|
public final NacosRestTemplate createNacosRestTemplate() {
|
||||||
RequestConfig requestConfig = getRequestConfig();
|
HttpClientConfig httpClientConfig = buildHttpClientConfig();
|
||||||
return new NacosRestTemplate(
|
return new NacosRestTemplate(assignLogger(), new JdkHttpClientRequest(httpClientConfig));
|
||||||
new DefaultHttpClientRequest(HttpClients.custom().setDefaultRequestConfig(requestConfig).build()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final NacosAsyncRestTemplate createNacosAsyncRestTemplate() {
|
public final NacosAsyncRestTemplate createNacosAsyncRestTemplate() {
|
||||||
RequestConfig requestConfig = getRequestConfig();
|
RequestConfig requestConfig = getRequestConfig();
|
||||||
return new NacosAsyncRestTemplate(new DefaultAsyncHttpClientRequest(
|
return new NacosAsyncRestTemplate(assignLogger(), new DefaultAsyncHttpClientRequest(
|
||||||
HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig).build()));
|
HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig).build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,4 +57,11 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory {
|
|||||||
* @return HttpClientConfig
|
* @return HttpClientConfig
|
||||||
*/
|
*/
|
||||||
protected abstract HttpClientConfig buildHttpClientConfig();
|
protected abstract HttpClientConfig buildHttpClientConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* assign Logger.
|
||||||
|
*
|
||||||
|
* @return Logger
|
||||||
|
*/
|
||||||
|
protected abstract Logger assignLogger();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.common.http;
|
package com.alibaba.nacos.common.http;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* default http client factory.
|
* default http client factory.
|
||||||
*
|
*
|
||||||
@ -25,8 +27,19 @@ public class DefaultHttpClientFactory extends AbstractHttpClientFactory {
|
|||||||
|
|
||||||
private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000);
|
private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000);
|
||||||
|
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
|
public DefaultHttpClientFactory(Logger logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HttpClientConfig buildHttpClientConfig() {
|
protected HttpClientConfig buildHttpClientConfig() {
|
||||||
return HttpClientConfig.builder().setConTimeOutMillis(TIMEOUT).setReadTimeOutMillis(TIMEOUT >> 1).build();
|
return HttpClientConfig.builder().setConTimeOutMillis(TIMEOUT).setReadTimeOutMillis(TIMEOUT >> 1).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Logger assignLogger() {
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,15 +18,10 @@ package com.alibaba.nacos.common.http;
|
|||||||
|
|
||||||
import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
|
import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
|
||||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
|
||||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
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.
|
||||||
@ -35,25 +30,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
*/
|
*/
|
||||||
public final class HttpClientBeanHolder {
|
public final class HttpClientBeanHolder {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientManager.class);
|
|
||||||
|
|
||||||
private static final Map<String, NacosRestTemplate> SINGLETON_REST = new HashMap<String, NacosRestTemplate>(10);
|
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 Map<String, NacosAsyncRestTemplate> SINGLETON_ASYNC_REST = new HashMap<String, NacosAsyncRestTemplate>(
|
||||||
|
10);
|
||||||
|
|
||||||
private static final AtomicBoolean ALREADY_SHUTDOWN = new AtomicBoolean(false);
|
public static NacosRestTemplate getNacosRestTemplate(Logger logger) {
|
||||||
|
return getNacosRestTemplate(new DefaultHttpClientFactory(logger));
|
||||||
static {
|
|
||||||
ThreadUtils.addShutdownHook(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NacosRestTemplate getNacosRestTemplate() {
|
|
||||||
return getNacosRestTemplate(new DefaultHttpClientFactory());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NacosRestTemplate getNacosRestTemplate(HttpClientFactory httpClientFactory) {
|
public static NacosRestTemplate getNacosRestTemplate(HttpClientFactory httpClientFactory) {
|
||||||
@ -75,8 +58,8 @@ public final class HttpClientBeanHolder {
|
|||||||
return nacosRestTemplate;
|
return nacosRestTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NacosAsyncRestTemplate getNacosAsyncRestTemplate() {
|
public static NacosAsyncRestTemplate getNacosAsyncRestTemplate(Logger logger) {
|
||||||
return getNacosAsyncRestTemplate(new DefaultHttpClientFactory());
|
return getNacosAsyncRestTemplate(new DefaultHttpClientFactory(logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NacosAsyncRestTemplate getNacosAsyncRestTemplate(HttpClientFactory httpClientFactory) {
|
public static NacosAsyncRestTemplate getNacosAsyncRestTemplate(HttpClientFactory httpClientFactory) {
|
||||||
@ -99,40 +82,41 @@ public final class HttpClientBeanHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shutdown http client holder and close all template.
|
* Shutdown http client holder and close remove template.
|
||||||
|
*
|
||||||
|
* @param className HttpClientFactory implement class name
|
||||||
|
* @throws Exception ex
|
||||||
*/
|
*/
|
||||||
public static void shutdown() {
|
public static void shutdown(String className) throws Exception {
|
||||||
if (!ALREADY_SHUTDOWN.compareAndSet(false, true)) {
|
shutdownNacostSyncRest(className);
|
||||||
return;
|
shutdownNacosAsyncRest(className);
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
LOGGER.warn("[HttpClientBeanFactory] Destruction of the end");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void nacostRestTemplateShutdown() throws Exception {
|
/**
|
||||||
if (!SINGLETON_REST.isEmpty()) {
|
* Shutdown sync http client holder and remove template.
|
||||||
Collection<NacosRestTemplate> nacosRestTemplates = SINGLETON_REST.values();
|
*
|
||||||
for (NacosRestTemplate nacosRestTemplate : nacosRestTemplates) {
|
* @param className HttpClientFactory implement class name
|
||||||
nacosRestTemplate.close();
|
* @throws Exception ex
|
||||||
}
|
*/
|
||||||
SINGLETON_REST.clear();
|
public static void shutdownNacostSyncRest(String className) throws Exception {
|
||||||
|
final NacosRestTemplate nacosRestTemplate = SINGLETON_REST.get(className);
|
||||||
|
if (nacosRestTemplate != null) {
|
||||||
|
nacosRestTemplate.close();
|
||||||
|
SINGLETON_REST.remove(className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void nacosAsyncRestTemplateShutdown() throws Exception {
|
/**
|
||||||
if (!SINGLETON_ASYNC_REST.isEmpty()) {
|
* Shutdown async http client holder and remove template.
|
||||||
Collection<NacosAsyncRestTemplate> nacosAsyncRestTemplates = SINGLETON_ASYNC_REST.values();
|
*
|
||||||
for (NacosAsyncRestTemplate nacosAsyncRestTemplate : nacosAsyncRestTemplates) {
|
* @param className HttpClientFactory implement class name
|
||||||
nacosAsyncRestTemplate.close();
|
* @throws Exception ex
|
||||||
}
|
*/
|
||||||
SINGLETON_ASYNC_REST.clear();
|
public static void shutdownNacosAsyncRest(String className) throws Exception {
|
||||||
|
final NacosAsyncRestTemplate nacosAsyncRestTemplate = SINGLETON_ASYNC_REST.get(className);
|
||||||
|
if (nacosAsyncRestTemplate != null) {
|
||||||
|
nacosAsyncRestTemplate.close();
|
||||||
|
SINGLETON_ASYNC_REST.remove(className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,8 @@ public class HttpRestResult<T> extends RestResult<T> {
|
|||||||
public HttpRestResult() {
|
public HttpRestResult() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpRestResult(Header header, int code, T data) {
|
public HttpRestResult(Header header, int code, T data, String message) {
|
||||||
super(code, data);
|
super(code, message, data);
|
||||||
this.header = header;
|
this.header = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.constant.ResponseHandlerType;
|
||||||
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
|
import com.fasterxml.jackson.databind.JavaType;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For NacosRestTemplate and NacosAsyncRestTemplate, provide initialization and register of response converter.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public abstract class AbstractNacosRestTemplate {
|
||||||
|
|
||||||
|
private final Map<String, ResponseHandler> responseHandlerMap = new HashMap<String, ResponseHandler>();
|
||||||
|
|
||||||
|
protected final Logger logger;
|
||||||
|
|
||||||
|
public AbstractNacosRestTemplate(Logger logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
initDefaultResponseHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initDefaultResponseHandler() {
|
||||||
|
// init response handler
|
||||||
|
responseHandlerMap.put(ResponseHandlerType.STRING_TYPE, new StringResponseHandler());
|
||||||
|
responseHandlerMap.put(ResponseHandlerType.RESTRESULT_TYPE, new RestResultResponseHandler());
|
||||||
|
responseHandlerMap.put(ResponseHandlerType.DEFAULT_BEAN_TYPE, new BeanResponseHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* register customization Response Handler.
|
||||||
|
*
|
||||||
|
* @param responseHandler {@link ResponseHandler}
|
||||||
|
*/
|
||||||
|
public void registerResponseHandler(String responseHandlerType, ResponseHandler responseHandler) {
|
||||||
|
responseHandlerMap.put(responseHandlerType, responseHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select a response handler by responseType.
|
||||||
|
*
|
||||||
|
* @param responseType responseType
|
||||||
|
* @return ResponseHandler
|
||||||
|
*/
|
||||||
|
protected ResponseHandler selectResponseHandler(Type responseType) {
|
||||||
|
ResponseHandler responseHandler = null;
|
||||||
|
if (responseType == null) {
|
||||||
|
responseHandler = responseHandlerMap.get(ResponseHandlerType.STRING_TYPE);
|
||||||
|
}
|
||||||
|
if (responseHandler == null) {
|
||||||
|
JavaType javaType = JacksonUtils.constructJavaType(responseType);
|
||||||
|
String name = javaType.getRawClass().getName();
|
||||||
|
responseHandler = responseHandlerMap.get(name);
|
||||||
|
}
|
||||||
|
// When the corresponding type of response handler cannot be obtained,
|
||||||
|
// the default bean response handler is used
|
||||||
|
if (responseHandler == null) {
|
||||||
|
responseHandler = responseHandlerMap.get(ResponseHandlerType.DEFAULT_BEAN_TYPE);
|
||||||
|
}
|
||||||
|
responseHandler.setResponseType(responseType);
|
||||||
|
return responseHandler;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
|
import com.alibaba.nacos.common.utils.IoUtils;
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract response handler.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public abstract class AbstractResponseHandler<T> implements ResponseHandler<T> {
|
||||||
|
|
||||||
|
private Type responseType;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void setResponseType(Type responseType) {
|
||||||
|
this.responseType = responseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final HttpRestResult<T> handle(HttpClientResponse response) throws Exception {
|
||||||
|
if (HttpStatus.SC_OK != response.getStatusCode()) {
|
||||||
|
return handleError(response);
|
||||||
|
}
|
||||||
|
return convertResult(response, this.responseType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpRestResult<T> handleError(HttpClientResponse response) throws Exception {
|
||||||
|
Header headers = response.getHeaders();
|
||||||
|
String message = IoUtils.toString(response.getBody(), headers.getCharset());
|
||||||
|
return new HttpRestResult<T>(headers, response.getStatusCode(), null, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract convertResult method, Different types of converters for expansion.
|
||||||
|
*
|
||||||
|
* @param response http client response
|
||||||
|
* @param responseType responseType
|
||||||
|
* @return HttpRestResult
|
||||||
|
* @throws Exception ex
|
||||||
|
*/
|
||||||
|
public abstract HttpRestResult<T> convertResult(HttpClientResponse response, Type responseType) throws Exception;
|
||||||
|
|
||||||
|
}
|
@ -20,7 +20,6 @@ import com.alibaba.nacos.common.http.Callback;
|
|||||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,10 +36,10 @@ public interface AsyncHttpClientRequest extends Closeable {
|
|||||||
* @param uri http url
|
* @param uri http url
|
||||||
* @param httpMethod http request method
|
* @param httpMethod http request method
|
||||||
* @param requestHttpEntity http request entity
|
* @param requestHttpEntity http request entity
|
||||||
* @param responseType http response type
|
* @param responseHandler http response handler
|
||||||
* @param callback http response callback
|
* @param callback http response callback
|
||||||
* @throws Exception ex
|
* @throws Exception ex
|
||||||
*/
|
*/
|
||||||
<T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType,
|
<T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity,
|
||||||
final Callback<T> callback) throws Exception;
|
final ResponseHandler<T> responseHandler, final Callback<T> callback) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bean response handler,
|
||||||
|
* Mainly converter response type as bean type.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public class BeanResponseHandler<T> extends AbstractResponseHandler<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpRestResult<T> convertResult(HttpClientResponse response, Type responseType) throws Exception {
|
||||||
|
final Header headers = response.getHeaders();
|
||||||
|
InputStream body = response.getBody();
|
||||||
|
T extractBody = JacksonUtils.toObj(body, responseType);
|
||||||
|
return new HttpRestResult<T>(headers, response.getStatusCode(), extractBody, null);
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,6 @@ package com.alibaba.nacos.common.http.client;
|
|||||||
|
|
||||||
import com.alibaba.nacos.common.http.Callback;
|
import com.alibaba.nacos.common.http.Callback;
|
||||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
import com.alibaba.nacos.common.http.handler.ResponseHandler;
|
|
||||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.methods.HttpRequestBase;
|
import org.apache.http.client.methods.HttpRequestBase;
|
||||||
@ -26,7 +25,6 @@ import org.apache.http.concurrent.FutureCallback;
|
|||||||
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +44,7 @@ public class DefaultAsyncHttpClientRequest implements AsyncHttpClientRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType,
|
public <T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final ResponseHandler<T> responseHandler,
|
||||||
final Callback<T> callback) throws Exception {
|
final Callback<T> callback) throws Exception {
|
||||||
HttpRequestBase httpRequestBase = DefaultHttpClientRequest.build(uri, httpMethod, requestHttpEntity);
|
HttpRequestBase httpRequestBase = DefaultHttpClientRequest.build(uri, httpMethod, requestHttpEntity);
|
||||||
asyncClient.execute(httpRequestBase, new FutureCallback<HttpResponse>() {
|
asyncClient.execute(httpRequestBase, new FutureCallback<HttpResponse>() {
|
||||||
@ -54,7 +52,7 @@ public class DefaultAsyncHttpClientRequest implements AsyncHttpClientRequest {
|
|||||||
public void completed(HttpResponse result) {
|
public void completed(HttpResponse result) {
|
||||||
DefaultClientHttpResponse response = new DefaultClientHttpResponse(result);
|
DefaultClientHttpResponse response = new DefaultClientHttpResponse(result);
|
||||||
try {
|
try {
|
||||||
HttpRestResult<T> httpRestResult = ResponseHandler.responseEntityExtractor(response, responseType);
|
HttpRestResult<T> httpRestResult = responseHandler.handle(response);
|
||||||
callback.onReceive(httpRestResult);
|
callback.onReceive(httpRestResult);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
callback.onError(e);
|
callback.onError(e);
|
||||||
|
@ -18,14 +18,14 @@ package com.alibaba.nacos.common.http.client;
|
|||||||
|
|
||||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||||
import com.alibaba.nacos.common.http.BaseHttpMethod;
|
import com.alibaba.nacos.common.http.BaseHttpMethod;
|
||||||
|
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||||
import com.alibaba.nacos.common.http.param.Header;
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
import com.alibaba.nacos.common.http.param.MediaType;
|
import com.alibaba.nacos.common.http.param.MediaType;
|
||||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpRequestBase;
|
import org.apache.http.client.methods.HttpRequestBase;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -39,8 +39,6 @@ import java.util.Map;
|
|||||||
@SuppressWarnings({"unchecked", "resource"})
|
@SuppressWarnings({"unchecked", "resource"})
|
||||||
public class DefaultHttpClientRequest implements HttpClientRequest {
|
public class DefaultHttpClientRequest implements HttpClientRequest {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultHttpClientRequest.class);
|
|
||||||
|
|
||||||
private final CloseableHttpClient client;
|
private final CloseableHttpClient client;
|
||||||
|
|
||||||
public DefaultHttpClientRequest(CloseableHttpClient client) {
|
public DefaultHttpClientRequest(CloseableHttpClient client) {
|
||||||
@ -52,9 +50,6 @@ public class DefaultHttpClientRequest implements HttpClientRequest {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
HttpRequestBase request = build(uri, httpMethod, requestHttpEntity);
|
HttpRequestBase request = build(uri, httpMethod, requestHttpEntity);
|
||||||
CloseableHttpResponse response = client.execute(request);
|
CloseableHttpResponse response = client.execute(request);
|
||||||
if (LOGGER.isDebugEnabled()) {
|
|
||||||
LOGGER.debug("Request from server: " + request.getURI().toString());
|
|
||||||
}
|
|
||||||
return new DefaultClientHttpResponse(response);
|
return new DefaultClientHttpResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +64,24 @@ public class DefaultHttpClientRequest implements HttpClientRequest {
|
|||||||
} else {
|
} else {
|
||||||
httpMethod.initEntity(requestHttpEntity.getBody(), headers.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
httpMethod.initEntity(requestHttpEntity.getBody(), headers.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||||
}
|
}
|
||||||
return httpMethod.getRequestBase();
|
HttpRequestBase requestBase = httpMethod.getRequestBase();
|
||||||
|
replaceDefaultConfig(requestBase, requestHttpEntity.getHttpClientConfig());
|
||||||
|
return requestBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the HTTP config created by default with the HTTP config specified in the request.
|
||||||
|
*
|
||||||
|
* @param requestBase requestBase
|
||||||
|
* @param httpClientConfig http config
|
||||||
|
*/
|
||||||
|
private static void replaceDefaultConfig(HttpRequestBase requestBase, HttpClientConfig httpClientConfig) {
|
||||||
|
if (httpClientConfig == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
requestBase.setConfig(RequestConfig.custom()
|
||||||
|
.setConnectTimeout(httpClientConfig.getConTimeOutMillis())
|
||||||
|
.setSocketTimeout(httpClientConfig.getReadTimeOutMillis()).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intercepts client-side HTTP requests. Implementations of this interface can be.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public interface HttpClientRequestInterceptor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is intercept.
|
||||||
|
*
|
||||||
|
* @param uri uri
|
||||||
|
* @param httpMethod http method
|
||||||
|
* @param requestHttpEntity request entity
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
boolean isIntercept(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if isIntercept method is true Intercept the given request, and return a response Otherwise,
|
||||||
|
* the {@link HttpClientRequest} will be used for execution.
|
||||||
|
*
|
||||||
|
* @return HttpClientResponse
|
||||||
|
*/
|
||||||
|
HttpClientResponse intercept();
|
||||||
|
}
|
@ -48,15 +48,17 @@ public interface HttpClientResponse extends Closeable {
|
|||||||
* Return the HTTP status code.
|
* Return the HTTP status code.
|
||||||
*
|
*
|
||||||
* @return the HTTP status as an integer
|
* @return the HTTP status as an integer
|
||||||
|
* @throws IOException IOException
|
||||||
*/
|
*/
|
||||||
int getStatusCode();
|
int getStatusCode() throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the HTTP status text of the response.
|
* Return the HTTP status text of the response.
|
||||||
*
|
*
|
||||||
* @return the HTTP status text
|
* @return the HTTP status text
|
||||||
|
* @throws IOException IOException
|
||||||
*/
|
*/
|
||||||
String getStatusText();
|
String getStatusText() throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* close response InputStream.
|
* close response InputStream.
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap http client request and perform corresponding interception.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public class InterceptingHttpClientRequest implements HttpClientRequest {
|
||||||
|
|
||||||
|
private final HttpClientRequest httpClientRequest;
|
||||||
|
|
||||||
|
private final Iterator<HttpClientRequestInterceptor> interceptors;
|
||||||
|
|
||||||
|
public InterceptingHttpClientRequest(HttpClientRequest httpClientRequest,
|
||||||
|
Iterator<HttpClientRequestInterceptor> interceptors) {
|
||||||
|
this.httpClientRequest = httpClientRequest;
|
||||||
|
this.interceptors = interceptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity)
|
||||||
|
throws Exception {
|
||||||
|
while (interceptors.hasNext()) {
|
||||||
|
HttpClientRequestInterceptor nextInterceptor = interceptors.next();
|
||||||
|
if (nextInterceptor.isIntercept(uri, httpMethod, requestHttpEntity)) {
|
||||||
|
return nextInterceptor.intercept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return httpClientRequest.execute(uri, httpMethod, requestHttpEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
httpClientRequest.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||||
|
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||||
|
import com.alibaba.nacos.common.http.HttpUtils;
|
||||||
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
|
import com.alibaba.nacos.common.http.param.MediaType;
|
||||||
|
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||||
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JDK http client request implement.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public class JdkHttpClientRequest implements HttpClientRequest {
|
||||||
|
|
||||||
|
private HttpClientConfig httpClientConfig;
|
||||||
|
|
||||||
|
public JdkHttpClientRequest(HttpClientConfig httpClientConfig) {
|
||||||
|
this.httpClientConfig = httpClientConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity)
|
||||||
|
throws Exception {
|
||||||
|
final Object body = requestHttpEntity.getBody();
|
||||||
|
final Header headers = requestHttpEntity.getHeaders();
|
||||||
|
replaceDefaultConfig(requestHttpEntity.getHttpClientConfig());
|
||||||
|
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) uri.toURL().openConnection();
|
||||||
|
Map<String, String> headerMap = headers.getHeader();
|
||||||
|
if (headerMap != null && headerMap.size() > 0) {
|
||||||
|
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
|
||||||
|
conn.setRequestProperty(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.setConnectTimeout(this.httpClientConfig.getConTimeOutMillis());
|
||||||
|
conn.setReadTimeout(this.httpClientConfig.getReadTimeOutMillis());
|
||||||
|
conn.setRequestMethod(httpMethod);
|
||||||
|
if (body != null) {
|
||||||
|
String contentType = headers.getValue(HttpHeaderConsts.CONTENT_TYPE);
|
||||||
|
String bodyStr = JacksonUtils.toJson(body);
|
||||||
|
if (MediaType.APPLICATION_FORM_URLENCODED.equals(contentType)) {
|
||||||
|
Map<String, String> map = JacksonUtils.toObj(bodyStr, HashMap.class);
|
||||||
|
bodyStr = HttpUtils.encodingParams(map, headers.getCharset());
|
||||||
|
}
|
||||||
|
if (bodyStr != null) {
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
byte[] b = bodyStr.getBytes();
|
||||||
|
conn.setRequestProperty("Content-Length", String.valueOf(b.length));
|
||||||
|
conn.getOutputStream().write(b, 0, b.length);
|
||||||
|
conn.getOutputStream().flush();
|
||||||
|
conn.getOutputStream().close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conn.connect();
|
||||||
|
return new JdkHttpClientResponse(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the HTTP config created by default with the HTTP config specified in the request.
|
||||||
|
*
|
||||||
|
* @param replaceConfig http config
|
||||||
|
*/
|
||||||
|
private void replaceDefaultConfig(HttpClientConfig replaceConfig) {
|
||||||
|
if (replaceConfig == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.httpClientConfig = replaceConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
|
import com.alibaba.nacos.common.utils.IoUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JDk http client response implement.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public class JdkHttpClientResponse implements HttpClientResponse {
|
||||||
|
|
||||||
|
private final HttpURLConnection conn;
|
||||||
|
|
||||||
|
private InputStream responseStream;
|
||||||
|
|
||||||
|
private Header responseHeader;
|
||||||
|
|
||||||
|
public JdkHttpClientResponse(HttpURLConnection conn) {
|
||||||
|
this.conn = conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Header getHeaders() {
|
||||||
|
if (this.responseHeader == null) {
|
||||||
|
this.responseHeader = Header.newInstance();
|
||||||
|
}
|
||||||
|
this.responseHeader.setOriginalResponseHeader(conn.getHeaderFields());
|
||||||
|
return this.responseHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getBody() throws IOException {
|
||||||
|
InputStream errorStream = this.conn.getErrorStream();
|
||||||
|
this.responseStream = (errorStream != null ? errorStream : this.conn.getInputStream());
|
||||||
|
return this.responseStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStatusCode() throws IOException {
|
||||||
|
return this.conn.getResponseCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStatusText() throws IOException {
|
||||||
|
return this.conn.getResponseMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
IoUtils.closeQuietly(this.responseStream);
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,6 @@ import com.alibaba.nacos.common.http.param.Query;
|
|||||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -37,13 +36,12 @@ import java.util.Map;
|
|||||||
* @see AsyncHttpClientRequest
|
* @see AsyncHttpClientRequest
|
||||||
* @see HttpClientResponse
|
* @see HttpClientResponse
|
||||||
*/
|
*/
|
||||||
public class NacosAsyncRestTemplate {
|
public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(NacosAsyncRestTemplate.class);
|
private final AsyncHttpClientRequest clientRequest;
|
||||||
|
|
||||||
private AsyncHttpClientRequest clientRequest;
|
public NacosAsyncRestTemplate(Logger logger, AsyncHttpClientRequest clientRequest) {
|
||||||
|
super(logger);
|
||||||
public NacosAsyncRestTemplate(AsyncHttpClientRequest clientRequest) {
|
|
||||||
this.clientRequest = clientRequest;
|
this.clientRequest = clientRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,13 +328,15 @@ public class NacosAsyncRestTemplate {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type responseType,
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type type,
|
||||||
Callback<T> callback) throws Exception {
|
Callback<T> callback) throws Exception {
|
||||||
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
|
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
LOGGER.debug("HTTP " + httpMethod + " " + url);
|
logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody());
|
||||||
}
|
}
|
||||||
clientRequest.execute(uri, httpMethod, requestEntity, responseType, callback);
|
ResponseHandler<T> responseHandler = super.selectResponseHandler(type);
|
||||||
|
clientRequest.execute(uri, httpMethod, requestEntity, responseHandler, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,19 +16,21 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.common.http.client;
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
import com.alibaba.nacos.common.http.HttpUtils;
|
import com.alibaba.nacos.common.http.HttpUtils;
|
||||||
import com.alibaba.nacos.common.http.handler.ResponseHandler;
|
|
||||||
import com.alibaba.nacos.common.http.param.Header;
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
import com.alibaba.nacos.common.http.param.MediaType;
|
import com.alibaba.nacos.common.http.param.MediaType;
|
||||||
import com.alibaba.nacos.common.http.param.Query;
|
import com.alibaba.nacos.common.http.param.Query;
|
||||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||||
|
import com.alibaba.nacos.common.utils.CollectionUtils;
|
||||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,13 +40,14 @@ import java.util.Map;
|
|||||||
* @see HttpClientRequest
|
* @see HttpClientRequest
|
||||||
* @see HttpClientResponse
|
* @see HttpClientResponse
|
||||||
*/
|
*/
|
||||||
public class NacosRestTemplate {
|
public class NacosRestTemplate extends AbstractNacosRestTemplate {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(NacosRestTemplate.class);
|
private final HttpClientRequest requestClient;
|
||||||
|
|
||||||
private HttpClientRequest requestClient;
|
private final List<HttpClientRequestInterceptor> interceptors = new ArrayList<HttpClientRequestInterceptor>();
|
||||||
|
|
||||||
public NacosRestTemplate(HttpClientRequest requestClient) {
|
public NacosRestTemplate(Logger logger, HttpClientRequest requestClient) {
|
||||||
|
super(logger);
|
||||||
this.requestClient = requestClient;
|
this.requestClient = requestClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +86,28 @@ public class NacosRestTemplate {
|
|||||||
return execute(url, HttpMethod.GET, requestHttpEntity, responseType);
|
return execute(url, HttpMethod.GET, requestHttpEntity, responseType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http get URL request params are expanded using the given query {@link Query}.
|
||||||
|
*
|
||||||
|
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||||
|
*
|
||||||
|
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
|
||||||
|
*
|
||||||
|
* @param url url
|
||||||
|
* @param config http config
|
||||||
|
* @param header headers
|
||||||
|
* @param paramValues paramValues
|
||||||
|
* @param responseType return type
|
||||||
|
* @return {@link HttpRestResult}
|
||||||
|
* @throws Exception ex
|
||||||
|
*/
|
||||||
|
public <T> HttpRestResult<T> get(String url, HttpClientConfig config, Header header,
|
||||||
|
Map<String, String> paramValues, Type responseType) throws Exception {
|
||||||
|
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header,
|
||||||
|
Query.newInstance().initParams(paramValues));
|
||||||
|
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.
|
* More request parameters can be set via body.
|
||||||
@ -118,6 +143,27 @@ public class NacosRestTemplate {
|
|||||||
return execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType);
|
return execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
|
||||||
|
*
|
||||||
|
* @param url url
|
||||||
|
* @param config http config
|
||||||
|
* @param header http header param
|
||||||
|
* @param paramValues http query param
|
||||||
|
* @param responseType return type
|
||||||
|
* @return {@link HttpRestResult}
|
||||||
|
* @throws Exception ex
|
||||||
|
*/
|
||||||
|
public <T> HttpRestResult<T> delete(String url, HttpClientConfig config, Header header,
|
||||||
|
Map<String, String> paramValues, Type responseType) throws Exception {
|
||||||
|
return execute(url, HttpMethod.DELETE,
|
||||||
|
new RequestHttpEntity(config, header, Query.newInstance().initParams(paramValues)), responseType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
*
|
*
|
||||||
@ -208,6 +254,33 @@ public class NacosRestTemplate {
|
|||||||
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
|
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'.
|
||||||
|
*
|
||||||
|
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||||
|
*
|
||||||
|
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||||
|
*
|
||||||
|
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
|
||||||
|
*
|
||||||
|
* @param url url
|
||||||
|
* @param config http config
|
||||||
|
* @param header http header param
|
||||||
|
* @param paramValues http query param
|
||||||
|
* @param bodyValues http body param
|
||||||
|
* @param responseType return type
|
||||||
|
* @return {@link HttpRestResult}
|
||||||
|
* @throws Exception ex
|
||||||
|
*/
|
||||||
|
public <T> HttpRestResult<T> putForm(String url, HttpClientConfig config, Header header,
|
||||||
|
Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||||
|
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config,
|
||||||
|
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.
|
||||||
*
|
*
|
||||||
@ -298,6 +371,33 @@ public class NacosRestTemplate {
|
|||||||
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
|
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'.
|
||||||
|
*
|
||||||
|
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||||
|
*
|
||||||
|
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||||
|
*
|
||||||
|
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
|
||||||
|
*
|
||||||
|
* @param url url
|
||||||
|
* @param config http config
|
||||||
|
* @param header http header param
|
||||||
|
* @param paramValues http query param
|
||||||
|
* @param bodyValues http body param
|
||||||
|
* @param responseType return type
|
||||||
|
* @return {@link HttpRestResult}
|
||||||
|
* @throws Exception ex
|
||||||
|
*/
|
||||||
|
public <T> HttpRestResult<T> postForm(String url, HttpClientConfig config, Header header,
|
||||||
|
Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||||
|
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config,
|
||||||
|
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||||
|
Query.newInstance().initParams(paramValues), bodyValues);
|
||||||
|
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the HTTP method to the given URI template, writing the given request entity to the request, and returns
|
* Execute the HTTP method to the given URI template, writing the given request entity to the request, and returns
|
||||||
* the response as {@link HttpRestResult}.
|
* the response as {@link HttpRestResult}.
|
||||||
@ -319,16 +419,40 @@ public class NacosRestTemplate {
|
|||||||
return execute(url, httpMethod, requestHttpEntity, responseType);
|
return execute(url, httpMethod, requestHttpEntity, responseType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the request interceptors that this accessor should use.
|
||||||
|
*
|
||||||
|
* @param interceptors {@link HttpClientRequestInterceptor}
|
||||||
|
*/
|
||||||
|
public void setInterceptors(List<HttpClientRequestInterceptor> interceptors) {
|
||||||
|
if (this.interceptors != interceptors) {
|
||||||
|
this.interceptors.clear();
|
||||||
|
this.interceptors.addAll(interceptors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the request interceptors that this accessor uses.
|
||||||
|
*
|
||||||
|
* <p>The returned {@link List} is active and may get appended to.
|
||||||
|
*/
|
||||||
|
public List<HttpClientRequestInterceptor> getInterceptors() {
|
||||||
|
return interceptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttpEntity requestEntity,
|
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());
|
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
LOGGER.debug("HTTP " + httpMethod + " " + url);
|
logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResponseHandler<T> responseHandler = super.selectResponseHandler(responseType);
|
||||||
HttpClientResponse response = null;
|
HttpClientResponse response = null;
|
||||||
try {
|
try {
|
||||||
response = requestClient.execute(uri, httpMethod, requestEntity);
|
response = this.requestClient().execute(uri, httpMethod, requestEntity);
|
||||||
return ResponseHandler.responseEntityExtractor(response, responseType);
|
return responseHandler.handle(response);
|
||||||
} finally {
|
} finally {
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
response.close();
|
response.close();
|
||||||
@ -336,6 +460,16 @@ public class NacosRestTemplate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HttpClientRequest requestClient() {
|
||||||
|
if (CollectionUtils.isNotEmpty(interceptors)) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Execute via interceptors :{}", interceptors);
|
||||||
|
}
|
||||||
|
return new InterceptingHttpClientRequest(requestClient, interceptors.iterator());
|
||||||
|
}
|
||||||
|
return requestClient;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* close request client.
|
* close request client.
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response Handler abstract interface,
|
||||||
|
* the actual processing of the response conversion is done by a concrete implementation class.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public interface ResponseHandler<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set response type.
|
||||||
|
*
|
||||||
|
* @param responseType responseType
|
||||||
|
*/
|
||||||
|
void setResponseType(Type responseType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle response convert to HttpRestResult.
|
||||||
|
*
|
||||||
|
* @param response http response
|
||||||
|
* @return HttpRestResult {@link HttpRestResult}
|
||||||
|
* @throws Exception ex
|
||||||
|
*/
|
||||||
|
HttpRestResult<T> handle(HttpClientResponse response) throws Exception;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
|
import com.alibaba.nacos.common.model.RestResult;
|
||||||
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RestResult response handler, Mainly converter response type as {@link RestResult} type.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public class RestResultResponseHandler<T> extends AbstractResponseHandler<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public HttpRestResult<T> convertResult(HttpClientResponse response, Type responseType) throws Exception {
|
||||||
|
final Header headers = response.getHeaders();
|
||||||
|
InputStream body = response.getBody();
|
||||||
|
T extractBody = JacksonUtils.toObj(body, responseType);
|
||||||
|
HttpRestResult<T> httpRestResult = convert((RestResult<T>) extractBody);
|
||||||
|
httpRestResult.setHeader(headers);
|
||||||
|
return httpRestResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.common.http.client;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||||
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
|
import com.alibaba.nacos.common.utils.IoUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* string response handler, Mainly converter response type as string type.
|
||||||
|
*
|
||||||
|
* @author mai.jh
|
||||||
|
*/
|
||||||
|
public class StringResponseHandler extends AbstractResponseHandler<String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpRestResult<String> convertResult(HttpClientResponse response, Type responseType) throws Exception {
|
||||||
|
final Header headers = response.getHeaders();
|
||||||
|
String extractBody = IoUtils.toString(response.getBody(), headers.getCharset());
|
||||||
|
return new HttpRestResult<String>(headers, response.getStatusCode(), extractBody, null);
|
||||||
|
}
|
||||||
|
}
|
@ -16,18 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.common.http.handler;
|
package com.alibaba.nacos.common.http.handler;
|
||||||
|
|
||||||
import com.alibaba.nacos.api.exception.runtime.NacosDeserializationException;
|
|
||||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
|
||||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
|
||||||
import com.alibaba.nacos.common.http.client.HttpClientResponse;
|
|
||||||
import com.alibaba.nacos.common.http.param.Header;
|
|
||||||
import com.alibaba.nacos.common.http.param.MediaType;
|
|
||||||
import com.alibaba.nacos.common.model.RestResult;
|
|
||||||
import com.alibaba.nacos.common.utils.IoUtils;
|
|
||||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
import org.apache.http.HttpStatus;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
@ -39,8 +28,6 @@ import java.lang.reflect.Type;
|
|||||||
*/
|
*/
|
||||||
public final class ResponseHandler {
|
public final class ResponseHandler {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ResponseHandler.class);
|
|
||||||
|
|
||||||
public static <T> T convert(String s, Class<T> cls) throws Exception {
|
public static <T> T convert(String s, Class<T> cls) throws Exception {
|
||||||
return JacksonUtils.toObj(s, cls);
|
return JacksonUtils.toObj(s, cls);
|
||||||
}
|
}
|
||||||
@ -52,55 +39,4 @@ public final class ResponseHandler {
|
|||||||
public static <T> T convert(InputStream inputStream, Type type) throws Exception {
|
public static <T> T convert(InputStream inputStream, Type type) throws Exception {
|
||||||
return JacksonUtils.toObj(inputStream, type);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract response entity to {@link HttpRestResult}.
|
|
||||||
*
|
|
||||||
* @param response response
|
|
||||||
* @param type type
|
|
||||||
* @param <T> general type
|
|
||||||
* @return {@link HttpRestResult}
|
|
||||||
* @throws Exception exception
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "resource"})
|
|
||||||
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;
|
|
||||||
final boolean typeToStr = String.class.toString().equals(type.toString());
|
|
||||||
if (contentType != null && contentType.startsWith(MediaType.APPLICATION_JSON) && HttpStatus.SC_OK == response
|
|
||||||
.getStatusCode()) {
|
|
||||||
// When the type is string type and the response contentType is [application/json],
|
|
||||||
// then it should be serialized as string
|
|
||||||
if (typeToStr) {
|
|
||||||
extractBody = (T) IoUtils.toString(body, headers.getCharset());
|
|
||||||
} else {
|
|
||||||
extractBody = convert(body, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (extractBody == null) {
|
|
||||||
if (!typeToStr) {
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
if (extractBody instanceof RestResult) {
|
|
||||||
HttpRestResult<T> httpRestResult = convert((RestResult<T>) extractBody);
|
|
||||||
httpRestResult.setHeader(headers);
|
|
||||||
return httpRestResult;
|
|
||||||
}
|
|
||||||
return new HttpRestResult<T>(response.getHeaders(), response.getStatusCode(), extractBody);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,11 @@ public class Header {
|
|||||||
|
|
||||||
private final Map<String, String> header;
|
private final Map<String, String> header;
|
||||||
|
|
||||||
|
private final Map<String, List<String>> originalResponseHeader;
|
||||||
|
|
||||||
private Header() {
|
private Header() {
|
||||||
header = new LinkedHashMap<String, String>();
|
header = new LinkedHashMap<String, String>();
|
||||||
|
originalResponseHeader = new LinkedHashMap<String, List<String>>();
|
||||||
addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_JSON);
|
addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_JSON);
|
||||||
addParam(HttpHeaderConsts.ACCEPT_CHARSET, "UTF-8");
|
addParam(HttpHeaderConsts.ACCEPT_CHARSET, "UTF-8");
|
||||||
addParam(HttpHeaderConsts.ACCEPT_ENCODING, "gzip");
|
addParam(HttpHeaderConsts.ACCEPT_ENCODING, "gzip");
|
||||||
@ -120,6 +123,31 @@ public class Header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set original format response header.
|
||||||
|
*
|
||||||
|
* <p>Currently only corresponds to the response header of JDK.
|
||||||
|
*
|
||||||
|
* @param headers original response header
|
||||||
|
*/
|
||||||
|
public void setOriginalResponseHeader(Map<String, List<String>> headers) {
|
||||||
|
this.originalResponseHeader.putAll(headers);
|
||||||
|
for (Map.Entry<String, List<String>> entry : this.originalResponseHeader.entrySet()) {
|
||||||
|
addParam(entry.getKey(), entry.getValue().get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get original format response header.
|
||||||
|
*
|
||||||
|
* <p>Currently only corresponds to the response header of JDK.
|
||||||
|
*
|
||||||
|
* @return Map original response header
|
||||||
|
*/
|
||||||
|
public Map<String, List<String>> getOriginalResponseHeader() {
|
||||||
|
return this.originalResponseHeader;
|
||||||
|
}
|
||||||
|
|
||||||
public String getCharset() {
|
public String getCharset() {
|
||||||
String acceptCharset = getValue(HttpHeaderConsts.ACCEPT_CHARSET);
|
String acceptCharset = getValue(HttpHeaderConsts.ACCEPT_CHARSET);
|
||||||
if (acceptCharset == null) {
|
if (acceptCharset == null) {
|
||||||
@ -145,6 +173,7 @@ public class Header {
|
|||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
header.clear();
|
header.clear();
|
||||||
|
originalResponseHeader.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.common.model;
|
package com.alibaba.nacos.common.model;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.http.HttpClientConfig;
|
||||||
import com.alibaba.nacos.common.http.param.Header;
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
import com.alibaba.nacos.common.http.param.Query;
|
import com.alibaba.nacos.common.http.param.Query;
|
||||||
|
|
||||||
@ -31,17 +32,27 @@ public class RequestHttpEntity {
|
|||||||
|
|
||||||
private final Header headers = Header.newInstance();
|
private final Header headers = Header.newInstance();
|
||||||
|
|
||||||
|
private final HttpClientConfig httpClientConfig;
|
||||||
|
|
||||||
private final Query query;
|
private final Query query;
|
||||||
|
|
||||||
private Object body;
|
private Object body;
|
||||||
|
|
||||||
public RequestHttpEntity(Header header, Query query) {
|
public RequestHttpEntity(Header header, Query query) {
|
||||||
handleHeader(header);
|
this(null, header, query);
|
||||||
this.query = query;
|
}
|
||||||
|
|
||||||
|
public RequestHttpEntity(HttpClientConfig httpClientConfig, Header header, Query query) {
|
||||||
|
this(httpClientConfig, header, query, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestHttpEntity(Header header, Query query, Object body) {
|
public RequestHttpEntity(Header header, Query query, Object body) {
|
||||||
|
this(null, header, query, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestHttpEntity(HttpClientConfig httpClientConfig, Header header, Query query, Object body) {
|
||||||
handleHeader(header);
|
handleHeader(header);
|
||||||
|
this.httpClientConfig = httpClientConfig;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
@ -65,6 +76,10 @@ public class RequestHttpEntity {
|
|||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HttpClientConfig getHttpClientConfig() {
|
||||||
|
return httpClientConfig;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEmptyBody() {
|
public boolean isEmptyBody() {
|
||||||
return body == null;
|
return body == null;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.common.notify;
|
package com.alibaba.nacos.common.notify;
|
||||||
|
|
||||||
import com.alibaba.nacos.api.exception.NacosException;
|
|
||||||
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
|
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
|
||||||
import com.alibaba.nacos.common.JustForTest;
|
import com.alibaba.nacos.common.JustForTest;
|
||||||
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
@ -291,7 +290,9 @@ public class NotifyCenter {
|
|||||||
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
||||||
return publisher.publish(event);
|
return publisher.publish(event);
|
||||||
}
|
}
|
||||||
throw new NoSuchElementException("There are no [" + topic + "] publishers for this event, please register");
|
|
||||||
|
LOGGER.warn("There are no [{}] publishers for this event, please register", topic);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -310,8 +311,7 @@ public class NotifyCenter {
|
|||||||
* @param eventType class Instances type of the event type.
|
* @param eventType class Instances type of the event type.
|
||||||
* @param queueMaxSize the publisher's queue max size.
|
* @param queueMaxSize the publisher's queue max size.
|
||||||
*/
|
*/
|
||||||
public static EventPublisher registerToPublisher(final Class<? extends Event> eventType, final int queueMaxSize)
|
public static EventPublisher registerToPublisher(final Class<? extends Event> eventType, final int queueMaxSize) {
|
||||||
throws NacosException {
|
|
||||||
if (ClassUtils.isAssignableFrom(SlowEvent.class, eventType)) {
|
if (ClassUtils.isAssignableFrom(SlowEvent.class, eventType)) {
|
||||||
return INSTANCE.sharePublisher;
|
return INSTANCE.sharePublisher;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.JavaType;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||||
@ -264,4 +265,14 @@ public final class JacksonUtils {
|
|||||||
public static JsonNode transferToJsonNode(Object obj) {
|
public static JsonNode transferToJsonNode(Object obj) {
|
||||||
return mapper.valueToTree(obj);
|
return mapper.valueToTree(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* construct java type -> Jackson Java Type.
|
||||||
|
*
|
||||||
|
* @param type java type
|
||||||
|
* @return JavaType {@link JavaType}
|
||||||
|
*/
|
||||||
|
public static JavaType constructJavaType(Type type) {
|
||||||
|
return mapper.constructType(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
public class NotifyCenterTest {
|
public class NotifyCenterTest {
|
||||||
|
|
||||||
private static class TestSlowEvent extends SlowEvent {
|
private static class TestSlowEvent extends SlowEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestEvent extends Event {
|
private static class TestEvent extends Event {
|
||||||
@ -330,9 +331,11 @@ public class NotifyCenterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class TestSlowEvent1 extends SlowEvent {
|
private static class TestSlowEvent1 extends SlowEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestSlowEvent2 extends SlowEvent {
|
private static class TestSlowEvent2 extends SlowEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -343,10 +346,10 @@ public class NotifyCenterTest {
|
|||||||
|
|
||||||
final AtomicInteger count1 = new AtomicInteger(0);
|
final AtomicInteger count1 = new AtomicInteger(0);
|
||||||
final AtomicInteger count2 = new AtomicInteger(0);
|
final AtomicInteger count2 = new AtomicInteger(0);
|
||||||
|
|
||||||
final CountDownLatch latch1 = new CountDownLatch(3);
|
final CountDownLatch latch1 = new CountDownLatch(3);
|
||||||
final CountDownLatch latch2 = new CountDownLatch(3);
|
final CountDownLatch latch2 = new CountDownLatch(3);
|
||||||
|
|
||||||
NotifyCenter.registerSubscriber(new Subscriber<TestSlowEvent1>() {
|
NotifyCenter.registerSubscriber(new Subscriber<TestSlowEvent1>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(TestSlowEvent1 event) {
|
public void onEvent(TestSlowEvent1 event) {
|
||||||
@ -365,7 +368,7 @@ public class NotifyCenterTest {
|
|||||||
public void onEvent(TestSlowEvent2 event) {
|
public void onEvent(TestSlowEvent2 event) {
|
||||||
count2.incrementAndGet();
|
count2.incrementAndGet();
|
||||||
latch2.countDown();
|
latch2.countDown();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -373,26 +376,28 @@ public class NotifyCenterTest {
|
|||||||
return TestSlowEvent2.class;
|
return TestSlowEvent2.class;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
Assert.assertTrue(NotifyCenter.publishEvent(new TestSlowEvent1()));
|
Assert.assertTrue(NotifyCenter.publishEvent(new TestSlowEvent1()));
|
||||||
Assert.assertTrue(NotifyCenter.publishEvent(new TestSlowEvent2()));
|
Assert.assertTrue(NotifyCenter.publishEvent(new TestSlowEvent2()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadUtils.sleep(2000L);
|
ThreadUtils.sleep(2000L);
|
||||||
|
|
||||||
latch1.await(3000L, TimeUnit.MILLISECONDS);
|
latch1.await(3000L, TimeUnit.MILLISECONDS);
|
||||||
latch2.await(3000L, TimeUnit.MILLISECONDS);
|
latch2.await(3000L, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
Assert.assertEquals(3, count1.get());
|
Assert.assertEquals(3, count1.get());
|
||||||
Assert.assertEquals(3, count2.get());
|
Assert.assertEquals(3, count2.get());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestSlowEvent3 extends SlowEvent {
|
private static class TestSlowEvent3 extends SlowEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestSlowEvent4 extends SlowEvent {
|
private static class TestSlowEvent4 extends SlowEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -408,7 +413,7 @@ public class NotifyCenterTest {
|
|||||||
final CountDownLatch latch2 = new CountDownLatch(3);
|
final CountDownLatch latch2 = new CountDownLatch(3);
|
||||||
|
|
||||||
NotifyCenter.registerSubscriber(new SmartSubscriber() {
|
NotifyCenter.registerSubscriber(new SmartSubscriber() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
if (event instanceof TestSlowEvent3) {
|
if (event instanceof TestSlowEvent3) {
|
||||||
@ -421,7 +426,7 @@ public class NotifyCenterTest {
|
|||||||
latch2.countDown();
|
latch2.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Class<? extends Event>> subscribeTypes() {
|
public List<Class<? extends Event>> subscribeTypes() {
|
||||||
List<Class<? extends Event>> subTypes = new ArrayList<Class<? extends Event>>();
|
List<Class<? extends Event>> subTypes = new ArrayList<Class<? extends Event>>();
|
||||||
@ -447,9 +452,11 @@ public class NotifyCenterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class TestSlowEvent5 extends SlowEvent {
|
private static class TestSlowEvent5 extends SlowEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestEvent6 extends Event {
|
private static class TestEvent6 extends Event {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -502,4 +509,16 @@ public class NotifyCenterTest {
|
|||||||
Assert.assertEquals(3, count2.get());
|
Assert.assertEquals(3, count2.get());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class TestEvent7 extends Event {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPublishEventByNoSubscriber() {
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
Assert.assertFalse(NotifyCenter.publishEvent(new TestEvent7()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package com.alibaba.nacos.config.server.controller;
|
|||||||
import com.alibaba.nacos.common.model.RestResult;
|
import com.alibaba.nacos.common.model.RestResult;
|
||||||
import com.alibaba.nacos.common.model.RestResultUtils;
|
import com.alibaba.nacos.common.model.RestResultUtils;
|
||||||
import com.alibaba.nacos.common.utils.Objects;
|
import com.alibaba.nacos.common.utils.Objects;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.config.server.constant.Constants;
|
import com.alibaba.nacos.config.server.constant.Constants;
|
||||||
import com.alibaba.nacos.config.server.model.event.DerbyImportEvent;
|
import com.alibaba.nacos.config.server.model.event.DerbyImportEvent;
|
||||||
import com.alibaba.nacos.config.server.service.datasource.DynamicDataSource;
|
import com.alibaba.nacos.config.server.service.datasource.DynamicDataSource;
|
||||||
@ -30,7 +31,6 @@ import com.alibaba.nacos.config.server.utils.LogUtil;
|
|||||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||||
import com.alibaba.nacos.core.auth.ActionTypes;
|
import com.alibaba.nacos.core.auth.ActionTypes;
|
||||||
import com.alibaba.nacos.core.auth.Secured;
|
import com.alibaba.nacos.core.auth.Secured;
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
import com.alibaba.nacos.core.utils.WebUtils;
|
import com.alibaba.nacos.core.utils.WebUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
package com.alibaba.nacos.config.server.filter;
|
package com.alibaba.nacos.config.server.filter;
|
||||||
|
|
||||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||||
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
|
import com.alibaba.nacos.common.notify.listener.SmartSubscriber;
|
||||||
import com.alibaba.nacos.config.server.constant.Constants;
|
import com.alibaba.nacos.config.server.constant.Constants;
|
||||||
import com.alibaba.nacos.config.server.model.event.RaftDbErrorEvent;
|
import com.alibaba.nacos.config.server.model.event.RaftDbErrorEvent;
|
||||||
import com.alibaba.nacos.config.server.model.event.RaftDbErrorRecoverEvent;
|
import com.alibaba.nacos.config.server.model.event.RaftDbErrorRecoverEvent;
|
||||||
@ -26,9 +29,6 @@ import com.alibaba.nacos.core.cluster.Member;
|
|||||||
import com.alibaba.nacos.core.cluster.MemberMetaDataConstants;
|
import com.alibaba.nacos.core.cluster.MemberMetaDataConstants;
|
||||||
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||||
import com.alibaba.nacos.core.code.ControllerMethodsCache;
|
import com.alibaba.nacos.core.code.ControllerMethodsCache;
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.SmartSubscribe;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@ -41,6 +41,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.AccessControlException;
|
import java.security.AccessControlException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,7 +120,7 @@ public class CurcuitFilter implements Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void registerSubscribe() {
|
private void registerSubscribe() {
|
||||||
NotifyCenter.registerSubscribe(new SmartSubscribe() {
|
NotifyCenter.registerSubscriber(new SmartSubscriber() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
@ -135,8 +136,8 @@ public class CurcuitFilter implements Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canNotify(Event event) {
|
public List<Class<? extends Event>> subscribeTypes() {
|
||||||
return (event instanceof RaftDbErrorEvent) || (event instanceof RaftDbErrorRecoverEvent);
|
return Arrays.asList(RaftDbErrorRecoverEvent.class, RaftDbErrorEvent.class);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.model.event;
|
package com.alibaba.nacos.config.server.model.event;
|
||||||
|
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event;
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,7 +24,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
public class ConfigDataChangeEvent implements Event {
|
public class ConfigDataChangeEvent extends Event {
|
||||||
|
|
||||||
public final boolean isBeta;
|
public final boolean isBeta;
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.model.event;
|
package com.alibaba.nacos.config.server.model.event;
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConfigDumpEvent.
|
* ConfigDumpEvent.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
public class ConfigDumpEvent implements Event {
|
public class ConfigDumpEvent extends Event {
|
||||||
|
|
||||||
private static final long serialVersionUID = -8776888606458370294L;
|
private static final long serialVersionUID = -8776888606458370294L;
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ public class ConfigDumpEvent implements Event {
|
|||||||
this.lastModifiedTs = lastModifiedTs;
|
this.lastModifiedTs = lastModifiedTs;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a configDumpEvent.
|
* Build a configDumpEvent.
|
||||||
*
|
*
|
||||||
|
@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.model.event;
|
package com.alibaba.nacos.config.server.model.event;
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.SlowEvent;
|
import com.alibaba.nacos.common.notify.SlowEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data import event.
|
* Data import event.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
public class DerbyImportEvent implements SlowEvent {
|
public class DerbyImportEvent extends SlowEvent {
|
||||||
|
|
||||||
private static final long serialVersionUID = 3299565864352399053L;
|
private static final long serialVersionUID = 3299565864352399053L;
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.model.event;
|
package com.alibaba.nacos.config.server.model.event;
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.SlowEvent;
|
import com.alibaba.nacos.common.notify.SlowEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DerbyLoadEvent.
|
* DerbyLoadEvent.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
public class DerbyLoadEvent implements SlowEvent {
|
public class DerbyLoadEvent extends SlowEvent {
|
||||||
|
|
||||||
public static final DerbyLoadEvent INSTANCE = new DerbyLoadEvent();
|
public static final DerbyLoadEvent INSTANCE = new DerbyLoadEvent();
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.model.event;
|
package com.alibaba.nacos.config.server.model.event;
|
||||||
|
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event;
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
public class LocalDataChangeEvent implements Event {
|
public class LocalDataChangeEvent extends Event {
|
||||||
|
|
||||||
public final String groupKey;
|
public final String groupKey;
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.model.event;
|
package com.alibaba.nacos.config.server.model.event;
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.SlowEvent;
|
import com.alibaba.nacos.common.notify.SlowEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RaftDBErrorEvent.
|
* RaftDBErrorEvent.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
public class RaftDbErrorEvent implements SlowEvent {
|
public class RaftDbErrorEvent extends SlowEvent {
|
||||||
|
|
||||||
private static final long serialVersionUID = 101591819161802336L;
|
private static final long serialVersionUID = 101591819161802336L;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
package com.alibaba.nacos.config.server.model.event;
|
package com.alibaba.nacos.config.server.model.event;
|
||||||
|
|
||||||
import com.alibaba.nacos.common.JustForTest;
|
import com.alibaba.nacos.common.JustForTest;
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RaftDBErrorRecoverEvent.
|
* RaftDBErrorRecoverEvent.
|
||||||
@ -25,6 +25,6 @@ import com.alibaba.nacos.core.notify.Event;
|
|||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
@JustForTest
|
@JustForTest
|
||||||
public class RaftDbErrorRecoverEvent implements Event {
|
public class RaftDbErrorRecoverEvent extends Event {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,13 +35,14 @@ public class MemoryMonitor {
|
|||||||
@Autowired
|
@Autowired
|
||||||
public MemoryMonitor(AsyncNotifyService notifySingleService) {
|
public MemoryMonitor(AsyncNotifyService notifySingleService) {
|
||||||
|
|
||||||
ConfigExecutor.scheduleWithFixedDelay(new PrintMemoryTask(), DELAY_SECONDS, DELAY_SECONDS, TimeUnit.SECONDS);
|
ConfigExecutor.scheduleConfigTask(new PrintMemoryTask(), DELAY_SECONDS, DELAY_SECONDS, TimeUnit.SECONDS);
|
||||||
|
|
||||||
ConfigExecutor.scheduleWithFixedDelay(new PrintGetConfigResponeTask(), DELAY_SECONDS, DELAY_SECONDS,
|
ConfigExecutor
|
||||||
TimeUnit.SECONDS);
|
.scheduleConfigTask(new PrintGetConfigResponeTask(), DELAY_SECONDS, DELAY_SECONDS, TimeUnit.SECONDS);
|
||||||
|
|
||||||
ConfigExecutor.scheduleWithFixedDelay(new NotifyTaskQueueMonitorTask(notifySingleService), DELAY_SECONDS,
|
ConfigExecutor
|
||||||
DELAY_SECONDS, TimeUnit.SECONDS);
|
.scheduleConfigTask(new NotifyTaskQueueMonitorTask(notifySingleService), DELAY_SECONDS, DELAY_SECONDS,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
package com.alibaba.nacos.config.server.monitor;
|
package com.alibaba.nacos.config.server.monitor;
|
||||||
|
|
||||||
import com.alibaba.nacos.config.server.service.notify.AsyncNotifyService;
|
import com.alibaba.nacos.config.server.service.notify.AsyncNotifyService;
|
||||||
|
import com.alibaba.nacos.config.server.utils.ConfigExecutor;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
||||||
|
|
||||||
import static com.alibaba.nacos.config.server.utils.LogUtil.MEMORY_LOG;
|
import static com.alibaba.nacos.config.server.utils.LogUtil.MEMORY_LOG;
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ public class NotifyTaskQueueMonitorTask implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int size = ((ScheduledThreadPoolExecutor) notifySingleService.getExecutor()).getQueue().size();
|
int size = ConfigExecutor.asyncNotifyQueueSize();
|
||||||
MEMORY_LOG.info("toNotifyTaskSize = {}", size);
|
MEMORY_LOG.info("toNotifyTaskSize = {}", size);
|
||||||
MetricsMonitor.getNotifyTaskMonitor().set(size);
|
MetricsMonitor.getNotifyTaskMonitor().set(size);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.service;
|
package com.alibaba.nacos.config.server.service;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||||
import com.alibaba.nacos.config.server.constant.Constants;
|
import com.alibaba.nacos.config.server.constant.Constants;
|
||||||
import com.alibaba.nacos.config.server.model.CacheItem;
|
import com.alibaba.nacos.config.server.model.CacheItem;
|
||||||
@ -26,7 +27,6 @@ import com.alibaba.nacos.config.server.utils.DiskUtil;
|
|||||||
import com.alibaba.nacos.config.server.utils.GroupKey;
|
import com.alibaba.nacos.config.server.utils.GroupKey;
|
||||||
import com.alibaba.nacos.config.server.utils.GroupKey2;
|
import com.alibaba.nacos.config.server.utils.GroupKey2;
|
||||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -67,12 +67,12 @@ public class ConfigCacheService {
|
|||||||
/**
|
/**
|
||||||
* Save config file and update md5 value in cache.
|
* Save config file and update md5 value in cache.
|
||||||
*
|
*
|
||||||
* @param dataId dataId string value.
|
* @param dataId dataId string value.
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @param content content string value.
|
* @param content content string value.
|
||||||
* @param lastModifiedTs lastModifiedTs.
|
* @param lastModifiedTs lastModifiedTs.
|
||||||
* @param type file type.
|
* @param type file type.
|
||||||
* @return dumpChange success or not.
|
* @return dumpChange success or not.
|
||||||
*/
|
*/
|
||||||
public static boolean dump(String dataId, String group, String tenant, String content, long lastModifiedTs,
|
public static boolean dump(String dataId, String group, String tenant, String content, long lastModifiedTs,
|
||||||
@ -120,12 +120,12 @@ public class ConfigCacheService {
|
|||||||
/**
|
/**
|
||||||
* Save config file and update md5 value in cache.
|
* Save config file and update md5 value in cache.
|
||||||
*
|
*
|
||||||
* @param dataId dataId string value.
|
* @param dataId dataId string value.
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @param content content string value.
|
* @param content content string value.
|
||||||
* @param lastModifiedTs lastModifiedTs.
|
* @param lastModifiedTs lastModifiedTs.
|
||||||
* @param betaIps betaIps string value.
|
* @param betaIps betaIps string value.
|
||||||
* @return dumpChange success or not.
|
* @return dumpChange success or not.
|
||||||
*/
|
*/
|
||||||
public static boolean dumpBeta(String dataId, String group, String tenant, String content, long lastModifiedTs,
|
public static boolean dumpBeta(String dataId, String group, String tenant, String content, long lastModifiedTs,
|
||||||
@ -165,12 +165,12 @@ public class ConfigCacheService {
|
|||||||
/**
|
/**
|
||||||
* Save config file and update md5 value in cache.
|
* Save config file and update md5 value in cache.
|
||||||
*
|
*
|
||||||
* @param dataId dataId string value.
|
* @param dataId dataId string value.
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @param content content string value.
|
* @param content content string value.
|
||||||
* @param lastModifiedTs lastModifiedTs.
|
* @param lastModifiedTs lastModifiedTs.
|
||||||
* @param tag tag string value.
|
* @param tag tag string value.
|
||||||
* @return dumpChange success or not.
|
* @return dumpChange success or not.
|
||||||
*/
|
*/
|
||||||
public static boolean dumpTag(String dataId, String group, String tenant, String tag, String content,
|
public static boolean dumpTag(String dataId, String group, String tenant, String tag, String content,
|
||||||
@ -209,10 +209,10 @@ public class ConfigCacheService {
|
|||||||
/**
|
/**
|
||||||
* Save config file and update md5 value in cache.
|
* Save config file and update md5 value in cache.
|
||||||
*
|
*
|
||||||
* @param dataId dataId string value.
|
* @param dataId dataId string value.
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @param content content string value.
|
* @param content content string value.
|
||||||
* @param lastModifiedTs lastModifiedTs.
|
* @param lastModifiedTs lastModifiedTs.
|
||||||
* @return dumpChange success or not.
|
* @return dumpChange success or not.
|
||||||
*/
|
*/
|
||||||
@ -313,6 +313,7 @@ public class ConfigCacheService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check md5.
|
* Check md5.
|
||||||
|
*
|
||||||
* @return return diff result list.
|
* @return return diff result list.
|
||||||
*/
|
*/
|
||||||
public static List<String> checkMd5() {
|
public static List<String> checkMd5() {
|
||||||
@ -343,20 +344,20 @@ public class ConfigCacheService {
|
|||||||
* Delete config file, and delete cache.
|
* Delete config file, and delete cache.
|
||||||
*
|
*
|
||||||
* @param dataId dataId string value.
|
* @param dataId dataId string value.
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @return remove success or not.
|
* @return remove success or not.
|
||||||
*/
|
*/
|
||||||
public static boolean remove(String dataId, String group, String tenant) {
|
public static boolean remove(String dataId, String group, String tenant) {
|
||||||
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
||||||
final int lockResult = tryWriteLock(groupKey);
|
final int lockResult = tryWriteLock(groupKey);
|
||||||
|
|
||||||
// If data is non-existent.
|
// If data is non-existent.
|
||||||
if (0 == lockResult) {
|
if (0 == lockResult) {
|
||||||
DUMP_LOG.info("[remove-ok] {} not exist.", groupKey);
|
DUMP_LOG.info("[remove-ok] {} not exist.", groupKey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to lock failed
|
// try to lock failed
|
||||||
if (lockResult < 0) {
|
if (lockResult < 0) {
|
||||||
DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey);
|
DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey);
|
||||||
@ -368,7 +369,7 @@ public class ConfigCacheService {
|
|||||||
DiskUtil.removeConfigInfo(dataId, group, tenant);
|
DiskUtil.removeConfigInfo(dataId, group, tenant);
|
||||||
}
|
}
|
||||||
CACHE.remove(groupKey);
|
CACHE.remove(groupKey);
|
||||||
EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey));
|
NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} finally {
|
} finally {
|
||||||
@ -380,7 +381,7 @@ public class ConfigCacheService {
|
|||||||
* Delete beta config file, and delete cache.
|
* Delete beta config file, and delete cache.
|
||||||
*
|
*
|
||||||
* @param dataId dataId string value.
|
* @param dataId dataId string value.
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @return remove success or not.
|
* @return remove success or not.
|
||||||
*/
|
*/
|
||||||
@ -393,7 +394,7 @@ public class ConfigCacheService {
|
|||||||
DUMP_LOG.info("[remove-ok] {} not exist.", groupKey);
|
DUMP_LOG.info("[remove-ok] {} not exist.", groupKey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to lock failed
|
// try to lock failed
|
||||||
if (lockResult < 0) {
|
if (lockResult < 0) {
|
||||||
DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey);
|
DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey);
|
||||||
@ -404,7 +405,7 @@ public class ConfigCacheService {
|
|||||||
if (!PropertyUtil.isDirectRead()) {
|
if (!PropertyUtil.isDirectRead()) {
|
||||||
DiskUtil.removeConfigInfo4Beta(dataId, group, tenant);
|
DiskUtil.removeConfigInfo4Beta(dataId, group, tenant);
|
||||||
}
|
}
|
||||||
EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, true, CACHE.get(groupKey).getIps4Beta()));
|
NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, true, CACHE.get(groupKey).getIps4Beta()));
|
||||||
CACHE.get(groupKey).setBeta(false);
|
CACHE.get(groupKey).setBeta(false);
|
||||||
CACHE.get(groupKey).setIps4Beta(null);
|
CACHE.get(groupKey).setIps4Beta(null);
|
||||||
CACHE.get(groupKey).setMd54Beta(Constants.NULL);
|
CACHE.get(groupKey).setMd54Beta(Constants.NULL);
|
||||||
@ -418,21 +419,21 @@ public class ConfigCacheService {
|
|||||||
* Delete tag config file, and delete cache.
|
* Delete tag config file, and delete cache.
|
||||||
*
|
*
|
||||||
* @param dataId dataId string value.
|
* @param dataId dataId string value.
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @param tag tag string value.
|
* @param tag tag string value.
|
||||||
* @return remove success or not.
|
* @return remove success or not.
|
||||||
*/
|
*/
|
||||||
public static boolean removeTag(String dataId, String group, String tenant, String tag) {
|
public static boolean removeTag(String dataId, String group, String tenant, String tag) {
|
||||||
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
final String groupKey = GroupKey2.getKey(dataId, group, tenant);
|
||||||
final int lockResult = tryWriteLock(groupKey);
|
final int lockResult = tryWriteLock(groupKey);
|
||||||
|
|
||||||
// If data is non-existent.
|
// If data is non-existent.
|
||||||
if (0 == lockResult) {
|
if (0 == lockResult) {
|
||||||
DUMP_LOG.info("[remove-ok] {} not exist.", groupKey);
|
DUMP_LOG.info("[remove-ok] {} not exist.", groupKey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to lock failed
|
// try to lock failed
|
||||||
if (lockResult < 0) {
|
if (lockResult < 0) {
|
||||||
DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey);
|
DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey);
|
||||||
@ -447,7 +448,7 @@ public class ConfigCacheService {
|
|||||||
CacheItem ci = CACHE.get(groupKey);
|
CacheItem ci = CACHE.get(groupKey);
|
||||||
ci.tagMd5.remove(tag);
|
ci.tagMd5.remove(tag);
|
||||||
ci.tagLastModifiedTs.remove(tag);
|
ci.tagLastModifiedTs.remove(tag);
|
||||||
EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, false, null, tag));
|
NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, false, null, tag));
|
||||||
return true;
|
return true;
|
||||||
} finally {
|
} finally {
|
||||||
releaseWriteLock(groupKey);
|
releaseWriteLock(groupKey);
|
||||||
@ -457,8 +458,8 @@ public class ConfigCacheService {
|
|||||||
/**
|
/**
|
||||||
* Update md5 value.
|
* Update md5 value.
|
||||||
*
|
*
|
||||||
* @param groupKey groupKey string value.
|
* @param groupKey groupKey string value.
|
||||||
* @param md5 md5 string value.
|
* @param md5 md5 string value.
|
||||||
* @param lastModifiedTs lastModifiedTs long value.
|
* @param lastModifiedTs lastModifiedTs long value.
|
||||||
*/
|
*/
|
||||||
public static void updateMd5(String groupKey, String md5, long lastModifiedTs) {
|
public static void updateMd5(String groupKey, String md5, long lastModifiedTs) {
|
||||||
@ -466,16 +467,16 @@ public class ConfigCacheService {
|
|||||||
if (cache.md5 == null || !cache.md5.equals(md5)) {
|
if (cache.md5 == null || !cache.md5.equals(md5)) {
|
||||||
cache.md5 = md5;
|
cache.md5 = md5;
|
||||||
cache.lastModifiedTs = lastModifiedTs;
|
cache.lastModifiedTs = lastModifiedTs;
|
||||||
EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey));
|
NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update Beta md5 value.
|
* Update Beta md5 value.
|
||||||
*
|
*
|
||||||
* @param groupKey groupKey string value.
|
* @param groupKey groupKey string value.
|
||||||
* @param md5 md5 string value.
|
* @param md5 md5 string value.
|
||||||
* @param ips4Beta ips4Beta List.
|
* @param ips4Beta ips4Beta List.
|
||||||
* @param lastModifiedTs lastModifiedTs long value.
|
* @param lastModifiedTs lastModifiedTs long value.
|
||||||
*/
|
*/
|
||||||
public static void updateBetaMd5(String groupKey, String md5, List<String> ips4Beta, long lastModifiedTs) {
|
public static void updateBetaMd5(String groupKey, String md5, List<String> ips4Beta, long lastModifiedTs) {
|
||||||
@ -485,16 +486,16 @@ public class ConfigCacheService {
|
|||||||
cache.md54Beta = md5;
|
cache.md54Beta = md5;
|
||||||
cache.lastModifiedTs4Beta = lastModifiedTs;
|
cache.lastModifiedTs4Beta = lastModifiedTs;
|
||||||
cache.ips4Beta = ips4Beta;
|
cache.ips4Beta = ips4Beta;
|
||||||
EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, true, ips4Beta));
|
NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, true, ips4Beta));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update tag md5 value.
|
* Update tag md5 value.
|
||||||
*
|
*
|
||||||
* @param groupKey groupKey string value.
|
* @param groupKey groupKey string value.
|
||||||
* @param tag tag string value.
|
* @param tag tag string value.
|
||||||
* @param md5 md5 string value.
|
* @param md5 md5 string value.
|
||||||
* @param lastModifiedTs lastModifiedTs long value.
|
* @param lastModifiedTs lastModifiedTs long value.
|
||||||
*/
|
*/
|
||||||
public static void updateTagMd5(String groupKey, String tag, String md5, long lastModifiedTs) {
|
public static void updateTagMd5(String groupKey, String tag, String md5, long lastModifiedTs) {
|
||||||
@ -510,13 +511,13 @@ public class ConfigCacheService {
|
|||||||
} else {
|
} else {
|
||||||
cache.tagLastModifiedTs.put(tag, lastModifiedTs);
|
cache.tagLastModifiedTs.put(tag, lastModifiedTs);
|
||||||
}
|
}
|
||||||
EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, false, null, tag));
|
NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, false, null, tag));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cache.tagMd5.get(tag) == null || !cache.tagMd5.get(tag).equals(md5)) {
|
if (cache.tagMd5.get(tag) == null || !cache.tagMd5.get(tag).equals(md5)) {
|
||||||
cache.tagMd5.put(tag, md5);
|
cache.tagMd5.put(tag, md5);
|
||||||
cache.tagLastModifiedTs.put(tag, lastModifiedTs);
|
cache.tagLastModifiedTs.put(tag, lastModifiedTs);
|
||||||
EventDispatcher.fireEvent(new LocalDataChangeEvent(groupKey, false, null, tag));
|
NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, false, null, tag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.service;
|
package com.alibaba.nacos.config.server.service;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
||||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher;
|
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,13 +30,14 @@ public class ConfigChangePublisher {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify ConfigChange.
|
* Notify ConfigChange.
|
||||||
|
*
|
||||||
* @param event ConfigDataChangeEvent instance.
|
* @param event ConfigDataChangeEvent instance.
|
||||||
*/
|
*/
|
||||||
public static void notifyConfigChange(ConfigDataChangeEvent event) {
|
public static void notifyConfigChange(ConfigDataChangeEvent event) {
|
||||||
if (PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode()) {
|
if (PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
EventDispatcher.fireEvent(event);
|
NotifyCenter.publishEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,17 +16,17 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.service;
|
package com.alibaba.nacos.config.server.service;
|
||||||
|
|
||||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
|
||||||
import com.alibaba.nacos.config.server.constant.Constants;
|
import com.alibaba.nacos.config.server.constant.Constants;
|
||||||
import com.alibaba.nacos.config.server.model.SampleResult;
|
import com.alibaba.nacos.config.server.model.SampleResult;
|
||||||
import com.alibaba.nacos.config.server.service.notify.NotifyService;
|
import com.alibaba.nacos.config.server.service.notify.NotifyService;
|
||||||
|
import com.alibaba.nacos.config.server.utils.ConfigExecutor;
|
||||||
import com.alibaba.nacos.config.server.utils.JSONUtils;
|
import com.alibaba.nacos.config.server.utils.JSONUtils;
|
||||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||||
import com.alibaba.nacos.core.cluster.Member;
|
import com.alibaba.nacos.core.cluster.Member;
|
||||||
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@ -37,18 +37,15 @@ import java.util.Collection;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletionService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CompletionService;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorCompletionService;
|
import java.util.concurrent.ExecutorCompletionService;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config sub service.
|
* Config sub service.
|
||||||
@ -58,24 +55,12 @@ import java.util.concurrent.ExecutorCompletionService;
|
|||||||
@Service
|
@Service
|
||||||
public class ConfigSubService {
|
public class ConfigSubService {
|
||||||
|
|
||||||
private ScheduledExecutorService scheduler;
|
|
||||||
|
|
||||||
private ServerMemberManager memberManager;
|
private ServerMemberManager memberManager;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
||||||
public ConfigSubService(ServerMemberManager memberManager) {
|
public ConfigSubService(ServerMemberManager memberManager) {
|
||||||
this.memberManager = memberManager;
|
this.memberManager = memberManager;
|
||||||
|
|
||||||
scheduler = Executors.newScheduledThreadPool(ThreadUtils.getSuitableThreadCount(), new ThreadFactory() {
|
|
||||||
@Override
|
|
||||||
public Thread newThread(Runnable r) {
|
|
||||||
Thread t = new Thread(r);
|
|
||||||
t.setDaemon(true);
|
|
||||||
t.setName("com.alibaba.nacos.ConfigSubService");
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ConfigSubService() {
|
protected ConfigSubService() {
|
||||||
@ -140,7 +125,7 @@ public class ConfigSubService {
|
|||||||
* Merge SampleResult.
|
* Merge SampleResult.
|
||||||
*
|
*
|
||||||
* @param sampleCollectResult sampleCollectResult.
|
* @param sampleCollectResult sampleCollectResult.
|
||||||
* @param sampleResults sampleResults.
|
* @param sampleResults sampleResults.
|
||||||
* @return SampleResult.
|
* @return SampleResult.
|
||||||
*/
|
*/
|
||||||
public SampleResult mergeSampleResult(SampleResult sampleCollectResult, List<SampleResult> sampleResults) {
|
public SampleResult mergeSampleResult(SampleResult sampleCollectResult, List<SampleResult> sampleResults) {
|
||||||
@ -195,7 +180,7 @@ public class ConfigSubService {
|
|||||||
String urlAll = getUrl(ip, url) + "?" + paramUrl;
|
String urlAll = getUrl(ip, url) + "?" + paramUrl;
|
||||||
com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult result = NotifyService
|
com.alibaba.nacos.config.server.service.notify.NotifyService.HttpResult result = NotifyService
|
||||||
.invokeURL(urlAll, null, Constants.ENCODE);
|
.invokeURL(urlAll, null, Constants.ENCODE);
|
||||||
|
|
||||||
// Http code 200
|
// Http code 200
|
||||||
if (result.code == HttpURLConnection.HTTP_OK) {
|
if (result.code == HttpURLConnection.HTTP_OK) {
|
||||||
String json = result.content;
|
String json = result.content;
|
||||||
@ -227,8 +212,8 @@ public class ConfigSubService {
|
|||||||
}
|
}
|
||||||
BlockingQueue<Future<SampleResult>> queue = new LinkedBlockingDeque<Future<SampleResult>>(
|
BlockingQueue<Future<SampleResult>> queue = new LinkedBlockingDeque<Future<SampleResult>>(
|
||||||
memberManager.getServerList().size());
|
memberManager.getServerList().size());
|
||||||
CompletionService<SampleResult> completionService = new ExecutorCompletionService<SampleResult>(scheduler,
|
CompletionService<SampleResult> completionService = new ExecutorCompletionService<SampleResult>(
|
||||||
queue);
|
ConfigExecutor.getConfigSubServiceExecutor(), queue);
|
||||||
|
|
||||||
SampleResult sampleCollectResult = new SampleResult();
|
SampleResult sampleCollectResult = new SampleResult();
|
||||||
for (int i = 0; i < sampleTime; i++) {
|
for (int i = 0; i < sampleTime; i++) {
|
||||||
@ -247,8 +232,8 @@ public class ConfigSubService {
|
|||||||
params.put("ip", ip);
|
params.put("ip", ip);
|
||||||
BlockingQueue<Future<SampleResult>> queue = new LinkedBlockingDeque<Future<SampleResult>>(
|
BlockingQueue<Future<SampleResult>> queue = new LinkedBlockingDeque<Future<SampleResult>>(
|
||||||
memberManager.getServerList().size());
|
memberManager.getServerList().size());
|
||||||
CompletionService<SampleResult> completionService = new ExecutorCompletionService<SampleResult>(scheduler,
|
CompletionService<SampleResult> completionService = new ExecutorCompletionService<SampleResult>(
|
||||||
queue);
|
ConfigExecutor.getConfigSubServiceExecutor(), queue);
|
||||||
|
|
||||||
SampleResult sampleCollectResult = new SampleResult();
|
SampleResult sampleCollectResult = new SampleResult();
|
||||||
for (int i = 0; i < sampleTime; i++) {
|
for (int i = 0; i < sampleTime; i++) {
|
||||||
|
@ -17,17 +17,20 @@
|
|||||||
package com.alibaba.nacos.config.server.service;
|
package com.alibaba.nacos.config.server.service;
|
||||||
|
|
||||||
import com.alibaba.nacos.api.config.remote.response.ConfigChangeNotifyResponse;
|
import com.alibaba.nacos.api.config.remote.response.ConfigChangeNotifyResponse;
|
||||||
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
import com.alibaba.nacos.common.utils.CollectionUtils;
|
import com.alibaba.nacos.common.utils.CollectionUtils;
|
||||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||||
import com.alibaba.nacos.config.server.model.SampleResult;
|
import com.alibaba.nacos.config.server.model.SampleResult;
|
||||||
import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent;
|
import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent;
|
||||||
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
|
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
|
||||||
|
import com.alibaba.nacos.config.server.utils.ConfigExecutor;
|
||||||
import com.alibaba.nacos.config.server.utils.GroupKey;
|
import com.alibaba.nacos.config.server.utils.GroupKey;
|
||||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.MD5Util;
|
import com.alibaba.nacos.config.server.utils.MD5Util;
|
||||||
import com.alibaba.nacos.config.server.utils.RequestUtil;
|
import com.alibaba.nacos.config.server.utils.RequestUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher.AbstractEventListener;
|
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event;
|
|
||||||
import com.alibaba.nacos.core.remote.DataChangeListenerNotifier;
|
import com.alibaba.nacos.core.remote.DataChangeListenerNotifier;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -48,10 +51,7 @@ import java.util.Queue;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static com.alibaba.nacos.config.server.utils.LogUtil.MEMORY_LOG;
|
import static com.alibaba.nacos.config.server.utils.LogUtil.MEMORY_LOG;
|
||||||
@ -63,7 +63,7 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.PULL_LOG;
|
|||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class LongPollingService extends AbstractEventListener {
|
public class LongPollingService {
|
||||||
|
|
||||||
private static final int FIXED_POLLING_INTERVAL_MS = 10000;
|
private static final int FIXED_POLLING_INTERVAL_MS = 10000;
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
String appName = req.getHeader(RequestUtil.CLIENT_APPNAME_HEADER);
|
String appName = req.getHeader(RequestUtil.CLIENT_APPNAME_HEADER);
|
||||||
String tag = req.getHeader("Vipserver-Tag");
|
String tag = req.getHeader("Vipserver-Tag");
|
||||||
int delayTime = SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500);
|
int delayTime = SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500);
|
||||||
|
|
||||||
// Add delay time for LoadBalance, and one response is returned 500 ms in advance to avoid client timeout.
|
// Add delay time for LoadBalance, and one response is returned 500 ms in advance to avoid client timeout.
|
||||||
long timeout = Math.max(10000, Long.parseLong(str) - delayTime);
|
long timeout = Math.max(10000, Long.parseLong(str) - delayTime);
|
||||||
if (isFixedPolling()) {
|
if (isFixedPolling()) {
|
||||||
@ -281,29 +281,10 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
// AsyncContext.setTimeout() is incorrect, Control by oneself
|
// AsyncContext.setTimeout() is incorrect, Control by oneself
|
||||||
asyncContext.setTimeout(0L);
|
asyncContext.setTimeout(0L);
|
||||||
|
|
||||||
scheduler.execute(
|
ConfigExecutor.executeLongPolling(
|
||||||
new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag));
|
new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Event>> interest() {
|
|
||||||
List<Class<? extends Event>> eventTypes = new ArrayList<Class<? extends Event>>();
|
|
||||||
eventTypes.add(LocalDataChangeEvent.class);
|
|
||||||
return eventTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEvent(Event event) {
|
|
||||||
if (isFixedPolling()) {
|
|
||||||
// Ignore.
|
|
||||||
} else {
|
|
||||||
if (event instanceof LocalDataChangeEvent) {
|
|
||||||
LocalDataChangeEvent evt = (LocalDataChangeEvent) event;
|
|
||||||
scheduler.execute(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSupportLongPolling(HttpServletRequest req) {
|
public static boolean isSupportLongPolling(HttpServletRequest req) {
|
||||||
return null != req.getHeader(LONG_POLLING_HEADER);
|
return null != req.getHeader(LONG_POLLING_HEADER);
|
||||||
}
|
}
|
||||||
@ -312,24 +293,38 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
public LongPollingService() {
|
public LongPollingService() {
|
||||||
allSubs = new ConcurrentLinkedQueue<ClientLongPolling>();
|
allSubs = new ConcurrentLinkedQueue<ClientLongPolling>();
|
||||||
|
|
||||||
scheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() {
|
ConfigExecutor.scheduleLongPolling(new StatTask(), 0L, 10L, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
// Register LocalDataChangeEvent to NotifyCenter.
|
||||||
|
NotifyCenter.registerToPublisher(LocalDataChangeEvent.class, NotifyCenter.ringBufferSize);
|
||||||
|
|
||||||
|
// Register A Subscriber to subscribe LocalDataChangeEvent.
|
||||||
|
NotifyCenter.registerSubscriber(new Subscriber() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Thread newThread(Runnable r) {
|
public void onEvent(Event event) {
|
||||||
Thread t = new Thread(r);
|
if (isFixedPolling()) {
|
||||||
t.setDaemon(true);
|
// Ignore.
|
||||||
t.setName("com.alibaba.nacos.LongPolling");
|
} else {
|
||||||
return t;
|
if (event instanceof LocalDataChangeEvent) {
|
||||||
|
LocalDataChangeEvent evt = (LocalDataChangeEvent) event;
|
||||||
|
ConfigExecutor.executeLongPolling(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Event> subscribeType() {
|
||||||
|
return LocalDataChangeEvent.class;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
scheduler.scheduleWithFixedDelay(new StatTask(), 0L, 10L, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String LONG_POLLING_HEADER = "Long-Pulling-Timeout";
|
public static final String LONG_POLLING_HEADER = "Long-Pulling-Timeout";
|
||||||
|
|
||||||
public static final String LONG_POLLING_NO_HANG_UP_HEADER = "Long-Pulling-Timeout-No-Hangup";
|
public static final String LONG_POLLING_NO_HANG_UP_HEADER = "Long-Pulling-Timeout-No-Hangup";
|
||||||
|
|
||||||
final ScheduledExecutorService scheduler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClientLongPolling subscibers.
|
* ClientLongPolling subscibers.
|
||||||
*/
|
*/
|
||||||
@ -413,12 +408,12 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
asyncTimeoutFuture = scheduler.schedule(new Runnable() {
|
asyncTimeoutFuture = ConfigExecutor.scheduleLongPolling(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
getRetainIps().put(ClientLongPolling.this.ip, System.currentTimeMillis());
|
getRetainIps().put(ClientLongPolling.this.ip, System.currentTimeMillis());
|
||||||
|
|
||||||
// Delete subsciber's relations.
|
// Delete subsciber's relations.
|
||||||
allSubs.remove(ClientLongPolling.this);
|
allSubs.remove(ClientLongPolling.this);
|
||||||
|
|
||||||
@ -454,7 +449,7 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendResponse(List<String> changedGroups) {
|
void sendResponse(List<String> changedGroups) {
|
||||||
|
|
||||||
// Cancel time out task.
|
// Cancel time out task.
|
||||||
if (null != asyncTimeoutFuture) {
|
if (null != asyncTimeoutFuture) {
|
||||||
asyncTimeoutFuture.cancel(false);
|
asyncTimeoutFuture.cancel(false);
|
||||||
@ -464,7 +459,7 @@ public class LongPollingService extends AbstractEventListener {
|
|||||||
|
|
||||||
void generateResponse(List<String> changedGroups) {
|
void generateResponse(List<String> changedGroups) {
|
||||||
if (null == changedGroups) {
|
if (null == changedGroups) {
|
||||||
|
|
||||||
// Tell web container to send http response.
|
// Tell web container to send http response.
|
||||||
asyncContext.complete();
|
asyncContext.complete();
|
||||||
return;
|
return;
|
||||||
|
@ -21,11 +21,11 @@ import com.alibaba.nacos.config.server.model.capacity.Capacity;
|
|||||||
import com.alibaba.nacos.config.server.model.capacity.GroupCapacity;
|
import com.alibaba.nacos.config.server.model.capacity.GroupCapacity;
|
||||||
import com.alibaba.nacos.config.server.model.capacity.TenantCapacity;
|
import com.alibaba.nacos.config.server.model.capacity.TenantCapacity;
|
||||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||||
|
import com.alibaba.nacos.config.server.utils.ConfigExecutor;
|
||||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -34,12 +34,8 @@ import org.springframework.dao.DuplicateKeyException;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.PreDestroy;
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,8 +62,6 @@ public class CapacityService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PersistService persistService;
|
private PersistService persistService;
|
||||||
|
|
||||||
private ScheduledExecutorService scheduledExecutorService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init.
|
* Init.
|
||||||
*/
|
*/
|
||||||
@ -75,10 +69,7 @@ public class CapacityService {
|
|||||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
||||||
public void init() {
|
public void init() {
|
||||||
// All servers have jobs that modify usage, idempotent.
|
// All servers have jobs that modify usage, idempotent.
|
||||||
ThreadFactory threadFactory = new ThreadFactoryBuilder()
|
ConfigExecutor.scheduleCorrectUsageTask(new Runnable() {
|
||||||
.setNameFormat("com.alibaba.nacos.CapacityManagement-%d").setDaemon(true).build();
|
|
||||||
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(threadFactory);
|
|
||||||
scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
LOGGER.info("[capacityManagement] start correct usage");
|
LOGGER.info("[capacityManagement] start correct usage");
|
||||||
@ -90,11 +81,6 @@ public class CapacityService {
|
|||||||
}, PropertyUtil.getCorrectUsageDelay(), PropertyUtil.getCorrectUsageDelay(), TimeUnit.SECONDS);
|
}, PropertyUtil.getCorrectUsageDelay(), PropertyUtil.getCorrectUsageDelay(), TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
|
||||||
public void destroy() {
|
|
||||||
scheduledExecutorService.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void correctUsage() {
|
public void correctUsage() {
|
||||||
correctGroupUsage();
|
correctGroupUsage();
|
||||||
correctTenantUsage();
|
correctTenantUsage();
|
||||||
@ -192,11 +178,10 @@ public class CapacityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To Cluster.
|
* To Cluster. 1.If the capacity information does not exist, initialize the capacity information. 2.Update capacity
|
||||||
* 1.If the capacity information does not exist, initialize the capacity information.
|
* usage, plus or minus one.
|
||||||
* 2.Update capacity usage, plus or minus one.
|
|
||||||
*
|
*
|
||||||
* @param counterMode increase or decrease mode.
|
* @param counterMode increase or decrease mode.
|
||||||
* @param ignoreQuotaLimit ignoreQuotaLimit flag.
|
* @param ignoreQuotaLimit ignoreQuotaLimit flag.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@ -215,12 +200,11 @@ public class CapacityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is used for counting when the limit check function of capacity management is turned off.
|
* It is used for counting when the limit check function of capacity management is turned off. 1.If the capacity
|
||||||
* 1.If the capacity information does not exist, initialize the capacity information.
|
* information does not exist, initialize the capacity information. 2.Update capacity usage, plus or minus one.
|
||||||
* 2.Update capacity usage, plus or minus one.
|
|
||||||
*
|
*
|
||||||
* @param counterMode increase or decrease mode.
|
* @param counterMode increase or decrease mode.
|
||||||
* @param group tenant string value.
|
* @param group tenant string value.
|
||||||
* @param ignoreQuotaLimit ignoreQuotaLimit flag.
|
* @param ignoreQuotaLimit ignoreQuotaLimit flag.
|
||||||
* @return operate successfully or not.
|
* @return operate successfully or not.
|
||||||
*/
|
*/
|
||||||
@ -260,8 +244,8 @@ public class CapacityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the capacity information of the group.
|
* Initialize the capacity information of the group. If the quota is reached, the capacity will be automatically
|
||||||
* If the quota is reached, the capacity will be automatically expanded to reduce the operation and maintenance cost.
|
* expanded to reduce the operation and maintenance cost.
|
||||||
*
|
*
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @return init result.
|
* @return init result.
|
||||||
@ -271,14 +255,14 @@ public class CapacityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the capacity information of the group. If the quota is reached,
|
* Initialize the capacity information of the group. If the quota is reached, the capacity will be automatically
|
||||||
* the capacity will be automatically expanded to reduce the operation and maintenance cost.
|
* expanded to reduce the operation and maintenance cost.
|
||||||
*
|
*
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param quota quota int value.
|
* @param quota quota int value.
|
||||||
* @param maxSize maxSize int value.
|
* @param maxSize maxSize int value.
|
||||||
* @param maxAggrCount maxAggrCount int value.
|
* @param maxAggrCount maxAggrCount int value.
|
||||||
* @param maxAggrSize maxAggrSize int value.
|
* @param maxAggrSize maxAggrSize int value.
|
||||||
* @return init result.
|
* @return init result.
|
||||||
*/
|
*/
|
||||||
private boolean initGroupCapacity(String group, Integer quota, Integer maxSize, Integer maxAggrCount,
|
private boolean initGroupCapacity(String group, Integer quota, Integer maxSize, Integer maxAggrCount,
|
||||||
@ -290,11 +274,11 @@ public class CapacityService {
|
|||||||
autoExpansion(group, null);
|
autoExpansion(group, null);
|
||||||
return insertSuccess;
|
return insertSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand capacity automatically.
|
* Expand capacity automatically.
|
||||||
*
|
*
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
*/
|
*/
|
||||||
private void autoExpansion(String group, String tenant) {
|
private void autoExpansion(String group, String tenant) {
|
||||||
@ -377,7 +361,7 @@ public class CapacityService {
|
|||||||
/**
|
/**
|
||||||
* Init capacity.
|
* Init capacity.
|
||||||
*
|
*
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @return init result.
|
* @return init result.
|
||||||
*/
|
*/
|
||||||
@ -423,12 +407,11 @@ public class CapacityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is used for counting when the limit check function of capacity management is turned off.
|
* It is used for counting when the limit check function of capacity management is turned off. 1.If the capacity
|
||||||
* 1.If the capacity information does not exist, initialize the capacity information.
|
* information does not exist, initialize the capacity information. 2.Update capacity usage, plus or minus one.
|
||||||
* 2.Update capacity usage, plus or minus one.
|
|
||||||
*
|
*
|
||||||
* @param counterMode increase or decrease mode.
|
* @param counterMode increase or decrease mode.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @param ignoreQuotaLimit ignoreQuotaLimit flag.
|
* @param ignoreQuotaLimit ignoreQuotaLimit flag.
|
||||||
* @return operate successfully or not.
|
* @return operate successfully or not.
|
||||||
*/
|
*/
|
||||||
@ -464,8 +447,8 @@ public class CapacityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the capacity information of the tenant. If the quota is reached,
|
* Initialize the capacity information of the tenant. If the quota is reached, the capacity will be automatically
|
||||||
* the capacity will be automatically expanded to reduce the operation and maintenance cos.
|
* expanded to reduce the operation and maintenance cos.
|
||||||
*
|
*
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @return init result.
|
* @return init result.
|
||||||
@ -475,14 +458,14 @@ public class CapacityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the capacity information of the tenant. If the quota is reached,
|
* Initialize the capacity information of the tenant. If the quota is reached, the capacity will be automatically
|
||||||
* the capacity will be automatically expanded to reduce the operation and maintenance cost
|
* expanded to reduce the operation and maintenance cost
|
||||||
*
|
*
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @param quota quota int value.
|
* @param quota quota int value.
|
||||||
* @param maxSize maxSize int value.
|
* @param maxSize maxSize int value.
|
||||||
* @param maxAggrCount maxAggrCount int value.
|
* @param maxAggrCount maxAggrCount int value.
|
||||||
* @param maxAggrSize maxAggrSize int value.
|
* @param maxAggrSize maxAggrSize int value.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean initTenantCapacity(String tenant, Integer quota, Integer maxSize, Integer maxAggrCount,
|
public boolean initTenantCapacity(String tenant, Integer quota, Integer maxSize, Integer maxAggrCount,
|
||||||
@ -530,15 +513,15 @@ public class CapacityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for API interface, Tenant: initialize if the record does not exist,
|
* Support for API interface, Tenant: initialize if the record does not exist, and update the capacity quota or
|
||||||
* and update the capacity quota or content size directly if it exists.
|
* content size directly if it exists.
|
||||||
*
|
*
|
||||||
* @param group group string value.
|
* @param group group string value.
|
||||||
* @param tenant tenant string value.
|
* @param tenant tenant string value.
|
||||||
* @param quota quota int value.
|
* @param quota quota int value.
|
||||||
* @param maxSize maxSize int value.
|
* @param maxSize maxSize int value.
|
||||||
* @param maxAggrCount maxAggrCount int value.
|
* @param maxAggrCount maxAggrCount int value.
|
||||||
* @param maxAggrSize maxAggrSize int value.
|
* @param maxAggrSize maxAggrSize int value.
|
||||||
* @return operate successfully or not.
|
* @return operate successfully or not.
|
||||||
*/
|
*/
|
||||||
public boolean insertOrUpdateCapacity(String group, String tenant, Integer quota, Integer maxSize,
|
public boolean insertOrUpdateCapacity(String group, String tenant, Integer quota, Integer maxSize,
|
||||||
|
@ -45,7 +45,7 @@ public class ExternalDataSourceProperties {
|
|||||||
|
|
||||||
public static final int DEFAULT_MAX_POOL_SIZE = 20;
|
public static final int DEFAULT_MAX_POOL_SIZE = 20;
|
||||||
|
|
||||||
public static final int DEFAULT_MINIMUM_IDLE = 50;
|
public static final int DEFAULT_MINIMUM_IDLE = 20;
|
||||||
|
|
||||||
private Integer num;
|
private Integer num;
|
||||||
|
|
||||||
|
@ -101,13 +101,13 @@ public class ExternalDataSourceServiceImpl implements DataSourceService {
|
|||||||
testMasterWritableJT.setQueryTimeout(1);
|
testMasterWritableJT.setQueryTimeout(1);
|
||||||
|
|
||||||
// Database health check
|
// Database health check
|
||||||
|
|
||||||
testJtList = new ArrayList<JdbcTemplate>();
|
testJtList = new ArrayList<JdbcTemplate>();
|
||||||
isHealthList = new ArrayList<Boolean>();
|
isHealthList = new ArrayList<Boolean>();
|
||||||
|
|
||||||
tm = new DataSourceTransactionManager();
|
tm = new DataSourceTransactionManager();
|
||||||
tjt = new TransactionTemplate(tm);
|
tjt = new TransactionTemplate(tm);
|
||||||
|
|
||||||
// Transaction timeout needs to be distinguished from ordinary operations.
|
// Transaction timeout needs to be distinguished from ordinary operations.
|
||||||
tjt.setTimeout(TRANSACTION_QUERY_TIMEOUT);
|
tjt.setTimeout(TRANSACTION_QUERY_TIMEOUT);
|
||||||
if (PropertyUtil.isUseExternalDB()) {
|
if (PropertyUtil.isUseExternalDB()) {
|
||||||
@ -118,8 +118,8 @@ public class ExternalDataSourceServiceImpl implements DataSourceService {
|
|||||||
throw new RuntimeException(DB_LOAD_ERROR_MSG);
|
throw new RuntimeException(DB_LOAD_ERROR_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigExecutor.scheduleWithFixedDelay(new SelectMasterTask(), 10, 10, TimeUnit.SECONDS);
|
ConfigExecutor.scheduleConfigTask(new SelectMasterTask(), 10, 10, TimeUnit.SECONDS);
|
||||||
ConfigExecutor.scheduleWithFixedDelay(new CheckDbHealthTask(), 10, 10, TimeUnit.SECONDS);
|
ConfigExecutor.scheduleConfigTask(new CheckDbHealthTask(), 10, 10, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,28 +17,27 @@
|
|||||||
package com.alibaba.nacos.config.server.service.dump;
|
package com.alibaba.nacos.config.server.service.dump;
|
||||||
|
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
import com.alibaba.nacos.config.server.model.event.ConfigDumpEvent;
|
import com.alibaba.nacos.config.server.model.event.ConfigDumpEvent;
|
||||||
import com.alibaba.nacos.config.server.service.AggrWhitelist;
|
import com.alibaba.nacos.config.server.service.AggrWhitelist;
|
||||||
import com.alibaba.nacos.config.server.service.ClientIpWhiteList;
|
import com.alibaba.nacos.config.server.service.ClientIpWhiteList;
|
||||||
import com.alibaba.nacos.config.server.service.ConfigCacheService;
|
import com.alibaba.nacos.config.server.service.ConfigCacheService;
|
||||||
import com.alibaba.nacos.config.server.service.SwitchService;
|
import com.alibaba.nacos.config.server.service.SwitchService;
|
||||||
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump config subscriber.
|
* Dump config subscriber.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
public class DumpConfigHandler implements Subscribe<ConfigDumpEvent> {
|
public class DumpConfigHandler extends Subscriber<ConfigDumpEvent> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* trigger config dump event.
|
* trigger config dump event.
|
||||||
*
|
*
|
||||||
* @param event {@link ConfigDumpEvent}
|
* @param event {@link ConfigDumpEvent}
|
||||||
* @return {@code true} if the config dump task success , else
|
* @return {@code true} if the config dump task success , else {@code false}
|
||||||
* {@code false}
|
|
||||||
*/
|
*/
|
||||||
public static boolean configDump(ConfigDumpEvent event) {
|
public static boolean configDump(ConfigDumpEvent event) {
|
||||||
final String dataId = event.getDataId();
|
final String dataId = event.getDataId();
|
||||||
|
@ -152,7 +152,8 @@ public abstract class DumpService {
|
|||||||
if (totalCount > 0) {
|
if (totalCount > 0) {
|
||||||
int pageSize = 1000;
|
int pageSize = 1000;
|
||||||
int removeTime = (totalCount + pageSize - 1) / pageSize;
|
int removeTime = (totalCount + pageSize - 1) / pageSize;
|
||||||
LOGGER.warn("clearConfigHistory, getBeforeStamp:{}, totalCount:{}, pageSize:{}, removeTime:{}",
|
LOGGER.warn(
|
||||||
|
"clearConfigHistory, getBeforeStamp:{}, totalCount:{}, pageSize:{}, removeTime:{}",
|
||||||
startTime, totalCount, pageSize, removeTime);
|
startTime, totalCount, pageSize, removeTime);
|
||||||
while (removeTime > 0) {
|
while (removeTime > 0) {
|
||||||
// delete paging to avoid reporting errors in batches
|
// delete paging to avoid reporting errors in batches
|
||||||
@ -212,22 +213,21 @@ public abstract class DumpService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfigExecutor.scheduleWithFixedDelay(heartbeat, 0, 10, TimeUnit.SECONDS);
|
ConfigExecutor.scheduleConfigTask(heartbeat, 0, 10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
long initialDelay = new Random().nextInt(INITIAL_DELAY_IN_MINUTE) + 10;
|
long initialDelay = new Random().nextInt(INITIAL_DELAY_IN_MINUTE) + 10;
|
||||||
LogUtil.DEFAULT_LOG.warn("initialDelay:{}", initialDelay);
|
LogUtil.DEFAULT_LOG.warn("initialDelay:{}", initialDelay);
|
||||||
|
|
||||||
|
ConfigExecutor.scheduleConfigTask(dumpAll, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES);
|
||||||
|
|
||||||
ConfigExecutor
|
ConfigExecutor
|
||||||
.scheduleWithFixedDelay(dumpAll, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES);
|
.scheduleConfigTask(dumpAllBeta, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES);
|
||||||
|
|
||||||
ConfigExecutor.scheduleWithFixedDelay(dumpAllBeta, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE,
|
ConfigExecutor
|
||||||
TimeUnit.MINUTES);
|
.scheduleConfigTask(dumpAllTag, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES);
|
||||||
|
|
||||||
ConfigExecutor.scheduleWithFixedDelay(dumpAllTag, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE,
|
|
||||||
TimeUnit.MINUTES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigExecutor.scheduleWithFixedDelay(clearConfigHistory, 10, 10, TimeUnit.MINUTES);
|
ConfigExecutor.scheduleConfigTask(clearConfigHistory, 10, 10, TimeUnit.MINUTES);
|
||||||
} finally {
|
} finally {
|
||||||
TimerContext.end(LogUtil.DUMP_LOG);
|
TimerContext.end(LogUtil.DUMP_LOG);
|
||||||
}
|
}
|
||||||
@ -276,7 +276,7 @@ public abstract class DumpService {
|
|||||||
}
|
}
|
||||||
LogUtil.DEFAULT_LOG.error("end checkMd5Task");
|
LogUtil.DEFAULT_LOG.error("end checkMd5Task");
|
||||||
};
|
};
|
||||||
ConfigExecutor.scheduleWithFixedDelay(checkMd5Task, 0, 12, TimeUnit.HOURS);
|
ConfigExecutor.scheduleConfigTask(checkMd5Task, 0, 12, TimeUnit.HOURS);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogUtil.FATAL_LOG.error("dump config fail" + e.getMessage());
|
LogUtil.FATAL_LOG.error("dump config fail" + e.getMessage());
|
||||||
@ -420,8 +420,9 @@ public abstract class DumpService {
|
|||||||
} else {
|
} else {
|
||||||
// remove config info
|
// remove config info
|
||||||
persistService.removeConfigInfo(dataId, group, tenant, InetUtils.getSelfIp(), null);
|
persistService.removeConfigInfo(dataId, group, tenant, InetUtils.getSelfIp(), null);
|
||||||
LOGGER.warn("[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId="
|
LOGGER.warn(
|
||||||
+ group);
|
"[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId="
|
||||||
|
+ group);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.service.merge;
|
package com.alibaba.nacos.config.server.service.merge;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.config.server.constant.Constants;
|
import com.alibaba.nacos.config.server.constant.Constants;
|
||||||
import com.alibaba.nacos.config.server.manager.AbstractTask;
|
import com.alibaba.nacos.config.server.manager.AbstractTask;
|
||||||
import com.alibaba.nacos.config.server.manager.TaskProcessor;
|
import com.alibaba.nacos.config.server.manager.TaskProcessor;
|
||||||
@ -27,7 +28,6 @@ import com.alibaba.nacos.config.server.service.repository.PersistService;
|
|||||||
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
||||||
import com.alibaba.nacos.config.server.utils.ContentUtils;
|
import com.alibaba.nacos.config.server.utils.ContentUtils;
|
||||||
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher;
|
|
||||||
import com.alibaba.nacos.core.utils.InetUtils;
|
import com.alibaba.nacos.core.utils.InetUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -79,8 +79,9 @@ public class MergeTaskProcessor implements TaskProcessor {
|
|||||||
|
|
||||||
persistService.insertOrUpdate(null, null, cf, time, null);
|
persistService.insertOrUpdate(null, null, cf, time, null);
|
||||||
|
|
||||||
LOGGER.info("[merge-ok] {}, {}, size={}, length={}, md5={}, content={}", dataId, group, datumList.size(),
|
LOGGER.info("[merge-ok] {}, {}, size={}, length={}, md5={}, content={}", dataId, group,
|
||||||
cf.getContent().length(), cf.getMd5(), ContentUtils.truncateContent(cf.getContent()));
|
datumList.size(), cf.getContent().length(), cf.getMd5(),
|
||||||
|
ContentUtils.truncateContent(cf.getContent()));
|
||||||
|
|
||||||
ConfigTraceService
|
ConfigTraceService
|
||||||
.logPersistenceEvent(dataId, group, tenant, null, time.getTime(), InetUtils.getSelfIp(),
|
.logPersistenceEvent(dataId, group, tenant, null, time.getTime(), InetUtils.getSelfIp(),
|
||||||
@ -93,14 +94,14 @@ public class MergeTaskProcessor implements TaskProcessor {
|
|||||||
persistService.removeConfigInfoTag(dataId, group, tenant, tag, clientIp, null);
|
persistService.removeConfigInfoTag(dataId, group, tenant, tag, clientIp, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.warn("[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId=" + group);
|
LOGGER.warn(
|
||||||
|
"[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId=" + group);
|
||||||
|
|
||||||
ConfigTraceService
|
ConfigTraceService
|
||||||
.logPersistenceEvent(dataId, group, tenant, null, time.getTime(), InetUtils.getSelfIp(),
|
.logPersistenceEvent(dataId, group, tenant, null, time.getTime(), InetUtils.getSelfIp(),
|
||||||
ConfigTraceService.PERSISTENCE_EVENT_REMOVE, null);
|
ConfigTraceService.PERSISTENCE_EVENT_REMOVE, null);
|
||||||
}
|
}
|
||||||
|
NotifyCenter.publishEvent(new ConfigDataChangeEvent(false, dataId, group, tenant, tag, time.getTime()));
|
||||||
EventDispatcher.fireEvent(new ConfigDataChangeEvent(false, dataId, group, tenant, tag, time.getTime()));
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
mergeService.addMergeTask(dataId, group, tenant, mergeTask.getClientIp());
|
mergeService.addMergeTask(dataId, group, tenant, mergeTask.getClientIp());
|
||||||
@ -113,9 +114,9 @@ public class MergeTaskProcessor implements TaskProcessor {
|
|||||||
/**
|
/**
|
||||||
* merge datumList {@link ConfigInfoAggr}.
|
* merge datumList {@link ConfigInfoAggr}.
|
||||||
*
|
*
|
||||||
* @param dataId data id
|
* @param dataId data id
|
||||||
* @param group group
|
* @param group group
|
||||||
* @param tenant tenant
|
* @param tenant tenant
|
||||||
* @param datumList datumList
|
* @param datumList datumList
|
||||||
* @return {@link ConfigInfo}
|
* @return {@link ConfigInfo}
|
||||||
*/
|
*/
|
||||||
|
@ -16,14 +16,16 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.service.notify;
|
package com.alibaba.nacos.config.server.service.notify;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
import com.alibaba.nacos.config.server.constant.Constants;
|
import com.alibaba.nacos.config.server.constant.Constants;
|
||||||
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
|
|
||||||
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
||||||
|
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
|
||||||
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
||||||
|
import com.alibaba.nacos.config.server.utils.ConfigExecutor;
|
||||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher.AbstractEventListener;
|
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event;
|
|
||||||
import com.alibaba.nacos.core.cluster.Member;
|
import com.alibaba.nacos.core.cluster.Member;
|
||||||
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
@ -45,15 +47,9 @@ import org.springframework.stereotype.Service;
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,51 +58,48 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* @author Nacos
|
* @author Nacos
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class AsyncNotifyService extends AbstractEventListener {
|
public class AsyncNotifyService {
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Event>> interest() {
|
|
||||||
List<Class<? extends Event>> types = new ArrayList<Class<? extends Event>>();
|
|
||||||
// Trigger configuration change synchronization notification
|
|
||||||
types.add(ConfigDataChangeEvent.class);
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEvent(Event event) {
|
|
||||||
|
|
||||||
// Generate ConfigDataChangeEvent concurrently
|
|
||||||
if (event instanceof ConfigDataChangeEvent) {
|
|
||||||
ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event;
|
|
||||||
long dumpTs = evt.lastModifiedTs;
|
|
||||||
String dataId = evt.dataId;
|
|
||||||
String group = evt.group;
|
|
||||||
String tenant = evt.tenant;
|
|
||||||
String tag = evt.tag;
|
|
||||||
Collection<Member> ipList = memberManager.allMembers();
|
|
||||||
|
|
||||||
// In fact, any type of queue here can be
|
|
||||||
Queue<NotifySingleTask> queue = new LinkedList<NotifySingleTask>();
|
|
||||||
for (Member member : ipList) {
|
|
||||||
queue.add(new NotifySingleTask(dataId, group, tenant, tag, dumpTs, member.getAddress(), evt.isBeta));
|
|
||||||
}
|
|
||||||
EXECUTOR.execute(new AsyncTask(httpclient, queue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public AsyncNotifyService(ServerMemberManager memberManager) {
|
public AsyncNotifyService(ServerMemberManager memberManager) {
|
||||||
this.memberManager = memberManager;
|
this.memberManager = memberManager;
|
||||||
httpclient.start();
|
httpclient.start();
|
||||||
|
|
||||||
|
// Register ConfigDataChangeEvent to NotifyCenter.
|
||||||
|
NotifyCenter.registerToPublisher(ConfigDataChangeEvent.class, NotifyCenter.ringBufferSize);
|
||||||
|
|
||||||
|
// Register A Subscriber to subscribe ConfigDataChangeEvent.
|
||||||
|
NotifyCenter.registerSubscriber(new Subscriber() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEvent(Event event) {
|
||||||
|
// Generate ConfigDataChangeEvent concurrently
|
||||||
|
if (event instanceof ConfigDataChangeEvent) {
|
||||||
|
ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event;
|
||||||
|
long dumpTs = evt.lastModifiedTs;
|
||||||
|
String dataId = evt.dataId;
|
||||||
|
String group = evt.group;
|
||||||
|
String tenant = evt.tenant;
|
||||||
|
String tag = evt.tag;
|
||||||
|
Collection<Member> ipList = memberManager.allMembers();
|
||||||
|
|
||||||
|
// In fact, any type of queue here can be
|
||||||
|
Queue<NotifySingleTask> queue = new LinkedList<NotifySingleTask>();
|
||||||
|
for (Member member : ipList) {
|
||||||
|
queue.add(new NotifySingleTask(dataId, group, tenant, tag, dumpTs, member.getAddress(),
|
||||||
|
evt.isBeta));
|
||||||
|
}
|
||||||
|
ConfigExecutor.executeAsyncNotify(new AsyncTask(httpclient, queue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Event> subscribeType() {
|
||||||
|
return ConfigDataChangeEvent.class;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Executor getExecutor() {
|
|
||||||
return EXECUTOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
|
||||||
private static final Executor EXECUTOR = Executors.newScheduledThreadPool(100, new NotifyThreadFactory());
|
|
||||||
|
|
||||||
private RequestConfig requestConfig = RequestConfig.custom()
|
private RequestConfig requestConfig = RequestConfig.custom()
|
||||||
.setConnectTimeout(PropertyUtil.getNotifyConnectTimeout())
|
.setConnectTimeout(PropertyUtil.getNotifyConnectTimeout())
|
||||||
.setSocketTimeout(PropertyUtil.getNotifySocketTimeout()).build();
|
.setSocketTimeout(PropertyUtil.getNotifySocketTimeout()).build();
|
||||||
@ -169,7 +162,7 @@ public class AsyncNotifyService extends AbstractEventListener {
|
|||||||
Queue<NotifySingleTask> queue = new LinkedList<NotifySingleTask>();
|
Queue<NotifySingleTask> queue = new LinkedList<NotifySingleTask>();
|
||||||
queue.add(task);
|
queue.add(task);
|
||||||
AsyncTask asyncTask = new AsyncTask(httpclient, queue);
|
AsyncTask asyncTask = new AsyncTask(httpclient, queue);
|
||||||
((ScheduledThreadPoolExecutor) EXECUTOR).schedule(asyncTask, delay, TimeUnit.MILLISECONDS);
|
ConfigExecutor.scheduleAsyncNotify(asyncTask, delay, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AsyncNotifyCallBack implements FutureCallback<HttpResponse> {
|
class AsyncNotifyCallBack implements FutureCallback<HttpResponse> {
|
||||||
@ -310,16 +303,6 @@ public class AsyncNotifyService extends AbstractEventListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class NotifyThreadFactory implements ThreadFactory {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Thread newThread(Runnable r) {
|
|
||||||
Thread thread = new Thread(r, "com.alibaba.nacos.AsyncNotifyServiceThread");
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get delayTime and also set failCount to task; The failure time index increases, so as not to retry invalid tasks
|
* get delayTime and also set failCount to task; The failure time index increases, so as not to retry invalid tasks
|
||||||
* in the offline scene, which affects the normal synchronization.
|
* in the offline scene, which affects the normal synchronization.
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.service.notify;
|
package com.alibaba.nacos.config.server.service.notify;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||||
|
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||||
import com.alibaba.nacos.config.server.manager.AbstractTask;
|
import com.alibaba.nacos.config.server.manager.AbstractTask;
|
||||||
import com.alibaba.nacos.config.server.utils.GroupKey2;
|
import com.alibaba.nacos.config.server.utils.GroupKey2;
|
||||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||||
@ -28,9 +30,7 @@ import java.util.Collection;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -102,22 +102,6 @@ public class NotifySingleService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class NotifyThreadFactory implements ThreadFactory {
|
|
||||||
|
|
||||||
private final String notifyTarget;
|
|
||||||
|
|
||||||
NotifyThreadFactory(String notifyTarget) {
|
|
||||||
this.notifyTarget = notifyTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Thread newThread(Runnable r) {
|
|
||||||
Thread thread = new Thread(r, "com.alibaba.nacos.NotifySingleServiceThread-" + notifyTarget);
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public NotifySingleService(ServerMemberManager memberManager) {
|
public NotifySingleService(ServerMemberManager memberManager) {
|
||||||
this.memberManager = memberManager;
|
this.memberManager = memberManager;
|
||||||
@ -141,8 +125,8 @@ public class NotifySingleService {
|
|||||||
* there will be no continuous task accumulation,
|
* there will be no continuous task accumulation,
|
||||||
* there is occasional instantaneous pressure)
|
* there is occasional instantaneous pressure)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("PMD.ThreadPoolCreationRule") Executor executor = Executors
|
Executor executor = ExecutorFactory.newSingleScheduledExecutorService(
|
||||||
.newScheduledThreadPool(1, new NotifyThreadFactory(address));
|
new NameThreadFactory("com.alibaba.nacos.config.NotifySingleServiceThread-" + address));
|
||||||
|
|
||||||
if (null == executors.putIfAbsent(address, executor)) {
|
if (null == executors.putIfAbsent(address, executor)) {
|
||||||
LOGGER.warn("[notify-thread-pool] setup thread target ip {} ok.", address);
|
LOGGER.warn("[notify-thread-pool] setup thread target ip {} ok.", address);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.service.repository.embedded;
|
package com.alibaba.nacos.config.server.service.repository.embedded;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.config.server.model.event.DerbyLoadEvent;
|
import com.alibaba.nacos.config.server.model.event.DerbyLoadEvent;
|
||||||
import com.alibaba.nacos.config.server.service.datasource.DataSourceService;
|
import com.alibaba.nacos.config.server.service.datasource.DataSourceService;
|
||||||
import com.alibaba.nacos.config.server.service.datasource.DynamicDataSource;
|
import com.alibaba.nacos.config.server.service.datasource.DynamicDataSource;
|
||||||
@ -27,7 +28,6 @@ import com.alibaba.nacos.consistency.snapshot.SnapshotOperation;
|
|||||||
import com.alibaba.nacos.consistency.snapshot.Writer;
|
import com.alibaba.nacos.consistency.snapshot.Writer;
|
||||||
import com.alibaba.nacos.core.distributed.raft.utils.RaftExecutor;
|
import com.alibaba.nacos.core.distributed.raft.utils.RaftExecutor;
|
||||||
import com.alibaba.nacos.core.utils.DiskUtils;
|
import com.alibaba.nacos.core.utils.DiskUtils;
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
import com.alibaba.nacos.core.utils.TimerContext;
|
import com.alibaba.nacos.core.utils.TimerContext;
|
||||||
import com.alipay.sofa.jraft.util.CRC64;
|
import com.alipay.sofa.jraft.util.CRC64;
|
||||||
|
@ -21,6 +21,9 @@ import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
|
|||||||
import com.alibaba.nacos.common.JustForTest;
|
import com.alibaba.nacos.common.JustForTest;
|
||||||
import com.alibaba.nacos.common.model.RestResult;
|
import com.alibaba.nacos.common.model.RestResult;
|
||||||
import com.alibaba.nacos.common.model.RestResultUtils;
|
import com.alibaba.nacos.common.model.RestResultUtils;
|
||||||
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
import com.alibaba.nacos.common.utils.LoggerUtils;
|
import com.alibaba.nacos.common.utils.LoggerUtils;
|
||||||
@ -53,9 +56,6 @@ import com.alibaba.nacos.consistency.exception.ConsistencyException;
|
|||||||
import com.alibaba.nacos.consistency.snapshot.SnapshotOperation;
|
import com.alibaba.nacos.consistency.snapshot.SnapshotOperation;
|
||||||
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||||
import com.alibaba.nacos.core.distributed.ProtocolManager;
|
import com.alibaba.nacos.core.distributed.ProtocolManager;
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
|
||||||
import com.alibaba.nacos.core.utils.ClassUtils;
|
import com.alibaba.nacos.core.utils.ClassUtils;
|
||||||
import com.alibaba.nacos.core.utils.DiskUtils;
|
import com.alibaba.nacos.core.utils.DiskUtils;
|
||||||
import com.alibaba.nacos.core.utils.GenericType;
|
import com.alibaba.nacos.core.utils.GenericType;
|
||||||
@ -190,7 +190,7 @@ public class DistributedDatabaseOperateImpl extends LogProcessor4CP implements B
|
|||||||
// Register the snapshot load event
|
// Register the snapshot load event
|
||||||
NotifyCenter.registerToSharePublisher(DerbyLoadEvent.class);
|
NotifyCenter.registerToSharePublisher(DerbyLoadEvent.class);
|
||||||
|
|
||||||
NotifyCenter.registerSubscribe(new Subscribe<RaftDbErrorEvent>() {
|
NotifyCenter.registerSubscriber(new Subscriber<RaftDbErrorEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(RaftDbErrorEvent event) {
|
public void onEvent(RaftDbErrorEvent event) {
|
||||||
dataSourceService.setHealthStatus("DOWN");
|
dataSourceService.setHealthStatus("DOWN");
|
||||||
@ -202,8 +202,8 @@ public class DistributedDatabaseOperateImpl extends LogProcessor4CP implements B
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
NotifyCenter.registerToPublisher(ConfigDumpEvent.class, NotifyCenter.RING_BUFFER_SIZE);
|
NotifyCenter.registerToPublisher(ConfigDumpEvent.class, NotifyCenter.ringBufferSize);
|
||||||
NotifyCenter.registerSubscribe(new DumpConfigHandler());
|
NotifyCenter.registerSubscriber(new DumpConfigHandler());
|
||||||
|
|
||||||
this.protocol.addLogProcessors(Collections.singletonList(this));
|
this.protocol.addLogProcessors(Collections.singletonList(this));
|
||||||
LogUtil.DEFAULT_LOG.info("use DistributedTransactionServicesImpl");
|
LogUtil.DEFAULT_LOG.info("use DistributedTransactionServicesImpl");
|
||||||
|
@ -18,6 +18,7 @@ package com.alibaba.nacos.config.server.service.repository.embedded;
|
|||||||
|
|
||||||
import com.alibaba.nacos.api.exception.NacosException;
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
|
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
|
||||||
import com.alibaba.nacos.config.server.constant.Constants;
|
import com.alibaba.nacos.config.server.constant.Constants;
|
||||||
import com.alibaba.nacos.config.server.enums.FileTypeEnum;
|
import com.alibaba.nacos.config.server.enums.FileTypeEnum;
|
||||||
@ -48,7 +49,6 @@ import com.alibaba.nacos.config.server.service.sql.EmbeddedStorageContextUtils;
|
|||||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.ParamUtils;
|
import com.alibaba.nacos.config.server.utils.ParamUtils;
|
||||||
import com.alibaba.nacos.core.distributed.id.IdGeneratorManager;
|
import com.alibaba.nacos.core.distributed.id.IdGeneratorManager;
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
@ -18,10 +18,14 @@ package com.alibaba.nacos.config.server.utils;
|
|||||||
|
|
||||||
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||||
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||||
|
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||||
import com.alibaba.nacos.config.server.Config;
|
import com.alibaba.nacos.config.server.Config;
|
||||||
|
import com.alibaba.nacos.core.utils.ClassUtils;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,15 +35,32 @@ import java.util.concurrent.TimeUnit;
|
|||||||
*/
|
*/
|
||||||
public final class ConfigExecutor {
|
public final class ConfigExecutor {
|
||||||
|
|
||||||
private static final Executor DUMP_EXECUTOR = ExecutorFactory
|
private static final Executor DUMP_EXECUTOR = ExecutorFactory.Managed
|
||||||
.newFixedExecutorService(Config.class.getCanonicalName(), 1,
|
.newSingleExecutorService(ClassUtils.getCanonicalName(Config.class),
|
||||||
new NameThreadFactory("nacos.config.embedded.dump"));
|
new NameThreadFactory("com.alibaba.nacos.config.embedded.dump"));
|
||||||
|
|
||||||
private static final ScheduledExecutorService TIMER_EXECUTOR = ExecutorFactory
|
private static final ScheduledExecutorService TIMER_EXECUTOR = ExecutorFactory.Managed
|
||||||
.newScheduledExecutorService(Config.class.getCanonicalName(), 10,
|
.newScheduledExecutorService(ClassUtils.getCanonicalName(Config.class), 10,
|
||||||
new NameThreadFactory("com.alibaba.nacos.server.Timer"));
|
new NameThreadFactory("com.alibaba.nacos.config.server.timer"));
|
||||||
|
|
||||||
public static void scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
|
private static final ScheduledExecutorService CAPACITY_MANAGEMENT_EXECUTOR = ExecutorFactory.Managed
|
||||||
|
.newSingleScheduledExecutorService(ClassUtils.getCanonicalName(Config.class),
|
||||||
|
new NameThreadFactory("com.alibaba.nacos.config.CapacityManagement"));
|
||||||
|
|
||||||
|
private static final ScheduledExecutorService ASYNC_NOTIFY_EXECUTOR = ExecutorFactory.Managed
|
||||||
|
.newScheduledExecutorService(ClassUtils.getCanonicalName(Config.class), 100,
|
||||||
|
new NameThreadFactory("com.alibaba.nacos.config.AsyncNotifyService"));
|
||||||
|
|
||||||
|
private static final ScheduledExecutorService CONFIG_SUB_SERVICE_EXECUTOR = ExecutorFactory.Managed
|
||||||
|
.newScheduledExecutorService(ClassUtils.getCanonicalName(Config.class),
|
||||||
|
ThreadUtils.getSuitableThreadCount(),
|
||||||
|
new NameThreadFactory("com.alibaba.nacos.config.ConfigSubService"));
|
||||||
|
|
||||||
|
private static final ScheduledExecutorService LONG_POLLING_EXECUTOR = ExecutorFactory.Managed
|
||||||
|
.newSingleScheduledExecutorService(ClassUtils.getCanonicalName(Config.class),
|
||||||
|
new NameThreadFactory("com.alibaba.nacos.config.LongPolling"));
|
||||||
|
|
||||||
|
public static void scheduleConfigTask(Runnable command, long initialDelay, long delay, TimeUnit unit) {
|
||||||
TIMER_EXECUTOR.scheduleWithFixedDelay(command, initialDelay, delay, unit);
|
TIMER_EXECUTOR.scheduleWithFixedDelay(command, initialDelay, delay, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,4 +68,35 @@ public final class ConfigExecutor {
|
|||||||
DUMP_EXECUTOR.execute(runnable);
|
DUMP_EXECUTOR.execute(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void scheduleCorrectUsageTask(Runnable runnable, long initialDelay, long delay, TimeUnit unit) {
|
||||||
|
CAPACITY_MANAGEMENT_EXECUTOR.scheduleWithFixedDelay(runnable, initialDelay, delay, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void executeAsyncNotify(Runnable runnable) {
|
||||||
|
ASYNC_NOTIFY_EXECUTOR.execute(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void scheduleAsyncNotify(Runnable command, long delay, TimeUnit unit) {
|
||||||
|
ASYNC_NOTIFY_EXECUTOR.schedule(command, delay, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int asyncNotifyQueueSize() {
|
||||||
|
return ((ScheduledThreadPoolExecutor) ASYNC_NOTIFY_EXECUTOR).getQueue().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScheduledExecutorService getConfigSubServiceExecutor() {
|
||||||
|
return CONFIG_SUB_SERVICE_EXECUTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void scheduleLongPolling(Runnable runnable, long initialDelay, long period, TimeUnit unit) {
|
||||||
|
LONG_POLLING_EXECUTOR.scheduleWithFixedDelay(runnable, initialDelay, period, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScheduledFuture<?> scheduleLongPolling(Runnable runnable, long period, TimeUnit unit) {
|
||||||
|
return LONG_POLLING_EXECUTOR.schedule(runnable, period, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void executeLongPolling(Runnable runnable) {
|
||||||
|
LONG_POLLING_EXECUTOR.execute(runnable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.utils;
|
package com.alibaba.nacos.config.server.utils;
|
||||||
|
|
||||||
import java.util.concurrent.Executors;
|
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||||
|
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||||
|
import com.alibaba.nacos.config.server.Config;
|
||||||
|
import com.alibaba.nacos.core.utils.ClassUtils;
|
||||||
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@ -37,18 +40,9 @@ public class SimpleFlowData {
|
|||||||
|
|
||||||
private int slotCount;
|
private int slotCount;
|
||||||
|
|
||||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
private ScheduledExecutorService timer = ExecutorFactory.Managed
|
||||||
private ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
|
.newSingleScheduledExecutorService(ClassUtils.getCanonicalName(Config.class),
|
||||||
|
new NameThreadFactory("com.alibaba.nacos.config.flow.control"));
|
||||||
@Override
|
|
||||||
public Thread newThread(Runnable r) {
|
|
||||||
Thread t = new Thread(r);
|
|
||||||
t.setName("nacos flow control thread");
|
|
||||||
t.setDaemon(true);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
public SimpleFlowData(int slotCount, int interval) {
|
public SimpleFlowData(int slotCount, int interval) {
|
||||||
this.slotCount = slotCount;
|
this.slotCount = slotCount;
|
||||||
|
@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.utils;
|
package com.alibaba.nacos.config.server.utils;
|
||||||
|
|
||||||
import java.util.concurrent.Executors;
|
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||||
|
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||||
|
import com.alibaba.nacos.config.server.Config;
|
||||||
|
import com.alibaba.nacos.core.utils.ClassUtils;
|
||||||
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@ -35,18 +38,9 @@ public class SimpleIpFlowData {
|
|||||||
|
|
||||||
private int averageCount;
|
private int averageCount;
|
||||||
|
|
||||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
private ScheduledExecutorService timer = ExecutorFactory.Managed
|
||||||
private ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
|
.newSingleScheduledExecutorService(ClassUtils.getCanonicalName(Config.class),
|
||||||
|
new NameThreadFactory("com.alibaba.nacos.config.flow.control.ip"));
|
||||||
@Override
|
|
||||||
public Thread newThread(Runnable r) {
|
|
||||||
Thread t = new Thread(r);
|
|
||||||
t.setName("nacos ip flow control thread");
|
|
||||||
t.setDaemon(true);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
class DefaultIpFlowDataManagerTask implements Runnable {
|
class DefaultIpFlowDataManagerTask implements Runnable {
|
||||||
|
|
||||||
|
@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.alibaba.nacos.config.server.utils.event;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event dispatcher.
|
|
||||||
*
|
|
||||||
* @author Nacos
|
|
||||||
*/
|
|
||||||
public class EventDispatcher {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* add event listener.
|
|
||||||
*/
|
|
||||||
public static void addEventListener(AbstractEventListener listener) {
|
|
||||||
for (Class<? extends Event> type : listener.interest()) {
|
|
||||||
getEntry(type).listeners.addIfAbsent(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fire event, notify listeners.
|
|
||||||
*/
|
|
||||||
public static void fireEvent(Event event) {
|
|
||||||
if (null == event) {
|
|
||||||
throw new IllegalArgumentException("event is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (AbstractEventListener listener : getEntry(event.getClass()).listeners) {
|
|
||||||
try {
|
|
||||||
listener.onEvent(event);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.error(e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For only test purpose.
|
|
||||||
*/
|
|
||||||
public static void clear() {
|
|
||||||
LISTENER_HUB.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get event listener for eventType. Add Entry if not exist.
|
|
||||||
*/
|
|
||||||
static Entry getEntry(Class<? extends Event> eventType) {
|
|
||||||
for (; ; ) {
|
|
||||||
for (Entry entry : LISTENER_HUB) {
|
|
||||||
if (entry.eventType == eventType) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Entry tmp = new Entry(eventType);
|
|
||||||
// false means already exists
|
|
||||||
if (LISTENER_HUB.addIfAbsent(tmp)) {
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Entry {
|
|
||||||
|
|
||||||
final Class<? extends Event> eventType;
|
|
||||||
|
|
||||||
final CopyOnWriteArrayList<AbstractEventListener> listeners;
|
|
||||||
|
|
||||||
Entry(Class<? extends Event> type) {
|
|
||||||
eventType = type;
|
|
||||||
listeners = new CopyOnWriteArrayList<AbstractEventListener>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (null == obj || obj.getClass() != getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return eventType == ((Entry) obj).eventType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return super.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(EventDispatcher.class);
|
|
||||||
|
|
||||||
static final CopyOnWriteArrayList<Entry> LISTENER_HUB = new CopyOnWriteArrayList<Entry>();
|
|
||||||
|
|
||||||
public interface Event {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract static class AbstractEventListener {
|
|
||||||
|
|
||||||
public AbstractEventListener() {
|
|
||||||
// automatic register
|
|
||||||
EventDispatcher.addEventListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of events of interest.
|
|
||||||
*
|
|
||||||
* @return event list
|
|
||||||
*/
|
|
||||||
public abstract List<Class<? extends Event>> interest();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle events.
|
|
||||||
*
|
|
||||||
* @param event event
|
|
||||||
*/
|
|
||||||
public abstract void onEvent(Event event);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -16,33 +16,35 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.config.server.service;
|
package com.alibaba.nacos.config.server.service;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
||||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher;
|
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
public class ConfigChangePublisherTest {
|
public class ConfigChangePublisherTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConfigChangeNotify() {
|
public void testConfigChangeNotify() throws InterruptedException {
|
||||||
|
|
||||||
AtomicReference<ConfigDataChangeEvent> reference = new AtomicReference<>();
|
AtomicReference<ConfigDataChangeEvent> reference = new AtomicReference<>();
|
||||||
|
|
||||||
EventDispatcher.addEventListener(new EventDispatcher.AbstractEventListener() {
|
NotifyCenter.registerToPublisher(ConfigDataChangeEvent.class, NotifyCenter.ringBufferSize);
|
||||||
|
NotifyCenter.registerSubscriber(new Subscriber() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Class<? extends EventDispatcher.Event>> interest() {
|
public void onEvent(Event event) {
|
||||||
return Collections.singletonList(ConfigDataChangeEvent.class);
|
reference.set((ConfigDataChangeEvent) event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(EventDispatcher.Event event) {
|
public Class<? extends Event> subscribeType() {
|
||||||
reference.set((ConfigDataChangeEvent) event);
|
return ConfigDataChangeEvent.class;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -52,33 +54,34 @@ public class ConfigChangePublisherTest {
|
|||||||
|
|
||||||
ConfigChangePublisher
|
ConfigChangePublisher
|
||||||
.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
||||||
|
Thread.sleep(2000);
|
||||||
Assert.assertNotNull(reference.get());
|
Assert.assertNotNull(reference.get());
|
||||||
reference.set(null);
|
reference.set(null);
|
||||||
|
|
||||||
// nacos is standalone mode and use external storage
|
// nacos is standalone mode and use external storage
|
||||||
ApplicationUtils.setIsStandalone(true);
|
ApplicationUtils.setIsStandalone(true);
|
||||||
PropertyUtil.setEmbeddedStorage(false);
|
PropertyUtil.setEmbeddedStorage(false);
|
||||||
|
|
||||||
ConfigChangePublisher
|
ConfigChangePublisher
|
||||||
.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
||||||
|
Thread.sleep(2000);
|
||||||
Assert.assertNotNull(reference.get());
|
Assert.assertNotNull(reference.get());
|
||||||
reference.set(null);
|
reference.set(null);
|
||||||
|
|
||||||
// nacos is cluster mode and use embedded storage
|
// nacos is cluster mode and use embedded storage
|
||||||
ApplicationUtils.setIsStandalone(false);
|
ApplicationUtils.setIsStandalone(false);
|
||||||
PropertyUtil.setEmbeddedStorage(true);
|
PropertyUtil.setEmbeddedStorage(true);
|
||||||
|
|
||||||
ConfigChangePublisher
|
ConfigChangePublisher
|
||||||
.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
||||||
|
Thread.sleep(2000);
|
||||||
Assert.assertNull(reference.get());
|
Assert.assertNull(reference.get());
|
||||||
reference.set(null);
|
reference.set(null);
|
||||||
|
|
||||||
// nacos is cluster mode and use external storage
|
// nacos is cluster mode and use external storage
|
||||||
ApplicationUtils.setIsStandalone(false);
|
ApplicationUtils.setIsStandalone(false);
|
||||||
PropertyUtil.setEmbeddedStorage(false);
|
PropertyUtil.setEmbeddedStorage(false);
|
||||||
|
|
||||||
ConfigChangePublisher
|
ConfigChangePublisher
|
||||||
.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
||||||
|
Thread.sleep(2000);
|
||||||
Assert.assertNotNull(reference.get());
|
Assert.assertNotNull(reference.get());
|
||||||
reference.set(null);
|
reference.set(null);
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,20 @@ public class ExternalDataSourcePropertiesTest {
|
|||||||
}));
|
}));
|
||||||
Assert.assertEquals(dataSources.size(), 2);
|
Assert.assertEquals(dataSources.size(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void externalDatasourceToAssertMinIdle() {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
environment.setProperty("db.num", "1");
|
||||||
|
environment.setProperty("db.user", USERNAME);
|
||||||
|
environment.setProperty("db.password", PASSWORD);
|
||||||
|
environment.setProperty("db.url.0", JDBC_URL);
|
||||||
|
List<HikariDataSource> dataSources = new ExternalDataSourceProperties().build(environment, (dataSource -> {
|
||||||
|
dataSource.validate();
|
||||||
|
Assert.assertEquals(dataSource.getMinimumIdle(), ExternalDataSourceProperties.DEFAULT_MINIMUM_IDLE);
|
||||||
|
}));
|
||||||
|
Assert.assertEquals(dataSources.size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void externalDatasourceFailureWithLarkInfo() {
|
public void externalDatasourceFailureWithLarkInfo() {
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.alibaba.nacos.config.server.utils.event;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher.AbstractEventListener;
|
|
||||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher.Event;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|
||||||
import org.springframework.test.context.web.WebAppConfiguration;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
|
||||||
@WebAppConfiguration
|
|
||||||
public class EventDispatcherTest {
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void after() {
|
|
||||||
EventDispatcher.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Test
|
|
||||||
public void testAddListener() throws Exception {
|
|
||||||
final AbstractEventListener listener = new MockListener();
|
|
||||||
|
|
||||||
int vusers = 1000;
|
|
||||||
final CountDownLatch latch = new CountDownLatch(vusers);
|
|
||||||
|
|
||||||
for (int i = 0; i < vusers; ++i) {
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
latch.countDown();
|
|
||||||
EventDispatcher.addEventListener(listener);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
latch.await();
|
|
||||||
assertEquals(1, EventDispatcher.LISTENER_HUB.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFireEvent() {
|
|
||||||
EventDispatcher.fireEvent(new MockEvent());
|
|
||||||
assertEquals(0, MockListener.count);
|
|
||||||
|
|
||||||
EventDispatcher.addEventListener(new MockListener());
|
|
||||||
|
|
||||||
EventDispatcher.fireEvent(new MockEvent());
|
|
||||||
assertEquals(1, MockListener.count);
|
|
||||||
|
|
||||||
EventDispatcher.fireEvent(new MockEvent());
|
|
||||||
assertEquals(2, MockListener.count);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class MockEvent implements Event {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class MockListener extends AbstractEventListener {
|
|
||||||
|
|
||||||
static int count = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Class<? extends Event>> interest() {
|
|
||||||
List<Class<? extends Event>> types = new ArrayList<Class<? extends Event>>();
|
|
||||||
types.add(MockEvent.class);
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEvent(Event event) {
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,15 +16,16 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.core.cluster;
|
package com.alibaba.nacos.core.cluster;
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node change listeners.
|
* Node change listeners.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
public interface MemberChangeListener extends Subscribe<MembersChangeEvent> {
|
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
||||||
|
public abstract class MemberChangeListener extends Subscriber<MembersChangeEvent> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return NodeChangeEvent.class info.
|
* return NodeChangeEvent.class info.
|
||||||
@ -32,7 +33,7 @@ public interface MemberChangeListener extends Subscribe<MembersChangeEvent> {
|
|||||||
* @return {@link MembersChangeEvent#getClass()}
|
* @return {@link MembersChangeEvent#getClass()}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
default Class<? extends Event> subscribeType() {
|
public Class<? extends Event> subscribeType() {
|
||||||
return MembersChangeEvent.class;
|
return MembersChangeEvent.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ public interface MemberChangeListener extends Subscribe<MembersChangeEvent> {
|
|||||||
* @return default value is {@link Boolean#TRUE}
|
* @return default value is {@link Boolean#TRUE}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
default boolean ignoreExpireEvent() {
|
public boolean ignoreExpireEvent() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,9 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.core.cluster;
|
package com.alibaba.nacos.core.cluster;
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish this event when the node list changes,All interested in the node list change event can listen to this event.
|
* Publish this event when the node list changes,All interested in the node list change event can listen to this event.
|
||||||
@ -32,16 +31,12 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
public class MembersChangeEvent implements Event {
|
public class MembersChangeEvent extends Event {
|
||||||
|
|
||||||
private static final AtomicLong SEQUENCE = new AtomicLong(0);
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 7308126651076668976L;
|
private static final long serialVersionUID = 7308126651076668976L;
|
||||||
|
|
||||||
private Collection<Member> members;
|
private Collection<Member> members;
|
||||||
|
|
||||||
private long no = SEQUENCE.getAndIncrement();
|
|
||||||
|
|
||||||
public static MemberChangeEventBuilder builder() {
|
public static MemberChangeEventBuilder builder() {
|
||||||
return new MemberChangeEventBuilder();
|
return new MemberChangeEventBuilder();
|
||||||
}
|
}
|
||||||
@ -54,14 +49,9 @@ public class MembersChangeEvent implements Event {
|
|||||||
this.members = members;
|
this.members = members;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long sequence() {
|
|
||||||
return no;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "MembersChangeEvent{" + "members=" + members + ", no=" + no + '}';
|
return "MembersChangeEvent{" + "members=" + members + ", no=" + sequence() + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class MemberChangeEventBuilder {
|
public static final class MemberChangeEventBuilder {
|
||||||
|
@ -25,13 +25,13 @@ import com.alibaba.nacos.common.http.NAsyncHttpClient;
|
|||||||
import com.alibaba.nacos.common.http.param.Header;
|
import com.alibaba.nacos.common.http.param.Header;
|
||||||
import com.alibaba.nacos.common.http.param.Query;
|
import com.alibaba.nacos.common.http.param.Query;
|
||||||
import com.alibaba.nacos.common.model.RestResult;
|
import com.alibaba.nacos.common.model.RestResult;
|
||||||
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
|
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
|
||||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||||
import com.alibaba.nacos.common.utils.VersionUtils;
|
import com.alibaba.nacos.common.utils.VersionUtils;
|
||||||
import com.alibaba.nacos.core.cluster.lookup.LookupFactory;
|
import com.alibaba.nacos.core.cluster.lookup.LookupFactory;
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
import com.alibaba.nacos.core.utils.Commons;
|
import com.alibaba.nacos.core.utils.Commons;
|
||||||
import com.alibaba.nacos.core.utils.Constants;
|
import com.alibaba.nacos.core.utils.Constants;
|
||||||
@ -166,7 +166,7 @@ public class ServerMemberManager implements ApplicationListener<WebServerInitial
|
|||||||
|
|
||||||
// The address information of this node needs to be dynamically modified
|
// The address information of this node needs to be dynamically modified
|
||||||
// when registering the IP change of this node
|
// when registering the IP change of this node
|
||||||
NotifyCenter.registerSubscribe(new Subscribe<InetUtils.IPChangeEvent>() {
|
NotifyCenter.registerSubscriber(new Subscriber<InetUtils.IPChangeEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(InetUtils.IPChangeEvent event) {
|
public void onEvent(InetUtils.IPChangeEvent event) {
|
||||||
String newAddress = event.getNewIp() + ":" + port;
|
String newAddress = event.getNewIp() + ":" + port;
|
||||||
|
@ -20,8 +20,8 @@ import com.alibaba.nacos.common.executor.ExecutorFactory;
|
|||||||
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||||
import com.alibaba.nacos.common.executor.ThreadPoolManager;
|
import com.alibaba.nacos.common.executor.ThreadPoolManager;
|
||||||
import com.alibaba.nacos.common.http.HttpClientManager;
|
import com.alibaba.nacos.common.http.HttpClientManager;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.core.file.WatchFileCenter;
|
import com.alibaba.nacos.core.file.WatchFileCenter;
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
import com.alibaba.nacos.core.utils.DiskUtils;
|
import com.alibaba.nacos.core.utils.DiskUtils;
|
||||||
import com.alibaba.nacos.core.utils.InetUtils;
|
import com.alibaba.nacos.core.utils.InetUtils;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.core.distributed;
|
package com.alibaba.nacos.core.distributed;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.consistency.Config;
|
import com.alibaba.nacos.consistency.Config;
|
||||||
import com.alibaba.nacos.consistency.ap.APProtocol;
|
import com.alibaba.nacos.consistency.ap.APProtocol;
|
||||||
import com.alibaba.nacos.consistency.cp.CPProtocol;
|
import com.alibaba.nacos.consistency.cp.CPProtocol;
|
||||||
@ -25,7 +26,6 @@ import com.alibaba.nacos.core.cluster.MemberChangeListener;
|
|||||||
import com.alibaba.nacos.core.cluster.MemberMetaDataConstants;
|
import com.alibaba.nacos.core.cluster.MemberMetaDataConstants;
|
||||||
import com.alibaba.nacos.core.cluster.MemberUtils;
|
import com.alibaba.nacos.core.cluster.MemberUtils;
|
||||||
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
import com.alibaba.nacos.core.utils.ClassUtils;
|
import com.alibaba.nacos.core.utils.ClassUtils;
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
@ -49,7 +49,7 @@ import java.util.Set;
|
|||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@Component(value = "ProtocolManager")
|
@Component(value = "ProtocolManager")
|
||||||
@DependsOn("serverMemberManager")
|
@DependsOn("serverMemberManager")
|
||||||
public class ProtocolManager implements ApplicationListener<ContextStartedEvent>, DisposableBean, MemberChangeListener {
|
public class ProtocolManager extends MemberChangeListener implements ApplicationListener<ContextStartedEvent>, DisposableBean {
|
||||||
|
|
||||||
private CPProtocol cpProtocol;
|
private CPProtocol cpProtocol;
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ public class ProtocolManager implements ApplicationListener<ContextStartedEvent>
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
this.memberManager = memberManager;
|
this.memberManager = memberManager;
|
||||||
NotifyCenter.registerSubscribe(this);
|
NotifyCenter.registerSubscriber(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CPProtocol getCpProtocol() {
|
public CPProtocol getCpProtocol() {
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
package com.alibaba.nacos.core.distributed.raft;
|
package com.alibaba.nacos.core.distributed.raft;
|
||||||
|
|
||||||
import com.alibaba.nacos.common.model.RestResult;
|
import com.alibaba.nacos.common.model.RestResult;
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
|
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||||
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
import com.alibaba.nacos.common.utils.MapUtils;
|
import com.alibaba.nacos.common.utils.MapUtils;
|
||||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||||
import com.alibaba.nacos.consistency.ProtocolMetaData;
|
import com.alibaba.nacos.consistency.ProtocolMetaData;
|
||||||
@ -32,9 +35,6 @@ import com.alibaba.nacos.core.cluster.Member;
|
|||||||
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||||
import com.alibaba.nacos.core.distributed.AbstractConsistencyProtocol;
|
import com.alibaba.nacos.core.distributed.AbstractConsistencyProtocol;
|
||||||
import com.alibaba.nacos.core.distributed.raft.exception.NoSuchRaftGroupException;
|
import com.alibaba.nacos.core.distributed.raft.exception.NoSuchRaftGroupException;
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
|
||||||
import com.alibaba.nacos.core.utils.Loggers;
|
import com.alibaba.nacos.core.utils.Loggers;
|
||||||
import com.alipay.sofa.jraft.Node;
|
import com.alipay.sofa.jraft.Node;
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ public class JRaftProtocol extends AbstractConsistencyProtocol<RaftConfig, LogPr
|
|||||||
|
|
||||||
// There is only one consumer to ensure that the internal consumption
|
// There is only one consumer to ensure that the internal consumption
|
||||||
// is sequential and there is no concurrent competition
|
// is sequential and there is no concurrent competition
|
||||||
NotifyCenter.registerSubscribe(new Subscribe<RaftEvent>() {
|
NotifyCenter.registerSubscriber(new Subscriber<RaftEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(RaftEvent event) {
|
public void onEvent(RaftEvent event) {
|
||||||
Loggers.RAFT.info("This Raft event changes : {}", event);
|
Loggers.RAFT.info("This Raft event changes : {}", event);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.core.distributed.raft;
|
package com.alibaba.nacos.core.distributed.raft;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
import com.alibaba.nacos.common.utils.LoggerUtils;
|
import com.alibaba.nacos.common.utils.LoggerUtils;
|
||||||
@ -30,7 +31,6 @@ import com.alibaba.nacos.consistency.snapshot.Reader;
|
|||||||
import com.alibaba.nacos.consistency.snapshot.SnapshotOperation;
|
import com.alibaba.nacos.consistency.snapshot.SnapshotOperation;
|
||||||
import com.alibaba.nacos.consistency.snapshot.Writer;
|
import com.alibaba.nacos.consistency.snapshot.Writer;
|
||||||
import com.alibaba.nacos.core.distributed.raft.utils.JRaftUtils;
|
import com.alibaba.nacos.core.distributed.raft.utils.JRaftUtils;
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.utils.Loggers;
|
import com.alibaba.nacos.core.utils.Loggers;
|
||||||
import com.alipay.sofa.jraft.Closure;
|
import com.alipay.sofa.jraft.Closure;
|
||||||
import com.alipay.sofa.jraft.Iterator;
|
import com.alipay.sofa.jraft.Iterator;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.core.distributed.raft;
|
package com.alibaba.nacos.core.distributed.raft;
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
import com.alibaba.nacos.common.notify.Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The RAFT protocol runs an exception event. If this event is published, it means that the current raft Group cannot
|
* The RAFT protocol runs an exception event. If this event is published, it means that the current raft Group cannot
|
||||||
@ -24,7 +24,7 @@ import com.alibaba.nacos.core.notify.Event;
|
|||||||
*
|
*
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
public class RaftErrorEvent implements Event {
|
public class RaftErrorEvent extends Event {
|
||||||
|
|
||||||
private static final long serialVersionUID = 3016514657754158167L;
|
private static final long serialVersionUID = 3016514657754158167L;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.core.distributed.raft;
|
package com.alibaba.nacos.core.distributed.raft;
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.SlowEvent;
|
import com.alibaba.nacos.common.notify.SlowEvent;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -27,7 +27,7 @@ import java.util.List;
|
|||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public class RaftEvent implements SlowEvent {
|
public class RaftEvent extends SlowEvent {
|
||||||
|
|
||||||
private static final long serialVersionUID = -4304258594602886451L;
|
private static final long serialVersionUID = -4304258594602886451L;
|
||||||
|
|
||||||
|
@ -1,211 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.alibaba.nacos.core.notify;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
|
|
||||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.SmartSubscribe;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
|
||||||
|
|
||||||
import static com.alibaba.nacos.core.notify.NotifyCenter.RING_BUFFER_SIZE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default event publisher implementation. Internally, use {@link ArrayBlockingQueue} as a message staging queue
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
|
||||||
*/
|
|
||||||
public class DefaultPublisher extends Thread implements EventPublisher {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(NotifyCenter.class);
|
|
||||||
|
|
||||||
private final ConcurrentHashSet<Subscribe> subscribes = new ConcurrentHashSet<>();
|
|
||||||
|
|
||||||
private final AtomicReferenceFieldUpdater<DefaultPublisher, Long> updater = AtomicReferenceFieldUpdater
|
|
||||||
.newUpdater(DefaultPublisher.class, Long.class, "lastEventSequence");
|
|
||||||
|
|
||||||
private volatile boolean initialized = false;
|
|
||||||
|
|
||||||
private volatile boolean canOpen = false;
|
|
||||||
|
|
||||||
private volatile boolean shutdown = false;
|
|
||||||
|
|
||||||
private Class<? extends Event> eventType;
|
|
||||||
|
|
||||||
private int queueMaxSize = -1;
|
|
||||||
|
|
||||||
private BlockingQueue<Event> queue;
|
|
||||||
|
|
||||||
private volatile Long lastEventSequence = -1L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Class<? extends Event> type, int bufferSize) {
|
|
||||||
setDaemon(true);
|
|
||||||
setName("nacos.publisher-" + type.getName());
|
|
||||||
this.eventType = type;
|
|
||||||
this.queueMaxSize = bufferSize;
|
|
||||||
this.queue = new ArrayBlockingQueue<>(bufferSize);
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConcurrentHashSet<Subscribe> getSubscribes() {
|
|
||||||
return subscribes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void start() {
|
|
||||||
super.start();
|
|
||||||
if (!initialized) {
|
|
||||||
if (queueMaxSize == -1) {
|
|
||||||
queueMaxSize = RING_BUFFER_SIZE;
|
|
||||||
}
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long currentEventSize() {
|
|
||||||
return queue.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
openEventHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
void openEventHandler() {
|
|
||||||
try {
|
|
||||||
int waitTimes = 60;
|
|
||||||
// To ensure that messages are not lost, enable EventHandler when
|
|
||||||
// waiting for the first Subscriber to register
|
|
||||||
for (; ; ) {
|
|
||||||
if (shutdown || canOpen || waitTimes <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ThreadUtils.sleep(1_000L);
|
|
||||||
waitTimes--;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; ; ) {
|
|
||||||
if (shutdown) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
final Event event = queue.take();
|
|
||||||
receiveEvent(event);
|
|
||||||
updater.compareAndSet(this, lastEventSequence, Math.max(lastEventSequence, event.sequence()));
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
LOGGER.error("Event listener exception : {}", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addSubscribe(Subscribe subscribe) {
|
|
||||||
subscribes.add(subscribe);
|
|
||||||
canOpen = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unSubscribe(Subscribe subscribe) {
|
|
||||||
subscribes.remove(subscribe);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean publish(Event event) {
|
|
||||||
checkIsStart();
|
|
||||||
boolean success = this.queue.offer(event);
|
|
||||||
if (!success) {
|
|
||||||
LOGGER.warn("Unable to plug in due to interruption, synchronize sending time, event : {}", event);
|
|
||||||
receiveEvent(event);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkIsStart() {
|
|
||||||
if (!initialized) {
|
|
||||||
throw new IllegalStateException("Publisher does not start");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void shutdown() {
|
|
||||||
this.shutdown = true;
|
|
||||||
this.queue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInitialized() {
|
|
||||||
return initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
void receiveEvent(Event event) {
|
|
||||||
final long currentEventSequence = event.sequence();
|
|
||||||
final String sourceName = event.getClass().getName();
|
|
||||||
|
|
||||||
// Notification single event listener
|
|
||||||
for (Subscribe subscribe : subscribes) {
|
|
||||||
// Whether to ignore expiration events
|
|
||||||
if (subscribe.ignoreExpireEvent() && lastEventSequence > currentEventSequence) {
|
|
||||||
LOGGER.debug("[NotifyCenter] the {} is unacceptable to this subscriber, because had expire",
|
|
||||||
event.getClass());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String targetName = subscribe.subscribeType().getName();
|
|
||||||
if (!Objects.equals(sourceName, targetName)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
notifySubscriber(subscribe, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notification multi-event event listener
|
|
||||||
for (SmartSubscribe subscribe : SMART_SUBSCRIBES) {
|
|
||||||
// If you are a multi-event listener, you need to make additional logical judgments
|
|
||||||
if (!subscribe.canNotify(event)) {
|
|
||||||
LOGGER.debug("[NotifyCenter] the {} is unacceptable to this multi-event subscriber", event.getClass());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
notifySubscriber(subscribe, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifySubscriber(final Subscribe subscribe, final Event event) {
|
|
||||||
|
|
||||||
LOGGER.debug("[NotifyCenter] the {} will received by {}", event, subscribe);
|
|
||||||
|
|
||||||
final Runnable job = () -> subscribe.onEvent(event);
|
|
||||||
final Executor executor = subscribe.executor();
|
|
||||||
if (Objects.nonNull(executor)) {
|
|
||||||
executor.execute(job);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
job.run();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LOGGER.error("Event callback exception : {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.alibaba.nacos.core.notify;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.SmartSubscribe;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event publisher.
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
|
||||||
*/
|
|
||||||
public interface EventPublisher {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Multi-event listener collection list.
|
|
||||||
*/
|
|
||||||
Set<SmartSubscribe> SMART_SUBSCRIBES = new ConcurrentHashSet<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the event publisher.
|
|
||||||
*
|
|
||||||
* @param type {@link Class}
|
|
||||||
* @param bufferSize Message staging queue size
|
|
||||||
*/
|
|
||||||
void init(Class<? extends Event> type, int bufferSize);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of currently staged events.
|
|
||||||
*
|
|
||||||
* @return event size
|
|
||||||
*/
|
|
||||||
long currentEventSize();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add listener.
|
|
||||||
*
|
|
||||||
* @param subscribe {@link Subscribe}
|
|
||||||
*/
|
|
||||||
void addSubscribe(Subscribe subscribe);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove listener.
|
|
||||||
*
|
|
||||||
* @param subscribe {@link Subscribe}
|
|
||||||
*/
|
|
||||||
void unSubscribe(Subscribe subscribe);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* publish event.
|
|
||||||
*
|
|
||||||
* @param event {@link Event}
|
|
||||||
* @return publish event is success
|
|
||||||
*/
|
|
||||||
boolean publish(Event event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify listener.
|
|
||||||
*
|
|
||||||
* @param subscribe {@link Subscribe}
|
|
||||||
* @param event {@link Event}
|
|
||||||
*/
|
|
||||||
void notifySubscriber(Subscribe subscribe, Event event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* shutdown this publisher.
|
|
||||||
*/
|
|
||||||
void shutdown();
|
|
||||||
}
|
|
@ -1,280 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.alibaba.nacos.core.notify;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.common.JustForTest;
|
|
||||||
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
|
|
||||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.SmartSubscribe;
|
|
||||||
import com.alibaba.nacos.core.notify.listener.Subscribe;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.ServiceLoader;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* notify center.
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public class NotifyCenter {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(NotifyCenter.class);
|
|
||||||
|
|
||||||
private static final AtomicBoolean CLOSED = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
private static final NotifyCenter INSTANCE = new NotifyCenter();
|
|
||||||
|
|
||||||
private static final AtomicBoolean closed = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
public static int RING_BUFFER_SIZE = 16384;
|
|
||||||
|
|
||||||
public static int SHATE_BUFFER_SIZE = 1024;
|
|
||||||
|
|
||||||
private static BiFunction<Class<? extends Event>, Integer, EventPublisher> BUILD_FACTORY = null;
|
|
||||||
|
|
||||||
static {
|
|
||||||
// Internal ArrayBlockingQueue buffer size. For applications with high write throughput,
|
|
||||||
// this value needs to be increased appropriately. default value is 16384
|
|
||||||
String ringBufferSizeProperty = "nacos.core.notify.ring-buffer-size";
|
|
||||||
RING_BUFFER_SIZE = Integer.getInteger(ringBufferSizeProperty, 16384);
|
|
||||||
|
|
||||||
// The size of the public publisher's message staging queue buffer
|
|
||||||
String shareBufferSizeProperty = "nacos.core.notify.share-buffer-size";
|
|
||||||
SHATE_BUFFER_SIZE = Integer.getInteger(shareBufferSizeProperty, 1024);
|
|
||||||
|
|
||||||
ServiceLoader<EventPublisher> loader = ServiceLoader.load(EventPublisher.class);
|
|
||||||
Iterator<EventPublisher> iterator = loader.iterator();
|
|
||||||
|
|
||||||
if (iterator.hasNext()) {
|
|
||||||
BUILD_FACTORY = (cls, buffer) -> {
|
|
||||||
loader.reload();
|
|
||||||
EventPublisher publisher = ServiceLoader.load(EventPublisher.class).iterator().next();
|
|
||||||
publisher.init(cls, buffer);
|
|
||||||
return publisher;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
BUILD_FACTORY = (cls, buffer) -> {
|
|
||||||
EventPublisher publisher = new DefaultPublisher();
|
|
||||||
publisher.init(cls, buffer);
|
|
||||||
return publisher;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANCE.sharePublisher = BUILD_FACTORY.apply(SlowEvent.class, SHATE_BUFFER_SIZE);
|
|
||||||
ThreadUtils.addShutdownHook(new Thread(() -> {
|
|
||||||
shutdown();
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Publisher management container
|
|
||||||
*/
|
|
||||||
private final Map<String, EventPublisher> publisherMap = new ConcurrentHashMap<>(16);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Multi-event listening list
|
|
||||||
*/
|
|
||||||
private final Set<SmartSubscribe> smartSubscribes = new ConcurrentHashSet<>();
|
|
||||||
|
|
||||||
private EventPublisher sharePublisher;
|
|
||||||
|
|
||||||
@JustForTest
|
|
||||||
public static Map<String, EventPublisher> getPublisherMap() {
|
|
||||||
return INSTANCE.publisherMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JustForTest
|
|
||||||
public static EventPublisher getPublisher(Class<? extends Event> topic) {
|
|
||||||
if (SlowEvent.class.isAssignableFrom(topic)) {
|
|
||||||
return INSTANCE.sharePublisher;
|
|
||||||
}
|
|
||||||
return INSTANCE.publisherMap.get(topic.getCanonicalName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@JustForTest
|
|
||||||
public static Set<SmartSubscribe> getSmartSubscribes() {
|
|
||||||
return EventPublisher.SMART_SUBSCRIBES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JustForTest
|
|
||||||
public static EventPublisher getSharePublisher() {
|
|
||||||
return INSTANCE.sharePublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void shutdown() {
|
|
||||||
if (!closed.compareAndSet(false, true)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LOGGER.warn("[NotifyCenter] Start destroying Publisher");
|
|
||||||
try {
|
|
||||||
INSTANCE.publisherMap.forEach(new BiConsumer<String, EventPublisher>() {
|
|
||||||
@Override
|
|
||||||
public void accept(String s, EventPublisher publisher) {
|
|
||||||
publisher.shutdown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
INSTANCE.sharePublisher.shutdown();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LOGGER.error("NotifyCenter shutdown has error : {}", e);
|
|
||||||
}
|
|
||||||
LOGGER.warn("[NotifyCenter] Destruction of the end");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a Subscriber. If the Publisher concerned by the Subscriber does not exist, then PublihserMap will
|
|
||||||
* preempt a placeholder Publisher first. not call {@link Publisher#start()}
|
|
||||||
*
|
|
||||||
* @param eventType Types of events that Subscriber cares about
|
|
||||||
* @param consumer subscriber
|
|
||||||
* @param <T> event type
|
|
||||||
*/
|
|
||||||
public static <T> void registerSubscribe(final Subscribe consumer) {
|
|
||||||
final Class<? extends Event> cls = consumer.subscribeType();
|
|
||||||
// If you want to listen to multiple events, you do it separately,
|
|
||||||
// without automatically registering the appropriate publisher
|
|
||||||
if (consumer instanceof SmartSubscribe) {
|
|
||||||
EventPublisher.SMART_SUBSCRIBES.add((SmartSubscribe) consumer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If the event does not require additional queue resources,
|
|
||||||
// go to share-publisher to reduce resource waste
|
|
||||||
if (SlowEvent.class.isAssignableFrom(cls)) {
|
|
||||||
INSTANCE.sharePublisher.addSubscribe(consumer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String topic = consumer.subscribeType().getCanonicalName();
|
|
||||||
INSTANCE.publisherMap.computeIfAbsent(topic, s -> BUILD_FACTORY.apply(cls, RING_BUFFER_SIZE));
|
|
||||||
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
|
||||||
publisher.addSubscribe(consumer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* deregister subscriber
|
|
||||||
*
|
|
||||||
* @param consumer subscriber
|
|
||||||
* @param <T>
|
|
||||||
*/
|
|
||||||
public static <T> void deregisterSubscribe(final Subscribe consumer) {
|
|
||||||
final Class<? extends Event> cls = consumer.subscribeType();
|
|
||||||
if (consumer instanceof SmartSubscribe) {
|
|
||||||
EventPublisher.SMART_SUBSCRIBES.remove((SmartSubscribe) consumer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (SlowEvent.class.isAssignableFrom(cls)) {
|
|
||||||
INSTANCE.sharePublisher.unSubscribe(consumer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String topic = consumer.subscribeType().getCanonicalName();
|
|
||||||
if (INSTANCE.publisherMap.containsKey(topic)) {
|
|
||||||
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
|
||||||
publisher.unSubscribe(consumer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new NoSuchElementException("The subcriber has no event publisher");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* request publisher publish event Publishers load lazily, calling publisher. Start () only when the event is
|
|
||||||
* actually published
|
|
||||||
*
|
|
||||||
* @param event
|
|
||||||
*/
|
|
||||||
public static boolean publishEvent(final Event event) {
|
|
||||||
try {
|
|
||||||
return publishEvent(event.getClass(), event);
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
LOGGER.error("There was an exception to the message publishing : {}", ex);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* request publisher publish event Publishers load lazily, calling publisher. Start () only when the event is
|
|
||||||
* actually published
|
|
||||||
*
|
|
||||||
* @param eventType
|
|
||||||
* @param event
|
|
||||||
*/
|
|
||||||
private static boolean publishEvent(final Class<? extends Event> eventType, final Event event) {
|
|
||||||
final String topic = eventType.getCanonicalName();
|
|
||||||
if (SlowEvent.class.isAssignableFrom(eventType)) {
|
|
||||||
return INSTANCE.sharePublisher.publish(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (INSTANCE.publisherMap.containsKey(topic)) {
|
|
||||||
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
|
||||||
return publisher.publish(event);
|
|
||||||
}
|
|
||||||
throw new NoSuchElementException("There are no [" + topic + "] publishers for this event, please register");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* register to share-publisher
|
|
||||||
*
|
|
||||||
* @param supplier
|
|
||||||
* @param eventType
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static EventPublisher registerToSharePublisher(final Class<? extends SlowEvent> eventType) {
|
|
||||||
return INSTANCE.sharePublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* register publisher
|
|
||||||
*
|
|
||||||
* @param supplier
|
|
||||||
* @param eventType
|
|
||||||
* @param queueMaxSize
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static EventPublisher registerToPublisher(final Class<? extends Event> eventType, final int queueMaxSize) {
|
|
||||||
|
|
||||||
if (SlowEvent.class.isAssignableFrom(eventType)) {
|
|
||||||
return INSTANCE.sharePublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String topic = eventType.getCanonicalName();
|
|
||||||
INSTANCE.publisherMap.computeIfAbsent(topic, s -> BUILD_FACTORY.apply(eventType, queueMaxSize));
|
|
||||||
EventPublisher publisher = INSTANCE.publisherMap.get(topic);
|
|
||||||
return publisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* deregister publisher
|
|
||||||
*
|
|
||||||
* @param eventType
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static void deregisterPublisher(final Class<? extends Event> eventType) {
|
|
||||||
final String topic = eventType.getCanonicalName();
|
|
||||||
EventPublisher publisher = INSTANCE.publisherMap.remove(topic);
|
|
||||||
publisher.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.alibaba.nacos.core.notify.listener;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribers to multiple events can be listened to.
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
|
||||||
public abstract class SmartSubscribe implements Subscribe<Event> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if the processing message is acceptable.
|
|
||||||
*
|
|
||||||
* @param event {@link Event}
|
|
||||||
* @return Determines if the processing message is acceptable
|
|
||||||
*/
|
|
||||||
public abstract boolean canNotify(Event event);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final Class<? extends Event> subscribeType() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean ignoreExpireEvent() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.alibaba.nacos.core.notify.listener;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.Event;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* subscriber.
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
|
||||||
*/
|
|
||||||
public interface Subscribe<T extends Event> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event callback.
|
|
||||||
*
|
|
||||||
* @param event {@link Event}
|
|
||||||
*/
|
|
||||||
void onEvent(T event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type of this subscriber's subscription.
|
|
||||||
*
|
|
||||||
* @return Class which extends {@link Event}
|
|
||||||
*/
|
|
||||||
Class<? extends Event> subscribeType();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* It is up to the listener to determine whether the callback is asynchronous or synchronous.
|
|
||||||
*
|
|
||||||
* @return {@link Executor}
|
|
||||||
*/
|
|
||||||
default Executor executor() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to ignore expired events.
|
|
||||||
*
|
|
||||||
* @return default value is {@link Boolean#FALSE}
|
|
||||||
*/
|
|
||||||
default boolean ignoreExpireEvent() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.core.utils;
|
package com.alibaba.nacos.core.utils;
|
||||||
|
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.core.notify.SlowEvent;
|
import com.alibaba.nacos.common.notify.SlowEvent;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -229,7 +229,7 @@ public class InetUtils {
|
|||||||
* {@link com.alibaba.nacos.core.cluster.ServerMemberManager} is listener.
|
* {@link com.alibaba.nacos.core.cluster.ServerMemberManager} is listener.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"PMD.ClassNamingShouldBeCamelRule", "checkstyle:AbbreviationAsWordInName"})
|
@SuppressWarnings({"PMD.ClassNamingShouldBeCamelRule", "checkstyle:AbbreviationAsWordInName"})
|
||||||
public static class IPChangeEvent implements SlowEvent {
|
public static class IPChangeEvent extends SlowEvent {
|
||||||
|
|
||||||
private String oldIp;
|
private String oldIp;
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@
|
|||||||
<level value="INFO"/>
|
<level value="INFO"/>
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
<logger name="com.alibaba.nacos.core.notify.NotifyCenter">
|
<logger name="com.alibaba.nacos.common.notify.NotifyCenter">
|
||||||
<appender-ref ref="CONSOLE"/>
|
<appender-ref ref="CONSOLE"/>
|
||||||
<level value="INFO"/>
|
<level value="INFO"/>
|
||||||
</logger>
|
</logger>
|
||||||
|
@ -665,7 +665,7 @@
|
|||||||
<level value="INFO"/>
|
<level value="INFO"/>
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
<logger name="com.alibaba.nacos.core.notify.NotifyCenter">
|
<logger name="com.alibaba.nacos.common.notify.NotifyCenter">
|
||||||
<appender-ref ref="CONSOLE"/>
|
<appender-ref ref="CONSOLE"/>
|
||||||
<level value="INFO"/>
|
<level value="INFO"/>
|
||||||
</logger>
|
</logger>
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.naming.cluster;
|
package com.alibaba.nacos.naming.cluster;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
import com.alibaba.nacos.core.cluster.Member;
|
import com.alibaba.nacos.core.cluster.Member;
|
||||||
import com.alibaba.nacos.core.cluster.MembersChangeEvent;
|
import com.alibaba.nacos.core.cluster.MembersChangeEvent;
|
||||||
@ -23,7 +24,6 @@ import com.alibaba.nacos.core.cluster.MemberChangeListener;
|
|||||||
import com.alibaba.nacos.core.cluster.MemberMetaDataConstants;
|
import com.alibaba.nacos.core.cluster.MemberMetaDataConstants;
|
||||||
import com.alibaba.nacos.core.cluster.NodeState;
|
import com.alibaba.nacos.core.cluster.NodeState;
|
||||||
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer;
|
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer;
|
||||||
import com.alibaba.nacos.naming.misc.GlobalExecutor;
|
import com.alibaba.nacos.naming.misc.GlobalExecutor;
|
||||||
@ -54,7 +54,7 @@ import java.util.Optional;
|
|||||||
* @deprecated 1.3.0 This object will be deleted sometime after version 1.3.0
|
* @deprecated 1.3.0 This object will be deleted sometime after version 1.3.0
|
||||||
*/
|
*/
|
||||||
@Component("serverListManager")
|
@Component("serverListManager")
|
||||||
public class ServerListManager implements MemberChangeListener {
|
public class ServerListManager extends MemberChangeListener {
|
||||||
|
|
||||||
private static final String LOCALHOST_SITE = UtilsAndCommons.UNKNOWN_SITE;
|
private static final String LOCALHOST_SITE = UtilsAndCommons.UNKNOWN_SITE;
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ public class ServerListManager implements MemberChangeListener {
|
|||||||
public ServerListManager(final SwitchDomain switchDomain, final ServerMemberManager memberManager) {
|
public ServerListManager(final SwitchDomain switchDomain, final ServerMemberManager memberManager) {
|
||||||
this.switchDomain = switchDomain;
|
this.switchDomain = switchDomain;
|
||||||
this.memberManager = memberManager;
|
this.memberManager = memberManager;
|
||||||
NotifyCenter.registerSubscribe(this);
|
NotifyCenter.registerSubscriber(this);
|
||||||
this.servers = new ArrayList<>(memberManager.allMembers());
|
this.servers = new ArrayList<>(memberManager.allMembers());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.naming.consistency.persistent.raft;
|
package com.alibaba.nacos.naming.consistency.persistent.raft;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||||
import com.alibaba.nacos.core.cluster.Member;
|
import com.alibaba.nacos.core.cluster.Member;
|
||||||
import com.alibaba.nacos.core.cluster.MemberChangeListener;
|
import com.alibaba.nacos.core.cluster.MemberChangeListener;
|
||||||
import com.alibaba.nacos.core.cluster.MembersChangeEvent;
|
import com.alibaba.nacos.core.cluster.MembersChangeEvent;
|
||||||
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
import com.alibaba.nacos.core.cluster.ServerMemberManager;
|
||||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
|
||||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||||
import com.alibaba.nacos.naming.misc.HttpClient;
|
import com.alibaba.nacos.naming.misc.HttpClient;
|
||||||
import com.alibaba.nacos.naming.misc.Loggers;
|
import com.alibaba.nacos.naming.misc.Loggers;
|
||||||
@ -53,7 +53,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@DependsOn("ProtocolManager")
|
@DependsOn("ProtocolManager")
|
||||||
public class RaftPeerSet implements MemberChangeListener {
|
public class RaftPeerSet extends MemberChangeListener {
|
||||||
|
|
||||||
private final ServerMemberManager memberManager;
|
private final ServerMemberManager memberManager;
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ public class RaftPeerSet implements MemberChangeListener {
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
NotifyCenter.registerSubscribe(this);
|
NotifyCenter.registerSubscriber(this);
|
||||||
changePeers(memberManager.allMembers());
|
changePeers(memberManager.allMembers());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user