commit
6709b0686d
3
.gitignore
vendored
3
.gitignore
vendored
@ -12,3 +12,6 @@ target
|
||||
node_modules
|
||||
test/derby.log
|
||||
derby.log
|
||||
work
|
||||
test/logs
|
||||
derby.log
|
||||
|
@ -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
|
||||
|
2
BUILDING
2
BUILDING
@ -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
|
||||
|
@ -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?
|
||||
|
10
README.md
10
README.md
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
12
api/pom.xml
12
api/pom.xml
@ -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>
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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";
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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;
|
||||
}
|
@ -144,4 +144,6 @@ public class NacosException extends Exception {
|
||||
*/
|
||||
public static final int OVER_THRESHOLD = 503;
|
||||
|
||||
public static final int RESOURCE_NOT_FOUND = -404;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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) {
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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()) {
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
||||
}
|
@ -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 + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() : ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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) {}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
*
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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";
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
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);
|
||||
}
|
||||
HttpResult httpResult = new HttpResult(respCode, IoUtils.toString(inputStream, getCharset(conn)), respHeaders);
|
||||
|
||||
return 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 + '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
public JsonNode sendBeat(BeatInfo beatInfo, boolean lightBeatEnabled) throws NacosException {
|
||||
|
||||
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));
|
||||
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());
|
||||
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/beat", params, HttpMethod.PUT);
|
||||
JSONObject jsonObject = JSON.parseObject(result);
|
||||
|
||||
if (jsonObject != null) {
|
||||
return jsonObject.getLong("clientBeatInterval");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: " + JSON.toJSONString(beatInfo), e);
|
||||
}
|
||||
return 0L;
|
||||
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,44 +464,50 @@ 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());
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(nacosDomain)) {
|
||||
for (int i = 0; i < UtilAndComs.REQUEST_DOMAIN_RETRY_COUNT; i++) {
|
||||
try {
|
||||
return callServer(api, params, nacosDomain);
|
||||
} catch (Exception e) {
|
||||
return callServer(api, params, body, nacosDomain, method);
|
||||
} catch (NacosException e) {
|
||||
exception = e;
|
||||
NAMING_LOGGER.error("[NA] req api:" + api + " failed, server(" + nacosDomain, 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;
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(ak) && StringUtils.isNotBlank(sk)) {
|
||||
try {
|
||||
String signData = getSignData(params.get("serviceName"));
|
||||
String signature = SignUtil.sign(signData, sk);
|
||||
@ -497,7 +515,8 @@ public class NamingProxy {
|
||||
params.put("data", signData);
|
||||
params.put("ak", ak);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
NAMING_LOGGER.error("inject ak/sk failed.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author nkorange
|
||||
* @author alibaba
|
||||
*/
|
||||
public class Chooser<K, T> {
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.io.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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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 中的优先,
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Tenant Util
|
||||
*
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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, ","));
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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}));
|
||||
}
|
||||
}
|
95
client/src/test/java/com/alibaba/nacos/client/naming/cache/DiskCacheTest.java
vendored
Normal file
95
client/src/test/java/com/alibaba/nacos/client/naming/cache/DiskCacheTest.java
vendored
Normal 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());
|
||||
}
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user