Merge pull request #2816 from alibaba/develop

merge 1.3.0 Beta
This commit is contained in:
yanlinly 2020-05-15 19:39:23 +08:00 committed by GitHub
commit 2cf0d40c1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
425 changed files with 32860 additions and 9733 deletions

3
.gitignore vendored
View File

@ -8,8 +8,11 @@ target
.DS_Store
.factorypath
/logs
/lib
*.iml
node_modules
test/derby.log
derby.log
work
test/logs
derby.log

View File

@ -16,7 +16,7 @@
<parent>
<artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId>
<version>1.2.1</version>
<version>1.3.0-BETA</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.2.1</version>
<version>1.3.0-BETA</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -25,125 +25,125 @@ import org.apache.commons.lang3.StringUtils;
*/
public class NacosException extends Exception {
/**
* serialVersionUID
*/
private static final long serialVersionUID = -3913902031489277776L;
/**
* serialVersionUID
*/
private static final long serialVersionUID = -3913902031489277776L;
private int errCode;
private int errCode;
private String errMsg;
private String errMsg;
private Throwable causeThrowable;
private Throwable causeThrowable;
public NacosException() {
}
public NacosException() {
}
public NacosException(int errCode, String errMsg) {
super(errMsg);
this.errCode = errCode;
this.errMsg = errMsg;
}
public NacosException(int errCode, String errMsg) {
super(errMsg);
this.errCode = errCode;
this.errMsg = errMsg;
}
public NacosException(int errCode, Throwable throwable) {
super(throwable);
this.errCode = errCode;
setCauseThrowable(throwable);
}
public NacosException(int errCode, Throwable throwable) {
super(throwable);
this.errCode = errCode;
setCauseThrowable(throwable);
}
public NacosException(int errCode, String errMsg, Throwable throwable) {
super(errMsg, throwable);
this.errCode = errCode;
this.errMsg = errMsg;
setCauseThrowable(throwable);
}
public NacosException(int errCode, String errMsg, Throwable throwable) {
super(errMsg, throwable);
this.errCode = errCode;
this.errMsg = errMsg;
setCauseThrowable(throwable);
}
public int getErrCode() {
return errCode;
}
public int getErrCode() {
return errCode;
}
public String getErrMsg() {
if (!StringUtils.isBlank(this.errMsg)) {
return errMsg;
}
if (this.causeThrowable != null) {
return causeThrowable.getMessage();
}
return Constants.NULL;
}
public String getErrMsg() {
if (!StringUtils.isBlank(this.errMsg)) {
return errMsg;
}
if (this.causeThrowable != null) {
return causeThrowable.getMessage();
}
return Constants.NULL;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
public void setCauseThrowable(Throwable throwable) {
this.causeThrowable = getCauseThrowable(throwable);
}
public void setCauseThrowable(Throwable throwable) {
this.causeThrowable = getCauseThrowable(throwable);
}
private Throwable getCauseThrowable(Throwable t) {
if (t.getCause() == null) {
return t;
}
return getCauseThrowable(t.getCause());
}
private Throwable getCauseThrowable(Throwable t) {
if (t.getCause() == null) {
return t;
}
return getCauseThrowable(t.getCause());
}
@Override
public String toString() {
return "ErrCode:" + getErrCode() + ", ErrMsg:" + getErrMsg();
}
@Override
public String toString() {
return "ErrCode:" + getErrCode() + ", ErrMsg:" + getErrMsg();
}
/**
* client error code
* -400 -503 throw exception to user
*/
/**
* invalid param参数错误
*/
public static final int CLIENT_INVALID_PARAM = -400;
/**
* over client threshold超过server端的限流阈值
*/
public static final int CLIENT_OVER_THRESHOLD = -503;
/**
* client error code
* -400 -503 throw exception to user
*/
/**
* invalid param参数错误
*/
public static final int CLIENT_INVALID_PARAM = -400;
/**
* over client threshold超过server端的限流阈值
*/
public static final int CLIENT_OVER_THRESHOLD = -503;
/**
* server error code
* 400 403 throw exception to user
* 500 502 503 change ip and retry
*/
/**
* server error code
* 400 403 throw exception to user
* 500 502 503 change ip and retry
*/
/**
* invalid param参数错误
*/
public static final int INVALID_PARAM = 400;
/**
* no right鉴权失败
*/
public static final int NO_RIGHT = 403;
/**
* not found
*/
public static final int NOT_FOUND = 404;
/**
* conflict写并发冲突
*/
public static final int CONFLICT = 409;
/**
* server errorserver异常如超时
*/
public static final int SERVER_ERROR = 500;
/**
* bad gateway路由异常如nginx后面的Server挂掉
*/
public static final int BAD_GATEWAY = 502;
/**
* over threshold超过server端的限流阈值
*/
public static final int OVER_THRESHOLD = 503;
/**
* invalid param参数错误
*/
public static final int INVALID_PARAM = 400;
/**
* no right鉴权失败
*/
public static final int NO_RIGHT = 403;
/**
* not found
*/
public static final int NOT_FOUND = 404;
/**
* conflict写并发冲突
*/
public static final int CONFLICT = 409;
/**
* server errorserver异常如超时
*/
public static final int SERVER_ERROR = 500;
/**
* bad gateway路由异常如nginx后面的Server挂掉
*/
public static final int BAD_GATEWAY = 502;
/**
* over threshold超过server端的限流阈值
*/
public static final int OVER_THRESHOLD = 503;
public static final int RESOURCE_NOT_FOUND = -404;
public static final int RESOURCE_NOT_FOUND = -404;
}

View File

@ -187,8 +187,7 @@ public class Instance {
}
Instance host = (Instance) obj;
return strEquals(toString(), host.toString());
return strEquals(host.toString(), toString());
}
@Override

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.2.1</version>
<version>1.3.0-BETA</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -129,8 +129,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>6</source>
<target>6</target>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>

View File

