diff --git a/address/pom.xml b/address/pom.xml
index f97092c61f7..50643dd9d15 100644
--- a/address/pom.xml
+++ b/address/pom.xml
@@ -16,7 +16,7 @@
nacos-allcom.alibaba.nacos
- 1.3.0-BETA
+ 1.3.04.0.0
@@ -24,7 +24,7 @@
jarnacos-address ${project.version}
- http://maven.apache.org
+ http://nacos.ioUTF-8
@@ -56,13 +56,11 @@
org.mockitomockito-all
- 1.10.19testorg.hamcresthamcrest-all
- 1.3test
@@ -80,7 +78,6 @@
org.codehaus.mojofindbugs-maven-plugin
- 3.0.4
diff --git a/address/src/main/java/com/alibaba/nacos/address/controller/AddressServerClusterController.java b/address/src/main/java/com/alibaba/nacos/address/controller/AddressServerClusterController.java
index 347b792d811..c917201d25b 100644
--- a/address/src/main/java/com/alibaba/nacos/address/controller/AddressServerClusterController.java
+++ b/address/src/main/java/com/alibaba/nacos/address/controller/AddressServerClusterController.java
@@ -21,7 +21,7 @@
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;
diff --git a/api/pom.xml b/api/pom.xml
index 0349a81a05b..7cd60209eec 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -16,7 +16,7 @@
com.alibaba.nacosnacos-all
- 1.3.0-BETA
+ 1.3.04.0.0
@@ -25,7 +25,7 @@
jarnacos-api ${project.version}
- http://maven.apache.org
+ http://nacos.io
@@ -45,8 +45,12 @@
- com.alibaba
- fastjson
+ com.fasterxml.jackson.core
+ jackson-core
+
+
+ com.fasterxml.jackson.core
+ jackson-databindorg.apache.commons
diff --git a/api/src/main/java/com/alibaba/nacos/api/exception/runtime/NacosDeserializationException.java b/api/src/main/java/com/alibaba/nacos/api/exception/runtime/NacosDeserializationException.java
new file mode 100644
index 00000000000..77c423e87cd
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/exception/runtime/NacosDeserializationException.java
@@ -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;
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/exception/runtime/NacosRuntimeException.java b/api/src/main/java/com/alibaba/nacos/api/exception/runtime/NacosRuntimeException.java
new file mode 100644
index 00000000000..8f63c90d6ee
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/exception/runtime/NacosRuntimeException.java
@@ -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;
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/exception/runtime/NacosSerializationException.java b/api/src/main/java/com/alibaba/nacos/api/exception/runtime/NacosSerializationException.java
new file mode 100644
index 00000000000..b783ab27c08
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/exception/runtime/NacosSerializationException.java
@@ -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;
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/AbstractHealthChecker.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/AbstractHealthChecker.java
deleted file mode 100644
index 97259572b06..00000000000
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/AbstractHealthChecker.java
+++ /dev/null
@@ -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 getCustomHeaders() {
- if (StringUtils.isBlank(headers)) {
- return Collections.emptyMap();
- }
-
- Map headerMap = new HashMap(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);
- }
-}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java
index a571e0edb24..04a91c463d5 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java
@@ -18,6 +18,9 @@
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.
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Instance.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Instance.java
index ba6c7dd2c38..3d2c120e1df 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Instance.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Instance.java
@@ -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 @@
*
* @author nkorange
*/
+@JsonInclude(Include.NON_NULL)
public class Instance {
/**
@@ -173,7 +176,18 @@ public void setEphemeral(boolean ephemeral) {
@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() {
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ListView.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ListView.java
index 7df2672d390..a59a531e432 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ListView.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ListView.java
@@ -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 void setCount(int count) {
@Override
public String toString() {
- return JSON.toJSONString(this);
+ return "ListView{" +
+ "data=" + data +
+ ", count=" + count +
+ '}';
}
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java
index 98ea5cca406..0c13c52f2b7 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java
@@ -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 @@
*
* @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 hosts = new ArrayList();
private long lastRefTime = 0L;
@@ -162,7 +165,7 @@ public boolean validate() {
return true;
}
- @JSONField(serialize = false)
+ @JsonIgnore
public String getJsonFromServer() {
return jsonFromServer;
}
@@ -171,12 +174,12 @@ public void setJsonFromServer(String jsonFromServer) {
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 String getKeyEncoded() {
}
}
- @JSONField(serialize = false)
public static ServiceInfo fromKey(String key) {
ServiceInfo serviceInfo = new ServiceInfo();
int maxSegCount = 3;
@@ -201,7 +203,7 @@ public static ServiceInfo fromKey(String key) {
return serviceInfo;
}
- @JSONField(serialize = false)
+ @JsonIgnore
public static String getKey(String name, String clusters) {
if (!isEmpty(clusters)) {
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/AbstractHealthChecker.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/AbstractHealthChecker.java
new file mode 100644
index 00000000000..d74f8761130
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/AbstractHealthChecker.java
@@ -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();
+ }
+ }
+}
diff --git a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HealthCheckType.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/HealthCheckType.java
similarity index 50%
rename from naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HealthCheckType.java
rename to api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/HealthCheckType.java
index 025211a82a4..0d9e7313659 100644
--- a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HealthCheckType.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/HealthCheckType.java
@@ -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> EXTEND = new ConcurrentHashMap>();
- private static Map 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 static Class ofHealthCheckerClass(String type){
return enumType.healthCheckerClass;
}
- public static List getLoadedHealthCheckerClasses(){
- List all = new ArrayList<>();
+ public static List> getLoadedHealthCheckerClasses(){
+ List> all = new ArrayList>();
for(HealthCheckType type : values()){
all.add(type.healthCheckerClass);
}
- for(Map.Entry entry : EXTEND.entrySet()){
+ for(Map.Entry> entry : EXTEND.entrySet()){
all.add(entry.getValue());
}
return all;
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/HealthCheckerFactory.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/HealthCheckerFactory.java
new file mode 100644
index 00000000000..540cc3d7eba
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/HealthCheckerFactory.java
@@ -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);
+ }
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/Http.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/Http.java
new file mode 100644
index 00000000000..4b04ac6f92b
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/Http.java
@@ -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 getCustomHeaders() {
+ if (StringUtils.isBlank(headers)) {
+ return Collections.emptyMap();
+ }
+ Map headerMap = new HashMap(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;
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/Mysql.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/Mysql.java
new file mode 100644
index 00000000000..a9ddb381704
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/Mysql.java
@@ -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;
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/Tcp.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/Tcp.java
new file mode 100644
index 00000000000..a31f3598648
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/Tcp.java
@@ -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();
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/selector/AbstractSelector.java b/api/src/main/java/com/alibaba/nacos/api/selector/AbstractSelector.java
index 3c9fb579e95..8567ee7f654 100644
--- a/api/src/main/java/com/alibaba/nacos/api/selector/AbstractSelector.java
+++ b/api/src/main/java/com/alibaba/nacos/api/selector/AbstractSelector.java
@@ -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;
- public String getType() {
- return type;
+ protected AbstractSelector(String type) {
+ this.type = type;
}
- protected void setType(String type) {
- this.type = type;
+ public String getType() {
+ return type;
}
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/selector/ExpressionSelector.java b/api/src/main/java/com/alibaba/nacos/api/selector/ExpressionSelector.java
index 00c07980071..6bf5ac417d3 100644
--- a/api/src/main/java/com/alibaba/nacos/api/selector/ExpressionSelector.java
+++ b/api/src/main/java/com/alibaba/nacos/api/selector/ExpressionSelector.java
@@ -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() {
diff --git a/api/src/main/java/com/alibaba/nacos/api/selector/NoneSelector.java b/api/src/main/java/com/alibaba/nacos/api/selector/NoneSelector.java
index 1873007cc38..2444626f397 100644
--- a/api/src/main/java/com/alibaba/nacos/api/selector/NoneSelector.java
+++ b/api/src/main/java/com/alibaba/nacos/api/selector/NoneSelector.java
@@ -23,6 +23,6 @@
public class NoneSelector extends AbstractSelector {
public NoneSelector() {
- this.setType(SelectorType.none.name());
+ super(SelectorType.none.name());
}
}
diff --git a/api/src/test/java/com/alibaba/nacos/api/annotation/NacosPropertiesTest.java b/api/src/test/java/com/alibaba/nacos/api/annotation/NacosPropertiesTest.java
index a76c2585eeb..bdebc15f4e7 100644
--- a/api/src/test/java/com/alibaba/nacos/api/annotation/NacosPropertiesTest.java
+++ b/api/src/test/java/com/alibaba/nacos/api/annotation/NacosPropertiesTest.java
@@ -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;
diff --git a/api/src/test/java/com/alibaba/nacos/api/naming/pojo/ServiceInfoTest.java b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/ServiceInfoTest.java
new file mode 100644
index 00000000000..8c5d725e3e9
--- /dev/null
+++ b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/ServiceInfoTest.java
@@ -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());
+ }
+}
diff --git a/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/AbstractHealthCheckerTest.java b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/AbstractHealthCheckerTest.java
new file mode 100644
index 00000000000..627fcb37245
--- /dev/null
+++ b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/AbstractHealthCheckerTest.java
@@ -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());
+ }
+}
diff --git a/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/HealthCheckerFactoryTest.java b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/HealthCheckerFactoryTest.java
new file mode 100644
index 00000000000..551168e583d
--- /dev/null
+++ b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/HealthCheckerFactoryTest.java
@@ -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());
+ }
+}
diff --git a/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/TestChecker.java b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/TestChecker.java
new file mode 100644
index 00000000000..229270083b4
--- /dev/null
+++ b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/TestChecker.java
@@ -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;
+ }
+}
diff --git a/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/HttpTest.java b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/HttpTest.java
new file mode 100644
index 00000000000..b7711b5b9c8
--- /dev/null
+++ b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/HttpTest.java
@@ -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 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());
+ }
+}
diff --git a/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/MysqlTest.java b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/MysqlTest.java
new file mode 100644
index 00000000000..84a592206a5
--- /dev/null
+++ b/api/src/test/java/com/alibaba/nacos/api/naming/pojo/healthcheck/impl/MysqlTest.java
@@ -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());
+ }
+}
diff --git a/client/pom.xml b/client/pom.xml
index 3a7c3675095..49d845a1c1d 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -16,7 +16,7 @@
com.alibaba.nacosnacos-all
- 1.3.0-BETA
+ 1.3.0../pom.xml
@@ -26,7 +26,7 @@
jarnacos-client ${project.version}
- https://github.com/alibaba/nacos
+ http://nacos.ioUTF-8
@@ -109,7 +109,6 @@
io.prometheussimpleclient
- 0.5.0org.mockito
diff --git a/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java b/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java
index 4a042460ae2..05f036a7a0c 100644
--- a/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java
+++ b/client/src/main/java/com/alibaba/nacos/client/config/http/ServerHttpAgent.java
@@ -24,11 +24,11 @@
import com.alibaba.nacos.client.config.impl.SpasAdapter;
import com.alibaba.nacos.client.identify.STSConfig;
import com.alibaba.nacos.client.security.SecurityProxy;
-import com.alibaba.nacos.client.utils.JSONUtils;
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;
@@ -366,8 +366,7 @@ private STSCredential getSTSCredential() throws IOException {
}
}
String stsResponse = getSTSResponse();
- STSCredential stsCredentialTmp = JSONUtils.deserializeObject(stsResponse,
- new TypeReference() {
+ STSCredential stsCredentialTmp = JacksonUtils.toObj(stsResponse, new TypeReference() {
});
sTSCredential = stsCredentialTmp;
LOGGER.info("[getSTSCredential] code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}", sTSCredential.getCode(),
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingMaintainService.java b/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingMaintainService.java
index 9c7d5027f31..efc783f2d7c 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingMaintainService.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingMaintainService.java
@@ -61,6 +61,7 @@ public NacosNamingMaintainService(Properties 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, properties);
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingService.java b/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingService.java
index 6984e66fb9d..2ed85d280a4 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingService.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/NacosNamingService.java
@@ -34,7 +34,6 @@
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.InitUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
-import com.alibaba.nacos.client.security.SecurityProxy;
import com.alibaba.nacos.client.utils.ValidatorUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
@@ -44,7 +43,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
-import java.util.concurrent.TimeUnit;
/**
* Nacos Naming Service
@@ -88,6 +86,7 @@ public NacosNamingService(Properties properties) {
private void init(Properties properties) {
ValidatorUtils.checkInitParam(properties);
namespace = InitUtils.initNamespaceForNaming(properties);
+ InitUtils.initSerialization();
initServerAddr(properties);
InitUtils.initWebRootContext();
initCacheDir();
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/backups/FailoverReactor.java b/client/src/main/java/com/alibaba/nacos/client/naming/backups/FailoverReactor.java
index cdf4ff80f5f..d969259bdea 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/backups/FailoverReactor.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/backups/FailoverReactor.java
@@ -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 void run() {
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);
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatInfo.java b/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatInfo.java
index d405838f744..6edea9b78d0 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatInfo.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatInfo.java
@@ -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() {
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatReactor.java b/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatReactor.java
index c1ee4ed23d7..60fb52dc339 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatReactor.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/beat/BeatReactor.java
@@ -15,8 +15,6 @@
*/
package com.alibaba.nacos.client.naming.beat;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams;
@@ -26,6 +24,8 @@
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.*;
@@ -43,7 +43,7 @@ public class BeatReactor {
private boolean lightBeatEnabled = false;
- public final Map dom2Beat = new ConcurrentHashMap();
+ public final Map dom2Beat = new ConcurrentHashMap<>();
public BeatReactor(NamingProxy serverProxy) {
this(serverProxy, UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT);
@@ -105,19 +105,19 @@ public void run() {
}
long nextTime = beatInfo.getPeriod();
try {
- JSONObject result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
- long interval = result.getIntValue("clientBeatInterval");
+ JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
+ long interval = result.get("clientBeatInterval").asInt();
boolean lightBeatEnabled = false;
- if (result.containsKey(CommonParams.LIGHT_BEAT_ENABLED)) {
- lightBeatEnabled = result.getBooleanValue(CommonParams.LIGHT_BEAT_ENABLED);
+ 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.containsKey(CommonParams.CODE)) {
- code = result.getIntValue(CommonParams.CODE);
+ if (result.has(CommonParams.CODE)) {
+ code = result.get(CommonParams.CODE).asInt();
}
if (code == NamingResponseCode.RESOURCE_NOT_FOUND) {
Instance instance = new Instance();
@@ -137,7 +137,7 @@ public void run() {
}
} catch (NacosException ne) {
NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: {}, code: {}, msg: {}",
- JSON.toJSONString(beatInfo), ne.getErrCode(), ne.getErrMsg());
+ JacksonUtils.toJson(beatInfo), ne.getErrCode(), ne.getErrMsg());
}
executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/cache/DiskCache.java b/client/src/main/java/com/alibaba/nacos/client/naming/cache/DiskCache.java
index 691ad1f67cd..8211b90143f 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/cache/DiskCache.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/cache/DiskCache.java
@@ -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 static void write(ServiceInfo dom, String dir) {
String json = dom.getJsonFromServer();
if (StringUtils.isEmpty(json)) {
- json = JSON.toJSONString(dom);
+ json = JacksonUtils.toJson(dom);
}
keyContentBuffer.append(json);
@@ -112,10 +113,10 @@ public static Map read(String cacheDir) {
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);
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/core/HostReactor.java b/client/src/main/java/com/alibaba/nacos/client/naming/core/HostReactor.java
index 40f6ac58e4f..04d269d2a79 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/core/HostReactor.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/core/HostReactor.java
@@ -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.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 synchronized ScheduledFuture> addTask(UpdateTask task) {
}
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 ServiceInfo processServiceJSON(String json) {
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 ServiceInfo processServiceJSON(String json) {
} 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 ServiceInfo processServiceJSON(String json) {
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 @@ private ServiceInfo getServiceInfo0(String serviceName, String clusters) {
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;
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/core/PushReceiver.java b/client/src/main/java/com/alibaba/nacos/client/naming/core/PushReceiver.java
index 1222205e1a2..56a933eaceb 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/core/PushReceiver.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/core/PushReceiver.java
@@ -15,7 +15,7 @@
*/
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;
@@ -75,7 +75,7 @@ public void run() {
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 void run() {
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
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/net/HttpClient.java b/client/src/main/java/com/alibaba/nacos/client/naming/net/HttpClient.java
index 41d2cc78b53..06959be1574 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/net/HttpClient.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/net/HttpClient.java
@@ -129,8 +129,14 @@ private static HttpResult getResult(HttpURLConnection conn) throws IOException {
if (encodingGzip.equals(respHeaders.get(HttpHeaders.CONTENT_ENCODING))) {
inputStream = new GZIPInputStream(inputStream);
}
-
- return new HttpResult(respCode, IoUtils.toString(inputStream, getCharset(conn)), respHeaders);
+ HttpResult httpResult = new HttpResult(respCode, IoUtils.toString(inputStream, getCharset(conn)), respHeaders);
+
+ //InputStream from HttpURLConnection can be closed automatically,but new GZIPInputStream can't be closed automatically
+ //so needs to close it manually
+ if (inputStream instanceof GZIPInputStream) {
+ inputStream.close();
+ }
+ return httpResult;
}
private static String getCharset(HttpURLConnection conn) {
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java
index 7085a99a1e4..73554285d6e 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java
@@ -15,9 +15,6 @@
*/
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;
@@ -42,8 +39,12 @@
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;
@@ -207,7 +208,7 @@ public void registerService(String serviceName, String groupName, Instance insta
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);
@@ -243,7 +244,7 @@ public void updateInstance(String serviceName, String groupName, Instance instan
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);
}
@@ -258,8 +259,7 @@ public Service queryService(String serviceName, String groupName) throws NacosEx
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 {
@@ -272,8 +272,8 @@ public void createService(Service service, AbstractSelector selector) throws Nac
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);
@@ -301,8 +301,8 @@ public void updateService(Service service, AbstractSelector selector) throws Nac
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);
}
@@ -321,7 +321,7 @@ public String queryList(String serviceName, String clusters, int udpPort, boolea
return reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/list", params, HttpMethod.GET);
}
- public JSONObject sendBeat(BeatInfo beatInfo, boolean lightBeatEnabled) throws NacosException {
+ public JsonNode sendBeat(BeatInfo beatInfo, boolean lightBeatEnabled) throws NacosException {
if (NAMING_LOGGER.isDebugEnabled()) {
NAMING_LOGGER.debug("[BEAT] {} sending beat to server: {}", namespaceId, beatInfo.toString());
@@ -330,7 +330,7 @@ public JSONObject sendBeat(BeatInfo beatInfo, boolean lightBeatEnabled) throws N
String body = StringUtils.EMPTY;
if (!lightBeatEnabled) {
try {
- body = "beat=" + URLEncoder.encode(JSON.toJSONString(beatInfo), "UTF-8");
+ body = "beat=" + URLEncoder.encode(JacksonUtils.toJson(beatInfo), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new NacosException(NacosException.SERVER_ERROR, "encode beatInfo error", e);
}
@@ -341,7 +341,7 @@ public JSONObject sendBeat(BeatInfo beatInfo, boolean lightBeatEnabled) throws N
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 JSON.parseObject(result);
+ return JacksonUtils.toObj(result);
}
public boolean serverHealthy() {
@@ -349,8 +349,8 @@ public boolean serverHealthy() {
try {
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/operator/metrics",
new HashMap(2), HttpMethod.GET);
- JSONObject json = JSON.parseObject(result);
- String serverStatus = json.getString("status");
+ JsonNode json = JacksonUtils.toObj(result);
+ String serverStatus = json.get("status").asText();
return "UP".equals(serverStatus);
} catch (Exception e) {
return false;
@@ -375,7 +375,7 @@ public ListView getServiceList(int pageNo, int pageSize, String groupNam
break;
case label:
ExpressionSelector expressionSelector = (ExpressionSelector) selector;
- params.put("selector", JSON.toJSONString(expressionSelector));
+ params.put("selector", JacksonUtils.toJson(expressionSelector));
break;
default:
break;
@@ -384,11 +384,10 @@ public ListView getServiceList(int pageNo, int pageSize, String groupNam
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/service/list", params, HttpMethod.GET);
- JSONObject json = JSON.parseObject(result);
- ListView listView = new ListView();
- listView.setCount(json.getInteger("count"));
- listView.setData(JSON.parseObject(json.getString("doms"), new TypeReference>() {
- }));
+ JsonNode json = JacksonUtils.toObj(result);
+ ListView listView = new ListView<>();
+ listView.setCount(json.get("count").asInt());
+ listView.setData(JacksonUtils.toObj(json.get("doms").toString(), new TypeReference>() {}));
return listView;
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/utils/InitUtils.java b/client/src/main/java/com/alibaba/nacos/client/naming/utils/InitUtils.java
index 9002b3a27f7..dc869b761dc 100644
--- a/client/src/main/java/com/alibaba/nacos/client/naming/utils/InitUtils.java
+++ b/client/src/main/java/com/alibaba/nacos/client/naming/utils/InitUtils.java
@@ -19,7 +19,11 @@
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;
@@ -151,4 +155,21 @@ public String call() {
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());
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java b/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java
index f7ff7ed97a3..20662b94f41 100644
--- a/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java
+++ b/client/src/main/java/com/alibaba/nacos/client/security/SecurityProxy.java
@@ -15,13 +15,13 @@
*/
package com.alibaba.nacos.client.security;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
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;
@@ -122,14 +122,14 @@ public boolean login(String server) {
params, body, Charsets.UTF_8.name(), HttpMethod.POST);
if (result.code != HttpURLConnection.HTTP_OK) {
- SECURITY_LOGGER.error("login failed: {}", JSON.toJSONString(result));
+ SECURITY_LOGGER.error("login failed: {}", JacksonUtils.toJson(result));
return false;
}
- JSONObject obj = JSON.parseObject(result.content);
- if (obj.containsKey(Constants.ACCESS_TOKEN)) {
- accessToken = obj.getString(Constants.ACCESS_TOKEN);
- tokenTtl = obj.getIntValue(Constants.TOKEN_TTL);
+ 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;
}
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/utils/JSONUtils.java b/client/src/main/java/com/alibaba/nacos/client/utils/JSONUtils.java
deleted file mode 100644
index fa91b0d23a8..00000000000
--- a/client/src/main/java/com/alibaba/nacos/client/utils/JSONUtils.java
+++ /dev/null
@@ -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 deserializeObject(String s, TypeReference typeReference)
- throws IOException {
- return mapper.readValue(s, typeReference);
- }
-
-}
diff --git a/client/src/test/java/com/alibaba/nacos/client/ConfigTest.java b/client/src/test/java/com/alibaba/nacos/client/ConfigTest.java
index 0a0ca4b7a18..cc65e123775 100644
--- a/client/src/test/java/com/alibaba/nacos/client/ConfigTest.java
+++ b/client/src/test/java/com/alibaba/nacos/client/ConfigTest.java
@@ -1,18 +1,18 @@
/*
*
- * * 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.
+ * 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.
*
*/
@@ -21,13 +21,17 @@
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 liaochuntao
@@ -35,20 +39,20 @@
@Ignore
public class ConfigTest {
- private ConfigService configService;
+ private static ConfigService configService;
- @Before
- public void before() throws Exception {
+ public static void main(String[] args) throws Exception {
+ before();
+ test();
+ }
+
+ public static void before() throws Exception {
Properties properties = new Properties();
- properties.setProperty(PropertyKeyConst.NAMESPACE, "bebf0150-e1ea-47e2-81fe-6814caf2b952");
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");
- properties.setProperty(PropertyKeyConst.USERNAME, "chuntaojun");
- properties.setProperty(PropertyKeyConst.PASSWORD, "1017");
configService = NacosFactory.createConfigService(properties);
}
- @Test
- public void test() throws Exception {
+ public static void test() throws Exception {
final String dataId = "lessspring";
final String group = "lessspring";
final String content = "lessspring-" + System.currentTimeMillis();
@@ -56,8 +60,25 @@ public void test() throws Exception {
Assert.assertTrue(result);
ThreadUtils.sleep(10_000);
- String response = configService.getConfig(dataId, group, 5000);
- System.out.println(response);
+
+ 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);
+ }
}
}
diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/cache/DiskCacheTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/cache/DiskCacheTest.java
new file mode 100644
index 00000000000..f624669eebf
--- /dev/null
+++ b/client/src/test/java/com/alibaba/nacos/client/naming/cache/DiskCacheTest.java
@@ -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 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 actual, List 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());
+ }
+}
diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/core/HostReactorTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/core/HostReactorTest.java
new file mode 100644
index 00000000000..2462a32b3a8
--- /dev/null
+++ b/client/src/test/java/com/alibaba/nacos/client/naming/core/HostReactorTest.java
@@ -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"
+ + "}";
+}
diff --git a/client/src/test/java/com/alibaba/nacos/client/security/SecurityProxyTest.java b/client/src/test/java/com/alibaba/nacos/client/security/SecurityProxyTest.java
new file mode 100644
index 00000000000..21ec29ddcfb
--- /dev/null
+++ b/client/src/test/java/com/alibaba/nacos/client/security/SecurityProxyTest.java
@@ -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.client.security;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+import com.alibaba.nacos.api.common.Constants;
+import com.alibaba.nacos.common.utils.JacksonUtils;
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class SecurityProxyTest {
+
+ /**
+ * Just test for replace fastjson with jackson.
+ *
+ */
+ @Test
+ public void testLogin() {
+ String example = "{\"accessToken\":\"ttttttttttttttttt\",\"tokenTtl\":1000}";
+ JsonNode obj = JacksonUtils.toObj(example);
+ if (obj.has(Constants.ACCESS_TOKEN)) {
+ if (obj.has(Constants.ACCESS_TOKEN)) {
+ assertEquals("ttttttttttttttttt", obj.get(Constants.ACCESS_TOKEN).asText());
+ assertEquals(1000, obj.get(Constants.TOKEN_TTL).asInt());
+ }
+ }
+ }
+}
diff --git a/cmdb/pom.xml b/cmdb/pom.xml
index e2873195f6a..09f1b9eec78 100644
--- a/cmdb/pom.xml
+++ b/cmdb/pom.xml
@@ -18,7 +18,7 @@
nacos-allcom.alibaba.nacos
- 1.3.0-BETA
+ 1.3.0../pom.xml4.0.0
@@ -27,8 +27,7 @@
jarnacos-cmdb ${project.version}
-
- http://www.example.com
+ http://nacos.ioUTF-8
diff --git a/cmdb/src/main/java/com/alibaba/nacos/cmdb/memory/CmdbProvider.java b/cmdb/src/main/java/com/alibaba/nacos/cmdb/memory/CmdbProvider.java
index b75a59e1772..c796bf2258b 100644
--- a/cmdb/src/main/java/com/alibaba/nacos/cmdb/memory/CmdbProvider.java
+++ b/cmdb/src/main/java/com/alibaba/nacos/cmdb/memory/CmdbProvider.java
@@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.cmdb.memory;
-import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.cmdb.spi.CmdbService;
import com.alibaba.nacos.api.cmdb.pojo.Entity;
import com.alibaba.nacos.api.cmdb.pojo.EntityEvent;
@@ -26,6 +25,8 @@
import com.alibaba.nacos.cmdb.service.CmdbWriter;
import com.alibaba.nacos.cmdb.utils.Loggers;
import com.alibaba.nacos.cmdb.utils.UtilsAndCommons;
+import com.alibaba.nacos.common.utils.JacksonUtils;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -166,7 +167,7 @@ public void run() {
}
if (Loggers.MAIN.isDebugEnabled()) {
- Loggers.MAIN.debug("LABEL-TASK {}", "got label map:" + JSON.toJSONString(tmpLabelMap));
+ Loggers.MAIN.debug("LABEL-TASK {}", "got label map:" + JacksonUtils.toJson(tmpLabelMap));
}
labelMap = tmpLabelMap;
@@ -219,7 +220,7 @@ public void run() {
eventTimestamp = current;
if (Loggers.MAIN.isDebugEnabled()) {
- Loggers.MAIN.debug("EVENT-TASK {}", "got events size:" + ", events:" + JSON.toJSONString(events));
+ Loggers.MAIN.debug("EVENT-TASK {}", "got events size:" + ", events:" + JacksonUtils.toJson(events));
}
if (events != null && !events.isEmpty()) {
diff --git a/common/pom.xml b/common/pom.xml
index 03c731d96b2..2eefb5195a8 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -18,7 +18,7 @@
com.alibaba.nacosnacos-all
- 1.3.0-BETA
+ 1.3.0../pom.xml4.0.0
@@ -27,7 +27,7 @@
jarnacos-common ${project.version}
- http://maven.apache.org
+ http://nacos.ioUTF-8
@@ -82,8 +82,8 @@
org.apache.maven.pluginsmaven-compiler-plugin
- 7
- 7
+ 6
+ 6
diff --git a/common/src/main/java/com/alibaba/nacos/common/executor/ExecutorFactory.java b/common/src/main/java/com/alibaba/nacos/common/executor/ExecutorFactory.java
index c3e0daa9c92..301c4c2f00f 100644
--- a/common/src/main/java/com/alibaba/nacos/common/executor/ExecutorFactory.java
+++ b/common/src/main/java/com/alibaba/nacos/common/executor/ExecutorFactory.java
@@ -16,10 +16,8 @@
package com.alibaba.nacos.common.executor;
-import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
@@ -39,19 +37,6 @@ public final class ExecutorFactory {
public static final String DEFAULT_NAMESPACE = "nacos";
- public static ForkJoinPool newForkJoinPool(final String group) {
- ForkJoinPool forkJoinPool = new ForkJoinPool();
- THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, forkJoinPool);
- return forkJoinPool;
- }
-
- public static ForkJoinPool newForkJoinPool(final String group,
- final int nThreads) {
- ForkJoinPool forkJoinPool = new ForkJoinPool(nThreads);
- THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, forkJoinPool);
- return forkJoinPool;
- }
-
public static ExecutorService newSingleExecutorService(final String group) {
ExecutorService executorService = Executors.newFixedThreadPool(1);
THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
diff --git a/common/src/main/java/com/alibaba/nacos/common/executor/ThreadPoolManager.java b/common/src/main/java/com/alibaba/nacos/common/executor/ThreadPoolManager.java
index c7cfa0dd9b4..0f7b01f50b2 100644
--- a/common/src/main/java/com/alibaba/nacos/common/executor/ThreadPoolManager.java
+++ b/common/src/main/java/com/alibaba/nacos/common/executor/ThreadPoolManager.java
@@ -17,6 +17,7 @@
import com.alibaba.nacos.common.utils.ShutdownUtils;
+import com.alibaba.nacos.common.utils.ThreadUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -69,7 +70,7 @@ public static ThreadPoolManager getInstance() {
private ThreadPoolManager() {}
private void init() {
- resourcesManager = new ConcurrentHashMap<>(8);
+ resourcesManager = new ConcurrentHashMap>>(8);
}
/**
@@ -89,7 +90,7 @@ public void register(String namespace, String group, ExecutorService executor) {
synchronized (monitor) {
Map> map = resourcesManager.get(namespace);
if (map == null) {
- map = new HashMap<>(8);
+ map = new HashMap>(8);
map.put(group, new HashSet());
map.get(group).add(executor);
resourcesManager.put(namespace, map);
@@ -136,7 +137,12 @@ public void deregister(String namespace, String group, ExecutorService executor)
}
}
- public void destroy(String namespace) {
+ /**
+ * Destroys all thread pool resources under this namespace
+ *
+ * @param namespace namespace
+ */
+ public void destroy(final String namespace) {
final Object monitor = lockers.get(namespace);
if (monitor == null) {
return;
@@ -148,7 +154,7 @@ public void destroy(String namespace) {
}
for (Map.Entry> entry : subResource.entrySet()) {
for (ExecutorService executor : entry.getValue()) {
- shutdownThreadPool(executor);
+ ThreadUtils.shutdownThreadPool(executor);
}
}
resourcesManager.get(namespace).clear();
@@ -156,23 +162,28 @@ public void destroy(String namespace) {
}
}
- private void shutdownThreadPool(ExecutorService executor) {
- executor.shutdown();
- int retry = 3;
- while (retry > 0) {
- retry --;
- try {
- if (executor.awaitTermination(10, TimeUnit.SECONDS)) {
- return;
- }
- } catch (InterruptedException e) {
- executor.shutdownNow();
- Thread.interrupted();
- } catch (Throwable ex) {
- LOGGER.error("ThreadPoolManager shutdown executor has error : {}", ex);
+ /**
+ * This namespace destroys all thread pool resources under the grouping
+ *
+ * @param namespace namespace
+ * @param group group
+ */
+ public void destroy(final String namespace, final String group) {
+ final Object monitor = lockers.get(namespace);
+ if (monitor == null) {
+ return;
+ }
+ synchronized (monitor) {
+ Map> subResource = resourcesManager.get(namespace);
+ if (subResource == null) {
+ return;
+ }
+ Set waitDestroy = subResource.get(group);
+ for (ExecutorService executor : waitDestroy) {
+ ThreadUtils.shutdownThreadPool(executor);
}
+ resourcesManager.get(namespace).remove(group);
}
- executor.shutdownNow();
}
public static void shutdown() {
diff --git a/common/src/main/java/com/alibaba/nacos/common/http/BaseHttpClient.java b/common/src/main/java/com/alibaba/nacos/common/http/BaseHttpClient.java
index 157adc69040..ad3595e2f11 100644
--- a/common/src/main/java/com/alibaba/nacos/common/http/BaseHttpClient.java
+++ b/common/src/main/java/com/alibaba/nacos/common/http/BaseHttpClient.java
@@ -65,6 +65,7 @@ public void completed(HttpResponse response) {
try {
final String body = EntityUtils.toString(response.getEntity());
RestResult data = ResponseHandler.convert(body, type);
+ data.setCode(response.getStatusLine().getStatusCode());
callback.onReceive(data);
}
catch (Throwable e) {
diff --git a/common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java b/common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java
index b29a69bbc20..2a7e91dfc94 100644
--- a/common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java
+++ b/common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java
@@ -21,7 +21,6 @@
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
diff --git a/common/src/main/java/com/alibaba/nacos/common/utils/ByteUtils.java b/common/src/main/java/com/alibaba/nacos/common/utils/ByteUtils.java
index 2e393fad115..343354aac86 100644
--- a/common/src/main/java/com/alibaba/nacos/common/utils/ByteUtils.java
+++ b/common/src/main/java/com/alibaba/nacos/common/utils/ByteUtils.java
@@ -17,12 +17,14 @@
package com.alibaba.nacos.common.utils;
import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
+
+import com.alibaba.nacos.api.common.Constants;
import org.apache.commons.lang3.StringUtils;
/**
* @author liaochuntao
*/
+@SuppressWarnings("all")
public final class ByteUtils {
public static final byte[] EMPTY = new byte[0];
@@ -31,7 +33,7 @@ public static byte[] toBytes(String s) {
if (s == null) {
return EMPTY;
}
- return s.getBytes(Charset.forName(StandardCharsets.UTF_8.name()));
+ return s.getBytes(Charset.forName(Constants.ENCODE));
}
public static byte[] toBytes(Object s) {
@@ -45,7 +47,7 @@ public static String toString(byte[] bytes) {
if (bytes == null) {
return StringUtils.EMPTY;
}
- return new String(bytes, Charset.forName(StandardCharsets.UTF_8.name()));
+ return new String(bytes, Charset.forName(Constants.ENCODE));
}
public static boolean isEmpty(byte[] data) {
diff --git a/common/src/main/java/com/alibaba/nacos/common/utils/CollectionUtils.java b/common/src/main/java/com/alibaba/nacos/common/utils/CollectionUtils.java
new file mode 100644
index 00000000000..ffe7d70b4fd
--- /dev/null
+++ b/common/src/main/java/com/alibaba/nacos/common/utils/CollectionUtils.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.nacos.common.utils;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * copy from org.apache.commons.collections
+ *
+ * @author liaochuntao
+ */
+public final class CollectionUtils {
+
+ /**
+ * Returns the index-th value in object, throwing
+ * IndexOutOfBoundsException if there is no such element or
+ * IllegalArgumentException if object is not an
+ * instance of one of the supported types.
+ *
+ * The supported types, and associated semantics are:
+ *
+ *
Map -- the value returned is the Map.Entry in position
+ * index in the map's entrySet iterator,
+ * if there is such an entry.
+ *
List -- this method is equivalent to the list's get method.
+ *
Array -- the index-th array entry is returned,
+ * if there is such an entry; otherwise an IndexOutOfBoundsException
+ * is thrown.
+ *
Collection -- the value returned is the index-th object
+ * returned by the collection's default iterator, if there is such an element.
+ *
Iterator or Enumeration -- the value returned is the
+ * index-th object in the Iterator/Enumeration, if there
+ * is such an element. The Iterator/Enumeration is advanced to
+ * index (or to the end, if index exceeds the
+ * number of entries) as a side effect of this method.
+ *
+ *
+ * @param object the object to get a value from
+ * @param index the index to get
+ * @return the object at the specified index
+ * @throws IndexOutOfBoundsException if the index is invalid
+ * @throws IllegalArgumentException if the object type is invalid
+ */
+ public static Object get(Object object, int index) {
+ if (index < 0) {
+ throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
+ }
+ if (object instanceof Map) {
+ Map map = (Map) object;
+ Iterator iterator = map.entrySet().iterator();
+ return get(iterator, index);
+ } else if (object instanceof List) {
+ return ((List) object).get(index);
+ } else if (object instanceof Object[]) {
+ return ((Object[]) object)[index];
+ } else if (object instanceof Iterator) {
+ Iterator it = (Iterator) object;
+ while (it.hasNext()) {
+ index--;
+ if (index == -1) {
+ return it.next();
+ } else {
+ it.next();
+ }
+ }
+ throw new IndexOutOfBoundsException("Entry does not exist: " + index);
+ } else if (object instanceof Collection) {
+ Iterator iterator = ((Collection) object).iterator();
+ return get(iterator, index);
+ } else if (object instanceof Enumeration) {
+ Enumeration it = (Enumeration) object;
+ while (it.hasMoreElements()) {
+ index--;
+ if (index == -1) {
+ return it.nextElement();
+ } else {
+ it.nextElement();
+ }
+ }
+ throw new IndexOutOfBoundsException("Entry does not exist: " + index);
+ } else if (object == null) {
+ throw new IllegalArgumentException("Unsupported object type: null");
+ } else {
+ try {
+ return Array.get(object, index);
+ } catch (IllegalArgumentException ex) {
+ throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
+ }
+ }
+ }
+
+ /**
+ * Gets the size of the collection/iterator specified.
+ *
+ * This method can handles objects as follows
+ *
+ *
Collection - the collection size
+ *
Map - the map size
+ *
Array - the array size
+ *
Iterator - the number of elements remaining in the iterator
+ *
Enumeration - the number of elements remaining in the enumeration
+ *
+ *
+ * @param object the object to get the size of
+ * @return the size of the specified collection
+ * @throws IllegalArgumentException thrown if object is not recognised or null
+ * @since Commons Collections 3.1
+ */
+ public static int size(Object object) {
+ int total = 0;
+ if (object instanceof Map) {
+ total = ((Map) object).size();
+ } else if (object instanceof Collection) {
+ total = ((Collection) object).size();
+ } else if (object instanceof Object[]) {
+ total = ((Object[]) object).length;
+ } else if (object instanceof Iterator) {
+ Iterator it = (Iterator) object;
+ while (it.hasNext()) {
+ total++;
+ it.next();
+ }
+ } else if (object instanceof Enumeration) {
+ Enumeration it = (Enumeration) object;
+ while (it.hasMoreElements()) {
+ total++;
+ it.nextElement();
+ }
+ } else if (object == null) {
+ throw new IllegalArgumentException("Unsupported object type: null");
+ } else {
+ try {
+ total = Array.getLength(object);
+ } catch (IllegalArgumentException ex) {
+ throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
+ }
+ }
+ return total;
+ }
+
+ public static boolean sizeIsEmpty(Object object) {
+ if (object instanceof Collection) {
+ return ((Collection) object).isEmpty();
+ } else if (object instanceof Map) {
+ return ((Map) object).isEmpty();
+ } else if (object instanceof Object[]) {
+ return ((Object[]) object).length == 0;
+ } else if (object instanceof Iterator) {
+ return ((Iterator) object).hasNext() == false;
+ } else if (object instanceof Enumeration) {
+ return ((Enumeration) object).hasMoreElements() == false;
+ } else if (object == null) {
+ throw new IllegalArgumentException("Unsupported object type: null");
+ } else {
+ try {
+ return Array.getLength(object) == 0;
+ } catch (IllegalArgumentException ex) {
+ throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
+ }
+ }
+ }
+
+ /**
+ * Null-safe check if the specified collection is empty.
+ *
+ * Null returns true.
+ *
+ * @param coll the collection to check, may be null
+ * @return true if empty or null
+ * @since Commons Collections 3.2
+ */
+ public static boolean isEmpty(Collection coll) {
+ return (coll == null || coll.isEmpty());
+ }
+
+ /**
+ * Null-safe check if the specified collection is not empty.
+ *
+ * Null returns false.
+ *
+ * @param coll the collection to check, may be null
+ * @return true if non-null and non-empty
+ * @since Commons Collections 3.2
+ */
+ public static boolean isNotEmpty(Collection coll) {
+ return !CollectionUtils.isEmpty(coll);
+ }
+
+}
diff --git a/common/src/main/java/com/alibaba/nacos/common/utils/ConvertUtils.java b/common/src/main/java/com/alibaba/nacos/common/utils/ConvertUtils.java
index cfa5db3665d..81474104122 100644
--- a/common/src/main/java/com/alibaba/nacos/common/utils/ConvertUtils.java
+++ b/common/src/main/java/com/alibaba/nacos/common/utils/ConvertUtils.java
@@ -42,7 +42,7 @@ public static long toLong(String val, long defaultValue) {
return Long.parseLong(val);
}
- public static boolean toBoolean(String val, boolean defaultValue) {
+ public static boolean toBool(String val, boolean defaultValue) {
if (StringUtils.isBlank(val)) {
return defaultValue;
}
diff --git a/common/src/main/java/com/alibaba/nacos/common/utils/ExceptionUtil.java b/common/src/main/java/com/alibaba/nacos/common/utils/ExceptionUtil.java
index 83c2c77fb52..62473c11c1c 100644
--- a/common/src/main/java/com/alibaba/nacos/common/utils/ExceptionUtil.java
+++ b/common/src/main/java/com/alibaba/nacos/common/utils/ExceptionUtil.java
@@ -41,18 +41,23 @@ public static String getAllExceptionMsg(Throwable e) {
return strBuilder.toString();
}
+ public static Throwable getCause(final Throwable t) {
+ final Throwable cause = t.getCause();
+ if (Objects.isNull(cause)) {
+ return t;
+ }
+ return cause;
+ }
+
public static String getStackTrace(final Throwable t) {
if (t == null) {
return "";
}
- try (final ByteArrayOutputStream out = new ByteArrayOutputStream(); final PrintStream ps = new PrintStream(out)) {
- t.printStackTrace(ps);
- ps.flush();
- return new String(out.toByteArray());
- } catch (final IOException ignored) {
- // ignored
- }
- return "";
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintStream ps = new PrintStream(out);
+ t.printStackTrace(ps);
+ ps.flush();
+ return new String(out.toByteArray());
}
}
diff --git a/common/src/main/java/com/alibaba/nacos/common/utils/JacksonUtils.java b/common/src/main/java/com/alibaba/nacos/common/utils/JacksonUtils.java
index 9f4c94fdd05..ddaafaa9489 100644
--- a/common/src/main/java/com/alibaba/nacos/common/utils/JacksonUtils.java
+++ b/common/src/main/java/com/alibaba/nacos/common/utils/JacksonUtils.java
@@ -16,9 +16,19 @@
package com.alibaba.nacos.common.utils;
+import com.alibaba.nacos.api.exception.runtime.NacosDeserializationException;
+import com.alibaba.nacos.api.exception.runtime.NacosSerializationException;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.jsontype.NamedType;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
import java.lang.reflect.Type;
/**
@@ -30,29 +40,103 @@ public final class JacksonUtils {
static {
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+ mapper.setSerializationInclusion(Include.NON_NULL);
}
- public static String toJson(Object obj) throws Exception {
- return mapper.writeValueAsString(obj);
+ public static String toJson(Object obj) {
+ try {
+ return mapper.writeValueAsString(obj);
+ }
+ catch (JsonProcessingException e) {
+ throw new NacosSerializationException(obj.getClass(), e);
+ }
}
- public static byte[] toJsonBytes(Object obj) throws Exception {
- return ByteUtils.toBytes(mapper.writeValueAsString(obj));
+ public static byte[] toJsonBytes(Object obj) {
+ try {
+ return ByteUtils.toBytes(mapper.writeValueAsString(obj));
+ }
+ catch (JsonProcessingException e) {
+ throw new NacosSerializationException(obj.getClass(), e);
+ }
}
- public static T toObj(byte[] json, Class cls) throws Exception {
- return toObj(StringUtils.newString4UTF8(json), cls);
+ public static T toObj(byte[] json, Class cls) {
+ try {
+ return toObj(StringUtils.newString4UTF8(json), cls);
+ }
+ catch (Exception e) {
+ throw new NacosDeserializationException(cls, e);
+ }
}
- public static T toObj(byte[] json, Type cls) throws Exception {
- return toObj(StringUtils.newString4UTF8(json), cls);
+ public static T toObj(byte[] json, Type cls) {
+ try {
+ return toObj(StringUtils.newString4UTF8(json), cls);
+ }
+ catch (Exception e) {
+ throw new NacosDeserializationException(e);
+ }
}
- public static T toObj(String json, Class cls) throws Exception {
- return mapper.readValue(json, cls);
+ public static T toObj(byte[] json, TypeReference typeReference) {
+ try {
+ return toObj(StringUtils.newString4UTF8(json), typeReference);
+ }
+ catch (Exception e) {
+ throw new NacosDeserializationException(e);
+ }
}
- public static T toObj(String json, Type type) throws Exception {
- return mapper.readValue(json, mapper.constructType(type));
+ public static T toObj(String json, Class cls) {
+ try {
+ return mapper.readValue(json, cls);
+ }
+ catch (IOException e) {
+ throw new NacosDeserializationException(cls, e);
+ }
+ }
+
+ public static T toObj(String json, Type type) {
+ try {
+ return mapper.readValue(json, mapper.constructType(type));
+ }
+ catch (IOException e) {
+ throw new NacosDeserializationException(e);
+ }
+ }
+
+ public static T toObj(String json, TypeReference typeReference) {
+ try {
+ return mapper.readValue(json, typeReference);
+ }
+ catch (IOException e) {
+ throw new NacosDeserializationException(typeReference.getClass(), e);
+ }
+ }
+
+ public static JsonNode toObj(String json) {
+ try {
+ return mapper.readTree(json);
+ }
+ catch (IOException e) {
+ throw new NacosDeserializationException(e);
+ }
+ }
+
+ public static void registerSubtype(Class> clz, String type) {
+ mapper.registerSubtypes(new NamedType(clz, type));
+ }
+
+ public static ObjectNode createEmptyJsonNode() {
+ return new ObjectNode(mapper.getNodeFactory());
+ }
+
+ public static ArrayNode createEmptyArrayNode() {
+ return new ArrayNode(mapper.getNodeFactory());
+ }
+
+ public static JsonNode transferToJsonNode(Object obj) {
+ return mapper.valueToTree(obj);
}
}
diff --git a/common/src/main/java/com/alibaba/nacos/common/utils/LoggerUtils.java b/common/src/main/java/com/alibaba/nacos/common/utils/LoggerUtils.java
index 2173dd98d60..5288fbc5d8c 100644
--- a/common/src/main/java/com/alibaba/nacos/common/utils/LoggerUtils.java
+++ b/common/src/main/java/com/alibaba/nacos/common/utils/LoggerUtils.java
@@ -23,6 +23,16 @@
*/
public final class LoggerUtils {
+ public static final String TRACE = "TRACE";
+
+ public static final String INFO = "INFO";
+
+ public static final String DEBUG = "DEBUG";
+
+ public static final String WARN = "WARN";
+
+ public static final String ERROR = "ERROR";
+
public static void printIfDebugEnabled(Logger logger, String s, Object... args) {
if (logger.isDebugEnabled()) {
logger.debug(s, args);
@@ -35,4 +45,22 @@ public static void printIfInfoEnabled(Logger logger, String s, Object... args) {
}
}
+ public static void printIfTraceEnabled(Logger logger, String s, Object... args) {
+ if (logger.isTraceEnabled()) {
+ logger.trace(s, args);
+ }
+ }
+
+ public static void printIfWarnEnabled(Logger logger, String s, Object... args) {
+ if (logger.isWarnEnabled()) {
+ logger.warn(s, args);
+ }
+ }
+
+ public static void printIfErrorEnabled(Logger logger, String s, Object... args) {
+ if (logger.isErrorEnabled()) {
+ logger.error(s, args);
+ }
+ }
+
}
diff --git a/common/src/main/java/com/alibaba/nacos/common/utils/MapUtils.java b/common/src/main/java/com/alibaba/nacos/common/utils/MapUtils.java
new file mode 100644
index 00000000000..97044ea21a2
--- /dev/null
+++ b/common/src/main/java/com/alibaba/nacos/common/utils/MapUtils.java
@@ -0,0 +1,114 @@
+/*
+ *
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.alibaba.nacos.common.utils;
+
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Map;
+
+/**
+ * @author liaochuntao
+ */
+@SuppressWarnings("all")
+public class MapUtils {
+
+ /**
+ * Null-safe check if the specified Dictionary is empty.
+ *
+ * Null returns true.
+ *
+ * @param map the collection to check, may be null
+ * @return true if empty or null
+ */
+ public static boolean isEmpty(Map map) {
+ return (map == null || map.isEmpty());
+ }
+
+ /**
+ * Null-safe check if the specified Dictionary is not empty.
+ *
+ * Null returns false.
+ *
+ * @param map the collection to check, may be null
+ * @return true if non-null and non-empty
+ */
+ public static boolean isNotEmpty(Map map) {
+ return !isEmpty(map);
+ }
+
+ /**
+ * Null-safe check if the specified Dictionary is empty.
+ *
+ * Null returns true.
+ *
+ * @param coll the collection to check, may be null
+ * @return true if empty or null
+ */
+ public static boolean isEmpty(Dictionary coll) {
+ return (coll == null || coll.isEmpty());
+ }
+
+ /**
+ * Null-safe check if the specified Dictionary is not empty.
+ *
+ * Null returns false.
+ *
+ * @param coll the collection to check, may be null
+ * @return true if non-null and non-empty
+ */
+ public static boolean isNotEmpty(Dictionary coll) {
+ return !isEmpty(coll);
+ }
+
+ public static void putIfValNoNull(Map target, Object key, Object value) {
+ Objects.requireNonNull(key, "key");
+ if (value != null) {
+ target.put(key, value);
+ }
+ }
+
+ public static void putIfValNoEmpty(Map target, Object key, Object value) {
+ Objects.requireNonNull(key, "key");
+ if (value instanceof String) {
+ if (StringUtils.isNotEmpty((String) value)) {
+ target.put(key, value);
+ }
+ return;
+ }
+ if (value instanceof Collection) {
+ if (CollectionUtils.isNotEmpty((Collection) value)) {
+ target.put(key, value);
+ }
+ return;
+ }
+ if (value instanceof Map) {
+ if (isNotEmpty((Map) value)) {
+ target.put(key, value);
+ }
+ return;
+ }
+ if (value instanceof Dictionary) {
+ if (isNotEmpty((Dictionary) value)) {
+ target.put(key, value);
+ }
+ return;
+ }
+ }
+
+}
diff --git a/common/src/main/java/com/alibaba/nacos/common/utils/Objects.java b/common/src/main/java/com/alibaba/nacos/common/utils/Objects.java
new file mode 100644
index 00000000000..82fbaa8dd3b
--- /dev/null
+++ b/common/src/main/java/com/alibaba/nacos/common/utils/Objects.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.nacos.common.utils;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * @author liaochuntao
+ */
+@SuppressWarnings("all")
+public class Objects {
+
+ /**
+ * Returns {@code true} if the arguments are equal to each other
+ * and {@code false} otherwise.
+ * Consequently, if both arguments are {@code null}, {@code true}
+ * is returned and if exactly one argument is {@code null}, {@code
+ * false} is returned. Otherwise, equality is determined by using
+ * the {@link Object#equals equals} method of the first
+ * argument.
+ *
+ * @param a an object
+ * @param b an object to be compared with {@code a} for equality
+ * @return {@code true} if the arguments are equal to each other
+ * and {@code false} otherwise
+ * @see Object#equals(Object)
+ */
+ public static boolean equals(Object a, Object b) {
+ return (a == b) || (a != null && a.equals(b));
+ }
+
+ /**
+ * Returns the hash code of a non-{@code null} argument and 0 for
+ * a {@code null} argument.
+ *
+ * @param o an object
+ * @return the hash code of a non-{@code null} argument and 0 for
+ * a {@code null} argument
+ * @see Object#hashCode
+ */
+ public static int hashCode(Object o) {
+ return o != null ? o.hashCode() : 0;
+ }
+
+ /**
+ * Generates a hash code for a sequence of input values. The hash
+ * code is generated as if all the input values were placed into an
+ * array, and that array were hashed by calling {@link
+ * Arrays#hashCode(Object[])}.
+ *
+ *
This method is useful for implementing {@link
+ * Object#hashCode()} on objects containing multiple fields. For
+ * example, if an object that has three fields, {@code x}, {@code
+ * y}, and {@code z}, one could write:
+ *
+ *
+ * @Override public int hashCode() {
+ * return Objects.hash(x, y, z);
+ * }
+ *
+ *
+ * Warning: When a single object reference is supplied, the returned
+ * value does not equal the hash code of that object reference. This
+ * value can be computed by calling {@link #hashCode(Object)}.
+ *
+ * @param values the values to be hashed
+ * @return a hash value of the sequence of input values
+ * @see Arrays#hashCode(Object[])
+ * @see List#hashCode
+ */
+ public static int hash(Object... values) {
+ return Arrays.hashCode(values);
+ }
+
+ /**
+ * Returns the result of calling {@code toString} for a non-{@code
+ * null} argument and {@code "null"} for a {@code null} argument.
+ *
+ * @param o an object
+ * @return the result of calling {@code toString} for a non-{@code
+ * null} argument and {@code "null"} for a {@code null} argument
+ * @see Object#toString
+ * @see String#valueOf(Object)
+ */
+ public static String toString(Object o) {
+ return String.valueOf(o);
+ }
+
+ /**
+ * Returns the result of calling {@code toString} on the first
+ * argument if the first argument is not {@code null} and returns
+ * the second argument otherwise.
+ *
+ * @param o an object
+ * @param nullDefault string to return if the first argument is
+ * {@code null}
+ * @return the result of calling {@code toString} on the first
+ * argument if it is not {@code null} and the second argument
+ * otherwise.
+ */
+ public static String toString(Object o, String nullDefault) {
+ return (o != null) ? o.toString() : nullDefault;
+ }
+
+ /**
+ * Returns 0 if the arguments are identical and {@code
+ * c.compare(a, b)} otherwise.
+ * Consequently, if both arguments are {@code null} 0
+ * is returned.
+ *
+ *
Note that if one of the arguments is {@code null}, a {@code
+ * NullPointerException} may or may not be thrown depending on
+ * what ordering policy, if any, the {@link Comparator Comparator}
+ * chooses to have for {@code null} values.
+ *
+ * @param the type of the objects being compared
+ * @param a an object
+ * @param b an object to be compared with {@code a}
+ * @param c the {@code Comparator} to compare the first two arguments
+ * @return 0 if the arguments are identical and {@code
+ * c.compare(a, b)} otherwise.
+ * @see Comparable
+ * @see Comparator
+ */
+ public static int compare(T a, T b, Comparator super T> c) {
+ return (a == b) ? 0 : c.compare(a, b);
+ }
+
+ /**
+ * Checks that the specified object reference is not {@code null}. This
+ * method is designed primarily for doing parameter validation in methods
+ * and constructors, as demonstrated below:
+ *
+ *
+ * @param obj the object reference to check for nullity
+ * @param the type of the reference
+ * @return {@code obj} if not {@code null}
+ * @throws NullPointerException if {@code obj} is {@code null}
+ */
+ public static T requireNonNull(T obj) {
+ if (obj == null)
+ throw new NullPointerException();
+ return obj;
+ }
+
+ /**
+ * Checks that the specified object reference is not {@code null} and
+ * throws a customized {@link NullPointerException} if it is. This method
+ * is designed primarily for doing parameter validation in methods and
+ * constructors with multiple parameters, as demonstrated below:
+ *
+ * public Foo(Bar bar, Baz baz) {
+ * this.bar = Objects.requireNonNull(bar, "bar must not be null");
+ * this.baz = Objects.requireNonNull(baz, "baz must not be null");
+ * }
+ *