commit
3ea2200fb0
33
.github/stale.yml
vendored
Normal file
33
.github/stale.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 180
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- good first issue
|
||||
- contribution welcome
|
||||
- dependencies
|
||||
- kind/bug
|
||||
- kind/code quality
|
||||
- kind/enhancement
|
||||
- kind/performance
|
||||
- kind/proposal
|
||||
- kind/refactor
|
||||
- kind/user experience
|
||||
- Soc2019
|
||||
- SoC2020
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: expired
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
Thanks for your feedback and contribution. But the issue/pull request has
|
||||
not had recent activity more than **180 days**. This issue/pull request will
|
||||
be closed if no further activity occurs **7 days later**.
|
||||
|
||||
We may solve this issue in new version. So can you upgrade to newest version
|
||||
and retry?
|
||||
|
||||
If there are still issues or want to contribute again. Please create new issue
|
||||
or pull request again.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
@ -29,6 +29,7 @@ before_install:
|
||||
script:
|
||||
- mvn -B clean package apache-rat:check findbugs:findbugs -Dmaven.test.skip=true
|
||||
- mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
|
||||
- mvn clean install -Pcit-test
|
||||
- mvn clean package -Pit-test
|
||||
after_success:
|
||||
- mvn clean package -Pit-test
|
||||
|
@ -11,7 +11,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/nacos-address.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
|
@ -97,5 +97,4 @@ public class NacosFactory {
|
||||
public static NamingMaintainService createMaintainService(Properties properties) throws NacosException {
|
||||
return NamingMaintainFactory.createMaintainService(properties);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,5 +58,4 @@ public class ConfigFactory {
|
||||
properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
|
||||
return createConfigService(properties);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -105,4 +105,10 @@ public interface ConfigService {
|
||||
*/
|
||||
String getServerStatus();
|
||||
|
||||
/**
|
||||
* Shutdown the resource service
|
||||
*
|
||||
* @throws NacosException exception.
|
||||
*/
|
||||
void shutDown() throws NacosException;
|
||||
}
|
||||
|
@ -145,5 +145,4 @@ public class NacosException extends Exception {
|
||||
public static final int OVER_THRESHOLD = 503;
|
||||
|
||||
public static final int RESOURCE_NOT_FOUND = -404;
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.api.exception.runtime;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Nacos deserialization exception.
|
||||
*
|
||||
@ -42,6 +44,10 @@ public class NacosDeserializationException extends NacosRuntimeException {
|
||||
this.targetClass = targetClass;
|
||||
}
|
||||
|
||||
public NacosDeserializationException(Type targetType) {
|
||||
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetType.toString()));
|
||||
}
|
||||
|
||||
public NacosDeserializationException(Throwable throwable) {
|
||||
super(ERROR_CODE, DEFAULT_MSG, throwable);
|
||||
}
|
||||
@ -51,6 +57,14 @@ public class NacosDeserializationException extends NacosRuntimeException {
|
||||
this.targetClass = targetClass;
|
||||
}
|
||||
|
||||
public NacosDeserializationException(Type targetType, Throwable throwable) {
|
||||
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetType.toString()), throwable);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public Class<?> getTargetClass() {
|
||||
return targetClass;
|
||||
}
|
||||
|
@ -555,4 +555,11 @@ public interface NamingService {
|
||||
* @return is server healthy
|
||||
*/
|
||||
String getServerStatus();
|
||||
|
||||
/**
|
||||
* Shutdown the resource service.
|
||||
*
|
||||
* @throws NacosException exception.
|
||||
*/
|
||||
void shutDown() throws NacosException;
|
||||
}
|
||||
|
@ -72,14 +72,15 @@ public class NacosConfigService implements ConfigService {
|
||||
ValidatorUtils.checkInitParam(properties);
|
||||
String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
|
||||
if (StringUtils.isBlank(encodeTmp)) {
|
||||
encode = Constants.ENCODE;
|
||||
this.encode = Constants.ENCODE;
|
||||
} else {
|
||||
encode = encodeTmp.trim();
|
||||
this.encode = encodeTmp.trim();
|
||||
}
|
||||
initNamespace(properties);
|
||||
agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
|
||||
agent.start();
|
||||
worker = new ClientWorker(agent, configFilterChainManager, properties);
|
||||
|
||||
this.agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
|
||||
this.agent.start();
|
||||
this.worker = new ClientWorker(this.agent, this.configFilterChainManager, properties);
|
||||
}
|
||||
|
||||
private void initNamespace(Properties properties) {
|
||||
@ -281,4 +282,9 @@ public class NacosConfigService implements ConfigService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() throws NacosException{
|
||||
agent.shutdown();
|
||||
worker.shutdown();
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package com.alibaba.nacos.client.config.http;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@ -27,7 +28,8 @@ import java.util.List;
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public interface HttpAgent {
|
||||
public interface HttpAgent extends Closeable {
|
||||
|
||||
/**
|
||||
* start to get nacos ip list
|
||||
* @return Nothing.
|
||||
|
@ -13,6 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* MetricsHttpAgent
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
package com.alibaba.nacos.client.config.http;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
@ -29,6 +34,7 @@ import java.util.List;
|
||||
* @author Nacos
|
||||
*/
|
||||
public class MetricsHttpAgent implements HttpAgent {
|
||||
|
||||
private HttpAgent httpAgent;
|
||||
|
||||
public MetricsHttpAgent(HttpAgent httpAgent) {
|
||||
@ -108,5 +114,10 @@ public class MetricsHttpAgent implements HttpAgent {
|
||||
public String getEncode() {
|
||||
return httpAgent.getEncode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
httpAgent.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.client.utils.TemplateUtils;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -44,7 +45,11 @@ import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Server Agent
|
||||
@ -61,6 +66,8 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
|
||||
private long securityInfoRefreshIntervalMills = TimeUnit.SECONDS.toMillis(5);
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
/**
|
||||
* @param path 相对于web应用根,以/开头
|
||||
* @param headers
|
||||
@ -235,7 +242,7 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
|
||||
private String getUrl(String serverAddr, String relativePath) {
|
||||
String contextPath = serverListMgr.getContentPath().startsWith("/") ?
|
||||
serverListMgr.getContentPath() : "/" + serverListMgr.getContentPath();
|
||||
serverListMgr.getContentPath() : "/" + serverListMgr.getContentPath();
|
||||
return serverAddr + contextPath + relativePath;
|
||||
}
|
||||
|
||||
@ -244,22 +251,24 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
public ServerHttpAgent(ServerListManager mgr) {
|
||||
serverListMgr = mgr;
|
||||
this.serverListMgr = mgr;
|
||||
}
|
||||
|
||||
public ServerHttpAgent(ServerListManager mgr, Properties properties) {
|
||||
serverListMgr = mgr;
|
||||
this.serverListMgr = mgr;
|
||||
init(properties);
|
||||
}
|
||||
|
||||
public ServerHttpAgent(Properties properties) throws NacosException {
|
||||
serverListMgr = new ServerListManager(properties);
|
||||
securityProxy = new SecurityProxy(properties);
|
||||
namespaceId = properties.getProperty(PropertyKeyConst.NAMESPACE);
|
||||
this.serverListMgr = new ServerListManager(properties);
|
||||
this.securityProxy = new SecurityProxy(properties);
|
||||
this.namespaceId = properties.getProperty(PropertyKeyConst.NAMESPACE);
|
||||
init(properties);
|
||||
securityProxy.login(serverListMgr.getServerUrls());
|
||||
this.securityProxy.login(this.serverListMgr.getServerUrls());
|
||||
|
||||
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||
|
||||
// init executorService
|
||||
this.executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
@ -269,12 +278,13 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
}
|
||||
});
|
||||
|
||||
executorService.scheduleWithFixedDelay(new Runnable() {
|
||||
this.executorService.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
securityProxy.login(serverListMgr.getServerUrls());
|
||||
}
|
||||
}, 0, securityInfoRefreshIntervalMills, TimeUnit.MILLISECONDS);
|
||||
}, 0, this.securityInfoRefreshIntervalMills, TimeUnit.MILLISECONDS);
|
||||
|
||||
}
|
||||
|
||||
private void injectSecurityInfo(List<String> params) {
|
||||
@ -329,7 +339,7 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void start() throws NacosException {
|
||||
public void start() throws NacosException {
|
||||
serverListMgr.start();
|
||||
}
|
||||
|
||||
@ -430,6 +440,14 @@ public class ServerHttpAgent implements HttpAgent {
|
||||
return encode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
String className = this.getClass().getName();
|
||||
LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, LOGGER);
|
||||
LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
private static class STSCredential {
|
||||
@JsonProperty(value = "AccessKeyId")
|
||||
|
@ -25,12 +25,14 @@ import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
|
||||
import com.alibaba.nacos.client.config.http.HttpAgent;
|
||||
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
|
||||
import com.alibaba.nacos.client.config.utils.ContentUtils;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import com.alibaba.nacos.client.monitor.MetricsMonitor;
|
||||
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.client.utils.TenantUtil;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.slf4j.Logger;
|
||||
@ -55,7 +57,7 @@ import static com.alibaba.nacos.api.common.Constants.CONFIG_TYPE;
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ClientWorker {
|
||||
public class ClientWorker implements Closeable {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.logger(ClientWorker.class);
|
||||
|
||||
@ -116,7 +118,7 @@ public class ClientWorker {
|
||||
copy.remove(groupKey);
|
||||
cacheMap.set(copy);
|
||||
}
|
||||
LOGGER.info("[{}] [unsubscribe] {}", agent.getName(), groupKey);
|
||||
LOGGER.info("[{}] [unsubscribe] {}", this.agent.getName(), groupKey);
|
||||
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
|
||||
}
|
||||
@ -160,7 +162,7 @@ public class ClientWorker {
|
||||
cacheMap.set(copy);
|
||||
}
|
||||
|
||||
LOGGER.info("[{}] [subscribe] {}", agent.getName(), key);
|
||||
LOGGER.info("[{}] [subscribe] {}", this.agent.getName(), key);
|
||||
|
||||
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
|
||||
|
||||
@ -191,7 +193,7 @@ public class ClientWorker {
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
|
||||
Map<String, CacheData> copy = new HashMap<String, CacheData>(this.cacheMap.get());
|
||||
copy.put(key, cache);
|
||||
cacheMap.set(copy);
|
||||
}
|
||||
@ -277,7 +279,6 @@ public class ClientWorker {
|
||||
final String tenant = cacheData.tenant;
|
||||
File path = LocalConfigInfoProcessor.getFailoverFile(agent.getName(), dataId, group, tenant);
|
||||
|
||||
// 没有 -> 有
|
||||
if (!cacheData.isUseLocalConfigInfo() && path.exists()) {
|
||||
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
|
||||
String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
|
||||
@ -290,7 +291,7 @@ public class ClientWorker {
|
||||
return;
|
||||
}
|
||||
|
||||
// 有 -> 没有。不通知业务监听器,从server拿到配置后通知。
|
||||
// If use local config info, then it doesn't notify business listener and notify after getting from server.
|
||||
if (cacheData.isUseLocalConfigInfo() && !path.exists()) {
|
||||
cacheData.setUseLocalConfigInfo(false);
|
||||
LOGGER.warn("[{}] [failover-change] failover file deleted. dataId={}, group={}, tenant={}", agent.getName(),
|
||||
@ -298,7 +299,7 @@ public class ClientWorker {
|
||||
return;
|
||||
}
|
||||
|
||||
// 有变更
|
||||
// When it changed.
|
||||
if (cacheData.isUseLocalConfigInfo() && path.exists()
|
||||
&& cacheData.getLocalConfigInfoVersion() != path.lastModified()) {
|
||||
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
|
||||
@ -316,13 +317,13 @@ public class ClientWorker {
|
||||
}
|
||||
|
||||
public void checkConfigInfo() {
|
||||
// 分任务
|
||||
// Dispatch taskes.
|
||||
int listenerSize = cacheMap.get().size();
|
||||
// 向上取整为批数
|
||||
// Round up the longingTaskCount.
|
||||
int longingTaskCount = (int) Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
|
||||
if (longingTaskCount > currentLongingTaskCount) {
|
||||
for (int i = (int) currentLongingTaskCount; i < longingTaskCount; i++) {
|
||||
// 要判断任务是否在执行 这块需要好好想想。 任务列表现在是无序的。变化过程可能有问题
|
||||
// The task list is no order.So it maybe has issues when changing.
|
||||
executorService.execute(new LongPollingRunnable(i));
|
||||
}
|
||||
currentLongingTaskCount = longingTaskCount;
|
||||
@ -330,7 +331,13 @@ public class ClientWorker {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Server获取值变化了的DataID列表。返回的对象里只有dataId和group是有效的。 保证不返回NULL。
|
||||
* Fetch the dataId list from server.
|
||||
*
|
||||
* @param cacheDatas CacheDatas for config infomations.
|
||||
* @param inInitializingCacheList initial cache lists.
|
||||
* @return String include dataId and group (ps: it maybe null).
|
||||
*
|
||||
* @throws IOException Exception.
|
||||
*/
|
||||
List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> inInitializingCacheList) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -345,7 +352,7 @@ public class ClientWorker {
|
||||
sb.append(cacheData.getTenant()).append(LINE_SEPARATOR);
|
||||
}
|
||||
if (cacheData.isInitializing()) {
|
||||
// cacheData 首次出现在cacheMap中&首次check更新
|
||||
// It updates when cacheData occours in cacheMap by first time.
|
||||
inInitializingCacheList
|
||||
.add(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant));
|
||||
}
|
||||
@ -356,7 +363,13 @@ public class ClientWorker {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Server获取值变化了的DataID列表。返回的对象里只有dataId和group是有效的。 保证不返回NULL。
|
||||
* Fetch the updated dataId list from server.
|
||||
*
|
||||
*
|
||||
* @param probeUpdateString updated attribute string value.
|
||||
* @param isInitializingCacheList initial cache lists.
|
||||
* @return The updated dataId list(ps: it maybe null).
|
||||
* @throws IOException Exception.
|
||||
*/
|
||||
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException {
|
||||
|
||||
@ -403,7 +416,10 @@ public class ClientWorker {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从HTTP响应拿到变化的groupKey。保证不返回NULL。
|
||||
* Get the groupKey list from the http response.
|
||||
*
|
||||
* @param response Http response.
|
||||
* @return GroupKey List, (ps: it maybe null).
|
||||
*/
|
||||
private List<String> parseUpdateDataIdResponse(String response) {
|
||||
if (StringUtils.isBlank(response)) {
|
||||
@ -448,7 +464,7 @@ public class ClientWorker {
|
||||
|
||||
init(properties);
|
||||
|
||||
executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
|
||||
this.executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
@ -458,7 +474,7 @@ public class ClientWorker {
|
||||
}
|
||||
});
|
||||
|
||||
executorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
|
||||
this.executorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
@ -468,7 +484,7 @@ public class ClientWorker {
|
||||
}
|
||||
});
|
||||
|
||||
executor.scheduleWithFixedDelay(new Runnable() {
|
||||
this.executor.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@ -482,12 +498,21 @@ public class ClientWorker {
|
||||
|
||||
private void init(Properties properties) {
|
||||
|
||||
timeout = Math.max(NumberUtils.toInt(properties.getProperty(PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT),
|
||||
this.timeout = Math.max(NumberUtils.toInt(properties.getProperty(PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT),
|
||||
Constants.CONFIG_LONG_POLL_TIMEOUT), Constants.MIN_CONFIG_LONG_POLL_TIMEOUT);
|
||||
|
||||
taskPenaltyTime = NumberUtils.toInt(properties.getProperty(PropertyKeyConst.CONFIG_RETRY_TIME), Constants.CONFIG_RETRY_TIME);
|
||||
this.taskPenaltyTime = NumberUtils.toInt(properties.getProperty(PropertyKeyConst.CONFIG_RETRY_TIME), Constants.CONFIG_RETRY_TIME);
|
||||
|
||||
enableRemoteSyncConfig = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG));
|
||||
this.enableRemoteSyncConfig = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, LOGGER);
|
||||
ThreadUtils.shutdownThreadPool(executor, LOGGER);
|
||||
LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
class LongPollingRunnable implements Runnable {
|
||||
|
@ -20,35 +20,56 @@ import com.alibaba.nacos.api.SystemPropertyKeyConst;
|
||||
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.*;
|
||||
import com.alibaba.nacos.client.utils.EnvUtil;
|
||||
import com.alibaba.nacos.client.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.client.utils.TemplateUtils;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Properties;
|
||||
import java.util.Iterator;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Serverlist Manager
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ServerListManager {
|
||||
public class ServerListManager implements Closeable {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.logger(ServerListManager.class);
|
||||
private static final String HTTPS = "https://";
|
||||
private static final String HTTP = "http://";
|
||||
private ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("com.alibaba.nacos.client.ServerListManager");
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
||||
public ServerListManager() {
|
||||
isFixed = false;
|
||||
isStarted = false;
|
||||
name = DEFAULT_NAME;
|
||||
this.isFixed = false;
|
||||
this.isStarted = false;
|
||||
this.name = DEFAULT_NAME;
|
||||
}
|
||||
|
||||
public ServerListManager(List<String> fixed) {
|
||||
@ -56,8 +77,8 @@ public class ServerListManager {
|
||||
}
|
||||
|
||||
public ServerListManager(List<String> fixed, String namespace) {
|
||||
isFixed = true;
|
||||
isStarted = true;
|
||||
this.isFixed = true;
|
||||
this.isStarted = true;
|
||||
List<String> serverAddrs = new ArrayList<String>();
|
||||
for (String serverAddr : fixed) {
|
||||
String[] serverAddrArr = serverAddr.split(":");
|
||||
@ -67,21 +88,21 @@ public class ServerListManager {
|
||||
serverAddrs.add(serverAddr);
|
||||
}
|
||||
}
|
||||
serverUrls = new ArrayList<String>(serverAddrs);
|
||||
this.serverUrls = new ArrayList<String>(serverAddrs);
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()]));
|
||||
this.name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()]));
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()])) + "-"
|
||||
this.name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()])) + "-"
|
||||
+ namespace;
|
||||
}
|
||||
}
|
||||
|
||||
public ServerListManager(String host, int port) {
|
||||
isFixed = false;
|
||||
isStarted = false;
|
||||
name = CUSTOM_NAME + "-" + host + "-" + port;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s", host, port, contentPath, serverListName);
|
||||
this.isFixed = false;
|
||||
this.isStarted = false;
|
||||
this.name = CUSTOM_NAME + "-" + host + "-" + port;
|
||||
this.addressServerUrl = String.format("http://%s:%d/%s/%s", host, port, this.contentPath, this.serverListName);
|
||||
}
|
||||
|
||||
public ServerListManager(String endpoint) throws NacosException {
|
||||
@ -89,8 +110,8 @@ public class ServerListManager {
|
||||
}
|
||||
|
||||
public ServerListManager(String endpoint, String namespace) throws NacosException {
|
||||
isFixed = false;
|
||||
isStarted = false;
|
||||
this.isFixed = false;
|
||||
this.isStarted = false;
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(PropertyKeyConst.ENDPOINT, endpoint);
|
||||
endpoint = initEndpoint(properties);
|
||||
@ -99,30 +120,33 @@ public class ServerListManager {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
}
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = endpoint;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
|
||||
serverListName);
|
||||
this.name = endpoint;
|
||||
this.addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, this.endpointPort, this.contentPath,
|
||||
this.serverListName);
|
||||
} else {
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
}
|
||||
name = endpoint + "-" + namespace;
|
||||
this.name = endpoint + "-" + namespace;
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort, contentPath,
|
||||
serverListName, namespace);
|
||||
this.addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, this.endpointPort, this.contentPath,
|
||||
this.serverListName, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ServerListManager(Properties properties) throws NacosException {
|
||||
isStarted = false;
|
||||
serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
|
||||
this.isStarted = false;
|
||||
this.serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
|
||||
String namespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
|
||||
initParam(properties);
|
||||
|
||||
if (StringUtils.isNotEmpty(serverAddrsStr)) {
|
||||
isFixed = true;
|
||||
this.isFixed = true;
|
||||
List<String> serverAddrs = new ArrayList<String>();
|
||||
String[] serverAddrsArr = serverAddrsStr.split(",");
|
||||
String[] serverAddrsArr = this.serverAddrsStr.split(",");
|
||||
for (String serverAddr: serverAddrsArr) {
|
||||
if (serverAddr.startsWith(HTTPS) || serverAddr.startsWith(HTTP)) {
|
||||
serverAddrs.add(serverAddr);
|
||||
@ -135,45 +159,44 @@ public class ServerListManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
serverUrls = serverAddrs;
|
||||
this.serverUrls = serverAddrs;
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()]));
|
||||
this.name = FIXED_NAME + "-" + getFixedNameSuffix(this.serverUrls.toArray(new String[this.serverUrls.size()]));
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()])) + "-"
|
||||
this.name = FIXED_NAME + "-" + getFixedNameSuffix(this.serverUrls.toArray(new String[this.serverUrls.size()])) + "-"
|
||||
+ namespace;
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
}
|
||||
isFixed = false;
|
||||
this.isFixed = false;
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = endpoint;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
|
||||
serverListName);
|
||||
this.name = endpoint;
|
||||
this.addressServerUrl = String.format("http://%s:%d/%s/%s", this.endpoint, this.endpointPort, this.contentPath,
|
||||
this.serverListName);
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
name = endpoint + "-" + namespace;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort,
|
||||
contentPath, serverListName, namespace);
|
||||
this.name = this.endpoint + "-" + namespace;
|
||||
this.addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", this.endpoint, this.endpointPort,
|
||||
this.contentPath, this.serverListName, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void initParam(Properties properties) {
|
||||
endpoint = initEndpoint(properties);
|
||||
this.endpoint = initEndpoint(properties);
|
||||
|
||||
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
|
||||
if (!StringUtils.isBlank(contentPathTmp)) {
|
||||
contentPath = contentPathTmp;
|
||||
this.contentPath = contentPathTmp;
|
||||
}
|
||||
String serverListNameTmp = properties.getProperty(PropertyKeyConst.CLUSTER_NAME);
|
||||
if (!StringUtils.isBlank(serverListNameTmp)) {
|
||||
serverListName = serverListNameTmp;
|
||||
this.serverListName = serverListNameTmp;
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,7 +210,7 @@ public class ServerListManager {
|
||||
});
|
||||
|
||||
if (StringUtils.isNotBlank(endpointPortTmp)) {
|
||||
endpointPort = Integer.parseInt(endpointPortTmp);
|
||||
this.endpointPort = Integer.parseInt(endpointPortTmp);
|
||||
}
|
||||
|
||||
String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT);
|
||||
@ -200,7 +223,7 @@ public class ServerListManager {
|
||||
if (Boolean.parseBoolean(isUseEndpointRuleParsing)) {
|
||||
String endpointUrl = ParamUtil.parsingEndpointRule(endpointTmp);
|
||||
if (StringUtils.isNotBlank(endpointUrl)) {
|
||||
serverAddrsStr = "";
|
||||
this.serverAddrsStr = "";
|
||||
}
|
||||
return endpointUrl;
|
||||
}
|
||||
@ -231,7 +254,8 @@ public class ServerListManager {
|
||||
"fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl);
|
||||
}
|
||||
|
||||
TimerService.scheduleWithFixedDelay(getServersTask, 0L, 30L, TimeUnit.SECONDS);
|
||||
// executor schedules the timer task
|
||||
this.executorService.scheduleWithFixedDelay(getServersTask,0L, 30L, TimeUnit.SECONDS);
|
||||
isStarted = true;
|
||||
}
|
||||
|
||||
@ -246,6 +270,14 @@ public class ServerListManager {
|
||||
return new ServerAddressIterator(serverUrls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
String className = this.getClass().getName();
|
||||
LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, LOGGER);
|
||||
LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
class GetServerListTask implements Runnable {
|
||||
final String url;
|
||||
|
||||
|
@ -1,44 +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 java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* Time Service
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class TimerService {
|
||||
|
||||
static public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,
|
||||
long delay, TimeUnit unit) {
|
||||
return scheduledExecutor.scheduleWithFixedDelay(command, initialDelay, delay, unit);
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
||||
static ScheduledExecutorService scheduledExecutor = Executors
|
||||
.newSingleThreadScheduledExecutor(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("com.alibaba.nacos.client.Timer");
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
@ -85,18 +85,18 @@ public class NacosNamingService implements NamingService {
|
||||
|
||||
private void init(Properties properties) {
|
||||
ValidatorUtils.checkInitParam(properties);
|
||||
namespace = InitUtils.initNamespaceForNaming(properties);
|
||||
this.namespace = InitUtils.initNamespaceForNaming(properties);
|
||||
InitUtils.initSerialization();
|
||||
initServerAddr(properties);
|
||||
InitUtils.initWebRootContext();
|
||||
initCacheDir();
|
||||
initLogName(properties);
|
||||
|
||||
eventDispatcher = new EventDispatcher();
|
||||
serverProxy = new NamingProxy(namespace, endpoint, serverList, properties);
|
||||
beatReactor = new BeatReactor(serverProxy, initClientBeatThreadCount(properties));
|
||||
hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, isLoadCacheAtStart(properties),
|
||||
initPollingThreadCount(properties));
|
||||
this.eventDispatcher = new EventDispatcher();
|
||||
this.serverProxy = new NamingProxy(this.namespace, this.endpoint, this.serverList, properties);
|
||||
this.beatReactor = new BeatReactor(this.serverProxy, initClientBeatThreadCount(properties));
|
||||
this.hostReactor = new HostReactor(this.eventDispatcher, this.serverProxy, beatReactor, this.cacheDir,
|
||||
isLoadCacheAtStart(properties), initPollingThreadCount(properties));
|
||||
}
|
||||
|
||||
private int initClientBeatThreadCount(Properties properties) {
|
||||
@ -189,21 +189,10 @@ public class NacosNamingService implements NamingService {
|
||||
|
||||
@Override
|
||||
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
|
||||
|
||||
if (instance.isEphemeral()) {
|
||||
BeatInfo beatInfo = new BeatInfo();
|
||||
beatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName));
|
||||
beatInfo.setIp(instance.getIp());
|
||||
beatInfo.setPort(instance.getPort());
|
||||
beatInfo.setCluster(instance.getClusterName());
|
||||
beatInfo.setWeight(instance.getWeight());
|
||||
beatInfo.setMetadata(instance.getMetadata());
|
||||
beatInfo.setScheduled(false);
|
||||
beatInfo.setPeriod(instance.getInstanceHeartBeatInterval());
|
||||
|
||||
BeatInfo beatInfo = beatReactor.buildBeatInfo(instance);
|
||||
beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
|
||||
}
|
||||
|
||||
serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
|
||||
}
|
||||
|
||||
@ -487,4 +476,12 @@ public class NacosNamingService implements NamingService {
|
||||
public BeatReactor getBeatReactor() {
|
||||
return beatReactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() throws NacosException {
|
||||
beatReactor.shutdown();
|
||||
eventDispatcher.shutdown();
|
||||
hostReactor.shutdown();
|
||||
serverProxy.shutdown();
|
||||
}
|
||||
}
|
||||
|
@ -15,14 +15,17 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.naming.backups;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.client.naming.cache.ConcurrentDiskUtil;
|
||||
import com.alibaba.nacos.client.naming.cache.DiskCache;
|
||||
import com.alibaba.nacos.client.naming.core.HostReactor;
|
||||
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@ -37,29 +40,31 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
/**
|
||||
* @author nkorange
|
||||
*/
|
||||
public class FailoverReactor {
|
||||
public class FailoverReactor implements Closeable {
|
||||
|
||||
private String failoverDir;
|
||||
|
||||
private HostReactor hostReactor;
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
public FailoverReactor(HostReactor hostReactor, String cacheDir) {
|
||||
this.hostReactor = hostReactor;
|
||||
this.failoverDir = cacheDir + "/failover";
|
||||
// init executorService
|
||||
this.executorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r);
|
||||
thread.setDaemon(true);
|
||||
thread.setName("com.alibaba.nacos.naming.failover");
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
this.init();
|
||||
}
|
||||
|
||||
private Map<String, ServiceInfo> serviceMap = new ConcurrentHashMap<String, ServiceInfo>();
|
||||
private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r);
|
||||
thread.setDaemon(true);
|
||||
thread.setName("com.alibaba.nacos.naming.failover");
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
|
||||
private Map<String, String> switchParams = new ConcurrentHashMap<String, String>();
|
||||
private static final long DAY_PERIOD_MINUTES = 24 * 60;
|
||||
|
||||
@ -99,6 +104,14 @@ public class FailoverReactor {
|
||||
return startDT.getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
class SwitchRefresher implements Runnable {
|
||||
long lastModifiedMillis = 0L;
|
||||
|
||||
|
@ -24,7 +24,9 @@ import com.alibaba.nacos.api.naming.utils.NamingUtils;
|
||||
import com.alibaba.nacos.client.monitor.MetricsMonitor;
|
||||
import com.alibaba.nacos.client.naming.net.NamingProxy;
|
||||
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.util.Map;
|
||||
@ -35,7 +37,7 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
/**
|
||||
* @author harold
|
||||
*/
|
||||
public class BeatReactor {
|
||||
public class BeatReactor implements Closeable {
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
@ -51,7 +53,7 @@ public class BeatReactor {
|
||||
|
||||
public BeatReactor(NamingProxy serverProxy, int threadCount) {
|
||||
this.serverProxy = serverProxy;
|
||||
executorService = new ScheduledThreadPoolExecutor(threadCount, new ThreadFactory() {
|
||||
this.executorService = new ScheduledThreadPoolExecutor(threadCount, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r);
|
||||
@ -85,11 +87,32 @@ public class BeatReactor {
|
||||
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
|
||||
}
|
||||
|
||||
private String buildKey(String serviceName, String ip, int port) {
|
||||
public BeatInfo buildBeatInfo(Instance instance) {
|
||||
BeatInfo beatInfo = new BeatInfo();
|
||||
beatInfo.setServiceName(instance.getServiceName());
|
||||
beatInfo.setIp(instance.getIp());
|
||||
beatInfo.setPort(instance.getPort());
|
||||
beatInfo.setCluster(instance.getClusterName());
|
||||
beatInfo.setWeight(instance.getWeight());
|
||||
beatInfo.setMetadata(instance.getMetadata());
|
||||
beatInfo.setScheduled(false);
|
||||
beatInfo.setPeriod(instance.getInstanceHeartBeatInterval());
|
||||
return beatInfo;
|
||||
}
|
||||
|
||||
public String buildKey(String serviceName, String ip, int port) {
|
||||
return serviceName + Constants.NAMING_INSTANCE_ID_SPLITTER
|
||||
+ ip + Constants.NAMING_INSTANCE_ID_SPLITTER + port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
class BeatTask implements Runnable {
|
||||
|
||||
BeatInfo beatInfo;
|
||||
|
@ -23,7 +23,6 @@ import com.alibaba.nacos.client.naming.utils.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
@ -32,11 +31,6 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
*/
|
||||
public class Balancer {
|
||||
|
||||
/**
|
||||
* report status to server
|
||||
*/
|
||||
public final static List<String> UNCONSISTENT_SERVICE_WITH_ADDRESS_SERVER = new CopyOnWriteArrayList<String>();
|
||||
|
||||
public static class RandomByWeight {
|
||||
|
||||
public static List<Instance> selectAll(ServiceInfo serviceInfo) {
|
||||
|
@ -15,11 +15,14 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.naming.core;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.listener.EventListener;
|
||||
import com.alibaba.nacos.api.naming.listener.NamingEvent;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -32,7 +35,7 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
/**
|
||||
* @author xuanyin
|
||||
*/
|
||||
public class EventDispatcher {
|
||||
public class EventDispatcher implements Closeable {
|
||||
|
||||
private ExecutorService executor = null;
|
||||
|
||||
@ -43,7 +46,7 @@ public class EventDispatcher {
|
||||
|
||||
public EventDispatcher() {
|
||||
|
||||
executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
|
||||
this.executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r, "com.alibaba.nacos.naming.client.listener");
|
||||
@ -53,7 +56,7 @@ public class EventDispatcher {
|
||||
}
|
||||
});
|
||||
|
||||
executor.execute(new Notifier());
|
||||
this.executor.execute(new Notifier());
|
||||
}
|
||||
|
||||
public void addListener(ServiceInfo serviceInfo, String clusters, EventListener listener) {
|
||||
@ -109,6 +112,14 @@ public class EventDispatcher {
|
||||
changedServices.add(serviceInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executor, NAMING_LOGGER);
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
private class Notifier implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -20,22 +20,37 @@ import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.client.monitor.MetricsMonitor;
|
||||
import com.alibaba.nacos.client.naming.backups.FailoverReactor;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatInfo;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatReactor;
|
||||
import com.alibaba.nacos.client.naming.cache.DiskCache;
|
||||
import com.alibaba.nacos.client.naming.net.NamingProxy;
|
||||
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
|
||||
/**
|
||||
* @author xuanyin
|
||||
*/
|
||||
public class HostReactor {
|
||||
public class HostReactor implements Closeable {
|
||||
|
||||
private static final long DEFAULT_DELAY = 1000L;
|
||||
|
||||
@ -51,6 +66,8 @@ public class HostReactor {
|
||||
|
||||
private EventDispatcher eventDispatcher;
|
||||
|
||||
private BeatReactor beatReactor;
|
||||
|
||||
private NamingProxy serverProxy;
|
||||
|
||||
private FailoverReactor failoverReactor;
|
||||
@ -59,14 +76,14 @@ public class HostReactor {
|
||||
|
||||
private ScheduledExecutorService executor;
|
||||
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, String cacheDir) {
|
||||
this(eventDispatcher, serverProxy, cacheDir, false, UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, BeatReactor beatReactor, String cacheDir) {
|
||||
this(eventDispatcher, serverProxy, beatReactor, cacheDir, false, UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
|
||||
}
|
||||
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, String cacheDir,
|
||||
public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, BeatReactor beatReactor, String cacheDir,
|
||||
boolean loadCacheAtStart, int pollingThreadCount) {
|
||||
|
||||
executor = new ScheduledThreadPoolExecutor(pollingThreadCount, new ThreadFactory() {
|
||||
// init executorService
|
||||
this.executor = new ScheduledThreadPoolExecutor(pollingThreadCount, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r);
|
||||
@ -75,8 +92,8 @@ public class HostReactor {
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
this.beatReactor = beatReactor;
|
||||
this.serverProxy = serverProxy;
|
||||
this.cacheDir = cacheDir;
|
||||
if (loadCacheAtStart) {
|
||||
@ -174,6 +191,7 @@ public class HostReactor {
|
||||
|
||||
if (modHosts.size() > 0) {
|
||||
changed = true;
|
||||
updateBeatInfo(modHosts);
|
||||
NAMING_LOGGER.info("modified ips(" + modHosts.size() + ") service: "
|
||||
+ serviceInfo.getKey() + " -> " + JacksonUtils.toJson(modHosts));
|
||||
}
|
||||
@ -205,6 +223,16 @@ public class HostReactor {
|
||||
return serviceInfo;
|
||||
}
|
||||
|
||||
private void updateBeatInfo(Set<Instance> modHosts) {
|
||||
for (Instance instance : modHosts) {
|
||||
String key = beatReactor.buildKey(instance.getServiceName(), instance.getIp(), instance.getPort());
|
||||
if (beatReactor.dom2Beat.containsKey(key) && instance.isEphemeral()) {
|
||||
BeatInfo beatInfo = beatReactor.buildBeatInfo(instance);
|
||||
beatReactor.addBeatInfo(instance.getServiceName(), beatInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ServiceInfo getServiceInfo0(String serviceName, String clusters) {
|
||||
|
||||
String key = ServiceInfo.getKey(serviceName, clusters);
|
||||
@ -259,7 +287,6 @@ public class HostReactor {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void scheduleUpdateIfAbsent(String serviceName, String clusters) {
|
||||
if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) != null) {
|
||||
return;
|
||||
@ -303,6 +330,14 @@ public class HostReactor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executor, NAMING_LOGGER);
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
public class UpdateTask implements Runnable {
|
||||
long lastRefTime = Long.MAX_VALUE;
|
||||
private String clusters;
|
||||
|
@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.naming.core;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
@ -31,7 +34,7 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
/**
|
||||
* @author xuanyin
|
||||
*/
|
||||
public class PushReceiver implements Runnable {
|
||||
public class PushReceiver implements Runnable, Closeable {
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
@ -44,9 +47,9 @@ public class PushReceiver implements Runnable {
|
||||
public PushReceiver(HostReactor hostReactor) {
|
||||
try {
|
||||
this.hostReactor = hostReactor;
|
||||
udpSocket = new DatagramSocket();
|
||||
this.udpSocket = new DatagramSocket();
|
||||
|
||||
executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||
this.executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r);
|
||||
@ -56,7 +59,7 @@ public class PushReceiver implements Runnable {
|
||||
}
|
||||
});
|
||||
|
||||
executorService.execute(this);
|
||||
this.executorService.execute(this);
|
||||
} catch (Exception e) {
|
||||
NAMING_LOGGER.error("[NA] init udp socket failed", e);
|
||||
}
|
||||
@ -106,6 +109,14 @@ public class PushReceiver implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException {
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
|
||||
public static class PushPacket {
|
||||
public String type;
|
||||
public long lastRefTime;
|
||||
@ -113,6 +124,6 @@ public class PushReceiver implements Runnable {
|
||||
}
|
||||
|
||||
public int getUDPPort() {
|
||||
return udpSocket.getLocalPort();
|
||||
return this.udpSocket.getLocalPort();
|
||||
}
|
||||
}
|
||||
|
@ -37,11 +37,8 @@ import com.alibaba.nacos.client.security.SecurityProxy;
|
||||
import com.alibaba.nacos.client.utils.AppNameUtils;
|
||||
import com.alibaba.nacos.client.utils.TemplateUtils;
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||
import com.alibaba.nacos.common.utils.VersionUtils;
|
||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||
import com.alibaba.nacos.common.utils.*;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
@ -60,7 +57,7 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
|
||||
/**
|
||||
* @author nkorange
|
||||
*/
|
||||
public class NamingProxy {
|
||||
public class NamingProxy implements Closeable {
|
||||
|
||||
private static final int DEFAULT_SERVER_PORT = 8848;
|
||||
|
||||
@ -86,9 +83,11 @@ public class NamingProxy {
|
||||
|
||||
private Properties properties;
|
||||
|
||||
private ScheduledExecutorService executorService;
|
||||
|
||||
public NamingProxy(String namespaceId, String endpoint, String serverList, Properties properties) {
|
||||
|
||||
securityProxy = new SecurityProxy(properties);
|
||||
this.securityProxy = new SecurityProxy(properties);
|
||||
this.properties = properties;
|
||||
this.setServerPort(DEFAULT_SERVER_PORT);
|
||||
this.namespaceId = namespaceId;
|
||||
@ -99,13 +98,12 @@ public class NamingProxy {
|
||||
this.nacosDomain = serverList;
|
||||
}
|
||||
}
|
||||
|
||||
initRefreshTask();
|
||||
this.initRefreshTask();
|
||||
}
|
||||
|
||||
private void initRefreshTask() {
|
||||
|
||||
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(2, new ThreadFactory() {
|
||||
this.executorService = new ScheduledThreadPoolExecutor(2, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
@ -115,7 +113,7 @@ public class NamingProxy {
|
||||
}
|
||||
});
|
||||
|
||||
executorService.scheduleWithFixedDelay(new Runnable() {
|
||||
this.executorService.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
refreshSrvIfNeed();
|
||||
@ -123,7 +121,7 @@ public class NamingProxy {
|
||||
}, 0, vipSrvRefInterMillis, TimeUnit.MILLISECONDS);
|
||||
|
||||
|
||||
executorService.scheduleWithFixedDelay(new Runnable() {
|
||||
this.executorService.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
securityProxy.login(getServerList());
|
||||
@ -131,7 +129,7 @@ public class NamingProxy {
|
||||
}, 0, securityInfoRefreshIntervalMills, TimeUnit.MILLISECONDS);
|
||||
|
||||
refreshSrvIfNeed();
|
||||
securityProxy.login(getServerList());
|
||||
this.securityProxy.login(getServerList());
|
||||
}
|
||||
|
||||
public List<String> getServerListFromEndpoint() {
|
||||
@ -197,7 +195,7 @@ public class NamingProxy {
|
||||
NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}",
|
||||
namespaceId, serviceName, instance);
|
||||
|
||||
final Map<String, String> params = new HashMap<String, String>(9);
|
||||
final Map<String, String> params = new HashMap<String, String>(16);
|
||||
params.put(CommonParams.NAMESPACE_ID, namespaceId);
|
||||
params.put(CommonParams.SERVICE_NAME, serviceName);
|
||||
params.put(CommonParams.GROUP_NAME, groupName);
|
||||
@ -583,5 +581,12 @@ public class NamingProxy {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws NacosException{
|
||||
String className = this.getClass().getName();
|
||||
NAMING_LOGGER.info("{} do shutdown begin", className);
|
||||
ThreadUtils.shutdownThreadPool(executorService, NAMING_LOGGER);
|
||||
NAMING_LOGGER.info("{} do shutdown stop", className);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,15 +23,11 @@ import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.*;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
@ -52,6 +48,12 @@ public class ConfigTest {
|
||||
configService = NacosFactory.createConfigService(properties);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() throws Exception {
|
||||
configService.shutDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void test() throws Exception {
|
||||
final String dataId = "lessspring";
|
||||
final String group = "lessspring";
|
||||
|
@ -16,20 +16,23 @@
|
||||
|
||||
package com.alibaba.nacos.client.naming.core;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatInfo;
|
||||
import com.alibaba.nacos.client.naming.beat.BeatReactor;
|
||||
import com.alibaba.nacos.client.naming.net.NamingProxy;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||
import com.alibaba.nacos.client.naming.net.NamingProxy;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class HostReactorTest {
|
||||
|
||||
@ -43,15 +46,31 @@ public class HostReactorTest {
|
||||
|
||||
private HostReactor hostReactor;
|
||||
|
||||
private BeatReactor beatReactor;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
hostReactor = new HostReactor(eventDispatcher, namingProxy, CACHE_DIR);
|
||||
beatReactor = new BeatReactor(namingProxy);
|
||||
BeatInfo beatInfo = new BeatInfo();
|
||||
beatInfo.setServiceName("testName");
|
||||
beatInfo.setIp("1.1.1.1");
|
||||
beatInfo.setPort(1234);
|
||||
beatInfo.setCluster("clusterName");
|
||||
beatInfo.setWeight(1);
|
||||
beatInfo.setMetadata(new HashMap<String, String>());
|
||||
beatInfo.setScheduled(false);
|
||||
beatInfo.setPeriod(1000L);
|
||||
beatReactor.addBeatInfo("testName", beatInfo);
|
||||
hostReactor = new HostReactor(eventDispatcher, namingProxy, beatReactor, CACHE_DIR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessServiceJSON() {
|
||||
ServiceInfo actual = hostReactor.processServiceJSON(EXAMPLE);
|
||||
assertServiceInfo(actual);
|
||||
hostReactor.processServiceJSON(CHANGE_DATA_EXAMPLE);
|
||||
BeatInfo actualBeatInfo = beatReactor.dom2Beat.get(beatReactor.buildKey("testName", "1.1.1.1", 1234));
|
||||
assertEquals(2.0, actualBeatInfo.getWeight(), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -105,4 +124,30 @@ public class HostReactorTest {
|
||||
+ "\t\"allIPs\": false,\n"
|
||||
+ "\t\"valid\": true\n"
|
||||
+ "}";
|
||||
|
||||
//the weight changed from 1.0 to 2.0
|
||||
private static final String CHANGE_DATA_EXAMPLE = "{\n"
|
||||
+ "\t\"name\": \"testName\",\n"
|
||||
+ "\t\"clusters\": \"testClusters\",\n"
|
||||
+ "\t\"cacheMillis\": 1000,\n"
|
||||
+ "\t\"hosts\": [{\n"
|
||||
+ "\t\t\"ip\": \"1.1.1.1\",\n"
|
||||
+ "\t\t\"port\": 1234,\n"
|
||||
+ "\t\t\"weight\": 2.0,\n"
|
||||
+ "\t\t\"healthy\": true,\n"
|
||||
+ "\t\t\"enabled\": true,\n"
|
||||
+ "\t\t\"ephemeral\": true,\n"
|
||||
+ "\t\t\"clusterName\": \"testClusters\",\n"
|
||||
+ "\t\t\"serviceName\": \"testName\",\n"
|
||||
+ "\t\t\"metadata\": {},\n"
|
||||
+ "\t\t\"instanceHeartBeatInterval\": 5000,\n"
|
||||
+ "\t\t\"instanceHeartBeatTimeOut\": 15000,\n"
|
||||
+ "\t\t\"ipDeleteTimeout\": 30000,\n"
|
||||
+ "\t\t\"instanceIdGenerator\": \"simple\"\n"
|
||||
+ "\t}],\n"
|
||||
+ "\t\"lastRefTime\": 0,\n"
|
||||
+ "\t\"checksum\": \"\",\n"
|
||||
+ "\t\"allIPs\": false,\n"
|
||||
+ "\t\"valid\": true\n"
|
||||
+ "}";
|
||||
}
|
||||
|
@ -25,5 +25,10 @@ public interface HttpHeaderConsts {
|
||||
String CLIENT_VERSION_HEADER = "Client-Version";
|
||||
String USER_AGENT_HEADER = "User-Agent";
|
||||
String REQUEST_SOURCE_HEADER = "Request-Source";
|
||||
String CONTENT_TYPE = "Content-Type";
|
||||
String CONTENT_LENGTH = "Content-Length";
|
||||
String ACCEPT_CHARSET = "Accept-Charset";
|
||||
String ACCEPT_ENCODING = "Accept-Encoding";
|
||||
String CONTENT_ENCODING = "Content-Encoding";
|
||||
|
||||
}
|
||||
|
@ -16,14 +16,22 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.http.handler.RequestHandler;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpHead;
|
||||
@ -34,6 +42,7 @@ import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.client.methods.HttpTrace;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
@ -157,7 +166,6 @@ public enum BaseHttpMethod {
|
||||
if (body == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestBase instanceof HttpEntityEnclosingRequest) {
|
||||
HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) requestBase;
|
||||
ContentType contentType = ContentType.create(mediaType);
|
||||
@ -166,6 +174,21 @@ public enum BaseHttpMethod {
|
||||
}
|
||||
}
|
||||
|
||||
public void initFromEntity(Map<String, String> body, String charset) throws Exception{
|
||||
if (body.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<NameValuePair> params = new ArrayList<NameValuePair>(body.size());
|
||||
for (Map.Entry<String, String> entry : body.entrySet()) {
|
||||
params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
if (requestBase instanceof HttpEntityEnclosingRequest) {
|
||||
HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) requestBase;
|
||||
HttpEntity entity = new UrlEncodedFormEntity(params, charset);
|
||||
request.setEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public HttpRequestBase getRequestBase() {
|
||||
return (HttpRequestBase) requestBase;
|
||||
}
|
||||
|
@ -16,8 +16,12 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||
import com.alibaba.nacos.common.http.client.DefaultAsyncHttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.client.DefaultHttpClientRequest;
|
||||
import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
|
||||
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
|
||||
import com.alibaba.nacos.common.utils.ShutdownUtils;
|
||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
||||
@ -47,8 +51,15 @@ public class HttpClientManager {
|
||||
private static final NAsyncHttpClient ASYNC_HTTP_CLIENT = new NacosAsyncHttpClient(
|
||||
HttpAsyncClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
|
||||
|
||||
private static final NacosRestTemplate NACOS_REST_TEMPLATE = new NacosRestTemplate(
|
||||
new DefaultHttpClientRequest(HttpClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build()));
|
||||
|
||||
private static final NacosAsyncRestTemplate NACOS_ASYNC_REST_TEMPLATE = new NacosAsyncRestTemplate(
|
||||
new DefaultAsyncHttpClientRequest(HttpAsyncClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build()));
|
||||
|
||||
private static final AtomicBoolean alreadyShutdown = new AtomicBoolean(false);
|
||||
|
||||
|
||||
static {
|
||||
ShutdownUtils.addShutdownHook(new Runnable() {
|
||||
@Override
|
||||
@ -67,6 +78,14 @@ public class HttpClientManager {
|
||||
return ASYNC_HTTP_CLIENT;
|
||||
}
|
||||
|
||||
public static NacosRestTemplate getNacosRestTemplate() {
|
||||
return NACOS_REST_TEMPLATE;
|
||||
}
|
||||
|
||||
public static NacosAsyncRestTemplate getNacosAsyncRestTemplate() {
|
||||
return NACOS_ASYNC_REST_TEMPLATE;
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
if (!alreadyShutdown.compareAndSet(false, true)) {
|
||||
return;
|
||||
@ -75,6 +94,8 @@ public class HttpClientManager {
|
||||
try {
|
||||
SYNC_HTTP_CLIENT.close();
|
||||
ASYNC_HTTP_CLIENT.close();
|
||||
NACOS_REST_TEMPLATE.close();
|
||||
NACOS_ASYNC_REST_TEMPLATE.close();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.error("An exception occurred when the HTTP client was closed : {}",
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
|
||||
/**
|
||||
* http RestResult
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/31
|
||||
*/
|
||||
public class HttpRestResult<T> extends RestResult<T> {
|
||||
|
||||
private static final long serialVersionUID = 3766947816720175947L;
|
||||
private Header header;
|
||||
|
||||
public HttpRestResult() {
|
||||
}
|
||||
|
||||
public HttpRestResult(Header header, int code, T data) {
|
||||
super(code, data);
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public Header getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
public void setHeader(Header header) {
|
||||
this.header = header;
|
||||
}
|
||||
}
|
@ -16,9 +16,12 @@
|
||||
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
@ -120,6 +123,19 @@ public final class HttpUtils {
|
||||
return innerDecode(null, str, encode);
|
||||
}
|
||||
|
||||
/**
|
||||
* build URI By url and query
|
||||
* @param url url
|
||||
* @param query query param {@link Query}
|
||||
* @return
|
||||
*/
|
||||
public static URI buildUri(String url, Query query) throws URISyntaxException {
|
||||
if (!query.isEmpty()) {
|
||||
url = url + "?" + query.toQueryUrl();
|
||||
}
|
||||
return new URI(url);
|
||||
}
|
||||
|
||||
private static String innerDecode(String pre, String now, String encode) throws UnsupportedEncodingException {
|
||||
// Because the data may be encoded by the URL more than once,
|
||||
// it needs to be decoded recursively until it is fully successful
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.Callback;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Represents a client-side Async HTTP request.
|
||||
* Created via an implementation execute.
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/29
|
||||
*/
|
||||
public interface AsyncHttpClientRequest extends Closeable {
|
||||
|
||||
|
||||
/**
|
||||
* execute async http request
|
||||
*
|
||||
* @param uri http url
|
||||
* @param httpMethod http request method
|
||||
* @param requestHttpEntity http request entity
|
||||
* @param responseType http response type
|
||||
* @param callback http response callback
|
||||
* @throws Exception ex
|
||||
*/
|
||||
<T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity,
|
||||
final Type responseType, final Callback<T> callback) throws Exception;
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.Callback;
|
||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||
import com.alibaba.nacos.common.http.handler.ResponseHandler;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.concurrent.FutureCallback;
|
||||
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* {@link AsyncHttpClientRequest} implementation that uses apache async http client to
|
||||
* execute streaming requests
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/29
|
||||
*/
|
||||
public class DefaultAsyncHttpClientRequest implements AsyncHttpClientRequest {
|
||||
|
||||
private final CloseableHttpAsyncClient asyncClient;
|
||||
|
||||
public DefaultAsyncHttpClientRequest(CloseableHttpAsyncClient asyncClient) {
|
||||
this.asyncClient = asyncClient;
|
||||
if (!this.asyncClient.isRunning()) {
|
||||
this.asyncClient.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType, final Callback<T> callback) throws Exception {
|
||||
HttpRequestBase httpRequestBase = DefaultHttpClientRequest.build(uri, httpMethod, requestHttpEntity);
|
||||
asyncClient.execute(httpRequestBase, new FutureCallback<HttpResponse>() {
|
||||
@Override
|
||||
public void completed(HttpResponse result) {
|
||||
DefaultClientHttpResponse response = new DefaultClientHttpResponse(result);
|
||||
try {
|
||||
HttpRestResult<T> httpRestResult = ResponseHandler.responseEntityExtractor(response, responseType);
|
||||
callback.onReceive(httpRestResult);
|
||||
} catch (Exception e) {
|
||||
callback.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception ex) {
|
||||
callback.onError(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.asyncClient.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.utils.HttpClientUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* ApacheClientHttpResponse implementation {@link HttpClientResponse}
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/25
|
||||
*/
|
||||
public class DefaultClientHttpResponse implements HttpClientResponse {
|
||||
|
||||
private HttpResponse response;
|
||||
|
||||
private Header responseHeader;
|
||||
|
||||
public DefaultClientHttpResponse(HttpResponse response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return this.response.getStatusLine().getStatusCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusText() {
|
||||
return this.response.getStatusLine().getReasonPhrase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header getHeaders() {
|
||||
if (this.responseHeader == null) {
|
||||
this.responseHeader = Header.newInstance();
|
||||
org.apache.http.Header[] allHeaders = response.getAllHeaders();
|
||||
for (org.apache.http.Header header : allHeaders) {
|
||||
this.responseHeader.addParam(header.getName(), header.getValue());
|
||||
}
|
||||
}
|
||||
return this.responseHeader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException{
|
||||
return response.getEntity().getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
if (this.response != null) {
|
||||
HttpClientUtils.closeQuietly(response);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.BaseHttpMethod;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link HttpClientRequest} implementation that uses apache http client to
|
||||
* execute streaming requests
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/24
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "resource"})
|
||||
public class DefaultHttpClientRequest implements HttpClientRequest {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultHttpClientRequest.class);
|
||||
|
||||
private final CloseableHttpClient client;
|
||||
|
||||
public DefaultHttpClientRequest(CloseableHttpClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) throws Exception {
|
||||
HttpRequestBase request = build(uri, httpMethod, requestHttpEntity);
|
||||
CloseableHttpResponse response = client.execute(request);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Request from server: " + request.getURI().toString());
|
||||
}
|
||||
return new DefaultClientHttpResponse(response);
|
||||
}
|
||||
|
||||
static HttpRequestBase build(URI uri, String method, RequestHttpEntity requestHttpEntity) throws Exception {
|
||||
Header headers = requestHttpEntity.getHeaders();
|
||||
BaseHttpMethod httpMethod = BaseHttpMethod.sourceOf(method);
|
||||
httpMethod.init(uri.toString());
|
||||
httpMethod.initHeader(headers);
|
||||
if (MediaType.APPLICATION_FORM_URLENCODED.equals(headers.getValue(HttpHeaderConsts.CONTENT_TYPE))
|
||||
&& requestHttpEntity.getBody() instanceof Map) {
|
||||
httpMethod.initFromEntity((Map<String, String>) requestHttpEntity.getBody(), headers.getCharset());
|
||||
} else {
|
||||
httpMethod.initEntity(requestHttpEntity.getBody(), headers.getValue(HttpHeaderConsts.CONTENT_TYPE));
|
||||
}
|
||||
return httpMethod.getRequestBase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
client.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client;
|
||||
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Represents a client-side HTTP request.
|
||||
* Created via an implementation execute.
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/23
|
||||
*/
|
||||
public interface HttpClientRequest extends Closeable {
|
||||
|
||||
/**
|
||||
* execute http request
|
||||
* @param uri http url
|
||||
* @param httpMethod http request method
|
||||
* @param requestHttpEntity http request entity
|
||||
* @return HttpClientResponse
|
||||
* @throws Exception ex
|
||||
*/
|
||||
HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) throws Exception;
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.common.http.client;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Represents a client-side HTTP response.
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/23
|
||||
*/
|
||||
public interface HttpClientResponse extends Closeable {
|
||||
|
||||
/**
|
||||
* Return the headers of this message.
|
||||
* @return a corresponding HttpHeaders object (never {@code null})
|
||||
*/
|
||||
Header getHeaders();
|
||||
|
||||
/**
|
||||
* Return the body of the message as an input stream.
|
||||
* @return String response body
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
InputStream getBody() throws IOException;
|
||||
|
||||
/**
|
||||
* Return the HTTP status code
|
||||
* @return the HTTP status as an integer
|
||||
*/
|
||||
int getStatusCode();
|
||||
|
||||
/**
|
||||
* Return the HTTP status text of the response.
|
||||
* @return the HTTP status text
|
||||
*/
|
||||
String getStatusText();
|
||||
|
||||
/**
|
||||
* close response InputStream
|
||||
* @throws IOException ex
|
||||
*/
|
||||
@Override
|
||||
void close() throws IOException;
|
||||
}
|
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* 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.Callback;
|
||||
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.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* NacosAsyncRestTemplate async
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/29
|
||||
* @see AsyncHttpClientRequest
|
||||
* @see HttpClientResponse
|
||||
*/
|
||||
public class NacosAsyncRestTemplate {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(NacosAsyncRestTemplate.class);
|
||||
|
||||
private AsyncHttpClientRequest clientRequest;
|
||||
|
||||
public NacosAsyncRestTemplate(AsyncHttpClientRequest clientRequest) {
|
||||
this.clientRequest = clientRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* async http get
|
||||
* URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param responseType return type
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void get(String url, Header header, Query query, Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.GET, new RequestHttpEntity(header, query), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http get
|
||||
* URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header headers
|
||||
* @param paramValues paramValues
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void get(String url, Header header, Map<String, String> paramValues,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.GET, new RequestHttpEntity(header,
|
||||
Query.newInstance().initParams(paramValues)), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async get request, may be pulling a lot of data
|
||||
* URL request params are expanded using the given query {@link Query},
|
||||
* More request parameters can be set via body.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body get with body
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void getLarge(String url, Header header, Query query, Object body,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.GET_LARGE,
|
||||
new RequestHttpEntity(header, query, body), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http delete
|
||||
* URL request params are expanded using the given query {@link Query},
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void delete(String url, Header header, Query query,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.DELETE,
|
||||
new RequestHttpEntity(header, query), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http put
|
||||
* Create a new resource by PUTting the given body to http request.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void put(String url, Header header, Query query, Object body,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.PUT,
|
||||
new RequestHttpEntity(header, query, body), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http put Json
|
||||
* Create a new resource by PUTting the given body to http request,
|
||||
* http header contentType default 'application/json;charset=UTF-8'.
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void putJson(String url, Header header, Map<String, String> paramValues,
|
||||
String body, Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.PUT, new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_JSON),
|
||||
Query.newInstance().initParams(paramValues), body),
|
||||
responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http put from
|
||||
* Create a new resource by PUTting the given map {@code bodyValues} to http request,
|
||||
* http header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void putFrom(String url, Header header, Query query, Map<String, String> bodyValues,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.PUT, new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
query, bodyValues), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http put from
|
||||
* Create a new resource by PUTting the given map {@code bodyValues} to http request,
|
||||
* http header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void putFrom(String url, Header header, Map<String, String> paramValues,
|
||||
Map<String, String> bodyValues, Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.PUT, new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues), bodyValues), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http post
|
||||
* Create a new resource by POSTing the given object to the http request.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void post(String url, Header header, Query query, Object body,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.POST, new RequestHttpEntity(
|
||||
header, query, body), responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http post Json
|
||||
* Create a new resource by POSTing the given object to the http request,
|
||||
* http header contentType default 'application/json;charset=UTF-8'.
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void postJson(String url, Header header, Map<String, String> paramValues,
|
||||
String body, Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.POST, new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_JSON),
|
||||
Query.newInstance().initParams(paramValues), body),
|
||||
responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http post from
|
||||
* Create a new resource by PUTting the given map {@code bodyValues} to http request,
|
||||
* http header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void postFrom(String url, Header header, Query query, Map<String, String> bodyValues,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.POST, new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues),
|
||||
responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* async http post from
|
||||
* Create a new resource by PUTting the given map {@code bodyValues} to http request,
|
||||
* http header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>{@code responseType} can be an RestResult or RestResult data {@code T} type.
|
||||
* <p>{@code callback} Result callback execution,
|
||||
* if you need response headers, you can convert the received RestResult to HttpRestResult.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> void postFrom(String url, Header header, Map<String, String> paramValues,
|
||||
Map<String, String> bodyValues, Type responseType, Callback<T> callback) throws Exception {
|
||||
execute(url, HttpMethod.POST, new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues),
|
||||
bodyValues), responseType, callback);
|
||||
|
||||
}
|
||||
|
||||
private <T> void execute(String url, String httpMethod, RequestHttpEntity requestEntity,
|
||||
Type responseType, Callback<T> callback) throws Exception {
|
||||
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("HTTP " + httpMethod + " " + url);
|
||||
}
|
||||
clientRequest.execute(uri, httpMethod, requestEntity, responseType, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* close request client
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
clientRequest.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,315 @@
|
||||
/*
|
||||
* 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.HttpUtils;
|
||||
import com.alibaba.nacos.common.http.handler.ResponseHandler;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.MediaType;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RequestHttpEntity;
|
||||
import com.alibaba.nacos.common.utils.HttpMethod;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* NacosRestTemplate
|
||||
* Interface specifying a basic set of RESTful operations.
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/24
|
||||
* @see HttpClientRequest
|
||||
* @see HttpClientResponse
|
||||
*/
|
||||
public class NacosRestTemplate {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(NacosRestTemplate.class);
|
||||
|
||||
private HttpClientRequest requestClient;
|
||||
|
||||
public NacosRestTemplate(HttpClientRequest requestClient) {
|
||||
this.requestClient = requestClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* http get
|
||||
* URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> get(String url, Header header, Query query, Type responseType) throws Exception {
|
||||
return execute(url, HttpMethod.GET, new RequestHttpEntity(header, query), responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http get
|
||||
* URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header headers
|
||||
* @param paramValues paramValues
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> get(String url, Header header, Map<String, String> paramValues, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header, Query.newInstance().initParams(paramValues));
|
||||
return execute(url, HttpMethod.GET, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* get request, may be pulling a lot of data
|
||||
* URL request params are expanded using the given query {@link Query},
|
||||
* More request parameters can be set via body.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body get with body
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> getLarge(String url, Header header, Query query, Object body, Type responseType) throws Exception {
|
||||
return execute(url, HttpMethod.GET_LARGE, new RequestHttpEntity(header, query, body), responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http delete
|
||||
* URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> delete(String url, Header header, Query query, Type responseType) throws Exception {
|
||||
return execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http put
|
||||
* Create a new resource by PUTting the given body to http request.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> put(String url, Header header, Query query, Object body, Type responseType) throws Exception {
|
||||
return execute(url, HttpMethod.PUT, new RequestHttpEntity(header, query, body), responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http put json
|
||||
* Create a new resource by PUTting the given body to http request,
|
||||
* http header contentType default 'application/json;charset=UTF-8'.
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> putJson(String url, Header header, Map<String, String> paramValues, String body, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_JSON),
|
||||
Query.newInstance().initParams(paramValues),
|
||||
body);
|
||||
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http put from
|
||||
* Create a new resource by PUTting the given map {@code bodyValues} to http request,
|
||||
* http header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
* <p>URL request params are expanded using the given query {@code Query}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> putFrom(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues);
|
||||
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http put from
|
||||
* Create a new resource by PUTting the given map {@code bodyValues} to http request,
|
||||
* http header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> putFrom(String url, Header header, Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues),
|
||||
bodyValues);
|
||||
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http post
|
||||
* Create a new resource by POSTing the given object to the http request.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> post(String url, Header header, Query query, Object body, Type responseType) throws Exception {
|
||||
return execute(url, HttpMethod.POST, new RequestHttpEntity(header, query, body),
|
||||
responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http post json
|
||||
* Create a new resource by POSTing the given object to the http request,
|
||||
* http header contentType default 'application/json;charset=UTF-8'.
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param body http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> postJson(String url, Header header, Map<String, String> paramValues, String body, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_JSON),
|
||||
Query.newInstance().initParams(paramValues),
|
||||
body);
|
||||
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http post from
|
||||
* Create a new resource by PUTting the given map {@code bodyValues} to http request,
|
||||
* http header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
* <p>URL request params are expanded using the given query {@link Query}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param query http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> postFrom(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues);
|
||||
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* http post from
|
||||
* Create a new resource by PUTting the given map {@code bodyValues} to http request,
|
||||
* http header contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
|
||||
* <p>URL request params are expanded using the given map {@code paramValues}.
|
||||
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
|
||||
*
|
||||
* @param url url
|
||||
* @param header http header param
|
||||
* @param paramValues http query param
|
||||
* @param bodyValues http body param
|
||||
* @param responseType return type
|
||||
* @return {@link HttpRestResult}
|
||||
* @throws Exception ex
|
||||
*/
|
||||
public <T> HttpRestResult<T> postFrom(String url, Header header, Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
|
||||
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(
|
||||
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
|
||||
Query.newInstance().initParams(paramValues),
|
||||
bodyValues);
|
||||
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
|
||||
}
|
||||
|
||||
private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttpEntity requestEntity,
|
||||
Type responseType) throws Exception {
|
||||
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("HTTP " + httpMethod + " " + url);
|
||||
}
|
||||
HttpClientResponse response = null;
|
||||
try {
|
||||
response = requestClient.execute(uri, httpMethod, requestEntity);
|
||||
return ResponseHandler.responseEntityExtractor(response, responseType);
|
||||
} finally {
|
||||
if (response != null) {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* close request client
|
||||
*/
|
||||
public void close() throws Exception{
|
||||
requestClient.close();
|
||||
}
|
||||
|
||||
}
|
@ -16,10 +16,21 @@
|
||||
|
||||
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 org.apache.http.HttpStatus;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
@ -37,4 +48,41 @@ public final class ResponseHandler {
|
||||
return JacksonUtils.toObj(s, type);
|
||||
}
|
||||
|
||||
public static <T> T convert(InputStream inputStream, Type type) throws Exception {
|
||||
return JacksonUtils.toObj(inputStream, type);
|
||||
}
|
||||
|
||||
@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;
|
||||
if (MediaType.APPLICATION_JSON.equals(contentType) && HttpStatus.SC_OK == response.getStatusCode()) {
|
||||
extractBody = convert(body, type);
|
||||
}
|
||||
if (extractBody == null) {
|
||||
if (!String.class.toString().equals(type.toString())) {
|
||||
logger.error("if the response contentType is not [application/json]," +
|
||||
" only support to java.lang.String");
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
||||
package com.alibaba.nacos.common.http.param;
|
||||
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -34,10 +38,10 @@ public class Header {
|
||||
|
||||
private Header() {
|
||||
header = new LinkedHashMap<String, String>();
|
||||
addParam("Content-Type", "application/json");
|
||||
addParam("Accept-Charset", "UTF-8");
|
||||
addParam("Accept-Encoding", "gzip");
|
||||
addParam("Content-Encoding", "gzip");
|
||||
addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_JSON);
|
||||
addParam(HttpHeaderConsts.ACCEPT_CHARSET, "UTF-8");
|
||||
addParam(HttpHeaderConsts.ACCEPT_ENCODING, "gzip");
|
||||
addParam(HttpHeaderConsts.CONTENT_ENCODING, "gzip");
|
||||
}
|
||||
|
||||
public static Header newInstance() {
|
||||
@ -49,7 +53,14 @@ public class Header {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Header builded() {
|
||||
public Header setContentType(String contentType) {
|
||||
if (contentType == null) {
|
||||
contentType = MediaType.APPLICATION_JSON;
|
||||
}
|
||||
return addParam(HttpHeaderConsts.CONTENT_TYPE, contentType);
|
||||
}
|
||||
|
||||
public Header build() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -76,13 +87,14 @@ public class Header {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void addAll(List<String> list) {
|
||||
public Header addAll(List<String> list) {
|
||||
if ((list.size() & 1) != 0) {
|
||||
throw new IllegalArgumentException("list size must be a multiple of 2");
|
||||
}
|
||||
for (int i = 0; i < list.size();) {
|
||||
header.put(list.get(i++), list.get(i++));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void addAll(Map<String, String> params) {
|
||||
@ -91,9 +103,38 @@ public class Header {
|
||||
}
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
String acceptCharset = getValue(HttpHeaderConsts.ACCEPT_CHARSET);
|
||||
if (acceptCharset == null) {
|
||||
String contentType = getValue(HttpHeaderConsts.CONTENT_TYPE);
|
||||
acceptCharset = StringUtils.isNotBlank(contentType) ? analysisCharset(contentType) : Constants.ENCODE;
|
||||
}
|
||||
return acceptCharset;
|
||||
}
|
||||
|
||||
private String analysisCharset(String contentType) {
|
||||
String[] values = contentType.split(";");
|
||||
String charset = Constants.ENCODE;
|
||||
if (values.length == 0) {
|
||||
return charset;
|
||||
}
|
||||
for (String value : values) {
|
||||
if (value.startsWith("charset=")) {
|
||||
charset = value.substring("charset=".length());
|
||||
}
|
||||
}
|
||||
return charset;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
header.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Header{" +
|
||||
"headerToMap=" + header +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,8 @@ public final class MediaType {
|
||||
|
||||
public static final String APPLICATION_XML = "application/xml";
|
||||
|
||||
public static final String APPLICATION_JSON = "application/json";
|
||||
|
||||
public static final String MULTIPART_FORM_DATA = "multipart/form-data";
|
||||
|
||||
public static final String TEXT_HTML = "text/html";
|
||||
|
@ -52,10 +52,11 @@ public class Query {
|
||||
return params.get(key);
|
||||
}
|
||||
|
||||
public void initParams(Map<String, String> params) {
|
||||
public Query initParams(Map<String, String> params) {
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
addParam(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void initParams(List<String> list) {
|
||||
|
@ -13,15 +13,25 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.nacos.common.lifecycle;
|
||||
|
||||
package com.alibaba.nacos.config.server.filter;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
* An interface is used to define the resource's close and shutdown,
|
||||
* such as IO Connection and ThreadPool.
|
||||
*
|
||||
* @author zongtanghu
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ToLeader {
|
||||
public interface Closeable {
|
||||
|
||||
/**
|
||||
* Shutdown the Resources, such as Thread Pool.
|
||||
*
|
||||
* @throws NacosException exception.
|
||||
*/
|
||||
public void shutdown() throws NacosException;
|
||||
|
||||
}
|
@ -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.model;
|
||||
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* Represents an HTTP request , consisting of headers and body.
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/23
|
||||
*/
|
||||
public class RequestHttpEntity {
|
||||
|
||||
private final Header headers = Header.newInstance();
|
||||
|
||||
private final Query query;
|
||||
|
||||
private Object body;
|
||||
|
||||
public RequestHttpEntity(Header header, Query query) {
|
||||
handleHeader(header);
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public RequestHttpEntity(Header header, Query query, Object body) {
|
||||
handleHeader(header);
|
||||
this.query = query;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
private void handleHeader(Header header) {
|
||||
if (header != null && !header.getHeader().isEmpty()) {
|
||||
Map<String, String> headerMap = header.getHeader();
|
||||
headers.addAll(headerMap);
|
||||
}
|
||||
}
|
||||
|
||||
public Header getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
public Query getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
public Object getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public boolean isEmptyBody() {
|
||||
return body == null;
|
||||
}
|
||||
|
||||
}
|
@ -179,6 +179,13 @@ public final class CollectionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> boolean contains(Collection<T> coll, T target) {
|
||||
if (isEmpty(coll)) {
|
||||
return false;
|
||||
}
|
||||
return coll.contains(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe check if the specified collection is empty.
|
||||
* <p>
|
||||
|
@ -28,6 +28,7 @@ import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
@ -46,8 +47,7 @@ public final class JacksonUtils {
|
||||
public static String toJson(Object obj) {
|
||||
try {
|
||||
return mapper.writeValueAsString(obj);
|
||||
}
|
||||
catch (JsonProcessingException e) {
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new NacosSerializationException(obj.getClass(), e);
|
||||
}
|
||||
}
|
||||
@ -55,8 +55,7 @@ public final class JacksonUtils {
|
||||
public static byte[] toJsonBytes(Object obj) {
|
||||
try {
|
||||
return ByteUtils.toBytes(mapper.writeValueAsString(obj));
|
||||
}
|
||||
catch (JsonProcessingException e) {
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new NacosSerializationException(obj.getClass(), e);
|
||||
}
|
||||
}
|
||||
@ -64,35 +63,39 @@ public final class JacksonUtils {
|
||||
public static <T> T toObj(byte[] json, Class<T> cls) {
|
||||
try {
|
||||
return toObj(StringUtils.newString4UTF8(json), cls);
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
throw new NacosDeserializationException(cls, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T toObj(byte[] json, Type cls) {
|
||||
try {
|
||||
return toObj(StringUtils.newString4UTF8(json), cls);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new NacosDeserializationException(e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return toObj(StringUtils.newString4UTF8(json), cls);
|
||||
} catch (Exception e) {
|
||||
throw new NacosDeserializationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T toObj(byte[] json, TypeReference<T> typeReference) {
|
||||
try {
|
||||
return toObj(StringUtils.newString4UTF8(json), typeReference);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new NacosDeserializationException(e);
|
||||
}
|
||||
}
|
||||
public static <T> T toObj(InputStream inputStream, Class<T> tClass) {
|
||||
try {
|
||||
return mapper.readValue(inputStream, tClass);
|
||||
} catch (IOException e) {
|
||||
throw new NacosDeserializationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T toObj(byte[] json, TypeReference<T> typeReference) {
|
||||
try {
|
||||
return toObj(StringUtils.newString4UTF8(json), typeReference);
|
||||
} catch (Exception e) {
|
||||
throw new NacosDeserializationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T toObj(String json, Class<T> cls) {
|
||||
try {
|
||||
return mapper.readValue(json, cls);
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new NacosDeserializationException(cls, e);
|
||||
}
|
||||
}
|
||||
@ -100,8 +103,7 @@ public final class JacksonUtils {
|
||||
public static <T> T toObj(String json, Type type) {
|
||||
try {
|
||||
return mapper.readValue(json, mapper.constructType(type));
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new NacosDeserializationException(e);
|
||||
}
|
||||
}
|
||||
@ -109,17 +111,23 @@ public final class JacksonUtils {
|
||||
public static <T> T toObj(String json, TypeReference<T> typeReference) {
|
||||
try {
|
||||
return mapper.readValue(json, typeReference);
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new NacosDeserializationException(typeReference.getClass(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T toObj(InputStream inputStream, Type type) {
|
||||
try {
|
||||
return mapper.readValue(inputStream, mapper.constructType(type));
|
||||
} catch (IOException e) {
|
||||
throw new NacosDeserializationException(type, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonNode toObj(String json) {
|
||||
try {
|
||||
return mapper.readTree(json);
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new NacosDeserializationException(e);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
package com.alibaba.nacos.common.http;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class HttpUtilsTest {
|
||||
|
||||
@Test
|
||||
public void test_url_encode() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,6 @@ import com.alibaba.nacos.common.utils.MapUtils;
|
||||
import com.alibaba.nacos.config.server.auth.ConfigResourceParser;
|
||||
import com.alibaba.nacos.config.server.constant.Constants;
|
||||
import com.alibaba.nacos.config.server.controller.parameters.SameNamespaceCloneConfigBean;
|
||||
import com.alibaba.nacos.config.server.filter.ToLeader;
|
||||
import com.alibaba.nacos.config.server.model.ConfigAdvanceInfo;
|
||||
import com.alibaba.nacos.config.server.model.ConfigAllInfo;
|
||||
import com.alibaba.nacos.config.server.model.ConfigInfo;
|
||||
@ -34,6 +33,7 @@ import com.alibaba.nacos.config.server.result.ResultBuilder;
|
||||
import com.alibaba.nacos.config.server.result.code.ResultCodeEnum;
|
||||
import com.alibaba.nacos.config.server.service.AggrWhitelist;
|
||||
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
||||
import com.alibaba.nacos.config.server.service.ConfigChangePublisher;
|
||||
import com.alibaba.nacos.config.server.service.ConfigSubService;
|
||||
import com.alibaba.nacos.config.server.service.repository.PersistService;
|
||||
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
||||
@ -42,7 +42,6 @@ import com.alibaba.nacos.config.server.utils.ParamUtils;
|
||||
import com.alibaba.nacos.config.server.utils.RequestUtil;
|
||||
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
||||
import com.alibaba.nacos.config.server.utils.ZipUtils;
|
||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher;
|
||||
import com.alibaba.nacos.core.auth.ActionTypes;
|
||||
import com.alibaba.nacos.core.auth.Secured;
|
||||
import com.alibaba.nacos.core.utils.InetUtils;
|
||||
@ -113,17 +112,16 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加或更新非聚合数据。
|
||||
* Adds or updates non-aggregated data.
|
||||
*
|
||||
* @throws NacosException
|
||||
*/
|
||||
@PostMapping
|
||||
@ToLeader
|
||||
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
|
||||
public Boolean publishConfig(HttpServletRequest request, HttpServletResponse response,
|
||||
@RequestParam("dataId") String dataId, @RequestParam("group") String group,
|
||||
@RequestParam(value = "dataId") String dataId, @RequestParam(value = "group") String group,
|
||||
@RequestParam(value = "tenant", required = false, defaultValue = StringUtils.EMPTY) String tenant,
|
||||
@RequestParam("content") String content,
|
||||
@RequestParam(value = "content") String content,
|
||||
@RequestParam(value = "tag", required = false) String tag,
|
||||
@RequestParam(value = "appName", required = false) String appName,
|
||||
@RequestParam(value = "src_user", required = false) String srcUser,
|
||||
@ -165,16 +163,19 @@ public class ConfigController {
|
||||
if (StringUtils.isBlank(tag)) {
|
||||
persistService.insertOrUpdate(srcIp, srcUser, configInfo, time,
|
||||
configAdvanceInfo, true);
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(false, dataId, group, tenant, time.getTime()));
|
||||
}
|
||||
else {
|
||||
persistService
|
||||
.insertOrUpdateTag(configInfo, tag, srcIp, srcUser, time, true);
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(false, dataId, group, tenant, tag, time.getTime()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// beta publish
|
||||
persistService
|
||||
.insertOrUpdateBeta(configInfo, betaIps, srcIp, srcUser, time, true);
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(true, dataId, group, tenant, time.getTime()));
|
||||
}
|
||||
ConfigTraceService.logPersistenceEvent(dataId, group, tenant, requestIpApp, time.getTime(),
|
||||
InetUtils.getSelfIp(), ConfigTraceService.PERSISTENCE_EVENT_PUB, content);
|
||||
@ -182,7 +183,7 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取数据
|
||||
* get configure board infomation fail
|
||||
*
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
@ -207,7 +208,7 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取数据
|
||||
* Get the specific configuration information that the console USES
|
||||
*
|
||||
* @throws NacosException
|
||||
*/
|
||||
@ -226,12 +227,11 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步删除某个dataId下面所有的聚合前数据
|
||||
* Synchronously delete all pre-aggregation data under a dataId
|
||||
*
|
||||
* @throws NacosException
|
||||
*/
|
||||
@DeleteMapping
|
||||
@ToLeader
|
||||
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
|
||||
public Boolean deleteConfig(HttpServletRequest request, HttpServletResponse response,
|
||||
@RequestParam("dataId") String dataId, //
|
||||
@ -255,6 +255,7 @@ public class ConfigController {
|
||||
ConfigTraceService
|
||||
.logPersistenceEvent(dataId, group, tenant, null, time.getTime(),
|
||||
clientIp, ConfigTraceService.PERSISTENCE_EVENT_REMOVE, null);
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(false, dataId, group, tenant, tag, time.getTime()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -266,7 +267,6 @@ public class ConfigController {
|
||||
* @Param [request, response, dataId, group, tenant, tag]
|
||||
*/
|
||||
@DeleteMapping(params = "delType=ids")
|
||||
@ToLeader
|
||||
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
|
||||
public RestResult<Boolean> deleteConfigs(HttpServletRequest request,
|
||||
HttpServletResponse response, @RequestParam(value = "ids") List<Long> ids) {
|
||||
@ -276,6 +276,8 @@ public class ConfigController {
|
||||
.removeConfigInfoByIds(ids, clientIp, null);
|
||||
if (!CollectionUtils.isEmpty(configInfoList)) {
|
||||
for (ConfigInfo configInfo : configInfoList) {
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(false, configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(), time.getTime()));
|
||||
ConfigTraceService.logPersistenceEvent(configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(), null,
|
||||
time.getTime(), clientIp,
|
||||
@ -299,7 +301,7 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较MD5
|
||||
* The client listens for configuration changes
|
||||
*/
|
||||
@PostMapping("/listener")
|
||||
@Secured(action = ActionTypes.READ, parser = ConfigResourceParser.class)
|
||||
@ -326,7 +328,7 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅改配置的客户端信息
|
||||
* Subscribe to configured client information
|
||||
*/
|
||||
@GetMapping("/listener")
|
||||
@Secured(action = ActionTypes.READ, parser = ConfigResourceParser.class)
|
||||
@ -348,7 +350,7 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询配置信息,返回JSON格式。
|
||||
* Query the configuration information and return it in JSON format.
|
||||
*/
|
||||
@GetMapping(params = "search=accurate")
|
||||
@Secured(action = ActionTypes.READ, parser = ConfigResourceParser.class)
|
||||
@ -379,7 +381,8 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 模糊查询配置信息。不允许只根据内容模糊查询,即dataId和group都为NULL,但content不是NULL。这种情况下,返回所有配置。
|
||||
* Fuzzy query configuration information. Fuzzy queries based only on content are not allowed, that is,
|
||||
* both dataId and group are NULL, but content is not NULL. In this case, all configurations are returned.
|
||||
*/
|
||||
@GetMapping(params = "search=blur")
|
||||
@Secured(action = ActionTypes.READ, parser = ConfigResourceParser.class)
|
||||
@ -410,7 +413,6 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
@DeleteMapping(params = "beta=true")
|
||||
@ToLeader
|
||||
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
|
||||
public RestResult<Boolean> stopBeta(@RequestParam(value = "dataId") String dataId,
|
||||
@RequestParam(value = "group") String group,
|
||||
@ -426,6 +428,7 @@ public class ConfigController {
|
||||
rr.setMessage("remove beta data error");
|
||||
return rr;
|
||||
}
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(true, dataId, group, tenant, System.currentTimeMillis()));
|
||||
rr.setCode(200);
|
||||
rr.setData(true);
|
||||
rr.setMessage("stop beta ok");
|
||||
@ -504,7 +507,6 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
@PostMapping(params = "import=true")
|
||||
@ToLeader
|
||||
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
|
||||
public RestResult<Map<String, Object>> importAndPublishConfig(
|
||||
HttpServletRequest request,
|
||||
@ -593,7 +595,7 @@ public class ConfigController {
|
||||
.batchInsertOrUpdate(configInfoList, srcUser, srcIp, null, time, false,
|
||||
policy);
|
||||
for (ConfigInfo configInfo : configInfoList) {
|
||||
EventDispatcher.fireEvent(
|
||||
ConfigChangePublisher.notifyConfigChange(
|
||||
new ConfigDataChangeEvent(false, configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(),
|
||||
time.getTime()));
|
||||
@ -607,7 +609,6 @@ public class ConfigController {
|
||||
}
|
||||
|
||||
@PostMapping(params = "clone=true")
|
||||
@ToLeader
|
||||
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
|
||||
public RestResult<Map<String, Object>> cloneConfig(HttpServletRequest request,
|
||||
@RequestParam(value = "src_user", required = false) String srcUser,
|
||||
@ -681,7 +682,7 @@ public class ConfigController {
|
||||
.batchInsertOrUpdate(configInfoList4Clone, srcUser, srcIp, null, time,
|
||||
false, policy);
|
||||
for (ConfigInfo configInfo : configInfoList4Clone) {
|
||||
EventDispatcher.fireEvent(
|
||||
ConfigChangePublisher.notifyConfigChange(
|
||||
new ConfigDataChangeEvent(false, configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(),
|
||||
time.getTime()));
|
||||
@ -691,7 +692,7 @@ public class ConfigController {
|
||||
InetUtils.getSelfIp(), ConfigTraceService.PERSISTENCE_EVENT_PUB,
|
||||
configInfo.getContent());
|
||||
}
|
||||
return ResultBuilder.buildSuccessResult("克隆成功", saveResult);
|
||||
return ResultBuilder.buildSuccessResult("Clone Completed Successfully", saveResult);
|
||||
}
|
||||
|
||||
private String processTenant(String tenant) {
|
||||
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.service;
|
||||
|
||||
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class ConfigChangePublisher {
|
||||
|
||||
public static void notifyConfigChange(ConfigDataChangeEvent event) {
|
||||
if (PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode()) {
|
||||
return;
|
||||
}
|
||||
EventDispatcher.fireEvent(event);
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.nacos.config.server.service;
|
||||
|
||||
import com.alibaba.nacos.common.utils.CollectionUtils;
|
||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||
import com.alibaba.nacos.config.server.model.SampleResult;
|
||||
import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent;
|
||||
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
|
||||
@ -308,7 +310,7 @@ public class LongPollingService extends AbstractEventListener {
|
||||
ClientLongPolling clientSub = iter.next();
|
||||
if (clientSub.clientMd5Map.containsKey(groupKey)) {
|
||||
// 如果beta发布且不在beta列表直接跳过
|
||||
if (isBeta && !betaIps.contains(clientSub.ip)) {
|
||||
if (isBeta && !CollectionUtils.contains(betaIps, clientSub.ip)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -329,14 +331,10 @@ public class LongPollingService extends AbstractEventListener {
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LogUtil.defaultLog.error("data change error:" + t.getMessage(), t.getCause());
|
||||
LogUtil.defaultLog.error("data change error: {}", ExceptionUtil.getStackTrace(t));
|
||||
}
|
||||
}
|
||||
|
||||
DataChangeTask(String groupKey) {
|
||||
this(groupKey, false, null);
|
||||
}
|
||||
|
||||
DataChangeTask(String groupKey, boolean isBeta, List<String> betaIps) {
|
||||
this(groupKey, isBeta, betaIps, null);
|
||||
}
|
||||
@ -475,6 +473,14 @@ public class LongPollingService extends AbstractEventListener {
|
||||
final long timeoutTime;
|
||||
|
||||
Future<?> asyncTimeoutFuture;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ClientLongPolling{" + "clientMd5Map=" + clientMd5Map + ", createTime="
|
||||
+ createTime + ", ip='" + ip + '\'' + ", appName='" + appName + '\''
|
||||
+ ", tag='" + tag + '\'' + ", probeRequestSize=" + probeRequestSize
|
||||
+ ", timeoutTime=" + timeoutTime + '}';
|
||||
}
|
||||
}
|
||||
|
||||
void generateResponse(HttpServletRequest request, HttpServletResponse response, List<String> changedGroups) {
|
||||
|
@ -93,6 +93,12 @@ public abstract class DumpService {
|
||||
|
||||
this.dumpAllTaskMgr = new TaskManager("com.alibaba.nacos.server.DumpAllTaskManager");
|
||||
this.dumpAllTaskMgr.setDefaultTaskProcessor(dumpAllProcessor);
|
||||
|
||||
this.dumpAllTaskMgr.addProcessor(DumpAllTask.TASK_ID, dumpAllProcessor);
|
||||
this.dumpAllTaskMgr.addProcessor(DumpAllBetaTask.TASK_ID, dumpAllBetaProcessor);
|
||||
this.dumpAllTaskMgr.addProcessor(DumpAllTagTask.TASK_ID, dumpAllTagProcessor);
|
||||
|
||||
|
||||
DynamicDataSource.getInstance().getDataSource();
|
||||
}
|
||||
|
||||
@ -124,6 +130,9 @@ public abstract class DumpService {
|
||||
Runnable dumpAllBeta = () -> dumpAllTaskMgr
|
||||
.addTask(DumpAllBetaTask.TASK_ID, new DumpAllBetaTask());
|
||||
|
||||
Runnable dumpAllTag = () -> dumpAllTaskMgr
|
||||
.addTask(DumpAllTagTask.TASK_ID, new DumpAllTagTask());
|
||||
|
||||
Runnable clearConfigHistory = () -> {
|
||||
log.warn("clearConfigHistory start");
|
||||
if (canExecute()) {
|
||||
@ -212,7 +221,10 @@ public abstract class DumpService {
|
||||
DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES);
|
||||
|
||||
ConfigExecutor.scheduleWithFixedDelay(dumpAllBeta, initialDelay,
|
||||
DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES);
|
||||
DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES);
|
||||
|
||||
ConfigExecutor.scheduleWithFixedDelay(dumpAllTag, initialDelay,
|
||||
DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
ConfigExecutor
|
||||
|
@ -160,17 +160,11 @@ public class EmbeddedDumpService extends DumpService {
|
||||
|
||||
@Override
|
||||
protected boolean canExecute() {
|
||||
try {
|
||||
// if is derby + raft mode, only leader can execute
|
||||
CPProtocol protocol = protocolManager.getCpProtocol();
|
||||
return protocol.isLeader(Constants.CONFIG_MODEL_RAFT_GROUP);
|
||||
}
|
||||
catch (NoSuchRaftGroupException e) {
|
||||
if (ApplicationUtils.getStandaloneMode()) {
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
// It's impossible to get to this point
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// if is derby + raft mode, only leader can execute
|
||||
CPProtocol protocol = protocolManager.getCpProtocol();
|
||||
return protocol.isLeader(Constants.CONFIG_MODEL_RAFT_GROUP);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,9 @@ import com.alibaba.nacos.config.server.utils.ContentUtils;
|
||||
import com.alibaba.nacos.config.server.utils.PropertyUtil;
|
||||
import com.alibaba.nacos.config.server.utils.TimeUtils;
|
||||
import com.alibaba.nacos.consistency.cp.CPProtocol;
|
||||
import com.alibaba.nacos.core.distributed.ProtocolManager;
|
||||
import com.alibaba.nacos.core.distributed.raft.exception.NoSuchRaftGroupException;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
import com.alibaba.nacos.core.utils.InetUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -53,8 +55,6 @@ public class MergeDatumService {
|
||||
static final AtomicInteger FINISHED = new AtomicInteger();
|
||||
static int total = 0;
|
||||
|
||||
private CPProtocol protocol;
|
||||
|
||||
@Autowired
|
||||
public MergeDatumService(PersistService persistService) {
|
||||
this.persistService = persistService;
|
||||
@ -109,14 +109,11 @@ public class MergeDatumService {
|
||||
if (!PropertyUtil.isEmbeddedStorage()) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return protocol.isLeader(Constants.CONFIG_MODEL_RAFT_GROUP);
|
||||
} catch (NoSuchRaftGroupException e) {
|
||||
if (ApplicationUtils.getStandaloneMode()) {
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
// It's impossible to get to this point
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ProtocolManager protocolManager = ApplicationUtils.getBean(ProtocolManager.class);
|
||||
return protocolManager.getCpProtocol().isLeader(Constants.CONFIG_MODEL_RAFT_GROUP);
|
||||
}
|
||||
|
||||
class MergeAllDataWorker extends Thread {
|
||||
|
@ -49,7 +49,6 @@ import com.google.common.collect.Lists;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
@ -2610,3 +2609,4 @@ public class EmbeddedStoragePersistServiceImpl implements PersistService {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -38,13 +38,10 @@ import com.alibaba.nacos.config.server.model.Page;
|
||||
import com.alibaba.nacos.config.server.model.SameConfigPolicy;
|
||||
import com.alibaba.nacos.config.server.model.SubInfo;
|
||||
import com.alibaba.nacos.config.server.model.TenantInfo;
|
||||
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
||||
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.trace.ConfigTraceService;
|
||||
import com.alibaba.nacos.config.server.utils.LogUtil;
|
||||
import com.alibaba.nacos.config.server.utils.ParamUtils;
|
||||
import com.alibaba.nacos.config.server.utils.event.EventDispatcher;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
@ -184,12 +181,6 @@ public class ExternalStoragePersistServiceImpl implements PersistService {
|
||||
addConfigTagsRelation(configId, configTags, configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant());
|
||||
insertConfigHistoryAtomic(0, configInfo, srcIp, srcUser, time, "I");
|
||||
if (notify) {
|
||||
EventDispatcher.fireEvent(
|
||||
new ConfigDataChangeEvent(false, configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(),
|
||||
time.getTime()));
|
||||
}
|
||||
}
|
||||
catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
@ -349,10 +340,6 @@ public class ExternalStoragePersistServiceImpl implements PersistService {
|
||||
updateConfigInfo4Beta(configInfo, betaIps, srcIp, null, time,
|
||||
notify);
|
||||
}
|
||||
EventDispatcher.fireEvent(
|
||||
new ConfigDataChangeEvent(true, configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(),
|
||||
time.getTime()));
|
||||
}
|
||||
|
||||
public void insertOrUpdateTag(final ConfigInfo configInfo,
|
||||
@ -364,10 +351,6 @@ public class ExternalStoragePersistServiceImpl implements PersistService {
|
||||
catch (DataIntegrityViolationException ive) { // 唯一性约束冲突
|
||||
updateConfigInfo4Tag(configInfo, tag, srcIp, null, time, notify);
|
||||
}
|
||||
EventDispatcher.fireEvent(
|
||||
new ConfigDataChangeEvent(false, configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(), tag,
|
||||
time.getTime()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -406,10 +389,6 @@ public class ExternalStoragePersistServiceImpl implements PersistService {
|
||||
updateConfigInfo(configInfo, srcIp, srcUser, time, configAdvanceInfo,
|
||||
notify);
|
||||
}
|
||||
EventDispatcher.fireEvent(
|
||||
new ConfigDataChangeEvent(false, configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(),
|
||||
time.getTime()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -452,9 +431,6 @@ public class ExternalStoragePersistServiceImpl implements PersistService {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
});
|
||||
|
||||
EventDispatcher.fireEvent(new ConfigDataChangeEvent(false, dataId, group, tenant,
|
||||
System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -496,20 +472,6 @@ public class ExternalStoragePersistServiceImpl implements PersistService {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!CollectionUtils.isEmpty(result)) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
for (ConfigInfo configInfo : result) {
|
||||
ConfigTraceService.logPersistenceEvent(configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(), null, currentTime,
|
||||
srcIp, ConfigTraceService.PERSISTENCE_EVENT_REMOVE, null);
|
||||
EventDispatcher.fireEvent(
|
||||
new ConfigDataChangeEvent(false, configInfo.getDataId(),
|
||||
configInfo.getGroup(), configInfo.getTenant(),
|
||||
currentTime));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -519,27 +481,21 @@ public class ExternalStoragePersistServiceImpl implements PersistService {
|
||||
public void removeConfigInfo4Beta(final String dataId, final String group,
|
||||
final String tenant) {
|
||||
final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant;
|
||||
tjt.execute(new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(TransactionStatus status) {
|
||||
try {
|
||||
ConfigInfo configInfo = findConfigInfo4Beta(dataId, group, tenant);
|
||||
if (configInfo != null) {
|
||||
jt.update(
|
||||
"DELETE FROM config_info_beta WHERE data_id=? AND group_id=? AND tenant_id=?",
|
||||
dataId, group, tenantTmp);
|
||||
}
|
||||
tjt.execute(status -> {
|
||||
try {
|
||||
ConfigInfo configInfo = findConfigInfo4Beta(dataId, group, tenant);
|
||||
if (configInfo != null) {
|
||||
jt.update(
|
||||
"DELETE FROM config_info_beta WHERE data_id=? AND group_id=? AND tenant_id=?",
|
||||
dataId, group, tenantTmp);
|
||||
}
|
||||
catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
});
|
||||
|
||||
EventDispatcher.fireEvent(new ConfigDataChangeEvent(true, dataId, group, tenant,
|
||||
System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
// ----------------------- config_aggr_info 表 insert update delete
|
||||
@ -2688,9 +2644,6 @@ public class ExternalStoragePersistServiceImpl implements PersistService {
|
||||
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
EventDispatcher.fireEvent(
|
||||
new ConfigDataChangeEvent(false, dataId, group, tenant, tag,
|
||||
System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,7 +9,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-dump.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -25,7 +25,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-pull.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -41,7 +41,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-fatal.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -57,7 +57,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-memory.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -73,7 +73,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-pull-check.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -90,7 +90,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-acl.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>512MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -107,7 +107,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-client-request.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -124,7 +124,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-sdk-request.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -141,7 +141,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-trace.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -158,7 +158,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-notify.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -175,7 +175,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-app.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -192,7 +192,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-server.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>512MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
|
@ -0,0 +1,69 @@
|
||||
package com.alibaba.nacos.config.server.service;
|
||||
|
||||
import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent;
|
||||
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 org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class ConfigChangePublisherTest {
|
||||
|
||||
@Test
|
||||
public void testConfigChangeNotify() {
|
||||
|
||||
AtomicReference<ConfigDataChangeEvent> reference = new AtomicReference<>();
|
||||
|
||||
EventDispatcher.addEventListener(new EventDispatcher.AbstractEventListener() {
|
||||
@Override
|
||||
public List<Class<? extends EventDispatcher.Event>> interest() {
|
||||
return Collections.singletonList(ConfigDataChangeEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(EventDispatcher.Event event) {
|
||||
reference.set((ConfigDataChangeEvent) event);
|
||||
}
|
||||
});
|
||||
|
||||
// nacos is standalone mode and use embedded storage
|
||||
ApplicationUtils.setIsStandalone(true);
|
||||
PropertyUtil.setEmbeddedStorage(true);
|
||||
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
||||
Assert.assertNotNull(reference.get());
|
||||
reference.set(null);
|
||||
|
||||
|
||||
// nacos is standalone mode and use external storage
|
||||
ApplicationUtils.setIsStandalone(true);
|
||||
PropertyUtil.setEmbeddedStorage(false);
|
||||
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
||||
Assert.assertNotNull(reference.get());
|
||||
reference.set(null);
|
||||
|
||||
|
||||
// nacos is cluster mode and use embedded storage
|
||||
ApplicationUtils.setIsStandalone(false);
|
||||
PropertyUtil.setEmbeddedStorage(true);
|
||||
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
||||
Assert.assertNull(reference.get());
|
||||
reference.set(null);
|
||||
|
||||
|
||||
// nacos is cluster mode and use external storage
|
||||
ApplicationUtils.setIsStandalone(false);
|
||||
PropertyUtil.setEmbeddedStorage(false);
|
||||
|
||||
ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent("chuntaojun", "chuntaojun", System.currentTimeMillis()));
|
||||
Assert.assertNotNull(reference.get());
|
||||
reference.set(null);
|
||||
}
|
||||
|
||||
}
|
@ -30,8 +30,7 @@ public interface CPProtocol<C extends Config, P extends LogProcessor4CP> extends
|
||||
*
|
||||
* @param group business module info
|
||||
* @return is leader
|
||||
* @throws Exception
|
||||
*/
|
||||
boolean isLeader(String group) throws Exception;
|
||||
boolean isLeader(String group);
|
||||
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public class JwtTokenManager {
|
||||
|
||||
public String createToken(String userName) {
|
||||
|
||||
long now = (new Date()).getTime();
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
Date validity;
|
||||
validity = new Date(now + authConfigs.getTokenValidityInSeconds() * 1000L);
|
||||
|
@ -104,7 +104,7 @@ public class JwtTokenUtils {
|
||||
/**
|
||||
* Current time
|
||||
*/
|
||||
long now = (new Date()).getTime();
|
||||
long now = System.currentTimeMillis();
|
||||
/**
|
||||
* Validity date
|
||||
*/
|
||||
|
@ -209,7 +209,7 @@ public class JRaftProtocol
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeader(String group) throws Exception {
|
||||
public boolean isLeader(String group) {
|
||||
Node node = raftServer.findNodeByGroup(group);
|
||||
if (node == null) {
|
||||
throw new NoSuchRaftGroupException(group);
|
||||
|
@ -16,10 +16,10 @@
|
||||
|
||||
package com.alibaba.nacos.core.distributed.raft;
|
||||
|
||||
import com.alibaba.nacos.common.JustForTest;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||
import com.alibaba.nacos.common.utils.LoggerUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import com.alibaba.nacos.consistency.LogProcessor;
|
||||
import com.alibaba.nacos.consistency.SerializeFactory;
|
||||
@ -39,11 +39,8 @@ import com.alibaba.nacos.core.distributed.raft.utils.JRaftUtils;
|
||||
import com.alibaba.nacos.core.distributed.raft.utils.RaftExecutor;
|
||||
import com.alibaba.nacos.core.distributed.raft.utils.RaftOptionsBuilder;
|
||||
import com.alibaba.nacos.core.monitor.MetricsMonitor;
|
||||
import com.alibaba.nacos.core.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
import com.alibaba.nacos.core.utils.ClassUtils;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
import com.alibaba.nacos.core.utils.TimerContext;
|
||||
import com.alipay.sofa.jraft.CliService;
|
||||
import com.alipay.sofa.jraft.Node;
|
||||
import com.alipay.sofa.jraft.RaftGroupService;
|
||||
@ -64,8 +61,8 @@ import com.alipay.sofa.jraft.rpc.RpcServer;
|
||||
import com.alipay.sofa.jraft.rpc.impl.cli.CliClientServiceImpl;
|
||||
import com.alipay.sofa.jraft.util.BytesUtil;
|
||||
import com.alipay.sofa.jraft.util.Endpoint;
|
||||
import com.google.protobuf.Message;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.protobuf.Message;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@ -138,11 +135,13 @@ public class JRaftServer {
|
||||
// System.getProperties().setProperty("bolt.channel_write_buf_low_water_mark", String.valueOf(64 * 1024 * 1024));
|
||||
// System.getProperties().setProperty("bolt.channel_write_buf_high_water_mark", String.valueOf(256 * 1024 * 1024));
|
||||
|
||||
System.getProperties().setProperty("bolt.netty.buffer.low.watermark", String.valueOf(128 * 1024 * 1024));
|
||||
System.getProperties().setProperty("bolt.netty.buffer.high.watermark", String.valueOf(256 * 1024 * 1024));
|
||||
System.getProperties().setProperty("bolt.netty.buffer.low.watermark",
|
||||
String.valueOf(128 * 1024 * 1024));
|
||||
System.getProperties().setProperty("bolt.netty.buffer.high.watermark",
|
||||
String.valueOf(256 * 1024 * 1024));
|
||||
}
|
||||
|
||||
public JRaftServer() throws Exception {
|
||||
public JRaftServer() {
|
||||
this.conf = new Configuration();
|
||||
}
|
||||
|
||||
@ -272,7 +271,8 @@ public class JRaftServer {
|
||||
machine.setNode(node);
|
||||
RouteTable.getInstance().updateConfiguration(groupName, configuration);
|
||||
|
||||
RaftExecutor.executeByCommon(() -> registerSelfToCluster(groupName, localPeerId, configuration));
|
||||
RaftExecutor.executeByCommon(
|
||||
() -> registerSelfToCluster(groupName, localPeerId, configuration));
|
||||
|
||||
// Turn on the leader auto refresh for this group
|
||||
Random random = new Random();
|
||||
@ -305,21 +305,25 @@ public class JRaftServer {
|
||||
}
|
||||
catch (Throwable t) {
|
||||
MetricsMonitor.raftReadIndexFailed();
|
||||
future.completeExceptionally(new ConsistencyException("The conformance protocol is temporarily unavailable for reading", t));
|
||||
future.completeExceptionally(new ConsistencyException(
|
||||
"The conformance protocol is temporarily unavailable for reading",
|
||||
t));
|
||||
}
|
||||
return;
|
||||
}
|
||||
MetricsMonitor.raftReadIndexFailed();
|
||||
Loggers.RAFT.error("ReadIndex has error : {}", status.getErrorMsg());
|
||||
future.completeExceptionally(
|
||||
new ConsistencyException("The conformance protocol is temporarily unavailable for reading, " + status.getErrorMsg()));
|
||||
future.completeExceptionally(new ConsistencyException(
|
||||
"The conformance protocol is temporarily unavailable for reading, "
|
||||
+ status.getErrorMsg()));
|
||||
}
|
||||
});
|
||||
return future;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
MetricsMonitor.raftReadFromLeader();
|
||||
Loggers.RAFT.warn("Raft linear read failed, go to Leader read logic : {}", e.toString());
|
||||
Loggers.RAFT.warn("Raft linear read failed, go to Leader read logic : {}",
|
||||
e.toString());
|
||||
// run raft read
|
||||
readFromLeader(request, future);
|
||||
return future;
|
||||
@ -333,20 +337,25 @@ public class JRaftServer {
|
||||
@Override
|
||||
public void accept(Response response, Throwable throwable) {
|
||||
if (Objects.nonNull(throwable)) {
|
||||
future.completeExceptionally(new ConsistencyException("The conformance protocol is temporarily unavailable for reading", throwable));
|
||||
future.completeExceptionally(new ConsistencyException(
|
||||
"The conformance protocol is temporarily unavailable for reading",
|
||||
throwable));
|
||||
return;
|
||||
}
|
||||
if (response.getSuccess()) {
|
||||
future.complete(response);
|
||||
} else {
|
||||
future.completeExceptionally(
|
||||
new ConsistencyException("The conformance protocol is temporarily unavailable for reading, " + response.getErrMsg()));
|
||||
}
|
||||
else {
|
||||
future.completeExceptionally(new ConsistencyException(
|
||||
"The conformance protocol is temporarily unavailable for reading, "
|
||||
+ response.getErrMsg()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<Response> commit(final String group, final Message data, final CompletableFuture<Response> future) {
|
||||
public CompletableFuture<Response> commit(final String group, final Message data,
|
||||
final CompletableFuture<Response> future) {
|
||||
LoggerUtils
|
||||
.printIfDebugEnabled(Loggers.RAFT, "data requested this time : {}", data);
|
||||
final RaftGroupTuple tuple = findTupleByGroup(group);
|
||||
@ -374,12 +383,12 @@ public class JRaftServer {
|
||||
* Add yourself to the Raft cluster
|
||||
*
|
||||
* @param groupId raft group
|
||||
* @param selfIp local raft node address
|
||||
* @param conf {@link Configuration} without self info
|
||||
* @param selfIp local raft node address
|
||||
* @param conf {@link Configuration} without self info
|
||||
* @return join success
|
||||
*/
|
||||
void registerSelfToCluster(String groupId, PeerId selfIp, Configuration conf) {
|
||||
for ( ; ; ) {
|
||||
for (; ; ) {
|
||||
List<PeerId> peerIds = cliService.getPeers(groupId, conf);
|
||||
if (peerIds.contains(selfIp)) {
|
||||
return;
|
||||
@ -428,14 +437,10 @@ public class JRaftServer {
|
||||
public void applyOperation(Node node, Message data, FailoverClosure closure) {
|
||||
final Task task = new Task();
|
||||
task.setDone(new NacosClosure(data, status -> {
|
||||
NacosClosure.NStatus nStatus = (NacosClosure.NStatus) status;
|
||||
if (Objects.nonNull(nStatus.getThrowable())) {
|
||||
closure.setThrowable(nStatus.getThrowable());
|
||||
}
|
||||
else {
|
||||
closure.setData(nStatus.getResult());
|
||||
}
|
||||
closure.run(nStatus);
|
||||
NacosClosure.NacosStatus nacosStatus = (NacosClosure.NacosStatus) status;
|
||||
closure.setThrowable(nacosStatus.getThrowable());
|
||||
closure.setResponse(nacosStatus.getResponse());
|
||||
closure.run(nacosStatus);
|
||||
}));
|
||||
task.setData(ByteBuffer.wrap(data.toByteArray()));
|
||||
node.apply(task);
|
||||
@ -452,10 +457,11 @@ public class JRaftServer {
|
||||
public void complete(Object o, Throwable ex) {
|
||||
if (Objects.nonNull(ex)) {
|
||||
closure.setThrowable(ex);
|
||||
closure.run(new Status(RaftError.UNKNOWN, ex.getMessage()));
|
||||
closure.run(
|
||||
new Status(RaftError.UNKNOWN, ex.getMessage()));
|
||||
return;
|
||||
}
|
||||
closure.setData(o);
|
||||
closure.setResponse((Response) o);
|
||||
closure.run(Status.OK());
|
||||
}
|
||||
|
||||
@ -491,7 +497,8 @@ public class JRaftServer {
|
||||
RestResult<String> result = maintainService.execute(params);
|
||||
if (result.ok()) {
|
||||
successCnt.incrementAndGet();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Loggers.RAFT.error("Node removal failed : {}", result);
|
||||
}
|
||||
}
|
||||
@ -513,7 +520,8 @@ public class JRaftServer {
|
||||
Configuration oldConf = instance.getConfiguration(groupName);
|
||||
String oldLeader = Optional.ofNullable(instance.selectLeader(groupName))
|
||||
.orElse(PeerId.emptyPeer()).getEndpoint().toString();
|
||||
status = instance.refreshConfiguration(this.cliClientService, groupName, rpcRequestTimeoutMs);
|
||||
status = instance.refreshConfiguration(this.cliClientService, groupName,
|
||||
rpcRequestTimeoutMs);
|
||||
if (!status.isOk()) {
|
||||
Loggers.RAFT
|
||||
.error("Fail to refresh route configuration for group : {}, status is : {}",
|
||||
@ -548,12 +556,16 @@ public class JRaftServer {
|
||||
return cliService;
|
||||
}
|
||||
|
||||
public class RaftGroupTuple {
|
||||
public static class RaftGroupTuple {
|
||||
|
||||
private final LogProcessor processor;
|
||||
private final Node node;
|
||||
private final RaftGroupService raftGroupService;
|
||||
private final NacosStateMachine machine;
|
||||
private LogProcessor processor;
|
||||
private Node node;
|
||||
private RaftGroupService raftGroupService;
|
||||
private NacosStateMachine machine;
|
||||
|
||||
@JustForTest
|
||||
public RaftGroupTuple() {
|
||||
}
|
||||
|
||||
public RaftGroupTuple(Node node, LogProcessor processor,
|
||||
RaftGroupService raftGroupService, NacosStateMachine machine) {
|
||||
|
@ -16,8 +16,10 @@
|
||||
|
||||
package com.alibaba.nacos.core.distributed.raft;
|
||||
|
||||
import com.alibaba.nacos.consistency.entity.Response;
|
||||
import com.alipay.sofa.jraft.Closure;
|
||||
import com.alipay.sofa.jraft.Status;
|
||||
import com.alipay.sofa.jraft.error.RaftError;
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
/**
|
||||
@ -25,76 +27,113 @@ import com.google.protobuf.Message;
|
||||
*/
|
||||
public class NacosClosure implements Closure {
|
||||
|
||||
private final Message log;
|
||||
private final Message message;
|
||||
private final Closure closure;
|
||||
private Throwable throwable;
|
||||
private Object object;
|
||||
private final NacosStatus nacosStatus = new NacosStatus();
|
||||
|
||||
public NacosClosure(Message log, Closure closure) {
|
||||
this.log = log;
|
||||
public NacosClosure(Message message, Closure closure) {
|
||||
this.message = message;
|
||||
this.closure = closure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Status status) {
|
||||
if (closure != null) {
|
||||
NStatus status1 = new NStatus(status, throwable);
|
||||
status1.setResult(object);
|
||||
closure.run(status1);
|
||||
}
|
||||
nacosStatus.setStatus(status);
|
||||
closure.run(nacosStatus);
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public void setObject(Object object) {
|
||||
this.object = object;
|
||||
public void setResponse(Response response) {
|
||||
this.nacosStatus.setResponse(response);
|
||||
}
|
||||
|
||||
public void setThrowable(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
this.nacosStatus.setThrowable(throwable);
|
||||
}
|
||||
|
||||
public Closure getClosure() {
|
||||
return closure;
|
||||
}
|
||||
|
||||
public Message getLog() {
|
||||
return log;
|
||||
public Message getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
// Pass the Throwable inside the state machine to the outer layer
|
||||
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public static class NStatus extends Status {
|
||||
public static class NacosStatus extends Status {
|
||||
|
||||
private Status status;
|
||||
|
||||
private Object result;
|
||||
private Response response = null;
|
||||
|
||||
private Throwable throwable;
|
||||
|
||||
public NStatus(Status status, Throwable throwable) {
|
||||
super();
|
||||
this.status = status;
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
private Throwable throwable = null;
|
||||
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Object getResult() {
|
||||
return result;
|
||||
@Override
|
||||
public void reset() {
|
||||
status.reset();
|
||||
}
|
||||
|
||||
public void setResult(Object result) {
|
||||
this.result = result;
|
||||
@Override
|
||||
public boolean isOk() {
|
||||
return status.isOk();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCode(int code) {
|
||||
status.setCode(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCode() {
|
||||
return status.getCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaftError getRaftError() {
|
||||
return status.getRaftError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorMsg(String errMsg) {
|
||||
status.setErrorMsg(errMsg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setError(int code, String fmt, Object... args) {
|
||||
status.setError(code, fmt, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setError(RaftError error, String fmt, Object... args) {
|
||||
status.setError(error, fmt, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return status.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status copy() {
|
||||
NacosStatus copy = new NacosStatus();
|
||||
copy.status = this.status;
|
||||
copy.response = this.response;
|
||||
copy.throwable = this.throwable;
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMsg() {
|
||||
return status.getErrorMsg();
|
||||
}
|
||||
|
||||
public Response getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public void setResponse(Response response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public Throwable getThrowable() {
|
||||
|
@ -32,7 +32,6 @@ import com.alibaba.nacos.consistency.snapshot.Writer;
|
||||
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.TimerContext;
|
||||
import com.alipay.sofa.jraft.Closure;
|
||||
import com.alipay.sofa.jraft.Iterator;
|
||||
import com.alipay.sofa.jraft.Node;
|
||||
@ -94,7 +93,7 @@ class NacosStateMachine extends StateMachineAdapter {
|
||||
try {
|
||||
if (iter.done() != null) {
|
||||
closure = (NacosClosure) iter.done();
|
||||
message = closure.getLog();
|
||||
message = closure.getMessage();
|
||||
}
|
||||
else {
|
||||
final ByteBuffer data = iter.getData();
|
||||
@ -246,9 +245,9 @@ class NacosStateMachine extends StateMachineAdapter {
|
||||
RouteTable.getInstance().getConfiguration(node.getGroupId()).getPeers());
|
||||
}
|
||||
|
||||
private void postProcessor(Object data, NacosClosure closure) {
|
||||
private void postProcessor(Response data, NacosClosure closure) {
|
||||
if (Objects.nonNull(closure)) {
|
||||
closure.setObject(data);
|
||||
closure.setResponse(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ package com.alibaba.nacos.core.distributed.raft.exception;
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class NoSuchRaftGroupException extends Exception {
|
||||
public class NoSuchRaftGroupException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1755681688785678765L;
|
||||
|
||||
|
@ -71,13 +71,13 @@ public abstract class AbstractProcessor {
|
||||
}
|
||||
|
||||
protected void execute(JRaftServer server, final RpcContext asyncCtx, final Message log, final JRaftServer.RaftGroupTuple tuple) {
|
||||
FailoverClosure<Object> closure = new FailoverClosure<Object>() {
|
||||
FailoverClosure closure = new FailoverClosure() {
|
||||
|
||||
Object data;
|
||||
Response data;
|
||||
Throwable ex;
|
||||
|
||||
@Override
|
||||
public void setData(Object data) {
|
||||
public void setResponse(Response data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@ -93,14 +93,7 @@ public abstract class AbstractProcessor {
|
||||
asyncCtx.sendResponse(Response.newBuilder().setErrMsg(ex.toString())
|
||||
.setSuccess(false).build());
|
||||
} else {
|
||||
ByteString bytes = Objects.nonNull(data) ? ByteString.copyFrom(serializer.serialize(data)) : ByteString.EMPTY;
|
||||
|
||||
Response response = Response.newBuilder()
|
||||
.setSuccess(true)
|
||||
.setData(bytes)
|
||||
.build();
|
||||
|
||||
asyncCtx.sendResponse(response);
|
||||
asyncCtx.sendResponse(data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.alibaba.nacos.core.distributed.raft.utils;
|
||||
|
||||
import com.alibaba.nacos.consistency.entity.Response;
|
||||
import com.alipay.sofa.jraft.Closure;
|
||||
|
||||
/**
|
||||
@ -23,14 +24,14 @@ import com.alipay.sofa.jraft.Closure;
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public interface FailoverClosure<T> extends Closure {
|
||||
public interface FailoverClosure extends Closure {
|
||||
|
||||
/**
|
||||
* Set the return interface if needed
|
||||
*
|
||||
* @param data data
|
||||
* @param response {@link Response} data
|
||||
*/
|
||||
void setData(T data);
|
||||
void setResponse(Response response);
|
||||
|
||||
/**
|
||||
* Catch exception
|
||||
|
@ -16,11 +16,11 @@
|
||||
|
||||
package com.alibaba.nacos.core.distributed.raft.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.LoggerUtils;
|
||||
import com.alibaba.nacos.common.utils.Objects;
|
||||
import com.alibaba.nacos.consistency.entity.Response;
|
||||
import com.alibaba.nacos.consistency.exception.ConsistencyException;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
import com.alipay.sofa.jraft.Status;
|
||||
import java.util.Objects;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
@ -28,39 +28,36 @@ import java.util.concurrent.CompletableFuture;
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class FailoverClosureImpl<T> implements FailoverClosure<T> {
|
||||
public class FailoverClosureImpl implements FailoverClosure {
|
||||
|
||||
private final CompletableFuture<T> future;
|
||||
private volatile T data;
|
||||
private volatile Throwable throwable;
|
||||
private final CompletableFuture<Response> future;
|
||||
private volatile Response data;
|
||||
private volatile Throwable throwable;
|
||||
|
||||
public FailoverClosureImpl(final CompletableFuture<T> future) {
|
||||
this.future = future;
|
||||
}
|
||||
public FailoverClosureImpl(final CompletableFuture<Response> future) {
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
@Override
|
||||
public void setResponse(Response data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThrowable(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
@Override
|
||||
public void setThrowable(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Status status) {
|
||||
if (status.isOk()) {
|
||||
boolean success = future.complete(data);
|
||||
LoggerUtils.printIfDebugEnabled(Loggers.RAFT, "future.complete execute {}", success);
|
||||
return;
|
||||
}
|
||||
final Throwable throwable = this.throwable;
|
||||
if (Objects.nonNull(throwable)) {
|
||||
future.completeExceptionally(new ConsistencyException(throwable.toString()));
|
||||
} else {
|
||||
future.completeExceptionally(new ConsistencyException("operation failure"));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void run(Status status) {
|
||||
if (status.isOk()) {
|
||||
future.complete(data);
|
||||
return;
|
||||
}
|
||||
final Throwable throwable = this.throwable;
|
||||
future.completeExceptionally(Objects.nonNull(throwable) ?
|
||||
new ConsistencyException(throwable.toString()) :
|
||||
new ConsistencyException("operation failure"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/nacos.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>512MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -42,7 +42,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/core-auth.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -59,7 +59,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/protocol-raft.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -76,7 +76,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/protocol-distro.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -93,7 +93,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/nacos-cluster.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -110,7 +110,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/alipay-jraft.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
|
@ -0,0 +1,59 @@
|
||||
package com.alibaba.nacos.core.distributed.raft.processor;
|
||||
|
||||
import com.alibaba.nacos.consistency.SerializeFactory;
|
||||
import com.alibaba.nacos.consistency.entity.Log;
|
||||
import com.alibaba.nacos.consistency.entity.Response;
|
||||
import com.alibaba.nacos.core.distributed.raft.JRaftServer;
|
||||
import com.alibaba.nacos.core.distributed.raft.utils.FailoverClosure;
|
||||
import com.alipay.sofa.jraft.Node;
|
||||
import com.alipay.sofa.jraft.Status;
|
||||
import com.alipay.sofa.jraft.error.RaftError;
|
||||
import com.alipay.sofa.jraft.rpc.Connection;
|
||||
import com.alipay.sofa.jraft.rpc.RpcContext;
|
||||
import com.google.protobuf.Message;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class AbstractProcessorTest {
|
||||
|
||||
private JRaftServer server = new JRaftServer() {
|
||||
@Override
|
||||
public void applyOperation(Node node, Message data, FailoverClosure closure) {
|
||||
closure.setResponse(Response.newBuilder().setSuccess(false).setErrMsg("Error message transmission").build());
|
||||
closure.run(new Status(RaftError.UNKNOWN, "Error message transmission"));
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testErrorThroughRPC() {
|
||||
final AtomicReference<Response> reference = new AtomicReference<>();
|
||||
|
||||
RpcContext context = new RpcContext() {
|
||||
@Override
|
||||
public void sendResponse(Object responseObj) {
|
||||
reference.set((Response) responseObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteAddress() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
AbstractProcessor processor = new NacosLogProcessor(server, SerializeFactory.getDefault());
|
||||
processor.execute(server, context, Log.newBuilder().build(), new JRaftServer.RaftGroupTuple());
|
||||
|
||||
Response response = reference.get();
|
||||
Assert.assertNotNull(response);
|
||||
|
||||
Assert.assertEquals("Error message transmission", response.getErrMsg());
|
||||
Assert.assertFalse(response.getSuccess());
|
||||
}
|
||||
|
||||
}
|
@ -13,7 +13,7 @@ server.port=8848
|
||||
|
||||
|
||||
#*************** Config Module Related Configurations ***************#
|
||||
### If user MySQL as datasource:
|
||||
### If use MySQL as datasource:
|
||||
# spring.datasource.platform=mysql
|
||||
|
||||
### Count of DB:
|
||||
|
@ -11,7 +11,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${nacos.home}/logs/cmdb-main.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -35,7 +35,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-server.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -59,7 +59,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-raft.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -84,7 +84,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-distro.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -108,7 +108,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-event.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -132,7 +132,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-push.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -148,7 +148,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-rt.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -165,7 +165,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-performance.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -183,7 +183,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-dump.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -199,7 +199,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-pull.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -215,7 +215,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-fatal.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -231,7 +231,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-memory.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -247,7 +247,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-pull-check.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -264,7 +264,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-client-request.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -281,7 +281,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-trace.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -298,7 +298,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-notify.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -315,7 +315,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/config-server.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>512MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -332,7 +332,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/nacos.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>512MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -349,7 +349,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/nacos-address.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -366,7 +366,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/istio-main.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -383,7 +383,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/core-auth.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -400,7 +400,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/protocol-raft.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -417,7 +417,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/protocol-distro.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -434,7 +434,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/nacos-cluster.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -451,7 +451,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/alipay-jraft.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
|
@ -192,7 +192,7 @@ CREATE TABLE `roles` (
|
||||
|
||||
CREATE TABLE `permissions` (
|
||||
`role` varchar(50) NOT NULL,
|
||||
`resource` varchar(512) NOT NULL,
|
||||
`resource` varchar(255) NOT NULL,
|
||||
`action` varchar(8) NOT NULL,
|
||||
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
|
||||
);
|
||||
|
@ -50,11 +50,13 @@ import java.util.concurrent.ConcurrentMap;
|
||||
@Component
|
||||
public class RaftStore {
|
||||
|
||||
private Properties meta = new Properties();
|
||||
private final Properties meta = new Properties();
|
||||
|
||||
private String metaFileName = UtilsAndCommons.DATA_BASE_DIR + File.separator + "meta.properties";
|
||||
private static final String META_FILE_NAME = UtilsAndCommons.DATA_BASE_DIR + File.separator + "meta.properties";
|
||||
|
||||
private String cacheDir = UtilsAndCommons.DATA_BASE_DIR + File.separator + "data";
|
||||
private static final String CACHE_DIR = UtilsAndCommons.DATA_BASE_DIR + File.separator + "data";
|
||||
|
||||
private static final String CACHE_FILE_SUFFIX = ".datum";
|
||||
|
||||
public synchronized void loadDatums(RaftCore.Notifier notifier, ConcurrentMap<String, Datum> datums) throws Exception {
|
||||
|
||||
@ -81,7 +83,7 @@ public class RaftStore {
|
||||
}
|
||||
|
||||
public synchronized Properties loadMeta() throws Exception {
|
||||
File metaFile = new File(metaFileName);
|
||||
File metaFile = new File(META_FILE_NAME);
|
||||
if (!metaFile.exists() && !metaFile.getParentFile().mkdirs() && !metaFile.createNewFile()) {
|
||||
throw new IllegalStateException("failed to create meta file: " + metaFile.getAbsolutePath());
|
||||
}
|
||||
@ -100,7 +102,7 @@ public class RaftStore {
|
||||
Loggers.RAFT.warn("warning: encountered directory in cache dir: {}", cache.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (!StringUtils.equals(cache.getName(), encodeFileName(key))) {
|
||||
if (!StringUtils.equals(cache.getName(), encodeDatumKey(key) + CACHE_FILE_SUFFIX)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -112,12 +114,16 @@ public class RaftStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized Datum readDatum(File file, String namespaceId) throws IOException {
|
||||
private boolean isDatumCacheFile(String fileName) {
|
||||
return fileName.endsWith(CACHE_FILE_SUFFIX);
|
||||
}
|
||||
|
||||
public synchronized Datum readDatum(File file, String namespaceId) throws IOException {
|
||||
if (!isDatumCacheFile(file.getName())) {
|
||||
return null;
|
||||
}
|
||||
ByteBuffer buffer;
|
||||
FileChannel fc = null;
|
||||
try {
|
||||
fc = new FileInputStream(file).getChannel();
|
||||
try (FileChannel fc = new FileInputStream(file).getChannel()) {
|
||||
buffer = ByteBuffer.allocate((int) file.length());
|
||||
fc.read(buffer);
|
||||
|
||||
@ -192,24 +198,25 @@ public class RaftStore {
|
||||
} catch (Exception e) {
|
||||
Loggers.RAFT.warn("waning: failed to deserialize key: {}", file.getName());
|
||||
throw e;
|
||||
} finally {
|
||||
if (fc != null) {
|
||||
fc.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String cacheFileName(String namespaceId, Datum datum) {
|
||||
String fileName;
|
||||
if (StringUtils.isNotBlank(namespaceId)) {
|
||||
fileName = CACHE_DIR + File.separator + namespaceId + File.separator + encodeDatumKey(datum.key);
|
||||
} else {
|
||||
fileName = CACHE_DIR + File.separator + encodeDatumKey(datum.key);
|
||||
}
|
||||
fileName += CACHE_FILE_SUFFIX;
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public synchronized void write(final Datum datum) throws Exception {
|
||||
|
||||
String namespaceId = KeyBuilder.getNamespace(datum.key);
|
||||
|
||||
File cacheFile;
|
||||
|
||||
if (StringUtils.isNotBlank(namespaceId)) {
|
||||
cacheFile = new File(cacheDir + File.separator + namespaceId + File.separator + encodeFileName(datum.key));
|
||||
} else {
|
||||
cacheFile = new File(cacheDir + File.separator + encodeFileName(datum.key));
|
||||
}
|
||||
File cacheFile = new File(cacheFileName(namespaceId, datum));
|
||||
|
||||
if (!cacheFile.exists() && !cacheFile.getParentFile().mkdirs() && !cacheFile.createNewFile()) {
|
||||
MetricsMonitor.getDiskException().increment();
|
||||
@ -241,7 +248,7 @@ public class RaftStore {
|
||||
String oldFormatKey =
|
||||
datum.key.replace(Constants.DEFAULT_GROUP + Constants.SERVICE_INFO_SPLITER, StringUtils.EMPTY);
|
||||
|
||||
cacheFile = new File(cacheDir + File.separator + namespaceId + File.separator + encodeFileName(oldFormatKey));
|
||||
cacheFile = new File(cacheFileName(namespaceId, datum));
|
||||
if (cacheFile.exists() && !cacheFile.delete()) {
|
||||
Loggers.RAFT.error("[RAFT-DELETE] failed to delete old format datum: {}, value: {}",
|
||||
datum.key, datum.value);
|
||||
@ -252,7 +259,7 @@ public class RaftStore {
|
||||
}
|
||||
|
||||
private File[] listCaches() throws Exception {
|
||||
File cacheDir = new File(this.cacheDir);
|
||||
File cacheDir = new File(CACHE_DIR);
|
||||
if (!cacheDir.exists() && !cacheDir.mkdirs()) {
|
||||
throw new IllegalStateException("cloud not make out directory: " + cacheDir.getName());
|
||||
}
|
||||
@ -267,7 +274,7 @@ public class RaftStore {
|
||||
|
||||
if (StringUtils.isNotBlank(namespaceId)) {
|
||||
|
||||
File cacheFile = new File(cacheDir + File.separator + namespaceId + File.separator + encodeFileName(datum.key));
|
||||
File cacheFile = new File(cacheFileName(namespaceId, datum));
|
||||
if (cacheFile.exists() && !cacheFile.delete()) {
|
||||
Loggers.RAFT.error("[RAFT-DELETE] failed to delete datum: {}, value: {}", datum.key, datum.value);
|
||||
throw new IllegalStateException("failed to delete datum: " + datum.key);
|
||||
@ -276,7 +283,7 @@ public class RaftStore {
|
||||
}
|
||||
|
||||
public void updateTerm(long term) throws Exception {
|
||||
File file = new File(metaFileName);
|
||||
File file = new File(META_FILE_NAME);
|
||||
if (!file.exists() && !file.getParentFile().mkdirs() && !file.createNewFile()) {
|
||||
throw new IllegalStateException("failed to create meta file");
|
||||
}
|
||||
@ -288,11 +295,11 @@ public class RaftStore {
|
||||
}
|
||||
}
|
||||
|
||||
private static String encodeFileName(String fileName) {
|
||||
return fileName.replace(':', '#');
|
||||
private static String encodeDatumKey(String datumKey) {
|
||||
return datumKey.replace(':', '#');
|
||||
}
|
||||
|
||||
private static String decodeFileName(String fileName) {
|
||||
return fileName.replace("#", ":");
|
||||
private static String decodeDatumKey(String datumKey) {
|
||||
return datumKey.replace("#", ":");
|
||||
}
|
||||
}
|
||||
|
@ -106,13 +106,13 @@ public class DistroController {
|
||||
datumMap.put(key, datum);
|
||||
}
|
||||
|
||||
String content = new String(serializer.serialize(datumMap), StandardCharsets.UTF_8);
|
||||
byte[] content = serializer.serialize(datumMap);
|
||||
return ResponseEntity.ok(content);
|
||||
}
|
||||
|
||||
@GetMapping("/datums")
|
||||
public ResponseEntity getAllDatums() {
|
||||
String content = new String(serializer.serialize(dataStore.getDataMap()), StandardCharsets.UTF_8);
|
||||
byte[] content = serializer.serialize(dataStore.getDataMap());
|
||||
return ResponseEntity.ok(content);
|
||||
}
|
||||
}
|
||||
|
@ -21,17 +21,13 @@ import com.alibaba.nacos.naming.core.Instance;
|
||||
import com.alibaba.nacos.naming.misc.Loggers;
|
||||
import com.alibaba.nacos.naming.misc.SwitchDomain;
|
||||
import com.alibaba.nacos.naming.monitor.MetricsMonitor;
|
||||
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
|
||||
import io.netty.channel.ConnectTimeoutException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
@ -149,17 +145,11 @@ public class MysqlHealthCheckProcessor implements HealthCheckProcessor {
|
||||
Mysql config = (Mysql) cluster.getHealthChecker();
|
||||
|
||||
if (connection == null || connection.isClosed()) {
|
||||
MysqlDataSource dataSource = new MysqlDataSource();
|
||||
dataSource.setConnectTimeout(CONNECT_TIMEOUT_MS);
|
||||
dataSource.setSocketTimeout(CONNECT_TIMEOUT_MS);
|
||||
dataSource.setUser(config.getUser());
|
||||
dataSource.setPassword(config.getPwd());
|
||||
dataSource.setLoginTimeout(1);
|
||||
|
||||
dataSource.setServerName(ip.getIp());
|
||||
dataSource.setPort(ip.getPort());
|
||||
|
||||
connection = dataSource.getConnection();
|
||||
String url = "jdbc:mysql://" + ip.getIp() + ":" + ip.getPort() +
|
||||
"?connectTimeout=" + CONNECT_TIMEOUT_MS +
|
||||
"&socketTimeout=" + CONNECT_TIMEOUT_MS +
|
||||
"&loginTimeout=" + 1;
|
||||
connection = DriverManager.getConnection(url, config.getUser(), config.getPwd());
|
||||
CONNECTION_POOL.put(key, connection);
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
@ -318,18 +319,16 @@ public class HttpClient {
|
||||
|
||||
public static HttpResult httpPutLarge(String url, Map<String, String> headers, byte[] content) {
|
||||
try {
|
||||
HttpClientBuilder builder = HttpClients.custom();
|
||||
builder.setUserAgent(UtilsAndCommons.SERVER_VERSION);
|
||||
builder.setConnectionTimeToLive(500, TimeUnit.MILLISECONDS);
|
||||
|
||||
HttpClientBuilder builder = HttpClients.custom()
|
||||
.setUserAgent(UtilsAndCommons.SERVER_VERSION)
|
||||
.setConnectionTimeToLive(500, TimeUnit.MILLISECONDS);
|
||||
CloseableHttpClient httpClient = builder.build();
|
||||
HttpPut httpPut = new HttpPut(url);
|
||||
|
||||
HttpPut httpPut = new HttpPut(url);
|
||||
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||
httpPut.setHeader(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
httpPut.setEntity(new StringEntity(new String(content, StandardCharsets.UTF_8), ContentType.create("application/json", StandardCharsets.UTF_8)));
|
||||
httpPut.setEntity(new ByteArrayEntity(content, ContentType.APPLICATION_JSON));
|
||||
|
||||
HttpResponse response = httpClient.execute(httpPut);
|
||||
HttpEntity entity = response.getEntity();
|
||||
|
@ -11,7 +11,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-server.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -27,7 +27,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-raft.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -43,7 +43,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-event.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -59,7 +59,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-push.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -75,7 +75,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-rt.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -92,7 +92,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-performance.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>512MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -109,7 +109,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-router.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -126,7 +126,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-cache.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -143,7 +143,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-device.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>7GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -160,7 +160,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-tag.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -177,7 +177,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-debug.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<MaxHistory>15</MaxHistory>
|
||||
<maxHistory>15</maxHistory>
|
||||
<totalSizeCap>128MB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
@ -194,7 +194,7 @@
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_HOME}/naming-distro.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<maxFileSize>1GB</maxFileSize>
|
||||
<MaxHistory>7</MaxHistory>
|
||||
<maxHistory>7</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||
</rollingPolicy>
|
||||
|
28
pom.xml
28
pom.xml
@ -460,6 +460,34 @@
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<!-- Run integration tests for configuration modules separately -->
|
||||
<id>cit-test</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
<configuration>
|
||||
<argLine>@{failsafeArgLine}</argLine>
|
||||
<argLine>-Dnacos.standalone=true</argLine>
|
||||
<includes>
|
||||
<include>**/*CITCase.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<!-- Run integration tests for all modules separately -->
|
||||
<id>it-test</id>
|
||||
<build>
|
||||
<plugins>
|
||||
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.test.common;
|
||||
|
||||
import com.alibaba.nacos.Nacos;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.http.Callback;
|
||||
import com.alibaba.nacos.common.http.HttpClientManager;
|
||||
import com.alibaba.nacos.common.http.HttpRestResult;
|
||||
import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
|
||||
import com.alibaba.nacos.common.http.param.Header;
|
||||
import com.alibaba.nacos.common.http.param.Query;
|
||||
import com.alibaba.nacos.common.model.RestResult;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* NacosAsyncRestTemplate_ITCase
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/29
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class NacosAsyncRestTemplate_ITCase {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
private NacosAsyncRestTemplate nacosRestTemplate = HttpClientManager.getNacosAsyncRestTemplate();
|
||||
|
||||
private final String CONFIG_INSTANCE_PATH = "/nacos/v1/ns";
|
||||
private String IP = null;
|
||||
|
||||
@Before
|
||||
public void init() throws NacosException {
|
||||
IP = String.format("http://localhost:%d", port);
|
||||
}
|
||||
|
||||
private class CallbackMap<T> implements Callback<T> {
|
||||
|
||||
private HttpRestResult<T> restResult;
|
||||
private Throwable throwable;
|
||||
|
||||
@Override
|
||||
public void onReceive(RestResult<T> result) {
|
||||
restResult = (HttpRestResult<T>) result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable throwable) {
|
||||
throwable = throwable;
|
||||
}
|
||||
|
||||
public HttpRestResult<T> getRestResult() {
|
||||
return restResult;
|
||||
}
|
||||
|
||||
public Throwable getThrowable() {
|
||||
return throwable;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_url_post_from() throws Exception{
|
||||
String url = IP + CONFIG_INSTANCE_PATH + "/instance";
|
||||
Map<String, String> param = new HashMap<>();
|
||||
param.put("serviceName", "app-test");
|
||||
param.put("port", "8080");
|
||||
param.put("ip", "11.11.11.11");
|
||||
CallbackMap<String> callbackMap = new CallbackMap<>();
|
||||
nacosRestTemplate.postFrom(url, Header.newInstance(), Query.newInstance(), param, String.class, callbackMap);
|
||||
Thread.sleep(2000);
|
||||
HttpRestResult<String> restResult = callbackMap.getRestResult();
|
||||
System.out.println(restResult.getData());
|
||||
System.out.println(restResult.getHeader());
|
||||
Assert.assertTrue(restResult.ok());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_url_put_from() throws Exception{
|
||||
String url = IP + CONFIG_INSTANCE_PATH + "/instance";
|
||||
Map<String, String> param = new HashMap<>();
|
||||
param.put("serviceName", "app-test-change");
|
||||
param.put("port", "8080");
|
||||
param.put("ip", "11.11.11.11");
|
||||
CallbackMap<String> callbackMap = new CallbackMap<>();
|
||||
nacosRestTemplate.putFrom(url, Header.newInstance(), Query.newInstance(), param, String.class, callbackMap);
|
||||
Thread.sleep(2000);
|
||||
HttpRestResult<String> restResult = callbackMap.getRestResult();
|
||||
System.out.println(restResult.getData());
|
||||
System.out.println(restResult.getHeader());
|
||||
Assert.assertTrue(restResult.ok());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test_url_get() throws Exception {
|
||||
String url = IP + CONFIG_INSTANCE_PATH + "/instance/list";
|
||||
Query query = Query.newInstance().addParam("serviceName", "app-test");
|
||||
CallbackMap<Map> callbackMap = new CallbackMap<>();
|
||||
nacosRestTemplate.get(url, Header.newInstance(), query, Map.class, callbackMap);
|
||||
Thread.sleep(2000);
|
||||
HttpRestResult<Map> restResult = callbackMap.getRestResult();
|
||||
System.out.println(restResult.getData());
|
||||
System.out.println(restResult.getHeader());
|
||||
Assert.assertTrue(restResult.ok());
|
||||
Assert.assertEquals(restResult.getData().get("dom"), "app-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_url_by_map() throws Exception{
|
||||
String url = IP + CONFIG_INSTANCE_PATH + "/instance/list";
|
||||
Map<String, String> param = new HashMap<>();
|
||||
param.put("serviceName", "app-test");
|
||||
CallbackMap<Map> callbackMap = new CallbackMap<>();
|
||||
nacosRestTemplate.get(url, Header.newInstance(), param, Map.class, callbackMap);
|
||||
Thread.sleep(2000);
|
||||
HttpRestResult<Map> restResult = callbackMap.getRestResult();
|
||||
System.out.println(restResult.getData());
|
||||
System.out.println(restResult.getHeader());
|
||||
Assert.assertTrue(restResult.ok());
|
||||
Assert.assertEquals(restResult.getData().get("dom"), "app-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_url_delete() throws Exception{
|
||||
String url = IP + CONFIG_INSTANCE_PATH + "/instance";
|
||||
Query query = Query.newInstance()
|
||||
.addParam("ip", "11.11.11.11")
|
||||
.addParam("port", "8080")
|
||||
.addParam("serviceName", "app-test");
|
||||
CallbackMap<String> callbackMap = new CallbackMap<>();
|
||||
nacosRestTemplate.delete(url, Header.newInstance(), query, String.class, callbackMap);
|
||||
Thread.sleep(2000);
|
||||
HttpRestResult<String> restResult = callbackMap.getRestResult();
|
||||
System.out.println(restResult.getData());
|
||||
System.out.println(restResult.getHeader());
|
||||
Assert.assertTrue(restResult.ok());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.test.common;
|
||||
|
||||
import com.alibaba.nacos.Nacos;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.http.HttpClientManager;
|
||||
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.model.RestResult;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* NacosRestTemplate_ITCase
|
||||
*
|
||||
* @author mai.jh
|
||||
* @date 2020/5/30
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
public class NacosRestTemplate_ITCase {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
private NacosRestTemplate nacosRestTemplate = HttpClientManager.getNacosRestTemplate();
|
||||
|
||||
private final String INSTANCE_PATH = "/nacos/v1/ns";
|
||||
private final String CONFIG_PATH = "/nacos/v1/cs";
|
||||
private String IP = null;
|
||||
|
||||
@Before
|
||||
public void init() throws NacosException {
|
||||
IP = String.format("http://localhost:%d", port);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_url_get_return_restResult() throws Exception{
|
||||
String url = IP + CONFIG_PATH + "/configs";
|
||||
Query query = Query.newInstance().addParam("beta", true).addParam("dataId","test-1").addParam("group", "DEFAULT_GROUP");
|
||||
HttpRestResult<String> restResult = nacosRestTemplate.get(url, Header.newInstance(), query, RestResult.class);
|
||||
Assert.assertTrue(restResult.ok());
|
||||
System.out.println(restResult.getData());
|
||||
System.out.println(restResult.getHeader());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test_url_post_from() throws Exception{
|
||||
String url = IP + INSTANCE_PATH + "/instance";
|
||||
Map<String, String> param = new HashMap<>();
|
||||
param.put("serviceName", "app-test");
|
||||
param.put("port", "8080");
|
||||
param.put("ip", "11.11.11.11");
|
||||
HttpRestResult<String> restResult = nacosRestTemplate.postFrom(url, Header.newInstance(), Query.newInstance(), param, String.class);
|
||||
Assert.assertTrue(restResult.ok());
|
||||
System.out.println(restResult.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_url_put_from() throws Exception{
|
||||
String url = IP + INSTANCE_PATH + "/instance";
|
||||
Map<String, String> param = new HashMap<>();
|
||||
param.put("serviceName", "app-test-change");
|
||||
param.put("port", "8080");
|
||||
param.put("ip", "11.11.11.11");
|
||||
HttpRestResult<String> restResult = nacosRestTemplate.putFrom(url, Header.newInstance(), Query.newInstance(), param, String.class);
|
||||
Assert.assertTrue(restResult.ok());
|
||||
System.out.println(restResult.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_url_get() throws Exception {
|
||||
String url = IP + INSTANCE_PATH + "/instance/list";
|
||||
Query query = Query.newInstance().addParam("serviceName", "app-test");
|
||||
HttpRestResult<Map> restResult = nacosRestTemplate.get(url, Header.newInstance(), query, Map.class);
|
||||
Assert.assertTrue(restResult.ok());
|
||||
Assert.assertEquals(restResult.getData().get("dom"), "app-test");
|
||||
System.out.println(restResult.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_url_get_by_map() throws Exception {
|
||||
String url = IP + INSTANCE_PATH + "/instance/list";
|
||||
Map<String, String> param = new HashMap<>();
|
||||
param.put("serviceName", "app-test");
|
||||
HttpRestResult<Map> restResult = nacosRestTemplate.get(url, Header.newInstance(), param, Map.class);
|
||||
Assert.assertTrue(restResult.ok());
|
||||
Assert.assertEquals(restResult.getData().get("dom"), "app-test");
|
||||
System.out.println(restResult.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_url_delete() throws Exception{
|
||||
String url = IP + INSTANCE_PATH + "/instance";
|
||||
Query query = Query.newInstance()
|
||||
.addParam("ip", "11.11.11.11")
|
||||
.addParam("port", "8080")
|
||||
.addParam("serviceName", "app-test");
|
||||
HttpRestResult<String> restResult = nacosRestTemplate.delete(url, Header.newInstance(), query, String.class);
|
||||
Assert.assertTrue(restResult.ok());
|
||||
System.out.println(restResult);
|
||||
}
|
||||
|
||||
}
|
@ -50,9 +50,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
* @author xiaochun.xxc
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ConfigAPI_ITCase {
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7001"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
|
||||
public class ConfigAPI_CITCase {
|
||||
|
||||
public static final long TIME_OUT = 5000;
|
||||
static ConfigService iconfig = null;
|
||||
@ -72,7 +72,6 @@ public class ConfigAPI_ITCase {
|
||||
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1"+":"+port);
|
||||
properties.put(PropertyKeyConst.CONTEXT_PATH, "/nacos");
|
||||
iconfig = NacosFactory.createConfigService(properties);
|
||||
|
||||
agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
|
||||
agent.start();
|
||||
}
|
||||
@ -85,6 +84,7 @@ public class ConfigAPI_ITCase {
|
||||
result = agent.httpDelete(CONFIG_CONTROLLER_PATH + "/", null, params, agent.getEncode(), TIME_OUT);
|
||||
Assert.assertEquals(HttpURLConnection.HTTP_OK, result.code);
|
||||
Assert.assertTrue(JacksonUtils.toObj(result.content).get("data").booleanValue());
|
||||
Assert.assertTrue(JacksonUtils.toObj(result.content).get("data").booleanValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail();
|
||||
@ -378,7 +378,7 @@ public class ConfigAPI_ITCase {
|
||||
* @author xiaochun.xxc
|
||||
* @since 3.6.8
|
||||
*/
|
||||
@Test(timeout = 5 * TIME_OUT)
|
||||
@Test(timeout = Constants.CONFIG_LONG_POLL_TIMEOUT << 2)
|
||||
public void nacos_addListener_3() throws InterruptedException, NacosException {
|
||||
final AtomicInteger count = new AtomicInteger(0);
|
||||
final String dataId = "nacos_addListener_3";
|
||||
@ -386,7 +386,6 @@ public class ConfigAPI_ITCase {
|
||||
final String content = "test-abc";
|
||||
final String newContent = "nacos_addListener_3";
|
||||
boolean result = iconfig.publishConfig(dataId, group, content);
|
||||
Thread.sleep(TIME_OUT);
|
||||
Assert.assertTrue(result);
|
||||
|
||||
Listener ml = new AbstractListener() {
|
||||
@ -399,9 +398,6 @@ public class ConfigAPI_ITCase {
|
||||
iconfig.addListener(dataId, group, ml);
|
||||
result = iconfig.publishConfig(dataId, group, newContent);
|
||||
Assert.assertTrue(result);
|
||||
while (count.get() == 0) {
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
// Get enough sleep to ensure that the monitor is triggered only once
|
||||
// during the two long training sessions
|
||||
ThreadUtils.sleep(Constants.CONFIG_LONG_POLL_TIMEOUT << 1);
|
@ -19,6 +19,7 @@ package com.alibaba.nacos.test.config;
|
||||
import com.alibaba.nacos.Nacos;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import com.alibaba.nacos.test.base.Params;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
@ -41,9 +42,9 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
* @date 2019-07-03
|
||||
**/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ConfigBeta_ITCase {
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7002"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
|
||||
public class ConfigBeta_CITCase {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
@ -178,6 +179,8 @@ public class ConfigBeta_ITCase {
|
||||
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||
Assert.assertEquals("true", response.getBody());
|
||||
|
||||
ThreadUtils.sleep(10_000L);
|
||||
|
||||
ResponseEntity<String> response1 = request(CONFIG_CONTROLLER_PATH + "/configs?beta=false",
|
||||
Params.newParams()
|
||||
.appendParam("dataId", dataId)
|
@ -41,9 +41,9 @@ import java.util.*;
|
||||
* @date 2019/5/23 15:26
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ConfigExportAndImportAPI_ITCase {
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7003"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
|
||||
public class ConfigExportAndImportAPI_CITCase {
|
||||
|
||||
private static final long TIME_OUT = 2000;
|
||||
private static final String CONFIG_CONTROLLER_PATH = "/v1/cs/configs";
|
||||
@ -90,7 +90,7 @@ public class ConfigExportAndImportAPI_ITCase {
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup(){
|
||||
public void cleanup() throws Exception{
|
||||
HttpSimpleClient.HttpResult result;
|
||||
try {
|
||||
List<String> params2 = Arrays.asList("dataId", "testNoAppname1.yml", "group", "EXPORT_IMPORT_TEST_GROUP", "beta", "false");
|
||||
@ -119,9 +119,10 @@ public class ConfigExportAndImportAPI_ITCase {
|
||||
} catch (Exception e) {
|
||||
Assert.fail();
|
||||
}
|
||||
agent.shutdown();
|
||||
}
|
||||
|
||||
@Test(timeout = 3*TIME_OUT)
|
||||
@Test()
|
||||
public void testExportByIds(){
|
||||
String getDataUrl = "?search=accurate&dataId=&group=&appName=&config_tags=&pageNo=1&pageSize=10&tenant=&namespaceId=";
|
||||
String queryResult = httpClient.get(SERVER_ADDR + CONFIG_CONTROLLER_PATH + getDataUrl, null);
|
||||
@ -129,8 +130,9 @@ public class ConfigExportAndImportAPI_ITCase {
|
||||
JsonNode resultConfigs = resultObj.get("pageItems");
|
||||
JsonNode config1 = resultConfigs.get(0);
|
||||
JsonNode config2 = resultConfigs.get(1);
|
||||
String exportByIdsUrl = "?export=true&tenant=&group=&appName=&ids=" + config1.get("id").longValue()
|
||||
+ "," + config2.get("id").longValue();
|
||||
String id1 = config1.get("id").asText();
|
||||
String id2 = config2.get("id").asText();
|
||||
String exportByIdsUrl = "?export=true&tenant=&group=&appName=&ids=" + id1 + "," + id2;
|
||||
System.out.println(exportByIdsUrl);
|
||||
byte[] zipData = httpClient.download(SERVER_ADDR + CONFIG_CONTROLLER_PATH + exportByIdsUrl, null);
|
||||
ZipUtils.UnZipResult unZiped = ZipUtils.unzip(zipData);
|
@ -24,6 +24,7 @@ import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.PropertyChangeType;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -37,9 +38,9 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ConfigLongPollReturnChanges_ITCase {
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7005"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
|
||||
public class ConfigLongPollReturnChanges_CITCase {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
@ -56,6 +57,14 @@ public class ConfigLongPollReturnChanges_ITCase {
|
||||
configService = NacosFactory.createConfigService(properties);
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy(){
|
||||
try {
|
||||
configService.shutDown();
|
||||
}catch (NacosException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() throws InterruptedException, NacosException {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
@ -22,7 +22,7 @@ import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -39,9 +39,9 @@ import java.util.concurrent.TimeUnit;
|
||||
* @date 2019-06-07 22:24
|
||||
**/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ConfigLongPoll_ITCase {
|
||||
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7004"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
|
||||
public class ConfigLongPoll_CITCase {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
@ -58,6 +58,14 @@ public class ConfigLongPoll_ITCase {
|
||||
configService = NacosFactory.createConfigService(properties);
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy(){
|
||||
try {
|
||||
configService.shutDown();
|
||||
}catch (NacosException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws InterruptedException, NacosException {
|
||||
|
@ -29,7 +29,7 @@ import java.util.concurrent.Executors;
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class EmbeddedStorageContextUtils_ITCase {
|
||||
public class EmbeddedStorageContextUtils_CITCase {
|
||||
|
||||
@Test
|
||||
public void test_multi_thread_sql_contexts() throws Exception {
|
@ -157,7 +157,14 @@ public class BaseClusterTest extends HttpClient4Test {
|
||||
try {
|
||||
System.out.println("start close : " + context);
|
||||
context.close();
|
||||
} catch (Exception ignore) {
|
||||
iconfig7.shutDown();
|
||||
iconfig8.shutDown();
|
||||
iconfig9.shutDown();
|
||||
|
||||
inaming7.shutDown();
|
||||
inaming8.shutDown();
|
||||
inaming9.shutDown();
|
||||
} catch (Exception ignore) {
|
||||
} finally {
|
||||
System.out.println("finished close : " + context);
|
||||
latch.countDown();
|
||||
|
@ -23,7 +23,6 @@ import com.alibaba.nacos.api.config.ConfigChangeItem;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
|
||||
import com.alibaba.nacos.core.utils.ApplicationUtils;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
@ -65,8 +64,12 @@ public class ConfigAuth_ITCase extends AuthBase {
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
public void destroy(){
|
||||
try {
|
||||
iconfig.shutDown();
|
||||
}catch (NacosException ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,6 +81,7 @@ public class NamingAuth_ITCase extends AuthBase {
|
||||
} catch (NacosException ne) {
|
||||
Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ne.getErrCode());
|
||||
}
|
||||
namingService.shutDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -97,6 +98,8 @@ public class NamingAuth_ITCase extends AuthBase {
|
||||
|
||||
List<Instance> list = namingService.getAllInstances("test.1");
|
||||
Assert.assertEquals(1, list.size());
|
||||
namingService1.shutDown();
|
||||
namingService.shutDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -111,6 +114,7 @@ public class NamingAuth_ITCase extends AuthBase {
|
||||
TimeUnit.SECONDS.sleep(5L);
|
||||
|
||||
namingService.deregisterInstance("test.1", "1.2.3.4", 80);
|
||||
namingService.shutDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -126,7 +130,7 @@ public class NamingAuth_ITCase extends AuthBase {
|
||||
List<Instance> list = namingService.getAllInstances("test.1");
|
||||
|
||||
Assert.assertEquals(0, list.size());
|
||||
|
||||
namingService.shutDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -142,6 +146,7 @@ public class NamingAuth_ITCase extends AuthBase {
|
||||
List<Instance> list = namingService.getAllInstances("test.1");
|
||||
|
||||
Assert.assertEquals(1, list.size());
|
||||
namingService.shutDown();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.test.naming;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.NamingFactory;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.api.naming.utils.NamingUtils;
|
||||
import com.alibaba.nacos.naming.NamingApp;
|
||||
import com.alibaba.nacos.naming.cluster.transport.Serializer;
|
||||
import com.alibaba.nacos.naming.consistency.Datum;
|
||||
import com.alibaba.nacos.naming.consistency.KeyBuilder;
|
||||
import com.alibaba.nacos.naming.consistency.ephemeral.distro.DataStore;
|
||||
import com.alibaba.nacos.naming.core.Instance;
|
||||
import com.alibaba.nacos.naming.core.Instances;
|
||||
import com.alibaba.nacos.naming.misc.NamingProxy;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = NamingApp.class, properties = {"server.servlet.context-path=/nacos"},
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class NamingProxy_ITCase {
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
@Autowired
|
||||
private Serializer serializer;
|
||||
private final DataStore dataStore = new DataStore();
|
||||
private NamingService namingService;
|
||||
private final String namespaceId = "dev";
|
||||
private final String serviceName = "biz";
|
||||
private final String groupName = "DEFAULT_GROUP";
|
||||
|
||||
@Before
|
||||
public void init() throws NacosException {
|
||||
Properties properties = new Properties();
|
||||
properties.put(PropertyKeyConst.NAMESPACE, namespaceId);
|
||||
properties.put(PropertyKeyConst.SERVER_ADDR, "localhost:" + port);
|
||||
namingService = NamingFactory.createNamingService(properties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyncData() throws NacosException, InterruptedException {
|
||||
// write data to DataStore
|
||||
String groupedName = NamingUtils.getGroupedName(serviceName, groupName);
|
||||
Instances instances = new Instances();
|
||||
Instance instance = new Instance();
|
||||
instance.setIp("1.2.3.4");
|
||||
instance.setPort(8888);
|
||||
instance.setEphemeral(true);
|
||||
instance.setServiceName(groupedName);
|
||||
List<Instance> instanceList = new ArrayList<Instance>(1);
|
||||
instanceList.add(instance);
|
||||
instances.setInstanceList(instanceList);
|
||||
String key = KeyBuilder.buildInstanceListKey(namespaceId, instance.getServiceName(), true);
|
||||
|
||||
Datum<Instances> datum = new Datum<>();
|
||||
datum.value = instances;
|
||||
datum.key = key;
|
||||
datum.timestamp.incrementAndGet();
|
||||
this.dataStore.put(key, datum);
|
||||
|
||||
// sync data to server
|
||||
Map<String, Datum> dataMap = dataStore.getDataMap();
|
||||
byte[] content = serializer.serialize(dataMap);
|
||||
boolean result = NamingProxy.syncData(content, "localhost:" + port);
|
||||
if (!result) {
|
||||
Assert.fail("NamingProxy.syncData error");
|
||||
}
|
||||
|
||||
// query instance by api
|
||||
List<com.alibaba.nacos.api.naming.pojo.Instance> allInstances = namingService.getAllInstances(serviceName, false);
|
||||
for (int i = 0; i < 3 && allInstances.isEmpty(); i++) {
|
||||
// wait for async op
|
||||
TimeUnit.SECONDS.sleep(100);
|
||||
allInstances = namingService.getAllInstances(serviceName, false);
|
||||
}
|
||||
if (allInstances.isEmpty()) {
|
||||
Assert.fail("instance is empty");
|
||||
}
|
||||
|
||||
com.alibaba.nacos.api.naming.pojo.Instance dst = allInstances.get(0);
|
||||
Assert.assertEquals(instance.getIp(), dst.getIp());
|
||||
Assert.assertEquals(instance.getPort(), dst.getPort());
|
||||
Assert.assertEquals(instance.getServiceName(), dst.getServiceName());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user