@ -33,6 +33,7 @@ import com.alibaba.nacos.client.config.utils.ContentUtils;
import com.alibaba.nacos.client.config.utils.ParamUtils;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.ValidatorUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@ -70,6 +71,7 @@ public class NacosConfigService implements ConfigService {
private ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager();
public NacosConfigService(Properties properties) throws NacosException {
ValidatorUtils.checkInitParam(properties);
String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
if (StringUtils.isBlank(encodeTmp)) {
encode = Constants.ENCODE;

View File

@ -207,8 +207,10 @@ public class ServerHttpAgent implements HttpAgent {
return result;
}
} catch (ConnectException ce) {
ce.printStackTrace();
LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), ce.getMessage());
} catch (SocketTimeoutException stoe) {
stoe.printStackTrace();
LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{} err : {}", serverListMgr.getCurrentServerAddr(), stoe.getMessage());
} catch (IOException ioe) {
LOGGER.error("[NACOS IOException httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ioe);

View File

@ -23,7 +23,7 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
import com.alibaba.nacos.client.config.filter.impl.ConfigResponse;
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
import com.alibaba.nacos.client.config.utils.MD5;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.TenantUtil;
import org.slf4j.Logger;
@ -242,7 +242,7 @@ public class CacheData {
}
static public String getMd5String(String config) {
return (null == config) ? Constants.NULL : MD5.getInstance().getMD5String(config);
return (null == config) ? Constants.NULL : MD5Utils.md5Hex(config, Constants.ENCODE);
}
private String loadCacheContentFromDiskLocal(String name, String dataId, String group, String tenant) {

View File

@ -25,7 +25,7 @@ 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.client.config.utils.MD5;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
@ -279,7 +279,7 @@ public class ClientWorker {
// 没有 ->
if (!cacheData.isUseLocalConfigInfo() && path.exists()) {
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
String md5 = MD5.getInstance().getMD5String(content);
String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
cacheData.setUseLocalConfigInfo(true);
cacheData.setLocalConfigInfoVersion(path.lastModified());
cacheData.setContent(content);
@ -301,7 +301,7 @@ public class ClientWorker {
if (cacheData.isUseLocalConfigInfo() && path.exists()
&& cacheData.getLocalConfigInfoVersion() != path.lastModified()) {
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
String md5 = MD5.getInstance().getMD5String(content);
String md5 = MD5Utils.md5Hex(content, Constants.ENCODE);
cacheData.setUseLocalConfigInfo(true);
cacheData.setLocalConfigInfoVersion(path.lastModified());
cacheData.setContent(content);

View File

@ -17,7 +17,7 @@ package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.utils.MD5;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
import com.alibaba.nacos.common.utils.IoUtils;
@ -42,8 +42,8 @@ public class HttpSimpleClient {
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
String encodedContent = encodingParams(paramValues, encoding);
url += (null == encodedContent) ? "" : ("?" + encodedContent);
if (Limiter.isLimit(MD5.getInstance().getMD5String(
new StringBuilder(url).append(encodedContent).toString()))) {
if (Limiter.isLimit(MD5Utils.md5Hex(
new StringBuilder(url).append(encodedContent).toString(), Constants.ENCODE))) {
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
"More than client-side current limit threshold");
}
@ -98,8 +98,8 @@ public class HttpSimpleClient {
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
String encodedContent = encodingParams(paramValues, encoding);
encodedContent = (null == encodedContent) ? "" : encodedContent;
if (Limiter.isLimit(MD5.getInstance().getMD5String(
new StringBuilder(url).append(encodedContent).toString()))) {
if (Limiter.isLimit(MD5Utils.md5Hex(
new StringBuilder(url).append(encodedContent).toString(), Constants.ENCODE))) {
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
"More than client-side current limit threshold");
}
@ -150,8 +150,8 @@ public class HttpSimpleClient {
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
String encodedContent = encodingParams(paramValues, encoding);
url += (null == encodedContent) ? "" : ("?" + encodedContent);
if (Limiter.isLimit(MD5.getInstance().getMD5String(
new StringBuilder(url).append(encodedContent).toString()))) {
if (Limiter.isLimit(MD5Utils.md5Hex(
new StringBuilder(url).append(encodedContent).toString(), Constants.ENCODE))) {
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
"More than client-side current limit threshold");
}
@ -197,7 +197,7 @@ public class HttpSimpleClient {
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding);
String ts = String.valueOf(System.currentTimeMillis());
String token = MD5.getInstance().getMD5String(ts + ParamUtil.getAppKey());
String token = MD5Utils.md5Hex(ts + ParamUtil.getAppKey(), Constants.ENCODE);
conn.addRequestProperty(Constants.CLIENT_APPNAME_HEADER, ParamUtil.getAppName());
conn.addRequestProperty(Constants.CLIENT_REQUEST_TS_HEADER, ts);
@ -250,6 +250,12 @@ public class HttpSimpleClient {
this.headers = headers;
this.content = content;
}
@Override
public String toString() {
return "HttpResult{" + "code=" + code + ", headers=" + headers + ", content='"
+ content + '\'' + '}';
}
}
}

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import java.io.IOException;
import java.io.StringReader;

View File

@ -22,6 +22,7 @@ import com.alibaba.nacos.client.config.impl.EventDispatcher.ServerlistChangeEven
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.utils.*;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import org.slf4j.Logger;
import java.io.IOException;
@ -306,7 +307,7 @@ public class ServerListManager {
List<String> lines = IoUtils.readLines(new StringReader(httpResult.content));
List<String> result = new ArrayList<String>(lines.size());
for (String serverAddr : lines) {
if (org.apache.commons.lang3.StringUtils.isNotBlank(serverAddr)) {
if (StringUtils.isNotBlank(serverAddr)) {
String[] ipPort = serverAddr.trim().split(":");
String ip = ipPort[0].trim();
if (ipPort.length == 1) {

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import org.yaml.snakeyaml.Yaml;
import java.util.*;

View File

@ -1,132 +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.utils;
import com.alibaba.nacos.api.common.Constants;
import com.google.common.collect.Maps;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
/**
* MD5 util
*
* @author Nacos
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class MD5 {
private static int DIGITS_SIZE = 16;
private static char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static Map<Character, Integer> rDigits = Maps.newHashMapWithExpectedSize(16);
static {
for (int i = 0; i < digits.length; ++i) {
rDigits.put(digits[i], i);
}
}
private static MD5 me = new MD5();
private MessageDigest mHasher;
private ReentrantLock opLock = new ReentrantLock();
private MD5() {
try {
mHasher = MessageDigest.getInstance("md5");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static MD5 getInstance() {
return me;
}
public String getMD5String(String content) {
return bytes2string(hash(content));
}
public String getMD5String(byte[] content) {
return bytes2string(hash(content));
}
public byte[] getMD5Bytes(byte[] content) {
return hash(content);
}
/**
* 对字符串进行md5
*
* @param str
* @return md5 byte[16]
*/
public byte[] hash(String str) {
opLock.lock();
try {
byte[] bt = mHasher.digest(str.getBytes(Constants.ENCODE));
if (null == bt || bt.length != DIGITS_SIZE) {
throw new IllegalArgumentException("md5 need");
}
return bt;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("unsupported utf-8 encoding", e);
} finally {
opLock.unlock();
}
}
/**
* 对二进制数据进行md5
*
* @param data
* @return md5 byte[16]
*/
public byte[] hash(byte[] data) {
opLock.lock();
try {
byte[] bt = mHasher.digest(data);
if (null == bt || bt.length != DIGITS_SIZE) {
throw new IllegalArgumentException("md5 need");
}
return bt;
} finally {
opLock.unlock();
}
}
/**
* 将一个字节数组转化为可见的字符串
*
* @param bt
* @return
*/
public String bytes2string(byte[] bt) {
int l = bt.length;
char[] out = new char[l << 1];
for (int i = 0, j = 0; i < l; i++) {
out[j++] = digits[(0xF0 & bt[i]) >>> 4];
out[j++] = digits[0x0F & bt[i]];
}
return new String(out);
}
}

View File

@ -27,6 +27,7 @@ import com.alibaba.nacos.api.selector.ExpressionSelector;
import com.alibaba.nacos.api.selector.NoneSelector;
import com.alibaba.nacos.client.naming.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.InitUtils;
import com.alibaba.nacos.client.utils.ValidatorUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
@ -50,16 +51,15 @@ public class NacosNamingMaintainService implements NamingMaintainService {
public NacosNamingMaintainService(String serverList) {
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverList);
init(properties);
}
public NacosNamingMaintainService(Properties properties) {
init(properties);
}
private void init(Properties properties) {
ValidatorUtils.checkInitParam(properties);
namespace = InitUtils.initNamespaceForNaming(properties);
initServerAddr(properties);
InitUtils.initWebRootContext();

View File

@ -35,6 +35,7 @@ import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.InitUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.client.security.SecurityProxy;
import com.alibaba.nacos.client.utils.ValidatorUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
@ -77,7 +78,6 @@ public class NacosNamingService implements NamingService {
public NacosNamingService(String serverList) {
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverList);
init(properties);
}
@ -86,6 +86,7 @@ public class NacosNamingService implements NamingService {
}
private void init(Properties properties) {
ValidatorUtils.checkInitParam(properties);
namespace = InitUtils.initNamespaceForNaming(properties);
initServerAddr(properties);
InitUtils.initWebRootContext();

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.client.naming.core;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.common.utils.IoUtils;
import java.net.DatagramPacket;

View File

@ -38,8 +38,8 @@ import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
*/
public class HttpClient {
public static final int TIME_OUT_MILLIS = Integer
.getInteger("com.alibaba.nacos.client.naming.ctimeout", 50000);
public static final int READ_TIME_OUT_MILLIS = Integer
.getInteger("com.alibaba.nacos.client.naming.rtimeout", 50000);
public static final int CON_TIME_OUT_MILLIS = Integer
.getInteger("com.alibaba.nacos.client.naming.ctimeout", 3000);
private static final boolean ENABLE_HTTPS = Boolean
@ -73,7 +73,7 @@ public class HttpClient {
setHeaders(conn, headers, encoding);
conn.setConnectTimeout(CON_TIME_OUT_MILLIS);
conn.setReadTimeout(TIME_OUT_MILLIS);
conn.setReadTimeout(READ_TIME_OUT_MILLIS);
conn.setRequestMethod(method);
conn.setDoOutput(true);
if (StringUtils.isNotBlank(body)) {
@ -207,5 +207,11 @@ public class HttpClient {
public String getHeader(String name) {
return respHeaders.get(name);
}
@Override
public String toString() {
return "HttpResult{" + "code=" + code + ", content='" + content + '\''
+ ", respHeaders=" + respHeaders + '}';
}
}
}

View File

@ -492,7 +492,7 @@ public class NamingProxy {
NAMING_LOGGER.error("request: {} failed, servers: {}, code: {}, msg: {}",
api, servers, exception.getErrCode(), exception.getErrMsg());
throw new NacosException(exception.getErrCode(), "failed to req API:/api/" + api + " after all servers(" + servers + ") tried: "
throw new NacosException(exception.getErrCode(), "failed to req API:" + api + " after all servers(" + servers + ") tried: "
+ exception.getMessage());
}

View File

@ -20,6 +20,7 @@ import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.utils.*;
import com.alibaba.nacos.common.utils.StringUtils;
import java.util.Properties;
import java.util.concurrent.Callable;

View File

@ -15,6 +15,8 @@
*/
package com.alibaba.nacos.client.utils;
import com.alibaba.nacos.common.utils.StringUtils;
import java.io.File;
/**

View File

@ -15,6 +15,8 @@
*/
package com.alibaba.nacos.client.utils;
import com.alibaba.nacos.common.utils.StringUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

View File

@ -15,6 +15,8 @@
*/
package com.alibaba.nacos.client.utils;
import com.alibaba.nacos.common.utils.StringUtils;
import java.util.concurrent.Callable;
/**

View File

@ -15,6 +15,8 @@
*/
package com.alibaba.nacos.client.utils;
import com.alibaba.nacos.common.utils.StringUtils;
/**
* Tenant Util
*

View File

@ -0,0 +1,69 @@
/*
* 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.utils;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.common.utils.StringUtils;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* All parameter validation tools
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class ValidatorUtils {
private static final Pattern CONTEXT_PATH_MATCH = Pattern.compile("(\\/)\\1+");
private static final Pattern IP_MATCH = Pattern.compile("([^\\/:]+)(:\\d+)");
public static void checkInitParam(Properties properties) {
checkServerAddr(properties.getProperty(PropertyKeyConst.SERVER_ADDR));
checkContextPath(properties.getProperty(PropertyKeyConst.CONTEXT_PATH));
}
public static void checkServerAddr(String serverAddr) {
if (StringUtils.isEmpty(serverAddr)) {
throw new IllegalArgumentException("Please set the serverAddr");
}
String[] addrs;
if (serverAddr.contains(StringUtils.COMMA)) {
addrs = serverAddr.split(StringUtils.COMMA);
} else {
addrs = new String[]{serverAddr};
}
for (String addr : addrs) {
Matcher matcher = IP_MATCH.matcher(addr.trim());
if (!matcher.find()) {
throw new IllegalArgumentException("Incorrect serverAddr address : " + addr + ", example should like ip:port or domain:port");
}
}
}
public static void checkContextPath(String contextPath) {
if (contextPath == null) {
return;
}
Matcher matcher = CONTEXT_PATH_MATCH.matcher(contextPath);
if (matcher.find()) {
throw new IllegalArgumentException("Illegal url path expression");
}
}
}

View File

@ -8,8 +8,7 @@ import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.junit.MockitoJUnitRunner;
import java.lang.reflect.Field;
import java.util.HashMap;
@ -38,7 +37,6 @@ public class BeatReactorTest {
beatInfo.setScheduled(false);
beatInfo.setPeriod(1000L);
Mockito.doReturn(0L).when(namingProxy).sendBeat(beatInfo, true);
beatReactor.addBeatInfo("testService", beatInfo);
Assert.assertEquals(1, getActiveThread(beatReactor));

View File

@ -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.client;
import com.alibaba.nacos.api.config.ConfigService;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ConfigTest {
private ConfigService config7;
private ConfigService config8;
private ConfigService config9;
public void test() {
}
}

View File

@ -19,20 +19,22 @@ import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.common.utils.ThreadUtils;
import org.junit.Ignore;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* @author nkorange
*/
@Ignore
public class NamingTest {
@Test
@Ignore
public void testServiceList() throws Exception {
Properties properties = new Properties();
@ -53,6 +55,13 @@ public class NamingTest {
namingService.registerInstance("nacos.test.1", instance);
ThreadUtils.sleep(5_000L);
List<Instance> list = namingService.getAllInstances("nacos.test.1");
System.out.println(list);
ThreadUtils.sleep(60_000L);
// ExpressionSelector expressionSelector = new ExpressionSelector();
// expressionSelector.setExpression("INSTANCE.metadata.registerSource = 'dubbo'");
// ListView<String> serviceList = namingService.getServicesOfServer(1, 10, expressionSelector);

View File

@ -1,63 +0,0 @@
package com.alibaba.nacos.client;
import com.alibaba.nacos.client.utils.StringUtils;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import static com.alibaba.nacos.client.utils.StringUtils.*;
import static org.junit.Assert.*;
@Deprecated
public class StringUtilsTest {
@Test
public void testisNotBlank() {
assertTrue(isNotBlank("foo"));
assertFalse(isNotBlank(" "));
assertFalse(isNotBlank(null));
}
@Test
public void testIsNotEmpty() {
assertFalse(isNotEmpty(""));
assertTrue(isNotEmpty("foo"));
}
@Test
public void testDefaultIfEmpty() {
assertEquals("foo", defaultIfEmpty("", "foo"));
assertEquals("bar", defaultIfEmpty("bar", "foo"));
}
@Test
public void testEquals() {
assertTrue(StringUtils.equals("foo", "foo"));
assertFalse(StringUtils.equals("bar", "foo"));
assertFalse(StringUtils.equals(" ", "foo"));
assertFalse(StringUtils.equals("foo", null));
}
@Test
public void testSubstringBetween() {
assertNull(substringBetween(null, null, null));
assertNull(substringBetween("", "foo", ""));
assertNull(substringBetween("foo", "bar", "baz"));
assertEquals("", substringBetween("foo", "foo", ""));
}
@Test
public void testJoin() {
assertNull(join(null, ""));
Collection collection = new ArrayList();
collection.add("foo");
collection.add("bar");
assertEquals("foo,bar", join(collection, ","));
}
}

View File

@ -1,71 +0,0 @@
/*
* Copyright 1999-2019 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.utils;
import org.junit.Assert;
import org.junit.Test;
public class MD5Test {
@Test
public void testGetMD5String() {
Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e",
MD5.getInstance().getMD5String(""));
Assert.assertEquals("acbd18db4cc2f85cedef654fccc4a4d8",
MD5.getInstance().getMD5String("foo"));
Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e",
MD5.getInstance().getMD5String(new byte[0]));
Assert.assertEquals("5289df737df57326fcdd22597afb1fac",
MD5.getInstance().getMD5String(new byte[]{1, 2, 3}));
}
@Test
public void testGetMD5Bytes() {
byte[] bytes1 = new byte[]{-44, 29, -116, -39, -113, 0, -78,
4, -23, -128, 9, -104, -20, -8, 66, 126};
byte[] bytes2 = new byte[]{82, -119, -33, 115, 125, -11, 115,
38, -4, -35, 34, 89, 122, -5, 31, -84};
Assert.assertArrayEquals(bytes1,
MD5.getInstance().getMD5Bytes(new byte[0]));
Assert.assertArrayEquals(bytes2,
MD5.getInstance().getMD5Bytes(new byte[]{1, 2, 3}));
}
@Test
public void testHash() {
byte[] bytes1 = new byte[]{-44, 29, -116, -39, -113, 0, -78,
4, -23, -128, 9, -104, -20, -8, 66, 126};
byte[] bytes2 = new byte[]{-84, -67, 24, -37, 76, -62, -8, 92,
-19, -17, 101, 79, -52, -60, -92, -40};
byte[] bytes3 = new byte[]{82, -119, -33, 115, 125, -11, 115,
38, -4, -35, 34, 89, 122, -5, 31, -84};
Assert.assertArrayEquals(bytes1, MD5.getInstance().hash(""));
Assert.assertArrayEquals(bytes2, MD5.getInstance().hash("foo"));
Assert.assertArrayEquals(bytes1, MD5.getInstance().hash(new byte[0]));
Assert.assertArrayEquals(bytes3,
MD5.getInstance().hash(new byte[]{1, 2, 3}));
}
@Test
public void testBytes2string() {
Assert.assertEquals("", MD5.getInstance().bytes2string(new byte[0]));
Assert.assertEquals("010203",
MD5.getInstance().bytes2string(new byte[]{1, 2, 3}));
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.utils;
import com.alibaba.nacos.common.utils.StringUtils;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import static com.alibaba.nacos.common.utils.StringUtils.*;
import static org.junit.Assert.*;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class StringUtilsTest {
@Test
public void testisNotBlank() {
assertTrue(isNotBlank("foo"));
assertFalse(isNotBlank(" "));
assertFalse(isNotBlank(null));
}
@Test
public void testIsNotEmpty() {
assertFalse(isNotEmpty(""));
assertTrue(isNotEmpty("foo"));
}
@Test
public void testDefaultIfEmpty() {
assertEquals("foo", defaultIfEmpty("", "foo"));
assertEquals("bar", defaultIfEmpty("bar", "foo"));
}
@Test
public void testEquals() {
assertTrue(StringUtils.equals("foo", "foo"));
assertFalse(StringUtils.equals("bar", "foo"));
assertFalse(StringUtils.equals(" ", "foo"));
assertFalse(StringUtils.equals("foo", null));
}
@Test
public void testSubstringBetween() {
assertNull(substringBetween(null, null, null));
assertNull(substringBetween("", "foo", ""));
assertNull(substringBetween("foo", "bar", "baz"));
assertEquals("", substringBetween("foo", "foo", ""));
}
@Test
public void testJoin() {
assertNull(join(null, ""));
Collection collection = new ArrayList();
collection.add("foo");
collection.add("bar");
assertEquals("foo,bar", join(collection, ","));
}
}

View File

@ -0,0 +1,89 @@
package com.alibaba.nacos.client.utils;
import org.junit.Test;
public class ValidatorUtilsTest {
@Test
public void test_context_path_legal() {
String contextPath1 = "/nacos";
ValidatorUtils.checkContextPath(contextPath1);
String contextPath2 = "nacos";
ValidatorUtils.checkContextPath(contextPath2);
String contextPath3 = "/";
ValidatorUtils.checkContextPath(contextPath3);
String contextPath4 = "";
ValidatorUtils.checkContextPath(contextPath4);
}
@Test(expected = IllegalArgumentException.class)
public void test_context_path_illegal_1() {
String contextPath1 = "//nacos/";
ValidatorUtils.checkContextPath(contextPath1);
}
@Test(expected = IllegalArgumentException.class)
public void test_context_path_illegal_2() {
String contextPath2 = "/nacos//";
ValidatorUtils.checkContextPath(contextPath2);
}
@Test(expected = IllegalArgumentException.class)
public void test_context_path_illegal_3() {
String contextPath3 = "///";
ValidatorUtils.checkContextPath(contextPath3);
}
@Test(expected = IllegalArgumentException.class)
public void test_context_path_illegal_4() {
String contextPath4 = "//";
ValidatorUtils.checkContextPath(contextPath4);
}
@Test
public void test_server_addr() {
String serverAddr = "127.0.0.1:8848";
ValidatorUtils.checkServerAddr(serverAddr);
String serverAddrs = "127.0.0.1:8848,127.0.0.1:80,127.0.0.1:8809";
ValidatorUtils.checkServerAddr(serverAddrs);
}
@Test
public void test_server_addr_k8s() {
String serverAddr = "busybox-1.busybox-subdomain.default.svc.cluster.local:80";
ValidatorUtils.checkServerAddr(serverAddr);
String serverAddrs = "busybox-1.busybox-subdomain.default.svc.cluster.local:80,busybox-1.busybox-subdomain.default.svc.cluster.local:8111, busybox-1.busybox-subdomain.default.svc.cluster.local:8098";
ValidatorUtils.checkServerAddr(serverAddrs);
}
@Test(expected = IllegalArgumentException.class)
public void test_server_addr_err() {
String serverAddr = "127.0.0.1";
ValidatorUtils.checkServerAddr(serverAddr);
}
@Test(expected = IllegalArgumentException.class)
public void test_server_addr_illegal_err() {
String serverAddr = "127.0.0.1:";
ValidatorUtils.checkServerAddr(serverAddr);
}
@Test(expected = IllegalArgumentException.class)
public void test_server_addrs_err() {
String serverAddrs = "127.0.0.1:8848,127.0.0.1,127.0.0.1:8809";
ValidatorUtils.checkServerAddr(serverAddrs);
}
@Test(expected = IllegalArgumentException.class)
public void test_server_addr_k8s_err() {
String serverAddr = "busybox-1.busybox-subdomain.default.svc.cluster.local";
ValidatorUtils.checkServerAddr(serverAddr);
}
@Test(expected = IllegalArgumentException.class)
public void test_server_addrs_k8s_err() {
String serverAddrs = "busybox-1.busybox-subdomain.default.svc.cluster.local,busybox-1.busybox-subdomain.default.svc.cluster.local:8111, busybox-1.busybox-subdomain.default.svc.cluster.local:8098";
ValidatorUtils.checkServerAddr(serverAddrs);
}
}

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId>
<version>1.2.1</version>
<version>1.3.0-BETA</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.2.1</version>
<version>1.3.0-BETA</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -49,11 +49,25 @@
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
@ -68,8 +82,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>6</source>
<target>6</target>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>

View File

@ -0,0 +1,23 @@
/*
* 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;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public @interface JustForTest {
}

View File

@ -24,5 +24,6 @@ public interface HttpHeaderConsts {
String CLIENT_VERSION_HEADER = "Client-Version";
String USER_AGENT_HEADER = "User-Agent";
String REQUEST_SOURCE_HEADER = "Request-Source";
}

View File

@ -0,0 +1,111 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.executor;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Unified thread pool creation factory, and actively create thread
* pool resources by ThreadPoolManager for unified life cycle management
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("PMD.ThreadPoolCreationRule")
public final class ExecutorFactory {
private static final ThreadPoolManager THREAD_POOL_MANAGER = ThreadPoolManager.getInstance();
public static final String DEFAULT_NAMESPACE = "nacos";
public static ForkJoinPool newForkJoinPool(final String group) {
ForkJoinPool forkJoinPool = new ForkJoinPool();
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, forkJoinPool);
return forkJoinPool;
}
public static ForkJoinPool newForkJoinPool(final String group,
final int nThreads) {
ForkJoinPool forkJoinPool = new ForkJoinPool(nThreads);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, forkJoinPool);
return forkJoinPool;
}
public static ExecutorService newSingleExecutorService(final String group) {
ExecutorService executorService = Executors.newFixedThreadPool(1);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ExecutorService newSingleExecutorService(final String group,
final ThreadFactory threadFactory) {
ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ExecutorService newFixExecutorService(final String group,
final int nThreads) {
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ExecutorService newFixExecutorService(final String group,
final int nThreads,
final ThreadFactory threadFactory) {
ExecutorService executorService = Executors.newFixedThreadPool(nThreads, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ScheduledExecutorService newSingleScheduledExecutorService(final String group,
final ThreadFactory threadFactory) {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ScheduledExecutorService newScheduledExecutorService(final String group,
final int nThreads,
final ThreadFactory threadFactory) {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(nThreads, threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
return executorService;
}
public static ThreadPoolExecutor newCustomerThreadExecutor(final String group,
final int coreThreads,
final int maxThreads,
final long keepAliveTimeMs,
final ThreadFactory threadFactory) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(coreThreads, maxThreads,
keepAliveTimeMs, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executor);
return executor;
}
}

View File

@ -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.executor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class NameThreadFactory implements ThreadFactory {
private final AtomicInteger id = new AtomicInteger(0);
private String name;
public NameThreadFactory(String name) {
this.name = name;
}
@Override
public Thread newThread(Runnable r) {
String threadName = name + id.getAndDecrement();
Thread thread = new Thread(r, threadName);
thread.setDaemon(true);
return thread;
}
}

View File

@ -0,0 +1,188 @@
/*
* 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.executor;
import com.alibaba.nacos.common.utils.ShutdownUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* // TODO Access Metric
*
* For unified management of thread pool resources, the consumer can simply call
* the register method to {@link ThreadPoolManager#register(String, String, ExecutorService)}
* the thread pool that needs to be included in the life cycle management of the resource
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class ThreadPoolManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolManager.class);
private Map<String, Map<String, Set<ExecutorService>>> resourcesManager;
private Map<String, Object> lockers = new ConcurrentHashMap<String, Object>(8);
private static final ThreadPoolManager INSTANCE = new ThreadPoolManager();
private static final AtomicBoolean CLOSED = new AtomicBoolean(false);
static {
INSTANCE.init();
ShutdownUtils.addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
LOGGER.warn("[ThreadPoolManager] Start destroying ThreadPool");
shutdown();
LOGGER.warn("[ThreadPoolManager] Destruction of the end");
}
}));
}
public static ThreadPoolManager getInstance() {
return INSTANCE;
}
private ThreadPoolManager() {}
private void init() {
resourcesManager = new ConcurrentHashMap<>(8);
}
/**
* Register the thread pool resources with the resource manager
*
* @param namespace namespace name
* @param group group name
* @param executor {@link ExecutorService}
*/
public void register(String namespace, String group, ExecutorService executor) {
if (!resourcesManager.containsKey(namespace)) {
synchronized(this) {
lockers.put(namespace, new Object());
}
}
final Object monitor = lockers.get(namespace);
synchronized (monitor) {
Map<String, Set<ExecutorService>> map = resourcesManager.get(namespace);
if (map == null) {
map = new HashMap<>(8);
map.put(group, new HashSet<ExecutorService>());
map.get(group).add(executor);
resourcesManager.put(namespace, map);
return;
}
if (!map.containsKey(group)) {
map.put(group, new HashSet<ExecutorService>());
}
map.get(group).add(executor);
}
}
/**
* Cancel the uniform lifecycle management for all threads under this resource
*
* @param namespace namespace name
* @param group group name
*/
public void deregister(String namespace, String group) {
if (resourcesManager.containsKey(namespace)) {
final Object monitor = lockers.get(namespace);
synchronized (monitor) {
resourcesManager.get(namespace).remove(group);
}
}
}
/**
* Undoing the uniform lifecycle management of {@link ExecutorService} under this resource
*
* @param namespace namespace name
* @param group group name
* @param executor {@link ExecutorService}
*/
public void deregister(String namespace, String group, ExecutorService executor) {
if (resourcesManager.containsKey(namespace)) {
final Object monitor = lockers.get(namespace);
synchronized (monitor) {
final Map<String, Set<ExecutorService>> subResourceMap = resourcesManager.get(namespace);
if (subResourceMap.containsKey(group)) {
subResourceMap.get(group).remove(executor);
}
}
}
}
public void destroy(String namespace) {
final Object monitor = lockers.get(namespace);
if (monitor == null) {
return;
}
synchronized (monitor) {
Map<String, Set<ExecutorService>> subResource = resourcesManager.get(namespace);
if (subResource == null) {
return;
}
for (Map.Entry<String, Set<ExecutorService>> entry : subResource.entrySet()) {
for (ExecutorService executor : entry.getValue()) {
shutdownThreadPool(executor);
}
}
resourcesManager.get(namespace).clear();
resourcesManager.remove(namespace);
}
}
private void shutdownThreadPool(ExecutorService executor) {
executor.shutdown();
int retry = 3;
while (retry > 0) {
retry --;
try {
if (executor.awaitTermination(10, TimeUnit.SECONDS)) {
return;
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.interrupted();
} catch (Throwable ex) {
LOGGER.error("ThreadPoolManager shutdown executor has error : {}", ex);
}
}
executor.shutdownNow();
}
public static void shutdown() {
if (!CLOSED.compareAndSet(false, true)) {
return;
}
Set<String> namespaces = INSTANCE.resourcesManager.keySet();
for (String namespace : namespaces) {
INSTANCE.destroy(namespace);
}
}
}

View File

@ -0,0 +1,83 @@
/*
* 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.file;
import java.io.Serializable;
import java.nio.file.WatchEvent;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class FileChangeEvent implements Serializable {
private static final long serialVersionUID = -4255584033113954765L;
private String paths;
private Object context;
public static FileChangeEventBuilder builder() {
return new FileChangeEventBuilder();
}
public String getPaths() {
return paths;
}
public void setPaths(String paths) {
this.paths = paths;
}
public Object getContext() {
return context;
}
public void setContext(Object context) {
this.context = context;
}
@Override
public String toString() {
return "FileChangeEvent{" + "paths='" + paths + '\'' + ", context=" + context
+ '}';
}
public static final class FileChangeEventBuilder {
private String paths;
private Object context;
private FileChangeEventBuilder() {
}
public FileChangeEventBuilder paths(String paths) {
this.paths = paths;
return this;
}
public FileChangeEventBuilder context(Object context) {
this.context = context;
return this;
}
public FileChangeEvent build() {
FileChangeEvent fileChangeEvent = new FileChangeEvent();
fileChangeEvent.setPaths(paths);
fileChangeEvent.setContext(context);
return fileChangeEvent;
}
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.file;
import java.nio.file.WatchEvent;
import java.util.concurrent.Executor;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class FileWatcher {
/**
* Triggered when a file change occurs
*
* @param event {@link FileChangeEvent}
*/
public abstract void onChange(FileChangeEvent event);
/**
* WatchEvent context information
*
* @param context {@link WatchEvent#context()}
* @return is this watcher interest context
*/
public abstract boolean interest(String context);
/**
* If the FileWatcher has its own thread pool, use this thread
* pool to execute, otherwise use the WatchFileManager thread
*
* @return {@link Executor}
*/
public Executor executor() {
return null;
}
}

View File

@ -0,0 +1,262 @@
/*
* 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.file;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.common.executor.ExecutorFactory;
import com.alibaba.nacos.common.executor.NameThreadFactory;
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
import com.alibaba.nacos.common.utils.ShutdownUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Unified file change monitoring management center, which uses {@link WatchService} internally.
* One file directory corresponds to one {@link WatchService}. It can only monitor up to 32 file
* directories. When a file change occurs, a {@link FileChangeEvent} will be issued
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class WatchFileCenter {
private static final Logger LOGGER = LoggerFactory.getLogger(WatchFileCenter.class);
/**
* Maximum number of monitored file directories
*/
private static final int MAX_WATCH_FILE_JOB = Integer
.getInteger("nacos.watch-file.max-dirs", 16);
private static final Map<String, WatchDirJob> MANAGER = new HashMap<String, WatchDirJob>(
MAX_WATCH_FILE_JOB);
private static final FileSystem FILE_SYSTEM = FileSystems.getDefault();
private static final AtomicBoolean CLOSED = new AtomicBoolean(false);
static {
ShutdownUtils.addShutdownHook(new Runnable() {
@Override
public void run() {
shutdown();
}
});
}
/**
* The number of directories that are currently monitored
*/
private static int NOW_WATCH_JOB_CNT = 0;
public synchronized static boolean registerWatcher(final String paths,
FileWatcher watcher) throws NacosException {
checkState();
NOW_WATCH_JOB_CNT++;
if (NOW_WATCH_JOB_CNT > MAX_WATCH_FILE_JOB) {
return false;
}
WatchDirJob job = MANAGER.get(paths);
if (job == null) {
job = new WatchDirJob(paths);
job.start();
MANAGER.put(paths, job);
}
job.addSubscribe(watcher);
return true;
}
public synchronized static boolean deregisterAllWatcher(final String path) {
WatchDirJob job = MANAGER.get(path);
if (job != null) {
job.shutdown();
MANAGER.remove(path);
return true;
}
return false;
}
public static void shutdown() {
if (!CLOSED.compareAndSet(false, true)) {
return;
}
LOGGER.warn("[WatchFileCenter] start close");
for (Map.Entry<String, WatchDirJob> entry : MANAGER.entrySet()) {
LOGGER.warn("[WatchFileCenter] start to shutdown this watcher which is watch : " + entry.getKey());
try {
entry.getValue().shutdown();
} catch (Throwable e) {
LOGGER.error("[WatchFileCenter] shutdown has error : {}", e);
}
}
MANAGER.clear();
LOGGER.warn("[WatchFileCenter] already closed");
}
public synchronized static boolean deregisterWatcher(final String path, final FileWatcher watcher) {
WatchDirJob job = MANAGER.get(path);
if (job != null) {
job.watchers.remove(watcher);
return true;
}
return false;
}
private static class WatchDirJob extends Thread {
private ExecutorService callBackExecutor;
private final String paths;
private WatchService watchService;
private volatile boolean watch = true;
private Set<FileWatcher> watchers = new ConcurrentHashSet<>();
public WatchDirJob(String paths) throws NacosException {
setName(paths);
this.paths = paths;
final Path p = Paths.get(paths);
if (!p.toFile().isDirectory()) {
throw new IllegalArgumentException("Must be a file directory : " + paths);
}
this.callBackExecutor = ExecutorFactory
.newFixExecutorService(WatchFileCenter.class.getCanonicalName(),
1,
new NameThreadFactory("com.alibaba.nacos.file.watch-" + paths));
try {
WatchService service = FILE_SYSTEM.newWatchService();
p.register(service, StandardWatchEventKinds.OVERFLOW,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE);
this.watchService = service;
}
catch (Throwable ex) {
throw new NacosException(NacosException.SERVER_ERROR, ex);
}
}
void addSubscribe(final FileWatcher watcher) {
watchers.add(watcher);
}
void shutdown() {
watch = false;
}
@Override
public void run() {
while (watch) {
try {
final WatchKey watchKey = watchService.take();
final List<WatchEvent<?>> events = watchKey.pollEvents();
watchKey.reset();
if (callBackExecutor.isShutdown()) {
return;
}
callBackExecutor.execute(new Runnable() {
@Override
public void run() {
for (WatchEvent<?> event : events) {
WatchEvent.Kind<?> kind = event.kind();
// Since the OS's event cache may be overflow, a backstop is needed
if (StandardWatchEventKinds.OVERFLOW.equals(kind)) {
eventOverflow();
}
else {
eventProcess(event.context());
}
}
}
});
}
catch (InterruptedException ignore) {
Thread.interrupted();
} catch (Throwable ex) {
LOGGER.error("An exception occurred during file listening : {}", ex);
}
}
}
private void eventProcess(Object context) {
final FileChangeEvent fileChangeEvent = FileChangeEvent.builder().paths(paths)
.context(context).build();
final String str = String.valueOf(context);
for (final FileWatcher watcher : watchers) {
if (watcher.interest(str)) {
Runnable job = new Runnable() {
@Override
public void run() {
watcher.onChange(fileChangeEvent);
}
};
Executor executor = watcher.executor();
if (executor == null) {
try {
job.run();
} catch (Throwable ex) {
LOGGER.error("File change event callback error : {}", ex);
}
}
else {
executor.execute(job);
}
}
}
}
private void eventOverflow() {
File dir = Paths.get(paths).toFile();
for (File file : Objects.requireNonNull(dir.listFiles())) {
// Subdirectories do not participate in listening
if (file.isDirectory()) {
continue;
}
eventProcess(file.getName());
}
}
}
private static void checkState() {
if (CLOSED.get()) {
throw new IllegalStateException("WatchFileCenter already shutdown");
}
}
}

View File

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

View File

@ -0,0 +1,182 @@
/*
* 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.handler.RequestHandler;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.utils.HttpMethod;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
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;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public enum BaseHttpMethod {
/**
* get request
*/
GET(HttpMethod.GET) {
@Override
protected HttpRequestBase createRequest(String url) {
return new HttpGet(url);
}
},
GET_LARGE(HttpMethod.GET_LARGE) {
@Override
protected HttpRequestBase createRequest(String url) {
return new BaseHttpClient.HttpGetWithEntity(url);
}
},
/**
* post request
*/
POST(HttpMethod.POST) {
@Override
protected HttpRequestBase createRequest(String url) {
return new HttpPost(url);
}
},
/**
* put request
*/
PUT(HttpMethod.PUT) {
@Override
protected HttpRequestBase createRequest(String url) {
return new HttpPut(url);
}
},
/**
* delete request
*/
DELETE(HttpMethod.DELETE) {
@Override
protected HttpRequestBase createRequest(String url) {
return new HttpDelete(url);
}
},
/**
* head request
*/
HEAD(HttpMethod.HEAD) {
@Override
protected HttpRequestBase createRequest(String url) {
return new HttpHead(url);
}
},
/**
* trace request
*/
TRACE(HttpMethod.TRACE) {
@Override
protected HttpRequestBase createRequest(String url) {
return new HttpTrace(url);
}
},
/**
* patch request
*/
PATCH(HttpMethod.PATCH) {
@Override
protected HttpRequestBase createRequest(String url) {
return new HttpPatch(url);
}
},
/**
* options request
*/
OPTIONS(HttpMethod.OPTIONS) {
@Override
protected HttpRequestBase createRequest(String url) {
return new HttpTrace(url);
}
},
;
private String name;
private HttpRequest requestBase;
BaseHttpMethod(String name) {
this.name = name;
}
public void init(String url) {
requestBase = createRequest(url);
}
protected HttpRequestBase createRequest(String url) {
throw new UnsupportedOperationException();
}
public void initHeader(Header header) {
Iterator<Map.Entry<String, String>> iterator = header.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
requestBase.setHeader(entry.getKey(), entry.getValue());
}
}
public void initEntity(Object body, String mediaType) throws Exception {
if (body == null) {
return;
}
if (requestBase instanceof HttpEntityEnclosingRequest) {
HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) requestBase;
ContentType contentType = ContentType.create(mediaType);
StringEntity entity = new StringEntity(RequestHandler.parse(body), contentType);
request.setEntity(entity);
}
}
public HttpRequestBase getRequestBase() {
return (HttpRequestBase) requestBase;
}
public static BaseHttpMethod sourceOf(String name) {
for (BaseHttpMethod method : BaseHttpMethod.values()) {
if (StringUtils.equalsIgnoreCase(name, method.name)) {
return method;
}
}
throw new IllegalArgumentException("Unsupported http method : " + name);
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.model.RestResult;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface Callback<T> {
/**
* Callback after the request is responded
*
* @param result {@link RestResult}
*/
void onReceive(RestResult<T> result);
/**
* An error occurred during the request
*
* @param throwable {@link Throwable}
*/
void onError(Throwable throwable);
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.http;
import com.alibaba.nacos.common.utils.ShutdownUtils;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Use the same HttpClient object in the same space
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public class HttpClientManager {
private static final Logger logger = LoggerFactory.getLogger(HttpClientManager.class);
private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000);
private static final RequestConfig DEFAULT_CONFIG = RequestConfig.custom()
.setConnectTimeout(TIMEOUT).setSocketTimeout(TIMEOUT << 1).build();
private static final NSyncHttpClient SYNC_HTTP_CLIENT = new NacosSyncHttpClient(
HttpClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
private static final NAsyncHttpClient ASYNC_HTTP_CLIENT = new NacosAsyncHttpClient(
HttpAsyncClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());
static {
ShutdownUtils.addShutdownHook(new Runnable() {
@Override
public void run() {
logger.warn("[HttpClientManager] Start destroying HttpClient");
try {
SYNC_HTTP_CLIENT.close();
ASYNC_HTTP_CLIENT.close();
}
catch (Exception ignore) {
}
logger.warn("[HttpClientManager] Destruction of the end");
}
});
}
public static NSyncHttpClient getSyncHttpClient() {
return SYNC_HTTP_CLIENT;
}
public static NAsyncHttpClient getAsyncHttpClient() {
return ASYNC_HTTP_CLIENT;
}
}

View File

@ -0,0 +1,136 @@
/*
* 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.utils.StringUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class HttpUtils {
private static final Pattern CONTEXT_PATH_MATCH = Pattern.compile("(\\/)\\1+");
public static String buildUrl(boolean isHttps, String serverAddr, String... subPaths) {
StringBuilder sb = new StringBuilder();
if (isHttps) {
sb.append("https://");
} else {
sb.append("http://");
}
sb.append(serverAddr);
String pre = null;
for (String subPath : subPaths) {
if (StringUtils.isBlank(subPath)) {
continue;
}
Matcher matcher = CONTEXT_PATH_MATCH.matcher(subPath);
if (matcher.find()) {
throw new IllegalArgumentException("Illegal url path expression : " + subPath);
}
if (pre == null || !pre.endsWith("/")) {
if (subPath.startsWith("/")) {
sb.append(subPath);
}
else {
sb.append("/").append(subPath);
}
} else {
if (subPath.startsWith("/")) {
sb.append(subPath.replaceFirst("\\/", ""));
}
else {
sb.append(subPath);
}
}
pre = subPath;
}
return sb.toString();
}
public static Map<String, String> translateParameterMap(Map<String, String[]> parameterMap) throws Exception {
Map<String, String> map = new HashMap<String, String>(16);
for (String key : parameterMap.keySet()) {
map.put(key, parameterMap.get(key)[0]);
}
return map;
}
public static String encodingParams(Map<String, String> params, String encoding)
throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
if (null == params || params.isEmpty()) {
return null;
}
for (Map.Entry<String, String> entry : params.entrySet()) {
if (StringUtils.isEmpty(entry.getValue())) {
continue;
}
sb.append(entry.getKey()).append("=");
sb.append(URLEncoder.encode(entry.getValue(), encoding));
sb.append("&");
}
return sb.toString();
}
public static String encodingParams(List<String> paramValues, String encoding)
throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
if (null == paramValues) {
return null;
}
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext(); ) {
sb.append(iter.next()).append("=");
sb.append(URLEncoder.encode(iter.next(), encoding));
if (iter.hasNext()) {
sb.append("&");
}
}
return sb.toString();
}
public static String decode(String str, String encode) throws UnsupportedEncodingException {
return innerDecode(null, str, encode);
}
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
if (StringUtils.equals(pre, now)) {
return pre;
}
pre = now;
now = URLDecoder.decode(now, encode);
return innerDecode(pre, now, encode);
}
}

View File

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

View File

@ -0,0 +1,27 @@
/*
* 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 java.io.Closeable;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public interface NHttpClient extends Closeable {
}

View File

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

View File

@ -0,0 +1,97 @@
/*
* 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.http.param.Query;
import com.alibaba.nacos.common.utils.HttpMethod;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import java.io.IOException;
import java.lang.reflect.Type;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
class NacosAsyncHttpClient extends BaseHttpClient implements NAsyncHttpClient {
private CloseableHttpAsyncClient asyncClient;
NacosAsyncHttpClient(CloseableHttpAsyncClient asyncClient) {
this.asyncClient = asyncClient;
this.asyncClient.start();
}
@Override
public <T> void get(final String url,
final Header header,
final Query query,
final Type token,
final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.GET);
execute(asyncClient, token, callback, requestBase);
}
@Override
public <T> void getLarge(final String url,
final Header header,
final Query query,
final Object body,
final Type token,
final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.GET_LARGE);
execute(asyncClient, token, callback, requestBase);
}
@Override
public <T> void delete(final String url,
final Header header,
final Query query,
final Type token,
final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.DELETE);
execute(asyncClient, token, callback, requestBase);
}
@Override
public <T> void put(final String url,
final Header header,
final Query query,
final Object body,
final Type token,
final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.PUT);
execute(asyncClient, token, callback, requestBase);
}
@Override
public <T> void post(final String url,
final Header header,
final Query query,
final Object body,
final Type token,
final Callback<T> callback) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.POST);
execute(asyncClient, token, callback, requestBase);
}
@Override
public void close() throws IOException {
asyncClient.close();
}
}

View File

@ -0,0 +1,88 @@
/*
* 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.http.param.Query;
import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.common.utils.HttpMethod;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import java.io.IOException;
import java.lang.reflect.Type;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
class NacosSyncHttpClient extends BaseHttpClient implements NSyncHttpClient {
private CloseableHttpClient client;
NacosSyncHttpClient(CloseableHttpClient client) {
this.client = client;
}
@Override
public <T> RestResult<T> get(final String url,
final Header header,
final Query query,
final Type token) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.GET);
return execute(client, token, requestBase);
}
@Override
public <T> RestResult<T> getLarge(String url, Header header, Query query, Object body, Type token) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.GET_LARGE);
return execute(client, token, requestBase);
}
@Override
public <T> RestResult<T> delete(final String url,
final Header header,
final Query query,
final Type token) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, HttpMethod.DELETE);
return execute(client, token, requestBase);
}
@Override
public <T> RestResult<T> put(final String url,
final Header header,
final Query query,
final Object body,
final Type token) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.PUT);
return execute(client, token, requestBase);
}
@Override
public <T> RestResult<T> post(final String url,
final Header header,
final Query query,
final Object body,
final Type token) throws Exception {
HttpRequestBase requestBase = build(buildUrl(url, query), header, body, HttpMethod.POST);
return execute(client, token, requestBase);
}
@Override
public void close() throws IOException {
client.close();
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.http.handler;
import com.alibaba.nacos.common.utils.JacksonUtils;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class RequestHandler {
public static String parse(Object object) throws Exception {
return JacksonUtils.toJson(object);
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.handler;
import com.alibaba.nacos.common.utils.JacksonUtils;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Type;
import org.slf4j.Logger;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class ResponseHandler {
private static final Logger logger = LoggerFactory.getLogger(ResponseHandler.class);
public static <T> T convert(String s, Class<T> cls) throws Exception {
return JacksonUtils.toObj(s, cls);
}
public static <T> T convert(String s, Type type) throws Exception {
return JacksonUtils.toObj(s, type);
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.http.param;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class Header {
public static final Header EMPTY = Header.newInstance();
private final Map<String, String> header;
private Header() {
header = new LinkedHashMap<String, String>();
addParam("Content-Type", "application/json");
addParam("Accept-Charset", "UTF-8");
addParam("Accept-Encoding", "gzip");
addParam("Content-Encoding", "gzip");
}
public static Header newInstance() {
return new Header();
}
public Header addParam(String key, String value) {
header.put(key, value);
return this;
}
public Header builded() {
return this;
}
public String getValue(String key) {
return header.get(key);
}
public Map<String, String> getHeader() {
return header;
}
public Iterator<Map.Entry<String, String>> iterator() {
return header.entrySet().iterator();
}
public List<String> toList() {
List<String> list = new ArrayList<String>(header.size() * 2);
Iterator<Map.Entry<String, String>> iterator = iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
list.add(entry.getKey());
list.add(entry.getValue());
}
return list;
}
public void 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++));
}
}
public void addAll(Map<String, String> params) {
for (Map.Entry<String, String> entry : params.entrySet()) {
addParam(entry.getKey(), entry.getValue());
}
}
public void clear() {
header.clear();
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.http.param;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class MediaType {
private MediaType() {}
public static final String APPLICATION_ATOM_XML = "application/atom+xml";
public static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded";
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
public static final String APPLICATION_SVG_XML = "application/svg+xml";
public static final String APPLICATION_XHTML_XML = "application/xhtml+xml";
public static final String APPLICATION_XML = "application/xml";
public static final String MULTIPART_FORM_DATA = "multipart/form-data";
public static final String TEXT_HTML = "text/html";
public static final String TEXT_PLAIN = "text/xml";
}

View File

@ -0,0 +1,100 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.http.param;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class Query {
private boolean isEmpty = true;
public static final Query EMPTY = Query.newInstance();
private Map<String, Object> params;
public Query() {
params = new LinkedHashMap<String, Object>();
}
public static Query newInstance() {
return new Query();
}
public Query addParam(String key, Object value) {
isEmpty = false;
params.put(key, value);
return this;
}
public Object getValue(String key) {
return params.get(key);
}
public void initParams(Map<String, String> params) {
for (Map.Entry<String, String> entry : params.entrySet()) {
addParam(entry.getKey(), entry.getValue());
}
}
public void initParams(List<String> list) {
if ((list.size() & 1) != 0) {
throw new IllegalArgumentException("list size must be a multiple of 2");
}
for (int i = 0; i < list.size();) {
addParam(list.get(i++), list.get(i++));
}
}
public String toQueryUrl() {
StringBuilder urlBuilder = new StringBuilder();
Set<Map.Entry<String, Object>> entrySet = params.entrySet();
int i = entrySet.size();
for (Map.Entry<String, Object> entry : entrySet) {
try {
urlBuilder.append(entry.getKey()).append("=").append(
URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8"));
if (i > 1) {
urlBuilder.append("&");
}
i--;
}
catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
return urlBuilder.toString();
}
public void clear() {
isEmpty = false;
params.clear();
}
public boolean isEmpty() {
return isEmpty;
}
}

View File

@ -13,22 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.config.server.model;
package com.alibaba.nacos.common.model;
import java.io.Serializable;
/**
* rest result class
*
* @param <T> data type
* @author Nacos
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class RestResult<T> implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6095433538316185017L;
private int code;
@ -78,4 +72,52 @@ public class RestResult<T> implements Serializable {
this.data = data;
}
public boolean ok() {
return this.code == 0 || this.code == 200;
}
@Override
public String toString() {
return "RestResult{" +
"code=" + code +
", message='" + message + '\'' +
", data=" + data +
'}';
}
public static <T> ResResultBuilder<T> builder() {
return new ResResultBuilder<T>();
}
public static final class ResResultBuilder<T> {
private int code;
private String errMsg;
private T data;
private ResResultBuilder() {
}
public ResResultBuilder<T> withCode(int code) {
this.code = code;
return this;
}
public ResResultBuilder<T> withMsg(String errMsg) {
this.errMsg = errMsg;
return this;
}
public ResResultBuilder<T> withData(T data) {
this.data = data;
return this;
}
public RestResult<T> build() {
RestResult<T> restResult = new RestResult<T>();
restResult.setCode(code);
restResult.setMessage(errMsg);
restResult.setData(data);
return restResult;
}
}
}

View File

@ -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.model;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class RestResultUtils {
public static <T> RestResult<T> success() {
return RestResult.<T>builder()
.withCode(200)
.build();
}
public static <T> RestResult<T> success(T data) {
return RestResult.<T>builder()
.withCode(200)
.withData(data)
.build();
}
public static <T> RestResult<T> success(int code, T data) {
return RestResult.<T>builder()
.withCode(code)
.withData(data)
.build();
}
public static <T> RestResult<T> failed() {
return RestResult.<T>builder()
.withCode(500)
.build();
}
public static <T> RestResult<T> failed(String errMsg) {
return RestResult.<T>builder()
.withCode(500)
.withMsg(errMsg)
.build();
}
public static <T> RestResult<T> failed(int code, T data) {
return RestResult.<T>builder()
.withCode(code)
.withData(data)
.build();
}
public static <T> RestResult<T> failed(int code, T data, String errMsg) {
return RestResult.<T>builder()
.withCode(code)
.withData(data)
.withMsg(errMsg)
.build();
}
public static <T> RestResult<T> failedWithMsg(int code, String errMsg) {
return RestResult.<T>builder()
.withCode(code)
.withMsg(errMsg)
.build();
}
}

View File

@ -0,0 +1,17 @@
/*
* 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;

View File

@ -0,0 +1,59 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.apache.commons.lang3.StringUtils;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class ByteUtils {
public static final byte[] EMPTY = new byte[0];
public static byte[] toBytes(String s) {
if (s == null) {
return EMPTY;
}
return s.getBytes(Charset.forName(StandardCharsets.UTF_8.name()));
}
public static byte[] toBytes(Object s) {
if (s == null) {
return EMPTY;
}
return toBytes(String.valueOf(s));
}
public static String toString(byte[] bytes) {
if (bytes == null) {
return StringUtils.EMPTY;
}
return new String(bytes, Charset.forName(StandardCharsets.UTF_8.name()));
}
public static boolean isEmpty(byte[] data) {
return data == null || data.length == 0;
}
public static boolean isNotEmpty(byte[] data) {
return !isEmpty(data);
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ConcurrentHashSet<E> extends AbstractSet<E> {
private ConcurrentHashMap<E, Boolean> map;
/**
* constructor
*/
public ConcurrentHashSet() {
super();
map = new ConcurrentHashMap<E, Boolean>();
}
/**
* return the size of the map
*
* @see java.util.AbstractCollection#size()
*/
@Override
public int size() {
return map.size();
}
/**
* @see java.util.AbstractCollection#contains(java.lang.Object)
*/
@Override
public boolean contains(Object o) {
return map.containsKey(o);
}
/**
* @see java.util.AbstractCollection#iterator()
*/
@Override
public Iterator<E> iterator() {
return map.keySet().iterator();
}
/**
* add an obj to set, if exist, return false, else return true
*
* @see java.util.AbstractCollection#add(java.lang.Object)
*/
@Override
public boolean add(E o) {
return map.putIfAbsent(o, Boolean.TRUE) == null;
}
/**
* @see java.util.AbstractCollection#remove(java.lang.Object)
*/
@Override
public boolean remove(Object o) {
return map.remove(o) != null;
}
/**
* clear the set
*
* @see java.util.AbstractCollection#clear()
*/
@Override
public void clear() {
map.clear();
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import org.apache.commons.lang3.StringUtils;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class ConvertUtils {
private static final String NULL_STR = "null";
public static int toInt(String val, int defaultValue) {
if (StringUtils.equalsIgnoreCase(val, NULL_STR)) {
return defaultValue;
}
if (StringUtils.isBlank(val)) {
return defaultValue;
}
return Integer.parseInt(val);
}
public static long toLong(String val, long defaultValue) {
if (StringUtils.isBlank(val)) {
return defaultValue;
}
return Long.parseLong(val);
}
public static boolean toBoolean(String val, boolean defaultValue) {
if (StringUtils.isBlank(val)) {
return defaultValue;
}
return Boolean.parseBoolean(val);
}
}

View File

@ -0,0 +1,278 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.zip.CheckedInputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.Checksum;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class DiskUtils {
private static final Logger logger = LoggerFactory.getLogger(DiskUtils.class);
private final static String NO_SPACE_CN = "设备上没有空间";
private final static String NO_SPACE_EN = "No space left on device";
private final static String DISK_QUATA_CN = "超出磁盘限额";
private final static String DISK_QUATA_EN = "Disk quota exceeded";
private static final Charset CHARSET = StandardCharsets.UTF_8;
private static final CharsetDecoder DECODER = CHARSET.newDecoder();
public static void touch(String path, String fileName) throws IOException {
FileUtils.touch(Paths.get(path, fileName).toFile());
}
public static void touch(File file) throws IOException {
FileUtils.touch(file);
}
public static String readFile(String path, String fileName) {
File file = openFile(path, fileName);
if (file.exists()) {
return readFile(file);
}
return null;
}
public static String readFile(InputStream is) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
StringBuilder textBuilder = new StringBuilder();
String lineTxt = null;
while ((lineTxt = reader.readLine()) != null) {
textBuilder.append(lineTxt);
}
return textBuilder.toString();
} catch (IOException e) {
return null;
}
}
public static String readFile(File file) {
try (FileChannel fileChannel = new FileInputStream(file).getChannel()) {
StringBuilder text = new StringBuilder();
ByteBuffer buffer = ByteBuffer.allocate(4096);
CharBuffer charBuffer = CharBuffer.allocate(4096);
while (fileChannel.read(buffer) != -1) {
buffer.flip();
DECODER.decode(buffer, charBuffer, false);
charBuffer.flip();
while (charBuffer.hasRemaining()) {
text.append(charBuffer.get());
}
buffer.clear();
charBuffer.clear();
}
return text.toString();
} catch (IOException e) {
return null;
}
}
public static byte[] readFileBytes(File file) {
if (file.exists()) {
String result = readFile(file);
if (result != null) {
return ByteUtils.toBytes(result);
}
}
return null;
}
public static byte[] readFileBytes(String path, String fileName) {
File file = openFile(path, fileName);
return readFileBytes(file);
}
public static boolean writeFile(File file, byte[] content, boolean append) {
try (FileChannel fileChannel = new FileOutputStream(file, append).getChannel()) {
ByteBuffer buffer = ByteBuffer.wrap(content);
fileChannel.write(buffer);
return true;
} catch (IOException ioe) {
if (ioe.getMessage() != null) {
String errMsg = ioe.getMessage();
if (NO_SPACE_CN.equals(errMsg) || NO_SPACE_EN.equals(errMsg)
|| errMsg.contains(DISK_QUATA_CN)
|| errMsg.contains(DISK_QUATA_EN)) {
logger.warn("磁盘满,自杀退出");
System.exit(0);
}
}
}
return false;
}
public static boolean deleteFile(String path, String fileName) {
File file = openFile(path, fileName);
if (file.exists()) {
return file.delete();
}
return false;
}
public static void deleteDirectory(String path) throws IOException {
FileUtils.deleteDirectory(new File(path));
}
public static void forceMkdir(String path) throws IOException {
FileUtils.forceMkdir(new File(path));
}
public static void forceMkdir(File file) throws IOException {
FileUtils.forceMkdir(file);
}
public static void deleteDirThenMkdir(String path) throws IOException {
deleteDirectory(path);
forceMkdir(path);
}
public static void copyDirectory(File srcDir, File destDir) throws IOException {
FileUtils.copyDirectory(srcDir, destDir);
}
public static void copyFile(File src, File target) throws IOException {
FileUtils.copyFile(src, target);
}
public static File openFile(String path, String fileName) {
return openFile(path, fileName, false);
}
public static File openFile(String path, String fileName, boolean rewrite) {
File directory = new File(path);
boolean mkdirs = true;
if (!directory.exists()) {
mkdirs = directory.mkdirs();
}
if (!mkdirs) {
logger.error("[DiskUtils] can't create directory");
return null;
}
File file = new File(path, fileName);
try {
boolean create = true;
if (!file.exists()) {
file.createNewFile();
}
if (file.exists()) {
if (rewrite) {
file.delete();
} else {
create = false;
}
}
if (create) {
file.createNewFile();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return file;
}
// copy from sofa-jraft
public static void compress(final String rootDir, final String sourceDir, final String outputFile,
final Checksum checksum) throws IOException {
try (final FileOutputStream fos = new FileOutputStream(outputFile);
final CheckedOutputStream cos = new CheckedOutputStream(fos, checksum);
final ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(cos))) {
compressDirectoryToZipFile(rootDir, sourceDir, zos);
zos.flush();
fos.getFD().sync();
}
}
// copy from sofa-jraft
private static void compressDirectoryToZipFile(final String rootDir, final String sourceDir,
final ZipOutputStream zos) throws IOException {
final String dir = Paths.get(rootDir, sourceDir).toString();
final File[] files = Objects.requireNonNull(new File(dir).listFiles(), "files");
for (final File file : files) {
final String child = Paths.get(sourceDir, file.getName()).toString();
if (file.isDirectory()) {
compressDirectoryToZipFile(rootDir, child, zos);
} else {
zos.putNextEntry(new ZipEntry(child));
try (final FileInputStream fis = new FileInputStream(file);
final BufferedInputStream bis = new BufferedInputStream(fis)) {
IOUtils.copy(bis, zos);
}
}
}
}
// copy from sofa-jraft
public static void decompress(final String sourceFile, final String outputDir, final Checksum checksum)
throws IOException {
try (final FileInputStream fis = new FileInputStream(sourceFile);
final CheckedInputStream cis = new CheckedInputStream(fis, checksum);
final ZipInputStream zis = new ZipInputStream(new BufferedInputStream(cis))) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
final String fileName = entry.getName();
final File entryFile = new File(Paths.get(outputDir, fileName).toString());
FileUtils.forceMkdir(entryFile.getParentFile());
try (final FileOutputStream fos = new FileOutputStream(entryFile);
final BufferedOutputStream bos = new BufferedOutputStream(fos)) {
IOUtils.copy(zis, bos);
bos.flush();
fos.getFD().sync();
}
}
// Continue to read all remaining bytes(extra metadata of ZipEntry) directly from the checked stream,
// Otherwise, the checksum value maybe unexpected.
//
// See https://coderanch.com/t/279175/java/ZipInputStream
IOUtils.copy(cis, NullOutputStream.NULL_OUTPUT_STREAM);
}
}
}

View File

@ -13,10 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.core.utils;
package com.alibaba.nacos.common.utils;
import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
/**
* Common methods for exception
@ -37,4 +40,19 @@ public class ExceptionUtil {
return strBuilder.toString();
}
public static String getStackTrace(final Throwable t) {
if (t == null) {
return "";
}
try (final ByteArrayOutputStream out = new ByteArrayOutputStream(); final PrintStream ps = new PrintStream(out)) {
t.printStackTrace(ps);
ps.flush();
return new String(out.toByteArray());
} catch (final IOException ignored) {
// ignored
}
return "";
}
}

View File

@ -23,6 +23,10 @@ public class HttpMethod {
public static final String GET = "GET";
// this is only use in nacos, Custom request type, essentially a get request
public static final String GET_LARGE = "GET-LARGE";
public static final String HEAD = "HEAD";
public static final String POST = "POST";

View File

@ -0,0 +1,58 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.lang.reflect.Type;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class JacksonUtils {
static ObjectMapper mapper = new ObjectMapper();
static {
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
public static String toJson(Object obj) throws Exception {
return mapper.writeValueAsString(obj);
}
public static byte[] toJsonBytes(Object obj) throws Exception {
return ByteUtils.toBytes(mapper.writeValueAsString(obj));
}
public static <T> T toObj(byte[] json, Class<T> cls) throws Exception {
return toObj(StringUtils.newString4UTF8(json), cls);
}
public static <T> T toObj(byte[] json, Type cls) throws Exception {
return toObj(StringUtils.newString4UTF8(json), cls);
}
public static <T> T toObj(String json, Class<T> cls) throws Exception {
return mapper.readValue(json, cls);
}
public static <T> T toObj(String json, Type type) throws Exception {
return mapper.readValue(json, mapper.constructType(type));
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import org.slf4j.Logger;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class LoggerUtils {
public static void printIfDebugEnabled(Logger logger, String s, Object... args) {
if (logger.isDebugEnabled()) {
logger.debug(s, args);
}
}
}

View File

@ -15,16 +15,18 @@
*/
package com.alibaba.nacos.common.utils;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* MD5 generator
* MD5 util
*
* @author nacos
*@author nacos
*/
public class Md5Utils {
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class MD5Utils {
private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static ThreadLocal<MessageDigest> MESSAGE_DIGEST_LOCAL = new ThreadLocal<MessageDigest>() {
@Override
@ -37,23 +39,40 @@ public class Md5Utils {
}
};
private static final int HEX_VALUE_COUNT = 16;
public static String getMD5(byte[] bytes) throws NoSuchAlgorithmException {
MessageDigest messageDigest = MESSAGE_DIGEST_LOCAL.get();
if (messageDigest != null) {
return new BigInteger(1, messageDigest.digest(bytes)).toString(HEX_VALUE_COUNT);
public static String md5Hex(byte[] bytes) throws NoSuchAlgorithmException {
try {
MessageDigest messageDigest = MESSAGE_DIGEST_LOCAL.get();
if (messageDigest != null) {
return encodeHexString(messageDigest.digest(bytes));
}
throw new NoSuchAlgorithmException("MessageDigest get MD5 instance error");
} finally {
MESSAGE_DIGEST_LOCAL.remove();
}
throw new NoSuchAlgorithmException("MessageDigest get MD5 instance error");
}
public static String getMD5(String value, String encode) {
public static String md5Hex(String value,String encode) {
try {
return getMD5(value.getBytes(encode));
return md5Hex(value.getBytes(encode));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 将一个字节数组转化为可见的字符串
*/
public static String encodeHexString(byte[] bytes) {
int l = bytes.length;
char[] out = new char[l << 1];
for (int i = 0, j = 0; i < l; i++) {
out[j++] = DIGITS_LOWER[(0xF0 & bytes[i]) >>> 4];
out[j++] = DIGITS_LOWER[0x0F & bytes[i]];
}
return new String(out);
}
}

View File

@ -0,0 +1,157 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.util.Set;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class Observable {
private transient boolean changed = false;
private transient Set<Observer> obs = new ConcurrentHashSet<>();
/**
* Adds an observer to the set of observers for this object, provided
* that it is not the same as some observer already in the set.
* The order in which notifications will be delivered to multiple
* observers is not specified. See the class comment.
*
* @param o an observer to be added.
* @throws NullPointerException if the parameter o is null.
*/
public void addObserver(Observer o) {
if (o == null) {
throw new NullPointerException();
}
obs.add(o);
}
/**
* Deletes an observer from the set of observers of this object.
* Passing {@code null} to this method will have no effect.
* @param o the observer to be deleted.
*/
public void deleteObserver(Observer o) {
obs.remove(o);
}
/**
* If this object has changed, as indicated by the
* {@code hasChanged} method, then notify all of its observers
* and then call the {@code clearChanged} method to
* indicate that this object has no longer changed.
* <p>
* Each observer has its {@code update} method called with two
* arguments: this observable object and {@code null}. In other
* words, this method is equivalent to:
* <blockquote>{@code
* notifyObservers(null)}</blockquote>
*/
public void notifyObservers() {
notifyObservers(null);
}
/**
* If this object has changed, as indicated by the
* {@code hasChanged} method, then notify all of its observers
* and then call the {@code clearChanged} method to indicate
* that this object has no longer changed.
* <p>
* Each observer has its {@code update} method called with two
* arguments: this observable object and the {@code arg} argument.
*
* @param arg any object.
*/
public void notifyObservers(Object arg) {
synchronized (this) {
/* We don't want the Observer doing callbacks into
* arbitrary code while holding its own Monitor.
* The code where we extract each Observable from
* the Vector and store the state of the Observer
* needs synchronization, but notifying observers
* does not (should not). The worst result of any
* potential race-condition here is that:
* 1) a newly-added Observer will miss a
* notification in progress
* 2) a recently unregistered Observer will be
* wrongly notified when it doesn't care
*/
if (!changed) {
return;
}
clearChanged();
}
for (Observer observer : obs) {
observer.update(this, arg);
}
}
/**
* Clears the observer list so that this object no longer has any observers.
*/
public void deleteObservers() {
obs.clear();
}
/**
* Marks this {@code Observable} object as having been changed; the
* {@code hasChanged} method will now return {@code true}.
*/
protected synchronized void setChanged() {
changed = true;
}
/**
* Indicates that this object has no longer changed, or that it has
* already notified all of its observers of its most recent change,
* so that the {@code hasChanged} method will now return {@code false}.
* This method is called automatically by the
* {@code notifyObservers} methods.
*
* @see java.util.Observable#notifyObservers()
* @see java.util.Observable#notifyObservers(java.lang.Object)
*/
protected synchronized void clearChanged() {
changed = false;
}
/**
* Tests if this object has changed.
*
* @return {@code true} if and only if the {@code setChanged}
* method has been called more recently than the
* {@code clearChanged} method on this object;
* {@code false} otherwise.
*/
public synchronized boolean hasChanged() {
return changed;
}
/**
* Returns the number of observers of this {@code Observable} object.
*
* @return the number of observers of this object.
*/
public int countObservers() {
return obs.size();
}
}

View File

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

View File

@ -15,37 +15,27 @@
*/
package com.alibaba.nacos.common.utils;
import org.apache.commons.lang3.StringUtils;
/**
* @author nacos
*/
public class Pair {
private String key;
private String value;
public class Pair<A, B> {
private final A first;
private final B second;
public Pair(String key, String value) {
this.key = key;
this.value = value;
Pair(A first, B second) {
this.first = first;
this.second = second;
}
public Pair() {
this(StringUtils.EMPTY, StringUtils.EMPTY);
public static <A, B> Pair<A, B> with(A first, B second) {
return new Pair<>(first, second);
}
public String getKey() {
return key;
public A getFirst() {
return first;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
public B getSecond() {
return second;
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ShutdownUtils {
public static void addShutdownHook(Runnable runnable) {
Runtime.getRuntime().addShutdownHook(new Thread(runnable));
}
}

View File

@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.utils;
package com.alibaba.nacos.common.utils;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Locale;
@ -25,15 +27,20 @@ import java.util.Locale;
* string util
*
* @author Nacos
* @deprecated Use {@link org.apache.commons.lang3.StringUtils} instead
*/
@Deprecated
public class StringUtils {
private static final int INDEX_NOT_FOUND = -1;
public static final String COMMA = ",";
public static final String EMPTY = "";
public static String newString4UTF8(byte[] bytes) {
return new String(bytes, Charset.forName(StandardCharsets.UTF_8.name()));
}
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
@ -67,6 +74,10 @@ public class StringUtils {
return str1 == null ? str2 == null : str1.equals(str2);
}
public static String trim(final String str) {
return str == null ? null : str.trim();
}
public static String substringBetween(String str, String open, String close) {
if (str == null || open == null || close == null) {
return null;
@ -100,6 +111,7 @@ public class StringUtils {
return stringBuilder.toString();
}
public static String escapeJavaScript(String str) {
return escapeJavaStyleString(str, true, true);
}

View File

@ -13,14 +13,40 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.config.server.utils;
package com.alibaba.nacos.common.utils;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Thread util
*
* @author Nacos
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ThreadUtil {
public final class ThreadUtils {
public static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public static void latchAwait(CountDownLatch latch) {
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public static void latchAwait(CountDownLatch latch, long time, TimeUnit unit) {
try {
latch.await(time, unit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
/**
* 通过内核数算出合适的线程数1.5-2倍cpu内核数
@ -37,4 +63,5 @@ public class ThreadUtil {
}
private final static int THREAD_MULTIPLER = 2;
}

View File

@ -0,0 +1,12 @@
package com.alibaba.nacos.common.http;
import org.junit.Test;
public class HttpUtilsTest {
@Test
public void test_url_encode() throws Exception {
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import com.alibaba.nacos.api.common.Constants;
import java.security.NoSuchAlgorithmException;
import org.junit.Assert;
import org.junit.Test;
public class MD5UtilsTest {
@Test
public void testMd5Hex() throws NoSuchAlgorithmException {
Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e",
MD5Utils.md5Hex("", Constants.ENCODE));
Assert.assertEquals("acbd18db4cc2f85cedef654fccc4a4d8",
MD5Utils.md5Hex("foo",Constants.ENCODE));
Assert.assertEquals("02f463eb799797e2a978fb1a2ae2991e",
MD5Utils.md5Hex("38c5ee9532f037a20b93d0f804cf111fca4003e451d09a692d9dea8032308d9c64eda9047fcd5e850284a49b1a0cfb2ecd45",Constants.ENCODE));
Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e",
MD5Utils.md5Hex(new byte[0]));
Assert.assertEquals("5289df737df57326fcdd22597afb1fac",
MD5Utils.md5Hex(new byte[]{1, 2, 3}));
}
@Test
public void testEncodeHexString() {
Assert.assertEquals("", MD5Utils.encodeHexString(new byte[0]));
Assert.assertEquals("010203",
MD5Utils.encodeHexString(new byte[]{1, 2, 3}));
}
}

View File

@ -17,7 +17,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.2.1</version>
<version>1.3.0-BETA</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -25,7 +25,10 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* @author Nacos
*/
@EnableScheduling
@SpringBootApplication
@SpringBootApplication(scanBasePackages = {
"com.alibaba.nacos.config.server",
"com.alibaba.nacos.core"
})
public class Config {
public static void main(String[] args) {

View File

@ -19,7 +19,7 @@ import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.constant.CounterMode;
import com.alibaba.nacos.config.server.model.ConfigInfo;
import com.alibaba.nacos.config.server.model.capacity.Capacity;
import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.config.server.service.repository.PersistService;
import com.alibaba.nacos.config.server.service.capacity.CapacityService;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import org.apache.commons.lang3.StringUtils;

View File

@ -15,7 +15,7 @@
*/
package com.alibaba.nacos.config.server.aspect;
import com.alibaba.nacos.common.utils.Md5Utils;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import com.alibaba.nacos.config.server.service.ConfigService;
@ -67,7 +67,7 @@ public class RequestLogAspect {
public Object interfacePublishSingle(ProceedingJoinPoint pjp, HttpServletRequest request,
HttpServletResponse response, String dataId, String group, String tenant,
String content) throws Throwable {
final String md5 = content == null ? null : Md5Utils.getMD5(content, Constants.ENCODE);
final String md5 = content == null ? null : MD5Utils.md5Hex(content, Constants.ENCODE);
MetricsMonitor.getPublishMonitor().incrementAndGet();
return logClientRequest("publish", pjp, request, response, dataId, group, tenant, md5);
}

View File

@ -17,9 +17,8 @@ package com.alibaba.nacos.config.server.auth;
import com.alibaba.nacos.core.auth.Resource;
import com.alibaba.nacos.core.auth.ResourceParser;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
/**
* Config resource parser
@ -48,14 +47,14 @@ public class ConfigResourceParser implements ResourceParser {
if (StringUtils.isBlank(dataId)) {
sb.append("*")
.append(Resource.SPLITTER)
.append(AUTH_CONFIG_PREFIX)
.append("*");
.append(Resource.SPLITTER)
.append(AUTH_CONFIG_PREFIX)
.append("*");
} else {
sb.append(groupName)
.append(Resource.SPLITTER)
.append(AUTH_CONFIG_PREFIX)
.append(dataId);
.append(Resource.SPLITTER)
.append(AUTH_CONFIG_PREFIX)
.append(dataId);
}
return sb.toString();

View File

@ -0,0 +1,86 @@
/*
* 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.auth;
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.service.repository.EmbeddedStoragePersistServiceImpl;
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
import com.alibaba.nacos.config.server.service.repository.DatabaseOperate;
import com.alibaba.nacos.config.server.service.sql.SqlContextUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import static com.alibaba.nacos.config.server.service.RowMapperManager.PERMISSION_ROW_MAPPER;
/**
* There is no self-augmented primary key
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@Conditional(value = ConditionOnEmbeddedStorage.class)
@Component
public class EmbeddedPermissionPersistServiceImpl implements PermissionPersistService {
@Autowired
private DatabaseOperate databaseOperate;
@Autowired
private EmbeddedStoragePersistServiceImpl persistService;
public Page<PermissionInfo> getPermissions(String role, int pageNo, int pageSize) {
PaginationHelper<PermissionInfo> helper = persistService.createPaginationHelper();
String sqlCountRows = "select count(*) from permissions where ";
String sqlFetchRows
= "select role,resource,action from permissions where ";
String where = " role='" + role + "' ";
if (StringUtils.isBlank(role)) {
where = " 1=1 ";
}
Page<PermissionInfo> pageInfo = helper.fetchPage(sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, PERMISSION_ROW_MAPPER);
if (pageInfo == null) {
pageInfo = new Page<>();
pageInfo.setTotalCount(0);
pageInfo.setPageItems(new ArrayList<>());
}
return pageInfo;
}
public void addPermission(String role, String resource, String action) {
String sql = "INSERT into permissions (role, resource, action) VALUES (?, ?, ?)";
SqlContextUtils.addSqlContext(sql, role, resource, action);
databaseOperate.smartUpdate();
}
public void deletePermission(String role, String resource, String action) {
String sql = "DELETE from permissions WHERE role=? and resource=? and action=?";
SqlContextUtils.addSqlContext(sql, role, resource, action);
databaseOperate.smartUpdate();
}
}

View File

@ -0,0 +1,123 @@
/*
* 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.auth;
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.service.repository.EmbeddedStoragePersistServiceImpl;
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
import com.alibaba.nacos.config.server.service.repository.DatabaseOperate;
import com.alibaba.nacos.config.server.service.sql.SqlContextUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import static com.alibaba.nacos.config.server.service.RowMapperManager.ROLE_INFO_ROW_MAPPER;
/**
* There is no self-augmented primary key
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@Conditional(value = ConditionOnEmbeddedStorage.class)
@Component
public class EmbeddedRolePersistServiceImpl implements RolePersistService {
@Autowired
private DatabaseOperate databaseOperate;
@Autowired
private EmbeddedStoragePersistServiceImpl persistService;
public Page<RoleInfo> getRoles(int pageNo, int pageSize) {
PaginationHelper<RoleInfo> helper = persistService.createPaginationHelper();
String sqlCountRows = "select count(*) from (select distinct role from roles) roles where ";
String sqlFetchRows
= "select role,username from roles where ";
String where = " 1=1 ";
Page<RoleInfo> pageInfo = helper.fetchPage(sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, ROLE_INFO_ROW_MAPPER);
if (pageInfo == null) {
pageInfo = new Page<>();
pageInfo.setTotalCount(0);
pageInfo.setPageItems(new ArrayList<>());
}
return pageInfo;
}
public Page<RoleInfo> getRolesByUserName(String username, int pageNo, int pageSize) {
PaginationHelper<RoleInfo> helper = persistService.createPaginationHelper();
String sqlCountRows = "select count(*) from roles where ";
String sqlFetchRows
= "select role,username from roles where ";
String where = " username='" + username + "' ";
if (StringUtils.isBlank(username)) {
where = " 1=1 ";
}
return helper.fetchPage(sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, ROLE_INFO_ROW_MAPPER);
}
public void addRole(String role, String userName) {
String sql = "INSERT into roles (role, username) VALUES (?, ?)";
try {
SqlContextUtils.addSqlContext(sql, role, userName);
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
} finally {
SqlContextUtils.cleanCurrentSqlContext();
}
}
public void deleteRole(String role) {
String sql = "DELETE from roles WHERE role=?";
try {
SqlContextUtils.addSqlContext(sql, role);
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
} finally {
SqlContextUtils.cleanCurrentSqlContext();
}
}
public void deleteRole(String role, String username) {
String sql = "DELETE from roles WHERE role=? and username=?";
try {
SqlContextUtils.addSqlContext(sql, role, username);
databaseOperate.update(SqlContextUtils.getCurrentSqlContext());
} finally {
SqlContextUtils.cleanCurrentSqlContext();
}
}
}

View File

@ -0,0 +1,107 @@
/*
* 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.auth;
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.model.User;
import com.alibaba.nacos.config.server.service.repository.EmbeddedStoragePersistServiceImpl;
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
import com.alibaba.nacos.config.server.service.repository.DatabaseOperate;
import com.alibaba.nacos.config.server.service.sql.SqlContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import static com.alibaba.nacos.config.server.service.RowMapperManager.USER_ROW_MAPPER;
/**
* There is no self-augmented primary key
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@Conditional(value = ConditionOnEmbeddedStorage.class)
@Component
public class EmbeddedUserPersistServiceImpl implements UserPersistService {
@Autowired
private DatabaseOperate databaseOperate;
@Autowired
private EmbeddedStoragePersistServiceImpl persistService;
public void createUser(String username, String password) {
String sql = "INSERT into users (username, password, enabled) VALUES (?, ?, ?)";
try {
SqlContextUtils.addSqlContext(sql, username, password, true);
databaseOperate.smartUpdate();
} finally {
SqlContextUtils.cleanCurrentSqlContext();
}
}
public void deleteUser(String username) {
String sql = "DELETE from users WHERE username=?";
try {
SqlContextUtils.addSqlContext(sql, username);
databaseOperate.smartUpdate();
} finally {
SqlContextUtils.cleanCurrentSqlContext();
}
}
public void updateUserPassword(String username, String password) {
try {
SqlContextUtils.addSqlContext(
"UPDATE users SET password = ? WHERE username=?",
password, username);
databaseOperate.smartUpdate();
} finally {
SqlContextUtils.cleanCurrentSqlContext();
}
}
public User findUserByUsername(String username) {
String sql = "SELECT username,password FROM users WHERE username=? ";
return databaseOperate.queryOne(sql, new Object[]{username}, USER_ROW_MAPPER);
}
public Page<User> getUsers(int pageNo, int pageSize) {
PaginationHelper<User> helper = persistService.createPaginationHelper();
String sqlCountRows = "select count(*) from users where ";
String sqlFetchRows
= "select username,password from users where ";
String where = " 1=1 ";
Page<User> pageInfo = helper.fetchPage(sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, USER_ROW_MAPPER);
if (pageInfo == null) {
pageInfo = new Page<>();
pageInfo.setTotalCount(0);
pageInfo.setPageItems(new ArrayList<>());
}
return pageInfo;
}
}

View File

@ -0,0 +1,110 @@
/*
* 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.auth;
import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage;
import com.alibaba.nacos.config.server.configuration.ConditionOnExternalStorage;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.service.repository.ExternalStoragePersistServiceImpl;
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
import com.alibaba.nacos.config.server.utils.LogUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Conditional;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import static com.alibaba.nacos.config.server.service.RowMapperManager.PERMISSION_ROW_MAPPER;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@Conditional(value = ConditionOnExternalStorage.class)
@Component
public class ExternalPermissionPersistServiceImpl implements PermissionPersistService {
@Autowired
private ExternalStoragePersistServiceImpl persistService;
private JdbcTemplate jt;
@PostConstruct
protected void init() {
jt = persistService.getJdbcTemplate();
}
public Page<PermissionInfo> getPermissions(String role, int pageNo, int pageSize) {
PaginationHelper<PermissionInfo> helper = persistService.createPaginationHelper();
String sqlCountRows = "select count(*) from permissions where ";
String sqlFetchRows
= "select role,resource,action from permissions where ";
String where = " role='" + role + "' ";
if (StringUtils.isBlank(role)) {
where = " 1=1 ";
}
try {
Page<PermissionInfo> pageInfo = helper.fetchPage(sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, PERMISSION_ROW_MAPPER);
if (pageInfo==null) {
pageInfo = new Page<>();
pageInfo.setTotalCount(0);
pageInfo.setPageItems(new ArrayList<>());
}
return pageInfo;
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void addPermission(String role, String resource, String action) {
String sql = "INSERT into permissions (role, resource, action) VALUES (?, ?, ?)";
try {
jt.update(sql, role, resource, action);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void deletePermission(String role, String resource, String action) {
String sql = "DELETE from permissions WHERE role=? and resource=? and action=?";
try {
jt.update(sql, role, resource, action);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
}

View File

@ -0,0 +1,151 @@
/*
* 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.auth;
import com.alibaba.nacos.config.server.configuration.ConditionOnExternalStorage;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.service.repository.ExternalStoragePersistServiceImpl;
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
import com.alibaba.nacos.config.server.utils.LogUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Conditional;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import static com.alibaba.nacos.config.server.service.RowMapperManager.ROLE_INFO_ROW_MAPPER;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@Conditional(value = ConditionOnExternalStorage.class)
@Component
public class ExternalRolePersistServiceImpl implements RolePersistService {
@Autowired
private ExternalStoragePersistServiceImpl persistService;
private JdbcTemplate jt;
@PostConstruct
protected void init() {
jt = persistService.getJdbcTemplate();
}
public Page<RoleInfo> getRoles(int pageNo, int pageSize) {
PaginationHelper<RoleInfo> helper = persistService.createPaginationHelper();
String sqlCountRows = "select count(*) from (select distinct role from roles) roles where ";
String sqlFetchRows
= "select role,username from roles where ";
String where = " 1=1 ";
try {
Page<RoleInfo> pageInfo = helper.fetchPage(sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, ROLE_INFO_ROW_MAPPER);
if (pageInfo == null) {
pageInfo = new Page<>();
pageInfo.setTotalCount(0);
pageInfo.setPageItems(new ArrayList<>());
}
return pageInfo;
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public Page<RoleInfo> getRolesByUserName(String username, int pageNo, int pageSize) {
PaginationHelper<RoleInfo> helper = persistService.createPaginationHelper();
String sqlCountRows = "select count(*) from roles where ";
String sqlFetchRows
= "select role,username from roles where ";
String where = " username='" + username + "' ";
if (StringUtils.isBlank(username)) {
where = " 1=1 ";
}
try {
return helper.fetchPage(sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, ROLE_INFO_ROW_MAPPER);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void addRole(String role, String userName) {
String sql = "INSERT into roles (role, username) VALUES (?, ?)";
try {
jt.update(sql, role, userName);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void deleteRole(String role) {
String sql = "DELETE from roles WHERE role=?";
try {
jt.update(sql, role);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void deleteRole(String role, String username) {
String sql = "DELETE from roles WHERE role=? and username=?";
try {
jt.update(sql, role, username);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
private static final class RoleInfoRowMapper implements RowMapper<RoleInfo> {
@Override
public RoleInfo mapRow(ResultSet rs, int rowNum)
throws SQLException {
RoleInfo roleInfo = new RoleInfo();
roleInfo.setRole(rs.getString("role"));
roleInfo.setUsername(rs.getString("username"));
return roleInfo;
}
}
}

View File

@ -0,0 +1,129 @@
/*
* 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.auth;
import com.alibaba.nacos.config.server.configuration.ConditionOnExternalStorage;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.model.User;
import com.alibaba.nacos.config.server.service.repository.ExternalStoragePersistServiceImpl;
import com.alibaba.nacos.config.server.service.repository.PaginationHelper;
import com.alibaba.nacos.config.server.utils.LogUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Conditional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import static com.alibaba.nacos.config.server.service.RowMapperManager.USER_ROW_MAPPER;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@Conditional(value = ConditionOnExternalStorage.class)
@Component
public class ExternalUserPersistServiceImpl implements UserPersistService {
@Autowired
private ExternalStoragePersistServiceImpl persistService;
private JdbcTemplate jt;
@PostConstruct
protected void init() {
jt = persistService.getJdbcTemplate();
}
public void createUser(String username, String password) {
String sql = "INSERT into users (username, password, enabled) VALUES (?, ?, ?)";
try {
jt.update(sql, username, password, true);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void deleteUser(String username) {
String sql = "DELETE from users WHERE username=?";
try {
jt.update(sql, username);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void updateUserPassword(String username, String password) {
try {
jt.update(
"UPDATE users SET password = ? WHERE username=?",
password, username);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public User findUserByUsername(String username) {
String sql = "SELECT username,password FROM users WHERE username=? ";
try {
return this.jt.queryForObject(sql, new Object[]{username}, USER_ROW_MAPPER);
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
} catch (EmptyResultDataAccessException e) {
return null;
} catch (Exception e) {
LogUtil.fatalLog.error("[db-other-error]" + e.getMessage(), e);
throw new RuntimeException(e);
}
}
public Page<User> getUsers(int pageNo, int pageSize) {
PaginationHelper<User> helper = persistService.createPaginationHelper();
String sqlCountRows = "select count(*) from users where ";
String sqlFetchRows
= "select username,password from users where ";
String where = " 1=1 ";
try {
Page<User> pageInfo = helper.fetchPage(sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, USER_ROW_MAPPER);
if (pageInfo == null) {
pageInfo = new Page<>();
pageInfo.setTotalCount(0);
pageInfo.setPageItems(new ArrayList<>());
}
return pageInfo;
} catch (CannotGetJdbcConnectionException e) {
LogUtil.fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
}

View File

@ -15,12 +15,15 @@
*/
package com.alibaba.nacos.config.server.auth;
import java.io.Serializable;
/**
* @author nkorange
* @since 1.2.0
*/
public class PermissionInfo {
public class PermissionInfo implements Serializable {
private static final long serialVersionUID = 388813573388837395L;
/**
* Role name
*/

View File

@ -15,20 +15,7 @@
*/
package com.alibaba.nacos.config.server.auth;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.config.server.utils.PaginationHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
/**
* Permission CRUD service
@ -36,76 +23,13 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
* @author nkorange
* @since 1.2.0
*/
@Service
public class PermissionPersistService extends PersistService {
@SuppressWarnings("PMD.AbstractMethodOrInterfaceMethodMustUseJavadocRule")
public interface PermissionPersistService {
public Page<PermissionInfo> getPermissions(String role, int pageNo, int pageSize) {
PaginationHelper<PermissionInfo> helper = new PaginationHelper<>();
Page<PermissionInfo> getPermissions(String role, int pageNo, int pageSize);
String sqlCountRows = "select count(*) from permissions where ";
String sqlFetchRows
= "select role,resource,action from permissions where ";
void addPermission(String role, String resource, String action);
String where = " role='" + role + "' ";
void deletePermission(String role, String resource, String action);
if (StringUtils.isBlank(role)) {
where = " 1=1 ";
}
try {
Page<PermissionInfo> pageInfo = helper.fetchPage(jt, sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, PERMISSION_ROW_MAPPER);
if (pageInfo==null) {
pageInfo = new Page<>();
pageInfo.setTotalCount(0);
pageInfo.setPageItems(new ArrayList<>());
}
return pageInfo;
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void addPermission(String role, String resource, String action) {
String sql = "INSERT into permissions (role, resource, action) VALUES (?, ?, ?)";
try {
jt.update(sql, role, resource, action);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void deletePermission(String role, String resource, String action) {
String sql = "DELETE from permissions WHERE role=? and resource=? and action=?";
try {
jt.update(sql, role, resource, action);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
private static final class PermissionRowMapper implements
RowMapper<PermissionInfo> {
@Override
public PermissionInfo mapRow(ResultSet rs, int rowNum)
throws SQLException {
PermissionInfo info = new PermissionInfo();
info.setResource(rs.getString("resource"));
info.setAction(rs.getString("action"));
info.setRole(rs.getString("role"));
return info;
}
}
private static final PermissionRowMapper PERMISSION_ROW_MAPPER = new PermissionRowMapper();
}

View File

@ -15,13 +15,17 @@
*/
package com.alibaba.nacos.config.server.auth;
import java.io.Serializable;
/**
* Role Info
*
* @author nkorange
* @since 1.2.0
*/
public class RoleInfo {
public class RoleInfo implements Serializable {
private static final long serialVersionUID = 5946986388047856568L;
private String role;
@ -42,4 +46,12 @@ public class RoleInfo {
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "RoleInfo{" +
"role='" + role + '\'' +
", username='" + username + '\'' +
'}';
}
}

View File

@ -16,20 +16,6 @@
package com.alibaba.nacos.config.server.auth;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.model.User;
import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.config.server.utils.PaginationHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
/**
* Role CRUD service
@ -37,103 +23,17 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
* @author nkorange
* @since 1.2.0
*/
@Service
public class RolePersistService extends PersistService {
@SuppressWarnings("PMD.AbstractMethodOrInterfaceMethodMustUseJavadocRule")
public interface RolePersistService {
Page<RoleInfo> getRoles(int pageNo, int pageSize);
public Page<RoleInfo> getRoles(int pageNo, int pageSize) {
Page<RoleInfo> getRolesByUserName(String username, int pageNo, int pageSize);
PaginationHelper<RoleInfo> helper = new PaginationHelper<>();
void addRole(String role, String userName);
String sqlCountRows = "select count(*) from (select distinct role from roles) roles where ";
String sqlFetchRows
= "select role,username from roles where ";
void deleteRole(String role);
String where = " 1=1 ";
void deleteRole(String role, String username);
try {
Page<RoleInfo> pageInfo = helper.fetchPage(jt, sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, ROLE_INFO_ROW_MAPPER);
if (pageInfo == null) {
pageInfo = new Page<>();
pageInfo.setTotalCount(0);
pageInfo.setPageItems(new ArrayList<>());
}
return pageInfo;
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public Page<RoleInfo> getRolesByUserName(String username, int pageNo, int pageSize) {
PaginationHelper<RoleInfo> helper = new PaginationHelper<>();
String sqlCountRows = "select count(*) from roles where ";
String sqlFetchRows
= "select role,username from roles where ";
String where = " username='" + username + "' ";
if (StringUtils.isBlank(username)) {
where = " 1=1 ";
}
try {
return helper.fetchPage(jt, sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, ROLE_INFO_ROW_MAPPER);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void addRole(String role, String userName) {
String sql = "INSERT into roles (role, username) VALUES (?, ?)";
try {
jt.update(sql, role, userName);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void deleteRole(String role) {
String sql = "DELETE from roles WHERE role=?";
try {
jt.update(sql, role);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
public void deleteRole(String role, String username) {
String sql = "DELETE from roles WHERE role=? and username=?";
try {
jt.update(sql, role, username);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
private static final class RoleInfoRowMapper implements
RowMapper<RoleInfo> {
@Override
public RoleInfo mapRow(ResultSet rs, int rowNum)
throws SQLException {
RoleInfo roleInfo = new RoleInfo();
roleInfo.setRole(rs.getString("role"));
roleInfo.setUsername(rs.getString("username"));
return roleInfo;
}
}
private static final RoleInfoRowMapper ROLE_INFO_ROW_MAPPER = new RoleInfoRowMapper();
}

View File

@ -17,19 +17,6 @@ package com.alibaba.nacos.config.server.auth;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.model.User;
import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.config.server.utils.PaginationHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
/**
* User CRUD service
@ -37,94 +24,17 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
* @author nkorange
* @since 1.2.0
*/
@Service
public class UserPersistService extends PersistService {
@SuppressWarnings("PMD.AbstractMethodOrInterfaceMethodMustUseJavadocRule")
public interface UserPersistService {
public void createUser(String username, String password) {
String sql = "INSERT into users (username, password, enabled) VALUES (?, ?, ?)";
void createUser(String username, String password);
try {
jt.update(sql, username, password, true);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
void deleteUser(String username);
public void deleteUser(String username) {
String sql = "DELETE from users WHERE username=?";
try {
jt.update(sql, username);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
void updateUserPassword(String username, String password);
public void updateUserPassword(String username, String password) {
try {
jt.update(
"UPDATE users SET password = ? WHERE username=?",
password, username);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
User findUserByUsername(String username);
public User findUserByUsername(String username) {
String sql = "SELECT username,password FROM users WHERE username=? ";
try {
return this.jt.queryForObject(sql, new Object[]{username}, USER_ROW_MAPPER);
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
} catch (EmptyResultDataAccessException e) {
return null;
} catch (Exception e) {
fatalLog.error("[db-other-error]" + e.getMessage(), e);
throw new RuntimeException(e);
}
}
public Page<User> getUsers(int pageNo, int pageSize) {
PaginationHelper<User> helper = new PaginationHelper<>();
String sqlCountRows = "select count(*) from users where ";
String sqlFetchRows
= "select username,password from users where ";
String where = " 1=1 ";
try {
Page<User> pageInfo = helper.fetchPage(jt, sqlCountRows
+ where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
pageSize, USER_ROW_MAPPER);
if (pageInfo == null) {
pageInfo = new Page<>();
pageInfo.setTotalCount(0);
pageInfo.setPageItems(new ArrayList<>());
}
return pageInfo;
} catch (CannotGetJdbcConnectionException e) {
fatalLog.error("[db-error] " + e.toString(), e);
throw e;
}
}
private static final class UserRowMapper implements
RowMapper<User> {
@Override
public User mapRow(ResultSet rs, int rowNum)
throws SQLException {
User info = new User();
info.setUsername(rs.getString("username"));
info.setPassword(rs.getString("password"));
return info;
}
}
private static final UserRowMapper USER_ROW_MAPPER = new UserRowMapper();
Page<User> getUsers(int pageNo, int pageSize);
}

View File

@ -1,198 +0,0 @@
///*
// * Licensed to the Apache Software Foundation (ASF) under one or more
// * contributor license agreements. See the NOTICE file distributed with
// * this work for additional information regarding copyright ownership.
// * The ASF licenses this file to You 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.configuration;
//
//import com.alibaba.nacos.config.server.service.BasicDataSourceServiceImpl;
//import com.alibaba.nacos.config.server.service.TimerTaskService;
//import com.alibaba.nacos.config.server.utils.PropertyUtil;
//import org.apache.commons.dbcp.BasicDataSource;
//import org.apache.commons.lang.math.NumberUtils;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Profile;
//import org.springframework.jdbc.core.JdbcTemplate;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//import org.springframework.transaction.support.TransactionTemplate;
//
//import javax.annotation.PostConstruct;
//import javax.sql.DataSource;
//import java.io.IOException;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.concurrent.TimeUnit;
//import java.util.regex.Pattern;
//
//import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
//
///**
// * Cluster {@link DataSource} {@link Configuration}
// *
// * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
// * @since 0.2.2
// */
//@Profile("!standalone")
//@Configuration
//public class ClusterDataSourceConfiguration {
//
// private static final String JDBC_DRIVER_NAME = "com.mysql.jdbc.Driver";
//
// /**
// * JDBC执行超时时间, 单位秒
// */
// private int queryTimeout = 3;
//
// private static final int TRANSACTION_QUERY_TIMEOUT = 5;
//
// private static final String DB_LOAD_ERROR_MSG = "[db-load-error]load jdbc.properties error";
//
// private List<BasicDataSource> dataSourceList = new ArrayList<BasicDataSource>();
// private JdbcTemplate jt;
// private DataSourceTransactionManager tm;
// private TransactionTemplate tjt;
//
// private JdbcTemplate testMasterJT;
// private JdbcTemplate testMasterWritableJT;
//
// volatile private List<JdbcTemplate> testJTList;
// volatile private List<Boolean> isHealthList;
// private volatile int masterIndex;
// private static Pattern ipPattern = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
//
//
//
// @PostConstruct
// public void init() {
// queryTimeout = NumberUtils
// .toInt(System.getProperty("QUERYTIMEOUT"), 3);
// jt = new JdbcTemplate();
// /**
// * 设置最大记录数防止内存膨胀
// */
// jt.setMaxRows(50000);
// jt.setQueryTimeout(queryTimeout);
//
// testMasterJT = new JdbcTemplate();
// testMasterJT.setQueryTimeout(queryTimeout);
//
// testMasterWritableJT = new JdbcTemplate();
// /**
// * 防止login接口因为主库不可用而rt太长
// */
// testMasterWritableJT.setQueryTimeout(1);
// /**
// * 数据库健康检测
// */
// testJTList = new ArrayList<JdbcTemplate>();
// isHealthList = new ArrayList<Boolean>();
//
// tm = new DataSourceTransactionManager();
// tjt = new TransactionTemplate(tm);
// /**
// * 事务的超时时间需要与普通操作区分开
// */
// tjt.setTimeout(TRANSACTION_QUERY_TIMEOUT);
// if (!STANDALONE_MODE) {
// try {
// reload();
// } catch (IOException e) {
// e.printStackTrace();
// throw new RuntimeException(DB_LOAD_ERROR_MSG);
// }
//
// TimerTaskService.scheduleWithFixedDelay(new BasicDataSourceServiceImpl.SelectMasterTask(), 10, 10,
// TimeUnit.SECONDS);
// TimerTaskService.scheduleWithFixedDelay(new BasicDataSourceServiceImpl.CheckDBHealthTask(), 10, 10,
// TimeUnit.SECONDS);
// }
// }
//
// public synchronized void reload() throws IOException {
// List<BasicDataSource> dblist = new ArrayList<BasicDataSource>();
// try {
// String val = null;
// val = env.getProperty("db.num");
// if (null == val) {
// throw new IllegalArgumentException("db.num is null");
// }
// int dbNum = Integer.parseInt(val.trim());
//
// for (int i = 0; i < dbNum; i++) {
// BasicDataSource ds = new BasicDataSource();
// ds.setDriverClassName(JDBC_DRIVER_NAME);
//
// val = env.getProperty("db.url." + i);
// if (null == val) {
// fatalLog.error("db.url." + i + " is null");
// throw new IllegalArgumentException();
// }
// ds.setUrl(val.trim());
//
// val = env.getProperty("db.user");
// if (null == val) {
// fatalLog.error("db.user is null");
// throw new IllegalArgumentException();
// }
// ds.setUsername(val.trim());
//
// val = env.getProperty("db.password");
// if (null == val) {
// fatalLog.error("db.password is null");
// throw new IllegalArgumentException();
// }
// ds.setPassword(val.trim());
//
// val = env.getProperty("db.initialSize");
// ds.setInitialSize(Integer.parseInt(defaultIfNull(val, "10")));
//
// val = env.getProperty("db.maxActive");
// ds.setMaxActive(Integer.parseInt(defaultIfNull(val, "20")));
//
// val = env.getProperty("db.maxIdle");
// ds.setMaxIdle(Integer.parseInt(defaultIfNull(val, "50")));
//
// ds.setMaxWait(3000L);
// ds.setPoolPreparedStatements(true);
//
// // 每10分钟检查一遍连接池
// ds.setTimeBetweenEvictionRunsMillis(TimeUnit.MINUTES
// .toMillis(10L));
// ds.setTestWhileIdle(true);
// ds.setValidationQuery("SELECT 1 FROM dual");
//
// dblist.add(ds);
//
// JdbcTemplate jdbcTemplate = new JdbcTemplate();
// jdbcTemplate.setQueryTimeout(queryTimeout);
// jdbcTemplate.setDataSource(ds);
//
// testJTList.add(jdbcTemplate);
// isHealthList.add(Boolean.TRUE);
// }
//
// if (dblist == null || dblist.size() == 0) {
// throw new RuntimeException("no datasource available");
// }
//
// dataSourceList = dblist;
// new BasicDataSourceServiceImpl.SelectMasterTask().run();
// new BasicDataSourceServiceImpl.CheckDBHealthTask().run();
// } catch (RuntimeException e) {
// fatalLog.error(DB_LOAD_ERROR_MSG, e);
// throw new IOException(e);
// } finally {
// }
// }
//}

View File

@ -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.configuration;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import com.alibaba.nacos.core.utils.ApplicationUtils;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* when embeddedStorage==true and nacos.standalone=false
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ConditionDistributedEmbedStorage implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return PropertyUtil.isEmbeddedStorage() && !ApplicationUtils.getStandaloneMode();
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.config.server.configuration;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ConditionOnEmbeddedStorage implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return PropertyUtil.isEmbeddedStorage();
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.configuration;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ConditionOnExternalStorage implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return !PropertyUtil.isEmbeddedStorage();
}
}

View File

@ -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.configuration;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import com.alibaba.nacos.core.utils.ApplicationUtils;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* when embeddedStorage==false
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ConditionStandaloneEmbedStorage implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return PropertyUtil.isEmbeddedStorage() && ApplicationUtils.getStandaloneMode();
}
}

View File

@ -1,63 +0,0 @@
///*
// * Licensed to the Apache Software Foundation (ASF) under one or more
// * contributor license agreements. See the NOTICE file distributed with
// * this work for additional information regarding copyright ownership.
// * The ASF licenses this file to You 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.configuration;
//
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.core.env.Environment;
//import org.springframework.jdbc.core.JdbcTemplate;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//import org.springframework.transaction.PlatformTransactionManager;
//
//import javax.sql.DataSource;
//
///**
// * DataBase {@link Configuration}
// *
// * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
// * @since 0.2.2
// */
//@Configuration
//public class DataBaseConfiguration {
//
// /**
// * The bean name of {@link DataSource} for Nacos Config
// */
// public static final String DATA_SOURCE_BEAN_NAME = "nacosConfigDataSource";
//
// @Bean
// @Autowired
// public JdbcTemplate jdbcTemplate(@Qualifier(DATA_SOURCE_BEAN_NAME) DataSource dataSource, Environment environment) {
// JdbcTemplate jdbcTemplate = new JdbcTemplate();
// jdbcTemplate = new JdbcTemplate();
// jdbcTemplate.setMaxRows(50000);
// jdbcTemplate.setQueryTimeout(5000);
// jdbcTemplate.setDataSource(dataSource);
// return jdbcTemplate;
// }
//
// @Bean
// @Autowired
// public PlatformTransactionManager transactionManager(@Qualifier(DATA_SOURCE_BEAN_NAME) DataSource dataSource) {
// DataSourceTransactionManager manager = new DataSourceTransactionManager();
// manager.setDataSource(dataSource);
// return manager;
// }
//
//}

Some files were not shown because too many files have changed in this diff Show More