Merge pull request #1 from alibaba/develop

sync code
This commit is contained in:
Brian Huang 2020-06-07 18:47:55 +08:00 committed by GitHub
commit 6709b0686d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
660 changed files with 49838 additions and 17116 deletions

3
.gitignore vendored
View File

@ -12,3 +12,6 @@ target
node_modules
test/derby.log
derby.log
work
test/logs
derby.log

View File

@ -1,8 +1,6 @@
notifications:
email:
recipients:
- xchaos8@126.com
- nacos_dev@linux.alibaba.com
- dev-nacos@googlegroups.com
- mw_configcenter@list.alibaba-inc.com
on_success: change
@ -30,7 +28,7 @@ before_install:
script:
- mvn -B clean package apache-rat:check findbugs:findbugs -Dmaven.test.skip=true
- mvn -Prelease-nacos clean install -U
- mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
- mvn clean package -Pit-test
after_success:
- mvn clean package -Pit-test

View File

@ -35,4 +35,4 @@ Build Instructions for NACOS
Execute the following command in order to build the tar.gz packages and install JAR into local repository:
#build nacos
$ mvn -Prelease-nacos -DskipTests clean install -U
$ mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U

View File

@ -90,7 +90,7 @@ Some principles:
- Testability - 80% of the new code should be covered by unit test cases.
- Maintainability - Comply with our [PMD spec](style/codeStyle.xml), and 3-month-frequency update should be maintained at least.
- Maintainability - Comply with our [PMD spec](style/codeStyle.md), and 3-month-frequency update should be maintained at least.
### Now how about try become a committer?

View File

@ -97,9 +97,14 @@ Contributors are welcomed to join Nacos project. Please check [CONTRIBUTING](./C
* users-nacos@googlegroups.com: Nacos usage general discussion.
* dev-nacos@googlegroups.com: Nacos developer discussion (APIs, feature design, etc).
* commits-nacos@googlegroups.com: Commits notice, very high frequency.
* Join us from DingDing.
* Join us from DingDing(Group 1: 21708933(full), Group 2: 30438813).
![cwex](https://img.alicdn.com/tfs/TB1bpBlQmrqK1RjSZK9XXXyypXa-830-972.png_288x480q80.jpg)
![Nacos](https://img.alicdn.com/tfs/TB1TBKEzpP7gK0jSZFjXXc5aXXa-199-220.png)
## Download
- [Github Release](https://github.com/alibaba/nacos/releases)
- [Baidu Netdisk](https://pan.baidu.com/s/1186nmlqPGows9gUZKAx8Zw) Fetch Code : `rest`
## Who is using
@ -163,7 +168,6 @@ These are only part of the companies using Nacos, for reference only. If you are
![时代光华](https://img.alicdn.com/tfs/TB1UzuyNhTpK1RjSZR0XXbEwXXa-201-86.jpg)
![康美](https://img.alicdn.com/tfs/TB19RCANgHqK1RjSZFPXXcwapXa-180-180.jpg)
![环球易购](https://img.alicdn.com/tfs/TB1iCGyNb2pK1RjSZFsXXaNlXXa-143-143.jpg)
![海格管家](https://img.alicdn.com/tfs/TB1FNq4EwHqK1RjSZFgXXa7JXXa-232-232.jpg)
![Nepxion](https://avatars0.githubusercontent.com/u/16344119?s=200&v=4)
![东莞最佳拍档](https://img.alicdn.com/tfs/TB11ugsDzTpK1RjSZKPXXa3UpXa-300-300.png)
![chigua](https://img.alicdn.com/tfs/TB1aUe5EpzqK1RjSZSgXXcpAVXa-248-124.png)

View File

@ -16,7 +16,7 @@
<parent>
<artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId>
<version>1.2.0-SNAPSHOT</version>
<version>1.3.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -24,7 +24,7 @@
<packaging>jar</packaging>
<name>nacos-address ${project.version}</name>
<url>http://maven.apache.org</url>
<url>http://nacos.io</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -48,7 +48,7 @@
<artifactId>nacos-naming</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-cmdb</artifactId>
</exclusion>
</exclusions>
@ -56,13 +56,11 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -80,7 +78,6 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.4</version>
</plugin>
</plugins>
</reporting>

View File

@ -65,7 +65,7 @@ public class AddressServerGeneratorManager {
String[] ipAndPort = generateIpAndPort(ip);
Instance instance = new Instance();
instance.setIp(ipAndPort[0]);
instance.setPort(Integer.valueOf(ipAndPort[1]));
instance.setPort(Integer.parseInt(ipAndPort[1]));
instance.setClusterName(clusterName);
instance.setServiceName(serviceName);
instance.setTenant(Constants.DEFAULT_NAMESPACE_ID);

View File

@ -21,7 +21,7 @@ import com.alibaba.nacos.address.constant.AddressServerConstants;
import com.alibaba.nacos.address.misc.Loggers;
import com.alibaba.nacos.address.util.AddressServerParamCheckUtil;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
import com.alibaba.nacos.naming.core.Cluster;
import com.alibaba.nacos.naming.core.Instance;
import com.alibaba.nacos.naming.core.Service;

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.2.0-SNAPSHOT</version>
<version>1.3.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -25,7 +25,7 @@
<packaging>jar</packaging>
<name>nacos-api ${project.version}</name>
<url>http://maven.apache.org</url>
<url>http://nacos.io</url>
<build>
<plugins>
<plugin>
@ -45,8 +45,12 @@
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>

View File

@ -32,6 +32,10 @@ public class PropertyKeyConst {
public final static String NAMESPACE = "namespace";
public final static String USERNAME = "username";
public final static String PASSWORD = "password";
public final static String ACCESS_KEY = "accessKey";
public final static String SECRET_KEY = "secretKey";

View File

@ -96,6 +96,17 @@ public @interface NacosProperties {
*/
String ENABLE_REMOTE_SYNC_CONFIG = "enableRemoteSyncConfig";
/**
* The property name of "username"
*/
String USERNAME = "username";
/**
* The property name of "password"
*/
String PASSWORD = "password";
/**
* The placeholder of endpoint, the value is <code>"${nacos.endpoint:}"</code>
*/
@ -156,6 +167,16 @@ public @interface NacosProperties {
*/
String ENABLE_REMOTE_SYNC_CONFIG_PLACEHOLDER = "${" + PREFIX + ENABLE_REMOTE_SYNC_CONFIG + ":}";
/**
* The placeholder of endpoint, the value is <code>"${nacos.username:}"</code>
*/
String USERNAME_PLACEHOLDER = "${" + PREFIX + USERNAME + ":}";
/**
* The placeholder of endpoint, the value is <code>"${nacos.password:}"</code>
*/
String PASSWORD_PLACEHOLDER = "${" + PREFIX + PASSWORD + ":}";
/**
* The property of "endpoint"
*
@ -252,4 +273,20 @@ public @interface NacosProperties {
*/
String enableRemoteSyncConfig() default ENABLE_REMOTE_SYNC_CONFIG_PLACEHOLDER;
/**
* The property of "username"
*
* @return empty as default value
* @see #USERNAME_PLACEHOLDER
*/
String username() default USERNAME_PLACEHOLDER;
/**
* The property of "password"
*
* @return empty as default value
* @see #PASSWORD_PLACEHOLDER
*/
String password() default PASSWORD_PLACEHOLDER;
}

View File

@ -62,6 +62,8 @@ public class Constants {
public static final String CONFIG_VERSION = "Config-Version";
public static final String CONFIG_TYPE = "Config-Type";
public static final String IF_MODIFIED_SINCE = "If-Modified-Since";
public static final String SPACING_INTERVAL = "client-spacing-interval";
@ -70,6 +72,16 @@ public class Constants {
public static final String CONFIG_CONTROLLER_PATH = BASE_PATH + "/configs";
public static final String TOKEN = "token";
public static final String ACCESS_TOKEN = "accessToken";
public static final String TOKEN_TTL = "tokenTtl";
public static final String GLOBAL_ADMIN = "globalAdmin";
public static final String TOKEN_REFRESH_WINDOW = "tokenRefreshWindow";
/**
* second
*/
@ -169,4 +181,6 @@ public class Constants {
public static final String SNOWFLAKE_INSTANCE_ID_GENERATOR = "snowflake";
public static final String HTTP_PREFIX = "http";
}

View File

@ -0,0 +1,37 @@
/*
* 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.api.common;
/**
* Response code definitions.
* <p>
* This class and inherited classes define codes separated from HTTP code to provide richer and preciser
* information of the API results. A recommended rule for defining response code is:
* <li> Global and common code starts with 10001.
* <li> Naming module code starts with 20001.
* <li> Config module code starts with 30001.
*
* @author nkorange
* @since 1.2.0
*/
public class ResponseCode {
/**
* Everything normal
*/
public static final int OK = 10200;
}

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.api.config;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import java.util.Collection;
import java.util.Map;
/**
* ConfigChangeEvent
*
* @author rushsky518
*/
public class ConfigChangeEvent {
private Map<String, ConfigChangeItem> data;
public ConfigChangeEvent(Map<String, ConfigChangeItem> data) {
this.data = data;
}
public ConfigChangeItem getChangeItem(String key) {
return data.get(key);
}
public Collection<ConfigChangeItem> getChangeItems() {
return data.values();
}
}

View File

@ -0,0 +1,77 @@
/*
* 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.api.config;
/**
* ConfigChangeItem
*
* @author rushsky518
*/
public class ConfigChangeItem {
private String key;
private String oldValue;
private String newValue;
private PropertyChangeType type;
public ConfigChangeItem(String key, String oldValue, String newValue) {
this.key = key;
this.oldValue = oldValue;
this.newValue = newValue;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getOldValue() {
return oldValue;
}
public void setOldValue(String oldValue) {
this.oldValue = oldValue;
}
public String getNewValue() {
return newValue;
}
public void setNewValue(String newValue) {
this.newValue = newValue;
}
public PropertyChangeType getType() {
return type;
}
public void setType(PropertyChangeType type) {
this.type = type;
}
@Override
public String toString() {
return "ConfigChangeItem{" +
"key='" + key + '\'' +
", oldValue='" + oldValue + '\'' +
", newValue='" + newValue + '\'' +
", type=" + type +
'}';
}
}

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.api.config;
/**
* Property Change Type
*
* @author rushsky518
*/
public enum PropertyChangeType {
/** add */
ADDED,
/** modified */
MODIFIED,
/** deleted */
DELETED
}

View File

@ -0,0 +1,45 @@
/*
* 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.api.config.listener;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import java.io.IOException;
import java.util.Map;
/**
* ConfigChangeParser
*
* @author rushsky518
*/
public interface ConfigChangeParser {
/**
* judge type
* @param type
* @return
*/
boolean isResponsibleFor(String type);
/**
* compare old and new data
* @param oldContent
* @param newContent
* @param type
* @return
* @throws IOException
*/
Map<String, ConfigChangeItem> doParse(String oldContent, String newContent, String type) throws IOException;
}

View File

@ -25,123 +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;
}

View File

@ -0,0 +1,57 @@
/*
* 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.api.exception.runtime;
/**
* Nacos deserialization exception.
*
* @author yangyi
*/
public class NacosDeserializationException extends NacosRuntimeException {
public static final int ERROR_CODE = 101;
private static final long serialVersionUID = -2742350751684273728L;
private static final String DEFAULT_MSG = "Nacos deserialize failed. ";
private static final String MSG_FOR_SPECIFIED_CLASS = "Nacos deserialize for class [%s] failed. ";
private Class<?> targetClass;
public NacosDeserializationException() {
super(ERROR_CODE);
}
public NacosDeserializationException(Class<?> targetClass) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetClass.getName()));
this.targetClass = targetClass;
}
public NacosDeserializationException(Throwable throwable) {
super(ERROR_CODE, DEFAULT_MSG, throwable);
}
public NacosDeserializationException(Class<?> targetClass, Throwable throwable) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetClass.getName()), throwable);
this.targetClass = targetClass;
}
public Class<?> getTargetClass() {
return targetClass;
}
}

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.api.exception.runtime;
/**
* Nacos runtime exception.
*
* @author yangyi
*/
public class NacosRuntimeException extends RuntimeException {
private static final long serialVersionUID = 3513491993982293262L;
public static final String ERROR_MESSAGE_FORMAT = "errCode: %d, errMsg: %s ";
private int errCode;
public NacosRuntimeException(int errCode) {
super();
this.errCode = errCode;
}
public NacosRuntimeException(int errCode, String errMsg) {
super(String.format(ERROR_MESSAGE_FORMAT, errCode, errMsg));
this.errCode = errCode;
}
public NacosRuntimeException(int errCode, Throwable throwable) {
super(throwable);
this.errCode = errCode;
}
public NacosRuntimeException(int errCode, String errMsg, Throwable throwable) {
super(String.format(ERROR_MESSAGE_FORMAT, errCode, errMsg), throwable);
this.errCode = errCode;
}
public int getErrCode() {
return errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.api.exception.runtime;
/**
* Nacos serialization exception.
*
* @author yangyi
*/
public class NacosSerializationException extends NacosRuntimeException {
public static final int ERROR_CODE = 100;
private static final long serialVersionUID = -4308536346316915612L;
private static final String DEFAULT_MSG = "Nacos serialize failed. ";
private static final String MSG_FOR_SPECIFIED_CLASS = "Nacos serialize for class [%s] failed. ";
private Class<?> serializedClass;
public NacosSerializationException() {
super(ERROR_CODE);
}
public NacosSerializationException(Class<?> serializedClass) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, serializedClass.getName()));
this.serializedClass = serializedClass;
}
public NacosSerializationException(Throwable throwable) {
super(ERROR_CODE, DEFAULT_MSG, throwable);
}
public NacosSerializationException(Class<?> serializedClass, Throwable throwable) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, serializedClass.getName()), throwable);
this.serializedClass = serializedClass;
}
public Class<?> getSerializedClass() {
return serializedClass;
}
}

View File

@ -23,6 +23,8 @@ package com.alibaba.nacos.api.naming;
*/
public class CommonParams {
public static final String CODE = "code";
public static final String SERVICE_NAME = "serviceName";
public static final String CLUSTER_NAME = "clusterName";
@ -31,4 +33,5 @@ public class CommonParams {
public static final String GROUP_NAME = "groupName";
public static final String LIGHT_BEAT_ENABLED = "lightBeatEnabled";
}

View File

@ -0,0 +1,35 @@
/*
* 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.api.naming;
import com.alibaba.nacos.api.common.ResponseCode;
/**
* Business response code of naming module
*
* Every code stays between 20001 to 29999.
*
* @author nkorange
* @author 1.2.0
*/
public class NamingResponseCode extends ResponseCode {
/**
* The requested resource is not found
*/
public static final int RESOURCE_NOT_FOUND = 20404;
}

View File

@ -1,291 +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.api.naming.pojo;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.nacos.api.common.Constants;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.google.common.base.Objects;
/**
* @author nkorange
*/
public abstract class AbstractHealthChecker implements Cloneable {
protected String type = "unknown";
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
* Clone all fields of this instance to another one
*
* @return Another instance with exactly the same fields.
* @throws CloneNotSupportedException
*/
@Override
public abstract AbstractHealthChecker clone() throws CloneNotSupportedException;
/**
* used to JsonAdapter
*/
public void jsonAdapterCallback(SerializeWriter writer) {
// do nothing
}
public static class None extends AbstractHealthChecker {
public static final String TYPE = "NONE";
public None() {
this.setType(TYPE);
}
@Override
public AbstractHealthChecker clone() throws CloneNotSupportedException {
return new None();
}
}
public static class Http extends AbstractHealthChecker {
public static final String TYPE = "HTTP";
private String path = "";
private String headers = "";
private int expectedResponseCode = 200;
public Http() {
this.type = TYPE;
}
public int getExpectedResponseCode() {
return expectedResponseCode;
}
public void setExpectedResponseCode(int expectedResponseCode) {
this.expectedResponseCode = expectedResponseCode;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getHeaders() {
return headers;
}
public void setHeaders(String headers) {
this.headers = headers;
}
@JSONField(serialize = false)
public Map<String, String> getCustomHeaders() {
if (StringUtils.isBlank(headers)) {
return Collections.emptyMap();
}
Map<String, String> headerMap = new HashMap<String, String>(16);
for (String s : headers.split(Constants.NAMING_HTTP_HEADER_SPILIER)) {
String[] splits = s.split(":");
if (splits.length != 2) {
continue;
}
headerMap.put(StringUtils.trim(splits[0]), StringUtils.trim(splits[1]));
}
return headerMap;
}
/**
* used to JsonAdapter
*
* @param writer
*/
@Override
public void jsonAdapterCallback(SerializeWriter writer) {
writer.writeFieldValue(',', "path", getPath());
writer.writeFieldValue(',', "headers", getHeaders());
}
@Override
public int hashCode() {
return Objects.hashCode(path, headers, expectedResponseCode);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Http)) {
return false;
}
Http other = (Http) obj;
if (!strEquals(type, other.getType())) {
return false;
}
if (!strEquals(path, other.getPath())) {
return false;
}
if (!strEquals(headers, other.getHeaders())) {
return false;
}
return expectedResponseCode == other.getExpectedResponseCode();
}
@Override
public Http clone() throws CloneNotSupportedException {
Http config = new Http();
config.setPath(this.getPath());
config.setHeaders(this.getHeaders());
config.setType(this.getType());
config.setExpectedResponseCode(this.getExpectedResponseCode());
return config;
}
}
public static class Tcp extends AbstractHealthChecker {
public static final String TYPE = "TCP";
public Tcp() {
this.type = TYPE;
}
@Override
public int hashCode() {
return Objects.hashCode(TYPE);
}
@Override
public boolean equals(Object obj) {
return obj instanceof Tcp;
}
@Override
public Tcp clone() throws CloneNotSupportedException {
Tcp config = new Tcp();
config.setType(this.type);
return config;
}
}
public static class Mysql extends AbstractHealthChecker {
public static final String TYPE = "MYSQL";
private String user;
private String pwd;
private String cmd;
public Mysql() {
this.type = TYPE;
}
public String getCmd() {
return cmd;
}
public String getPwd() {
return pwd;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
/**
* used to JsonAdapter
*
* @param writer
*/
@Override
public void jsonAdapterCallback(SerializeWriter writer) {
writer.writeFieldValue(',', "user", getUser());
writer.writeFieldValue(',', "pwd", getPwd());
writer.writeFieldValue(',', "cmd", getCmd());
}
@Override
public int hashCode() {
return Objects.hashCode(user, pwd, cmd);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Mysql)) {
return false;
}
Mysql other = (Mysql) obj;
if (!strEquals(user, other.getUser())) {
return false;
}
if (!strEquals(pwd, other.getPwd())) {
return false;
}
return strEquals(cmd, other.getCmd());
}
@Override
public Mysql clone() throws CloneNotSupportedException {
Mysql config = new Mysql();
config.setUser(this.getUser());
config.setPwd(this.getPwd());
config.setCmd(this.getCmd());
config.setType(this.getType());
return config;
}
}
private static boolean strEquals(String str1, String str2) {
return str1 == null ? str2 == null : str1.equals(str2);
}
}

View File

@ -18,6 +18,9 @@ package com.alibaba.nacos.api.naming.pojo;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Tcp;
/**
* Cluster
*
@ -38,7 +41,7 @@ public class Cluster {
/**
* Health check config of this cluster
*/
private AbstractHealthChecker healthChecker = new AbstractHealthChecker.Tcp();
private AbstractHealthChecker healthChecker = new Tcp();
/**
* Default registered port for instances in this cluster.

View File

@ -15,9 +15,11 @@
*/
package com.alibaba.nacos.api.naming.pojo;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.PreservedMetadataKeys;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
@ -30,6 +32,7 @@ import static com.alibaba.nacos.api.common.Constants.NUMBER_PATTERN;
*
* @author nkorange
*/
@JsonInclude(Include.NON_NULL)
public class Instance {
/**
@ -173,7 +176,18 @@ public class Instance {
@Override
public String toString() {
return JSON.toJSONString(this);
return "Instance{" +
"instanceId='" + instanceId + '\'' +
", ip='" + ip + '\'' +
", port=" + port +
", weight=" + weight +
", healthy=" + healthy +
", enabled=" + enabled +
", ephemeral=" + ephemeral +
", clusterName='" + clusterName + '\'' +
", serviceName='" + serviceName + '\'' +
", metadata=" + metadata +
'}';
}
public String toInetAddr() {
@ -187,8 +201,7 @@ public class Instance {
}
Instance host = (Instance) obj;
return strEquals(toString(), host.toString());
return strEquals(host.toString(), toString());
}
@Override
@ -222,7 +235,7 @@ public class Instance {
}
String value = getMetadata().get(key);
if (!StringUtils.isEmpty(value) && value.matches(NUMBER_PATTERN)) {
return Long.valueOf(value);
return Long.parseLong(value);
}
return defaultValue;
}

View File

@ -15,8 +15,6 @@
*/
package com.alibaba.nacos.api.naming.pojo;
import com.alibaba.fastjson.JSON;
import java.util.List;
/**
@ -47,6 +45,9 @@ public class ListView<T> {
@Override
public String toString() {
return JSON.toJSONString(this);
return "ListView{" +
"data=" + data +
", count=" + count +
'}';
}
}

View File

@ -15,8 +15,10 @@
*/
package com.alibaba.nacos.api.naming.pojo;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.nacos.api.common.Constants;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@ -29,10 +31,12 @@ import java.util.List;
*
* @author nkorange
*/
@JsonInclude(Include.NON_NULL)
public class ServiceInfo {
@JSONField(serialize = false)
@JsonIgnore
private String jsonFromServer = EMPTY;
public static final String SPLITER = "@@";
private String name;
@ -43,7 +47,6 @@ public class ServiceInfo {
private long cacheMillis = 1000L;
@JSONField(name = "hosts")
private List<Instance> hosts = new ArrayList<Instance>();
private long lastRefTime = 0L;
@ -162,7 +165,7 @@ public class ServiceInfo {
return true;
}
@JSONField(serialize = false)
@JsonIgnore
public String getJsonFromServer() {
return jsonFromServer;
}
@ -171,12 +174,12 @@ public class ServiceInfo {
this.jsonFromServer = jsonFromServer;
}
@JSONField(serialize = false)
@JsonIgnore
public String getKey() {
return getKey(name, clusters);
}
@JSONField(serialize = false)
@JsonIgnore
public String getKeyEncoded() {
try {
return getKey(URLEncoder.encode(name, "UTF-8"), clusters);
@ -185,7 +188,6 @@ public class ServiceInfo {
}
}
@JSONField(serialize = false)
public static ServiceInfo fromKey(String key) {
ServiceInfo serviceInfo = new ServiceInfo();
int maxSegCount = 3;
@ -201,7 +203,7 @@ public class ServiceInfo {
return serviceInfo;
}
@JSONField(serialize = false)
@JsonIgnore
public static String getKey(String name, String clusters) {
if (!isEmpty(clusters)) {

View File

@ -0,0 +1,75 @@
/*
* 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.api.naming.pojo.healthcheck;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker.None;
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Http;
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Mysql;
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Tcp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
/**
* @author nkorange
*/
@JsonTypeInfo(use = Id.NAME, property = "type", defaultImpl = None.class)
@JsonSubTypes({
@JsonSubTypes.Type(name = Http.TYPE, value = Http.class),
@JsonSubTypes.Type(name = Mysql.TYPE, value = Mysql.class),
@JsonSubTypes.Type(name = Tcp.TYPE, value = Tcp.class)
})
public abstract class AbstractHealthChecker implements Cloneable {
@JsonIgnore
protected final String type;
protected AbstractHealthChecker(String type) {
this.type = type;
}
public String getType() {
return type;
}
/**
* Clone all fields of this instance to another one.
*
* @return Another instance with exactly the same fields
* @throws CloneNotSupportedException clone not supported exception
*/
@Override
public abstract AbstractHealthChecker clone() throws CloneNotSupportedException;
/**
* Default implementation of Health checker.
*/
public static class None extends AbstractHealthChecker {
public static final String TYPE = "NONE";
public None() {
super(TYPE);
}
@Override
public AbstractHealthChecker clone() throws CloneNotSupportedException {
return new None();
}
}
}

View File

@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.naming.healthcheck;
package com.alibaba.nacos.api.naming.pojo.healthcheck;
import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Http;
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Mysql;
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Tcp;
import java.util.ArrayList;
import java.util.List;
@ -29,37 +31,36 @@ public enum HealthCheckType {
/**
* TCP type
*/
TCP("tcp", AbstractHealthChecker.Tcp.class),
TCP(Tcp.class),
/**
* HTTP type
*/
HTTP("http", AbstractHealthChecker.Http.class),
HTTP(Http.class),
/**
* MySQL type
*/
MYSQL("mysql", AbstractHealthChecker.Mysql.class),
MYSQL(Mysql.class),
/**
* No check
*/
NONE("none", AbstractHealthChecker.None.class);
NONE(AbstractHealthChecker.None.class);
private String name;
private final Class<? extends AbstractHealthChecker> healthCheckerClass;
private Class healthCheckerClass;
private static final Map<String, Class<? extends AbstractHealthChecker>> EXTEND = new ConcurrentHashMap<String, Class<? extends AbstractHealthChecker>>();
private static Map<String, Class> EXTEND =
new ConcurrentHashMap<>();
HealthCheckType(String name, Class healthCheckerClass) {
this.name = name;
HealthCheckType(Class<? extends AbstractHealthChecker> healthCheckerClass) {
this.healthCheckerClass = healthCheckerClass;
}
public static void registerHealthChecker(String type, Class healthCheckerClass){
EXTEND.putIfAbsent(type, healthCheckerClass);
public static void registerHealthChecker(String type, Class<? extends AbstractHealthChecker> healthCheckerClass){
if (!EXTEND.containsKey(type)) {
EXTEND.put(type, healthCheckerClass);
HealthCheckerFactory.registerSubType(healthCheckerClass, type);
}
}
public static Class ofHealthCheckerClass(String type){
public static Class<? extends AbstractHealthChecker> ofHealthCheckerClass(String type){
HealthCheckType enumType;
try {
enumType = valueOf(type);
@ -69,12 +70,12 @@ public enum HealthCheckType {
return enumType.healthCheckerClass;
}
public static List<Class> getLoadedHealthCheckerClasses(){
List<Class> all = new ArrayList<>();
public static List<Class<? extends AbstractHealthChecker>> getLoadedHealthCheckerClasses(){
List<Class<? extends AbstractHealthChecker>> all = new ArrayList<Class<? extends AbstractHealthChecker>>();
for(HealthCheckType type : values()){
all.add(type.healthCheckerClass);
}
for(Map.Entry<String, Class> entry : EXTEND.entrySet()){
for(Map.Entry<String, Class<? extends AbstractHealthChecker>> entry : EXTEND.entrySet()){
all.add(entry.getValue());
}
return all;

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.api.naming.pojo.healthcheck;
import java.io.IOException;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker.None;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;
/**
* health checker factory.
*
* @author yangyi
*/
public class HealthCheckerFactory {
private static final ObjectMapper MAPPER = new ObjectMapper();
static {
MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
/**
* Register new sub type of health checker to factory for serialize and deserialize.
*
* @param extendHealthChecker extend health checker
*/
public static void registerSubType(AbstractHealthChecker extendHealthChecker) {
registerSubType(extendHealthChecker.getClass(), extendHealthChecker.getType());
}
/**
* Register new sub type of health checker to factory for serialize and deserialize.
*
* @param extendHealthCheckerClass extend health checker
* @param typeName typeName of health checker
*/
public static void registerSubType(Class<? extends AbstractHealthChecker> extendHealthCheckerClass, String typeName) {
MAPPER.registerSubtypes(new NamedType(extendHealthCheckerClass, typeName));
}
/**
* Create default {@link None} health checker.
*
* @return new none health checker
*/
public static None createNoneHealthChecker() {
return new None();
}
/**
* Deserialize and create a instance of health checker.
*
* @param jsonString json string of health checker
* @return new instance
*/
public static AbstractHealthChecker deserialize(String jsonString) {
try {
return MAPPER.readValue(jsonString, AbstractHealthChecker.class);
} catch (IOException e) {
// TODO replace with NacosDeserializeException.
throw new RuntimeException("Deserialize health checker from json failed", e);
}
}
/**
* Serialize a instance of health checker to json
*
* @param healthChecker health checker instance
* @return son string after serializing
*/
public static String serialize(AbstractHealthChecker healthChecker) {
try {
return MAPPER.writeValueAsString(healthChecker);
} catch (JsonProcessingException e) {
// TODO replace with NacosSerializeException.
throw new RuntimeException("Serialize health checker to json failed", e);
}
}
}

View File

@ -0,0 +1,121 @@
/*
* 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.api.naming.pojo.healthcheck.impl;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.Objects;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Implementation of health checker for HTTP.
*
* @author yangyi
*/
public class Http extends AbstractHealthChecker {
public static final String TYPE = "HTTP";
private String path = "";
private String headers = "";
private int expectedResponseCode = 200;
public Http() {
super(TYPE);
}
public int getExpectedResponseCode() {
return expectedResponseCode;
}
public void setExpectedResponseCode(int expectedResponseCode) {
this.expectedResponseCode = expectedResponseCode;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getHeaders() {
return headers;
}
public void setHeaders(String headers) {
this.headers = headers;
}
@JsonIgnore
public Map<String, String> getCustomHeaders() {
if (StringUtils.isBlank(headers)) {
return Collections.emptyMap();
}
Map<String, String> headerMap = new HashMap<String, String>(16);
for (String s : headers.split(Constants.NAMING_HTTP_HEADER_SPILIER)) {
String[] splits = s.split(":");
if (splits.length != 2) {
continue;
}
headerMap.put(StringUtils.trim(splits[0]), StringUtils.trim(splits[1]));
}
return headerMap;
}
@Override
public int hashCode() {
return Objects.hashCode(path, headers, expectedResponseCode);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Http)) {
return false;
}
Http other = (Http) obj;
if (!StringUtils.equals(type, other.getType())) {
return false;
}
if (!StringUtils.equals(path, other.getPath())) {
return false;
}
if (!StringUtils.equals(headers, other.getHeaders())) {
return false;
}
return expectedResponseCode == other.getExpectedResponseCode();
}
@Override
public Http clone() throws CloneNotSupportedException {
Http config = new Http();
config.setPath(this.getPath());
config.setHeaders(this.getHeaders());
config.setExpectedResponseCode(this.getExpectedResponseCode());
return config;
}
}

View File

@ -0,0 +1,98 @@
/*
* 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.api.naming.pojo.healthcheck.impl;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
import com.google.common.base.Objects;
/**
* Implementation of health checker for MYSQL.
*
* @author yangyi
*/
public class Mysql extends AbstractHealthChecker {
public static final String TYPE = "MYSQL";
private String user;
private String pwd;
private String cmd;
public Mysql() {
super(TYPE);
}
public String getCmd() {
return cmd;
}
public String getPwd() {
return pwd;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public int hashCode() {
return Objects.hashCode(user, pwd, cmd);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Mysql)) {
return false;
}
Mysql other = (Mysql) obj;
if (!StringUtils.equals(user, other.getUser())) {
return false;
}
if (!StringUtils.equals(pwd, other.getPwd())) {
return false;
}
return StringUtils.equals(cmd, other.getCmd());
}
@Override
public Mysql clone() throws CloneNotSupportedException {
Mysql config = new Mysql();
config.setUser(this.getUser());
config.setPwd(this.getPwd());
config.setCmd(this.getCmd());
return config;
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.api.naming.pojo.healthcheck.impl;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
import com.google.common.base.Objects;
/**
* Implementation of health checker for TCP.
*
* @author yangyi
*/
public class Tcp extends AbstractHealthChecker {
public static final String TYPE = "TCP";
public Tcp() {
super(TYPE);
}
@Override
public int hashCode() {
return Objects.hashCode(TYPE);
}
@Override
public boolean equals(Object obj) {
return obj instanceof Tcp;
}
@Override
public Tcp clone() throws CloneNotSupportedException {
return new Tcp();
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.api.naming.utils;
import com.alibaba.nacos.api.common.Constants;
import org.apache.commons.lang3.StringUtils;
/**
* @author nkorange
@ -32,6 +33,9 @@ public class NamingUtils {
}
public static String getServiceName(String serviceNameWithGroup) {
if (StringUtils.isBlank(serviceNameWithGroup)) {
return StringUtils.EMPTY;
}
if (!serviceNameWithGroup.contains(Constants.SERVICE_INFO_SPLITER)) {
return serviceNameWithGroup;
}
@ -39,6 +43,9 @@ public class NamingUtils {
}
public static String getGroupName(String serviceNameWithGroup) {
if (StringUtils.isBlank(serviceNameWithGroup)) {
return StringUtils.EMPTY;
}
if (!serviceNameWithGroup.contains(Constants.SERVICE_INFO_SPLITER)) {
return Constants.DEFAULT_GROUP;
}

View File

@ -15,24 +15,30 @@
*/
package com.alibaba.nacos.api.selector;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
/**
* Abstract selector that only contains a type
*
* @author nkorange
* @since 0.7.0
*/
@JsonTypeInfo(use = Id.NAME, property = "type", defaultImpl = NoneSelector.class)
public abstract class AbstractSelector {
/**
* The type of this selector, each child class should announce its own unique type.
*/
private String type;
@JsonIgnore
private final String type;
protected AbstractSelector(String type) {
this.type = type;
}
public String getType() {
return type;
}
protected void setType(String type) {
this.type = type;
}
}

View File

@ -29,7 +29,7 @@ public class ExpressionSelector extends AbstractSelector {
private String expression;
public ExpressionSelector() {
this.setType(SelectorType.label.name());
super(SelectorType.label.name());
}
public String getExpression() {

View File

@ -23,6 +23,6 @@ package com.alibaba.nacos.api.selector;
public class NoneSelector extends AbstractSelector {
public NoneSelector() {
this.setType(SelectorType.none.name());
super(SelectorType.none.name());
}
}

View File

@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.api.annotation;
import com.alibaba.fastjson.JSON;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.mock.env.MockEnvironment;

View File

@ -0,0 +1,71 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.api.naming.pojo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.*;
public class ServiceInfoTest {
private ObjectMapper mapper;
private ServiceInfo serviceInfo;
@Before
public void setUp() throws Exception {
mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
serviceInfo = new ServiceInfo("testName", "testClusters");
}
@Test
public void testSerialize() throws JsonProcessingException {
String actual = mapper.writeValueAsString(serviceInfo);
assertTrue(actual.contains("\"name\":\"testName\""));
assertTrue(actual.contains("\"clusters\":\"testClusters\""));
assertTrue(actual.contains("\"cacheMillis\":1000"));
assertTrue(actual.contains("\"hosts\":[]"));
assertTrue(actual.contains("\"lastRefTime\":0"));
assertTrue(actual.contains("\"checksum\":\"\""));
assertTrue(actual.contains("\"valid\":true"));
assertTrue(actual.contains("\"allIPs\":false"));
assertFalse(actual.contains("jsonFromServer"));
assertFalse(actual.contains("key"));
assertFalse(actual.contains("keyEncoded"));
}
@Test
public void testDeserialize() throws IOException {
String example = "{\"name\":\"testName\",\"clusters\":\"testClusters\",\"cacheMillis\":1000,\"hosts\":[],\"lastRefTime\":0,\"checksum\":\"\",\"allIPs\":false,\"valid\":true,\"groupName\":\"\"}";
ServiceInfo actual = mapper.readValue(example, ServiceInfo.class);
assertEquals("testName", actual.getName());
assertEquals("testClusters", actual.getClusters());
assertEquals("", actual.getChecksum());
assertEquals("", actual.getGroupName());
assertEquals(1000, actual.getCacheMillis());
assertEquals(0, actual.getLastRefTime());
assertTrue(actual.getHosts().isEmpty());
assertTrue(actual.isValid());
assertFalse(actual.isAllIPs());
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.api.naming.pojo.healthcheck;
import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
public class AbstractHealthCheckerTest {
private ObjectMapper objectMapper = new ObjectMapper();
@Before
public void setUp() {
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.registerSubtypes(new NamedType(TestChecker.class, TestChecker.TYPE));
}
@Test
public void testSerialize() throws JsonProcessingException {
TestChecker testChecker = new TestChecker();
testChecker.setTestValue("");
String actual = objectMapper.writeValueAsString(testChecker);
assertTrue(actual.contains("\"testValue\":\"\""));
assertTrue(actual.contains("\"type\":\"TEST\""));
}
@Test
public void testDeserialize() throws IOException {
String testChecker = "{\"type\":\"TEST\",\"testValue\":\"\"}";
TestChecker actual = objectMapper.readValue(testChecker, TestChecker.class);
assertEquals("", actual.getTestValue());
assertEquals(TestChecker.TYPE, actual.getType());
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.api.naming.pojo.healthcheck;
import static org.junit.Assert.*;
import org.junit.Test;
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Tcp;
public class HealthCheckerFactoryTest {
@Test
public void testSerialize() {
Tcp tcp = new Tcp();
String actual = HealthCheckerFactory.serialize(tcp);
assertTrue(actual.contains("\"type\":\"TCP\""));
}
@Test
public void testSerializeExtend() {
HealthCheckerFactory.registerSubType(TestChecker.class, TestChecker.TYPE);
TestChecker testChecker = new TestChecker();
String actual = HealthCheckerFactory.serialize(testChecker);
assertTrue(actual.contains("\"type\":\"TEST\""));
}
@Test
public void testDeserialize() {
String tcpString = "{\"type\":\"TCP\"}";
AbstractHealthChecker actual = HealthCheckerFactory.deserialize(tcpString);
assertEquals(Tcp.class, actual.getClass());
}
@Test
public void testDeserializeExtend() {
String tcpString = "{\"type\":\"TEST\",\"testValue\":null}";
AbstractHealthChecker actual = HealthCheckerFactory.deserialize(tcpString);
assertEquals(TestChecker.class, actual.getClass());
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.api.naming.pojo.healthcheck;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
public class TestChecker extends AbstractHealthChecker {
@JsonTypeInfo(use = Id.NAME, property = "type")
public static final String TYPE = "TEST";
private String testValue;
public String getTestValue() {
return testValue;
}
public void setTestValue(String testValue) {
this.testValue = testValue;
}
public TestChecker() {
super(TYPE);
}
@Override
public AbstractHealthChecker clone() throws CloneNotSupportedException {
return null;
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.api.naming.pojo.healthcheck.impl;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class HttpTest {
private ObjectMapper objectMapper;
private Http http;
@Before
public void setUp() {
objectMapper = new ObjectMapper();
http = new Http();
}
@Test
public void testGetExpectedResponseCodeWithEmpty() {
http.setHeaders("");
assertTrue(http.getCustomHeaders().isEmpty());
}
@Test
public void testGetExpectedResponseCodeWithoutEmpty() {
http.setHeaders("x:a|y:");
Map<String, String> actual = http.getCustomHeaders();
assertFalse(actual.isEmpty());
assertEquals(1, actual.size());
assertEquals("a", actual.get("x"));
}
@Test
public void testSerialize() throws JsonProcessingException {
http.setHeaders("x:a|y:");
http.setPath("/x");
String actual = objectMapper.writeValueAsString(http);
assertTrue(actual.contains("\"path\":\"/x\""));
assertTrue(actual.contains("\"type\":\"HTTP\""));
assertTrue(actual.contains("\"headers\":\"x:a|y:\""));
assertTrue(actual.contains("\"expectedResponseCode\":200"));
}
@Test
public void testDeserialize() throws IOException {
String testChecker = "{\"type\":\"HTTP\",\"path\":\"/x\",\"headers\":\"x:a|y:\",\"expectedResponseCode\":200}";
Http actual = objectMapper.readValue(testChecker, Http.class);
assertEquals("x:a|y:", actual.getHeaders());
assertEquals("/x", actual.getPath());
assertEquals(200, actual.getExpectedResponseCode());
assertEquals("x:a|y:", actual.getHeaders());
assertEquals(Http.TYPE, actual.getType());
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.api.naming.pojo.healthcheck.impl;
import static org.junit.Assert.*;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class MysqlTest {
private ObjectMapper objectMapper;
private Mysql mysql;
@Before
public void setUp() throws Exception {
mysql = new Mysql();
mysql.setUser("user");
mysql.setPwd("pwd");
mysql.setCmd("cmd");
objectMapper = new ObjectMapper();
}
@Test
public void testSerialize() throws JsonProcessingException {
String actual = objectMapper.writeValueAsString(mysql);
assertTrue(actual.contains("\"user\":\"user\""));
assertTrue(actual.contains("\"type\":\"MYSQL\""));
assertTrue(actual.contains("\"pwd\":\"pwd\""));
assertTrue(actual.contains("\"cmd\":\"cmd\""));
}
@Test
public void testDeserialize() throws IOException {
String testChecker = "{\"type\":\"MYSQL\",\"user\":\"user\",\"pwd\":\"pwd\",\"cmd\":\"cmd\"}";
Mysql actual = objectMapper.readValue(testChecker, Mysql.class);
assertEquals("cmd", actual.getCmd());
assertEquals("pwd", actual.getPwd());
assertEquals("user", actual.getUser());
assertEquals(Mysql.TYPE, actual.getType());
}
}

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.2.0-SNAPSHOT</version>
<version>1.3.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -26,7 +26,7 @@
<packaging>jar</packaging>
<name>nacos-client ${project.version}</name>
<url>https://github.com/alibaba/nacos</url>
<url>http://nacos.io</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -109,13 +109,16 @@
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>0.5.0</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
</dependencies>
@ -125,8 +128,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

@ -16,7 +16,6 @@
package com.alibaba.nacos.client.config;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
@ -33,8 +32,8 @@ import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
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.TemplateUtils;
import com.alibaba.nacos.client.utils.TenantUtil;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.ValidatorUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@ -44,7 +43,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Callable;
/**
* Config Impl
@ -58,8 +56,6 @@ public class NacosConfigService implements ConfigService {
private static final long POST_TIMEOUT = 3000L;
private static final String EMPTY = "";
/**
* http agent
*/
@ -73,6 +69,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;
@ -86,34 +83,7 @@ public class NacosConfigService implements ConfigService {
}
private void initNamespace(Properties properties) {
String namespaceTmp = null;
String isUseCloudNamespaceParsing =
properties.getProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
System.getProperty(SystemPropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
String.valueOf(Constants.DEFAULT_USE_CLOUD_NAMESPACE_PARSING)));
if (Boolean.parseBoolean(isUseCloudNamespaceParsing)) {
namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, new Callable<String>() {
@Override
public String call() {
return TenantUtil.getUserTenantForAcm();
}
});
namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, new Callable<String>() {
@Override
public String call() {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
return StringUtils.isNotBlank(namespace) ? namespace : EMPTY;
}
});
}
if (StringUtils.isBlank(namespaceTmp)) {
namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE);
}
namespace = StringUtils.isNotBlank(namespaceTmp) ? namespaceTmp.trim() : EMPTY;
namespace = ParamUtil.parseNamespace(properties);
properties.put(PropertyKeyConst.NAMESPACE, namespace);
}
@ -170,9 +140,8 @@ public class NacosConfigService implements ConfigService {
}
try {
content = worker.getServerConfig(dataId, group, tenant, timeoutMs);
cr.setContent(content);
String[] ct = worker.getServerConfig(dataId, group, tenant, timeoutMs);
cr.setContent(ct[0]);
configFilterChainManager.doFilter(null, cr);
content = cr.getContent();

View File

@ -15,11 +15,11 @@
*/
package com.alibaba.nacos.client.config.filter.impl;
import com.alibaba.nacos.api.config.filter.IConfigContext;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.nacos.api.config.filter.IConfigContext;
/**
* Config Context
*

View File

@ -15,16 +15,15 @@
*/
package com.alibaba.nacos.client.config.filter.impl;
import java.util.List;
import com.alibaba.nacos.api.config.filter.IConfigFilter;
import com.alibaba.nacos.api.config.filter.IConfigFilterChain;
import com.alibaba.nacos.api.config.filter.IConfigRequest;
import com.alibaba.nacos.api.config.filter.IConfigResponse;
import com.alibaba.nacos.api.exception.NacosException;
import com.google.common.collect.Lists;
import java.util.List;
/**
* Config Filter Chain Management
*

View File

@ -15,12 +15,12 @@
*/
package com.alibaba.nacos.client.config.filter.impl;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.nacos.api.config.filter.IConfigContext;
import com.alibaba.nacos.api.config.filter.IConfigRequest;
import java.util.HashMap;
import java.util.Map;
/**
* Config Request
*

View File

@ -15,12 +15,12 @@
*/
package com.alibaba.nacos.client.config.filter.impl;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.nacos.api.config.filter.IConfigContext;
import com.alibaba.nacos.api.config.filter.IConfigResponse;
import java.util.HashMap;
import java.util.Map;
/**
* Config Response
*

View File

@ -43,7 +43,7 @@ public class MetricsHttpAgent implements HttpAgent {
@Override
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("GET", path, "NA");
HttpResult result = null;
HttpResult result;
try {
result = httpAgent.httpGet(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
@ -59,7 +59,7 @@ public class MetricsHttpAgent implements HttpAgent {
@Override
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("POST", path, "NA");
HttpResult result = null;
HttpResult result;
try {
result = httpAgent.httpPost(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {
@ -75,7 +75,7 @@ public class MetricsHttpAgent implements HttpAgent {
@Override
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
Histogram.Timer timer = MetricsMonitor.getConfigRequestMonitor("DELETE", path, "NA");
HttpResult result = null;
HttpResult result;
try {
result = httpAgent.httpDelete(path, headers, paramValues, encoding, readTimeoutMs);
} catch (IOException e) {

View File

@ -22,12 +22,13 @@ import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.impl.ServerListManager;
import com.alibaba.nacos.client.config.impl.SpasAdapter;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.client.identify.STSConfig;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.client.utils.JSONUtils;
import com.alibaba.nacos.client.security.SecurityProxy;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.StringUtils;
@ -43,7 +44,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.*;
/**
* Server Agent
@ -54,6 +55,12 @@ public class ServerHttpAgent implements HttpAgent {
private static final Logger LOGGER = LogUtils.logger(ServerHttpAgent.class);
private SecurityProxy securityProxy;
private String namespaceId;
private long securityInfoRefreshIntervalMills = TimeUnit.SECONDS.toMillis(5);
/**
* @param path 相对于web应用根/开头
* @param headers
@ -68,7 +75,7 @@ public class ServerHttpAgent implements HttpAgent {
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
final boolean isSSL = false;
injectSecurityInfo(paramValues);
String currentServerAddr = serverListMgr.getCurrentServerAddr();
int maxRetry = this.maxRetry;
@ -121,7 +128,7 @@ public class ServerHttpAgent implements HttpAgent {
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
boolean isSSL = false;
injectSecurityInfo(paramValues);
String currentServerAddr = serverListMgr.getCurrentServerAddr();
int maxRetry = this.maxRetry;
@ -176,7 +183,7 @@ public class ServerHttpAgent implements HttpAgent {
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
boolean isSSL = false;
injectSecurityInfo(paramValues);
String currentServerAddr = serverListMgr.getCurrentServerAddr();
int maxRetry = this.maxRetry;
@ -200,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);
@ -225,7 +234,9 @@ public class ServerHttpAgent implements HttpAgent {
}
private String getUrl(String serverAddr, String relativePath) {
return serverAddr + "/" + serverListMgr.getContentPath() + relativePath;
String contextPath = serverListMgr.getContentPath().startsWith("/") ?
serverListMgr.getContentPath() : "/" + serverListMgr.getContentPath();
return serverAddr + contextPath + relativePath;
}
public static String getAppname() {
@ -243,7 +254,38 @@ public class ServerHttpAgent implements HttpAgent {
public ServerHttpAgent(Properties properties) throws NacosException {
serverListMgr = new ServerListManager(properties);
securityProxy = new SecurityProxy(properties);
namespaceId = properties.getProperty(PropertyKeyConst.NAMESPACE);
init(properties);
securityProxy.login(serverListMgr.getServerUrls());
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.config.security.updater");
t.setDaemon(true);
return t;
}
});
executorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
securityProxy.login(serverListMgr.getServerUrls());
}
}, 0, securityInfoRefreshIntervalMills, TimeUnit.MILLISECONDS);
}
private void injectSecurityInfo(List<String> params) {
if (StringUtils.isNotBlank(securityProxy.getAccessToken())) {
params.add(Constants.ACCESS_TOKEN);
params.add(securityProxy.getAccessToken());
}
if (StringUtils.isNotBlank(namespaceId) && !params.contains(SpasAdapter.TENANT_KEY)) {
params.add(SpasAdapter.TENANT_KEY);
params.add(namespaceId);
}
}
private void init(Properties properties) {
@ -324,8 +366,7 @@ public class ServerHttpAgent implements HttpAgent {
}
}
String stsResponse = getSTSResponse();
STSCredential stsCredentialTmp = JSONUtils.deserializeObject(stsResponse,
new TypeReference<STSCredential>() {
STSCredential stsCredentialTmp = JacksonUtils.toObj(stsResponse, new TypeReference<STSCredential>() {
});
sTSCredential = stsCredentialTmp;
LOGGER.info("[getSTSCredential] code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}", sTSCredential.getCode(),

View File

@ -0,0 +1,74 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.api.config.PropertyChangeType;
import com.alibaba.nacos.api.config.listener.ConfigChangeParser;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* AbstractConfigChangeParser
*
* @author rushsky518
*/
public abstract class AbstractConfigChangeParser implements ConfigChangeParser {
private String configType;
public AbstractConfigChangeParser(String configType) {
this.configType = configType;
}
@Override
public boolean isResponsibleFor(String type) {
return this.configType.equalsIgnoreCase(type);
}
protected Map<String, ConfigChangeItem> filterChangeData(Map oldMap, Map newMap) {
Map<String, ConfigChangeItem> result = new HashMap<String, ConfigChangeItem>(16);
for (Iterator<Map.Entry<String, Object>> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) {
Map.Entry<String, Object> e = entryItr.next();
ConfigChangeItem cci;
if (newMap.containsKey(e.getKey())) {
if (e.getValue().equals(newMap.get(e.getKey()))) {
continue;
}
cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), newMap.get(e.getKey()).toString());
cci.setType(PropertyChangeType.MODIFIED);
} else {
cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), null);
cci.setType(PropertyChangeType.DELETED);
}
result.put(e.getKey(), cci);
}
for (Iterator<Map.Entry<String, Object>> entryItr = newMap.entrySet().iterator(); entryItr.hasNext();) {
Map.Entry<String, Object> e = entryItr.next();
if (!oldMap.containsKey(e.getKey())) {
ConfigChangeItem cci = new ConfigChangeItem(e.getKey(), null, e.getValue().toString());
cci.setType(PropertyChangeType.ADDED);
result.put(e.getKey(), cci);
}
}
return result;
}
}

View File

@ -16,18 +16,21 @@
package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigChangeEvent;
import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
import com.alibaba.nacos.api.config.listener.Listener;
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.utils.MD5;
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
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;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@ -59,9 +62,17 @@ public class CacheData {
return content;
}
public void setContent(String newContent) {
this.content = newContent;
this.md5 = getMd5String(content);
public void setContent(String content) {
this.content = content;
this.md5 = getMd5String(this.content);
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
@ -74,7 +85,9 @@ public class CacheData {
if (null == listener) {
throw new IllegalArgumentException("listener is null");
}
ManagerListenerWrap wrap = new ManagerListenerWrap(listener, md5);
ManagerListenerWrap wrap = (listener instanceof AbstractConfigChangeListener) ?
new ManagerListenerWrap(listener, md5, content) : new ManagerListenerWrap(listener, md5);
if (listeners.addIfAbsent(wrap)) {
LOGGER.info("[{}] [add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", name, tenant, dataId, group,
listeners.size());
@ -158,12 +171,12 @@ public class CacheData {
void checkListenerMd5() {
for (ManagerListenerWrap wrap : listeners) {
if (!md5.equals(wrap.lastCallMd5)) {
safeNotifyListener(dataId, group, content, md5, wrap);
safeNotifyListener(dataId, group, content, type, md5, wrap);
}
}
}
private void safeNotifyListener(final String dataId, final String group, final String content,
private void safeNotifyListener(final String dataId, final String group, final String content, final String type,
final String md5, final ManagerListenerWrap listenerWrap) {
final Listener listener = listenerWrap.listener;
@ -188,6 +201,15 @@ public class CacheData {
configFilterChainManager.doFilter(null, cr);
String contentTmp = cr.getContent();
listener.receiveConfigInfo(contentTmp);
// compare lastContent and content
if (listener instanceof AbstractConfigChangeListener) {
Map data = ConfigChangeHandler.getInstance().parseChangeData(listenerWrap.lastContent, content, type);
ConfigChangeEvent event = new ConfigChangeEvent(data);
((AbstractConfigChangeListener)listener).receiveConfigChange(event);
listenerWrap.lastContent = content;
}
listenerWrap.lastCallMd5 = md5;
LOGGER.info("[{}] [notify-ok] dataId={}, group={}, md5={}, listener={} ", name, dataId, group, md5,
listener);
@ -220,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) {
@ -282,11 +304,13 @@ public class CacheData {
private volatile String content;
private int taskId;
private volatile boolean isInitializing = true;
private String type;
}
class ManagerListenerWrap {
final Listener listener;
String lastCallMd5 = CacheData.getMd5String(null);
String lastContent = null;
ManagerListenerWrap(Listener listener) {
this.listener = listener;
@ -297,6 +321,12 @@ class ManagerListenerWrap {
this.lastCallMd5 = md5;
}
ManagerListenerWrap(Listener listener, String md5, String lastContent) {
this.listener = listener;
this.lastCallMd5 = md5;
this.lastContent = lastContent;
}
@Override
public boolean equals(Object obj) {
if (null == obj || obj.getClass() != getClass()) {

View File

@ -17,6 +17,7 @@ package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.common.GroupKey;
@ -24,27 +25,21 @@ 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.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.TenantUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import com.alibaba.nacos.client.utils.TenantUtil;
import org.slf4j.Logger;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
@ -53,6 +48,7 @@ import java.util.concurrent.atomic.AtomicReference;
import static com.alibaba.nacos.api.common.Constants.LINE_SEPARATOR;
import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR;
import static com.alibaba.nacos.api.common.Constants.CONFIG_TYPE;
/**
* Longpolling
@ -190,8 +186,8 @@ public class ClientWorker {
cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant);
// fix issue # 1317
if (enableRemoteSyncConfig) {
String content = getServerConfig(dataId, group, tenant, 3000L);
cache.setContent(content);
String[] ct = getServerConfig(dataId, group, tenant, 3000L);
cache.setContent(ct[0]);
}
}
@ -217,8 +213,9 @@ public class ClientWorker {
return cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
}
public String getServerConfig(String dataId, String group, String tenant, long readTimeout)
public String[] getServerConfig(String dataId, String group, String tenant, long readTimeout)
throws NacosException {
String[] ct = new String[2];
if (StringUtils.isBlank(group)) {
group = Constants.DEFAULT_GROUP;
}
@ -227,9 +224,9 @@ public class ClientWorker {
try {
List<String> params = null;
if (StringUtils.isBlank(tenant)) {
params = Arrays.asList("dataId", dataId, "group", group);
params = new ArrayList<String>(Arrays.asList("dataId", dataId, "group", group));
} else {
params = Arrays.asList("dataId", dataId, "group", group, "tenant", tenant);
params = new ArrayList<String>(Arrays.asList("dataId", dataId, "group", group, "tenant", tenant));
}
result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
} catch (IOException e) {
@ -243,10 +240,16 @@ public class ClientWorker {
switch (result.code) {
case HttpURLConnection.HTTP_OK:
LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content);
return result.content;
ct[0] = result.content;
if (result.headers.containsKey(CONFIG_TYPE)) {
ct[1] = result.headers.get(CONFIG_TYPE).get(0);
} else {
ct[1] = ConfigType.TEXT.getType();
}
return ct;
case HttpURLConnection.HTTP_NOT_FOUND:
LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null);
return null;
return ct;
case HttpURLConnection.HTTP_CONFLICT: {
LOGGER.error(
"[{}] [sub-server-error] get server config being modified concurrently, dataId={}, group={}, "
@ -277,7 +280,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);
@ -299,7 +302,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);
@ -357,7 +360,10 @@ public class ClientWorker {
*/
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException {
List<String> params = Arrays.asList(Constants.PROBE_MODIFY_REQUEST, probeUpdateString);
List<String> params = new ArrayList<String>(2);
params.add(Constants.PROBE_MODIFY_REQUEST);
params.add(probeUpdateString);
List<String> headers = new ArrayList<String>(2);
headers.add("Long-Pulling-Timeout");
@ -514,6 +520,10 @@ public class ClientWorker {
// check server config
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
if (!CollectionUtils.isEmpty(changedGroupKeys)) {
LOGGER.info("get changedGroupKeys:" + changedGroupKeys);
}
for (String groupKey : changedGroupKeys) {
String[] key = GroupKey.parseKey(groupKey);
@ -524,12 +534,15 @@ public class ClientWorker {
tenant = key[2];
}
try {
String content = getServerConfig(dataId, group, tenant, 3000L);
String[] ct = getServerConfig(dataId, group, tenant, 3000L);
CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
cache.setContent(content);
LOGGER.info("[{}] [data-received] dataId={}, group={}, tenant={}, md5={}, content={}",
cache.setContent(ct[0]);
if (null != ct[1]) {
cache.setType(ct[1]);
}
LOGGER.info("[{}] [data-received] dataId={}, group={}, tenant={}, md5={}, content={}, type={}",
agent.getName(), dataId, group, tenant, cache.getMd5(),
ContentUtils.truncateContent(content));
ContentUtils.truncateContent(ct[0]), ct[1]);
} catch (NacosException ioe) {
String message = String.format(
"[%s] [get-update] get changed config exception. dataId=%s, group=%s, tenant=%s",

View File

@ -0,0 +1,67 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.config.listener.ConfigChangeParser;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Map;
import java.util.Iterator;
/**
* ConfigChangeHandler
*
* @author rushsky518
*/
public class ConfigChangeHandler {
private static class ConfigChangeHandlerHolder {
private final static ConfigChangeHandler INSTANCE = new ConfigChangeHandler();
}
private ConfigChangeHandler() {
this.parserList = new LinkedList<ConfigChangeParser>();
ServiceLoader<ConfigChangeParser> loader = ServiceLoader.load(ConfigChangeParser.class);
Iterator<ConfigChangeParser> itr = loader.iterator();
while (itr.hasNext()) {
this.parserList.add(itr.next());
}
this.parserList.add(new PropertiesChangeParser());
this.parserList.add(new YmlChangeParser());
}
public static ConfigChangeHandler getInstance() {
return ConfigChangeHandlerHolder.INSTANCE;
}
public Map parseChangeData(String oldContent, String newContent, String type) throws IOException {
for (ConfigChangeParser changeParser: this.parserList) {
if (changeParser.isResponsibleFor(type)) {
return changeParser.doParse(oldContent, newContent, type);
}
}
return Collections.emptyMap();
}
private List<ConfigChangeParser> parserList;
}

View File

@ -17,10 +17,10 @@ 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.common.utils.IoUtils;
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;
import com.alibaba.nacos.common.utils.UuidUtils;
import com.alibaba.nacos.common.utils.VersionUtils;
@ -29,10 +29,7 @@ import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* Http tool
@ -45,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");
}
@ -73,9 +70,7 @@ public class HttpSimpleClient {
}
return new HttpResult(respCode, conn.getHeaderFields(), resp);
} finally {
if (conn != null && conn.getInputStream() != null) {
conn.getInputStream().close();
}
IoUtils.closeQuietly(conn);
}
}
@ -103,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");
}
@ -131,9 +126,7 @@ public class HttpSimpleClient {
}
return new HttpResult(respCode, conn.getHeaderFields(), resp);
} finally {
if (conn != null && conn.getInputStream() != null) {
conn.getInputStream().close();
}
IoUtils.closeQuietly(conn);
}
}
@ -157,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");
}
@ -185,9 +178,7 @@ public class HttpSimpleClient {
}
return new HttpResult(respCode, conn.getHeaderFields(), resp);
} finally {
if (conn != null && conn.getInputStream() != null) {
conn.getInputStream().close();
}
IoUtils.closeQuietly(conn);
}
}
@ -206,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);
@ -259,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

@ -17,10 +17,10 @@ package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.config.utils.ConcurrentDiskUtil;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.client.config.utils.JVMUtil;
import com.alibaba.nacos.client.config.utils.SnapShotSwitch;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.common.utils.IoUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

View File

@ -0,0 +1,50 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.common.utils.StringUtils;
import java.io.IOException;
import java.io.StringReader;
import java.util.Map;
import java.util.Properties;
/**
* PropertiesChangeParser
*
* @author rushsky518
*/
public class PropertiesChangeParser extends AbstractConfigChangeParser {
public PropertiesChangeParser() {
super("properties");
}
@Override
public Map<String, ConfigChangeItem> doParse(String oldContent, String newContent, String type) throws IOException {
Properties oldProps = new Properties();
Properties newProps = new Properties();
if (StringUtils.isNotBlank(oldContent)) {
oldProps.load(new StringReader(oldContent));
}
if (StringUtils.isNotBlank(newContent)) {
newProps.load(new StringReader(newContent));
}
return filterChangeData(oldProps, newProps);
}
}

View File

@ -15,28 +15,23 @@
*/
package com.alibaba.nacos.client.config.impl;
import java.io.IOException;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.impl.EventDispatcher.ServerlistChangeEvent;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.common.utils.IoUtils;
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;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
@ -240,6 +235,10 @@ public class ServerListManager {
isStarted = true;
}
public List<String> getServerUrls() {
return serverUrls;
}
Iterator<String> iterator() {
if (serverUrls.isEmpty()) {
LOGGER.error("[{}] [iterator-serverlist] No server address defined!", name);
@ -308,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

@ -101,5 +101,5 @@ public class SpasAdapter {
}
private static final String GROUP_KEY = "group";
private static final String TENANT_KEY = "tenant";
public static final String TENANT_KEY = "tenant";
}

View File

@ -15,11 +15,7 @@
*/
package com.alibaba.nacos.client.config.impl;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
/**
* Time Service

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.client.config.impl;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.common.utils.StringUtils;
import org.yaml.snakeyaml.Yaml;
import java.util.*;
/**
* YmlChangeParser
*
* @author rushsky518
*/
public class YmlChangeParser extends AbstractConfigChangeParser {
public YmlChangeParser() {
super("yaml");
}
@Override
public Map<String, ConfigChangeItem> doParse(String oldContent, String newContent, String type) {
Map<String, Object> oldMap = Collections.emptyMap();
Map<String, Object> newMap = Collections.emptyMap();
if (StringUtils.isNotBlank(oldContent)) {
oldMap = (new Yaml()).load(oldContent);
oldMap = getFlattenedMap(oldMap);
}
if (StringUtils.isNotBlank(newContent)) {
newMap = (new Yaml()).load(newContent);
newMap = getFlattenedMap(newMap);
}
return filterChangeData(oldMap, newMap);
}
private final Map<String, Object> getFlattenedMap(Map<String, Object> source) {
Map<String, Object> result = new LinkedHashMap<String, Object>(128);
buildFlattenedMap(result, source, null);
return result;
}
private void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, String path) {
for (Iterator<Map.Entry<String, Object>> itr = source.entrySet().iterator(); itr.hasNext(); ) {
Map.Entry<String, Object> e = itr.next();
String key = e.getKey();
if (StringUtils.isNotBlank(path)) {
if (e.getKey().startsWith("[")) {
key = path + key;
} else {
key = path + '.' + key;
}
}
if (e.getValue() instanceof String) {
result.put(key, e.getValue());
} else if (e.getValue() instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) e.getValue();
buildFlattenedMap(result, map, key);
} else if (e.getValue() instanceof Collection) {
@SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) e.getValue();
if (collection.isEmpty()) {
result.put(key, "");
} else {
int count = 0;
for (Object object : collection) {
buildFlattenedMap(result, Collections.singletonMap("[" + (count++) + "]", object), key);
}
}
} else {
result.put(key, (e.getValue() != null ? e.getValue() : ""));
}
}
}
}

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.config.listener.impl;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.api.config.ConfigChangeEvent;
/**
* AbstractConfigChangeListener
*
* @author rushsky518
*/
public abstract class AbstractConfigChangeListener extends AbstractListener {
/**
* handle config change
* @param event
*/
public abstract void receiveConfigChange(final ConfigChangeEvent event);
@Override
public void receiveConfigInfo(final String configInfo) {}
}

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

@ -15,12 +15,12 @@
*/
package com.alibaba.nacos.client.config.utils;
import java.util.List;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.utils.IPUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
/**
* Param check util
*

View File

@ -53,7 +53,7 @@ public final class CredentialService implements SpasCredentialLoader {
}
public static CredentialService getInstance(String appName) {
String key = appName != null ? appName : Constants.NO_APP_NAME;
String key = appName != null ? appName : IdentifyConstants.NO_APP_NAME;
CredentialService instance = instances.get(key);
if (instance == null) {
instance = new CredentialService(appName);
@ -70,7 +70,7 @@ public final class CredentialService implements SpasCredentialLoader {
}
public static CredentialService freeInstance(String appName) {
String key = appName != null ? appName : Constants.NO_APP_NAME;
String key = appName != null ? appName : IdentifyConstants.NO_APP_NAME;
CredentialService instance = instances.remove(key);
if (instance != null) {
instance.free();

View File

@ -94,7 +94,7 @@ public class CredentialWatcher {
private void loadCredential(boolean init) {
boolean logWarn = init;
if (propertyPath == null) {
URL url = ClassLoader.getSystemResource(Constants.PROPERTIES_FILENAME);
URL url = ClassLoader.getSystemResource(IdentifyConstants.PROPERTIES_FILENAME);
if (url != null) {
propertyPath = url.getPath();
}
@ -105,7 +105,7 @@ public class CredentialWatcher {
propertyPath = value;
}
if (propertyPath == null || propertyPath.isEmpty()) {
propertyPath = Constants.CREDENTIAL_PATH + (appName == null ? Constants.CREDENTIAL_DEFAULT
propertyPath = IdentifyConstants.CREDENTIAL_PATH + (appName == null ? IdentifyConstants.CREDENTIAL_DEFAULT
: appName);
} else {
if (logWarn) {
@ -115,7 +115,7 @@ public class CredentialWatcher {
} else {
if (logWarn) {
SpasLogger.info("[{}] Load credential file from classpath: {}", appName,
Constants.PROPERTIES_FILENAME);
IdentifyConstants.PROPERTIES_FILENAME);
}
}
}
@ -125,13 +125,13 @@ public class CredentialWatcher {
try {
propertiesIS = new FileInputStream(propertyPath);
} catch (FileNotFoundException e) {
if (appName != null && !appName.equals(Constants.CREDENTIAL_DEFAULT) && propertyPath.equals(
Constants.CREDENTIAL_PATH + appName)) {
propertyPath = Constants.CREDENTIAL_PATH + Constants.CREDENTIAL_DEFAULT;
if (appName != null && !appName.equals(IdentifyConstants.CREDENTIAL_DEFAULT) && propertyPath.equals(
IdentifyConstants.CREDENTIAL_PATH + appName)) {
propertyPath = IdentifyConstants.CREDENTIAL_PATH + IdentifyConstants.CREDENTIAL_DEFAULT;
continue;
}
if (!Constants.DOCKER_CREDENTIAL_PATH.equals(propertyPath)) {
propertyPath = Constants.DOCKER_CREDENTIAL_PATH;
if (!IdentifyConstants.DOCKER_CREDENTIAL_PATH.equals(propertyPath)) {
propertyPath = IdentifyConstants.DOCKER_CREDENTIAL_PATH;
continue;
}
}
@ -143,8 +143,8 @@ public class CredentialWatcher {
String tenantId = null;
if (propertiesIS == null) {
propertyPath = null;
accessKey = System.getenv(Constants.ENV_ACCESS_KEY);
secretKey = System.getenv(Constants.ENV_SECRET_KEY);
accessKey = System.getenv(IdentifyConstants.ENV_ACCESS_KEY);
secretKey = System.getenv(IdentifyConstants.ENV_SECRET_KEY);
if (accessKey == null && secretKey == null) {
if (logWarn) {
SpasLogger.info("{} No credential found", appName);
@ -173,26 +173,26 @@ public class CredentialWatcher {
SpasLogger.info("[{}] Load credential file {}", appName, propertyPath);
}
if (!Constants.DOCKER_CREDENTIAL_PATH.equals(propertyPath)) {
if (properties.containsKey(Constants.ACCESS_KEY)) {
accessKey = properties.getProperty(Constants.ACCESS_KEY);
if (!IdentifyConstants.DOCKER_CREDENTIAL_PATH.equals(propertyPath)) {
if (properties.containsKey(IdentifyConstants.ACCESS_KEY)) {
accessKey = properties.getProperty(IdentifyConstants.ACCESS_KEY);
}
if (properties.containsKey(Constants.SECRET_KEY)) {
secretKey = properties.getProperty(Constants.SECRET_KEY);
if (properties.containsKey(IdentifyConstants.SECRET_KEY)) {
secretKey = properties.getProperty(IdentifyConstants.SECRET_KEY);
}
if (properties.containsKey(Constants.TENANT_ID)) {
tenantId = properties.getProperty(Constants.TENANT_ID);
if (properties.containsKey(IdentifyConstants.TENANT_ID)) {
tenantId = properties.getProperty(IdentifyConstants.TENANT_ID);
}
} else {
if (properties.containsKey(Constants.DOCKER_ACCESS_KEY)) {
accessKey = properties.getProperty(Constants.DOCKER_ACCESS_KEY);
if (properties.containsKey(IdentifyConstants.DOCKER_ACCESS_KEY)) {
accessKey = properties.getProperty(IdentifyConstants.DOCKER_ACCESS_KEY);
}
if (properties.containsKey(Constants.DOCKER_SECRET_KEY)) {
secretKey = properties.getProperty(Constants.DOCKER_SECRET_KEY);
if (properties.containsKey(IdentifyConstants.DOCKER_SECRET_KEY)) {
secretKey = properties.getProperty(IdentifyConstants.DOCKER_SECRET_KEY);
}
if (properties.containsKey(Constants.DOCKER_TENANT_ID)) {
tenantId = properties.getProperty(Constants.DOCKER_TENANT_ID);
if (properties.containsKey(IdentifyConstants.DOCKER_TENANT_ID)) {
tenantId = properties.getProperty(IdentifyConstants.DOCKER_TENANT_ID);
}
}
}
@ -211,7 +211,7 @@ public class CredentialWatcher {
Credentials credential = new Credentials(accessKey, secretKey, tenantId);
if (!credential.valid()) {
SpasLogger.warn("[1] Credential file missing required property {} Credential file missing {} or {}",
appName, Constants.ACCESS_KEY, Constants.SECRET_KEY);
appName, IdentifyConstants.ACCESS_KEY, IdentifyConstants.SECRET_KEY);
propertyPath = null;
// return;
}

View File

@ -20,7 +20,7 @@ package com.alibaba.nacos.client.identify;
*
* @author Nacos
*/
public class Constants {
public class IdentifyConstants {
public static final String ACCESS_KEY = "accessKey";
public static final String SECRET_KEY = "secretKey";

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,22 +51,20 @@ 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);
InitUtils.initSerialization();
initServerAddr(properties);
InitUtils.initWebRootContext();
serverProxy = new NamingProxy(namespace, endpoint, serverList);
serverProxy.setProperties(properties);
serverProxy = new NamingProxy(namespace, endpoint, serverList, properties);
}
private void initServerAddr(Properties properties) {

View File

@ -34,6 +34,7 @@ import com.alibaba.nacos.client.naming.net.NamingProxy;
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.utils.ValidatorUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
@ -42,18 +43,17 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
/**
* Nacos Naming Service
*
* @author nkorange
*/
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
public class NacosNamingService implements NamingService {
private static final String DEFAULT_PORT = "8080";
private static final long DEFAULT_HEART_BEAT_INTERVAL = TimeUnit.SECONDS.toMillis(5);
/**
* Each Naming instance should have different namespace.
* Each Naming service should have different namespace.
*/
private String namespace;
@ -76,7 +76,6 @@ public class NacosNamingService implements NamingService {
public NacosNamingService(String serverList) {
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverList);
init(properties);
}
@ -85,17 +84,19 @@ public class NacosNamingService implements NamingService {
}
private void init(Properties properties) {
ValidatorUtils.checkInitParam(properties);
namespace = InitUtils.initNamespaceForNaming(properties);
InitUtils.initSerialization();
initServerAddr(properties);
InitUtils.initWebRootContext();
initCacheDir();
initLogName(properties);
eventDispatcher = new EventDispatcher();
serverProxy = new NamingProxy(namespace, endpoint, serverList);
serverProxy.setProperties(properties);
serverProxy = new NamingProxy(namespace, endpoint, serverList, properties);
beatReactor = new BeatReactor(serverProxy, initClientBeatThreadCount(properties));
hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, isLoadCacheAtStart(properties), initPollingThreadCount(properties));
hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, isLoadCacheAtStart(properties),
initPollingThreadCount(properties));
}
private int initClientBeatThreadCount(Properties properties) {
@ -198,8 +199,7 @@ public class NacosNamingService implements NamingService {
beatInfo.setWeight(instance.getWeight());
beatInfo.setMetadata(instance.getMetadata());
beatInfo.setScheduled(false);
long instanceInterval = instance.getInstanceHeartBeatInterval();
beatInfo.setPeriod(instanceInterval == 0 ? DEFAULT_HEART_BEAT_INTERVAL : instanceInterval);
beatInfo.setPeriod(instance.getInstanceHeartBeatInterval());
beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
}
@ -207,7 +207,6 @@ public class NacosNamingService implements NamingService {
serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
}
@Override
public void deregisterInstance(String serviceName, String ip, int port) throws NacosException {
deregisterInstance(serviceName, ip, port, Constants.DEFAULT_CLUSTER_NAME);

View File

@ -15,13 +15,14 @@
*/
package com.alibaba.nacos.client.naming.backups;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.naming.cache.ConcurrentDiskUtil;
import com.alibaba.nacos.client.naming.cache.DiskCache;
import com.alibaba.nacos.client.naming.core.HostReactor;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.common.utils.JacksonUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.BufferedReader;
@ -180,7 +181,7 @@ public class FailoverReactor {
String json;
if ((json = reader.readLine()) != null) {
try {
dom = JSON.parseObject(json, ServiceInfo.class);
dom = JacksonUtils.toObj(json, ServiceInfo.class);
} catch (Exception e) {
NAMING_LOGGER.error("[NA] error while parsing cached dom : " + json, e);
}

View File

@ -15,8 +15,6 @@
*/
package com.alibaba.nacos.client.naming.beat;
import com.alibaba.fastjson.JSON;
import java.util.Map;
/**
@ -36,7 +34,17 @@ public class BeatInfo {
@Override
public String toString() {
return JSON.toJSONString(this);
return "BeatInfo{" +
"port=" + port +
", ip='" + ip + '\'' +
", weight=" + weight +
", serviceName='" + serviceName + '\'' +
", cluster='" + cluster + '\'' +
", metadata=" + metadata +
", scheduled=" + scheduled +
", period=" + period +
", stopped=" + stopped +
'}';
}
public String getServiceName() {

View File

@ -16,9 +16,16 @@
package com.alibaba.nacos.client.naming.beat;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams;
import com.alibaba.nacos.api.naming.NamingResponseCode;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.Map;
import java.util.concurrent.*;
@ -34,7 +41,9 @@ public class BeatReactor {
private NamingProxy serverProxy;
public final Map<String, BeatInfo> dom2Beat = new ConcurrentHashMap<String, BeatInfo>();
private boolean lightBeatEnabled = false;
public final Map<String, BeatInfo> dom2Beat = new ConcurrentHashMap<>();
public BeatReactor(NamingProxy serverProxy) {
this(serverProxy, UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT);
@ -42,7 +51,6 @@ public class BeatReactor {
public BeatReactor(NamingProxy serverProxy, int threadCount) {
this.serverProxy = serverProxy;
executorService = new ScheduledThreadPoolExecutor(threadCount, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
@ -95,8 +103,43 @@ public class BeatReactor {
if (beatInfo.isStopped()) {
return;
}
long result = serverProxy.sendBeat(beatInfo);
long nextTime = result > 0 ? result : beatInfo.getPeriod();
long nextTime = beatInfo.getPeriod();
try {
JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
long interval = result.get("clientBeatInterval").asInt();
boolean lightBeatEnabled = false;
if (result.has(CommonParams.LIGHT_BEAT_ENABLED)) {
lightBeatEnabled = result.get(CommonParams.LIGHT_BEAT_ENABLED).asBoolean();
}
BeatReactor.this.lightBeatEnabled = lightBeatEnabled;
if (interval > 0) {
nextTime = interval;
}
int code = NamingResponseCode.OK;
if (result.has(CommonParams.CODE)) {
code = result.get(CommonParams.CODE).asInt();
}
if (code == NamingResponseCode.RESOURCE_NOT_FOUND) {
Instance instance = new Instance();
instance.setPort(beatInfo.getPort());
instance.setIp(beatInfo.getIp());
instance.setWeight(beatInfo.getWeight());
instance.setMetadata(beatInfo.getMetadata());
instance.setClusterName(beatInfo.getCluster());
instance.setServiceName(beatInfo.getServiceName());
instance.setInstanceId(instance.getInstanceId());
instance.setEphemeral(true);
try {
serverProxy.registerService(beatInfo.getServiceName(),
NamingUtils.getGroupName(beatInfo.getServiceName()), instance);
} catch (Exception ignore) {
}
}
} catch (NacosException ne) {
NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: {}, code: {}, msg: {}",
JacksonUtils.toJson(beatInfo), ne.getErrCode(), ne.getErrMsg());
}
executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
}
}

View File

@ -15,11 +15,12 @@
*/
package com.alibaba.nacos.client.naming.cache;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.JacksonUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.BufferedReader;
@ -58,7 +59,7 @@ public class DiskCache {
String json = dom.getJsonFromServer();
if (StringUtils.isEmpty(json)) {
json = JSON.toJSONString(dom);
json = JacksonUtils.toJson(dom);
}
keyContentBuffer.append(json);
@ -112,10 +113,10 @@ public class DiskCache {
continue;
}
newFormat = JSON.parseObject(json, ServiceInfo.class);
newFormat = JacksonUtils.toObj(json, ServiceInfo.class);
if (StringUtils.isEmpty(newFormat.getName())) {
ips.add(JSON.parseObject(json, Instance.class));
ips.add(JacksonUtils.toObj(json, Instance.class));
}
} catch (Throwable e) {
NAMING_LOGGER.error("[NA] error while parsing cache file: " + json, e);

View File

@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.client.naming.core;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
@ -24,6 +23,8 @@ import com.alibaba.nacos.client.naming.backups.FailoverReactor;
import com.alibaba.nacos.client.naming.cache.DiskCache;
import com.alibaba.nacos.client.naming.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.common.utils.JacksonUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
@ -98,7 +99,7 @@ public class HostReactor {
}
public ServiceInfo processServiceJSON(String json) {
ServiceInfo serviceInfo = JSON.parseObject(json, ServiceInfo.class);
ServiceInfo serviceInfo = JacksonUtils.toObj(json, ServiceInfo.class);
ServiceInfo oldService = serviceInfoMap.get(serviceInfo.getKey());
if (serviceInfo.getHosts() == null || !serviceInfo.validate()) {
//empty or error push, just ignore
@ -162,19 +163,19 @@ public class HostReactor {
if (newHosts.size() > 0) {
changed = true;
NAMING_LOGGER.info("new ips(" + newHosts.size() + ") service: "
+ serviceInfo.getKey() + " -> " + JSON.toJSONString(newHosts));
+ serviceInfo.getKey() + " -> " + JacksonUtils.toJson(newHosts));
}
if (remvHosts.size() > 0) {
changed = true;
NAMING_LOGGER.info("removed ips(" + remvHosts.size() + ") service: "
+ serviceInfo.getKey() + " -> " + JSON.toJSONString(remvHosts));
+ serviceInfo.getKey() + " -> " + JacksonUtils.toJson(remvHosts));
}
if (modHosts.size() > 0) {
changed = true;
NAMING_LOGGER.info("modified ips(" + modHosts.size() + ") service: "
+ serviceInfo.getKey() + " -> " + JSON.toJSONString(modHosts));
+ serviceInfo.getKey() + " -> " + JacksonUtils.toJson(modHosts));
}
serviceInfo.setJsonFromServer(json);
@ -186,8 +187,8 @@ public class HostReactor {
} else {
changed = true;
NAMING_LOGGER.info("init new ips(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() + " -> " + JSON
.toJSONString(serviceInfo.getHosts()));
NAMING_LOGGER.info("init new ips(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() + " -> " +
JacksonUtils.toJson(serviceInfo.getHosts()));
serviceInfoMap.put(serviceInfo.getKey(), serviceInfo);
eventDispatcher.serviceChanged(serviceInfo);
serviceInfo.setJsonFromServer(json);
@ -198,7 +199,7 @@ public class HostReactor {
if (changed) {
NAMING_LOGGER.info("current ips:(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() +
" -> " + JSON.toJSONString(serviceInfo.getHosts()));
" -> " + JacksonUtils.toJson(serviceInfo.getHosts()));
}
return serviceInfo;
@ -214,7 +215,7 @@ public class HostReactor {
public ServiceInfo getServiceInfoDirectlyFromServer(final String serviceName, final String clusters) throws NacosException {
String result = serverProxy.queryList(serviceName, clusters, 0, false);
if (StringUtils.isNotEmpty(result)) {
return JSON.parseObject(result, ServiceInfo.class);
return JacksonUtils.toObj(result, ServiceInfo.class);
}
return null;
}
@ -314,12 +315,14 @@ public class HostReactor {
@Override
public void run() {
long delayTime = -1;
try {
ServiceInfo serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters));
if (serviceObj == null) {
updateServiceNow(serviceName, clusters);
executor.schedule(this, DEFAULT_DELAY, TimeUnit.MILLISECONDS);
delayTime = DEFAULT_DELAY;
return;
}
@ -341,11 +344,15 @@ public class HostReactor {
return;
}
executor.schedule(this, serviceObj.getCacheMillis(), TimeUnit.MILLISECONDS);
delayTime = serviceObj.getCacheMillis();
} catch (Throwable e) {
NAMING_LOGGER.warn("[NA] failed to update serviceName: " + serviceName, e);
} finally {
if (delayTime > 0) {
executor.schedule(this, delayTime, TimeUnit.MILLISECONDS);
}
}
}

View File

@ -15,9 +15,9 @@
*/
package com.alibaba.nacos.client.naming.core;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.client.utils.StringUtils;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
@ -75,7 +75,7 @@ public class PushReceiver implements Runnable {
String json = new String(IoUtils.tryDecompress(packet.getData()), "UTF-8").trim();
NAMING_LOGGER.info("received push data: " + json + " from " + packet.getAddress().toString());
PushPacket pushPacket = JSON.parseObject(json, PushPacket.class);
PushPacket pushPacket = JacksonUtils.toObj(json, PushPacket.class);
String ack;
if ("dom".equals(pushPacket.type) || "service".equals(pushPacket.type)) {
hostReactor.processServiceJSON(pushPacket.data);
@ -89,7 +89,7 @@ public class PushReceiver implements Runnable {
ack = "{\"type\": \"dump-ack\""
+ ", \"lastRefTime\": \"" + pushPacket.lastRefTime
+ "\", \"data\":" + "\""
+ StringUtils.escapeJavaScript(JSON.toJSONString(hostReactor.getServiceInfoMap()))
+ StringUtils.escapeJavaScript(JacksonUtils.toJson(hostReactor.getServiceInfoMap()))
+ "\"}";
} else {
// do nothing send ack only

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.client.naming.net;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.common.utils.HttpMethod;
import com.alibaba.nacos.common.utils.IoUtils;
import com.google.common.net.HttpHeaders;
import org.apache.commons.lang3.StringUtils;
@ -37,16 +38,13 @@ 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
.getBoolean("com.alibaba.nacos.client.naming.tls.enable");
private static final String POST = "POST";
private static final String PUT = "PUT";
static {
// limit max redirection
System.setProperty("http.maxRedirects", "5");
@ -62,10 +60,10 @@ public class HttpClient {
}
public static HttpResult httpGet(String url, List<String> headers, Map<String, String> paramValues, String encoding) {
return request(url, headers, paramValues, encoding, "GET");
return request(url, headers, paramValues, StringUtils.EMPTY, encoding, HttpMethod.GET);
}
public static HttpResult request(String url, List<String> headers, Map<String, String> paramValues, String encoding, String method) {
public static HttpResult request(String url, List<String> headers, Map<String, String> paramValues, String body, String encoding, String method) {
HttpURLConnection conn = null;
try {
String encodedContent = encodingParams(paramValues, encoding);
@ -75,19 +73,20 @@ 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 (POST.equals(method) || PUT.equals(method)) {
// fix: apache http nio framework must set some content to request body
byte[] b = encodedContent.getBytes();
if (StringUtils.isNotBlank(body)) {
byte[] b = body.getBytes();
conn.setRequestProperty("Content-Length", String.valueOf(b.length));
conn.getOutputStream().write(b, 0, b.length);
conn.getOutputStream().flush();
conn.getOutputStream().close();
}
conn.connect();
NAMING_LOGGER.debug("Request from server: " + url);
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER.debug("Request from server: " + url);
}
return getResult(conn);
} catch (Exception e) {
try {
@ -130,8 +129,14 @@ public class HttpClient {
if (encodingGzip.equals(respHeaders.get(HttpHeaders.CONTENT_ENCODING))) {
inputStream = new GZIPInputStream(inputStream);
}
return new HttpResult(respCode, IoUtils.toString(inputStream, getCharset(conn)), respHeaders);
HttpResult httpResult = new HttpResult(respCode, IoUtils.toString(inputStream, getCharset(conn)), respHeaders);
//InputStream from HttpURLConnection can be closed automatically,but new GZIPInputStream can't be closed automatically
//so needs to close it manually
if (inputStream instanceof GZIPInputStream) {
inputStream.close();
}
return httpResult;
}
private static String getCharset(HttpURLConnection conn) {
@ -208,5 +213,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

@ -15,11 +15,9 @@
*/
package com.alibaba.nacos.client.naming.net;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams;
import com.alibaba.nacos.api.naming.pojo.Instance;
@ -31,19 +29,29 @@ import com.alibaba.nacos.api.selector.SelectorType;
import com.alibaba.nacos.client.config.impl.SpasAdapter;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.beat.BeatInfo;
import com.alibaba.nacos.client.naming.utils.*;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.NetUtils;
import com.alibaba.nacos.client.naming.utils.SignUtil;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.client.security.SecurityProxy;
import com.alibaba.nacos.client.utils.AppNameUtils;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.common.constant.HttpHeaderConsts;
import com.alibaba.nacos.common.utils.HttpMethod;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.UuidUtils;
import com.alibaba.nacos.common.utils.VersionUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.*;
@ -68,14 +76,21 @@ public class NamingProxy {
private List<String> serversFromEndpoint = new ArrayList<String>();
private SecurityProxy securityProxy;
private long lastSrvRefTime = 0L;
private long vipSrvRefInterMillis = TimeUnit.SECONDS.toMillis(30);
private long securityInfoRefreshIntervalMills = TimeUnit.SECONDS.toMillis(5);
private Properties properties;
public NamingProxy(String namespaceId, String endpoint, String serverList) {
public NamingProxy(String namespaceId, String endpoint, String serverList, Properties properties) {
securityProxy = new SecurityProxy(properties);
this.properties = properties;
this.setServerPort(DEFAULT_SERVER_PORT);
this.namespaceId = namespaceId;
this.endpoint = endpoint;
if (StringUtils.isNotEmpty(serverList)) {
@ -85,19 +100,16 @@ public class NamingProxy {
}
}
initRefreshSrvIfNeed();
initRefreshTask();
}
private void initRefreshSrvIfNeed() {
if (StringUtils.isEmpty(endpoint)) {
return;
}
private void initRefreshTask() {
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(2, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.naming.serverlist.updater");
t.setName("com.alibaba.nacos.client.naming.updater");
t.setDaemon(true);
return t;
}
@ -110,7 +122,16 @@ public class NamingProxy {
}
}, 0, vipSrvRefInterMillis, TimeUnit.MILLISECONDS);
executorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
securityProxy.login(getServerList());
}
}, 0, securityInfoRefreshIntervalMills, TimeUnit.MILLISECONDS);
refreshSrvIfNeed();
securityProxy.login(getServerList());
}
public List<String> getServerListFromEndpoint() {
@ -187,7 +208,7 @@ public class NamingProxy {
params.put("enable", String.valueOf(instance.isEnabled()));
params.put("healthy", String.valueOf(instance.isHealthy()));
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
params.put("metadata", JSON.toJSONString(instance.getMetadata()));
params.put("metadata", JacksonUtils.toJson(instance.getMetadata()));
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.POST);
@ -223,7 +244,7 @@ public class NamingProxy {
params.put("weight", String.valueOf(instance.getWeight()));
params.put("enabled", String.valueOf(instance.isEnabled()));
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
params.put("metadata", JSON.toJSONString(instance.getMetadata()));
params.put("metadata", JacksonUtils.toJson(instance.getMetadata()));
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.PUT);
}
@ -238,8 +259,7 @@ public class NamingProxy {
params.put(CommonParams.GROUP_NAME, groupName);
String result = reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.GET);
JSONObject jsonObject = JSON.parseObject(result);
return jsonObject.toJavaObject(Service.class);
return JacksonUtils.toObj(result, Service.class);
}
public void createService(Service service, AbstractSelector selector) throws NacosException {
@ -252,8 +272,8 @@ public class NamingProxy {
params.put(CommonParams.SERVICE_NAME, service.getName());
params.put(CommonParams.GROUP_NAME, service.getGroupName());
params.put("protectThreshold", String.valueOf(service.getProtectThreshold()));
params.put("metadata", JSON.toJSONString(service.getMetadata()));
params.put("selector", JSON.toJSONString(selector));
params.put("metadata", JacksonUtils.toJson(service.getMetadata()));
params.put("selector", JacksonUtils.toJson(selector));
reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.POST);
@ -281,8 +301,8 @@ public class NamingProxy {
params.put(CommonParams.SERVICE_NAME, service.getName());
params.put(CommonParams.GROUP_NAME, service.getGroupName());
params.put("protectThreshold", String.valueOf(service.getProtectThreshold()));
params.put("metadata", JSON.toJSONString(service.getMetadata()));
params.put("selector", JSON.toJSONString(selector));
params.put("metadata", JacksonUtils.toJson(service.getMetadata()));
params.put("selector", JacksonUtils.toJson(selector));
reqAPI(UtilAndComs.NACOS_URL_SERVICE, params, HttpMethod.PUT);
}
@ -301,33 +321,36 @@ public class NamingProxy {
return reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/list", params, HttpMethod.GET);
}
public long sendBeat(BeatInfo beatInfo) {
try {
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER.debug("[BEAT] {} sending beat to server: {}", namespaceId, beatInfo.toString());
}
Map<String, String> params = new HashMap<String, String>(4);
params.put("beat", JSON.toJSONString(beatInfo));
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, beatInfo.getServiceName());
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/beat", params, HttpMethod.PUT);
JSONObject jsonObject = JSON.parseObject(result);
public JsonNode sendBeat(BeatInfo beatInfo, boolean lightBeatEnabled) throws NacosException {
if (jsonObject != null) {
return jsonObject.getLong("clientBeatInterval");
}
} catch (Exception e) {
NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: " + JSON.toJSONString(beatInfo), e);
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER.debug("[BEAT] {} sending beat to server: {}", namespaceId, beatInfo.toString());
}
return 0L;
Map<String, String> params = new HashMap<String, String>(8);
String body = StringUtils.EMPTY;
if (!lightBeatEnabled) {
try {
body = "beat=" + URLEncoder.encode(JacksonUtils.toJson(beatInfo), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new NacosException(NacosException.SERVER_ERROR, "encode beatInfo error", e);
}
}
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, beatInfo.getServiceName());
params.put(CommonParams.CLUSTER_NAME, beatInfo.getCluster());
params.put("ip", beatInfo.getIp());
params.put("port", String.valueOf(beatInfo.getPort()));
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/beat", params, body, HttpMethod.PUT);
return JacksonUtils.toObj(result);
}
public boolean serverHealthy() {
try {
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/operator/metrics", new HashMap<String, String>(2));
JSONObject json = JSON.parseObject(result);
String serverStatus = json.getString("status");
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/operator/metrics",
new HashMap<String, String>(2), HttpMethod.GET);
JsonNode json = JacksonUtils.toObj(result);
String serverStatus = json.get("status").asText();
return "UP".equals(serverStatus);
} catch (Exception e) {
return false;
@ -352,53 +375,48 @@ public class NamingProxy {
break;
case label:
ExpressionSelector expressionSelector = (ExpressionSelector) selector;
params.put("selector", JSON.toJSONString(expressionSelector));
params.put("selector", JacksonUtils.toJson(expressionSelector));
break;
default:
break;
}
}
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/service/list", params);
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/service/list", params, HttpMethod.GET);
JSONObject json = JSON.parseObject(result);
ListView<String> listView = new ListView<String>();
listView.setCount(json.getInteger("count"));
listView.setData(JSON.parseObject(json.getString("doms"), new TypeReference<List<String>>() {
}));
JsonNode json = JacksonUtils.toObj(result);
ListView<String> listView = new ListView<>();
listView.setCount(json.get("count").asInt());
listView.setData(JacksonUtils.toObj(json.get("doms").toString(), new TypeReference<List<String>>() {}));
return listView;
}
public String reqAPI(String api, Map<String, String> params) throws NacosException {
List<String> snapshot = serversFromEndpoint;
if (!CollectionUtils.isEmpty(serverList)) {
snapshot = serverList;
}
return reqAPI(api, params, snapshot);
}
public String reqAPI(String api, Map<String, String> params, String method) throws NacosException {
return reqAPI(api, params, StringUtils.EMPTY, method);
}
public String reqAPI(String api, Map<String, String> params, String body, String method) throws NacosException {
return reqAPI(api, params, body, getServerList(), method);
}
private List<String> getServerList() {
List<String> snapshot = serversFromEndpoint;
if (!CollectionUtils.isEmpty(serverList)) {
snapshot = serverList;
}
return reqAPI(api, params, snapshot, method);
return snapshot;
}
public String callServer(String api, Map<String, String> params, String curServer) throws NacosException {
return callServer(api, params, curServer, HttpMethod.GET);
public String callServer(String api, Map<String, String> params, String body, String curServer) throws NacosException {
return callServer(api, params, body, curServer, HttpMethod.GET);
}
public String callServer(String api, Map<String, String> params, String curServer, String method)
public String callServer(String api, Map<String, String> params, String body, String curServer, String method)
throws NacosException {
long start = System.currentTimeMillis();
long end = 0;
checkSignature(params);
injectSecurityInfo(params);
List<String> headers = builderHeaders();
String url;
@ -411,7 +429,7 @@ public class NamingProxy {
url = HttpClient.getPrefix() + curServer + api;
}
HttpClient.HttpResult result = HttpClient.request(url, headers, params, UtilAndComs.ENCODING, method);
HttpClient.HttpResult result = HttpClient.request(url, headers, params, body, UtilAndComs.ENCODING, method);
end = System.currentTimeMillis();
MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(result.code))
@ -425,16 +443,10 @@ public class NamingProxy {
return StringUtils.EMPTY;
}
throw new NacosException(NacosException.SERVER_ERROR, "failed to req API:"
+ curServer + api + ". code:"
+ result.code + " msg: " + result.content);
throw new NacosException(result.code, result.content);
}
public String reqAPI(String api, Map<String, String> params, List<String> servers) throws NacosException {
return reqAPI(api, params, servers, HttpMethod.GET);
}
public String reqAPI(String api, Map<String, String> params, List<String> servers, String method) throws NacosException {
public String reqAPI(String api, Map<String, String> params, String body, List<String> servers, String method) throws NacosException {
params.put(CommonParams.NAMESPACE_ID, getNamespaceId());
@ -442,7 +454,7 @@ public class NamingProxy {
throw new NacosException(NacosException.INVALID_PARAM, "no server available");
}
Exception exception = new Exception();
NacosException exception = new NacosException();
if (servers != null && !servers.isEmpty()) {
@ -452,52 +464,59 @@ public class NamingProxy {
for (int i = 0; i < servers.size(); i++) {
String server = servers.get(index);
try {
return callServer(api, params, server, method);
return callServer(api, params, body, server, method);
} catch (NacosException e) {
exception = e;
NAMING_LOGGER.error("request {} failed.", server, e);
} catch (Exception e) {
exception = e;
NAMING_LOGGER.error("request {} failed.", server, e);
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER.debug("request {} failed.", server, e);
}
}
index = (index + 1) % servers.size();
}
throw new NacosException(NacosException.SERVER_ERROR, "failed to req API:" + api + " after all servers(" + servers + ") tried: "
+ exception.getMessage());
}
for (int i = 0; i < UtilAndComs.REQUEST_DOMAIN_RETRY_COUNT; i++) {
try {
return callServer(api, params, nacosDomain);
} catch (Exception e) {
exception = e;
NAMING_LOGGER.error("[NA] req api:" + api + " failed, server(" + nacosDomain, e);
if (StringUtils.isNotBlank(nacosDomain)) {
for (int i = 0; i < UtilAndComs.REQUEST_DOMAIN_RETRY_COUNT; i++) {
try {
return callServer(api, params, body, nacosDomain, method);
} catch (NacosException e) {
exception = e;
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER.debug("request {} failed.", nacosDomain, e);
}
}
}
}
throw new NacosException(NacosException.SERVER_ERROR, "failed to req API:/api/" + api + " after all servers(" + servers + ") tried: "
NAMING_LOGGER.error("request: {} failed, servers: {}, code: {}, msg: {}",
api, servers, exception.getErrCode(), exception.getErrMsg());
throw new NacosException(exception.getErrCode(), "failed to req API:" + api + " after all servers(" + servers + ") tried: "
+ exception.getMessage());
}
private void checkSignature(Map<String, String> params) {
private void injectSecurityInfo(Map<String, String> params) {
// Inject token if exist:
if (StringUtils.isNotBlank(securityProxy.getAccessToken())) {
params.put(Constants.ACCESS_TOKEN, securityProxy.getAccessToken());
}
// Inject ak/sk if exist:
String ak = getAccessKey();
String sk = getSecretKey();
params.put("app", AppNameUtils.getAppName());
if (StringUtils.isEmpty(ak) && StringUtils.isEmpty(sk)) {
return;
}
try {
String signData = getSignData(params.get("serviceName"));
String signature = SignUtil.sign(signData, sk);
params.put("signature", signature);
params.put("data", signData);
params.put("ak", ak);
} catch (Exception e) {
e.printStackTrace();
if (StringUtils.isNotBlank(ak) && StringUtils.isNotBlank(sk)) {
try {
String signData = getSignData(params.get("serviceName"));
String signature = SignUtil.sign(signData, sk);
params.put("signature", signature);
params.put("data", signData);
params.put("ak", ak);
} catch (Exception e) {
NAMING_LOGGER.error("inject ak/sk failed.", e);
}
}
}
@ -563,6 +582,6 @@ public class NamingProxy {
this.serverPort = Integer.parseInt(sp);
}
}
}

View File

@ -20,7 +20,7 @@ import java.util.Arrays;
import java.util.List;
/**
* @author nkorange
* @author alibaba
*/
public class Chooser<K, T> {

View File

@ -19,7 +19,12 @@ package com.alibaba.nacos.client.naming.utils;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.selector.ExpressionSelector;
import com.alibaba.nacos.api.selector.NoneSelector;
import com.alibaba.nacos.api.selector.SelectorType;
import com.alibaba.nacos.client.utils.*;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import java.util.Properties;
import java.util.concurrent.Callable;
@ -150,4 +155,21 @@ public class InitUtils {
return endpointUrl + ":" + endpointPort;
}
/**
* Register subType for serialization
*
* Now these subType implementation class has registered in static code.
* But there are some problem for classloader. The implementation class
* will be loaded when they are used, which will make deserialize
* before register.
*
* 子类实现类中的静态代码串中已经向Jackson进行了注册但是由于classloader的原因只有当
* 该子类被使用的时候才会加载该类这可能会导致Jackson先进性反序列化再注册子类从而导致
* 反序列化失败
*/
public static void initSerialization() {
// TODO register in implementation class or remove subType
JacksonUtils.registerSubtype(NoneSelector.class, SelectorType.none.name());
JacksonUtils.registerSubtype(ExpressionSelector.class, SelectorType.label.name());
}
}

View File

@ -0,0 +1,142 @@
/*
* 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.security;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.naming.net.HttpClient;
import com.alibaba.nacos.common.utils.HttpMethod;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.HttpURLConnection;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* Security proxy to update security information
*
* @author nkorange
* @since 1.2.0
*/
public class SecurityProxy {
private static final Logger SECURITY_LOGGER = LoggerFactory.getLogger(SecurityProxy.class);
private static final String LOGIN_URL = "/v1/auth/users/login";
private String contextPath;
/**
* User's name
*/
private String username;
/**
* User's password
*/
private String password;
/**
* A token to take with when sending request to Nacos server
*/
private String accessToken;
/**
* TTL of token in seconds
*/
private long tokenTtl;
/**
* Last timestamp refresh security info from server
*/
private long lastRefreshTime;
/**
* time window to refresh security info in seconds
*/
private long tokenRefreshWindow;
/**
* Construct from properties, keeping flexibility
*
* @param properties a bunch of properties to read
*/
public SecurityProxy(Properties properties) {
username = properties.getProperty(PropertyKeyConst.USERNAME, StringUtils.EMPTY);
password = properties.getProperty(PropertyKeyConst.PASSWORD, StringUtils.EMPTY);
contextPath = properties.getProperty(PropertyKeyConst.CONTEXT_PATH, "/nacos");
contextPath = contextPath.startsWith("/") ? contextPath : "/" + contextPath;
}
public boolean login(List<String> servers) {
try {
if ((System.currentTimeMillis() - lastRefreshTime) < TimeUnit.SECONDS.toMillis(tokenTtl - tokenRefreshWindow)) {
return true;
}
for (String server : servers) {
if (login(server)) {
lastRefreshTime = System.currentTimeMillis();
return true;
}
}
} catch (Throwable ignore) {
}
return false;
}
public boolean login(String server) {
if (StringUtils.isNotBlank(username)) {
Map<String, String> params = new HashMap<String, String>(2);
params.put("username", username);
String body = "password=" + password;
String url = "http://" + server + contextPath + LOGIN_URL;
if (server.contains(Constants.HTTP_PREFIX)) {
url = server + contextPath + LOGIN_URL;
}
HttpClient.HttpResult result = HttpClient.request(url, new ArrayList<String>(2),
params, body, Charsets.UTF_8.name(), HttpMethod.POST);
if (result.code != HttpURLConnection.HTTP_OK) {
SECURITY_LOGGER.error("login failed: {}", JacksonUtils.toJson(result));
return false;
}
JsonNode obj = JacksonUtils.toObj(result.content);
if (obj.has(Constants.ACCESS_TOKEN)) {
accessToken = obj.get(Constants.ACCESS_TOKEN).asText();
tokenTtl = obj.get(Constants.TOKEN_TTL).asInt();
tokenRefreshWindow = tokenTtl / 10;
}
}
return true;
}
public String getAccessToken() {
return accessToken;
}
}

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

@ -1,51 +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.utils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* Json tool
*
* @author Nacos
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class JSONUtils {
private static ObjectMapper mapper = new ObjectMapper();
static {
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
public static String serializeObject(Object o) throws IOException {
return mapper.writeValueAsString(o);
}
public static Object deserializeObject(String s, Class<?> clazz) throws IOException {
return mapper.readValue(s, clazz);
}
public static <T> T deserializeObject(String s, TypeReference<T> typeReference)
throws IOException {
return mapper.readValue(s, typeReference);
}
}

View File

@ -16,8 +16,11 @@
package com.alibaba.nacos.client.utils;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient;
import org.slf4j.Logger;
import org.apache.commons.lang3.StringUtils;
import java.io.InputStream;
import java.util.Properties;
@ -152,6 +155,36 @@ public class ParamUtil {
ParamUtil.defaultNodesPath = defaultNodesPath;
}
public static String parseNamespace(Properties properties) {
String namespaceTmp = null;
String isUseCloudNamespaceParsing =
properties.getProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
System.getProperty(SystemPropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
String.valueOf(Constants.DEFAULT_USE_CLOUD_NAMESPACE_PARSING)));
if (Boolean.parseBoolean(isUseCloudNamespaceParsing)) {
namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, new Callable<String>() {
@Override
public String call() {
return TenantUtil.getUserTenantForAcm();
}
});
namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, new Callable<String>() {
@Override
public String call() {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
return StringUtils.isNotBlank(namespace) ? namespace : StringUtils.EMPTY;
}
});
}
if (StringUtils.isBlank(namespaceTmp)) {
namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE);
}
return StringUtils.isNotBlank(namespaceTmp) ? namespaceTmp.trim() : StringUtils.EMPTY;
}
public static String parsingEndpointRule(String endpointUrl) {
// 配置文件中输入的话 ENV 中的优先

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

@ -1,5 +1,6 @@
package com.alibaba.nacos.client;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.naming.beat.BeatInfo;
import com.alibaba.nacos.client.naming.beat.BeatReactor;
import com.alibaba.nacos.client.naming.net.NamingProxy;
@ -7,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;
@ -24,7 +24,7 @@ public class BeatReactorTest {
private NamingProxy namingProxy;
@Test
public void test() throws NoSuchFieldException, IllegalAccessException, InterruptedException {
public void test() throws NoSuchFieldException, IllegalAccessException, InterruptedException, NacosException {
BeatReactor beatReactor = new BeatReactor(namingProxy);
BeatInfo beatInfo = new BeatInfo();
@ -37,7 +37,6 @@ public class BeatReactorTest {
beatInfo.setScheduled(false);
beatInfo.setPeriod(1000L);
Mockito.doReturn(0L).when(namingProxy).sendBeat(beatInfo);
beatReactor.addBeatInfo("testService", beatInfo);
Assert.assertEquals(1, getActiveThread(beatReactor));

View File

@ -0,0 +1,84 @@
/*
*
* 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.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.common.utils.ThreadUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.util.Objects;
import java.util.Properties;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@Ignore
public class ConfigTest {
private static ConfigService configService;
public static void main(String[] args) throws Exception {
before();
test();
}
public static void before() throws Exception {
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
configService = NacosFactory.createConfigService(properties);
}
public static void test() throws Exception {
final String dataId = "lessspring";
final String group = "lessspring";
final String content = "lessspring-" + System.currentTimeMillis();
boolean result = configService.publishConfig(dataId, group, content);
Assert.assertTrue(result);
ThreadUtils.sleep(10_000);
String response = configService.getConfigAndSignListener(dataId, group, 5000, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
System.err.println(configInfo);
}
});
Assert.assertEquals(content, response);
Scanner scanner = new Scanner(System.in);
System.out.println("input content");
while (scanner.hasNextLine()){
String s = scanner.next();
if (Objects.equals("exit", s)) {
scanner.close();
return;
}
configService.publishConfig(dataId, group, s);
}
}
}

View File

@ -19,32 +19,34 @@ 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();
properties.put(PropertyKeyConst.SERVER_ADDR, "11.160.165.126:8848");
properties.put(PropertyKeyConst.NAMESPACE, "t1");
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
properties.put(PropertyKeyConst.USERNAME, "nacos");
properties.put(PropertyKeyConst.PASSWORD, "nacos");
NamingService namingService = NacosFactory.createNamingService(properties);
Instance instance = new Instance();
instance.setIp("1.1.1.1");
instance.setPort(80);
instance.setPort(800);
instance.setWeight(2);
Map<String, String> map = new HashMap<String, String>();
map.put("netType", "external");
@ -53,11 +55,17 @@ 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);
Thread.sleep(1000000000L);
}

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 org.junit.Assert.*;
import static com.alibaba.nacos.client.utils.StringUtils.*;
@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

@ -0,0 +1,39 @@
/*
* 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.listener.impl;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.client.config.impl.ConfigChangeHandler;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.util.Map;
public class ConfigChangeHandlerTest {
@Test
public void testParseProperties() throws IOException {
Map properties = ConfigChangeHandler.getInstance().parseChangeData("", "app.name = nacos", "properties");
Assert.assertEquals("nacos", ((ConfigChangeItem)properties.get("app.name")).getNewValue());
}
@Test
public void testParseYaml() throws IOException {
Map properties = ConfigChangeHandler.getInstance().parseChangeData("", "app:\n name: nacos", "yaml");
Assert.assertEquals("nacos", ((ConfigChangeItem)properties.get("app.name")).getNewValue());
}
}

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.client.config.listener.impl;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.client.config.impl.PropertiesChangeParser;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.util.Map;
public class PropertiesChangeParserTest {
private PropertiesChangeParser parser = new PropertiesChangeParser();
private final String type = "properties";
@Test
public void testType() {
Assert.assertEquals(true, parser.isResponsibleFor(type));
}
@Test
public void testAddKey() throws IOException {
Map<String, ConfigChangeItem> map = parser.doParse("", "app.name = nacos", type);
Assert.assertEquals(null, map.get("app.name").getOldValue());
Assert.assertEquals("nacos", map.get("app.name").getNewValue());
}
@Test
public void testRemoveKey() throws IOException {
Map<String, ConfigChangeItem> map = parser.doParse("app.name = nacos", "", type);
Assert.assertEquals("nacos", map.get("app.name").getOldValue());
Assert.assertEquals(null, map.get("app.name").getNewValue());
}
@Test
public void testModifyKey() throws IOException {
Map<String, ConfigChangeItem> map = parser.doParse("app.name = rocketMQ", "app.name = nacos", type);
Assert.assertEquals("rocketMQ", map.get("app.name").getOldValue());
Assert.assertEquals("nacos", map.get("app.name").getNewValue());
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.listener.impl;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.client.config.impl.YmlChangeParser;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.util.Map;
public class YmlChangeParserTest {
private YmlChangeParser parser = new YmlChangeParser();
private final String type = "yaml";
@Test
public void testType() {
Assert.assertEquals(true, parser.isResponsibleFor(type));
}
@Test
public void testAddKey() throws IOException {
Map<String, ConfigChangeItem> map = parser.doParse("", "app:\n name: nacos", type);
Assert.assertEquals(null, map.get("app.name").getOldValue());
Assert.assertEquals("nacos", map.get("app.name").getNewValue());
}
@Test
public void testRemoveKey() throws IOException {
Map<String, ConfigChangeItem> map = parser.doParse("app:\n name: nacos", "", type);
Assert.assertEquals("nacos", map.get("app.name").getOldValue());
Assert.assertEquals(null, map.get("app.name").getNewValue());
}
@Test
public void testModifyKey() throws IOException {
Map<String, ConfigChangeItem> map = parser.doParse("app:\n name: rocketMQ", "app:\n name: nacos", type);
Assert.assertEquals("rocketMQ", map.get("app.name").getOldValue());
Assert.assertEquals("nacos", map.get("app.name").getNewValue());
}
}

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,95 @@
/*
* 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.naming.cache;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
public class DiskCacheTest {
private static final String CACHE_DIR = DiskCacheTest.class.getResource("/").getPath() + "cache/";
private ServiceInfo serviceInfo;
private Instance instance;
@Before
public void setUp() throws Exception {
System.out.println(CACHE_DIR);
serviceInfo = new ServiceInfo("testName", "testClusters");
instance = new Instance();
instance.setClusterName("testClusters");
instance.setIp("1.1.1.1");
instance.setPort(1234);
instance.setServiceName("testName");
serviceInfo.setHosts(Collections.singletonList(instance));
}
@After
public void tearDown() {
File file = new File(CACHE_DIR);
if (file.exists() && file.list().length > 0) {
for (File each : file.listFiles()) {
each.delete();
}
}
}
@Test
public void testCache() {
DiskCache.write(serviceInfo, CACHE_DIR);
Map<String, ServiceInfo> actual = DiskCache.read(CACHE_DIR);
assertEquals(1, actual.size());
assertTrue(actual.containsKey(serviceInfo.getKeyEncoded()));
assertServiceInfo(actual.get(serviceInfo.getKeyEncoded()), serviceInfo);
}
private void assertServiceInfo(ServiceInfo actual, ServiceInfo expected) {
assertEquals(actual.getName(), expected.getName());
assertEquals(actual.getGroupName(), expected.getGroupName());
assertEquals(actual.getClusters(), expected.getClusters());
assertEquals(actual.getCacheMillis(), expected.getCacheMillis());
assertEquals(actual.getLastRefTime(), expected.getLastRefTime());
assertEquals(actual.getKey(), expected.getKey());
assertHosts(actual.getHosts(), expected.getHosts());
}
private void assertHosts(List<Instance> actual, List<Instance> expected) {
assertEquals(actual.size(), expected.size());
for (int i = 0; i < expected.size(); i++) {
assertInstance(actual.get(i), expected.get(i));
}
}
private void assertInstance(Instance actual, Instance expected) {
assertEquals(actual.getServiceName(), actual.getServiceName());
assertEquals(actual.getClusterName(), actual.getClusterName());
assertEquals(actual.getIp(), actual.getIp());
assertEquals(actual.getPort(), actual.getPort());
}
}

View File

@ -0,0 +1,108 @@
/*
* 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.naming.core;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.naming.net.NamingProxy;
@RunWith(MockitoJUnitRunner.class)
public class HostReactorTest {
private static final String CACHE_DIR = HostReactorTest.class.getResource("/").getPath() + "cache/";
@Mock
private NamingProxy namingProxy;
@Mock
private EventDispatcher eventDispatcher;
private HostReactor hostReactor;
@Before
public void setUp() throws Exception {
hostReactor = new HostReactor(eventDispatcher, namingProxy, CACHE_DIR);
}
@Test
public void testProcessServiceJSON() {
ServiceInfo actual = hostReactor.processServiceJSON(EXAMPLE);
assertServiceInfo(actual);
}
@Test
public void testGetServiceInfoDirectlyFromServer() throws NacosException {
when(namingProxy.queryList("testName", "testClusters", 0, false)).thenReturn(EXAMPLE);
ServiceInfo actual = hostReactor.getServiceInfoDirectlyFromServer("testName", "testClusters");
assertServiceInfo(actual);
}
private void assertServiceInfo(ServiceInfo actual) {
assertEquals("testName", actual.getName());
assertEquals("testClusters", actual.getClusters());
assertEquals("", actual.getChecksum());
assertEquals(1000, actual.getCacheMillis());
assertEquals(0, actual.getLastRefTime());
assertNull(actual.getGroupName());
assertTrue(actual.isValid());
assertFalse(actual.isAllIPs());
assertEquals(1, actual.getHosts().size());
assertInstance(actual.getHosts().get(0));
}
private void assertInstance(Instance actual) {
assertEquals("1.1.1.1", actual.getIp());
assertEquals("testClusters", actual.getClusterName());
assertEquals("testName", actual.getServiceName());
assertEquals(1234, actual.getPort());
}
private static final String EXAMPLE = "{\n"
+ "\t\"name\": \"testName\",\n"
+ "\t\"clusters\": \"testClusters\",\n"
+ "\t\"cacheMillis\": 1000,\n"
+ "\t\"hosts\": [{\n"
+ "\t\t\"ip\": \"1.1.1.1\",\n"
+ "\t\t\"port\": 1234,\n"
+ "\t\t\"weight\": 1.0,\n"
+ "\t\t\"healthy\": true,\n"
+ "\t\t\"enabled\": true,\n"
+ "\t\t\"ephemeral\": true,\n"
+ "\t\t\"clusterName\": \"testClusters\",\n"
+ "\t\t\"serviceName\": \"testName\",\n"
+ "\t\t\"metadata\": {},\n"
+ "\t\t\"instanceHeartBeatInterval\": 5000,\n"
+ "\t\t\"instanceHeartBeatTimeOut\": 15000,\n"
+ "\t\t\"ipDeleteTimeout\": 30000,\n"
+ "\t\t\"instanceIdGenerator\": \"simple\"\n"
+ "\t}],\n"
+ "\t\"lastRefTime\": 0,\n"
+ "\t\"checksum\": \"\",\n"
+ "\t\"allIPs\": false,\n"
+ "\t\"valid\": true\n"
+ "}";
}

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