Merge branch 'develop' into hotfix_337

This commit is contained in:
zhichen 2018-12-06 10:38:21 +08:00 committed by GitHub
commit 52fe7d52c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
337 changed files with 17635 additions and 17961 deletions

View File

@ -40,9 +40,9 @@ It is super easy to get started with your first project.
You can download the package from the [latest stable release](https://github.com/alibaba/nacos/releases). You can download the package from the [latest stable release](https://github.com/alibaba/nacos/releases).
Take release nacos-server-0.4.0.zip for example. Take release nacos-server-0.5.0.zip for example.
``` ```
unzip nacos-server-0.4.0.zip unzip nacos-server-0.5.0.zip
cd nacos/bin cd nacos/bin
``` ```

View File

@ -25,62 +25,53 @@ import com.alibaba.nacos.api.naming.NamingService;
/** /**
* Nacos Factory * Nacos Factory
*
* @author Nacos
* *
* @author Nacos
*/ */
public class NacosFactory { public class NacosFactory {
/** /**
* Create config * Create config
* *
* @param properties * @param properties init param
* init param * @return config
* @return config * @throws NacosException Exception
* @throws NacosException */
* Exception public static ConfigService createConfigService(Properties properties) throws NacosException {
*/ return ConfigFactory.createConfigService(properties);
public static ConfigService createConfigService(Properties properties) throws NacosException { }
return ConfigFactory.createConfigService(properties);
}
/** /**
* Create config * Create config
* *
* @param serverAddr * @param serverAddr server list
* server list * @return config
* @return config * @throws NacosException Exception
* @throws NacosException */
* Exception public static ConfigService createConfigService(String serverAddr) throws NacosException {
*/ return ConfigFactory.createConfigService(serverAddr);
public static ConfigService createConfigService(String serverAddr) throws NacosException { }
return ConfigFactory.createConfigService(serverAddr);
}
/** /**
* Create Naming * Create Naming
* *
* @param serverAddr * @param serverAddr server list
* server list * @return Naming
* @return Naming * @throws NacosException Exception
* @throws NacosException */
* Exception public static NamingService createNamingService(String serverAddr) throws NacosException {
*/ return NamingFactory.createNamingService(serverAddr);
public static NamingService createNamingService(String serverAddr) throws NacosException { }
return NamingFactory.createNamingService(serverAddr);
}
/** /**
* Create Naming * Create Naming
* *
* @param properties * @param properties init param
* init param * @return Naming
* @return Naming * @throws NacosException Exception
* @throws NacosException */
* Exception public static NamingService createNamingService(Properties properties) throws NacosException {
*/ return NamingFactory.createNamingService(properties);
public static NamingService createNamingService(Properties properties) throws NacosException { }
return NamingFactory.createNamingService(properties);
}
} }

View File

@ -17,19 +17,19 @@ package com.alibaba.nacos.api;
/** /**
* properties key * properties key
* @author Nacos
* *
* @author Nacos
*/ */
public class PropertyKeyConst { public class PropertyKeyConst {
public final static String ENDPOINT = "endpoint"; public final static String ENDPOINT = "endpoint";
public final static String NAMESPACE = "namespace"; public final static String NAMESPACE = "namespace";
public final static String ACCESS_KEY = "accessKey"; public final static String ACCESS_KEY = "accessKey";
public final static String SECRET_KEY = "secretKey"; public final static String SECRET_KEY = "secretKey";
public final static String SERVER_ADDR = "serverAddr"; public final static String SERVER_ADDR = "serverAddr";
public final static String CONTEXT_PATH = "contextPath"; public final static String CONTEXT_PATH = "contextPath";
public final static String CLUSTER_NAME = "clusterName"; public final static String CLUSTER_NAME = "clusterName";
public final static String ENCODE = "encode"; public final static String ENCODE = "encode";
public final static String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart"; public final static String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart";
} }

View File

@ -17,115 +17,114 @@ package com.alibaba.nacos.api.common;
/** /**
* Constant * Constant
*
* @author Nacos
* *
* @author Nacos
*/ */
public class Constants { public class Constants {
public static final String CLIENT_VERSION_HEADER = "Client-Version"; public static final String CLIENT_VERSION_HEADER = "Client-Version";
public static final String CLIENT_VERSION = "3.0.0"; public static final String CLIENT_VERSION = "3.0.0";
public static int DATA_IN_BODY_VERSION = 204; public static int DATA_IN_BODY_VERSION = 204;
public static final String DEFAULT_GROUP = "DEFAULT_GROUP"; public static final String DEFAULT_GROUP = "DEFAULT_GROUP";
public static final String APPNAME = "AppName"; public static final String APPNAME = "AppName";
public static final String UNKNOWN_APP = "UnknownApp"; public static final String UNKNOWN_APP = "UnknownApp";
public static final String DEFAULT_DOMAINNAME = "commonconfig.config-host.taobao.com"; public static final String DEFAULT_DOMAINNAME = "commonconfig.config-host.taobao.com";
public static final String DAILY_DOMAINNAME = "commonconfig.taobao.net"; public static final String DAILY_DOMAINNAME = "commonconfig.taobao.net";
public static final String NULL = ""; public static final String NULL = "";
public static final String DATAID = "dataId"; public static final String DATAID = "dataId";
public static final String GROUP = "group"; public static final String GROUP = "group";
public static final String LAST_MODIFIED = "Last-Modified"; public static final String LAST_MODIFIED = "Last-Modified";
public static final String ACCEPT_ENCODING = "Accept-Encoding"; public static final String ACCEPT_ENCODING = "Accept-Encoding";
public static final String CONTENT_ENCODING = "Content-Encoding"; public static final String CONTENT_ENCODING = "Content-Encoding";
public static final String PROBE_MODIFY_REQUEST = "Listening-Configs"; public static final String PROBE_MODIFY_REQUEST = "Listening-Configs";
public static final String PROBE_MODIFY_RESPONSE = "Probe-Modify-Response"; public static final String PROBE_MODIFY_RESPONSE = "Probe-Modify-Response";
public static final String PROBE_MODIFY_RESPONSE_NEW = "Probe-Modify-Response-New"; public static final String PROBE_MODIFY_RESPONSE_NEW = "Probe-Modify-Response-New";
public static final String USE_ZIP = "true"; public static final String USE_ZIP = "true";
public static final String CONTENT_MD5 = "Content-MD5"; public static final String CONTENT_MD5 = "Content-MD5";
public static final String CONFIG_VERSION = "Config-Version"; public static final String CONFIG_VERSION = "Config-Version";
public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; public static final String IF_MODIFIED_SINCE = "If-Modified-Since";
public static final String SPACING_INTERVAL = "client-spacing-interval"; public static final String SPACING_INTERVAL = "client-spacing-interval";
public static final String BASE_PATH = "/v1/cs"; public static final String BASE_PATH = "/v1/cs";
public static final String CONFIG_CONTROLLER_PATH = BASE_PATH + "/configs"; public static final String CONFIG_CONTROLLER_PATH = BASE_PATH + "/configs";
/** /**
* second * second
*/ */
public static final int ASYNC_UPDATE_ADDRESS_INTERVAL = 300; public static final int ASYNC_UPDATE_ADDRESS_INTERVAL = 300;
/** /**
* second * second
*/ */
public static final int POLLING_INTERVAL_TIME = 15; public static final int POLLING_INTERVAL_TIME = 15;
/** /**
* millisecond * millisecond
*/ */
public static final int ONCE_TIMEOUT = 2000; public static final int ONCE_TIMEOUT = 2000;
/** /**
* millisecond * millisecond
*/ */
public static final int CONN_TIMEOUT = 2000; public static final int CONN_TIMEOUT = 2000;
/** /**
* millisecond * millisecond
*/ */
public static final int SO_TIMEOUT = 60000; public static final int SO_TIMEOUT = 60000;
/** /**
* millisecond * millisecond
*/ */
public static final int RECV_WAIT_TIMEOUT = ONCE_TIMEOUT * 5; public static final int RECV_WAIT_TIMEOUT = ONCE_TIMEOUT * 5;
public static final String ENCODE = "UTF-8"; public static final String ENCODE = "UTF-8";
public static final String MAP_FILE = "map-file.js"; public static final String MAP_FILE = "map-file.js";
public static final int FLOW_CONTROL_THRESHOLD = 20; public static final int FLOW_CONTROL_THRESHOLD = 20;
public static final int FLOW_CONTROL_SLOT = 10; public static final int FLOW_CONTROL_SLOT = 10;
public static final int FLOW_CONTROL_INTERVAL = 1000; public static final int FLOW_CONTROL_INTERVAL = 1000;
public static final String LINE_SEPARATOR = Character.toString((char) 1); public static final String LINE_SEPARATOR = Character.toString((char)1);
public static final String WORD_SEPARATOR = Character.toString((char) 2); public static final String WORD_SEPARATOR = Character.toString((char)2);
public static final String LONGPULLING_LINE_SEPARATOR = "\r\n"; public static final String LONGPULLING_LINE_SEPARATOR = "\r\n";
public static final String CLIENT_APPNAME_HEADER = "Client-AppName"; public static final String CLIENT_APPNAME_HEADER = "Client-AppName";
public static final String CLIENT_REQUEST_TS_HEADER = "Client-RequestTS"; public static final String CLIENT_REQUEST_TS_HEADER = "Client-RequestTS";
public static final String CLIENT_REQUEST_TOKEN_HEADER = "Client-RequestToken"; public static final String CLIENT_REQUEST_TOKEN_HEADER = "Client-RequestToken";
public static final int ATOMIC_MAX_SIZE = 1000; public static final int ATOMIC_MAX_SIZE = 1000;
public static final String NAMING_INSTANCE_ID_SPLITTER = "#"; public static final String NAMING_INSTANCE_ID_SPLITTER = "#";
public static final int NAMING_INSTANCE_ID_SEG_COUNT = 4; public static final int NAMING_INSTANCE_ID_SEG_COUNT = 4;
public static final String NAMING_HTTP_HEADER_SPILIER = "\\|"; public static final String NAMING_HTTP_HEADER_SPILIER = "\\|";
public static final String NAMING_DEFAULT_CLUSTER_NAME = "DEFAULT"; public static final String NAMING_DEFAULT_CLUSTER_NAME = "DEFAULT";
} }

View File

@ -23,52 +23,47 @@ import com.alibaba.nacos.api.exception.NacosException;
/** /**
* Config Factory * Config Factory
*
* @author Nacos
* *
* @author Nacos
*/ */
public class ConfigFactory { public class ConfigFactory {
/** /**
* Create Config * Create Config
* *
* @param properties * @param properties init param
* init param * @return Config
* @return Config * @throws NacosException Exception
* @throws NacosException */
* Exception public static ConfigService createConfigService(Properties properties) throws NacosException {
*/ try {
public static ConfigService createConfigService(Properties properties) throws NacosException { Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService");
try { Constructor constructor = driverImplClass.getConstructor(Properties.class);
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService"); ConfigService vendorImpl = (ConfigService)constructor.newInstance(properties);
Constructor constructor = driverImplClass.getConstructor(Properties.class); return vendorImpl;
ConfigService vendorImpl = (ConfigService) constructor.newInstance(properties); } catch (Throwable e) {
return vendorImpl; throw new NacosException(-400, e.getMessage());
} catch (Throwable e) { }
throw new NacosException(-400, e.getMessage()); }
}
}
/** /**
* Create Config * Create Config
* *
* @param ServerAddr * @param ServerAddr serverlist
* serverlist * @return Config
* @return Config * @throws NacosException Exception
* @throws NacosException */
* Exception public static ConfigService createConfigService(String serverAddr) throws NacosException {
*/ Properties properties = new Properties();
public static ConfigService createConfigService(String serverAddr) throws NacosException { properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
Properties properties = new Properties(); try {
properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr); Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService");
try { Constructor constructor = driverImplClass.getConstructor(Properties.class);
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService"); ConfigService vendorImpl = (ConfigService)constructor.newInstance(properties);
Constructor constructor = driverImplClass.getConstructor(Properties.class); return vendorImpl;
ConfigService vendorImpl = (ConfigService) constructor.newInstance(properties); } catch (Throwable e) {
return vendorImpl; throw new NacosException(-400, e.getMessage());
} catch (Throwable e) { }
throw new NacosException(-400, e.getMessage()); }
}
}
} }

View File

@ -20,91 +20,70 @@ import com.alibaba.nacos.api.exception.NacosException;
/** /**
* Config Interface * Config Interface
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface ConfigService { public interface ConfigService {
/** /**
* Get Configuration * Get Configuration
* *
* @param dataId * @param dataId Config ID
* Config ID * @param group Config Group
* @param group * @param timeoutMs read timeout
* Config Group * @return config value
* @param timeoutMs * @throws NacosException NacosException
* read timeout */
* @return config value String getConfig(String dataId, String group, long timeoutMs) throws NacosException;
* @throws NacosException
* NacosException
*/
String getConfig(String dataId, String group, long timeoutMs) throws NacosException;
/** /**
* Add a listener to the configuration, after the server to modify the * Add a listener to the configuration, after the server to modify the configuration, the client will use the
* configuration, the client will use the incoming listener callback. * incoming listener callback. Recommended asynchronous processing, the application can implement the getExecutor
* Recommended asynchronous processing, the application can implement the * method in the ManagerListener, provide a thread pool of execution. If provided, use the main thread callback, May
* getExecutor method in the ManagerListener, provide a thread pool of * block other configurations or be blocked by other configurations.
* execution. If provided, use the main thread callback, May block other *
* configurations or be blocked by other configurations. * @param dataId Config ID
* * @param group Config Group
* @param dataId * @param listener listener
* Config ID * @throws NacosException NacosException
* @param group */
* Config Group void addListener(String dataId, String group, Listener listener) throws NacosException;
* @param listener
* listener
* @throws NacosException
* NacosException
*/
void addListener(String dataId, String group, Listener listener) throws NacosException;
/** /**
* publish config. * publish config.
* *
* @param dataId * @param dataId Config ID
* Config ID * @param group Config Group
* @param group * @param content Config Content
* Config Group * @return Whether publish
* @param content * @throws NacosException NacosException
* Config Content */
* @return Whether publish boolean publishConfig(String dataId, String group, String content) throws NacosException;
* @throws NacosException
* NacosException
*/
boolean publishConfig(String dataId, String group, String content) throws NacosException;
/** /**
* Remove Config * Remove Config
* *
* @param dataId * @param dataId Config ID
* Config ID * @param group Config Group
* @param group * @return whether remove
* Config Group * @throws NacosException NacosException
* @return whether remove */
* @throws NacosException boolean removeConfig(String dataId, String group) throws NacosException;
* NacosException
*/
boolean removeConfig(String dataId, String group) throws NacosException;
/** /**
* Remove Listener * Remove Listener
* *
* @param dataId * @param dataId Config ID
* Config ID * @param group Config Group
* @param group * @param listener listener
* Config Group */
* @param listener void removeListener(String dataId, String group, Listener listener);
* listener
*/ /**
void removeListener(String dataId, String group, Listener listener); * server health info
*
/** * @return whether health
* server health info */
* String getServerStatus();
* @return whether health
*/
String getServerStatus();
} }

View File

@ -56,8 +56,7 @@ public @interface NacosConfigListener {
Class<? extends NacosConfigConverter> converter() default NacosConfigConverter.class; Class<? extends NacosConfigConverter> converter() default NacosConfigConverter.class;
/** /**
* The {@link NacosProperties} attribute, If not specified, it will use * The {@link NacosProperties} attribute, If not specified, it will use global Nacos Properties.
* global Nacos Properties.
* *
* @return the default value is {@link NacosProperties} * @return the default value is {@link NacosProperties}
*/ */

View File

@ -23,7 +23,6 @@ import java.lang.annotation.*;
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP; import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
/** /**
* An annotation for Nacos configuration Properties for binding POJO as Properties Object. * An annotation for Nacos configuration Properties for binding POJO as Properties Object.
* *
@ -51,51 +50,46 @@ public @interface NacosConfigurationProperties {
String dataId(); String dataId();
/** /**
* It indicates the properties of current doBind bean is auto-refreshed * It indicates the properties of current doBind bean is auto-refreshed when Nacos configuration is changed.
* when Nacos configuration is changed.
* *
* @return default value is <code>false</code> * @return default value is <code>false</code>
*/ */
boolean autoRefreshed() default false; boolean autoRefreshed() default false;
/** /**
* Flag to indicate that when binding to this object invalid fields should be ignored. * Flag to indicate that when binding to this object invalid fields should be ignored. Invalid means invalid
* Invalid means invalid according to the binder that is used, and usually this means * according to the binder that is used, and usually this means fields of the wrong type (or that cannot be coerced
* fields of the wrong type (or that cannot be coerced into the correct type). * into the correct type).
* *
* @return the flag value (default false) * @return the flag value (default false)
*/ */
boolean ignoreInvalidFields() default false; boolean ignoreInvalidFields() default false;
/** /**
* Flag to indicate that when binding to this object fields with periods in their * Flag to indicate that when binding to this object fields with periods in their names should be ignored.
* names should be ignored.
* *
* @return the flag value (default false) * @return the flag value (default false)
*/ */
boolean ignoreNestedProperties() default false; boolean ignoreNestedProperties() default false;
/** /**
* Flag to indicate that when binding to this object unknown fields should be ignored. * Flag to indicate that when binding to this object unknown fields should be ignored. An unknown field could be a
* An unknown field could be a sign of a mistake in the Properties. * sign of a mistake in the Properties.
* *
* @return the flag value (default true) * @return the flag value (default true)
*/ */
boolean ignoreUnknownFields() default true; boolean ignoreUnknownFields() default true;
/** /**
* Flag to indicate that an exception should be raised if a Validator is available and * Flag to indicate that an exception should be raised if a Validator is available and validation fails. If it is
* validation fails. If it is set to false, validation errors will be swallowed. They * set to false, validation errors will be swallowed. They will be logged, but not propagated to the caller.
* will be logged, but not propagated to the caller.
* *
* @return the flag value (default true) * @return the flag value (default true)
*/ */
boolean exceptionIfInvalid() default true; boolean exceptionIfInvalid() default true;
/** /**
* The {@link NacosProperties} attribute, If not specified, it will use * The {@link NacosProperties} attribute, If not specified, it will use global Nacos Properties.
* global Nacos Properties.
* *
* @return the default value is {@link NacosProperties} * @return the default value is {@link NacosProperties}
*/ */

View File

@ -18,8 +18,7 @@ package com.alibaba.nacos.api.config.annotation;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* An annotation for ignore field from annotated * An annotation for ignore field from annotated {@link NacosConfigurationProperties} Properties Object.
* {@link NacosConfigurationProperties} Properties Object.
* *
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a> * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
* @see NacosConfigurationProperties * @see NacosConfigurationProperties

View File

@ -18,9 +18,8 @@ package com.alibaba.nacos.api.config.annotation;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* An annotation for Nacos Property name of Nacos Configuration to * An annotation for Nacos Property name of Nacos Configuration to bind a field from annotated {@link
* bind a field from annotated {@link NacosConfigurationProperties} * NacosConfigurationProperties} Properties Object.
* Properties Object.
* *
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a> * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
* @see NacosConfigurationProperties * @see NacosConfigurationProperties

View File

@ -40,5 +40,4 @@ public interface NacosConfigConverter<T> {
*/ */
T convert(String config); T convert(String config);
} }

View File

@ -17,26 +17,23 @@ package com.alibaba.nacos.api.config.filter;
/** /**
* Config Context Interface * Config Context Interface
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface IConfigContext { public interface IConfigContext {
/** /**
* get context by key * get context by key
* *
* @param key * @param key
* @return context * @return context
*/ */
public Object getParameter(String key); public Object getParameter(String key);
/** /**
* set context * set context
* *
* @param key * @param key key
* key * @param value value
* @param value */
* value public void setParameter(String key, Object value);
*/
public void setParameter(String key, Object value);
} }

View File

@ -19,51 +19,45 @@ import com.alibaba.nacos.api.exception.NacosException;
/** /**
* Config Filter Interface * Config Filter Interface
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface IConfigFilter { public interface IConfigFilter {
/** /**
* Init Fuction * Init Fuction
* *
* @param filterConfig * @param filterConfig Filter Config
* Filter Config */
*/ void init(IFilterConfig filterConfig);
void init(IFilterConfig filterConfig);
/** /**
* do filter * do filter
* *
* @param request * @param request request
* request * @param response response
* @param response * @param filterChain filter Chain
* response * @throws NacosException exception
* @param filterChain */
* filter Chain void doFilter(IConfigRequest request, IConfigResponse response, IConfigFilterChain filterChain)
* @throws NacosException throws NacosException;
* exception
*/
void doFilter(IConfigRequest request, IConfigResponse response, IConfigFilterChain filterChain)
throws NacosException;
/** /**
* deploy * deploy
*/ */
void deploy(); void deploy();
/** /**
* order * order
* *
* @return * @return
*/ */
int getOrder(); int getOrder();
/** /**
* filterName * filterName
* *
* @return * @return
*/ */
String getFilterName(); String getFilterName();
} }

View File

@ -19,21 +19,17 @@ import com.alibaba.nacos.api.exception.NacosException;
/** /**
* Config Filter Chain Interface * Config Filter Chain Interface
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface IConfigFilterChain { public interface IConfigFilterChain {
/** /**
* Filter aciton * Filter aciton
* *
* @param request * @param request request
* request * @param response response
* @param response * @throws NacosException NacosException
* response */
* @throws NacosException public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException;
* NacosException
*/
public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException;
} }

View File

@ -17,25 +17,23 @@ package com.alibaba.nacos.api.config.filter;
/** /**
* Config Request Interface * Config Request Interface
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface IConfigRequest { public interface IConfigRequest {
/** /**
* get param * get param
* *
* @param key * @param key key
* key * @return value
* @return value */
*/ public Object getParameter(String key);
public Object getParameter(String key);
/** /**
* get config context * get config context
* *
* @return * @return
*/ */
public IConfigContext getConfigContext(); public IConfigContext getConfigContext();
} }

View File

@ -17,25 +17,23 @@ package com.alibaba.nacos.api.config.filter;
/** /**
* Config Response Interface * Config Response Interface
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface IConfigResponse { public interface IConfigResponse {
/** /**
* get param * get param
* *
* @param key * @param key key
* key * @return value
* @return value */
*/ public Object getParameter(String key);
public Object getParameter(String key);
/** /**
* get context * get context
* *
* @return configContext * @return configContext
*/ */
public IConfigContext getConfigContext(); public IConfigContext getConfigContext();
} }

View File

@ -14,26 +14,27 @@
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.api.config.filter; package com.alibaba.nacos.api.config.filter;
/** /**
* Filter Config Interface * Filter Config Interface
* @author Nacos
* *
* @author Nacos
*/ */
public interface IFilterConfig { public interface IFilterConfig {
/** /**
* get filter name * get filter name
* *
* @return * @return
*/ */
public String getFilterName(); public String getFilterName();
/** /**
* get param * get param
* *
* @param name * @param name
* @return param * @return param
*/ */
public Object getInitParameter(String name); public Object getInitParameter(String name);
} }

View File

@ -19,16 +19,15 @@ import java.util.concurrent.Executor;
/** /**
* Listner Adapter,use default notify thread * Listner Adapter,use default notify thread
*
* @author water.lyl
* *
* @author water.lyl
*/ */
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule") @SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class AbstractListener implements Listener { public abstract class AbstractListener implements Listener {
/** /**
* use default Executor * use default Executor
*/ */
public Executor getExecutor() { public Executor getExecutor() {
return null; return null;
} }

View File

@ -19,9 +19,8 @@ import java.util.concurrent.Executor;
/** /**
* shared listener * shared listener
*
* @author Nacos
* *
* @author Nacos
*/ */
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule") @SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class AbstractSharedListener implements Listener { public abstract class AbstractSharedListener implements Listener {
@ -43,15 +42,12 @@ public abstract class AbstractSharedListener implements Listener {
return null; return null;
} }
/** /**
* receive * receive
* *
* @param dataId * @param dataId data ID
* data ID * @param group group
* @param group * @param configInfo content
* group */
* @param configInfo
* content
*/
public abstract void innerReceive(String dataId, String group, String configInfo); public abstract void innerReceive(String dataId, String group, String configInfo);
} }

View File

@ -17,26 +17,23 @@ package com.alibaba.nacos.api.config.listener;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** /**
* Listener for watch config * Listener for watch config
* *
* @author Nacos * @author Nacos
*
*/ */
public interface Listener { public interface Listener {
/** /**
* Executor to excute this receive * Executor to excute this receive
* *
* @return Executor * @return Executor
*/ */
public Executor getExecutor(); public Executor getExecutor();
/** /**
* 接收配置信息 * 接收配置信息
* *
* @param configInfo 配置值 * @param configInfo 配置值
*/ */
public void receiveConfigInfo(final String configInfo); public void receiveConfigInfo(final String configInfo);

View File

@ -17,94 +17,93 @@ package com.alibaba.nacos.api.exception;
/** /**
* Nacos Exception * Nacos Exception
*
* @author Nacos
* *
* @author Nacos
*/ */
public class NacosException extends Exception{ public class NacosException extends Exception {
/** /**
* serialVersionUID * serialVersionUID
*/ */
private static final long serialVersionUID = -3913902031489277776L; private static final long serialVersionUID = -3913902031489277776L;
private int errCode; private int errCode;
private String errMsg; private String errMsg;
public NacosException() {
};
public NacosException(int errCode, String errMsg) { public NacosException() {
this.errCode = errCode; }
this.errMsg = errMsg;
}
public int getErrCode() {
return errCode;
}
public String getErrMsg() { ;
return errMsg;
}
public void setErrCode(int errCode) { public NacosException(int errCode, String errMsg) {
this.errCode = errCode; this.errCode = errCode;
} this.errMsg = errMsg;
}
public void setErrMsg(String errMsg) { public int getErrCode() {
this.errMsg = errMsg; return errCode;
} }
@Override
public String toString() {
return "ErrCode:" + errCode + ",ErrMsg:" + errMsg;
}
/** public String getErrMsg() {
* client error code return errMsg;
* -400 -503 throw exception to user }
*/
/**
* invalid param参数错误
*/
public static final int CLIENT_INVALID_PARAM = -400;
/**
* over client threshold超过server端的限流阈值
*/
public static final int CLIENT_OVER_THRESHOLD = -503;
public void setErrCode(int errCode) {
/** this.errCode = errCode;
* server error code }
* 400 403 throw exception to user
* 500 502 503 change ip and retry public void setErrMsg(String errMsg) {
*/ this.errMsg = errMsg;
}
/**
* invalid param参数错误 @Override
*/ public String toString() {
public static final int INVALID_PARAM = 400; return "ErrCode:" + errCode + ",ErrMsg:" + errMsg;
/** }
* no right鉴权失败
*/ /**
public static final int NO_RIGHT = 403; * client error code
/** * -400 -503 throw exception to user
* conflict写并发冲突 */
*/ /**
public static final int CONFLICT = 409; * invalid param参数错误
/** */
* server errorserver异常如超时 public static final int CLIENT_INVALID_PARAM = -400;
*/ /**
public static final int SERVER_ERROR = 500; * over client threshold超过server端的限流阈值
/** */
* bad gateway路由异常如nginx后面的Server挂掉 public static final int CLIENT_OVER_THRESHOLD = -503;
*/
public static final int BAD_GATEWAY = 502; /**
/** * server error code
* over threshold超过server端的限流阈值 * 400 403 throw exception to user
*/ * 500 502 503 change ip and retry
public static final int OVER_THRESHOLD = 503; */
/**
* invalid param参数错误
*/
public static final int INVALID_PARAM = 400;
/**
* no right鉴权失败
*/
public static final int NO_RIGHT = 403;
/**
* conflict写并发冲突
*/
public static final int CONFLICT = 409;
/**
* server errorserver异常如超时
*/
public static final int SERVER_ERROR = 500;
/**
* bad gateway路由异常如nginx后面的Server挂掉
*/
public static final int BAD_GATEWAY = 502;
/**
* over threshold超过server端的限流阈值
*/
public static final int OVER_THRESHOLD = 503;
} }

View File

@ -21,29 +21,29 @@ import java.util.Properties;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
/** /**
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public class NamingFactory { public class NamingFactory {
public static NamingService createNamingService(String serverList) throws NacosException { public static NamingService createNamingService(String serverList) throws NacosException {
try { try {
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService"); Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
Constructor constructor = driverImplClass.getConstructor(String.class); Constructor constructor = driverImplClass.getConstructor(String.class);
NamingService vendorImpl = (NamingService) constructor.newInstance(serverList); NamingService vendorImpl = (NamingService)constructor.newInstance(serverList);
return vendorImpl; return vendorImpl;
} catch (Throwable e) { } catch (Throwable e) {
throw new NacosException(-400, e.getMessage()); throw new NacosException(-400, e.getMessage());
} }
} }
public static NamingService createNamingService(Properties properties) throws NacosException { public static NamingService createNamingService(Properties properties) throws NacosException {
try { try {
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService"); Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
Constructor constructor = driverImplClass.getConstructor(Properties.class); Constructor constructor = driverImplClass.getConstructor(Properties.class);
NamingService vendorImpl = (NamingService) constructor.newInstance(properties); NamingService vendorImpl = (NamingService)constructor.newInstance(properties);
return vendorImpl; return vendorImpl;
} catch (Throwable e) { } catch (Throwable e) {
throw new NacosException(-400, e.getMessage()); throw new NacosException(-400, e.getMessage());
} }
} }
} }

View File

@ -24,7 +24,7 @@ import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import java.util.List; import java.util.List;
/** /**
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public interface NamingService { public interface NamingService {

View File

@ -17,7 +17,7 @@ package com.alibaba.nacos.api.naming.listener;
/** /**
* event interface * event interface
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public interface Event { public interface Event {
} }

View File

@ -16,14 +16,15 @@
package com.alibaba.nacos.api.naming.listener; package com.alibaba.nacos.api.naming.listener;
/** /**
* event listener * event listener
* @author Nacos
* *
* @author Nacos
*/ */
public interface EventListener { public interface EventListener {
/** /**
* callback event * callback event
* @param event *
*/ * @param event
*/
void onEvent(Event event); void onEvent(Event event);
} }

View File

@ -20,7 +20,7 @@ import java.util.List;
import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.Instance;
/** /**
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public class NamingEvent implements Event { public class NamingEvent implements Event {

View File

@ -25,7 +25,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
/** /**
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public abstract class AbstractHealthChecker implements Cloneable { public abstract class AbstractHealthChecker implements Cloneable {
@ -113,7 +113,7 @@ public abstract class AbstractHealthChecker implements Cloneable {
return false; return false;
} }
Http other = (Http) obj; Http other = (Http)obj;
if (!strEquals(type, other.getType())) { if (!strEquals(type, other.getType())) {
return false; return false;
@ -212,7 +212,7 @@ public abstract class AbstractHealthChecker implements Cloneable {
return false; return false;
} }
Mysql other = (Mysql) obj; Mysql other = (Mysql)obj;
if (!strEquals(user, other.getUser())) { if (!strEquals(user, other.getUser())) {
return false; return false;

View File

@ -21,7 +21,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public class Cluster { public class Cluster {
@ -55,7 +55,6 @@ public class Cluster {
*/ */
private boolean useIPPort4Check = true; private boolean useIPPort4Check = true;
private Map<String, String> metadata = new HashMap<String, String>(); private Map<String, String> metadata = new HashMap<String, String>();
public Cluster() { public Cluster() {

View File

@ -22,7 +22,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public class Instance { public class Instance {
@ -160,7 +160,7 @@ public class Instance {
return false; return false;
} }
Instance host = (Instance) obj; Instance host = (Instance)obj;
return strEquals(toString(), host.toString()); return strEquals(toString(), host.toString());
} }

View File

@ -20,7 +20,7 @@ import com.alibaba.fastjson.JSON;
import java.util.List; import java.util.List;
/** /**
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public class ListView<T> { public class ListView<T> {

View File

@ -19,7 +19,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public class Service { public class Service {

View File

@ -22,7 +22,7 @@ import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
* @author dungu.zpf * @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
*/ */
public class ServiceInfo { public class ServiceInfo {
@ -205,7 +205,7 @@ public class ServiceInfo {
if (!isEmpty(clusters) && !isEmpty(unit)) { if (!isEmpty(clusters) && !isEmpty(unit)) {
return isAllIPs ? name + SPLITER + clusters + SPLITER + unit + SPLITER + ALL_IPS return isAllIPs ? name + SPLITER + clusters + SPLITER + unit + SPLITER + ALL_IPS
: name + SPLITER + clusters + SPLITER + unit; : name + SPLITER + clusters + SPLITER + unit;
} }
if (!isEmpty(clusters)) { if (!isEmpty(clusters)) {
@ -214,7 +214,7 @@ public class ServiceInfo {
if (!isEmpty(unit)) { if (!isEmpty(unit)) {
return isAllIPs ? name + SPLITER + EMPTY + SPLITER + unit + SPLITER + ALL_IPS : return isAllIPs ? name + SPLITER + EMPTY + SPLITER + unit + SPLITER + ALL_IPS :
name + SPLITER + EMPTY + SPLITER + unit; name + SPLITER + EMPTY + SPLITER + unit;
} }
return isAllIPs ? name + SPLITER + ALL_IPS : name; return isAllIPs ? name + SPLITER + ALL_IPS : name;

View File

@ -44,233 +44,233 @@ import java.util.Properties;
/** /**
* Config Impl * Config Impl
* @author Nacos
* *
* @author Nacos
*/ */
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule") @SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
public class NacosConfigService implements ConfigService { public class NacosConfigService implements ConfigService {
final static public Logger log = LogUtils.logger(NacosConfigService.class); final static public Logger log = LogUtils.logger(NacosConfigService.class);
public final long POST_TIMEOUT = 3000L; public final long POST_TIMEOUT = 3000L;
/** /**
* http agent * http agent
*/ */
private ServerHttpAgent agent; private ServerHttpAgent agent;
/** /**
* longpulling * longpulling
*/ */
private ClientWorker worker; private ClientWorker worker;
private String namespace; private String namespace;
private String encode; private String encode;
private ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager(); private ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager();
public NacosConfigService(Properties properties) throws NacosException { public NacosConfigService(Properties properties) throws NacosException {
String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE); String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
if (StringUtils.isBlank(encodeTmp)) { if (StringUtils.isBlank(encodeTmp)) {
encode = Constants.ENCODE; encode = Constants.ENCODE;
} else { } else {
encode = encodeTmp.trim(); encode = encodeTmp.trim();
} }
String namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE); String namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE);
if (StringUtils.isBlank(namespaceTmp)) { if (StringUtils.isBlank(namespaceTmp)) {
namespace = TenantUtil.getUserTenant(); namespace = TenantUtil.getUserTenant();
properties.put(PropertyKeyConst.NAMESPACE, namespace); properties.put(PropertyKeyConst.NAMESPACE, namespace);
} else { } else {
namespace = namespaceTmp; namespace = namespaceTmp;
properties.put(PropertyKeyConst.NAMESPACE, namespace); properties.put(PropertyKeyConst.NAMESPACE, namespace);
} }
agent = new ServerHttpAgent(properties); agent = new ServerHttpAgent(properties);
agent.start(); agent.start();
worker = new ClientWorker(agent, configFilterChainManager); worker = new ClientWorker(agent, configFilterChainManager);
} }
@Override @Override
public String getConfig(String dataId, String group, long timeoutMs) throws NacosException { public String getConfig(String dataId, String group, long timeoutMs) throws NacosException {
return getConfigInner(namespace, dataId, group, timeoutMs); return getConfigInner(namespace, dataId, group, timeoutMs);
} }
@Override @Override
public void addListener(String dataId, String group, Listener listener) throws NacosException { public void addListener(String dataId, String group, Listener listener) throws NacosException {
worker.addTenantListeners(dataId, group, Arrays.asList(listener)); worker.addTenantListeners(dataId, group, Arrays.asList(listener));
} }
@Override @Override
public boolean publishConfig(String dataId, String group, String content) throws NacosException { public boolean publishConfig(String dataId, String group, String content) throws NacosException {
return publishConfigInner(namespace, dataId, group, null, null, null, content); return publishConfigInner(namespace, dataId, group, null, null, null, content);
} }
@Override @Override
public boolean removeConfig(String dataId, String group) throws NacosException { public boolean removeConfig(String dataId, String group) throws NacosException {
return removeConfigInner(namespace, dataId, group, null); return removeConfigInner(namespace, dataId, group, null);
} }
@Override @Override
public void removeListener(String dataId, String group, Listener listener) { public void removeListener(String dataId, String group, Listener listener) {
worker.removeTenantListener(dataId, group, listener); worker.removeTenantListener(dataId, group, listener);
} }
private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException { private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException {
group = null2defaultGroup(group); group = null2defaultGroup(group);
ParamUtils.checkKeyParam(dataId, group); ParamUtils.checkKeyParam(dataId, group);
ConfigResponse cr = new ConfigResponse(); ConfigResponse cr = new ConfigResponse();
cr.setDataId(dataId); cr.setDataId(dataId);
cr.setTenant(tenant); cr.setTenant(tenant);
cr.setGroup(group); cr.setGroup(group);
// 优先使用本地配置 // 优先使用本地配置
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant); String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
if (content != null) { if (content != null) {
log.warn(agent.getName(), "[get-config] get failover ok, dataId={}, group={}, tenant={}, config={}", dataId, log.warn(agent.getName(), "[get-config] get failover ok, dataId={}, group={}, tenant={}, config={}", dataId,
group, tenant, ContentUtils.truncateContent(content)); group, tenant, ContentUtils.truncateContent(content));
cr.setContent(content); cr.setContent(content);
configFilterChainManager.doFilter(null, cr); configFilterChainManager.doFilter(null, cr);
content = cr.getContent(); content = cr.getContent();
return content; return content;
} }
try { try {
content = worker.getServerConfig(dataId, group, tenant, timeoutMs); content = worker.getServerConfig(dataId, group, tenant, timeoutMs);
cr.setContent(content); cr.setContent(content);
configFilterChainManager.doFilter(null, cr); configFilterChainManager.doFilter(null, cr);
content = cr.getContent(); content = cr.getContent();
return content; return content;
} catch (NacosException ioe) { } catch (NacosException ioe) {
if (NacosException.NO_RIGHT == ioe.getErrCode()) { if (NacosException.NO_RIGHT == ioe.getErrCode()) {
throw ioe; throw ioe;
} }
log.warn("NACOS-0003", log.warn("NACOS-0003",
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0003", "环境问题", "get from server error")); LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0003", "环境问题", "get from server error"));
log.warn(agent.getName(), "[get-config] get from server error, dataId={}, group={}, tenant={}, msg={}", log.warn(agent.getName(), "[get-config] get from server error, dataId={}, group={}, tenant={}, msg={}",
dataId, group, tenant, ioe.toString()); dataId, group, tenant, ioe.toString());
} }
log.warn(agent.getName(), "[get-config] get snapshot ok, dataId={}, group={}, tenant={}, config={}", dataId, log.warn(agent.getName(), "[get-config] get snapshot ok, dataId={}, group={}, tenant={}, config={}", dataId,
group, tenant, ContentUtils.truncateContent(content)); group, tenant, ContentUtils.truncateContent(content));
content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant); content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant);
cr.setContent(content); cr.setContent(content);
configFilterChainManager.doFilter(null, cr); configFilterChainManager.doFilter(null, cr);
content = cr.getContent(); content = cr.getContent();
return content; return content;
} }
private String null2defaultGroup(String group) { private String null2defaultGroup(String group) {
return (null == group) ? Constants.DEFAULT_GROUP : group.trim(); return (null == group) ? Constants.DEFAULT_GROUP : group.trim();
} }
private boolean removeConfigInner(String tenant, String dataId, String group, String tag) throws NacosException { private boolean removeConfigInner(String tenant, String dataId, String group, String tag) throws NacosException {
group = null2defaultGroup(group); group = null2defaultGroup(group);
ParamUtils.checkKeyParam(dataId, group); ParamUtils.checkKeyParam(dataId, group);
String url = Constants.CONFIG_CONTROLLER_PATH; String url = Constants.CONFIG_CONTROLLER_PATH;
List<String> params = new ArrayList<String>(); List<String> params = new ArrayList<String>();
params.add("dataId"); params.add("dataId");
params.add(dataId); params.add(dataId);
params.add("group"); params.add("group");
params.add(group); params.add(group);
if (StringUtils.isNotEmpty(tenant)) { if (StringUtils.isNotEmpty(tenant)) {
params.add("tenant"); params.add("tenant");
params.add(tenant); params.add(tenant);
} }
if (StringUtils.isNotEmpty(tag)) { if (StringUtils.isNotEmpty(tag)) {
params.add("tag"); params.add("tag");
params.add(tag); params.add(tag);
} }
HttpResult result = null; HttpResult result = null;
try { try {
result = agent.httpDelete(url, null, params, encode, POST_TIMEOUT); result = agent.httpDelete(url, null, params, encode, POST_TIMEOUT);
} catch (IOException ioe) { } catch (IOException ioe) {
log.warn("[remove] error, " + dataId + ", " + group + ", " + tenant + ", msg: " + ioe.toString()); log.warn("[remove] error, " + dataId + ", " + group + ", " + tenant + ", msg: " + ioe.toString());
return false; return false;
} }
if (HttpURLConnection.HTTP_OK == result.code) { if (HttpURLConnection.HTTP_OK == result.code) {
log.info(agent.getName(), "[remove] ok, dataId={}, group={}, tenant={}", dataId, group, tenant); log.info(agent.getName(), "[remove] ok, dataId={}, group={}, tenant={}", dataId, group, tenant);
return true; return true;
} else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) { } else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) {
log.warn(agent.getName(), "[remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, group, log.warn(agent.getName(), "[remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, group,
tenant, result.code, result.content); tenant, result.code, result.content);
throw new NacosException(result.code, result.content); throw new NacosException(result.code, result.content);
} else { } else {
log.warn(agent.getName(), "[remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, group, log.warn(agent.getName(), "[remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, group,
tenant, result.code, result.content); tenant, result.code, result.content);
return false; return false;
} }
} }
private boolean publishConfigInner(String tenant, String dataId, String group, String tag, String appName, private boolean publishConfigInner(String tenant, String dataId, String group, String tag, String appName,
String betaIps, String content) throws NacosException { String betaIps, String content) throws NacosException {
group = null2defaultGroup(group); group = null2defaultGroup(group);
ParamUtils.checkParam(dataId, group, content); ParamUtils.checkParam(dataId, group, content);
ConfigRequest cr = new ConfigRequest(); ConfigRequest cr = new ConfigRequest();
cr.setDataId(dataId); cr.setDataId(dataId);
cr.setTenant(tenant); cr.setTenant(tenant);
cr.setGroup(group); cr.setGroup(group);
cr.setContent(content); cr.setContent(content);
configFilterChainManager.doFilter(cr, null); configFilterChainManager.doFilter(cr, null);
content = cr.getContent(); content = cr.getContent();
String url = Constants.CONFIG_CONTROLLER_PATH; String url = Constants.CONFIG_CONTROLLER_PATH;
List<String> params = new ArrayList<String>(); List<String> params = new ArrayList<String>();
params.add("dataId"); params.add("dataId");
params.add(dataId); params.add(dataId);
params.add("group"); params.add("group");
params.add(group); params.add(group);
params.add("content"); params.add("content");
params.add(content); params.add(content);
if (StringUtils.isNotEmpty(tenant)) { if (StringUtils.isNotEmpty(tenant)) {
params.add("tenant"); params.add("tenant");
params.add(tenant); params.add(tenant);
} }
if (StringUtils.isNotEmpty(appName)) { if (StringUtils.isNotEmpty(appName)) {
params.add("appName"); params.add("appName");
params.add(appName); params.add(appName);
} }
if (StringUtils.isNotEmpty(tag)) { if (StringUtils.isNotEmpty(tag)) {
params.add("tag"); params.add("tag");
params.add(tag); params.add(tag);
} }
List<String> headers = new ArrayList<String>(); List<String> headers = new ArrayList<String>();
if (StringUtils.isNotEmpty(betaIps)) { if (StringUtils.isNotEmpty(betaIps)) {
headers.add("betaIps"); headers.add("betaIps");
headers.add(betaIps); headers.add(betaIps);
} }
HttpResult result = null; HttpResult result = null;
try { try {
result = agent.httpPost(url, headers, params, encode, POST_TIMEOUT); result = agent.httpPost(url, headers, params, encode, POST_TIMEOUT);
} catch (IOException ioe) { } catch (IOException ioe) {
log.warn("NACOS-0006", log.warn("NACOS-0006",
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0006", "环境问题", "[publish-single] exception")); LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0006", "环境问题", "[publish-single] exception"));
log.warn(agent.getName(), "[publish-single] exception, dataId={}, group={}, msg={}", dataId, group, log.warn(agent.getName(), "[publish-single] exception, dataId={}, group={}, msg={}", dataId, group,
ioe.toString()); ioe.toString());
return false; return false;
} }
if (HttpURLConnection.HTTP_OK == result.code) { if (HttpURLConnection.HTTP_OK == result.code) {
log.info(agent.getName(), "[publish-single] ok, dataId={}, group={}, tenant={}, config={}", dataId, group, log.info(agent.getName(), "[publish-single] ok, dataId={}, group={}, tenant={}, config={}", dataId, group,
tenant, ContentUtils.truncateContent(content)); tenant, ContentUtils.truncateContent(content));
return true; return true;
} else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) { } else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) {
log.warn(agent.getName(), "[publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, log.warn(agent.getName(), "[publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId,
group, tenant, result.code, result.content); group, tenant, result.code, result.content);
throw new NacosException(result.code, result.content); throw new NacosException(result.code, result.content);
} else { } else {
log.warn(agent.getName(), "[publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, log.warn(agent.getName(), "[publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId,
group, tenant, result.code, result.content); group, tenant, result.code, result.content);
return false; return false;
} }
} }
@Override @Override
public String getServerStatus() { public String getServerStatus() {
if (worker.isHealthServer()) { if (worker.isHealthServer()) {
return "UP"; return "UP";
} else { } else {
return "DOWN"; return "DOWN";
} }
} }
} }

View File

@ -18,9 +18,8 @@ package com.alibaba.nacos.client.config.common;
import com.alibaba.nacos.client.utils.StringUtils; import com.alibaba.nacos.client.utils.StringUtils;
/** /**
* Synthesize the form of dataId+groupId. Escapes reserved characters in dataId * Synthesize the form of dataId+groupId. Escapes reserved characters in dataId and groupId.
* and groupId. *
*
* @author Nacos * @author Nacos
*/ */
public class GroupKey { public class GroupKey {
@ -33,28 +32,28 @@ public class GroupKey {
return sb.toString(); return sb.toString();
} }
static public String getKeyTenant(String dataId, String group, String tenant) { static public String getKeyTenant(String dataId, String group, String tenant) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
urlEncode(dataId, sb); urlEncode(dataId, sb);
sb.append('+'); sb.append('+');
urlEncode(group, sb); urlEncode(group, sb);
if (StringUtils.isNotEmpty(tenant)) { if (StringUtils.isNotEmpty(tenant)) {
sb.append('+'); sb.append('+');
urlEncode(tenant, sb); urlEncode(tenant, sb);
} }
return sb.toString(); return sb.toString();
} }
static public String getKey(String dataId, String group, String datumStr) { static public String getKey(String dataId, String group, String datumStr) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
urlEncode(dataId, sb); urlEncode(dataId, sb);
sb.append('+'); sb.append('+');
urlEncode(group, sb); urlEncode(group, sb);
sb.append('+'); sb.append('+');
urlEncode(datumStr, sb); urlEncode(datumStr, sb);
return sb.toString(); return sb.toString();
} }
static public String[] parseKey(String groupKey) { static public String[] parseKey(String groupKey) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String dataId = null; String dataId = null;
@ -64,15 +63,15 @@ public class GroupKey {
for (int i = 0; i < groupKey.length(); ++i) { for (int i = 0; i < groupKey.length(); ++i) {
char c = groupKey.charAt(i); char c = groupKey.charAt(i);
if ('+' == c) { if ('+' == c) {
if (null == dataId) { if (null == dataId) {
dataId = sb.toString(); dataId = sb.toString();
sb.setLength(0); sb.setLength(0);
} else if (null == group) { } else if (null == group) {
group = sb.toString(); group = sb.toString();
sb.setLength(0); sb.setLength(0);
} else { } else {
throw new IllegalArgumentException("invalid groupkey:" + groupKey); throw new IllegalArgumentException("invalid groupkey:" + groupKey);
} }
} else if ('%' == c) { } else if ('%' == c) {
char next = groupKey.charAt(++i); char next = groupKey.charAt(++i);
char nextnext = groupKey.charAt(++i); char nextnext = groupKey.charAt(++i);
@ -87,25 +86,24 @@ public class GroupKey {
sb.append(c); sb.append(c);
} }
} }
if (StringUtils.isBlank(group)) { if (StringUtils.isBlank(group)) {
group = sb.toString(); group = sb.toString();
if (group.length() == 0) { if (group.length() == 0) {
throw new IllegalArgumentException("invalid groupkey:" + groupKey); throw new IllegalArgumentException("invalid groupkey:" + groupKey);
} }
} else { } else {
tenant = sb.toString(); tenant = sb.toString();
if (group.length() == 0) { if (group.length() == 0) {
throw new IllegalArgumentException("invalid groupkey:" + groupKey); throw new IllegalArgumentException("invalid groupkey:" + groupKey);
} }
} }
return new String[] { dataId, group, tenant }; return new String[] {dataId, group, tenant};
} }
/** /**
* + -> %2B * + -> %2B % -> %25
* % -> %25
*/ */
static void urlEncode(String str, StringBuilder sb) { static void urlEncode(String str, StringBuilder sb) {
for (int idx = 0; idx < str.length(); ++idx) { for (int idx = 0; idx < str.length(); ++idx) {

View File

@ -22,22 +22,21 @@ import com.alibaba.nacos.api.config.filter.IConfigContext;
/** /**
* Config Context * Config Context
*
* @author Nacos
* *
* @author Nacos
*/ */
public class ConfigContext implements IConfigContext { public class ConfigContext implements IConfigContext {
private Map<String, Object> param = new HashMap<String, Object>(); private Map<String, Object> param = new HashMap<String, Object>();
@Override @Override
public Object getParameter(String key) { public Object getParameter(String key) {
return param.get(key); return param.get(key);
} }
@Override @Override
public void setParameter(String key, Object value) { public void setParameter(String key, Object value) {
param.put(key, value); param.put(key, value);
} }
} }

View File

@ -26,62 +26,60 @@ import com.google.common.collect.Lists;
/** /**
* Config Filter Chain Management * Config Filter Chain Management
*
* @author Nacos
* *
* @author Nacos
*/ */
public class ConfigFilterChainManager implements IConfigFilterChain { public class ConfigFilterChainManager implements IConfigFilterChain {
private List<IConfigFilter> filters = Lists.newArrayList(); private List<IConfigFilter> filters = Lists.newArrayList();
public synchronized ConfigFilterChainManager addFilter(IConfigFilter filter) { public synchronized ConfigFilterChainManager addFilter(IConfigFilter filter) {
// 根据order大小顺序插入 // 根据order大小顺序插入
int i = 0; int i = 0;
while (i < this.filters.size()) { while (i < this.filters.size()) {
IConfigFilter currentValue = this.filters.get(i); IConfigFilter currentValue = this.filters.get(i);
if (currentValue.getFilterName().equals(filter.getFilterName())) { if (currentValue.getFilterName().equals(filter.getFilterName())) {
break; break;
} }
if (filter.getOrder() >= currentValue.getOrder() && i < this.filters.size()) { if (filter.getOrder() >= currentValue.getOrder() && i < this.filters.size()) {
i++; i++;
} else { } else {
this.filters.add(i, filter); this.filters.add(i, filter);
break; break;
} }
} }
if (i == this.filters.size()) { if (i == this.filters.size()) {
this.filters.add(i, filter); this.filters.add(i, filter);
} }
return this; return this;
} }
@Override @Override
public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException { public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException {
new VirtualFilterChain(this.filters).doFilter(request, response); new VirtualFilterChain(this.filters).doFilter(request, response);
} }
private static class VirtualFilterChain implements IConfigFilterChain { private static class VirtualFilterChain implements IConfigFilterChain {
private final List<? extends IConfigFilter> additionalFilters; private final List<? extends IConfigFilter> additionalFilters;
private int currentPosition = 0; private int currentPosition = 0;
public VirtualFilterChain(List<? extends IConfigFilter> additionalFilters) { public VirtualFilterChain(List<? extends IConfigFilter> additionalFilters) {
this.additionalFilters = additionalFilters; this.additionalFilters = additionalFilters;
} }
@Override @Override
public void doFilter(final IConfigRequest request, final IConfigResponse response) throws NacosException { public void doFilter(final IConfigRequest request, final IConfigResponse response) throws NacosException {
if (this.currentPosition == this.additionalFilters.size()) { if (this.currentPosition == this.additionalFilters.size()) {
return; return;
} else { } else {
this.currentPosition++; this.currentPosition++;
IConfigFilter nextFilter = this.additionalFilters.get(this.currentPosition - 1); IConfigFilter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
nextFilter.doFilter(request, response, this); nextFilter.doFilter(request, response, this);
} }
} }
} }
} }

View File

@ -23,56 +23,55 @@ import com.alibaba.nacos.api.config.filter.IConfigRequest;
/** /**
* Config Request * Config Request
*
* @author Nacos
* *
* @author Nacos
*/ */
public class ConfigRequest implements IConfigRequest { public class ConfigRequest implements IConfigRequest {
private Map<String, Object> param = new HashMap<String, Object>(); private Map<String, Object> param = new HashMap<String, Object>();
private IConfigContext configContext = new ConfigContext(); private IConfigContext configContext = new ConfigContext();
public String getTenant() { public String getTenant() {
return (String) param.get("tenant"); return (String)param.get("tenant");
} }
public void setTenant(String tenant) { public void setTenant(String tenant) {
param.put("tenant", tenant); param.put("tenant", tenant);
} }
public String getDataId() { public String getDataId() {
return (String) param.get("dataId"); return (String)param.get("dataId");
} }
public void setDataId(String dataId) { public void setDataId(String dataId) {
param.put("dataId", dataId); param.put("dataId", dataId);
} }
public String getGroup() { public String getGroup() {
return (String) param.get("group"); return (String)param.get("group");
} }
public void setGroup(String group) { public void setGroup(String group) {
param.put("group", group); param.put("group", group);
} }
public String getContent() { public String getContent() {
return (String) param.get("content"); return (String)param.get("content");
} }
public void setContent(String content) { public void setContent(String content) {
param.put("content", content); param.put("content", content);
} }
@Override @Override
public Object getParameter(String key) { public Object getParameter(String key) {
return param.get(key); return param.get(key);
} }
@Override @Override
public IConfigContext getConfigContext() { public IConfigContext getConfigContext() {
return configContext; return configContext;
} }
} }

View File

@ -23,56 +23,55 @@ import com.alibaba.nacos.api.config.filter.IConfigResponse;
/** /**
* Config Response * Config Response
*
* @author Nacos
* *
* @author Nacos
*/ */
public class ConfigResponse implements IConfigResponse { public class ConfigResponse implements IConfigResponse {
private Map<String, Object> param = new HashMap<String, Object>(); private Map<String, Object> param = new HashMap<String, Object>();
private IConfigContext configContext = new ConfigContext(); private IConfigContext configContext = new ConfigContext();
public String getTenant() { public String getTenant() {
return (String) param.get("tenant"); return (String)param.get("tenant");
} }
public void setTenant(String tenant) { public void setTenant(String tenant) {
param.put("tenant", tenant); param.put("tenant", tenant);
} }
public String getDataId() { public String getDataId() {
return (String) param.get("dataId"); return (String)param.get("dataId");
} }
public void setDataId(String dataId) { public void setDataId(String dataId) {
param.put("dataId", dataId); param.put("dataId", dataId);
} }
public String getGroup() { public String getGroup() {
return (String) param.get("group"); return (String)param.get("group");
} }
public void setGroup(String group) { public void setGroup(String group) {
param.put("group", group); param.put("group", group);
} }
public String getContent() { public String getContent() {
return (String) param.get("content"); return (String)param.get("content");
} }
public void setContent(String content) { public void setContent(String content) {
param.put("content", content); param.put("content", content);
} }
@Override @Override
public Object getParameter(String key) { public Object getParameter(String key) {
return param.get(key); return param.get(key);
} }
@Override @Override
public IConfigContext getConfigContext() { public IConfigContext getConfigContext() {
return configContext; return configContext;
} }
} }

View File

@ -32,56 +32,54 @@ import java.util.concurrent.CopyOnWriteArrayList;
/** /**
* Listner Management * Listner Management
*
* @author Nacos
* *
* @author Nacos
*/ */
public class CacheData { public class CacheData {
final static public Logger log = LogUtils.logger(CacheData.class); final static public Logger log = LogUtils.logger(CacheData.class);
public boolean isInitializing() {
return isInitializing;
}
public void setInitializing(boolean isInitializing) { public boolean isInitializing() {
this.isInitializing = isInitializing; return isInitializing;
} }
public String getMd5() { public void setInitializing(boolean isInitializing) {
this.isInitializing = isInitializing;
}
public String getMd5() {
return md5; return md5;
} }
public String getTenant() { public String getTenant() {
return tenant; return tenant;
} }
public String getContent() { public String getContent() {
return content; return content;
} }
public void setContent(String newContent) { public void setContent(String newContent) {
this.content = newContent; this.content = newContent;
this.md5 = getMd5String(content); this.md5 = getMd5String(content);
} }
/** /**
* Add listener * Add listener
* *
* @param listener * @param listener listener
* listener */
*/ public void addListener(Listener listener) {
public void addListener(Listener listener) { if (null == listener) {
if (null == listener) { throw new IllegalArgumentException("listener is null");
throw new IllegalArgumentException("listener is null"); }
} ManagerListenerWrap wrap = new ManagerListenerWrap(listener);
ManagerListenerWrap wrap = new ManagerListenerWrap(listener); if (listeners.addIfAbsent(wrap)) {
if (listeners.addIfAbsent(wrap)) { log.info(name, "[add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", tenant, dataId, group,
log.info(name, "[add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", tenant, dataId, group, listeners.size());
listeners.size()); }
} }
}
public void removeListener(Listener listener) { public void removeListener(Listener listener) {
if (null == listener) { if (null == listener) {
throw new IllegalArgumentException("listener is null"); throw new IllegalArgumentException("listener is null");
@ -91,7 +89,7 @@ public class CacheData {
log.info(name, "[remove-listener] ok, dataId={}, group={}, cnt={}", dataId, group, listeners.size()); log.info(name, "[remove-listener] ok, dataId={}, group={}, cnt={}", dataId, group, listeners.size());
} }
} }
/** /**
* 返回监听器列表上的迭代器只读保证不返回NULL * 返回监听器列表上的迭代器只读保证不返回NULL
*/ */
@ -103,32 +101,32 @@ public class CacheData {
return result; return result;
} }
public long getLocalConfigInfoVersion() { public long getLocalConfigInfoVersion() {
return localConfigLastModified; return localConfigLastModified;
} }
public void setLocalConfigInfoVersion(long localConfigLastModified) { public void setLocalConfigInfoVersion(long localConfigLastModified) {
this.localConfigLastModified = localConfigLastModified; this.localConfigLastModified = localConfigLastModified;
} }
public boolean isUseLocalConfigInfo() { public boolean isUseLocalConfigInfo() {
return isUseLocalConfig; return isUseLocalConfig;
} }
public void setUseLocalConfigInfo(boolean useLocalConfigInfo) { public void setUseLocalConfigInfo(boolean useLocalConfigInfo) {
this.isUseLocalConfig = useLocalConfigInfo; this.isUseLocalConfig = useLocalConfigInfo;
if (!useLocalConfigInfo) { if (!useLocalConfigInfo) {
localConfigLastModified = -1; localConfigLastModified = -1;
} }
} }
public int getTaskId() {
return taskId;
}
public void setTaskId(int taskId) { public int getTaskId() {
this.taskId = taskId; return taskId;
} }
public void setTaskId(int taskId) {
this.taskId = taskId;
}
@Override @Override
public int hashCode() { public int hashCode() {
@ -147,7 +145,7 @@ public class CacheData {
if (this == obj) { if (this == obj) {
return true; return true;
} }
CacheData other = (CacheData) obj; CacheData other = (CacheData)obj;
return dataId.equals(other.dataId) && group.equals(other.group); return dataId.equals(other.dataId) && group.equals(other.group);
} }
@ -155,7 +153,7 @@ public class CacheData {
public String toString() { public String toString() {
return "CacheData [" + dataId + ", " + group + "]"; return "CacheData [" + dataId + ", " + group + "]";
} }
void checkListenerMd5() { void checkListenerMd5() {
for (ManagerListenerWrap wrap : listeners) { for (ManagerListenerWrap wrap : listeners) {
if (!md5.equals(wrap.lastCallMd5)) { if (!md5.equals(wrap.lastCallMd5)) {
@ -163,48 +161,46 @@ public class CacheData {
} }
} }
} }
private void safeNotifyListener(final String dataId, final String group, final String content, private void safeNotifyListener(final String dataId, final String group, final String content,
final String md5, final ManagerListenerWrap listenerWrap) { final String md5, final ManagerListenerWrap listenerWrap) {
final Listener listener = listenerWrap.listener; final Listener listener = listenerWrap.listener;
Runnable job = new Runnable() { Runnable job = new Runnable() {
public void run() { public void run() {
ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader(); ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader appClassLoader= listener.getClass().getClassLoader(); ClassLoader appClassLoader = listener.getClass().getClassLoader();
try { try {
if(listener instanceof AbstractSharedListener){ if (listener instanceof AbstractSharedListener) {
AbstractSharedListener adapter = (AbstractSharedListener) listener; AbstractSharedListener adapter = (AbstractSharedListener)listener;
adapter.fillContext(dataId, group); adapter.fillContext(dataId, group);
log.info(name, "[notify-context] dataId={}, group={}, md5={}", dataId, group, md5); log.info(name, "[notify-context] dataId={}, group={}, md5={}", dataId, group, md5);
} }
// 执行回调之前先将线程classloader设置为具体webapp的classloader以免回调方法中调用spi接口是出现异常或错用多应用部署才会有该问题 // 执行回调之前先将线程classloader设置为具体webapp的classloader以免回调方法中调用spi接口是出现异常或错用多应用部署才会有该问题
Thread.currentThread().setContextClassLoader(appClassLoader); Thread.currentThread().setContextClassLoader(appClassLoader);
ConfigResponse cr = new ConfigResponse(); ConfigResponse cr = new ConfigResponse();
cr.setDataId(dataId); cr.setDataId(dataId);
cr.setGroup(group); cr.setGroup(group);
cr.setContent(content); cr.setContent(content);
configFilterChainManager.doFilter(null, cr); configFilterChainManager.doFilter(null, cr);
String contentTmp = cr.getContent(); String contentTmp = cr.getContent();
listener.receiveConfigInfo(contentTmp); listener.receiveConfigInfo(contentTmp);
listenerWrap.lastCallMd5 = md5; listenerWrap.lastCallMd5 = md5;
log.info( log.info(
name, name,
"[notify-ok] dataId={}, group={}, md5={}, listener={} ", "[notify-ok] dataId={}, group={}, md5={}, listener={} ",
dataId, group, md5, listener); dataId, group, md5, listener);
} catch (NacosException de) { } catch (NacosException de) {
log.error(name, "NACOS-XXXX", log.error(name, "NACOS-XXXX",
"[notify-error] dataId={}, group={}, md5={}, listener={} errCode={} errMsg={}", dataId, "[notify-error] dataId={}, group={}, md5={}, listener={} errCode={} errMsg={}", dataId,
group, md5, listener, de.getErrCode(), de.getErrMsg()); group, md5, listener, de.getErrCode(), de.getErrMsg());
} catch (Throwable t) { } catch (Throwable t) {
log.error(name, "NACOS-XXXX", log.error(name, "NACOS-XXXX",
"[notify-error] dataId={}, group={}, md5={}, listener={} tx={}", dataId, group, md5, "[notify-error] dataId={}, group={}, md5={}, listener={} tx={}", dataId, group, md5,
listener, t.getCause()); listener, t.getCause());
} } finally {
finally Thread.currentThread().setContextClassLoader(myClassLoader);
{
Thread.currentThread().setContextClassLoader(myClassLoader);
} }
} }
}; };
@ -217,57 +213,59 @@ public class CacheData {
job.run(); job.run();
} }
} catch (Throwable t) { } catch (Throwable t) {
log.error( log.error(
name, name,
"NACOS-XXXX", "NACOS-XXXX",
"[notify-error] dataId={}, group={}, md5={}, listener={} throwable={}", "[notify-error] dataId={}, group={}, md5={}, listener={} throwable={}",
dataId, group, md5, listener, t.getCause()); dataId, group, md5, listener, t.getCause());
} }
final long finishNotify = System.currentTimeMillis(); final long finishNotify = System.currentTimeMillis();
log.info(name, "[notify-listener] time cost={}ms in ClientWorker, dataId={}, group={}, md5={}, listener={} ",(finishNotify - startNotify), dataId ,group, md5, listener); log.info(name, "[notify-listener] time cost={}ms in ClientWorker, dataId={}, group={}, md5={}, listener={} ",
(finishNotify - startNotify), dataId, group, md5, listener);
} }
static public String getMd5String(String config) { static public String getMd5String(String config) {
return (null == config) ? Constants.NULL : MD5.getInstance().getMD5String(config); return (null == config) ? Constants.NULL : MD5.getInstance().getMD5String(config);
} }
private String loadCacheContentFromDiskLocal(String name, String dataId, String group, String tenant) { private String loadCacheContentFromDiskLocal(String name, String dataId, String group, String tenant) {
String content = LocalConfigInfoProcessor.getFailover(name, dataId, group, tenant); String content = LocalConfigInfoProcessor.getFailover(name, dataId, group, tenant);
content = (null != content) ? content content = (null != content) ? content
: LocalConfigInfoProcessor.getSnapshot(name, dataId, group, tenant); : LocalConfigInfoProcessor.getSnapshot(name, dataId, group, tenant);
return content; return content;
} }
public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group) { public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group) {
if (null == dataId || null == group) { if (null == dataId || null == group) {
throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group); throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group);
} }
this.name = name; this.name = name;
this.configFilterChainManager = configFilterChainManager; this.configFilterChainManager = configFilterChainManager;
this.dataId = dataId; this.dataId = dataId;
this.group = group; this.group = group;
this.tenant = TenantUtil.getUserTenant(); this.tenant = TenantUtil.getUserTenant();
listeners = new CopyOnWriteArrayList<ManagerListenerWrap>(); listeners = new CopyOnWriteArrayList<ManagerListenerWrap>();
this.isInitializing = true; this.isInitializing = true;
this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant); this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
this.md5 = getMd5String(content); this.md5 = getMd5String(content);
} }
public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group, String tenant) { public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group,
if (null == dataId || null == group) { String tenant) {
throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group); if (null == dataId || null == group) {
} throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group);
this.name = name; }
this.configFilterChainManager = configFilterChainManager; this.name = name;
this.dataId = dataId; this.configFilterChainManager = configFilterChainManager;
this.group = group; this.dataId = dataId;
this.tenant = tenant; this.group = group;
listeners = new CopyOnWriteArrayList<ManagerListenerWrap>(); this.tenant = tenant;
this.isInitializing = true; listeners = new CopyOnWriteArrayList<ManagerListenerWrap>();
this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant); this.isInitializing = true;
this.md5 = getMd5String(content); this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
this.md5 = getMd5String(content);
} }
// ================== // ==================
private final String name; private final String name;
@ -277,16 +275,16 @@ public class CacheData {
public final String tenant; public final String tenant;
private final CopyOnWriteArrayList<ManagerListenerWrap> listeners; private final CopyOnWriteArrayList<ManagerListenerWrap> listeners;
private volatile String md5; private volatile String md5;
/** /**
* whether use local config * whether use local config
*/ */
private volatile boolean isUseLocalConfig = false; private volatile boolean isUseLocalConfig = false;
/** /**
* last motify time * last motify time
*/ */
private volatile long localConfigLastModified; private volatile long localConfigLastModified;
private volatile String content; private volatile String content;
private int taskId; private int taskId;
private volatile boolean isInitializing = true; private volatile boolean isInitializing = true;
} }
@ -307,13 +305,13 @@ class ManagerListenerWrap {
if (obj == this) { if (obj == this) {
return true; return true;
} }
ManagerListenerWrap other = (ManagerListenerWrap) obj; ManagerListenerWrap other = (ManagerListenerWrap)obj;
return listener.equals(other.listener); return listener.equals(other.listener);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return super.hashCode(); return super.hashCode();
} }
} }

View File

@ -44,24 +44,23 @@ import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR;
/** /**
* Longpulling * Longpulling
*
* @author Nacos
* *
* @author Nacos
*/ */
public class ClientWorker { public class ClientWorker {
final static public Logger log = LogUtils.logger(ClientWorker.class);
public void addListeners(String dataId, String group, List<? extends Listener> listeners) { final static public Logger log = LogUtils.logger(ClientWorker.class);
public void addListeners(String dataId, String group, List<? extends Listener> listeners) {
group = null2defaultGroup(group); group = null2defaultGroup(group);
CacheData cache = addCacheDataIfAbsent(dataId, group); CacheData cache = addCacheDataIfAbsent(dataId, group);
for (Listener listener : listeners) { for (Listener listener : listeners) {
cache.addListener(listener); cache.addListener(listener);
} }
} }
public void removeListener(String dataId, String group, Listener listener) { public void removeListener(String dataId, String group, Listener listener) {
group = null2defaultGroup(group); group = null2defaultGroup(group);
CacheData cache = getCache(dataId, group); CacheData cache = getCache(dataId, group);
if (null != cache) { if (null != cache) {
cache.removeListener(listener); cache.removeListener(listener);
@ -69,30 +68,30 @@ public class ClientWorker {
removeCache(dataId, group); removeCache(dataId, group);
} }
} }
} }
public void addTenantListeners(String dataId, String group, List<? extends Listener> listeners) { public void addTenantListeners(String dataId, String group, List<? extends Listener> listeners) {
group = null2defaultGroup(group); group = null2defaultGroup(group);
String tenant = agent.getTenant(); String tenant = agent.getTenant();
CacheData cache = addCacheDataIfAbsent(dataId, group, tenant); CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
for (Listener listener : listeners) { for (Listener listener : listeners) {
cache.addListener(listener); cache.addListener(listener);
} }
} }
public void removeTenantListener(String dataId, String group, Listener listener) { public void removeTenantListener(String dataId, String group, Listener listener) {
group = null2defaultGroup(group); group = null2defaultGroup(group);
String tenant = agent.getTenant(); String tenant = agent.getTenant();
CacheData cache = getCache(dataId, group, tenant); CacheData cache = getCache(dataId, group, tenant);
if (null != cache) { if (null != cache) {
cache.removeListener(listener); cache.removeListener(listener);
if (cache.getListeners().isEmpty()) { if (cache.getListeners().isEmpty()) {
removeCache(dataId, group, tenant); removeCache(dataId, group, tenant);
} }
} }
} }
@SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER") @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
void removeCache(String dataId, String group) { void removeCache(String dataId, String group) {
String groupKey = GroupKey.getKey(dataId, group); String groupKey = GroupKey.getKey(dataId, group);
synchronized (cacheMap) { synchronized (cacheMap) {
@ -102,20 +101,20 @@ public class ClientWorker {
} }
log.info(agent.getName(), "[unsubscribe] {}", groupKey); log.info(agent.getName(), "[unsubscribe] {}", groupKey);
} }
@SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER") @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
void removeCache(String dataId, String group, String tenant) { void removeCache(String dataId, String group, String tenant) {
String groupKey = GroupKey.getKeyTenant(dataId, group, tenant); String groupKey = GroupKey.getKeyTenant(dataId, group, tenant);
synchronized (cacheMap) { synchronized (cacheMap) {
Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get()); Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
copy.remove(groupKey); copy.remove(groupKey);
cacheMap.set(copy); cacheMap.set(copy);
} }
log.info(agent.getName(), "[unsubscribe] {}", groupKey); log.info(agent.getName(), "[unsubscribe] {}", groupKey);
} }
@SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER") @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
public CacheData addCacheDataIfAbsent(String dataId, String group) { public CacheData addCacheDataIfAbsent(String dataId, String group) {
CacheData cache = getCache(dataId, group); CacheData cache = getCache(dataId, group);
if (null != cache) { if (null != cache) {
return cache; return cache;
@ -123,408 +122,409 @@ public class ClientWorker {
String key = GroupKey.getKey(dataId, group); String key = GroupKey.getKey(dataId, group);
cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group); cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group);
synchronized (cacheMap) { synchronized (cacheMap) {
CacheData cacheFromMap = getCache(dataId, group); CacheData cacheFromMap = getCache(dataId, group);
// multiple listeners on the same dataid+group and race condition,so double check again // multiple listeners on the same dataid+group and race condition,so double check again
//other listener thread beat me to set to cacheMap //other listener thread beat me to set to cacheMap
if(null != cacheFromMap) { if (null != cacheFromMap) {
cache = cacheFromMap; cache = cacheFromMap;
//reset so that server not hang this check //reset so that server not hang this check
cache.setInitializing(true); cache.setInitializing(true);
} else { } else {
int taskId = cacheMap.get().size() / (int) ParamUtil.getPerTaskConfigSize(); int taskId = cacheMap.get().size() / (int)ParamUtil.getPerTaskConfigSize();
cache.setTaskId(taskId); cache.setTaskId(taskId);
} }
Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get()); Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
copy.put(key, cache); copy.put(key, cache);
cacheMap.set(copy); cacheMap.set(copy);
} }
log.info(agent.getName(), "[subscribe] {}", key); log.info(agent.getName(), "[subscribe] {}", key);
return cache; return cache;
} }
@SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
public CacheData addCacheDataIfAbsent(String dataId, String group, String tenant) {
CacheData cache = getCache(dataId, group, tenant);
if (null != cache) {
return cache;
}
String key = GroupKey.getKeyTenant(dataId, group, tenant);
cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant);
synchronized (cacheMap) {
CacheData cacheFromMap = getCache(dataId, group, tenant);
// multiple listeners on the same dataid+group and race condition,so
// double check again
// other listener thread beat me to set to cacheMap
if (null != cacheFromMap) {
cache = cacheFromMap;
// reset so that server not hang this check
cache.setInitializing(true);
}
Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get()); @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
copy.put(key, cache); public CacheData addCacheDataIfAbsent(String dataId, String group, String tenant) {
cacheMap.set(copy); CacheData cache = getCache(dataId, group, tenant);
} if (null != cache) {
log.info(agent.getName(), "[subscribe] {}", key); return cache;
return cache; }
} String key = GroupKey.getKeyTenant(dataId, group, tenant);
cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant);
public CacheData getCache(String dataId, String group) { synchronized (cacheMap) {
return getCache(dataId, group, TenantUtil.getUserTenant()); CacheData cacheFromMap = getCache(dataId, group, tenant);
} // multiple listeners on the same dataid+group and race condition,so
// double check again
public CacheData getCache(String dataId, String group, String tenant) { // other listener thread beat me to set to cacheMap
if (null == dataId || null == group) { if (null != cacheFromMap) {
throw new IllegalArgumentException(); cache = cacheFromMap;
} // reset so that server not hang this check
return cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant)); cache.setInitializing(true);
} }
public String getServerConfig(String dataId, String group, String tenant, long readTimeout) Map<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
throws NacosException { copy.put(key, cache);
if (StringUtils.isBlank(group)) { cacheMap.set(copy);
group = Constants.DEFAULT_GROUP; }
} log.info(agent.getName(), "[subscribe] {}", key);
return cache;
}
HttpResult result = null; public CacheData getCache(String dataId, String group) {
try { return getCache(dataId, group, TenantUtil.getUserTenant());
List<String> params = null; }
if (StringUtils.isBlank(tenant)) {
params = Arrays.asList("dataId", dataId, "group", group);
} else {
params = Arrays.asList("dataId", dataId, "group", group, "tenant", tenant);
}
result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
} catch (IOException e) {
log.error(agent.getName(), "NACOS-XXXX",
"[sub-server] get server config exception, dataId={}, group={}, tenant={}, msg={}", dataId, group,
tenant, e.toString());
throw new NacosException(NacosException.SERVER_ERROR, e.getMessage());
}
switch (result.code) { public CacheData getCache(String dataId, String group, String tenant) {
case HttpURLConnection.HTTP_OK: if (null == dataId || null == group) {
LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content); throw new IllegalArgumentException();
return result.content; }
case HttpURLConnection.HTTP_NOT_FOUND: return cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null); }
return null;
case HttpURLConnection.HTTP_CONFLICT: {
log.error(agent.getName(), "NACOS-XXXX",
"[sub-server-error] get server config being modified concurrently, dataId={}, group={}, tenant={}",
dataId, group, tenant);
throw new NacosException(NacosException.CONFLICT,
"data being modified, dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
}
case HttpURLConnection.HTTP_FORBIDDEN: {
log.error(agent.getName(), "NACOS-XXXX", "[sub-server-error] no right, dataId={}, group={}, tenant={}",
dataId, group, tenant);
throw new NacosException(result.code, result.content);
}
default: {
log.error(agent.getName(), "NACOS-XXXX", "[sub-server-error] dataId={}, group={}, tenant={}, code={}",
dataId, group, tenant, result.code);
throw new NacosException(result.code,
"http error, code=" + result.code + ",dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
}
}
}
private void checkLocalConfig(CacheData cacheData) { public String getServerConfig(String dataId, String group, String tenant, long readTimeout)
final String dataId = cacheData.dataId; throws NacosException {
final String group = cacheData.group; if (StringUtils.isBlank(group)) {
final String tenant = cacheData.tenant; group = Constants.DEFAULT_GROUP;
File path = LocalConfigInfoProcessor.getFailoverFile(agent.getName(), dataId, group, tenant); }
// 没有 -> HttpResult result = null;
if (!cacheData.isUseLocalConfigInfo() && path.exists()) { try {
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant); List<String> params = null;
String md5 = MD5.getInstance().getMD5String(content); if (StringUtils.isBlank(tenant)) {
cacheData.setUseLocalConfigInfo(true); params = Arrays.asList("dataId", dataId, "group", group);
cacheData.setLocalConfigInfoVersion(path.lastModified()); } else {
cacheData.setContent(content); params = Arrays.asList("dataId", dataId, "group", group, "tenant", tenant);
}
result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
} catch (IOException e) {
log.error(agent.getName(), "NACOS-XXXX",
"[sub-server] get server config exception, dataId={}, group={}, tenant={}, msg={}", dataId, group,
tenant, e.toString());
throw new NacosException(NacosException.SERVER_ERROR, e.getMessage());
}
log.warn(agent.getName(), switch (result.code) {
"[failover-change] failover file created. dataId={}, group={}, tenant={}, md5={}, content={}", case HttpURLConnection.HTTP_OK:
dataId, group, tenant, md5, ContentUtils.truncateContent(content)); LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content);
return; return result.content;
} case HttpURLConnection.HTTP_NOT_FOUND:
LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null);
return null;
case HttpURLConnection.HTTP_CONFLICT: {
log.error(agent.getName(), "NACOS-XXXX",
"[sub-server-error] get server config being modified concurrently, dataId={}, group={}, tenant={}",
dataId, group, tenant);
throw new NacosException(NacosException.CONFLICT,
"data being modified, dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
}
case HttpURLConnection.HTTP_FORBIDDEN: {
log.error(agent.getName(), "NACOS-XXXX", "[sub-server-error] no right, dataId={}, group={}, tenant={}",
dataId, group, tenant);
throw new NacosException(result.code, result.content);
}
default: {
log.error(agent.getName(), "NACOS-XXXX", "[sub-server-error] dataId={}, group={}, tenant={}, code={}",
dataId, group, tenant, result.code);
throw new NacosException(result.code,
"http error, code=" + result.code + ",dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
}
}
}
// -> 没有不通知业务监听器从server拿到配置后通知 private void checkLocalConfig(CacheData cacheData) {
if (cacheData.isUseLocalConfigInfo() && !path.exists()) { final String dataId = cacheData.dataId;
cacheData.setUseLocalConfigInfo(false); final String group = cacheData.group;
log.warn(agent.getName(), "[failover-change] failover file deleted. dataId={}, group={}, tenant={}", dataId, final String tenant = cacheData.tenant;
group, tenant); File path = LocalConfigInfoProcessor.getFailoverFile(agent.getName(), dataId, group, tenant);
return;
} // 没有 ->
if (!cacheData.isUseLocalConfigInfo() && path.exists()) {
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
String md5 = MD5.getInstance().getMD5String(content);
cacheData.setUseLocalConfigInfo(true);
cacheData.setLocalConfigInfoVersion(path.lastModified());
cacheData.setContent(content);
log.warn(agent.getName(),
"[failover-change] failover file created. dataId={}, group={}, tenant={}, md5={}, content={}",
dataId, group, tenant, md5, ContentUtils.truncateContent(content));
return;
}
// -> 没有不通知业务监听器从server拿到配置后通知
if (cacheData.isUseLocalConfigInfo() && !path.exists()) {
cacheData.setUseLocalConfigInfo(false);
log.warn(agent.getName(), "[failover-change] failover file deleted. dataId={}, group={}, tenant={}", dataId,
group, tenant);
return;
}
// 有变更
if (cacheData.isUseLocalConfigInfo() && path.exists()
&& cacheData.getLocalConfigInfoVersion() != path.lastModified()) {
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
String md5 = MD5.getInstance().getMD5String(content);
cacheData.setUseLocalConfigInfo(true);
cacheData.setLocalConfigInfoVersion(path.lastModified());
cacheData.setContent(content);
log.warn(agent.getName(),
"[failover-change] failover file changed. dataId={}, group={}, tenant={}, md5={}, content={}",
dataId, group, tenant, md5, ContentUtils.truncateContent(content));
return;
}
}
// 有变更
if (cacheData.isUseLocalConfigInfo() && path.exists()
&& cacheData.getLocalConfigInfoVersion() != path.lastModified()) {
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
String md5 = MD5.getInstance().getMD5String(content);
cacheData.setUseLocalConfigInfo(true);
cacheData.setLocalConfigInfoVersion(path.lastModified());
cacheData.setContent(content);
log.warn(agent.getName(),
"[failover-change] failover file changed. dataId={}, group={}, tenant={}, md5={}, content={}",
dataId, group, tenant, md5, ContentUtils.truncateContent(content));
return;
}
}
private String null2defaultGroup(String group) { private String null2defaultGroup(String group) {
return (null == group) ? Constants.DEFAULT_GROUP : group.trim(); return (null == group) ? Constants.DEFAULT_GROUP : group.trim();
} }
public void checkConfigInfo() {
// 分任务
int listenerSize = cacheMap.get().size();
// 向上取整为批数
int longingTaskCount = (int) Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
if (longingTaskCount > currentLongingTaskCount) {
for (int i = (int) currentLongingTaskCount; i < longingTaskCount; i++) {
// 要判断任务是否在执行 这块需要好好想想 任务列表现在是无序的变化过程可能有问题
executorService.execute(new LongPullingRunnable(i));
}
currentLongingTaskCount = longingTaskCount;
}
}
/** public void checkConfigInfo() {
* 从Server获取值变化了的DataID列表返回的对象里只有dataId和group是有效的 保证不返回NULL // 分任务
*/ int listenerSize = cacheMap.get().size();
List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> inInitializingCacheList) { // 向上取整为批数
StringBuilder sb = new StringBuilder(); int longingTaskCount = (int)Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
for (CacheData cacheData : cacheDatas) { if (longingTaskCount > currentLongingTaskCount) {
if (!cacheData.isUseLocalConfigInfo()) { for (int i = (int)currentLongingTaskCount; i < longingTaskCount; i++) {
sb.append(cacheData.dataId).append(WORD_SEPARATOR); // 要判断任务是否在执行 这块需要好好想想 任务列表现在是无序的变化过程可能有问题
sb.append(cacheData.group).append(WORD_SEPARATOR); executorService.execute(new LongPullingRunnable(i));
if (StringUtils.isBlank(cacheData.tenant)) { }
sb.append(cacheData.getMd5()).append(LINE_SEPARATOR); currentLongingTaskCount = longingTaskCount;
} else { }
sb.append(cacheData.getMd5()).append(WORD_SEPARATOR); }
sb.append(cacheData.getTenant()).append(LINE_SEPARATOR);
}
if (cacheData.isInitializing()) {
// cacheData 首次出现在cacheMap中&首次check更新
inInitializingCacheList
.add(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant));
}
}
}
boolean isInitializingCacheList = !inInitializingCacheList.isEmpty();
return checkUpdateConfigStr(sb.toString(), isInitializingCacheList);
}
/** /**
* 从Server获取值变化了的DataID列表返回的对象里只有dataId和group是有效的 保证不返回NULL * 从Server获取值变化了的DataID列表返回的对象里只有dataId和group是有效的 保证不返回NULL
*/ */
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) { List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> inInitializingCacheList) {
StringBuilder sb = new StringBuilder();
for (CacheData cacheData : cacheDatas) {
if (!cacheData.isUseLocalConfigInfo()) {
sb.append(cacheData.dataId).append(WORD_SEPARATOR);
sb.append(cacheData.group).append(WORD_SEPARATOR);
if (StringUtils.isBlank(cacheData.tenant)) {
sb.append(cacheData.getMd5()).append(LINE_SEPARATOR);
} else {
sb.append(cacheData.getMd5()).append(WORD_SEPARATOR);
sb.append(cacheData.getTenant()).append(LINE_SEPARATOR);
}
if (cacheData.isInitializing()) {
// cacheData 首次出现在cacheMap中&首次check更新
inInitializingCacheList
.add(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant));
}
}
}
boolean isInitializingCacheList = !inInitializingCacheList.isEmpty();
return checkUpdateConfigStr(sb.toString(), isInitializingCacheList);
}
List<String> params = Arrays.asList(Constants.PROBE_MODIFY_REQUEST, probeUpdateString); /**
long timeout = TimeUnit.SECONDS.toMillis(30L); * 从Server获取值变化了的DataID列表返回的对象里只有dataId和group是有效的 保证不返回NULL
*/
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) {
List<String> headers = new ArrayList<String>(2); List<String> params = Arrays.asList(Constants.PROBE_MODIFY_REQUEST, probeUpdateString);
headers.add("Long-Pulling-Timeout"); long timeout = TimeUnit.SECONDS.toMillis(30L);
headers.add("" + timeout);
// told server do not hang me up if new initializing cacheData added in List<String> headers = new ArrayList<String>(2);
if (isInitializingCacheList) { headers.add("Long-Pulling-Timeout");
headers.add("Long-Pulling-Timeout-No-Hangup"); headers.add("" + timeout);
headers.add("true");
}
if (StringUtils.isBlank(probeUpdateString)) { // told server do not hang me up if new initializing cacheData added in
return Collections.emptyList(); if (isInitializingCacheList) {
} headers.add("Long-Pulling-Timeout-No-Hangup");
headers.add("true");
}
try { if (StringUtils.isBlank(probeUpdateString)) {
HttpResult result = agent.httpPost(Constants.CONFIG_CONTROLLER_PATH + "/listener", headers, params, return Collections.emptyList();
agent.getEncode(), timeout); }
if (HttpURLConnection.HTTP_OK == result.code) { try {
setHealthServer(true); HttpResult result = agent.httpPost(Constants.CONFIG_CONTROLLER_PATH + "/listener", headers, params,
return parseUpdateDataIdResponse(result.content); agent.getEncode(), timeout);
} else {
setHealthServer(false);
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR) {
log.error("NACOS-0007", LoggerHelper.getErrorCodeStr("Nacos", "Nacos-0007", "环境问题",
"[check-update] get changed dataId error"));
}
log.error(agent.getName(), "NACOS-XXXX", "[check-update] get changed dataId error, code={}",
result.code);
}
} catch (IOException e) {
setHealthServer(false);
log.error(agent.getName(), "NACOS-XXXX", "[check-update] get changed dataId exception, msg={}",
e.toString());
}
return Collections.emptyList();
}
/** if (HttpURLConnection.HTTP_OK == result.code) {
* 从HTTP响应拿到变化的groupKey保证不返回NULL setHealthServer(true);
*/ return parseUpdateDataIdResponse(result.content);
private List<String> parseUpdateDataIdResponse(String response) { } else {
if (StringUtils.isBlank(response)) { setHealthServer(false);
return Collections.emptyList(); if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR) {
} log.error("NACOS-0007", LoggerHelper.getErrorCodeStr("Nacos", "Nacos-0007", "环境问题",
"[check-update] get changed dataId error"));
}
log.error(agent.getName(), "NACOS-XXXX", "[check-update] get changed dataId error, code={}",
result.code);
}
} catch (IOException e) {
setHealthServer(false);
log.error(agent.getName(), "NACOS-XXXX", "[check-update] get changed dataId exception, msg={}",
e.toString());
}
return Collections.emptyList();
}
try { /**
response = URLDecoder.decode(response, "UTF-8"); * 从HTTP响应拿到变化的groupKey保证不返回NULL
} catch (Exception e) { */
log.error(agent.getName(), "NACOS-XXXX", "[polling-resp] decode modifiedDataIdsString error", e); private List<String> parseUpdateDataIdResponse(String response) {
} if (StringUtils.isBlank(response)) {
return Collections.emptyList();
}
List<String> updateList = new LinkedList<String>(); try {
response = URLDecoder.decode(response, "UTF-8");
} catch (Exception e) {
log.error(agent.getName(), "NACOS-XXXX", "[polling-resp] decode modifiedDataIdsString error", e);
}
for (String dataIdAndGroup : response.split(LINE_SEPARATOR)) { List<String> updateList = new LinkedList<String>();
if (!StringUtils.isBlank(dataIdAndGroup)) {
String[] keyArr = dataIdAndGroup.split(WORD_SEPARATOR);
String dataId = keyArr[0];
String group = keyArr[1];
if (keyArr.length == 2) {
updateList.add(GroupKey.getKey(dataId, group));
log.info(agent.getName(), "[polling-resp] config changed. dataId={}, group={}", dataId, group);
} else if (keyArr.length == 3) {
String tenant = keyArr[2];
updateList.add(GroupKey.getKeyTenant(dataId, group, tenant));
log.info(agent.getName(), "[polling-resp] config changed. dataId={}, group={}, tenant={}", dataId,
group, tenant);
} else {
log.error(agent.getName(), "NACOS-XXXX", "[polling-resp] invalid dataIdAndGroup error",
dataIdAndGroup);
}
}
}
return updateList;
}
@SuppressWarnings("PMD.ThreadPoolCreationRule") for (String dataIdAndGroup : response.split(LINE_SEPARATOR)) {
public ClientWorker(final ServerHttpAgent agent, final ConfigFilterChainManager configFilterChainManager) { if (!StringUtils.isBlank(dataIdAndGroup)) {
this.agent = agent; String[] keyArr = dataIdAndGroup.split(WORD_SEPARATOR);
this.configFilterChainManager = configFilterChainManager; String dataId = keyArr[0];
executor = Executors.newScheduledThreadPool(1, new ThreadFactory() { String group = keyArr[1];
@Override if (keyArr.length == 2) {
public Thread newThread(Runnable r) { updateList.add(GroupKey.getKey(dataId, group));
Thread t = new Thread(r); log.info(agent.getName(), "[polling-resp] config changed. dataId={}, group={}", dataId, group);
t.setName("com.alibaba.nacos.client.Worker." + agent.getName()); } else if (keyArr.length == 3) {
t.setDaemon(true); String tenant = keyArr[2];
return t; updateList.add(GroupKey.getKeyTenant(dataId, group, tenant));
} log.info(agent.getName(), "[polling-resp] config changed. dataId={}, group={}, tenant={}", dataId,
}); group, tenant);
} else {
log.error(agent.getName(), "NACOS-XXXX", "[polling-resp] invalid dataIdAndGroup error",
dataIdAndGroup);
}
}
}
return updateList;
}
executorService = Executors.newCachedThreadPool(new ThreadFactory() { @SuppressWarnings("PMD.ThreadPoolCreationRule")
@Override public ClientWorker(final ServerHttpAgent agent, final ConfigFilterChainManager configFilterChainManager) {
public Thread newThread(Runnable r) { this.agent = agent;
Thread t = new Thread(r); this.configFilterChainManager = configFilterChainManager;
t.setName("com.alibaba.nacos.client.Worker.longPulling" + agent.getName()); executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
t.setDaemon(true); @Override
return t; public Thread newThread(Runnable r) {
} Thread t = new Thread(r);
}); t.setName("com.alibaba.nacos.client.Worker." + agent.getName());
t.setDaemon(true);
return t;
}
});
executor.scheduleWithFixedDelay(new Runnable() { executorService = Executors.newCachedThreadPool(new ThreadFactory() {
public void run() { @Override
try { public Thread newThread(Runnable r) {
checkConfigInfo(); Thread t = new Thread(r);
} catch (Throwable e) { t.setName("com.alibaba.nacos.client.Worker.longPulling" + agent.getName());
log.error(agent.getName(), "NACOS-XXXX", "[sub-check] rotate check error", e); t.setDaemon(true);
} return t;
} }
}, 1L, 10L, TimeUnit.MILLISECONDS); });
}
class LongPullingRunnable implements Runnable { executor.scheduleWithFixedDelay(new Runnable() {
private int taskId; public void run() {
try {
checkConfigInfo();
} catch (Throwable e) {
log.error(agent.getName(), "NACOS-XXXX", "[sub-check] rotate check error", e);
}
}
}, 1L, 10L, TimeUnit.MILLISECONDS);
}
public LongPullingRunnable(int taskId) { class LongPullingRunnable implements Runnable {
this.taskId = taskId; private int taskId;
}
public void run() { public LongPullingRunnable(int taskId) {
try { this.taskId = taskId;
List<CacheData> cacheDatas = new ArrayList<CacheData>(); }
// check failover config
for (CacheData cacheData : cacheMap.get().values()) {
if (cacheData.getTaskId() == taskId) {
cacheDatas.add(cacheData);
try {
checkLocalConfig(cacheData);
if (cacheData.isUseLocalConfigInfo()) {
cacheData.checkListenerMd5();
}
} catch (Exception e) {
log.error("NACOS-CLIENT", "get local config info error", e);
}
}
}
List<String> inInitializingCacheList = new ArrayList<String>(); public void run() {
// check server config try {
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList); List<CacheData> cacheDatas = new ArrayList<CacheData>();
// check failover config
for (CacheData cacheData : cacheMap.get().values()) {
if (cacheData.getTaskId() == taskId) {
cacheDatas.add(cacheData);
try {
checkLocalConfig(cacheData);
if (cacheData.isUseLocalConfigInfo()) {
cacheData.checkListenerMd5();
}
} catch (Exception e) {
log.error("NACOS-CLIENT", "get local config info error", e);
}
}
}
for (String groupKey : changedGroupKeys) { List<String> inInitializingCacheList = new ArrayList<String>();
String[] key = GroupKey.parseKey(groupKey); // check server config
String dataId = key[0]; List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
String group = key[1];
String tenant = null;
if (key.length == 3) {
tenant = key[2];
}
try {
String content = getServerConfig(dataId, group, tenant, 3000L);
CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
cache.setContent(content);
log.info(agent.getName(), "[data-received] dataId={}, group={}, tenant={}, md5={}, content={}",
dataId, group, tenant, cache.getMd5(), ContentUtils.truncateContent(content));
} catch (NacosException ioe) {
log.error(agent.getName(), "NACOS-XXXX",
"[get-update] get changed config exception. dataId={}, group={}, tenant={}, msg={}",
dataId, group, tenant, ioe.toString());
}
}
for (CacheData cacheData : cacheDatas) {
if (!cacheData.isInitializing() || inInitializingCacheList
.contains(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant))) {
cacheData.checkListenerMd5();
cacheData.setInitializing(false);
}
}
inInitializingCacheList.clear();
} catch (Throwable e) {
log.error("500", "longPulling error", e);
} finally {
executorService.execute(this);
}
}
}
// ================= for (String groupKey : changedGroupKeys) {
String[] key = GroupKey.parseKey(groupKey);
String dataId = key[0];
String group = key[1];
String tenant = null;
if (key.length == 3) {
tenant = key[2];
}
try {
String content = getServerConfig(dataId, group, tenant, 3000L);
CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
cache.setContent(content);
log.info(agent.getName(), "[data-received] dataId={}, group={}, tenant={}, md5={}, content={}",
dataId, group, tenant, cache.getMd5(), ContentUtils.truncateContent(content));
} catch (NacosException ioe) {
log.error(agent.getName(), "NACOS-XXXX",
"[get-update] get changed config exception. dataId={}, group={}, tenant={}, msg={}",
dataId, group, tenant, ioe.toString());
}
}
for (CacheData cacheData : cacheDatas) {
if (!cacheData.isInitializing() || inInitializingCacheList
.contains(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant))) {
cacheData.checkListenerMd5();
cacheData.setInitializing(false);
}
}
inInitializingCacheList.clear();
} catch (Throwable e) {
log.error("500", "longPulling error", e);
} finally {
executorService.execute(this);
}
}
}
public boolean isHealthServer() { // =================
return isHealthServer;
}
private void setHealthServer(boolean isHealthServer) { public boolean isHealthServer() {
this.isHealthServer = isHealthServer; return isHealthServer;
} }
private void setHealthServer(boolean isHealthServer) {
this.isHealthServer = isHealthServer;
}
final ScheduledExecutorService executor;
final ExecutorService executorService;
/**
* groupKey -> cacheData
*/
AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
new HashMap<String, CacheData>());
ServerHttpAgent agent;
ConfigFilterChainManager configFilterChainManager;
private boolean isHealthServer = true;
private double currentLongingTaskCount = 0;
final ScheduledExecutorService executor;
final ExecutorService executorService;
/**
* groupKey -> cacheData
*/
AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(new HashMap<String, CacheData>());
ServerHttpAgent agent;
ConfigFilterChainManager configFilterChainManager;
private boolean isHealthServer = true;
private double currentLongingTaskCount = 0;
} }

View File

@ -24,16 +24,14 @@ import java.util.concurrent.CopyOnWriteArrayList;
import com.alibaba.nacos.client.config.utils.LogUtils; import com.alibaba.nacos.client.config.utils.LogUtils;
import com.alibaba.nacos.client.logger.Logger; import com.alibaba.nacos.client.logger.Logger;
/** /**
* Event subscription and publishing tools. * Event subscription and publishing tools.
*
* @author Nacos
* *
* @author Nacos
*/ */
public class EventDispatcher { public class EventDispatcher {
final static public Logger log = LogUtils.logger(EventDispatcher.class); final static public Logger log = LogUtils.logger(EventDispatcher.class);
/** /**
* 添加事件监听器 * 添加事件监听器
@ -55,7 +53,7 @@ public class EventDispatcher {
// 发布该事件暗示的其他事件 // 发布该事件暗示的其他事件
for (AbstractEvent implyEvent : abstractEvent.implyEvents()) { for (AbstractEvent implyEvent : abstractEvent.implyEvents()) {
try { try {
// 避免死循环 // 避免死循环
if (abstractEvent != implyEvent) { if (abstractEvent != implyEvent) {
fireEvent(implyEvent); fireEvent(implyEvent);
} }
@ -74,7 +72,7 @@ public class EventDispatcher {
} }
static synchronized CopyOnWriteArrayList<AbstractEventListener> getListenerList( static synchronized CopyOnWriteArrayList<AbstractEventListener> getListenerList(
Class<? extends AbstractEvent> eventType) { Class<? extends AbstractEvent> eventType) {
CopyOnWriteArrayList<AbstractEventListener> listeners = LISTENER_MAP.get(eventType); CopyOnWriteArrayList<AbstractEventListener> listeners = LISTENER_MAP.get(eventType);
if (null == listeners) { if (null == listeners) {
listeners = new CopyOnWriteArrayList<AbstractEventListener>(); listeners = new CopyOnWriteArrayList<AbstractEventListener>();
@ -84,8 +82,9 @@ public class EventDispatcher {
} }
// ======================== // ========================
static final Map<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>> LISTENER_MAP = new HashMap<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>>(); static final Map<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>> LISTENER_MAP
= new HashMap<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>>();
// ======================== // ========================
@ -105,29 +104,30 @@ public class EventDispatcher {
*/ */
static public abstract class AbstractEventListener { static public abstract class AbstractEventListener {
public AbstractEventListener() { public AbstractEventListener() {
/** /**
* 自动注册给EventDispatcher * 自动注册给EventDispatcher
*/ */
EventDispatcher.addEventListener(this); EventDispatcher.addEventListener(this);
} }
/** /**
* 感兴趣的事件列表 * 感兴趣的事件列表
* *
* @return event list * @return event list
*/ */
abstract public List<Class<? extends AbstractEvent>> interest(); abstract public List<Class<? extends AbstractEvent>> interest();
/** /**
* 处理事件 * 处理事件
*
* @param abstractEvent event to do * @param abstractEvent event to do
*/ */
abstract public void onEvent(AbstractEvent abstractEvent); abstract public void onEvent(AbstractEvent abstractEvent);
} }
/** /**
* serverList has changed * serverList has changed
*/ */
static public class ServerlistChangeEvent extends AbstractEvent { static public class ServerlistChangeEvent extends AbstractEvent {
} }
} }

View File

@ -34,95 +34,87 @@ import java.util.Map;
/** /**
* Http tool * Http tool
*
* @author Nacos
* *
* @author Nacos
*/ */
public class HttpSimpleClient { public class HttpSimpleClient {
static public HttpResult httpGet(String url, List<String> headers, List<String> paramValues, static public HttpResult httpGet(String url, List<String> headers, List<String> paramValues,
String encoding, long readTimeoutMs, boolean isSSL) throws IOException{ String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
String encodedContent = encodingParams(paramValues, encoding); String encodedContent = encodingParams(paramValues, encoding);
url += (null == encodedContent) ? "" : ("?" + encodedContent); url += (null == encodedContent) ? "" : ("?" + encodedContent);
if (Limiter.isLimit(MD5.getInstance().getMD5String( if (Limiter.isLimit(MD5.getInstance().getMD5String(
new StringBuilder(url).append(encodedContent).toString()))) { new StringBuilder(url).append(encodedContent).toString()))) {
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD, return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
"More than client-side current limit threshold"); "More than client-side current limit threshold");
} }
HttpURLConnection conn = null; HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
conn.setReadTimeout((int) readTimeoutMs);
List<String> newHeaders = getHeaders(url, headers, paramValues);
setHeaders(conn, newHeaders, encoding);
conn.connect(); try {
conn = (HttpURLConnection)new URL(url).openConnection();
int respCode = conn.getResponseCode(); conn.setRequestMethod("GET");
String resp = null; conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
conn.setReadTimeout((int)readTimeoutMs);
List<String> newHeaders = getHeaders(url, headers, paramValues);
setHeaders(conn, newHeaders, encoding);
if (HttpURLConnection.HTTP_OK == respCode) { conn.connect();
resp = IOUtils.toString(conn.getInputStream(), encoding);
} else { int respCode = conn.getResponseCode();
resp = IOUtils.toString(conn.getErrorStream(), encoding); String resp = null;
}
return new HttpResult(respCode, conn.getHeaderFields(), resp); if (HttpURLConnection.HTTP_OK == respCode) {
} finally { resp = IOUtils.toString(conn.getInputStream(), encoding);
} else {
resp = IOUtils.toString(conn.getErrorStream(), encoding);
}
return new HttpResult(respCode, conn.getHeaderFields(), resp);
} finally {
if (conn != null) { if (conn != null) {
conn.disconnect(); conn.disconnect();
} }
} }
} }
/**
/** * 发送GET请求
* 发送GET请求 */
*/ static public HttpResult httpGet(String url, List<String> headers, List<String> paramValues, String encoding,
static public HttpResult httpGet(String url, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
long readTimeoutMs) throws IOException { return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false);
return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false); }
}
/** /**
* 发送POST请求 * 发送POST请求
* *
* @param url * @param url
* @param headers * @param headers 请求Header可以为null
* 请求Header可以为null * @param paramValues 参数可以为null
* @param paramValues * @param encoding URL编码使用的字符集
* 参数可以为null * @param readTimeoutMs 响应超时
* @param encoding * @param isSSL 是否https
* URL编码使用的字符集
* @param readTimeoutMs
* 响应超时
* @param isSSL
* 是否https
* @return * @return
* @throws IOException * @throws IOException
*/ */
static public HttpResult httpPost(String url, List<String> headers, List<String> paramValues, static public HttpResult httpPost(String url, List<String> headers, List<String> paramValues,
String encoding, long readTimeoutMs, boolean isSSL) throws IOException { String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
String encodedContent = encodingParams(paramValues, encoding); String encodedContent = encodingParams(paramValues, encoding);
if (Limiter.isLimit(MD5.getInstance().getMD5String( if (Limiter.isLimit(MD5.getInstance().getMD5String(
new StringBuilder(url).append(encodedContent).toString()))) { new StringBuilder(url).append(encodedContent).toString()))) {
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD, return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
"More than client-side current limit threshold"); "More than client-side current limit threshold");
} }
HttpURLConnection conn = null; HttpURLConnection conn = null;
try { try {
conn = (HttpURLConnection) new URL(url).openConnection(); conn = (HttpURLConnection)new URL(url).openConnection();
conn.setRequestMethod("POST"); conn.setRequestMethod("POST");
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 3000 ? ParamUtil.getConnectTimeout() : 3000); conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 3000 ? ParamUtil.getConnectTimeout() : 3000);
conn.setReadTimeout((int) readTimeoutMs); conn.setReadTimeout((int)readTimeoutMs);
conn.setDoOutput(true); conn.setDoOutput(true);
conn.setDoInput(true); conn.setDoInput(true);
List<String> newHeaders = getHeaders(url, headers, paramValues); List<String> newHeaders = getHeaders(url, headers, paramValues);
setHeaders(conn, newHeaders, encoding); setHeaders(conn, newHeaders, encoding);
conn.getOutputStream().write(encodedContent.getBytes(encoding)); conn.getOutputStream().write(encodedContent.getBytes(encoding));
@ -141,81 +133,75 @@ public class HttpSimpleClient {
} }
} }
} }
/**
* 发送POST请求
*
* @param url
* @param headers
* 请求Header可以为null
* @param paramValues
* 参数可以为null
* @param encoding
* URL编码使用的字符集
* @param readTimeoutMs
* 响应超时
* @return
* @throws IOException
*/
static public HttpResult httpPost(String url, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException {
return httpPost(url, headers, paramValues, encoding, readTimeoutMs, false);
}
/**
* 发送POST请求
*
* @param url
* @param headers 请求Header可以为null
* @param paramValues 参数可以为null
* @param encoding URL编码使用的字符集
* @param readTimeoutMs 响应超时
* @return
* @throws IOException
*/
static public HttpResult httpPost(String url, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException {
return httpPost(url, headers, paramValues, encoding, readTimeoutMs, false);
}
static public HttpResult httpDelete(String url, List<String> headers, List<String> paramValues, static public HttpResult httpDelete(String url, List<String> headers, List<String> paramValues,
String encoding, long readTimeoutMs, boolean isSSL) throws IOException{ String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
String encodedContent = encodingParams(paramValues, encoding); String encodedContent = encodingParams(paramValues, encoding);
url += (null == encodedContent) ? "" : ("?" + encodedContent); url += (null == encodedContent) ? "" : ("?" + encodedContent);
if (Limiter.isLimit(MD5.getInstance().getMD5String( if (Limiter.isLimit(MD5.getInstance().getMD5String(
new StringBuilder(url).append(encodedContent).toString()))) { new StringBuilder(url).append(encodedContent).toString()))) {
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD, return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
"More than client-side current limit threshold"); "More than client-side current limit threshold");
} }
HttpURLConnection conn = null; HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("DELETE");
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
conn.setReadTimeout((int) readTimeoutMs);
List<String> newHeaders = getHeaders(url, headers, paramValues);
setHeaders(conn, newHeaders, encoding);
conn.connect(); try {
conn = (HttpURLConnection)new URL(url).openConnection();
int respCode = conn.getResponseCode(); conn.setRequestMethod("DELETE");
String resp = null; conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
conn.setReadTimeout((int)readTimeoutMs);
List<String> newHeaders = getHeaders(url, headers, paramValues);
setHeaders(conn, newHeaders, encoding);
if (HttpURLConnection.HTTP_OK == respCode) { conn.connect();
resp = IOUtils.toString(conn.getInputStream(), encoding);
} else { int respCode = conn.getResponseCode();
resp = IOUtils.toString(conn.getErrorStream(), encoding); String resp = null;
}
return new HttpResult(respCode, conn.getHeaderFields(), resp); if (HttpURLConnection.HTTP_OK == respCode) {
} finally { resp = IOUtils.toString(conn.getInputStream(), encoding);
} else {
resp = IOUtils.toString(conn.getErrorStream(), encoding);
}
return new HttpResult(respCode, conn.getHeaderFields(), resp);
} finally {
if (conn != null) { if (conn != null) {
conn.disconnect(); conn.disconnect();
} }
} }
} }
static public HttpResult httpDelete(String url, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException {
return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false);
}
static public HttpResult httpDelete(String url, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException {
return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false);
}
static private void setHeaders(HttpURLConnection conn, List<String> headers, String encoding) { static private void setHeaders(HttpURLConnection conn, List<String> headers, String encoding) {
if (null != headers) { if (null != headers) {
for (Iterator<String> iter = headers.iterator(); iter.hasNext();) { for (Iterator<String> iter = headers.iterator(); iter.hasNext(); ) {
conn.addRequestProperty(iter.next(), iter.next()); conn.addRequestProperty(iter.next(), iter.next());
} }
} }
conn.addRequestProperty("Client-Version", ParamUtil.getClientVersion()); conn.addRequestProperty("Client-Version", ParamUtil.getClientVersion());
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding); conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding);
String ts = String.valueOf(System.currentTimeMillis()); String ts = String.valueOf(System.currentTimeMillis());
String token = MD5.getInstance().getMD5String(ts + ParamUtil.getAppKey()); String token = MD5.getInstance().getMD5String(ts + ParamUtil.getAppKey());
@ -224,27 +210,27 @@ public class HttpSimpleClient {
conn.addRequestProperty(Constants.CLIENT_REQUEST_TOKEN_HEADER, token); conn.addRequestProperty(Constants.CLIENT_REQUEST_TOKEN_HEADER, token);
} }
private static List<String> getHeaders(String url, List<String> headers, List<String> paramValues) private static List<String> getHeaders(String url, List<String> headers, List<String> paramValues)
throws IOException { throws IOException {
List<String> newHeaders = new ArrayList<String>(); List<String> newHeaders = new ArrayList<String>();
newHeaders.add("exConfigInfo"); newHeaders.add("exConfigInfo");
newHeaders.add("true"); newHeaders.add("true");
newHeaders.add("RequestId"); newHeaders.add("RequestId");
newHeaders.add(UuidUtil.generateUuid()); newHeaders.add(UuidUtil.generateUuid());
if (headers!=null) { if (headers != null) {
newHeaders.addAll(headers); newHeaders.addAll(headers);
} }
return newHeaders; return newHeaders;
} }
static private String encodingParams(List<String> paramValues, String encoding) static private String encodingParams(List<String> paramValues, String encoding)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (null == paramValues) { if (null == paramValues) {
return null; return null;
} }
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext();) { for (Iterator<String> iter = paramValues.iterator(); iter.hasNext(); ) {
sb.append(iter.next()).append("="); sb.append(iter.next()).append("=");
sb.append(URLEncoder.encode(iter.next(), encoding)); sb.append(URLEncoder.encode(iter.next(), encoding));
if (iter.hasNext()) { if (iter.hasNext()) {
@ -253,23 +239,23 @@ public class HttpSimpleClient {
} }
return sb.toString(); return sb.toString();
} }
static public class HttpResult { static public class HttpResult {
final public int code; final public int code;
final public Map<String,List<String>> headers; final public Map<String, List<String>> headers;
final public String content; final public String content;
public HttpResult(int code, String content) { public HttpResult(int code, String content) {
this.code = code; this.code = code;
this.headers = null; this.headers = null;
this.content = content; this.content = content;
} }
public HttpResult(int code, Map<String, List<String>> headers, String content) { public HttpResult(int code, Map<String, List<String>> headers, String content) {
this.code = code; this.code = code;
this.headers = headers; this.headers = headers;
this.content = content; this.content = content;
} }
} }
} }

View File

@ -27,53 +27,52 @@ import com.google.common.util.concurrent.RateLimiter;
/** /**
* Limiter * Limiter
*
* @author Nacos
* *
* @author Nacos
*/ */
public class Limiter { public class Limiter {
static final public Logger log = LogUtils.logger(Limiter.class); static final public Logger log = LogUtils.logger(Limiter.class);
private static int CAPACITY_SIZE = 1000; private static int CAPACITY_SIZE = 1000;
private static int LIMIT_TIME = 1000; private static int LIMIT_TIME = 1000;
private static Cache<String, RateLimiter> cache = CacheBuilder.newBuilder() private static Cache<String, RateLimiter> cache = CacheBuilder.newBuilder()
.initialCapacity(CAPACITY_SIZE).expireAfterAccess(1, TimeUnit.MINUTES) .initialCapacity(CAPACITY_SIZE).expireAfterAccess(1, TimeUnit.MINUTES)
.build(); .build();
/** /**
* qps 5 * qps 5
*/ */
private static final String DEFAULT_LIMIT = "5"; private static final String DEFAULT_LIMIT = "5";
private static double limit = 5; private static double limit = 5;
static { static {
try { try {
String limitTimeStr = System String limitTimeStr = System
.getProperty("limitTime", DEFAULT_LIMIT); .getProperty("limitTime", DEFAULT_LIMIT);
limit = Double.parseDouble(limitTimeStr); limit = Double.parseDouble(limitTimeStr);
log.info("limitTime:{}", limit); log.info("limitTime:{}", limit);
} catch (Exception e) { } catch (Exception e) {
log.error("Nacos-xxx", "init limitTime fail", e); log.error("Nacos-xxx", "init limitTime fail", e);
} }
} }
public static boolean isLimit(String accessKeyID) { public static boolean isLimit(String accessKeyID) {
RateLimiter rateLimiter = null; RateLimiter rateLimiter = null;
try { try {
rateLimiter = cache.get(accessKeyID, new Callable<RateLimiter>() { rateLimiter = cache.get(accessKeyID, new Callable<RateLimiter>() {
@Override @Override
public RateLimiter call() throws Exception { public RateLimiter call() throws Exception {
return RateLimiter.create(limit); return RateLimiter.create(limit);
} }
}); });
} catch (ExecutionException e) { } catch (ExecutionException e) {
log.error("Nacos-XXX", "create limit fail", e); log.error("Nacos-XXX", "create limit fail", e);
} }
if (rateLimiter != null && !rateLimiter.tryAcquire(LIMIT_TIME, TimeUnit.MILLISECONDS)) { if (rateLimiter != null && !rateLimiter.tryAcquire(LIMIT_TIME, TimeUnit.MILLISECONDS)) {
log.error("Nacos-XXX", "access_key_id:{} limited", accessKeyID); log.error("Nacos-XXX", "access_key_id:{} limited", accessKeyID);
return true; return true;
} }
return false; return false;
} }
} }

View File

@ -25,169 +25,166 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
/** /**
* Local Disaster Recovery Directory Tool * Local Disaster Recovery Directory Tool
* *
* @author Nacos * @author Nacos
*/ */
public class LocalConfigInfoProcessor { public class LocalConfigInfoProcessor {
final static public Logger log = LogUtils.logger(LocalConfigInfoProcessor.class); final static public Logger log = LogUtils.logger(LocalConfigInfoProcessor.class);
static public String getFailover(String serverName, String dataId, String group, String tenant) { static public String getFailover(String serverName, String dataId, String group, String tenant) {
File localPath = getFailoverFile(serverName, dataId, group, tenant); File localPath = getFailoverFile(serverName, dataId, group, tenant);
if (!localPath.exists() || !localPath.isFile()) { if (!localPath.exists() || !localPath.isFile()) {
return null; return null;
} }
try { try {
return readFile(localPath); return readFile(localPath);
} catch (IOException ioe) { } catch (IOException ioe) {
log.error(serverName, "NACOS-XXXX","get failover error, " + localPath + ioe.toString()); log.error(serverName, "NACOS-XXXX", "get failover error, " + localPath + ioe.toString());
return null; return null;
} }
} }
/** /**
* 获取本地缓存文件内容NULL表示没有本地文件或抛出异常 * 获取本地缓存文件内容NULL表示没有本地文件或抛出异常
*/ */
static public String getSnapshot(String name, String dataId, String group, String tenant) { static public String getSnapshot(String name, String dataId, String group, String tenant) {
if (!SnapShotSwitch.getIsSnapShot()) { if (!SnapShotSwitch.getIsSnapShot()) {
return null; return null;
} }
File file = getSnapshotFile(name, dataId, group, tenant); File file = getSnapshotFile(name, dataId, group, tenant);
if (!file.exists() || !file.isFile()) { if (!file.exists() || !file.isFile()) {
return null; return null;
} }
try { try {
return readFile(file); return readFile(file);
} catch (IOException ioe) { } catch (IOException ioe) {
log.error(name, "NACOS-XXXX","get snapshot error, " + file + ", " + ioe.toString()); log.error(name, "NACOS-XXXX", "get snapshot error, " + file + ", " + ioe.toString());
return null; return null;
} }
} }
static private String readFile(File file) throws IOException {
if (!file.exists() || !file.isFile()) {
return null;
}
if (JVMUtil.isMultiInstance()) { static private String readFile(File file) throws IOException {
return ConcurrentDiskUtil.getFileContent(file, Constants.ENCODE); if (!file.exists() || !file.isFile()) {
} else { return null;
InputStream is = null; }
try {
is = new FileInputStream(file); if (JVMUtil.isMultiInstance()) {
return IOUtils.toString(is, Constants.ENCODE); return ConcurrentDiskUtil.getFileContent(file, Constants.ENCODE);
} finally { } else {
try { InputStream is = null;
if (null != is) { try {
is.close(); is = new FileInputStream(file);
} return IOUtils.toString(is, Constants.ENCODE);
} catch (IOException ioe) { } finally {
} try {
} if (null != is) {
} is.close();
} }
} catch (IOException ioe) {
}
}
}
}
static public void saveSnapshot(String envName, String dataId, String group, String tenant, String config) { static public void saveSnapshot(String envName, String dataId, String group, String tenant, String config) {
if (!SnapShotSwitch.getIsSnapShot()) { if (!SnapShotSwitch.getIsSnapShot()) {
return; return;
} }
File file = getSnapshotFile(envName, dataId, group, tenant); File file = getSnapshotFile(envName, dataId, group, tenant);
if (null == config) { if (null == config) {
try { try {
IOUtils.delete(file); IOUtils.delete(file);
} catch (IOException ioe) { } catch (IOException ioe) {
log.error(envName, "NACOS-XXXX","delete snapshot error, " + file + ", " + ioe.toString()); log.error(envName, "NACOS-XXXX", "delete snapshot error, " + file + ", " + ioe.toString());
} }
} else { } else {
try { try {
boolean isMdOk = file.getParentFile().mkdirs(); boolean isMdOk = file.getParentFile().mkdirs();
if (!isMdOk) { if (!isMdOk) {
log.error(envName, "NACOS-XXXX", "save snapshot error"); log.error(envName, "NACOS-XXXX", "save snapshot error");
} }
if (JVMUtil.isMultiInstance()) { if (JVMUtil.isMultiInstance()) {
ConcurrentDiskUtil.writeFileContent(file, config, ConcurrentDiskUtil.writeFileContent(file, config,
Constants.ENCODE); Constants.ENCODE);
} else { } else {
IOUtils.writeStringToFile(file, config, Constants.ENCODE); IOUtils.writeStringToFile(file, config, Constants.ENCODE);
} }
} catch (IOException ioe) { } catch (IOException ioe) {
log.error(envName, "NACOS-XXXX","save snapshot error, " + file + ", " + ioe.toString()); log.error(envName, "NACOS-XXXX", "save snapshot error, " + file + ", " + ioe.toString());
} }
} }
} }
/** /**
* 清除snapshot目录下所有缓存文件 * 清除snapshot目录下所有缓存文件
*/ */
static public void cleanAllSnapshot() { static public void cleanAllSnapshot() {
try { try {
File rootFile = new File(LOCAL_SNAPSHOT_PATH); File rootFile = new File(LOCAL_SNAPSHOT_PATH);
File[] files = rootFile.listFiles(); File[] files = rootFile.listFiles();
if (files == null || files.length == 0) { if (files == null || files.length == 0) {
return; return;
} }
for(File file : files){ for (File file : files) {
if(file.getName().endsWith("_nacos")){ if (file.getName().endsWith("_nacos")) {
IOUtils.cleanDirectory(file); IOUtils.cleanDirectory(file);
} }
} }
} catch (IOException ioe) { } catch (IOException ioe) {
log.error("NACOS-XXXX","clean all snapshot error, " + ioe.toString(), ioe); log.error("NACOS-XXXX", "clean all snapshot error, " + ioe.toString(), ioe);
} }
} }
static public void cleanEnvSnapshot(String envName){ static public void cleanEnvSnapshot(String envName) {
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos"); File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
tmp = new File(tmp, "snapshot"); tmp = new File(tmp, "snapshot");
try { try {
IOUtils.cleanDirectory(tmp); IOUtils.cleanDirectory(tmp);
log.info("success delete " + envName + "-snapshot"); log.info("success delete " + envName + "-snapshot");
} catch (IOException e) { } catch (IOException e) {
log.info("fail delete " + envName + "-snapshot, " + e.toString()); log.info("fail delete " + envName + "-snapshot, " + e.toString());
e.printStackTrace(); e.printStackTrace();
} }
} }
static File getFailoverFile(String serverName, String dataId, String group, String tenant) { static File getFailoverFile(String serverName, String dataId, String group, String tenant) {
File tmp = new File(LOCAL_SNAPSHOT_PATH, serverName + "_nacos"); File tmp = new File(LOCAL_SNAPSHOT_PATH, serverName + "_nacos");
tmp = new File(tmp, "data"); tmp = new File(tmp, "data");
if (StringUtils.isBlank(tenant)) { if (StringUtils.isBlank(tenant)) {
tmp = new File(tmp, "config-data"); tmp = new File(tmp, "config-data");
} else } else {
{ tmp = new File(tmp, "config-data-tenant");
tmp = new File(tmp, "config-data-tenant"); tmp = new File(tmp, tenant);
tmp = new File(tmp, tenant); }
}
return new File(new File(tmp, group), dataId);
}
static File getSnapshotFile(String envName, String dataId, String group, String tenant) {
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
if (StringUtils.isBlank(tenant)) {
tmp = new File(tmp, "snapshot");
} else {
tmp = new File(tmp, "snapshot-tenant");
tmp = new File(tmp, tenant);
}
return new File(new File(tmp, group), dataId); return new File(new File(tmp, group), dataId);
} }
static File getSnapshotFile(String envName, String dataId, String group, String tenant) {
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
if (StringUtils.isBlank(tenant)) {
tmp = new File(tmp, "snapshot");
} else {
tmp = new File(tmp, "snapshot-tenant");
tmp = new File(tmp, tenant);
}
return new File(new File(tmp, group), dataId);
}
public static final String LOCAL_FILEROOT_PATH; public static final String LOCAL_FILEROOT_PATH;
public static final String LOCAL_SNAPSHOT_PATH; public static final String LOCAL_SNAPSHOT_PATH;
static {
LOCAL_FILEROOT_PATH = System.getProperty("JM.LOG.PATH", System.getProperty("user.home")) + File.separator static {
+ "nacos" + File.separator + "config"; LOCAL_FILEROOT_PATH = System.getProperty("JM.LOG.PATH", System.getProperty("user.home")) + File.separator
LOCAL_SNAPSHOT_PATH = System.getProperty("JM.SNAPSHOT.PATH", System.getProperty("user.home")) + File.separator + "nacos" + File.separator + "config";
+ "nacos" + File.separator + "config"; LOCAL_SNAPSHOT_PATH = System.getProperty("JM.SNAPSHOT.PATH", System.getProperty("user.home")) + File.separator
log.warn("LOCAL_SNAPSHOT_PATH:{}", LOCAL_SNAPSHOT_PATH); + "nacos" + File.separator + "config";
} log.warn("LOCAL_SNAPSHOT_PATH:{}", LOCAL_SNAPSHOT_PATH);
}
} }

View File

@ -41,351 +41,352 @@ import java.util.List;
import java.util.Properties; import java.util.Properties;
/** /**
* Server Agent * Server Agent
*
* @author water.lyl
* *
* @author water.lyl
*/ */
public class ServerHttpAgent { public class ServerHttpAgent {
final static public Logger log = LogUtils.logger(ServerHttpAgent.class); final static public Logger log = LogUtils.logger(ServerHttpAgent.class);
/**
* @param path
* 相对于web应用根/开头
* @param headers
* @param paramValues
* @param encoding
* @param readTimeoutMs
* @return
* @throws IOException
*/
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
boolean isSSL = false; /**
* @param path 相对于web应用根/开头
do { * @param headers
try { * @param paramValues
List<String> newHeaders = getSpasHeaders(paramValues); * @param encoding
if (headers != null) { * @param readTimeoutMs
newHeaders.addAll(headers); * @return
} * @throws IOException
HttpResult result = HttpSimpleClient.httpGet( */
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding, public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
readTimeoutMs, isSSL); long readTimeoutMs) throws IOException {
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR final long endTime = System.currentTimeMillis() + readTimeoutMs;
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
new Object[] { serverListMgr.getCurrentServerAddr(), result.code });
} else {
return result;
}
} catch (ConnectException ce) {
log.error("NACOS ConnectException", "currentServerAddr:{}",
new Object[] { serverListMgr.getCurrentServerAddr() });
serverListMgr.refreshCurrentServerAddr();
} catch (SocketTimeoutException stoe) {
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
new Object[] { serverListMgr.getCurrentServerAddr()});
serverListMgr.refreshCurrentServerAddr();
} catch (IOException ioe) {
log.error("NACOS IOException", "currentServerAddr:{}",
new Object[] { serverListMgr.getCurrentServerAddr()});
throw ioe;
}
} while (System.currentTimeMillis() <= endTime);
log.error("NACOS-0002", boolean isSSL = false;
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
throw new ConnectException("no available server");
}
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, do {
long readTimeoutMs) throws IOException { try {
final long endTime = System.currentTimeMillis() + readTimeoutMs; List<String> newHeaders = getSpasHeaders(paramValues);
boolean isSSL = false; if (headers != null) {
do { newHeaders.addAll(headers);
try { }
List<String> newHeaders = getSpasHeaders(paramValues); HttpResult result = HttpSimpleClient.httpGet(
if (headers != null) { getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
newHeaders.addAll(headers); readTimeoutMs, isSSL);
} if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
HttpResult result = HttpSimpleClient.httpPost( || result.code == HttpURLConnection.HTTP_BAD_GATEWAY
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding, || result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
readTimeoutMs, isSSL); log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR new Object[] {serverListMgr.getCurrentServerAddr(), result.code});
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY } else {
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) { return result;
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:", }
new Object[] { serverListMgr.getCurrentServerAddr(), result.code }); } catch (ConnectException ce) {
} else { log.error("NACOS ConnectException", "currentServerAddr:{}",
return result; new Object[] {serverListMgr.getCurrentServerAddr()});
} serverListMgr.refreshCurrentServerAddr();
} catch (ConnectException ce) { } catch (SocketTimeoutException stoe) {
log.error("NACOS ConnectException", "currentServerAddr:{}", log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
new Object[] { serverListMgr.getCurrentServerAddr()}); new Object[] {serverListMgr.getCurrentServerAddr()});
serverListMgr.refreshCurrentServerAddr(); serverListMgr.refreshCurrentServerAddr();
} catch (SocketTimeoutException stoe) { } catch (IOException ioe) {
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}", log.error("NACOS IOException", "currentServerAddr:{}",
new Object[] { serverListMgr.getCurrentServerAddr()}); new Object[] {serverListMgr.getCurrentServerAddr()});
serverListMgr.refreshCurrentServerAddr(); throw ioe;
} catch (IOException ioe) { }
log.error("NACOS IOException", "currentServerAddr:{}", } while (System.currentTimeMillis() <= endTime);
new Object[] { serverListMgr.getCurrentServerAddr()});
throw ioe;
}
} while (System.currentTimeMillis() <= endTime); log.error("NACOS-0002",
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
throw new ConnectException("no available server");
}
log.error("NACOS-0002", public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server")); long readTimeoutMs) throws IOException {
throw new ConnectException("no available server"); final long endTime = System.currentTimeMillis() + readTimeoutMs;
} boolean isSSL = false;
do {
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding, try {
long readTimeoutMs) throws IOException { List<String> newHeaders = getSpasHeaders(paramValues);
final long endTime = System.currentTimeMillis() + readTimeoutMs; if (headers != null) {
boolean isSSL = false; newHeaders.addAll(headers);
do { }
try { HttpResult result = HttpSimpleClient.httpPost(
List<String> newHeaders = getSpasHeaders(paramValues); getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
if (headers != null) { readTimeoutMs, isSSL);
newHeaders.addAll(headers); if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
} || result.code == HttpURLConnection.HTTP_BAD_GATEWAY
HttpResult result = HttpSimpleClient.httpDelete( || result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding, log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
readTimeoutMs, isSSL); new Object[] {serverListMgr.getCurrentServerAddr(), result.code});
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR } else {
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY return result;
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) { }
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:", } catch (ConnectException ce) {
new Object[] { serverListMgr.getCurrentServerAddr(), result.code }); log.error("NACOS ConnectException", "currentServerAddr:{}",
} else { new Object[] {serverListMgr.getCurrentServerAddr()});
return result; serverListMgr.refreshCurrentServerAddr();
} } catch (SocketTimeoutException stoe) {
} catch (ConnectException ce) { log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
log.error("NACOS ConnectException", "currentServerAddr:{}", new Object[] {serverListMgr.getCurrentServerAddr()});
new Object[] { serverListMgr.getCurrentServerAddr()}); serverListMgr.refreshCurrentServerAddr();
serverListMgr.refreshCurrentServerAddr(); } catch (IOException ioe) {
} catch (SocketTimeoutException stoe) { log.error("NACOS IOException", "currentServerAddr:{}",
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}", new Object[] {serverListMgr.getCurrentServerAddr()});
new Object[] { serverListMgr.getCurrentServerAddr()}); throw ioe;
serverListMgr.refreshCurrentServerAddr(); }
} catch (IOException ioe) {
log.error("NACOS IOException", "currentServerAddr:{}",
new Object[] { serverListMgr.getCurrentServerAddr()});
throw ioe;
}
} while (System.currentTimeMillis() <= endTime);
log.error("NACOS-0002",
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
throw new ConnectException("no available server");
}
private String getUrl(String serverAddr, String relativePath, boolean isSSL) { } while (System.currentTimeMillis() <= endTime);
String httpPrefix = "http://";
if (isSSL) {
httpPrefix = "https://";
}
return httpPrefix + serverAddr + "/" + serverListMgr.getContentPath() + relativePath;
}
public static String getAppname() { log.error("NACOS-0002",
return ParamUtil.getAppName(); LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
} throw new ConnectException("no available server");
}
public ServerHttpAgent(ServerListManager mgr) { public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
serverListMgr = mgr; long readTimeoutMs) throws IOException {
} final long endTime = System.currentTimeMillis() + readTimeoutMs;
boolean isSSL = false;
public ServerHttpAgent(ServerListManager mgr, Properties properties) { do {
serverListMgr = mgr; try {
String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY); List<String> newHeaders = getSpasHeaders(paramValues);
if (StringUtils.isBlank(ak)) { if (headers != null) {
accessKey = SpasAdapter.getAk(); newHeaders.addAll(headers);
} else { }
accessKey = ak; HttpResult result = HttpSimpleClient.httpDelete(
} getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
readTimeoutMs, isSSL);
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
new Object[] {serverListMgr.getCurrentServerAddr(), result.code});
} else {
return result;
}
} catch (ConnectException ce) {
log.error("NACOS ConnectException", "currentServerAddr:{}",
new Object[] {serverListMgr.getCurrentServerAddr()});
serverListMgr.refreshCurrentServerAddr();
} catch (SocketTimeoutException stoe) {
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
new Object[] {serverListMgr.getCurrentServerAddr()});
serverListMgr.refreshCurrentServerAddr();
} catch (IOException ioe) {
log.error("NACOS IOException", "currentServerAddr:{}",
new Object[] {serverListMgr.getCurrentServerAddr()});
throw ioe;
}
String sk = properties.getProperty(PropertyKeyConst.SECRET_KEY); } while (System.currentTimeMillis() <= endTime);
if (StringUtils.isBlank(sk)) {
secretKey = SpasAdapter.getSk();
} else {
secretKey = sk;
}
}
public ServerHttpAgent(Properties properties) throws NacosException {
String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
if (StringUtils.isBlank(encodeTmp)) {
encode = Constants.ENCODE;
} else {
encode = encodeTmp.trim();
}
serverListMgr = new ServerListManager(properties);
String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
if (StringUtils.isBlank(ak)) {
accessKey = SpasAdapter.getAk();
} else {
accessKey = ak;
}
String sk = properties.getProperty(PropertyKeyConst.SECRET_KEY);
if (StringUtils.isBlank(sk)) {
secretKey = SpasAdapter.getSk();
} else {
secretKey = sk;
}
}
public synchronized void start() throws NacosException { log.error("NACOS-0002",
serverListMgr.start(); LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
} throw new ConnectException("no available server");
}
private List<String> getSpasHeaders(List<String> paramValues) throws IOException {
List<String> newHeaders = new ArrayList<String>();
// STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
if (STSConfig.getInstance().isSTSOn()) {
STSCredential sTSCredential = getSTSCredential();
accessKey = sTSCredential.accessKeyId;
secretKey = sTSCredential.accessKeySecret;
newHeaders.add("Spas-SecurityToken");
newHeaders.add(sTSCredential.securityToken);
}
if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) { private String getUrl(String serverAddr, String relativePath, boolean isSSL) {
newHeaders.add("Spas-AccessKey"); String httpPrefix = "http://";
newHeaders.add(accessKey); if (isSSL) {
List<String> signHeaders = SpasAdapter.getSignHeaders(paramValues, secretKey); httpPrefix = "https://";
if (signHeaders != null) { }
newHeaders.addAll(signHeaders); return httpPrefix + serverAddr + "/" + serverListMgr.getContentPath() + relativePath;
} }
}
return newHeaders;
}
private STSCredential getSTSCredential() throws IOException { public static String getAppname() {
boolean cacheSecurityCredentials = STSConfig.getInstance().isCacheSecurityCredentials(); return ParamUtil.getAppName();
if (cacheSecurityCredentials && sTSCredential != null) { }
long currentTime = System.currentTimeMillis();
long expirationTime = sTSCredential.expiration.getTime();
int timeToRefreshInMillisecond = STSConfig.getInstance().getTimeToRefreshInMillisecond();
if (expirationTime - currentTime > timeToRefreshInMillisecond) {
return sTSCredential;
}
}
String stsResponse = getSTSResponse();
STSCredential stsCredentialTmp = (STSCredential)JSONUtils.deserializeObject(stsResponse,
new TypeReference<STSCredential>() {});
sTSCredential = stsCredentialTmp;
log.info("getSTSCredential", "code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}", sTSCredential.getCode(),
sTSCredential.getAccessKeyId(), sTSCredential.getLastUpdated(), sTSCredential.getExpiration());
return sTSCredential;
}
private static String getSTSResponse() throws IOException { public ServerHttpAgent(ServerListManager mgr) {
String securityCredentials = STSConfig.getInstance().getSecurityCredentials(); serverListMgr = mgr;
if (securityCredentials != null) { }
return securityCredentials;
}
String securityCredentialsUrl = STSConfig.getInstance().getSecurityCredentialsUrl();
HttpURLConnection conn = null;
int respCode;
String response;
try {
conn = (HttpURLConnection)new URL(securityCredentialsUrl).openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
conn.setReadTimeout(1000);
conn.connect();
respCode = conn.getResponseCode();
if (HttpURLConnection.HTTP_OK == respCode) {
response = IOUtils.toString(conn.getInputStream(), Constants.ENCODE);
} else {
response = IOUtils.toString(conn.getErrorStream(), Constants.ENCODE);
}
} catch (IOException e) {
log.error("500", "can not get security credentials", e);
throw e;
} finally {
if (null != conn) {
conn.disconnect();
}
}
if (HttpURLConnection.HTTP_OK == respCode) {
return response;
}
log.error(respCode + "", "can not get security credentials, securityCredentialsUrl:{}, response:{}",
new Object[] {securityCredentialsUrl, response});
throw new IOException("can not get security credentials, responseCode: " + respCode + ", response: " + response);
}
public String getName() {
return serverListMgr.getName();
}
public String getNamespace() { public ServerHttpAgent(ServerListManager mgr, Properties properties) {
return serverListMgr.getNamespace(); serverListMgr = mgr;
} String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
public String getTenant() { if (StringUtils.isBlank(ak)) {
return serverListMgr.getTenant(); accessKey = SpasAdapter.getAk();
} } else {
accessKey = ak;
}
public String getEncode() { String sk = properties.getProperty(PropertyKeyConst.SECRET_KEY);
return encode; if (StringUtils.isBlank(sk)) {
} secretKey = SpasAdapter.getSk();
} else {
secretKey = sk;
}
}
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") public ServerHttpAgent(Properties properties) throws NacosException {
private static class STSCredential { String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
@JsonProperty(value = "AccessKeyId") if (StringUtils.isBlank(encodeTmp)) {
private String accessKeyId; encode = Constants.ENCODE;
@JsonProperty(value = "AccessKeySecret") } else {
private String accessKeySecret; encode = encodeTmp.trim();
@JsonProperty(value = "Expiration") }
private Date expiration; serverListMgr = new ServerListManager(properties);
@JsonProperty(value = "SecurityToken") String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
private String securityToken; if (StringUtils.isBlank(ak)) {
@JsonProperty(value = "LastUpdated") accessKey = SpasAdapter.getAk();
private Date lastUpdated; } else {
@JsonProperty(value = "Code") accessKey = ak;
private String code; }
public String getAccessKeyId() { String sk = properties.getProperty(PropertyKeyConst.SECRET_KEY);
return accessKeyId; if (StringUtils.isBlank(sk)) {
} secretKey = SpasAdapter.getSk();
} else {
secretKey = sk;
}
}
public Date getExpiration() { public synchronized void start() throws NacosException {
return expiration; serverListMgr.start();
} }
public Date getLastUpdated() { private List<String> getSpasHeaders(List<String> paramValues) throws IOException {
return lastUpdated; List<String> newHeaders = new ArrayList<String>();
} // STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
if (STSConfig.getInstance().isSTSOn()) {
STSCredential sTSCredential = getSTSCredential();
accessKey = sTSCredential.accessKeyId;
secretKey = sTSCredential.accessKeySecret;
newHeaders.add("Spas-SecurityToken");
newHeaders.add(sTSCredential.securityToken);
}
public String getCode() { if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) {
return code; newHeaders.add("Spas-AccessKey");
} newHeaders.add(accessKey);
List<String> signHeaders = SpasAdapter.getSignHeaders(paramValues, secretKey);
if (signHeaders != null) {
newHeaders.addAll(signHeaders);
}
}
return newHeaders;
}
public String toString() { private STSCredential getSTSCredential() throws IOException {
return "STSCredential{" + boolean cacheSecurityCredentials = STSConfig.getInstance().isCacheSecurityCredentials();
"accessKeyId='" + accessKeyId + '\'' + if (cacheSecurityCredentials && sTSCredential != null) {
", accessKeySecret='" + accessKeySecret + '\'' + long currentTime = System.currentTimeMillis();
", expiration=" + expiration + long expirationTime = sTSCredential.expiration.getTime();
", securityToken='" + securityToken + '\'' + int timeToRefreshInMillisecond = STSConfig.getInstance().getTimeToRefreshInMillisecond();
", lastUpdated=" + lastUpdated + if (expirationTime - currentTime > timeToRefreshInMillisecond) {
", code='" + code + '\'' + return sTSCredential;
'}'; }
} }
} String stsResponse = getSTSResponse();
STSCredential stsCredentialTmp = (STSCredential)JSONUtils.deserializeObject(stsResponse,
private String accessKey; new TypeReference<STSCredential>() {});
private String secretKey; sTSCredential = stsCredentialTmp;
private String encode; log.info("getSTSCredential", "code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}", sTSCredential.getCode(),
private volatile STSCredential sTSCredential; sTSCredential.getAccessKeyId(), sTSCredential.getLastUpdated(), sTSCredential.getExpiration());
final ServerListManager serverListMgr; return sTSCredential;
}
private static String getSTSResponse() throws IOException {
String securityCredentials = STSConfig.getInstance().getSecurityCredentials();
if (securityCredentials != null) {
return securityCredentials;
}
String securityCredentialsUrl = STSConfig.getInstance().getSecurityCredentialsUrl();
HttpURLConnection conn = null;
int respCode;
String response;
try {
conn = (HttpURLConnection)new URL(securityCredentialsUrl).openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
conn.setReadTimeout(1000);
conn.connect();
respCode = conn.getResponseCode();
if (HttpURLConnection.HTTP_OK == respCode) {
response = IOUtils.toString(conn.getInputStream(), Constants.ENCODE);
} else {
response = IOUtils.toString(conn.getErrorStream(), Constants.ENCODE);
}
} catch (IOException e) {
log.error("500", "can not get security credentials", e);
throw e;
} finally {
if (null != conn) {
conn.disconnect();
}
}
if (HttpURLConnection.HTTP_OK == respCode) {
return response;
}
log.error(respCode + "", "can not get security credentials, securityCredentialsUrl:{}, response:{}",
new Object[] {securityCredentialsUrl, response});
throw new IOException(
"can not get security credentials, responseCode: " + respCode + ", response: " + response);
}
public String getName() {
return serverListMgr.getName();
}
public String getNamespace() {
return serverListMgr.getNamespace();
}
public String getTenant() {
return serverListMgr.getTenant();
}
public String getEncode() {
return encode;
}
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
private static class STSCredential {
@JsonProperty(value = "AccessKeyId")
private String accessKeyId;
@JsonProperty(value = "AccessKeySecret")
private String accessKeySecret;
@JsonProperty(value = "Expiration")
private Date expiration;
@JsonProperty(value = "SecurityToken")
private String securityToken;
@JsonProperty(value = "LastUpdated")
private Date lastUpdated;
@JsonProperty(value = "Code")
private String code;
public String getAccessKeyId() {
return accessKeyId;
}
public Date getExpiration() {
return expiration;
}
public Date getLastUpdated() {
return lastUpdated;
}
public String getCode() {
return code;
}
public String toString() {
return "STSCredential{" +
"accessKeyId='" + accessKeyId + '\'' +
", accessKeySecret='" + accessKeySecret + '\'' +
", expiration=" + expiration +
", securityToken='" + securityToken + '\'' +
", lastUpdated=" + lastUpdated +
", code='" + code + '\'' +
'}';
}
}
private String accessKey;
private String secretKey;
private String encode;
private volatile STSCredential sTSCredential;
final ServerListManager serverListMgr;
} }

View File

@ -40,212 +40,213 @@ import com.alibaba.nacos.client.utils.StringUtils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/** /**
* Serverlist Manager * Serverlist Manager
* *
* @author Nacos * @author Nacos
*/ */
public class ServerListManager { public class ServerListManager {
final static public Logger log = LogUtils.logger(ServerListManager.class);
public ServerListManager() {
isFixed = false;
isStarted = false;
name = DEFAULT_NAME;
}
public ServerListManager(List<String> fixed) { final static public Logger log = LogUtils.logger(ServerListManager.class);
this(fixed, null);
}
public ServerListManager(List<String> fixed, String namespace) {
isFixed = true;
isStarted = true;
List<String> serverAddrs = new ArrayList<String>();
for (String serverAddr : fixed) {
String[] serverAddrArr = serverAddr.split(":");
if (serverAddrArr.length == 1) {
serverAddrs.add(serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
} else {
serverAddrs.add(serverAddr);
}
}
serverUrls = new ArrayList<String>(serverAddrs);
if (StringUtils.isBlank(namespace)) {
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()]));
} else {
this.namespace = namespace;
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()])) + "-"
+ namespace;
}
}
public ServerListManager(String host, int port) { public ServerListManager() {
isFixed = false; isFixed = false;
isStarted = false; isStarted = false;
name = CUSTOM_NAME + "-" + host + "-" + port; name = DEFAULT_NAME;
addressServerUrl = String.format("http://%s:%d/%s/%s", host, port, contentPath, serverListName); }
}
public ServerListManager(String endpoint) throws NacosException { public ServerListManager(List<String> fixed) {
this(endpoint, null); this(fixed, null);
} }
public ServerListManager(List<String> fixed, String namespace) {
isFixed = true;
isStarted = true;
List<String> serverAddrs = new ArrayList<String>();
for (String serverAddr : fixed) {
String[] serverAddrArr = serverAddr.split(":");
if (serverAddrArr.length == 1) {
serverAddrs.add(serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
} else {
serverAddrs.add(serverAddr);
}
}
serverUrls = new ArrayList<String>(serverAddrs);
if (StringUtils.isBlank(namespace)) {
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()]));
} else {
this.namespace = namespace;
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()])) + "-"
+ namespace;
}
}
public ServerListManager(String host, int port) {
isFixed = false;
isStarted = false;
name = CUSTOM_NAME + "-" + host + "-" + port;
addressServerUrl = String.format("http://%s:%d/%s/%s", host, port, contentPath, serverListName);
}
public ServerListManager(String endpoint) throws NacosException {
this(endpoint, null);
}
public ServerListManager(String endpoint, String namespace) throws NacosException {
isFixed = false;
isStarted = false;
if (StringUtils.isBlank(endpoint)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
}
if (StringUtils.isBlank(namespace)) {
name = endpoint;
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
serverListName);
} else {
if (StringUtils.isBlank(endpoint)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
}
name = endpoint + "-" + namespace;
this.namespace = namespace;
this.tenant = namespace;
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort, contentPath,
serverListName, namespace);
}
}
public ServerListManager(Properties properties) throws NacosException {
isStarted = false;
String serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
String namespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
initParam(properties);
if (StringUtils.isNotEmpty(serverAddrsStr)) {
isFixed = true;
List<String> serverAddrs = new ArrayList<String>();
String[] serverAddrsArr = serverAddrsStr.split(",");
for (String serverAddr : serverAddrsArr) {
String[] serverAddrArr = serverAddr.split(":");
if (serverAddrArr.length == 1) {
serverAddrs.add(serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
} else {
serverAddrs.add(serverAddr);
}
}
serverUrls = serverAddrs;
if (StringUtils.isBlank(namespace)) {
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()]));
} else {
this.namespace = namespace;
this.tenant = namespace;
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()])) + "-"
+ namespace;
}
} else {
if (StringUtils.isBlank(endpoint)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
}
isFixed = false;
if (StringUtils.isBlank(namespace)) {
name = endpoint;
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
serverListName);
} else {
this.namespace = namespace;
this.tenant = namespace;
name = endpoint + "-" + namespace;
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort,
contentPath, serverListName, namespace);
}
}
}
private void initParam(Properties properties) {
String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT);
if (!StringUtils.isBlank(endpointTmp)) {
endpoint = endpointTmp;
}
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
if (!StringUtils.isBlank(contentPathTmp)) {
contentPath = contentPathTmp;
}
String serverListNameTmp = properties.getProperty(PropertyKeyConst.CLUSTER_NAME);
if (!StringUtils.isBlank(serverListNameTmp)) {
serverListName = serverListNameTmp;
}
}
public ServerListManager(String endpoint, String namespace) throws NacosException {
isFixed = false;
isStarted = false;
if (StringUtils.isBlank(endpoint)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
}
if (StringUtils.isBlank(namespace)) {
name = endpoint;
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
serverListName);
} else {
if (StringUtils.isBlank(endpoint)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
}
name = endpoint + "-" + namespace;
this.namespace = namespace;
this.tenant = namespace;
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort, contentPath,
serverListName, namespace);
}
}
public ServerListManager(Properties properties) throws NacosException {
isStarted = false;
String serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
String namespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
initParam(properties);
if (StringUtils.isNotEmpty(serverAddrsStr)) {
isFixed = true;
List<String> serverAddrs = new ArrayList<String>();
String[] serverAddrsArr = serverAddrsStr.split(",");
for (String serverAddr : serverAddrsArr) {
String[] serverAddrArr = serverAddr.split(":");
if (serverAddrArr.length == 1) {
serverAddrs.add(serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
} else {
serverAddrs.add(serverAddr);
}
}
serverUrls = serverAddrs;
if (StringUtils.isBlank(namespace)) {
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()]));
} else {
this.namespace = namespace;
this.tenant = namespace;
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()])) + "-"
+ namespace;
}
} else {
if (StringUtils.isBlank(endpoint)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
}
isFixed = false;
if (StringUtils.isBlank(namespace)) {
name = endpoint;
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
serverListName);
} else {
this.namespace = namespace;
this.tenant = namespace;
name = endpoint + "-" + namespace;
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort,
contentPath, serverListName, namespace);
}
}
}
private void initParam(Properties properties) {
String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT);
if (!StringUtils.isBlank(endpointTmp)) {
endpoint = endpointTmp;
}
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
if (!StringUtils.isBlank(contentPathTmp)) {
contentPath = contentPathTmp;
}
String serverListNameTmp = properties.getProperty(PropertyKeyConst.CLUSTER_NAME);
if (!StringUtils.isBlank(serverListNameTmp)) {
serverListName = serverListNameTmp;
}
}
public synchronized void start() throws NacosException { public synchronized void start() throws NacosException {
if (isStarted || isFixed) { if (isStarted || isFixed) {
return; return;
} }
GetServerListTask getServersTask = new GetServerListTask(addressServerUrl); GetServerListTask getServersTask = new GetServerListTask(addressServerUrl);
for (int i = 0; i < initServerlistRetryTimes && serverUrls.isEmpty(); ++i) { for (int i = 0; i < initServerlistRetryTimes && serverUrls.isEmpty(); ++i) {
getServersTask.run(); getServersTask.run();
try { try {
this.wait((i + 1) * 100L); this.wait((i + 1) * 100L);
} catch (Exception e) { } catch (Exception e) {
log.warn("get serverlist fail,url: " + addressServerUrl); log.warn("get serverlist fail,url: " + addressServerUrl);
} }
} }
if (serverUrls.isEmpty()) { if (serverUrls.isEmpty()) {
log.error("NACOS-0008", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0008", "环境问题", log.error("NACOS-0008", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0008", "环境问题",
"fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl)); "fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl));
log.error(name, "NACOS-XXXX", "[init-serverlist] fail to get NACOS-server serverlist!"); log.error(name, "NACOS-XXXX", "[init-serverlist] fail to get NACOS-server serverlist!");
throw new NacosException(NacosException.SERVER_ERROR, throw new NacosException(NacosException.SERVER_ERROR,
"fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl); "fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl);
} }
TimerService.scheduleWithFixedDelay(getServersTask, 0L, 30L, TimeUnit.SECONDS); TimerService.scheduleWithFixedDelay(getServersTask, 0L, 30L, TimeUnit.SECONDS);
isStarted = true; isStarted = true;
} }
Iterator<String> iterator() { Iterator<String> iterator() {
if (serverUrls.isEmpty()) { if (serverUrls.isEmpty()) {
log.error(name, "NACOS-XXXX", "[iterator-serverlist] No server address defined!"); log.error(name, "NACOS-XXXX", "[iterator-serverlist] No server address defined!");
} }
return new ServerAddressIterator(serverUrls); return new ServerAddressIterator(serverUrls);
} }
class GetServerListTask implements Runnable { class GetServerListTask implements Runnable {
final String url; final String url;
GetServerListTask(String url) { GetServerListTask(String url) {
this.url = url; this.url = url;
} }
@Override @Override
public void run() { public void run() {
/** /**
* get serverlist from nameserver * get serverlist from nameserver
*/ */
try { try {
updateIfChanged(getApacheServerList(url, name)); updateIfChanged(getApacheServerList(url, name));
} catch (Exception e) { } catch (Exception e) {
log.error(name, "NACOS-XXXX", "[update-serverlist] failed to update serverlist from address server!", e); log.error(name, "NACOS-XXXX", "[update-serverlist] failed to update serverlist from address server!",
e);
} }
} }
} }
private void updateIfChanged(List<String> newList) { private void updateIfChanged(List<String> newList) {
if (null == newList || newList.isEmpty()) { if (null == newList || newList.isEmpty()) {
log.warn("NACOS-0001", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0001", "环境问题","[update-serverlist] current serverlist from address server is empty!!!")); log.warn("NACOS-0001", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0001", "环境问题",
"[update-serverlist] current serverlist from address server is empty!!!"));
log.warn(name, "[update-serverlist] current serverlist from address server is empty!!!"); log.warn(name, "[update-serverlist] current serverlist from address server is empty!!!");
return; return;
} }
/** /**
* no change * no change
*/ */
if (newList.equals(serverUrls)) { if (newList.equals(serverUrls)) {
return; return;
} }
serverUrls = new ArrayList<String>(newList); serverUrls = new ArrayList<String>(newList);
currentServerAddr = iterator().next(); currentServerAddr = iterator().next();
EventDispatcher.fireEvent(new ServerlistChangeEvent()); EventDispatcher.fireEvent(new ServerlistChangeEvent());
log.info(name, "[update-serverlist] serverlist updated to {}", serverUrls); log.info(name, "[update-serverlist] serverlist updated to {}", serverUrls);
} }
@ -253,38 +254,38 @@ public class ServerListManager {
private List<String> getApacheServerList(String url, String name) { private List<String> getApacheServerList(String url, String name) {
try { try {
HttpResult httpResult = HttpSimpleClient.httpGet(url, null, null, null, 3000); HttpResult httpResult = HttpSimpleClient.httpGet(url, null, null, null, 3000);
if (HttpURLConnection.HTTP_OK == httpResult.code) { if (HttpURLConnection.HTTP_OK == httpResult.code) {
if (DEFAULT_NAME.equals(name) ) { if (DEFAULT_NAME.equals(name)) {
EnvUtil.setSelfEnv(httpResult.headers); EnvUtil.setSelfEnv(httpResult.headers);
} }
List<String> lines = IOUtils.readLines(new StringReader(httpResult.content)); List<String> lines = IOUtils.readLines(new StringReader(httpResult.content));
List<String> result = new ArrayList<String>(lines.size()); List<String> result = new ArrayList<String>(lines.size());
for (String serverAddr : lines) { for (String serverAddr : lines) {
if (null == serverAddr || serverAddr.trim().isEmpty()) { if (null == serverAddr || serverAddr.trim().isEmpty()) {
continue; continue;
} else { } else {
String[] ipPort = serverAddr.trim().split(":"); String[] ipPort = serverAddr.trim().split(":");
String ip = ipPort[0].trim(); String ip = ipPort[0].trim();
if (ipPort.length == 1) { if (ipPort.length == 1) {
result.add(ip + ":" + ParamUtil.getDefaultServerPort()); result.add(ip + ":" + ParamUtil.getDefaultServerPort());
} else { } else {
result.add(serverAddr); result.add(serverAddr);
} }
} }
} }
return result; return result;
} else { } else {
log.error(addressServerUrl, "NACOS-XXXX", "[check-serverlist] error. code={}", httpResult.code); log.error(addressServerUrl, "NACOS-XXXX", "[check-serverlist] error. code={}", httpResult.code);
return null; return null;
} }
} catch (IOException e) { } catch (IOException e) {
log.error("NACOS-0001", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0001", "环境问题",e.toString())); log.error("NACOS-0001", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0001", "环境问题", e.toString()));
log.error(addressServerUrl, "NACOS-XXXX", "[check-serverlist] exception. msg={}", e.toString(), e); log.error(addressServerUrl, "NACOS-XXXX", "[check-serverlist] exception. msg={}", e.toString(), e);
return null; return null;
} }
} }
String getUrlString() { String getUrlString() {
return serverUrls.toString(); return serverUrls.toString();
} }
@ -300,99 +301,97 @@ public class ServerListManager {
return sb.toString(); return sb.toString();
} }
@Override @Override
public String toString() { public String toString() {
return "ServerManager-" + name + "-" +getUrlString(); return "ServerManager-" + name + "-" + getUrlString();
} }
public boolean contain(String ip){ public boolean contain(String ip) {
return serverUrls.contains(ip);
}
public void refreshCurrentServerAddr() { return serverUrls.contains(ip);
currentServerAddr = iterator().next(); }
}
public String getCurrentServerAddr() { public void refreshCurrentServerAddr() {
if (StringUtils.isBlank(currentServerAddr)) { currentServerAddr = iterator().next();
currentServerAddr = iterator().next(); }
}
return currentServerAddr;
}
public String getCurrentServerAddr() {
public String getContentPath() { if (StringUtils.isBlank(currentServerAddr)) {
return contentPath; currentServerAddr = iterator().next();
} }
return currentServerAddr;
public String getName() { }
return name;
}
public String getNamespace() {
return namespace;
}
public String getTenant() { public String getContentPath() {
return tenant; return contentPath;
} }
/** public String getName() {
* 不同环境的名称 return name;
*/ }
private String name;
private String namespace = ""; public String getNamespace() {
private String tenant = ""; return namespace;
}
public String getTenant() {
return tenant;
}
/**
* 不同环境的名称
*/
private String name;
private String namespace = "";
private String tenant = "";
static public final String DEFAULT_NAME = "default"; static public final String DEFAULT_NAME = "default";
static public final String CUSTOM_NAME = "custom"; static public final String CUSTOM_NAME = "custom";
static public final String FIXED_NAME = "fixed"; static public final String FIXED_NAME = "fixed";
private int initServerlistRetryTimes = 5; private int initServerlistRetryTimes = 5;
/** /**
* 和其他server的连接超时和socket超时 * 和其他server的连接超时和socket超时
*/ */
static final int TIMEOUT = 5000; static final int TIMEOUT = 5000;
final boolean isFixed; final boolean isFixed;
boolean isStarted = false; boolean isStarted = false;
private String endpoint; private String endpoint;
private int endpointPort = 8080; private int endpointPort = 8080;
private String contentPath = ParamUtil.getDefaultContextPath(); private String contentPath = ParamUtil.getDefaultContextPath();
private String serverListName = ParamUtil.getDefaultNodesPath(); private String serverListName = ParamUtil.getDefaultNodesPath();
volatile List<String> serverUrls = new ArrayList<String>(); volatile List<String> serverUrls = new ArrayList<String>();
private volatile String currentServerAddr; private volatile String currentServerAddr;
public String serverPort = ParamUtil.getDefaultServerPort(); public String serverPort = ParamUtil.getDefaultServerPort();
public String addressServerUrl; public String addressServerUrl;
} }
/** /**
* 对地址列表排序同机房优先 * 对地址列表排序同机房优先
*/ */
class ServerAddressIterator implements Iterator<String> { class ServerAddressIterator implements Iterator<String> {
static class RandomizedServerAddress implements Comparable<RandomizedServerAddress> { static class RandomizedServerAddress implements Comparable<RandomizedServerAddress> {
static Random random = new Random(); static Random random = new Random();
String serverIp; String serverIp;
int priority = 0; int priority = 0;
int seed; int seed;
public RandomizedServerAddress(String ip) { public RandomizedServerAddress(String ip) {
try { try {
this.serverIp = ip; this.serverIp = ip;
/** /**
* change random scope from 32 to Integer.MAX_VALUE to fix load balance issue * change random scope from 32 to Integer.MAX_VALUE to fix load balance issue
*/ */
this.seed = random.nextInt(Integer.MAX_VALUE); this.seed = random.nextInt(Integer.MAX_VALUE);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@Override @Override
@SuppressFBWarnings("EQ_COMPARETO_USE_OBJECT_EQUALS") @SuppressFBWarnings("EQ_COMPARETO_USE_OBJECT_EQUALS")
@ -425,7 +424,7 @@ class ServerAddressIterator implements Iterator<String> {
public void remove() { public void remove() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
final List<RandomizedServerAddress> sorted; final List<RandomizedServerAddress> sorted;
final Iterator<RandomizedServerAddress> iter; final Iterator<RandomizedServerAddress> iter;
} }

View File

@ -27,81 +27,79 @@ import java.util.*;
/** /**
* 适配spas接口 * 适配spas接口
*
* @author Nacos
* *
* @author Nacos
*/ */
public class SpasAdapter { public class SpasAdapter {
public static List<String> getSignHeaders(String resource, String secretKey) {
List<String> header = new ArrayList<String>();
String timeStamp = String.valueOf(System.currentTimeMillis());
header.add("Timestamp");
header.add(timeStamp);
if (secretKey != null) {
header.add("Spas-Signature");
String signature = "";
if (StringUtils.isBlank(resource)) {
signature = signWithhmacSHA1Encrypt(timeStamp, secretKey);
} else {
signature = signWithhmacSHA1Encrypt(resource + "+" + timeStamp, secretKey);
}
header.add(signature);
}
return header;
}
public static List<String> getSignHeaders(List<String> paramValues, String secretKey) {
if (null == paramValues) {
return null;
}
Map<String, String> signMap = new HashMap<String, String>(5);
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext();) {
String key = iter.next();
if (TENANT_KEY.equals(key) || GROUP_KEY.equals(key)) {
signMap.put(key, iter.next());
} else {
iter.next();
}
}
String resource = "";
if (signMap.size() > 1) {
resource = signMap.get(TENANT_KEY) + "+" + signMap.get(GROUP_KEY);
} else {
if (!StringUtils.isBlank(signMap.get(GROUP_KEY))) {
resource = signMap.get(GROUP_KEY);
}
}
return getSignHeaders(resource, secretKey);
}
public static String getSk() { public static List<String> getSignHeaders(String resource, String secretKey) {
return CredentialService.getInstance().getCredential().getSecretKey(); List<String> header = new ArrayList<String>();
} String timeStamp = String.valueOf(System.currentTimeMillis());
header.add("Timestamp");
header.add(timeStamp);
if (secretKey != null) {
header.add("Spas-Signature");
String signature = "";
if (StringUtils.isBlank(resource)) {
signature = signWithhmacSHA1Encrypt(timeStamp, secretKey);
} else {
signature = signWithhmacSHA1Encrypt(resource + "+" + timeStamp, secretKey);
}
header.add(signature);
}
return header;
}
public static String getAk() { public static List<String> getSignHeaders(List<String> paramValues, String secretKey) {
return CredentialService.getInstance().getCredential().getAccessKey(); if (null == paramValues) {
} return null;
}
public static String signWithhmacSHA1Encrypt(String encryptText, String encryptKey) { Map<String, String> signMap = new HashMap<String, String>(5);
try { for (Iterator<String> iter = paramValues.iterator(); iter.hasNext(); ) {
byte[] data = encryptKey.getBytes("UTF-8"); String key = iter.next();
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称 if (TENANT_KEY.equals(key) || GROUP_KEY.equals(key)) {
SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1"); signMap.put(key, iter.next());
// 生成一个指定 Mac 算法 Mac 对象 } else {
Mac mac = Mac.getInstance("HmacSHA1"); iter.next();
// 用给定密钥初始化 Mac 对象 }
mac.init(secretKey); }
byte[] text = encryptText.getBytes("UTF-8"); String resource = "";
byte[] textFinal = mac.doFinal(text); if (signMap.size() > 1) {
// 完成 Mac 操作, base64编码将byte数组转换为字符串 resource = signMap.get(TENANT_KEY) + "+" + signMap.get(GROUP_KEY);
return new String(Base64.encodeBase64(textFinal), Constants.ENCODE); } else {
} catch (Exception e) { if (!StringUtils.isBlank(signMap.get(GROUP_KEY))) {
throw new RuntimeException("signWithhmacSHA1Encrypt fail", e); resource = signMap.get(GROUP_KEY);
} }
} }
return getSignHeaders(resource, secretKey);
private static String GROUP_KEY = "group"; }
private static String TENANT_KEY = "tenant";
public static String getSk() {
return CredentialService.getInstance().getCredential().getSecretKey();
}
public static String getAk() {
return CredentialService.getInstance().getCredential().getAccessKey();
}
public static String signWithhmacSHA1Encrypt(String encryptText, String encryptKey) {
try {
byte[] data = encryptKey.getBytes("UTF-8");
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
// 生成一个指定 Mac 算法 Mac 对象
Mac mac = Mac.getInstance("HmacSHA1");
// 用给定密钥初始化 Mac 对象
mac.init(secretKey);
byte[] text = encryptText.getBytes("UTF-8");
byte[] textFinal = mac.doFinal(text);
// 完成 Mac 操作, base64编码将byte数组转换为字符串
return new String(Base64.encodeBase64(textFinal), Constants.ENCODE);
} catch (Exception e) {
throw new RuntimeException("signWithhmacSHA1Encrypt fail", e);
}
}
private static String GROUP_KEY = "group";
private static String TENANT_KEY = "tenant";
} }

View File

@ -21,28 +21,27 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Time Service * Time Service
* @author Nacos
* *
* @author Nacos
*/ */
public class TimerService { public class TimerService {
static public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, static public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,
long delay, TimeUnit unit) { long delay, TimeUnit unit) {
return scheduledExecutor.scheduleWithFixedDelay(command, initialDelay, delay, unit); return scheduledExecutor.scheduleWithFixedDelay(command, initialDelay, delay, unit);
} }
@SuppressWarnings("PMD.ThreadPoolCreationRule") @SuppressWarnings("PMD.ThreadPoolCreationRule")
static ScheduledExecutorService scheduledExecutor = Executors static ScheduledExecutorService scheduledExecutor = Executors
.newSingleThreadScheduledExecutor(new ThreadFactory() { .newSingleThreadScheduledExecutor(new ThreadFactory() {
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
Thread t = new Thread(r); Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Timer"); t.setName("com.alibaba.nacos.client.Timer");
t.setDaemon(true); t.setDaemon(true);
return t; return t;
} }
}); });
} }

View File

@ -26,14 +26,13 @@ import java.util.Properties;
/** /**
* Properties Listener * Properties Listener
*
* @author Nacos
* *
* @author Nacos
*/ */
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule") @SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class PropertiesListener extends AbstractListener { public abstract class PropertiesListener extends AbstractListener {
final static public Logger log = LogUtils.logger(PropertiesListener.class); final static public Logger log = LogUtils.logger(PropertiesListener.class);
public void receiveConfigInfo(String configInfo) { public void receiveConfigInfo(String configInfo) {
if (StringUtils.isEmpty(configInfo)) { if (StringUtils.isEmpty(configInfo)) {
return; return;
@ -43,19 +42,17 @@ public abstract class PropertiesListener extends AbstractListener {
try { try {
properties.load(new StringReader(configInfo)); properties.load(new StringReader(configInfo));
innerReceive(properties); innerReceive(properties);
} } catch (IOException e) {
catch (IOException e) { log.error("NACOS-XXXX", "load properties error" + configInfo, e);
log.error("NACOS-XXXX","load properties error" + configInfo, e);
} }
} }
/** /**
* properties type for receiver * properties type for receiver
* *
* @param properties * @param properties properties
* properties */
*/ public abstract void innerReceive(Properties properties);
public abstract void innerReceive(Properties properties);
} }

View File

@ -30,217 +30,199 @@ import java.nio.charset.CharsetDecoder;
/** /**
* concurrent disk util;op file with file lock * concurrent disk util;op file with file lock
*
* @author configCenter
* *
* @author configCenter
*/ */
public class ConcurrentDiskUtil { public class ConcurrentDiskUtil {
/** /**
* get file content * get file content
* *
* @param path * @param path file path
* file path * @param charsetName charsetName
* @param charsetName * @return content
* charsetName * @throws IOException IOException
* @return content */
* @throws IOException public static String getFileContent(String path, String charsetName)
* IOException throws IOException {
*/ File file = new File(path);
public static String getFileContent(String path, String charsetName) return getFileContent(file, charsetName);
throws IOException { }
File file = new File(path);
return getFileContent(file, charsetName);
}
/** /**
* get file content * get file content
* *
* @param file * @param file file
* file * @param charsetName charsetName
* @param charsetName * @return content
* charsetName * @throws IOException IOException
* @return content */
* @throws IOException public static String getFileContent(File file, String charsetName)
* IOException throws IOException {
*/ RandomAccessFile fis = null;
public static String getFileContent(File file, String charsetName) FileLock rlock = null;
throws IOException { try {
RandomAccessFile fis = null; fis = new RandomAccessFile(file, "r");
FileLock rlock = null; FileChannel fcin = fis.getChannel();
try { int i = 0;
fis = new RandomAccessFile(file, "r"); do {
FileChannel fcin = fis.getChannel(); try {
int i = 0; rlock = fcin.tryLock(0L, Long.MAX_VALUE, true);
do { } catch (Exception e) {
try { ++i;
rlock = fcin.tryLock(0L, Long.MAX_VALUE, true); if (i > RETRY_COUNT) {
} catch (Exception e) { log.error("read {} fail;retryed time:{}",
++i; file.getName(), i);
if (i > RETRY_COUNT) { throw new IOException("read " + file.getAbsolutePath()
log.error("read {} fail;retryed time:{}", + " conflict");
file.getName(), i); }
throw new IOException("read " + file.getAbsolutePath() sleep(SLEEP_BASETIME * i);
+ " conflict"); log.warn("read {} conflict;retry time:{}", file.getName(),
} i);
sleep(SLEEP_BASETIME * i); }
log.warn("read {} conflict;retry time:{}", file.getName(), } while (null == rlock);
i); int fileSize = (int)fcin.size();
} ByteBuffer byteBuffer = ByteBuffer.allocate(fileSize);
} while (null == rlock); fcin.read(byteBuffer);
int fileSize = (int) fcin.size(); byteBuffer.flip();
ByteBuffer byteBuffer = ByteBuffer.allocate(fileSize); return byteBufferToString(byteBuffer, charsetName);
fcin.read(byteBuffer); } finally {
byteBuffer.flip(); if (rlock != null) {
return byteBufferToString(byteBuffer, charsetName); rlock.release();
} finally { rlock = null;
if (rlock != null) { }
rlock.release(); if (fis != null) {
rlock = null; fis.close();
} fis = null;
if (fis != null) { }
fis.close(); }
fis = null; }
}
}
}
/** /**
* write file content * write file content
* *
* @param path * @param path file path
* file path * @param content content
* @param content * @param charsetName charsetName
* content * @return whether write ok
* @param charsetName * @throws IOException IOException
* charsetName */
* @return whether write ok public static Boolean writeFileContent(String path, String content,
* @throws IOException String charsetName) throws IOException {
* IOException File file = new File(path);
*/ return writeFileContent(file, content, charsetName);
public static Boolean writeFileContent(String path, String content, }
String charsetName) throws IOException {
File file = new File(path);
return writeFileContent(file, content, charsetName);
}
/** /**
* write file content * write file content
* *
* @param file * @param file file
* file * @param content content
* @param content * @param charsetName charsetName
* content * @return whether write ok
* @param charsetName * @throws IOException IOException
* charsetName */
* @return whether write ok public static Boolean writeFileContent(File file, String content,
* @throws IOException String charsetName) throws IOException {
* IOException if (!file.exists()) {
*/ boolean isCreateOk = file.createNewFile();
public static Boolean writeFileContent(File file, String content, if (!isCreateOk) {
String charsetName) throws IOException { return false;
if (!file.exists()) { }
boolean isCreateOk = file.createNewFile(); }
if (!isCreateOk) { FileChannel channel = null;
return false; FileLock lock = null;
} RandomAccessFile raf = null;
} try {
FileChannel channel = null; raf = new RandomAccessFile(file, "rw");
FileLock lock = null; channel = raf.getChannel();
RandomAccessFile raf = null; int i = 0;
try { do {
raf = new RandomAccessFile(file, "rw"); try {
channel = raf.getChannel(); lock = channel.tryLock();
int i = 0; } catch (Exception e) {
do { ++i;
try { if (i > RETRY_COUNT) {
lock = channel.tryLock(); log.error("write {} fail;retryed time:{}",
} catch (Exception e) { file.getName(), i);
++i; throw new IOException("write " + file.getAbsolutePath()
if (i > RETRY_COUNT) { + " conflict");
log.error("write {} fail;retryed time:{}", }
file.getName(), i); sleep(SLEEP_BASETIME * i);
throw new IOException("write " + file.getAbsolutePath() log.warn("write {} conflict;retry time:{}", file.getName(),
+ " conflict"); i);
} }
sleep(SLEEP_BASETIME * i); } while (null == lock);
log.warn("write {} conflict;retry time:{}", file.getName(),
i);
}
} while (null == lock);
ByteBuffer sendBuffer = ByteBuffer.wrap(content ByteBuffer sendBuffer = ByteBuffer.wrap(content
.getBytes(charsetName)); .getBytes(charsetName));
while (sendBuffer.hasRemaining()) { while (sendBuffer.hasRemaining()) {
channel.write(sendBuffer); channel.write(sendBuffer);
} }
channel.truncate(content.length()); channel.truncate(content.length());
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
throw new IOException("file not exist"); throw new IOException("file not exist");
} finally { } finally {
if (lock != null) { if (lock != null) {
try { try {
lock.release(); lock.release();
lock = null; lock = null;
} catch (IOException e) { } catch (IOException e) {
log.warn("close wrong", e); log.warn("close wrong", e);
} }
} }
if (channel != null) { if (channel != null) {
try { try {
channel.close(); channel.close();
channel = null; channel = null;
} catch (IOException e) { } catch (IOException e) {
log.warn("close wrong", e); log.warn("close wrong", e);
} }
} }
if (raf != null) { if (raf != null) {
try { try {
raf.close(); raf.close();
raf = null; raf = null;
} catch (IOException e) { } catch (IOException e) {
log.warn("close wrong", e); log.warn("close wrong", e);
} }
} }
} }
return true; return true;
} }
/** /**
* transfer ByteBuffer to String * transfer ByteBuffer to String
* *
* @param buffer * @param buffer buffer
* buffer * @param charsetName charsetName
* @param charsetName * @return String
* charsetName * @throws IOException IOException
* @return String */
* @throws IOException public static String byteBufferToString(ByteBuffer buffer,
* IOException String charsetName) throws IOException {
*/ Charset charset = null;
public static String byteBufferToString(ByteBuffer buffer, CharsetDecoder decoder = null;
String charsetName) throws IOException { CharBuffer charBuffer = null;
Charset charset = null; charset = Charset.forName(charsetName);
CharsetDecoder decoder = null; decoder = charset.newDecoder();
CharBuffer charBuffer = null; charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
charset = Charset.forName(charsetName); return charBuffer.toString();
decoder = charset.newDecoder(); }
charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
return charBuffer.toString();
}
private static void sleep(int time) { private static void sleep(int time) {
try { try {
Thread.sleep(time); Thread.sleep(time);
} catch (InterruptedException e) { } catch (InterruptedException e) {
log.warn("sleep wrong", e); log.warn("sleep wrong", e);
} }
} }
static final public Logger log = LogUtils.logger(ConcurrentDiskUtil.class); static final public Logger log = LogUtils.logger(ConcurrentDiskUtil.class);
static final int RETRY_COUNT = 10; static final int RETRY_COUNT = 10;
/** /**
* ms * ms
*/ */
static final int SLEEP_BASETIME = 10; static final int SLEEP_BASETIME = 10;
} }

View File

@ -21,9 +21,8 @@ import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR;
/** /**
* Content Util * Content Util
*
* @author Nacos
* *
* @author Nacos
*/ */
public class ContentUtils { public class ContentUtils {
@ -43,7 +42,6 @@ public class ContentUtils {
} }
} }
public static String getContentIdentity(String content) { public static String getContentIdentity(String content) {
int index = content.indexOf(WORD_SEPARATOR); int index = content.indexOf(WORD_SEPARATOR);
if (index == -1) { if (index == -1) {
@ -52,7 +50,6 @@ public class ContentUtils {
return content.substring(0, index); return content.substring(0, index);
} }
public static String getContent(String content) { public static String getContent(String content) {
int index = content.indexOf(WORD_SEPARATOR); int index = content.indexOf(WORD_SEPARATOR);
if (index == -1) { if (index == -1) {
@ -61,18 +58,15 @@ public class ContentUtils {
return content.substring(index + 1); return content.substring(index + 1);
} }
public static String truncateContent(String content) { public static String truncateContent(String content) {
if (content == null) { if (content == null) {
return ""; return "";
} } else if (content.length() <= SHOW_CONTENT_SIZE) {
else if (content.length() <= SHOW_CONTENT_SIZE) {
return content; return content;
} } else {
else { return content.substring(0, SHOW_CONTENT_SIZE) + "...";
return content.substring(0, SHOW_CONTENT_SIZE) + "...";
} }
} }
private static int SHOW_CONTENT_SIZE = 100; private static int SHOW_CONTENT_SIZE = 100;
} }

View File

@ -21,21 +21,19 @@ import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* IO Util * IO Util
*
* @author Nacos
* *
* @author Nacos
*/ */
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class IOUtils { public class IOUtils {
static public String toString(InputStream input, String encoding) throws IOException { static public String toString(InputStream input, String encoding) throws IOException {
return (null == encoding) ? toString(new InputStreamReader(input, Constants.ENCODE)) return (null == encoding) ? toString(new InputStreamReader(input, Constants.ENCODE))
: toString(new InputStreamReader(input, encoding)); : toString(new InputStreamReader(input, encoding));
} }
static public String toString(Reader reader) throws IOException { static public String toString(Reader reader) throws IOException {
CharArrayWriter sw = new CharArrayWriter(); CharArrayWriter sw = new CharArrayWriter();
copy(reader, sw); copy(reader, sw);
@ -45,7 +43,7 @@ public class IOUtils {
static public long copy(Reader input, Writer output) throws IOException { static public long copy(Reader input, Writer output) throws IOException {
char[] buffer = new char[1 << 12]; char[] buffer = new char[1 << 12];
long count = 0; long count = 0;
for (int n = 0; (n = input.read(buffer)) >= 0;) { for (int n = 0; (n = input.read(buffer)) >= 0; ) {
output.write(buffer, 0, n); output.write(buffer, 0, n);
count += n; count += n;
} }
@ -59,7 +57,7 @@ public class IOUtils {
BufferedReader reader = toBufferedReader(input); BufferedReader reader = toBufferedReader(input);
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<String>();
String line = null; String line = null;
for (;;) { for (; ; ) {
line = reader.readLine(); line = reader.readLine();
if (null != line) { if (null != line) {
list.add(line); list.add(line);
@ -71,8 +69,8 @@ public class IOUtils {
} }
static private BufferedReader toBufferedReader(Reader reader) { static private BufferedReader toBufferedReader(Reader reader) {
return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader( return reader instanceof BufferedReader ? (BufferedReader)reader : new BufferedReader(
reader); reader);
} }
public static void delete(File fileOrDir) throws IOException { public static void delete(File fileOrDir) throws IOException {
@ -82,16 +80,16 @@ public class IOUtils {
if (fileOrDir.isDirectory()) { if (fileOrDir.isDirectory()) {
cleanDirectory(fileOrDir); cleanDirectory(fileOrDir);
} else { } else {
if (fileOrDir.exists()) { if (fileOrDir.exists()) {
boolean isDeleteOk = fileOrDir.delete(); boolean isDeleteOk = fileOrDir.delete();
if (!isDeleteOk) { if (!isDeleteOk) {
throw new IOException("delete fail"); throw new IOException("delete fail");
} }
} }
} }
} }
/** /**
* 清理目录下的内容 * 清理目录下的内容
*/ */
@ -107,10 +105,10 @@ public class IOUtils {
} }
File[] files = directory.listFiles(); File[] files = directory.listFiles();
/** /**
* null if security restricted * null if security restricted
*/ */
if (files == null) { if (files == null) {
throw new IOException("Failed to list contents of " + directory); throw new IOException("Failed to list contents of " + directory);
} }
@ -129,7 +127,7 @@ public class IOUtils {
} }
public static void writeStringToFile(File file, String data, String encoding) public static void writeStringToFile(File file, String data, String encoding)
throws IOException { throws IOException {
OutputStream os = null; OutputStream os = null;
try { try {
os = new FileOutputStream(file); os = new FileOutputStream(file);

View File

@ -19,31 +19,30 @@ import com.alibaba.nacos.client.logger.Logger;
/** /**
* Get jvm config * Get jvm config
*
* @author Nacos
* *
* @author Nacos
*/ */
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class JVMUtil { public class JVMUtil {
/** /**
* whether is multi instance * whether is multi instance
* *
* @return whether multi * @return whether multi
*/ */
public static Boolean isMultiInstance() { public static Boolean isMultiInstance() {
return isMultiInstance; return isMultiInstance;
} }
private static Boolean isMultiInstance = false; private static Boolean isMultiInstance = false;
private static String TRUE = "true"; private static String TRUE = "true";
static final public Logger log = LogUtils.logger(JVMUtil.class); static final public Logger log = LogUtils.logger(JVMUtil.class);
static { static {
String multiDeploy = System.getProperty("isMultiInstance", "false"); String multiDeploy = System.getProperty("isMultiInstance", "false");
if (TRUE.equals(multiDeploy)) { if (TRUE.equals(multiDeploy)) {
isMultiInstance = true; isMultiInstance = true;
} }
log.info("isMultiInstance:{}", isMultiInstance); log.info("isMultiInstance:{}", isMultiInstance);
} }
} }

View File

@ -22,38 +22,38 @@ import com.alibaba.nacos.client.logger.LoggerFactory;
/** /**
* Log Util * Log Util
*
* @author Nacos
* *
* @author Nacos
*/ */
public class LogUtils { public class LogUtils {
static int JM_LOG_RETAIN_COUNT = 7; static int JM_LOG_RETAIN_COUNT = 7;
static String JM_LOG_FILE_SIZE = "10MB"; static String JM_LOG_FILE_SIZE = "10MB";
static { static {
String tmp = "7"; String tmp = "7";
try { try {
/** /**
* change timeout from 100 to 200 * change timeout from 100 to 200
*/ */
tmp = System.getProperty("JM.LOG.RETAIN.COUNT","7"); tmp = System.getProperty("JM.LOG.RETAIN.COUNT", "7");
JM_LOG_RETAIN_COUNT = Integer.parseInt(tmp); JM_LOG_RETAIN_COUNT = Integer.parseInt(tmp);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
e.printStackTrace(); e.printStackTrace();
throw e; throw e;
} }
JM_LOG_FILE_SIZE = System.getProperty("JM.LOG.FILE.SIZE","10MB"); JM_LOG_FILE_SIZE = System.getProperty("JM.LOG.FILE.SIZE", "10MB");
// logger init // logger init
Logger logger = LoggerFactory.getLogger("com.alibaba.nacos.client.config"); Logger logger = LoggerFactory.getLogger("com.alibaba.nacos.client.config");
logger.setLevel(Level.INFO); logger.setLevel(Level.INFO);
logger.setAdditivity(false); logger.setAdditivity(false);
logger.activateAppenderWithSizeRolling("nacos", "config.log", Constants.ENCODE, JM_LOG_FILE_SIZE, JM_LOG_RETAIN_COUNT); logger.activateAppenderWithSizeRolling("nacos", "config.log", Constants.ENCODE, JM_LOG_FILE_SIZE,
JM_LOG_RETAIN_COUNT);
} }
public static Logger logger(Class<?> clazz) { public static Logger logger(Class<?> clazz) {
return LoggerFactory.getLogger(clazz); return LoggerFactory.getLogger(clazz);
} }
} }

View File

@ -25,16 +25,16 @@ import java.util.concurrent.locks.ReentrantLock;
/** /**
* MD5 util * MD5 util
*
* @author Nacos
* *
* @author Nacos
*/ */
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class MD5 { public class MD5 {
private static int DIGITS_SIZE = 16; private static int DIGITS_SIZE = 16;
private static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; private static char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static Map<Character, Integer> rDigits = new HashMap<Character, Integer>(16); private static Map<Character, Integer> rDigits = new HashMap<Character, Integer>(16);
static { static {
for (int i = 0; i < digits.length; ++i) { for (int i = 0; i < digits.length; ++i) {
rDigits.put(digits[i], i); rDigits.put(digits[i], i);
@ -45,41 +45,34 @@ public class MD5 {
private MessageDigest mHasher; private MessageDigest mHasher;
private ReentrantLock opLock = new ReentrantLock(); private ReentrantLock opLock = new ReentrantLock();
private MD5() { private MD5() {
try { try {
mHasher = MessageDigest.getInstance("md5"); mHasher = MessageDigest.getInstance("md5");
} } catch (Exception e) {
catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public static MD5 getInstance() { public static MD5 getInstance() {
return me; return me;
} }
public String getMD5String(String content) { public String getMD5String(String content) {
return bytes2string(hash(content)); return bytes2string(hash(content));
} }
public String getMD5String(byte[] content) { public String getMD5String(byte[] content) {
return bytes2string(hash(content)); return bytes2string(hash(content));
} }
public byte[] getMD5Bytes(byte[] content) { public byte[] getMD5Bytes(byte[] content) {
return hash(content); return hash(content);
} }
/** /**
* 对字符串进行md5 * 对字符串进行md5
* *
* @param str * @param str
* @return md5 byte[16] * @return md5 byte[16]
*/ */
@ -91,19 +84,16 @@ public class MD5 {
throw new IllegalArgumentException("md5 need"); throw new IllegalArgumentException("md5 need");
} }
return bt; return bt;
} } catch (UnsupportedEncodingException e) {
catch (UnsupportedEncodingException e) {
throw new RuntimeException("unsupported utf-8 encoding", e); throw new RuntimeException("unsupported utf-8 encoding", e);
} } finally {
finally {
opLock.unlock(); opLock.unlock();
} }
} }
/** /**
* 对二进制数据进行md5 * 对二进制数据进行md5
* *
* @param data * @param data
* @return md5 byte[16] * @return md5 byte[16]
*/ */
@ -115,16 +105,14 @@ public class MD5 {
throw new IllegalArgumentException("md5 need"); throw new IllegalArgumentException("md5 need");
} }
return bt; return bt;
} } finally {
finally {
opLock.unlock(); opLock.unlock();
} }
} }
/** /**
* 将一个字节数组转化为可见的字符串 * 将一个字节数组转化为可见的字符串
* *
* @param bt * @param bt
* @return * @return
*/ */
@ -141,5 +129,4 @@ public class MD5 {
return new String(out); return new String(out);
} }
} }

View File

@ -23,18 +23,16 @@ import com.alibaba.nacos.client.utils.StringUtils;
/** /**
* Param check util * Param check util
* *
* @author Nacos * @author Nacos
*
*/ */
public class ParamUtils { public class ParamUtils {
private static char[] validChars = new char[] { '_', '-', '.', ':' }; private static char[] validChars = new char[] {'_', '-', '.', ':'};
/** /**
* 白名单的方式检查, 合法的参数只能包含字母数字以及validChars中的字符, 并且不能为空 * 白名单的方式检查, 合法的参数只能包含字母数字以及validChars中的字符, 并且不能为空
* *
* @param param * @param param
* @return * @return
*/ */
@ -47,18 +45,15 @@ public class ParamUtils {
char ch = param.charAt(i); char ch = param.charAt(i);
if (Character.isLetterOrDigit(ch)) { if (Character.isLetterOrDigit(ch)) {
continue; continue;
} } else if (isValidChar(ch)) {
else if (isValidChar(ch)) {
continue; continue;
} } else {
else {
return false; return false;
} }
} }
return true; return true;
} }
private static boolean isValidChar(char ch) { private static boolean isValidChar(char ch) {
for (char c : validChars) { for (char c : validChars) {
if (c == ch) { if (c == ch) {
@ -67,88 +62,88 @@ public class ParamUtils {
} }
return false; return false;
} }
public static void checkKeyParam(String dataId, String group) throws NacosException {
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
}
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
}
}
public static void checkTDG(String tenant, String dataId, String group) throws NacosException {
checkTenant(tenant);
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
}
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
}
}
public static void checkKeyParam(String dataId, String group, String datumId)
throws NacosException {
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
}
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
}
if (StringUtils.isBlank(datumId) || !ParamUtils.isValid(datumId)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "datumId invalid");
}
}
public static void checkKeyParam(List<String> dataIds, String group) throws NacosException {
if (dataIds == null || dataIds.size() == 0) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataIds invalid");
}
for (String dataId : dataIds) {
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
}
}
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
}
}
public static void checkParam(String dataId, String group, String content) throws NacosException { public static void checkKeyParam(String dataId, String group) throws NacosException {
checkKeyParam(dataId, group); if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
if (StringUtils.isBlank(content)) { throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid"); }
} if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
} throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
}
public static void checkParam(String dataId, String group, String datumId, String content) throws NacosException { }
checkKeyParam(dataId, group, datumId);
if (StringUtils.isBlank(content)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
}
}
public static void checkTenant(String tenant) throws NacosException { public static void checkTDG(String tenant, String dataId, String group) throws NacosException {
if (StringUtils.isBlank(tenant) || !ParamUtils.isValid(tenant)) { checkTenant(tenant);
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "tenant invalid"); if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
} throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
} }
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
public static void checkBetaIps(String betaIps) throws NacosException { throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
if (StringUtils.isBlank(betaIps)) { }
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid"); }
}
String[] ipsArr = betaIps.split(",");
for (String ip : ipsArr) {
if (!IPUtil.isIPV4(ip)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
}
}
}
public static void checkContent(String content) throws NacosException { public static void checkKeyParam(String dataId, String group, String datumId)
if (StringUtils.isBlank(content)) { throws NacosException {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid"); if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
} throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
} }
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
}
if (StringUtils.isBlank(datumId) || !ParamUtils.isValid(datumId)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "datumId invalid");
}
}
public static void checkKeyParam(List<String> dataIds, String group) throws NacosException {
if (dataIds == null || dataIds.size() == 0) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataIds invalid");
}
for (String dataId : dataIds) {
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
}
}
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
}
}
public static void checkParam(String dataId, String group, String content) throws NacosException {
checkKeyParam(dataId, group);
if (StringUtils.isBlank(content)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
}
}
public static void checkParam(String dataId, String group, String datumId, String content) throws NacosException {
checkKeyParam(dataId, group, datumId);
if (StringUtils.isBlank(content)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
}
}
public static void checkTenant(String tenant) throws NacosException {
if (StringUtils.isBlank(tenant) || !ParamUtils.isValid(tenant)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "tenant invalid");
}
}
public static void checkBetaIps(String betaIps) throws NacosException {
if (StringUtils.isBlank(betaIps)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
}
String[] ipsArr = betaIps.split(",");
for (String ip : ipsArr) {
if (!IPUtil.isIPV4(ip)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
}
}
}
public static void checkContent(String content) throws NacosException {
if (StringUtils.isBlank(content)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
}
}
} }

View File

@ -19,24 +19,23 @@ import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
/** /**
* Snapshot switch * Snapshot switch
*
* @author Nacos
* *
* @author Nacos
*/ */
public class SnapShotSwitch { public class SnapShotSwitch {
/** /**
* whether use local cache * whether use local cache
*/ */
private static Boolean isSnapShot = true; private static Boolean isSnapShot = true;
public static Boolean getIsSnapShot() { public static Boolean getIsSnapShot() {
return isSnapShot; return isSnapShot;
} }
public static void setIsSnapShot(Boolean isSnapShot) {
SnapShotSwitch.isSnapShot = isSnapShot;
LocalConfigInfoProcessor.cleanAllSnapshot();
}
public static void setIsSnapShot(Boolean isSnapShot) {
SnapShotSwitch.isSnapShot = isSnapShot;
LocalConfigInfoProcessor.cleanAllSnapshot();
}
} }

View File

@ -19,26 +19,25 @@ import com.alibaba.nacos.client.utils.StringUtils;
/** /**
* Tenant Util * Tenant Util
*
* @author Nacos
* *
* @author Nacos
*/ */
public class TenantUtil { public class TenantUtil {
static String userTenant = ""; static String userTenant = "";
static {
userTenant = System.getProperty("tenant.id", "");
if (StringUtils.isBlank(userTenant)) {
userTenant = System.getProperty("acm.namespace", "");
}
}
public static String getUserTenant() { static {
return userTenant; userTenant = System.getProperty("tenant.id", "");
} if (StringUtils.isBlank(userTenant)) {
userTenant = System.getProperty("acm.namespace", "");
}
}
public static void setUserTenant(String userTenant) { public static String getUserTenant() {
TenantUtil.userTenant = userTenant; return userTenant;
} }
public static void setUserTenant(String userTenant) {
TenantUtil.userTenant = userTenant;
}
} }

View File

@ -17,16 +17,15 @@ package com.alibaba.nacos.client.identify;
/** /**
* Identify Constants * Identify Constants
*
* @author Nacos
* *
* @author Nacos
*/ */
public class Constants { public class Constants {
public static final String ACCESS_KEY = "accessKey"; public static final String ACCESS_KEY = "accessKey";
public static final String SECRET_KEY = "secretKey"; public static final String SECRET_KEY = "secretKey";
public static final String PROPERTIES_FILENAME = "spas.properties"; public static final String PROPERTIES_FILENAME = "spas.properties";
public static final String CREDENTIAL_PATH = "/home/admin/.spas_key/"; public static final String CREDENTIAL_PATH = "/home/admin/.spas_key/";

View File

@ -17,13 +17,12 @@ package com.alibaba.nacos.client.identify;
/** /**
* Credential Listener * Credential Listener
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface CredentialListener { public interface CredentialListener {
/** /**
* update Credential * update Credential
*/ */
public void onUpdateCredential(); public void onUpdateCredential();
} }

View File

@ -23,34 +23,33 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* Credential Service * Credential Service
*
* @author Nacos
* *
* @author Nacos
*/ */
public final class CredentialService implements SpasCredentialLoader { public final class CredentialService implements SpasCredentialLoader {
static final public Logger log = LogUtils.logger(CredentialService.class); static final public Logger log = LogUtils.logger(CredentialService.class);
private static ConcurrentHashMap<String, CredentialService> instances = new ConcurrentHashMap<String, CredentialService>(); private static ConcurrentHashMap<String, CredentialService> instances
= new ConcurrentHashMap<String, CredentialService>();
private String appName; private String appName;
private Credentials credentials = new Credentials(); private Credentials credentials = new Credentials();
private CredentialWatcher watcher; private CredentialWatcher watcher;
private CredentialListener listener; private CredentialListener listener;
private CredentialService(String appName) { private CredentialService(String appName) {
if (appName == null) { if (appName == null) {
String value = System.getProperty("project.name"); String value = System.getProperty("project.name");
if (StringUtils.isNotEmpty(value)) { if (StringUtils.isNotEmpty(value)) {
appName = value; appName = value;
} }
} }
this.appName = appName; this.appName = appName;
watcher = new CredentialWatcher(appName, this); watcher = new CredentialWatcher(appName, this);
} }
public static CredentialService getInstance() {
public static CredentialService getInstance() {
return getInstance(null); return getInstance(null);
} }
public static CredentialService getInstance(String appName) { public static CredentialService getInstance(String appName) {
String key = appName != null ? appName : Constants.NO_APP_NAME; String key = appName != null ? appName : Constants.NO_APP_NAME;
@ -85,13 +84,13 @@ public final class CredentialService implements SpasCredentialLoader {
log.info(appName, this.getClass().getSimpleName() + " is freed"); log.info(appName, this.getClass().getSimpleName() + " is freed");
} }
public Credentials getCredential() { public Credentials getCredential() {
Credentials localCredential = credentials; Credentials localCredential = credentials;
if (localCredential.valid()) { if (localCredential.valid()) {
return localCredential; return localCredential;
} }
return credentials; return credentials;
} }
public void setCredential(Credentials credential) { public void setCredential(Credentials credential) {
boolean changed = !(credentials == credential || (credentials != null && credentials.identical(credential))); boolean changed = !(credentials == credential || (credentials != null && credentials.identical(credential)));
@ -113,23 +112,23 @@ public final class CredentialService implements SpasCredentialLoader {
} }
@Deprecated @Deprecated
public void setAccessKey(String accessKey) { public void setAccessKey(String accessKey) {
credentials.setAccessKey(accessKey); credentials.setAccessKey(accessKey);
} }
@Deprecated @Deprecated
public void setSecretKey(String secretKey) { public void setSecretKey(String secretKey) {
credentials.setSecretKey(secretKey); credentials.setSecretKey(secretKey);
} }
@Deprecated @Deprecated
public String getAccessKey() { public String getAccessKey() {
return credentials.getAccessKey(); return credentials.getAccessKey();
} }
@Deprecated @Deprecated
public String getSecretKey() { public String getSecretKey() {
return credentials.getSecretKey(); return credentials.getSecretKey();
} }
} }

View File

@ -31,12 +31,11 @@ import com.alibaba.nacos.client.utils.StringUtils;
/** /**
* Credential Watcher * Credential Watcher
*
* @author Nacos
* *
* @author Nacos
*/ */
public class CredentialWatcher { public class CredentialWatcher {
static final public Logger SpasLogger = LogUtils.logger(CredentialWatcher.class); static final public Logger SpasLogger = LogUtils.logger(CredentialWatcher.class);
private static final long REFRESH_INTERVAL = 10 * 1000; private static final long REFRESH_INTERVAL = 10 * 1000;
private CredentialService serviceInstance; private CredentialService serviceInstance;
@ -104,21 +103,20 @@ public class CredentialWatcher {
propertyPath = url.getPath(); propertyPath = url.getPath();
} }
if (propertyPath == null || propertyPath.isEmpty()) { if (propertyPath == null || propertyPath.isEmpty()) {
String value = System.getProperty("spas.identity"); String value = System.getProperty("spas.identity");
if (StringUtils.isNotEmpty(value)) { if (StringUtils.isNotEmpty(value)) {
propertyPath = value; propertyPath = value;
}
if (propertyPath == null || propertyPath.isEmpty()) {
propertyPath = Constants.CREDENTIAL_PATH + (appName == null ? Constants.CREDENTIAL_DEFAULT : appName);
} }
else { if (propertyPath == null || propertyPath.isEmpty()) {
propertyPath = Constants.CREDENTIAL_PATH + (appName == null ? Constants.CREDENTIAL_DEFAULT
: appName);
} else {
if (logWarn) { if (logWarn) {
SpasLogger.info(appName, "Defined credential file: -D" + "spas.identity" + "=" + propertyPath); SpasLogger.info(appName, "Defined credential file: -D" + "spas.identity" + "=" + propertyPath);
} }
} }
} } else {
else {
if (logWarn) { if (logWarn) {
SpasLogger.info(appName, "Load credential file from classpath: " + Constants.PROPERTIES_FILENAME); SpasLogger.info(appName, "Load credential file from classpath: " + Constants.PROPERTIES_FILENAME);
} }
@ -130,7 +128,8 @@ public class CredentialWatcher {
try { try {
propertiesIS = new FileInputStream(propertyPath); propertiesIS = new FileInputStream(propertyPath);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
if (appName != null && !appName.equals(Constants.CREDENTIAL_DEFAULT) && propertyPath.equals(Constants.CREDENTIAL_PATH + appName)) { if (appName != null && !appName.equals(Constants.CREDENTIAL_DEFAULT) && propertyPath.equals(
Constants.CREDENTIAL_PATH + appName)) {
propertyPath = Constants.CREDENTIAL_PATH + Constants.CREDENTIAL_DEFAULT; propertyPath = Constants.CREDENTIAL_PATH + Constants.CREDENTIAL_DEFAULT;
continue; continue;
} }
@ -154,22 +153,21 @@ public class CredentialWatcher {
} }
return; return;
} }
} } else {
else {
Properties properties = new Properties(); Properties properties = new Properties();
try { try {
properties.load(propertiesIS); properties.load(propertiesIS);
} catch (IOException e) { } catch (IOException e) {
SpasLogger.error("26", "Unable to load credential file, appName:" + appName SpasLogger.error("26", "Unable to load credential file, appName:" + appName
+ "Unable to load credential file " + propertyPath, e); + "Unable to load credential file " + propertyPath, e);
propertyPath = null; propertyPath = null;
return; return;
} finally { } finally {
try { try {
propertiesIS.close(); propertiesIS.close();
} catch (IOException e) { } catch (IOException e) {
SpasLogger.error("27", "Unable to close credential file, appName:" + appName SpasLogger.error("27", "Unable to close credential file, appName:" + appName
+ "Unable to close credential file " + propertyPath, e); + "Unable to close credential file " + propertyPath, e);
} }
} }
@ -202,12 +200,12 @@ public class CredentialWatcher {
} }
Credentials credential = new Credentials(accessKey, secretKey); Credentials credential = new Credentials(accessKey, secretKey);
if (!credential.valid()) { if (!credential.valid()) {
SpasLogger.warn("1", "Credential file missing required property" + appName + "Credential file missing " SpasLogger.warn("1", "Credential file missing required property" + appName + "Credential file missing "
+ Constants.ACCESS_KEY + " or " + Constants.SECRET_KEY); + Constants.ACCESS_KEY + " or " + Constants.SECRET_KEY);
propertyPath = null; propertyPath = null;
// return; // return;
} }
serviceInstance.setCredential(credential); serviceInstance.setCredential(credential);
} }

View File

@ -17,40 +17,39 @@ package com.alibaba.nacos.client.identify;
/** /**
* Credentials * Credentials
*
* @author Nacos
* *
* @author Nacos
*/ */
public class Credentials implements SpasCredential { public class Credentials implements SpasCredential {
private volatile String accessKey;
private volatile String secretKey;
public Credentials(String accessKey, String secretKey) {
this.accessKey = accessKey;
this.secretKey = secretKey;
}
public Credentials() {
this(null, null);
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) { private volatile String accessKey;
this.accessKey = accessKey;
}
public String getSecretKey() { private volatile String secretKey;
return secretKey;
}
public void setSecretKey(String secretKey) { public Credentials(String accessKey, String secretKey) {
this.secretKey = secretKey; this.accessKey = accessKey;
} this.secretKey = secretKey;
}
public Credentials() {
this(null, null);
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public boolean valid() { public boolean valid() {
return accessKey != null && !accessKey.isEmpty() && secretKey != null && !secretKey.isEmpty(); return accessKey != null && !accessKey.isEmpty() && secretKey != null && !secretKey.isEmpty();
@ -58,8 +57,10 @@ public class Credentials implements SpasCredential {
public boolean identical(Credentials other) { public boolean identical(Credentials other) {
return this == other || return this == other ||
(other != null && (other != null &&
(accessKey == null && other.accessKey == null || accessKey != null && accessKey.equals(other.accessKey)) && (accessKey == null && other.accessKey == null || accessKey != null && accessKey.equals(other.accessKey))
(secretKey == null && other.secretKey == null || secretKey != null && secretKey.equals(other.secretKey))); &&
(secretKey == null && other.secretKey == null || secretKey != null && secretKey.equals(
other.secretKey)));
} }
} }

View File

@ -19,110 +19,110 @@ import com.alibaba.nacos.client.utils.StringUtils;
/** /**
* Sts config * Sts config
* *
* @author Nacos * @author Nacos
*/ */
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class STSConfig { public class STSConfig {
private static final String RAM_SECURITY_CREDENTIALS_URL private static final String RAM_SECURITY_CREDENTIALS_URL
= ""; = "";
private String ramRoleName; private String ramRoleName;
/** /**
* STS 临时凭证有效期剩余多少时开始刷新允许本地时间比 STS 服务时间最多慢多久 * STS 临时凭证有效期剩余多少时开始刷新允许本地时间比 STS 服务时间最多慢多久
*/ */
private int timeToRefreshInMillisecond = 3 * 60 * 1000; private int timeToRefreshInMillisecond = 3 * 60 * 1000;
/** /**
* 获取 STS 临时凭证的元数据接口包含角色名称 * 获取 STS 临时凭证的元数据接口包含角色名称
*/ */
private String securityCredentialsUrl; private String securityCredentialsUrl;
/** /**
* 设定 STS 临时凭证不再通过元数据接口获取 * 设定 STS 临时凭证不再通过元数据接口获取
*/ */
private String securityCredentials; private String securityCredentials;
/** /**
* 是否缓存 * 是否缓存
*/ */
private boolean cacheSecurityCredentials = true; private boolean cacheSecurityCredentials = true;
private static class Singleton { private static class Singleton {
private static final STSConfig INSTANCE = new STSConfig(); private static final STSConfig INSTANCE = new STSConfig();
} }
private STSConfig() { private STSConfig() {
String ramRoleName = System.getProperty("ram.role.name"); String ramRoleName = System.getProperty("ram.role.name");
if (!StringUtils.isBlank(ramRoleName)) { if (!StringUtils.isBlank(ramRoleName)) {
setRamRoleName(ramRoleName); setRamRoleName(ramRoleName);
} }
String timeToRefreshInMillisecond = System.getProperty("time.to.refresh.in.millisecond"); String timeToRefreshInMillisecond = System.getProperty("time.to.refresh.in.millisecond");
if (!StringUtils.isBlank(timeToRefreshInMillisecond)) { if (!StringUtils.isBlank(timeToRefreshInMillisecond)) {
setTimeToRefreshInMillisecond(Integer.parseInt(timeToRefreshInMillisecond)); setTimeToRefreshInMillisecond(Integer.parseInt(timeToRefreshInMillisecond));
} }
String securityCredentials = System.getProperty("security.credentials"); String securityCredentials = System.getProperty("security.credentials");
if (!StringUtils.isBlank(securityCredentials)) { if (!StringUtils.isBlank(securityCredentials)) {
setSecurityCredentials(securityCredentials); setSecurityCredentials(securityCredentials);
} }
String securityCredentialsUrl = System.getProperty("security.credentials.url"); String securityCredentialsUrl = System.getProperty("security.credentials.url");
if (!StringUtils.isBlank(securityCredentialsUrl)) { if (!StringUtils.isBlank(securityCredentialsUrl)) {
setSecurityCredentialsUrl(securityCredentialsUrl); setSecurityCredentialsUrl(securityCredentialsUrl);
} }
String cacheSecurityCredentials = System.getProperty("cache.security.credentials"); String cacheSecurityCredentials = System.getProperty("cache.security.credentials");
if (!StringUtils.isBlank(cacheSecurityCredentials)) { if (!StringUtils.isBlank(cacheSecurityCredentials)) {
setCacheSecurityCredentials(Boolean.valueOf(cacheSecurityCredentials)); setCacheSecurityCredentials(Boolean.valueOf(cacheSecurityCredentials));
} }
} }
public static STSConfig getInstance() { public static STSConfig getInstance() {
return Singleton.INSTANCE; return Singleton.INSTANCE;
} }
public String getRamRoleName() { public String getRamRoleName() {
return ramRoleName; return ramRoleName;
} }
public void setRamRoleName(String ramRoleName) { public void setRamRoleName(String ramRoleName) {
this.ramRoleName = ramRoleName; this.ramRoleName = ramRoleName;
} }
public int getTimeToRefreshInMillisecond() { public int getTimeToRefreshInMillisecond() {
return timeToRefreshInMillisecond; return timeToRefreshInMillisecond;
} }
public void setTimeToRefreshInMillisecond(int timeToRefreshInMillisecond) { public void setTimeToRefreshInMillisecond(int timeToRefreshInMillisecond) {
this.timeToRefreshInMillisecond = timeToRefreshInMillisecond; this.timeToRefreshInMillisecond = timeToRefreshInMillisecond;
} }
public String getSecurityCredentialsUrl() { public String getSecurityCredentialsUrl() {
if (securityCredentialsUrl == null && ramRoleName != null) { if (securityCredentialsUrl == null && ramRoleName != null) {
return RAM_SECURITY_CREDENTIALS_URL + ramRoleName; return RAM_SECURITY_CREDENTIALS_URL + ramRoleName;
} }
return securityCredentialsUrl; return securityCredentialsUrl;
} }
public void setSecurityCredentialsUrl(String securityCredentialsUrl) { public void setSecurityCredentialsUrl(String securityCredentialsUrl) {
this.securityCredentialsUrl = securityCredentialsUrl; this.securityCredentialsUrl = securityCredentialsUrl;
} }
public String getSecurityCredentials() { public String getSecurityCredentials() {
return securityCredentials; return securityCredentials;
} }
public void setSecurityCredentials(String securityCredentials) { public void setSecurityCredentials(String securityCredentials) {
this.securityCredentials = securityCredentials; this.securityCredentials = securityCredentials;
} }
public boolean isSTSOn() { public boolean isSTSOn() {
return StringUtils.isNotEmpty(getSecurityCredentials()) || StringUtils.isNotEmpty(getSecurityCredentialsUrl()); return StringUtils.isNotEmpty(getSecurityCredentials()) || StringUtils.isNotEmpty(getSecurityCredentialsUrl());
} }
public boolean isCacheSecurityCredentials() { public boolean isCacheSecurityCredentials() {
return cacheSecurityCredentials; return cacheSecurityCredentials;
} }
public void setCacheSecurityCredentials(boolean cacheSecurityCredentials) { public void setCacheSecurityCredentials(boolean cacheSecurityCredentials) {
this.cacheSecurityCredentials = cacheSecurityCredentials; this.cacheSecurityCredentials = cacheSecurityCredentials;
} }
} }

View File

@ -17,22 +17,21 @@ package com.alibaba.nacos.client.identify;
/** /**
* Spas Credential Interface * Spas Credential Interface
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface SpasCredential { public interface SpasCredential {
/** /**
* get AccessKey * get AccessKey
* *
* @return AccessKey * @return AccessKey
*/ */
public String getAccessKey(); public String getAccessKey();
/** /**
* get SecretKey * get SecretKey
* *
* @return SecretKey * @return SecretKey
*/ */
public String getSecretKey(); public String getSecretKey();
} }

View File

@ -17,15 +17,14 @@ package com.alibaba.nacos.client.identify;
/** /**
* Spas Credential Loader * Spas Credential Loader
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface SpasCredentialLoader { public interface SpasCredentialLoader {
/** /**
* get Credential * get Credential
* *
* @return Credential * @return Credential
*/ */
SpasCredential getCredential(); SpasCredential getCredential();
} }

View File

@ -17,14 +17,18 @@ package com.alibaba.nacos.client.logger;
/** /**
* 阿里中间件日志级别 * 阿里中间件日志级别
* *
* @author zhuyong 2014年3月20日 上午9:57:27 * @author zhuyong 2014年3月20日 上午9:57:27
*/ */
public enum Level { public enum Level {
/** /**
* log level * log level
*/ */
DEBUG("DEBUG"), INFO("INFO"), WARN("WARN"), ERROR("ERROR"), OFF("OFF"); DEBUG("DEBUG"),
INFO("INFO"),
WARN("WARN"),
ERROR("ERROR"),
OFF("OFF");
private String name; private String name;

View File

@ -20,7 +20,7 @@ import com.alibaba.nacos.client.logger.option.ActivateOption;
/** /**
* <pre> * <pre>
* 阿里中间件日志API用于输出定制化的日志 * 阿里中间件日志API用于输出定制化的日志
* *
* 定制格式如下01 %d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n * 定制格式如下01 %d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n
* 其中 * 其中
* 01 日志API版本后续如果格式有变化会修改此版本号方便机器解析 * 01 日志API版本后续如果格式有变化会修改此版本号方便机器解析
@ -29,17 +29,17 @@ import com.alibaba.nacos.client.logger.option.ActivateOption;
* [%-5t:%c{2}] 线程名:日志名 * [%-5t:%c{2}] 线程名:日志名
* %m 日志信息 * %m 日志信息
* %n 换行 * %n 换行
* *
* 关于%m也有其中的格式要求[Context] [STAT-INFO] [ERROR-CODE] * 关于%m也有其中的格式要求[Context] [STAT-INFO] [ERROR-CODE]
* 其中 * 其中
* Context 打印时间时的上下文信息如果没有则内容为空'[]'这个占位符仍要输出 * Context 打印时间时的上下文信息如果没有则内容为空'[]'这个占位符仍要输出
* STAT-INFO 待定 * STAT-INFO 待定
* ERROR-CODE 常见的错误码帮助用户解决问题 * ERROR-CODE 常见的错误码帮助用户解决问题
* *
* 在异常中也需要输出ErrorCode及对应的TraceUrl可以使用 * 在异常中也需要输出ErrorCode及对应的TraceUrl可以使用
* com.alibaba.nacos.client.logger.support.LoggerHelper.getErrorCodeStr(String errorCode)来获取格式化后的串 * com.alibaba.nacos.client.logger.support.LoggerHelper.getErrorCodeStr(String errorCode)来获取格式化后的串
* </pre> * </pre>
* *
* @author zhuyong 2014年3月20日 上午9:58:27 * @author zhuyong 2014年3月20日 上午9:58:27
*/ */
public interface Logger extends ActivateOption { public interface Logger extends ActivateOption {
@ -55,7 +55,7 @@ public interface Logger extends ActivateOption {
* 输出Debug日志 * 输出Debug日志
* *
* @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param args 格式化串参数数组 * @param args 格式化串参数数组
*/ */
void debug(String format, Object... args); void debug(String format, Object... args);
@ -71,8 +71,8 @@ public interface Logger extends ActivateOption {
* 输出Debug日志 * 输出Debug日志
* *
* @param context 日志上下文信息 * @param context 日志上下文信息
* @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param args 格式化串参数数组 * @param args 格式化串参数数组
*/ */
void debug(String context, String format, Object... args); void debug(String context, String format, Object... args);
@ -87,7 +87,7 @@ public interface Logger extends ActivateOption {
* 输出Info日志 * 输出Info日志
* *
* @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param args 格式化串参数数组 * @param args 格式化串参数数组
*/ */
void info(String format, Object... args); void info(String format, Object... args);
@ -103,8 +103,8 @@ public interface Logger extends ActivateOption {
* 输出Info日志 * 输出Info日志
* *
* @param context 日志上下文信息 * @param context 日志上下文信息
* @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param args 格式化串参数数组 * @param args 格式化串参数数组
*/ */
void info(String context, String format, Object... args); void info(String context, String format, Object... args);
@ -119,7 +119,7 @@ public interface Logger extends ActivateOption {
* 输出Warn日志 * 输出Warn日志
* *
* @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param t 异常信息 * @param t 异常信息
* @since 0.1.5 * @since 0.1.5
*/ */
void warn(String message, Throwable t); void warn(String message, Throwable t);
@ -128,7 +128,7 @@ public interface Logger extends ActivateOption {
* 输出Warn日志 * 输出Warn日志
* *
* @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param args 格式化串参数数组 * @param args 格式化串参数数组
*/ */
void warn(String format, Object... args); void warn(String format, Object... args);
@ -144,8 +144,8 @@ public interface Logger extends ActivateOption {
* 输出Warn日志 * 输出Warn日志
* *
* @param context 日志上下文信息 * @param context 日志上下文信息
* @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param args 格式化串参数数组 * @param args 格式化串参数数组
*/ */
void warn(String context, String format, Object... args); void warn(String context, String format, Object... args);
@ -153,7 +153,7 @@ public interface Logger extends ActivateOption {
* 输出Error日志 * 输出Error日志
* *
* @param errorCode 错误码如HSF-0001 * @param errorCode 错误码如HSF-0001
* @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
*/ */
void error(String errorCode, String message); void error(String errorCode, String message);
@ -161,8 +161,8 @@ public interface Logger extends ActivateOption {
* 输出Error日志 * 输出Error日志
* *
* @param errorCode 错误码如HSF-0001 * @param errorCode 错误码如HSF-0001
* @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param t 异常信息 * @param t 异常信息
*/ */
void error(String errorCode, String message, Throwable t); void error(String errorCode, String message, Throwable t);
@ -170,68 +170,71 @@ public interface Logger extends ActivateOption {
* 输出Error日志 * 输出Error日志
* *
* @param errorCode 错误码如HSF-0001 * @param errorCode 错误码如HSF-0001
* @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param objs 格式化串参数数组 * @param objs 格式化串参数数组
*/ */
void error(String errorCode, String format, Object... objs); void error(String errorCode, String format, Object... objs);
/** /**
* 输出Error日志 * 输出Error日志
* *
* @param context 日志上下文信息 * @param context 日志上下文信息
* @param errorCode 错误码 * @param errorCode 错误码
* @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
*/ */
void error(String context, String errorCode, String message); void error(String context, String errorCode, String message);
/** /**
* 输出Error日志 * 输出Error日志
* *
* @param context 日志上下文信息 * @param context 日志上下文信息
* @param errorCode 错误码 * @param errorCode 错误码
* @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param message 日志信息当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param t 异常信息 * @param t 异常信息
*/ */
void error(String context, String errorCode, String message, Throwable t); void error(String context, String errorCode, String message, Throwable t);
/** /**
* 输出Error日志 * 输出Error日志
* *
* @param context 日志上下文信息 * @param context 日志上下文信息
* @param errorCode 错误码 * @param errorCode 错误码
* @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5 * @param format 日志信息格式化字符串比如 'Hi,{} {} {}'当使用ResourceBundle用于国际化日志输出时message为对应的key, since 0.1.5
* @param args 格式化串参数 * @param args 格式化串参数
*/ */
void error(String context, String errorCode, String format, Object... args); void error(String context, String errorCode, String format, Object... args);
/** /**
* 判断Debug级别是否开启 * 判断Debug级别是否开启
* *
* @return Debug级别是否开启 * @return Debug级别是否开启
*/ */
boolean isDebugEnabled(); boolean isDebugEnabled();
/** /**
* 判断Info级别是否开启 * 判断Info级别是否开启
*
* @return Info级别是否开启 * @return Info级别是否开启
*/ */
boolean isInfoEnabled(); boolean isInfoEnabled();
/** /**
* 判断Warn级别是否开启 * 判断Warn级别是否开启
*
* @return Warn级别是否开启 * @return Warn级别是否开启
*/ */
boolean isWarnEnabled(); boolean isWarnEnabled();
/** /**
* 判断Error级别是否开启 * 判断Error级别是否开启
* *
* @return Error级别是否开启 * @return Error级别是否开启
*/ */
boolean isErrorEnabled(); boolean isErrorEnabled();
/** /**
* * 获取内部日志实现对象 * * 获取内部日志实现对象
*
* @return 内部日志实现对象 * @return 内部日志实现对象
*/ */
Object getDelegate(); Object getDelegate();

View File

@ -61,7 +61,7 @@ public class LoggerFactory {
} catch (Throwable e2) { } catch (Throwable e2) {
setLoggerFactory(new NopLoggerFactory()); setLoggerFactory(new NopLoggerFactory());
LogLog.warn("Init JM logger with NopLoggerFactory, pay attention. " LogLog.warn("Init JM logger with NopLoggerFactory, pay attention. "
+ LoggerFactory.class.getClassLoader(), e2); + LoggerFactory.class.getClassLoader(), e2);
} }
} }

View File

@ -28,371 +28,367 @@ import java.util.Iterator;
/** /**
* A JSON array. JSONObject supports java.util.List interface. * A JSON array. JSONObject supports java.util.List interface.
* *
* @author FangYidong<fangyidong@yahoo.com.cn> * @author FangYidong<fangyidong @ yahoo.com.cn>
*/ */
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class JSONArray extends ArrayList implements JSONAware, JSONStreamAware { public class JSONArray extends ArrayList implements JSONAware, JSONStreamAware {
private static final long serialVersionUID = 3957988303675231981L; private static final long serialVersionUID = 3957988303675231981L;
/**
* Constructs an empty JSONArray.
*/
public JSONArray(){
super();
}
/**
* Constructs a JSONArray containing the elements of the specified
* collection, in the order they are returned by the collection's iterator.
*
* @param c the collection whose elements are to be placed into this JSONArray
*/
public JSONArray(Collection c){
super(c);
}
/** /**
* Encode a list into JSON text and write it to out. * Constructs an empty JSONArray.
* If this list is also a JSONStreamAware or a JSONAware, JSONStreamAware and JSONAware specific behaviours will be ignored at this top level. */
* public JSONArray() {
* @see com.alibaba.nacos.client.logger.json.JSONValue#writeJSONString(Object, Writer) super();
* }
/**
* Constructs a JSONArray containing the elements of the specified collection, in the order they are returned by the
* collection's iterator.
*
* @param c the collection whose elements are to be placed into this JSONArray
*/
public JSONArray(Collection c) {
super(c);
}
/**
* Encode a list into JSON text and write it to out. If this list is also a JSONStreamAware or a JSONAware,
* JSONStreamAware and JSONAware specific behaviours will be ignored at this top level.
*
* @param collection * @param collection
* @param out * @param out
* @see com.alibaba.nacos.client.logger.json.JSONValue#writeJSONString(Object, Writer)
*/ */
public static void writeJSONString(Collection collection, Writer out) throws IOException{ public static void writeJSONString(Collection collection, Writer out) throws IOException {
if(collection == null){ if (collection == null) {
out.write("null"); out.write("null");
return; return;
} }
boolean first = true; boolean first = true;
Iterator iter=collection.iterator(); Iterator iter = collection.iterator();
out.write('['); out.write('[');
while(iter.hasNext()){ while (iter.hasNext()) {
if(first) { if (first) {
first = false; first = false;
} } else {
else {
out.write(','); out.write(',');
} }
Object value=iter.next(); Object value = iter.next();
if(value == null){ if (value == null) {
out.write("null"); out.write("null");
continue; continue;
} }
JSONValue.writeJSONString(value, out);
}
out.write(']');
}
public void writeJSONString(Writer out) throws IOException{
writeJSONString(this, out);
}
/**
* Convert a list to JSON text. The result is a JSON array.
* If this list is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
*
* @see com.alibaba.nacos.client.logger.json.JSONValue#toJSONString(Object)
*
* @param collection
* @return JSON text, or "null" if list is null.
*/
public static String toJSONString(Collection collection){
final StringWriter writer = new StringWriter();
try {
writeJSONString(collection, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(byte[] array, Writer out) throws IOException{ JSONValue.writeJSONString(value, out);
if(array == null){ }
out.write("null"); out.write(']');
} else if(array.length == 0) { }
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for(int i = 1; i < array.length; i++){
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(byte[] array){
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(short[] array, Writer out) throws IOException{
if(array == null){
out.write("null");
} else if(array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for(int i = 1; i < array.length; i++){
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(short[] array){
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(int[] array, Writer out) throws IOException{
if(array == null){
out.write("null");
} else if(array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for(int i = 1; i < array.length; i++){
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(int[] array){
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(long[] array, Writer out) throws IOException{
if(array == null){
out.write("null");
} else if(array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for(int i = 1; i < array.length; i++){
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(long[] array){
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(float[] array, Writer out) throws IOException{
if(array == null){
out.write("null");
} else if(array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for(int i = 1; i < array.length; i++){
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(float[] array){
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(double[] array, Writer out) throws IOException{
if(array == null){
out.write("null");
} else if(array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for(int i = 1; i < array.length; i++){
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(double[] array){
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(boolean[] array, Writer out) throws IOException{
if(array == null){
out.write("null");
} else if(array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for(int i = 1; i < array.length; i++){
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(boolean[] array){
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(char[] array, Writer out) throws IOException{
if(array == null){
out.write("null");
} else if(array.length == 0) {
out.write("[]");
} else {
out.write("[\"");
out.write(String.valueOf(array[0]));
for(int i = 1; i < array.length; i++){
out.write("\",\"");
out.write(String.valueOf(array[i]));
}
out.write("\"]");
}
}
public static String toJSONString(char[] array){
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(Object[] array, Writer out) throws IOException{
if(array == null){
out.write("null");
} else if(array.length == 0) {
out.write("[]");
} else {
out.write("[");
JSONValue.writeJSONString(array[0], out);
for(int i = 1; i < array.length; i++){
out.write(",");
JSONValue.writeJSONString(array[i], out);
}
out.write("]");
}
}
public static String toJSONString(Object[] array){
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public String toJSONString(){
return toJSONString(this);
}
/** public void writeJSONString(Writer out) throws IOException {
* Returns a string representation of this array. This is equivalent to writeJSONString(this, out);
* calling {@link JSONArray#toJSONString()}. }
*/
public String toString() { /**
return toJSONString(); * Convert a list to JSON text. The result is a JSON array. If this list is also a JSONAware, JSONAware specific
} * behaviours will be omitted at this top level.
*
* @param collection
* @return JSON text, or "null" if list is null.
* @see com.alibaba.nacos.client.logger.json.JSONValue#toJSONString(Object)
*/
public static String toJSONString(Collection collection) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(collection, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(byte[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(byte[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(short[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(short[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(int[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(int[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(long[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(long[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(float[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(float[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(double[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(double[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(boolean[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write(",");
out.write(String.valueOf(array[i]));
}
out.write("]");
}
}
public static String toJSONString(boolean[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(char[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[\"");
out.write(String.valueOf(array[0]));
for (int i = 1; i < array.length; i++) {
out.write("\",\"");
out.write(String.valueOf(array[i]));
}
out.write("\"]");
}
}
public static String toJSONString(char[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public static void writeJSONString(Object[] array, Writer out) throws IOException {
if (array == null) {
out.write("null");
} else if (array.length == 0) {
out.write("[]");
} else {
out.write("[");
JSONValue.writeJSONString(array[0], out);
for (int i = 1; i < array.length; i++) {
out.write(",");
JSONValue.writeJSONString(array[i], out);
}
out.write("]");
}
}
public static String toJSONString(Object[] array) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(array, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
public String toJSONString() {
return toJSONString(this);
}
/**
* Returns a string representation of this array. This is equivalent to calling {@link JSONArray#toJSONString()}.
*/
public String toString() {
return toJSONString();
}
} }

View File

@ -16,15 +16,16 @@
package com.alibaba.nacos.client.logger.json; package com.alibaba.nacos.client.logger.json;
/** /**
* Beans that support customized output of JSON text shall implement this interface. * Beans that support customized output of JSON text shall implement this interface.
* @author FangYidong<fangyidong@yahoo.com.cn> *
* @author FangYidong<fangyidong @ yahoo.com.cn>
*/ */
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public interface JSONAware { public interface JSONAware {
/** /**
* format change * format change
* *
* @return JSON text * @return JSON text
*/ */
String toJSONString(); String toJSONString();
} }

View File

@ -28,125 +28,118 @@ import java.util.Map;
/** /**
* A JSON object. Key value pairs are unordered. JSONObject supports java.util.Map interface. * A JSON object. Key value pairs are unordered. JSONObject supports java.util.Map interface.
* *
* @author FangYidong<fangyidong@yahoo.com.cn> * @author FangYidong<fangyidong @ yahoo.com.cn>
*/ */
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware{ public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware {
private static final long serialVersionUID = -503443796854799292L;
public JSONObject() {
super();
}
/** private static final long serialVersionUID = -503443796854799292L;
* Allows creation of a JSONObject from a Map. After that, both the
* generated JSONObject and the Map can be modified independently.
*
* @param map
*/
public JSONObject(Map map) {
super(map);
}
public JSONObject() {
super();
}
/** /**
* Encode a map into JSON text and write it to out. * Allows creation of a JSONObject from a Map. After that, both the generated JSONObject and the Map can be modified
* If this map is also a JSONAware or JSONStreamAware, JSONAware or JSONStreamAware specific behaviours will be ignored at this top level. * independently.
* *
* @see com.alibaba.nacos.client.logger.json.JSONValue#writeJSONString(Object, Writer) * @param map
* */
public JSONObject(Map map) {
super(map);
}
/**
* Encode a map into JSON text and write it to out. If this map is also a JSONAware or JSONStreamAware, JSONAware or
* JSONStreamAware specific behaviours will be ignored at this top level.
*
* @param map * @param map
* @param out * @param out
* @see com.alibaba.nacos.client.logger.json.JSONValue#writeJSONString(Object, Writer)
*/ */
public static void writeJSONString(Map map, Writer out) throws IOException { public static void writeJSONString(Map map, Writer out) throws IOException {
if(map == null){ if (map == null) {
out.write("null"); out.write("null");
return; return;
} }
boolean first = true; boolean first = true;
Iterator iter=map.entrySet().iterator(); Iterator iter = map.entrySet().iterator();
out.write('{'); out.write('{');
while(iter.hasNext()){ while (iter.hasNext()) {
if (first) { if (first) {
first = false; first = false;
} } else {
else { out.write(',');
out.write(','); }
} Map.Entry entry = (Map.Entry)iter.next();
Map.Entry entry = (Map.Entry) iter.next();
out.write('\"'); out.write('\"');
out.write(escape(String.valueOf(entry.getKey()))); out.write(escape(String.valueOf(entry.getKey())));
out.write('\"'); out.write('\"');
out.write(':'); out.write(':');
JSONValue.writeJSONString(entry.getValue(), out); JSONValue.writeJSONString(entry.getValue(), out);
} }
out.write('}'); out.write('}');
} }
public void writeJSONString(Writer out) throws IOException{ public void writeJSONString(Writer out) throws IOException {
writeJSONString(this, out); writeJSONString(this, out);
} }
/**
* Convert a map to JSON text. The result is a JSON object.
* If this map is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
*
* @see com.alibaba.nacos.client.logger.json.JSONValue#toJSONString(Object)
*
* @param map
* @return JSON text, or "null" if map is null.
*/
public static String toJSONString(Map map){
final StringWriter writer = new StringWriter();
try {
writeJSONString(map, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen with a StringWriter
throw new RuntimeException(e);
}
}
public String toJSONString(){
return toJSONString(this);
}
public String toString(){
return toJSONString();
}
public static String toString(String key,Object value){ /**
* Convert a map to JSON text. The result is a JSON object. If this map is also a JSONAware, JSONAware specific
* behaviours will be omitted at this top level.
*
* @param map
* @return JSON text, or "null" if map is null.
* @see com.alibaba.nacos.client.logger.json.JSONValue#toJSONString(Object)
*/
public static String toJSONString(Map map) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(map, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen with a StringWriter
throw new RuntimeException(e);
}
}
public String toJSONString() {
return toJSONString(this);
}
public String toString() {
return toJSONString();
}
public static String toString(String key, Object value) {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
sb.append('\"'); sb.append('\"');
if(key == null) { if (key == null) {
sb.append("null"); sb.append("null");
} } else {
else {
JSONValue.escape(key, sb); JSONValue.escape(key, sb);
} }
sb.append('\"').append(':'); sb.append('\"').append(':');
sb.append(JSONValue.toJSONString(value)); sb.append(JSONValue.toJSONString(value));
return sb.toString(); return sb.toString();
} }
/** /**
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F). * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F). It's the same as
* It's the same as JSONValue.escape() only for compatibility here. * JSONValue.escape() only for compatibility here.
* *
* @see com.alibaba.nacos.client.logger.json.JSONValue#escape(String) * @param s
* * @return
* @param s * @see com.alibaba.nacos.client.logger.json.JSONValue#escape(String)
* @return */
*/ public static String escape(String s) {
public static String escape(String s){ return JSONValue.escape(s);
return JSONValue.escape(s); }
}
} }

View File

@ -19,20 +19,17 @@ import java.io.IOException;
import java.io.Writer; import java.io.Writer;
/** /**
* Beans that support customized output of JSON text to a writer shall implement * Beans that support customized output of JSON text to a writer shall implement this interface.
* this interface. *
* * @author FangYidong<fangyidong @ yahoo.com.cn>
* @author FangYidong<fangyidong@yahoo.com.cn>
*/ */
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public interface JSONStreamAware { public interface JSONStreamAware {
/** /**
* write JSON string to out. * write JSON string to out.
* *
* @param out * @param out out writer
* out writer * @throws IOException Exception
* @throws IOException */
* Exception void writeJSONString(Writer out) throws IOException;
*/
void writeJSONString(Writer out) throws IOException;
} }

View File

@ -30,314 +30,286 @@ import java.util.Map;
import com.alibaba.nacos.client.logger.json.parser.JSONParser; import com.alibaba.nacos.client.logger.json.parser.JSONParser;
import com.alibaba.nacos.client.logger.json.parser.ParseException; import com.alibaba.nacos.client.logger.json.parser.ParseException;
/** /**
* @author FangYidong<fangyidong@yahoo.com.cn> * @author FangYidong<fangyidong @ yahoo.com.cn>
*/ */
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule") @SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class JSONValue { public class JSONValue {
/** /**
* Parse JSON text into java object from the input source. * Parse JSON text into java object from the input source. Please use parseWithException() if you don't want to
* Please use parseWithException() if you don't want to ignore the exception. * ignore the exception.
* *
* @see com.alibaba.nacos.client.logger.jsonparser.JSONParser#parse(Reader) * @param in
* @see #parseWithException(Reader) * @return Instance of the following: com.alibaba.nacos.client.logger.jsonJSONObject,
* * com.alibaba.nacos.client.logger.jsonJSONArray, java.lang.String, java.lang.Number, java.lang.Boolean, null
* @param in * @see com.alibaba.nacos.client.logger.jsonparser.JSONParser#parse(Reader)
* @return Instance of the following: * @see #parseWithException(Reader)
* com.alibaba.nacos.client.logger.jsonJSONObject, * @deprecated this method may throw an {@code Error} instead of returning {@code null}; please use {@link
* com.alibaba.nacos.client.logger.jsonJSONArray, * JSONValue#parseWithException(Reader)} instead
* java.lang.String, */
* java.lang.Number, public static Object parse(Reader in) {
* java.lang.Boolean, try {
* null JSONParser parser = new JSONParser();
* return parser.parse(in);
* @deprecated this method may throw an {@code Error} instead of returning } catch (Exception e) {
* {@code null}; please use {@link JSONValue#parseWithException(Reader)} return null;
* instead }
*/ }
public static Object parse(Reader in){
try{ /**
JSONParser parser=new JSONParser(); * Parse JSON text into java object from the given string. Please use parseWithException() if you don't want to
return parser.parse(in); * ignore the exception.
} *
catch(Exception e){ * @param s
return null; * @return Instance of the following: com.alibaba.nacos.client.logger.jsonJSONObject,
} * com.alibaba.nacos.client.logger.jsonJSONArray, java.lang.String, java.lang.Number, java.lang.Boolean, null
} * @see com.alibaba.nacos.client.logger.jsonparser.JSONParser#parse(Reader)
* @see #parseWithException(Reader)
/** * @deprecated this method may throw an {@code Error} instead of returning {@code null}; please use {@link
* Parse JSON text into java object from the given string. * JSONValue#parseWithException(String)} instead
* Please use parseWithException() if you don't want to ignore the exception. */
* public static Object parse(String s) {
* @see com.alibaba.nacos.client.logger.jsonparser.JSONParser#parse(Reader) StringReader in = new StringReader(s);
* @see #parseWithException(Reader) return parse(in);
* }
* @param s
* @return Instance of the following: /**
* com.alibaba.nacos.client.logger.jsonJSONObject, * Parse JSON text into java object from the input source.
* com.alibaba.nacos.client.logger.jsonJSONArray, *
* java.lang.String, * @param in
* java.lang.Number, * @return Instance of the following: com.alibaba.nacos.client.logger.jsonJSONObject,
* java.lang.Boolean, * com.alibaba.nacos.client.logger.jsonJSONArray, java.lang.String, java.lang.Number, java.lang.Boolean, null
* null * @throws IOException
* * @throws ParseException
* @deprecated this method may throw an {@code Error} instead of returning * @see com.alibaba.nacos.client.logger.jsonparser.JSONParser
* {@code null}; please use {@link JSONValue#parseWithException(String)} */
* instead public static Object parseWithException(Reader in) throws IOException, ParseException {
*/ JSONParser parser = new JSONParser();
public static Object parse(String s){ return parser.parse(in);
StringReader in=new StringReader(s); }
return parse(in);
} public static Object parseWithException(String s) throws ParseException {
JSONParser parser = new JSONParser();
/** return parser.parse(s);
* Parse JSON text into java object from the input source. }
*
* @see com.alibaba.nacos.client.logger.jsonparser.JSONParser
*
* @param in
* @return Instance of the following:
* com.alibaba.nacos.client.logger.jsonJSONObject,
* com.alibaba.nacos.client.logger.jsonJSONArray,
* java.lang.String,
* java.lang.Number,
* java.lang.Boolean,
* null
*
* @throws IOException
* @throws ParseException
*/
public static Object parseWithException(Reader in) throws IOException, ParseException {
JSONParser parser=new JSONParser();
return parser.parse(in);
}
public static Object parseWithException(String s) throws ParseException{
JSONParser parser=new JSONParser();
return parser.parse(s);
}
/** /**
* Encode an object into JSON text and write it to out. * Encode an object into JSON text and write it to out.
* <p> * <p>
* If this object is a Map or a List, and it's also a JSONStreamAware or a JSONAware, JSONStreamAware or JSONAware will be considered firstly. * If this object is a Map or a List, and it's also a JSONStreamAware or a JSONAware, JSONStreamAware or JSONAware
* will be considered firstly.
* <p> * <p>
* DO NOT call this method from writeJSONString(Writer) of a class that implements both JSONStreamAware and (Map or List) with * DO NOT call this method from writeJSONString(Writer) of a class that implements both JSONStreamAware and (Map or
* "this" as the first parameter, use JSONObject.writeJSONString(Map, Writer) or JSONArray.writeJSONString(List, Writer) instead. * List) with "this" as the first parameter, use JSONObject.writeJSONString(Map, Writer) or
* * JSONArray.writeJSONString(List, Writer) instead.
* @see com.alibaba.nacos.client.logger.jsonJSONObject#writeJSONString(Map, Writer) *
* @see com.alibaba.nacos.client.logger.jsonJSONArray#writeJSONString(List, Writer)
*
* @param value * @param value
* @param writer * @param writer
* @see com.alibaba.nacos.client.logger.jsonJSONObject#writeJSONString(Map, Writer)
* @see com.alibaba.nacos.client.logger.jsonJSONArray#writeJSONString(List, Writer)
*/ */
public static void writeJSONString(Object value, Writer out) throws IOException { public static void writeJSONString(Object value, Writer out) throws IOException {
if(value == null){ if (value == null) {
out.write("null"); out.write("null");
return;
}
if(value instanceof String){
out.write('\"');
out.write(escape((String)value));
out.write('\"');
return;
}
if(value instanceof Double){
if(((Double)value).isInfinite() || ((Double)value).isNaN()) {
out.write("null");
}
else {
out.write(value.toString());
}
return;
}
if(value instanceof Float){
if(((Float)value).isInfinite() || ((Float)value).isNaN()) {
out.write("null");
}
else {
out.write(value.toString());
}
return;
}
if(value instanceof Number){
out.write(value.toString());
return;
}
if(value instanceof Boolean){
out.write(value.toString());
return;
}
if((value instanceof JSONStreamAware)){
((JSONStreamAware)value).writeJSONString(out);
return;
}
if((value instanceof JSONAware)){
out.write(((JSONAware)value).toJSONString());
return;
}
if(value instanceof Map){
JSONObject.writeJSONString((Map)value, out);
return;
}
if(value instanceof Collection){
JSONArray.writeJSONString((Collection)value, out);
return; return;
} }
if(value instanceof byte[]){
JSONArray.writeJSONString((byte[])value, out);
return;
}
if(value instanceof short[]){
JSONArray.writeJSONString((short[])value, out);
return;
}
if(value instanceof int[]){
JSONArray.writeJSONString((int[])value, out);
return;
}
if(value instanceof long[]){
JSONArray.writeJSONString((long[])value, out);
return;
}
if(value instanceof float[]){
JSONArray.writeJSONString((float[])value, out);
return;
}
if(value instanceof double[]){
JSONArray.writeJSONString((double[])value, out);
return;
}
if(value instanceof boolean[]){
JSONArray.writeJSONString((boolean[])value, out);
return;
}
if(value instanceof char[]){
JSONArray.writeJSONString((char[])value, out);
return;
}
if(value instanceof Object[]){
JSONArray.writeJSONString((Object[])value, out);
return;
}
out.write(value.toString());
}
/** if (value instanceof String) {
* Convert an object to JSON text. out.write('\"');
* <p> out.write(escape((String)value));
* If this object is a Map or a List, and it's also a JSONAware, JSONAware will be considered firstly. out.write('\"');
* <p> return;
* DO NOT call this method from toJSONString() of a class that implements both JSONAware and Map or List with }
* "this" as the parameter, use JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead.
*
* @see com.alibaba.nacos.client.logger.json.JSONObject#toJSONString(Map)
*
* @param value
* @return JSON text, or "null" if value is null or it's an NaN or an INF number.
*/
public static String toJSONString(Object value){
final StringWriter writer = new StringWriter();
try{
writeJSONString(value, writer);
return writer.toString();
} catch(IOException e){
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
/** if (value instanceof Double) {
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F). if (((Double)value).isInfinite() || ((Double)value).isNaN()) {
* @param s out.write("null");
* @return } else {
*/ out.write(value.toString());
public static String escape(String s){ }
if(s==null) { return;
return null; }
}
if (value instanceof Float) {
if (((Float)value).isInfinite() || ((Float)value).isNaN()) {
out.write("null");
} else {
out.write(value.toString());
}
return;
}
if (value instanceof Number) {
out.write(value.toString());
return;
}
if (value instanceof Boolean) {
out.write(value.toString());
return;
}
if ((value instanceof JSONStreamAware)) {
((JSONStreamAware)value).writeJSONString(out);
return;
}
if ((value instanceof JSONAware)) {
out.write(((JSONAware)value).toJSONString());
return;
}
if (value instanceof Map) {
JSONObject.writeJSONString((Map)value, out);
return;
}
if (value instanceof Collection) {
JSONArray.writeJSONString((Collection)value, out);
return;
}
if (value instanceof byte[]) {
JSONArray.writeJSONString((byte[])value, out);
return;
}
if (value instanceof short[]) {
JSONArray.writeJSONString((short[])value, out);
return;
}
if (value instanceof int[]) {
JSONArray.writeJSONString((int[])value, out);
return;
}
if (value instanceof long[]) {
JSONArray.writeJSONString((long[])value, out);
return;
}
if (value instanceof float[]) {
JSONArray.writeJSONString((float[])value, out);
return;
}
if (value instanceof double[]) {
JSONArray.writeJSONString((double[])value, out);
return;
}
if (value instanceof boolean[]) {
JSONArray.writeJSONString((boolean[])value, out);
return;
}
if (value instanceof char[]) {
JSONArray.writeJSONString((char[])value, out);
return;
}
if (value instanceof Object[]) {
JSONArray.writeJSONString((Object[])value, out);
return;
}
out.write(value.toString());
}
/**
* Convert an object to JSON text.
* <p>
* If this object is a Map or a List, and it's also a JSONAware, JSONAware will be considered firstly.
* <p>
* DO NOT call this method from toJSONString() of a class that implements both JSONAware and Map or List with "this"
* as the parameter, use JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead.
*
* @param value
* @return JSON text, or "null" if value is null or it's an NaN or an INF number.
* @see com.alibaba.nacos.client.logger.json.JSONObject#toJSONString(Map)
*/
public static String toJSONString(Object value) {
final StringWriter writer = new StringWriter();
try {
writeJSONString(value, writer);
return writer.toString();
} catch (IOException e) {
// This should never happen for a StringWriter
throw new RuntimeException(e);
}
}
/**
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
*
* @param s
* @return
*/
public static String escape(String s) {
if (s == null) {
return null;
}
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
escape(s, sb); escape(s, sb);
return sb.toString(); return sb.toString();
} }
/** /**
* @param s - Must not be null. * @param s - Must not be null.
* @param sb * @param sb
*/ */
static void escape(String s, StringBuffer sb) { static void escape(String s, StringBuffer sb) {
final int len = s.length(); final int len = s.length();
for(int i=0;i<len;i++){ for (int i = 0; i < len; i++) {
char ch=s.charAt(i); char ch = s.charAt(i);
switch(ch){ switch (ch) {
case '"': case '"':
sb.append("\\\""); sb.append("\\\"");
break; break;
case '\\': case '\\':
sb.append("\\\\"); sb.append("\\\\");
break; break;
case '\b': case '\b':
sb.append("\\b"); sb.append("\\b");
break; break;
case '\f': case '\f':
sb.append("\\f"); sb.append("\\f");
break; break;
case '\n': case '\n':
sb.append("\\n"); sb.append("\\n");
break; break;
case '\r': case '\r':
sb.append("\\r"); sb.append("\\r");
break; break;
case '\t': case '\t':
sb.append("\\t"); sb.append("\\t");
break; break;
case '/': case '/':
sb.append("\\/"); sb.append("\\/");
break; break;
default: default:
//Reference: http://www.unicode.org/versions/Unicode5.1.0/ //Reference: http://www.unicode.org/versions/Unicode5.1.0/
if(isUnicodeChar(ch)){ if (isUnicodeChar(ch)) {
String ss=Integer.toHexString(ch); String ss = Integer.toHexString(ch);
sb.append("\\u"); sb.append("\\u");
for(int k=0;k<FOUR-ss.length();k++){ for (int k = 0; k < FOUR - ss.length(); k++) {
sb.append('0'); sb.append('0');
} }
sb.append(ss.toUpperCase()); sb.append(ss.toUpperCase());
} } else {
else{ sb.append(ch);
sb.append(ch); }
} }
} }//for
}//for }
}
private static boolean isUnicodeChar(char ch) {
private static boolean isUnicodeChar(char ch) { return (ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F')
return (ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF');
|| (ch >= '\u2000' && ch <= '\u20FF'); }
}
private static int FOUR = 4;
private static int FOUR = 4;
} }

View File

@ -20,21 +20,24 @@ import java.util.Map;
/** /**
* Container factory for creating containers for JSON object and JSON array. * Container factory for creating containers for JSON object and JSON array.
* *
* @author FangYidong<fangyidong @ yahoo.com.cn>
* @see com.alibaba.nacos.client.logger.json.parser.JSONParser#parse(java.io.Reader, ContainerFactory) * @see com.alibaba.nacos.client.logger.json.parser.JSONParser#parse(java.io.Reader, ContainerFactory)
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/ */
public interface ContainerFactory { public interface ContainerFactory {
/** /**
* create json container * create json container
* @return A Map instance to store JSON object, or null if you want to use com.alibaba.nacos.client.logger.jsonJSONObject. *
*/ * @return A Map instance to store JSON object, or null if you want to use com.alibaba.nacos.client.logger
Map createObjectContainer(); * .jsonJSONObject.
*/
/** Map createObjectContainer();
* create array json container
* @return A List instance to store JSON array, or null if you want to use com.alibaba.nacos.client.logger.jsonJSONArray. /**
*/ * create array json container
List creatArrayContainer(); *
* @return A List instance to store JSON array, or null if you want to use com.alibaba.nacos.client.logger
* .jsonJSONArray.
*/
List creatArrayContainer();
} }

View File

@ -18,112 +18,100 @@ package com.alibaba.nacos.client.logger.json.parser;
import java.io.IOException; import java.io.IOException;
/** /**
* A simplified and stoppable SAX-like content handler for stream processing of JSON text. * A simplified and stoppable SAX-like content handler for stream processing of JSON text.
* *
* @author FangYidong<fangyidong @ yahoo.com.cn>
* @see org.xml.sax.ContentHandler * @see org.xml.sax.ContentHandler
* @see com.alibaba.nacos.client.logger.json.parser.JSONParser#parse(java.io.Reader, ContentHandler, boolean) * @see com.alibaba.nacos.client.logger.json.parser.JSONParser#parse(java.io.Reader, ContentHandler, boolean)
*
* @author FangYidong<fangyidong@yahoo.com.cn>
*/ */
public interface ContentHandler { public interface ContentHandler {
/** /**
* Receive notification of the beginning of JSON processing. * Receive notification of the beginning of JSON processing. The parser will invoke this method only once.
* The parser will invoke this method only once. *
* * @throws ParseException - JSONParser will stop and throw the same exception to the caller when receiving this
* @throws ParseException * exception.
* - JSONParser will stop and throw the same exception to the caller when receiving this exception.
* @throws IOException * @throws IOException
*/ */
void startJSON() throws ParseException, IOException; void startJSON() throws ParseException, IOException;
/** /**
* Receive notification of the end of JSON processing. * Receive notification of the end of JSON processing.
* *
* @throws ParseException * @throws ParseException
* @throws IOException * @throws IOException
*/ */
void endJSON() throws ParseException, IOException; void endJSON() throws ParseException, IOException;
/** /**
* Receive notification of the beginning of a JSON object. * Receive notification of the beginning of a JSON object.
* *
* @return false if the handler wants to stop parsing after return. * @return false if the handler wants to stop parsing after return.
* @throws ParseException * @throws ParseException - JSONParser will stop and throw the same exception to the caller when receiving this
* - JSONParser will stop and throw the same exception to the caller when receiving this exception. * exception.
* @throws IOException * @throws IOException
* @see #endJSON * @see #endJSON
*/ */
boolean startObject() throws ParseException, IOException; boolean startObject() throws ParseException, IOException;
/** /**
* Receive notification of the end of a JSON object. * Receive notification of the end of a JSON object.
* *
* @return false if the handler wants to stop parsing after return. * @return false if the handler wants to stop parsing after return.
* @throws ParseException * @throws ParseException
* @throws IOException * @throws IOException
* @see #startObject * @see #startObject
*/ */
boolean endObject() throws ParseException, IOException; boolean endObject() throws ParseException, IOException;
/** /**
* Receive notification of the beginning of a JSON object entry. * Receive notification of the beginning of a JSON object entry.
* *
* @param key - Key of a JSON object entry. * @param key - Key of a JSON object entry.
* * @return false if the handler wants to stop parsing after return.
* @return false if the handler wants to stop parsing after return. * @throws ParseException
* @throws ParseException * @throws IOException
* @throws IOException
* @see #endObjectEntry * @see #endObjectEntry
*/ */
boolean startObjectEntry(String key) throws ParseException, IOException; boolean startObjectEntry(String key) throws ParseException, IOException;
/** /**
* Receive notification of the end of the value of previous object entry. * Receive notification of the end of the value of previous object entry.
* *
* @return false if the handler wants to stop parsing after return. * @return false if the handler wants to stop parsing after return.
* @throws ParseException * @throws ParseException
* @throws IOException * @throws IOException
* @see #startObjectEntry * @see #startObjectEntry
*/ */
boolean endObjectEntry() throws ParseException, IOException; boolean endObjectEntry() throws ParseException, IOException;
/** /**
* Receive notification of the beginning of a JSON array. * Receive notification of the beginning of a JSON array.
* *
* @return false if the handler wants to stop parsing after return. * @return false if the handler wants to stop parsing after return.
* @throws ParseException * @throws ParseException
* @throws IOException * @throws IOException
* @see #endArray * @see #endArray
*/ */
boolean startArray() throws ParseException, IOException; boolean startArray() throws ParseException, IOException;
/** /**
* Receive notification of the end of a JSON array. * Receive notification of the end of a JSON array.
* *
* @return false if the handler wants to stop parsing after return. * @return false if the handler wants to stop parsing after return.
* @throws ParseException * @throws ParseException
* @throws IOException * @throws IOException
* @see #startArray * @see #startArray
*/ */
boolean endArray() throws ParseException, IOException; boolean endArray() throws ParseException, IOException;
/** /**
* Receive notification of the JSON primitive values: * Receive notification of the JSON primitive values: java.lang.String, java.lang.Number, java.lang.Boolean null
* java.lang.String, *
* java.lang.Number, * @param value - Instance of the following: java.lang.String, java.lang.Number, java.lang.Boolean null
* java.lang.Boolean * @return false if the handler wants to stop parsing after return.
* null * @throws ParseException
* * @throws IOException
* @param value - Instance of the following: */
* java.lang.String, boolean primitive(Object value) throws ParseException, IOException;
* java.lang.Number,
* java.lang.Boolean
* null
*
* @return false if the handler wants to stop parsing after return.
* @throws ParseException
* @throws IOException
*/
boolean primitive(Object value) throws ParseException, IOException;
} }

View File

@ -17,89 +17,87 @@ package com.alibaba.nacos.client.logger.json.parser;
/** /**
* ParseException explains why and where the error occurs in source JSON text. * ParseException explains why and where the error occurs in source JSON text.
*
* @author FangYidong<fangyidong@yahoo.com.cn>
* *
* @author FangYidong<fangyidong @ yahoo.com.cn>
*/ */
public class ParseException extends Exception { public class ParseException extends Exception {
private static final long serialVersionUID = -7880698968187728547L; private static final long serialVersionUID = -7880698968187728547L;
public static final int ERROR_UNEXPECTED_CHAR = 0;
public static final int ERROR_UNEXPECTED_TOKEN = 1;
public static final int ERROR_UNEXPECTED_EXCEPTION = 2;
private int errorType; public static final int ERROR_UNEXPECTED_CHAR = 0;
private Object unexpectedObject; public static final int ERROR_UNEXPECTED_TOKEN = 1;
private int position; public static final int ERROR_UNEXPECTED_EXCEPTION = 2;
public ParseException(int errorType){ private int errorType;
this(-1, errorType, null); private Object unexpectedObject;
} private int position;
public ParseException(int errorType, Object unexpectedObject){ public ParseException(int errorType) {
this(-1, errorType, unexpectedObject); this(-1, errorType, null);
} }
public ParseException(int position, int errorType, Object unexpectedObject){ public ParseException(int errorType, Object unexpectedObject) {
this.position = position; this(-1, errorType, unexpectedObject);
this.errorType = errorType; }
this.unexpectedObject = unexpectedObject;
} public ParseException(int position, int errorType, Object unexpectedObject) {
this.position = position;
public int getErrorType() { this.errorType = errorType;
return errorType; this.unexpectedObject = unexpectedObject;
} }
public void setErrorType(int errorType) { public int getErrorType() {
this.errorType = errorType; return errorType;
} }
/** public void setErrorType(int errorType) {
* @see com.alibaba.nacos.client.logger.json.parser.JSONParser#getPosition() this.errorType = errorType;
* }
* @return The character position (starting with 0) of the input where the error occurs.
*/ /**
public int getPosition() { * @return The character position (starting with 0) of the input where the error occurs.
return position; * @see com.alibaba.nacos.client.logger.json.parser.JSONParser#getPosition()
} */
public int getPosition() {
public void setPosition(int position) { return position;
this.position = position; }
}
public void setPosition(int position) {
/** this.position = position;
* @see com.alibaba.nacos.client.logger.json.parser.Yytoken }
*
* @return One of the following base on the value of errorType: /**
* ERROR_UNEXPECTED_CHAR java.lang.Character * @return One of the following base on the value of errorType: ERROR_UNEXPECTED_CHAR java.lang.Character
* ERROR_UNEXPECTED_TOKEN com.alibaba.nacos.client.logger.jsonparser.Yytoken * ERROR_UNEXPECTED_TOKEN com.alibaba.nacos.client.logger.jsonparser.Yytoken ERROR_UNEXPECTED_EXCEPTION
* ERROR_UNEXPECTED_EXCEPTION java.lang.Exception * java.lang.Exception
*/ * @see com.alibaba.nacos.client.logger.json.parser.Yytoken
public Object getUnexpectedObject() { */
return unexpectedObject; public Object getUnexpectedObject() {
} return unexpectedObject;
}
public void setUnexpectedObject(Object unexpectedObject) {
this.unexpectedObject = unexpectedObject; public void setUnexpectedObject(Object unexpectedObject) {
} this.unexpectedObject = unexpectedObject;
}
public String getMessage() {
StringBuffer sb = new StringBuffer(); public String getMessage() {
StringBuffer sb = new StringBuffer();
switch(errorType){
case ERROR_UNEXPECTED_CHAR: switch (errorType) {
sb.append("Unexpected character (").append(unexpectedObject).append(") at position ").append(position).append("."); case ERROR_UNEXPECTED_CHAR:
break; sb.append("Unexpected character (").append(unexpectedObject).append(") at position ").append(position)
case ERROR_UNEXPECTED_TOKEN: .append(".");
sb.append("Unexpected token ").append(unexpectedObject).append(" at position ").append(position).append("."); break;
break; case ERROR_UNEXPECTED_TOKEN:
case ERROR_UNEXPECTED_EXCEPTION: sb.append("Unexpected token ").append(unexpectedObject).append(" at position ").append(position).append(
sb.append("Unexpected exception at position ").append(position).append(": ").append(unexpectedObject); ".");
break; break;
default: case ERROR_UNEXPECTED_EXCEPTION:
sb.append("Unkown error at position ").append(position).append("."); sb.append("Unexpected exception at position ").append(position).append(": ").append(unexpectedObject);
break; break;
} default:
return sb.toString(); sb.append("Unkown error at position ").append(position).append(".");
} break;
}
return sb.toString();
}
} }

View File

@ -23,34 +23,38 @@ import java.io.UnsupportedEncodingException;
/** /**
* Yylex * Yylex
* @author Nacos
* *
* @author Nacos
*/ */
class Yylex { class Yylex {
/** This character denotes the end of file */ /**
* This character denotes the end of file
*/
public static final int YYEOF = -1; public static final int YYEOF = -1;
/** initial size of the lookahead buffer */ /**
* initial size of the lookahead buffer
*/
private static final int ZZ_BUFFERSIZE = 16384; private static final int ZZ_BUFFERSIZE = 16384;
/** lexical states */ /**
* lexical states
*/
public static final int YYINITIAL = 0; public static final int YYINITIAL = 0;
public static final int STRING_BEGIN = 2; public static final int STRING_BEGIN = 2;
/** /**
* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l ZZ_LEXSTATE[l+1] is the state in the DFA for the
* ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l * lexical state l at the beginning of a line l is of the form l = 2*k, k a non negative integer
* at the beginning of a line
* l is of the form l = 2*k, k a non negative integer
*/ */
private static final int ZZ_LEXSTATE[] = { 0, 0, 1, 1 }; private static final int ZZ_LEXSTATE[] = {0, 0, 1, 1};
/** /**
* Translates characters to character classes * Translates characters to character classes
*/ */
private static final String ZZ_CMAP_PACKED = private static final String ZZ_CMAP_PACKED =
"\11\0\1\7\1\7\2\0\1\7\22\0\1\7\1\0\1\11\10\0" + "\1\6\1\31\1\2\1\4\1\12\12\3\1\32\6\0\4\1\1\5" "\11\0\1\7\1\7\2\0\1\7\22\0\1\7\1\0\1\11\10\0" + "\1\6\1\31\1\2\1\4\1\12\12\3\1\32\6\0\4\1\1\5"
+ "\1\1\24\0\1\27\1\10\1\30\3\0\1\22\1\13\2\1\1\21" + "\1\14\5\0\1\23\1\0\1\15\3\0\1\16\1\24\1\17\1\20" + "\1\1\24\0\1\27\1\10\1\30\3\0\1\22\1\13\2\1\1\21" + "\1\14\5\0\1\23\1\0\1\15\3\0\1\16\1\24\1\17\1\20"
+ "\5\0\1\25\1\0\1\26\uff82\0"; + "\5\0\1\25\1\0\1\26\uff82\0";
@ -65,7 +69,7 @@ class Yylex {
private static final int[] ZZ_ACTION = zzUnpackAction(); private static final int[] ZZ_ACTION = zzUnpackAction();
private static final String ZZ_ACTION_PACKED_0 = private static final String ZZ_ACTION_PACKED_0 =
"\2\0\2\1\1\2\1\3\1\4\3\1\1\5\1\6" + "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\5\0" "\2\0\2\1\1\2\1\3\1\4\3\1\1\5\1\6" + "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\5\0"
+ "\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24" + "\1\0\1\25\1\0\1\25\4\0\1\26\1\27\2\0" + "\1\30"; + "\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24" + "\1\0\1\25\1\0\1\25\4\0\1\26\1\27\2\0" + "\1\30";
private static int[] zzUnpackAction() { private static int[] zzUnpackAction() {
@ -82,7 +86,7 @@ class Yylex {
while (i < l) { while (i < l) {
int count = packed.charAt(i++); int count = packed.charAt(i++);
int value = packed.charAt(i++); int value = packed.charAt(i++);
do result[j++] = value; while (--count > 0); do { result[j++] = value; } while (--count > 0);
} }
return j; return j;
} }
@ -93,7 +97,7 @@ class Yylex {
private static final int[] ZZ_ROWMAP = zzUnpackRowMap(); private static final int[] ZZ_ROWMAP = zzUnpackRowMap();
private static final String ZZ_ROWMAP_PACKED_0 = private static final String ZZ_ROWMAP_PACKED_0 =
"\0\0\0\33\0\66\0\121\0\154\0\207\0\66\0\242" + "\0\275\0\330\0\66\0\66\0\66\0\66\0\66\0\66" "\0\0\0\33\0\66\0\121\0\154\0\207\0\66\0\242" + "\0\275\0\330\0\66\0\66\0\66\0\66\0\66\0\66"
+ "\0\363\0\u010e\0\66\0\u0129\0\u0144\0\u015f\0\u017a\0\u0195" + "\0\66\0\66\0\66\0\66\0\66\0\66\0\66\0\66" + "\0\363\0\u010e\0\66\0\u0129\0\u0144\0\u015f\0\u017a\0\u0195" + "\0\66\0\66\0\66\0\66\0\66\0\66\0\66\0\66"
+ "\0\u01b0\0\u01cb\0\u01e6\0\u01e6\0\u0201\0\u021c\0\u0237\0\u0252" + "\0\66\0\66\0\u026d\0\u0288\0\66"; + "\0\u01b0\0\u01cb\0\u01e6\0\u01e6\0\u0201\0\u021c\0\u0237\0\u0252" + "\0\66\0\66\0\u026d\0\u0288\0\66";
@ -118,42 +122,42 @@ class Yylex {
/** /**
* The transition table of the DFA * The transition table of the DFA
*/ */
private static final int ZZ_TRANS[] = { 2, 2, 3, 4, 2, 2, 2, 5, 2, 6, 2, 2, 7, 8, 2, 9, 2, 2, 2, 2, 2, 10, 11, 12, private static final int ZZ_TRANS[] = {2, 2, 3, 4, 2, 2, 2, 5, 2, 6, 2, 2, 7, 8, 2, 9, 2, 2, 2, 2, 2, 10, 11, 12,
13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 18, 16, 16, 16, 16, 16, 16, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 18, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1, -1, -1, -1, -1, -1, -1, -1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 19, 20, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 16, 16, 16, 16, 16, 16, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 16, 16, 16, 16, 16, 16, 16, -1,
-1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1, -1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1,
-1, -1, -1, -1, -1, -1, -1, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, 35,
-1, -1, 34, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, 39, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, 39, -1, 39, -1, -1, -1, -1,
-1, 39, 39, -1, -1, -1, -1, 39, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, 39, -1, -1, -1, -1, 39, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 33, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, 33, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 42, -1, 42, -1, 42, -1, -1, -1, -1, -1, 42, 42, -1, -1, -1, -1, 42, 42, -1, 42, -1, 42, -1, 42, -1, -1, -1, -1, -1, 42, 42, -1, -1, -1, -1, 42, 42,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, 43, -1, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, 43, -1, 43, -1, -1, -1, -1, -1,
43, 43, -1, -1, -1, -1, 43, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, -1, 43, 43, -1, -1, -1, -1, 43, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, -1,
44, -1, 44, -1, -1, -1, -1, -1, 44, 44, -1, -1, -1, -1, 44, 44, -1, -1, -1, 44, -1, 44, -1, -1, -1, -1, -1, 44, 44, -1, -1, -1, -1, 44, 44, -1, -1, -1,
-1, -1, -1, -1, -1, }; -1, -1, -1, -1, -1,};
/** /**
* error codes * error codes
@ -163,10 +167,10 @@ class Yylex {
private static final int ZZ_PUSHBACK_2BIG = 2; private static final int ZZ_PUSHBACK_2BIG = 2;
private static final int NIGTY = 90; private static final int NIGTY = 90;
/** /**
* error messages for the codes above * error messages for the codes above
*/ */
private static final String[] ZZ_ERROR_MSG = { "Unkown internal scanner error", "Error: could not match input", private static final String[] ZZ_ERROR_MSG = {"Unkown internal scanner error", "Error: could not match input",
"Error: pushback value was too large" }; "Error: pushback value was too large"};
/** /**
* ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code> * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
@ -174,7 +178,7 @@ class Yylex {
private static final int[] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final int[] ZZ_ATTRIBUTE = zzUnpackAttribute();
private static final String ZZ_ATTRIBUTE_PACKED_0 = private static final String ZZ_ATTRIBUTE_PACKED_0 =
"\2\0\1\11\3\1\1\11\3\1\6\11\2\1\1\11" + "\5\0\10\11\1\0\1\1\1\0\1\1\4\0\2\11" + "\2\0\1\11"; "\2\0\1\11\3\1\1\11\3\1\6\11\2\1\1\11" + "\5\0\10\11\1\0\1\1\1\0\1\1\4\0\2\11" + "\2\0\1\11";
private static int[] zzUnpackAttribute() { private static int[] zzUnpackAttribute() {
int[] result = new int[45]; int[] result = new int[45];
@ -185,50 +189,64 @@ class Yylex {
private static int zzUnpackAttribute(String packed, int offset, int[] result) { private static int zzUnpackAttribute(String packed, int offset, int[] result) {
int i = 0; int i = 0;
int j = offset; int j = offset;
int l = packed.length(); int l = packed.length();
while (i < l) { while (i < l) {
int count = packed.charAt(i++); int count = packed.charAt(i++);
int value = packed.charAt(i++); int value = packed.charAt(i++);
do result[j++] = value; while (--count > 0); do { result[j++] = value; } while (--count > 0);
} }
return j; return j;
} }
/** the input device */ /**
* the input device
*/
private java.io.Reader zzReader; private java.io.Reader zzReader;
/** the current state of the DFA */ /**
* the current state of the DFA
*/
private int zzState; private int zzState;
/** the current lexical state */ /**
* the current lexical state
*/
private int zzLexicalState = YYINITIAL; private int zzLexicalState = YYINITIAL;
/** /**
* this buffer contains the current text to be matched and is * this buffer contains the current text to be matched and is the source of the yytext() string
* the source of the yytext() string
*/ */
private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
/** the textposition at the last accepting state */ /**
* the textposition at the last accepting state
*/
private int zzMarkedPos; private int zzMarkedPos;
/** the current text position in the buffer */ /**
* the current text position in the buffer
*/
private int zzCurrentPos; private int zzCurrentPos;
/** startRead marks the beginning of the yytext() string in the buffer */ /**
* startRead marks the beginning of the yytext() string in the buffer
*/
private int zzStartRead; private int zzStartRead;
/** /**
* endRead marks the last character in the buffer, that has been read * endRead marks the last character in the buffer, that has been read from input
* from input
*/ */
private int zzEndRead; private int zzEndRead;
/** the number of characters up to the start of the matched text */ /**
* the number of characters up to the start of the matched text
*/
private int yychar; private int yychar;
/** zzAtEOF == true <=> the scanner is at the EOF */ /**
* zzAtEOF == true <=> the scanner is at the EOF
*/
private boolean zzAtEOF; private boolean zzAtEOF;
/** /**
@ -241,8 +259,7 @@ class Yylex {
} }
/** /**
* Creates a new scanner * Creates a new scanner There is also a java.io.InputStream version of this constructor.
* There is also a java.io.InputStream version of this constructor.
* *
* @param in the java.io.Reader to read input from. * @param in the java.io.Reader to read input from.
*/ */
@ -251,11 +268,10 @@ class Yylex {
} }
/** /**
* Creates a new scanner. * Creates a new scanner. There is also java.io.Reader version of this constructor.
* There is also java.io.Reader version of this constructor.
* *
* @param in the java.io.Inputstream to read input from. * @param in the java.io.Inputstream to read input from.
* @throws UnsupportedEncodingException * @throws UnsupportedEncodingException
*/ */
Yylex(java.io.InputStream in) throws UnsupportedEncodingException { Yylex(java.io.InputStream in) throws UnsupportedEncodingException {
this(new java.io.InputStreamReader(in, Constants.ENCODE)); this(new java.io.InputStreamReader(in, Constants.ENCODE));
@ -269,12 +285,12 @@ class Yylex {
*/ */
private static char[] zzUnpackCMap(String packed) { private static char[] zzUnpackCMap(String packed) {
char[] map = new char[0x10000]; char[] map = new char[0x10000];
int i = 0; int i = 0;
int j = 0; int j = 0;
while (i < NIGTY) { while (i < NIGTY) {
int count = packed.charAt(i++); int count = packed.charAt(i++);
char value = packed.charAt(i++); char value = packed.charAt(i++);
do map[j++] = value; while (--count > 0); do { map[j++] = value; } while (--count > 0);
} }
return map; return map;
} }
@ -287,26 +303,26 @@ class Yylex {
*/ */
private boolean zzRefill() throws java.io.IOException { private boolean zzRefill() throws java.io.IOException {
/* first: make room (if you can) */ /* first: make room (if you can) */
if (zzStartRead > 0) { if (zzStartRead > 0) {
System.arraycopy(zzBuffer, zzStartRead, zzBuffer, 0, zzEndRead - zzStartRead); System.arraycopy(zzBuffer, zzStartRead, zzBuffer, 0, zzEndRead - zzStartRead);
/* translate stored positions */ /* translate stored positions */
zzEndRead -= zzStartRead; zzEndRead -= zzStartRead;
zzCurrentPos -= zzStartRead; zzCurrentPos -= zzStartRead;
zzMarkedPos -= zzStartRead; zzMarkedPos -= zzStartRead;
zzStartRead = 0; zzStartRead = 0;
} }
/* is the buffer big enough? */ /* is the buffer big enough? */
if (zzCurrentPos >= zzBuffer.length) { if (zzCurrentPos >= zzBuffer.length) {
/* if not: blow it up */ /* if not: blow it up */
char newBuffer[] = new char[zzCurrentPos * 2]; char newBuffer[] = new char[zzCurrentPos * 2];
System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);
zzBuffer = newBuffer; zzBuffer = newBuffer;
} }
/* finally: fill the buffer with new input */ /* finally: fill the buffer with new input */
int numRead = zzReader.read(zzBuffer, zzEndRead, zzBuffer.length - zzEndRead); int numRead = zzReader.read(zzBuffer, zzEndRead, zzBuffer.length - zzEndRead);
if (numRead > 0) { if (numRead > 0) {
@ -319,7 +335,7 @@ class Yylex {
if (c == -1) { if (c == -1) {
return true; return true;
} else { } else {
zzBuffer[zzEndRead++] = (char) c; zzBuffer[zzEndRead++] = (char)c;
return false; return false;
} }
} }
@ -333,19 +349,17 @@ class Yylex {
*/ */
public final void yyclose() throws java.io.IOException { public final void yyclose() throws java.io.IOException {
zzAtEOF = true; zzAtEOF = true;
zzEndRead = zzStartRead; zzEndRead = zzStartRead;
if (zzReader != null) { if (zzReader != null) {
zzReader.close(); zzReader.close();
} }
} }
/** /**
* Resets the scanner to read from a new input stream. * Resets the scanner to read from a new input stream. Does not close the old reader. All internal variables are
* Does not close the old reader. * reset, the old input stream <b>cannot</b> be reused (internal buffer is discarded and lost). Lexical state is set
* All internal variables are reset, the old input stream * to <tt>ZZ_INITIAL</tt>.
* <b>cannot</b> be reused (internal buffer is discarded and lost).
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
* *
* @param reader the new input stream * @param reader the new input stream
*/ */
@ -381,12 +395,10 @@ class Yylex {
} }
/** /**
* Returns the character at position <tt>pos</tt> from the * Returns the character at position <tt>pos</tt> from the matched text. It is equivalent to yytext().charAt(pos),
* matched text. * but faster
* It is equivalent to yytext().charAt(pos), but faster
* *
* @param pos the position of the character to fetch. * @param pos the position of the character to fetch. A value from 0 to yylength()-1.
* A value from 0 to yylength()-1.
* @return the character at position pos * @return the character at position pos
*/ */
public final char yycharat(int pos) { public final char yycharat(int pos) {
@ -401,14 +413,10 @@ class Yylex {
} }
/** /**
* Reports an error that occured while scanning. * Reports an error that occured while scanning. In a wellformed scanner (no or only correct usage of
* In a wellformed scanner (no or only correct usage of * yypushback(int) and a match-all fallback rule) this method will only be called with things that "Can't Possibly
* yypushback(int) and a match-all fallback rule) this method * Happen". If this method is called, something is seriously wrong (e.g. a JFlex bug producing a faulty scanner
* will only be called with things that "Can't Possibly Happen". * etc.). Usual syntax/scanner level error handling should be done in error fallback rules.
* If this method is called, something is seriously wrong
* (e.g. a JFlex bug producing a faulty scanner etc.).
* Usual syntax/scanner level error handling should be done
* in error fallback rules.
* *
* @param errorCode the code of the errormessage to display * @param errorCode the code of the errormessage to display
*/ */
@ -424,23 +432,22 @@ class Yylex {
} }
/** /**
* Pushes the specified amount of characters back into the input stream. * Pushes the specified amount of characters back into the input stream. They will be read again by then next call
* They will be read again by then next call of the scanning method * of the scanning method
* *
* @param number the number of characters to be read again. * @param number the number of characters to be read again. This number must not be greater than yylength()!
* This number must not be greater than yylength()!
*/ */
public void yypushback(int number) { public void yypushback(int number) {
if (number > yylength()) { if (number > yylength()) {
zzScanError(ZZ_PUSHBACK_2BIG); zzScanError(ZZ_PUSHBACK_2BIG);
} }
zzMarkedPos -= number; zzMarkedPos -= number;
} }
/** /**
* Resumes scanning until the next regular expression is matched, * Resumes scanning until the next regular expression is matched, the end of input is encountered or an I/O-Error
* the end of input is encountered or an I/O-Error occurs. * occurs.
* *
* @return the next token * @return the next token
* @throws java.io.IOException if any I/O-Error occurs * @throws java.io.IOException if any I/O-Error occurs
@ -476,10 +483,9 @@ class Yylex {
{ {
while (true) { while (true) {
if (zzCurrentPosL < zzEndReadL) { if (zzCurrentPosL < zzEndReadL) {
zzInput = zzBufferL[zzCurrentPosL++]; zzInput = zzBufferL[zzCurrentPosL++];
} } else if (zzAtEOF) {
else if (zzAtEOF) {
zzInput = YYEOF; zzInput = YYEOF;
break zzForAction; break zzForAction;
} else { } else {
@ -500,18 +506,18 @@ class Yylex {
} }
} }
int zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]]; int zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]];
if (zzNext == -1) { if (zzNext == -1) {
break zzForAction; break zzForAction;
} }
zzState = zzNext; zzState = zzNext;
int zzAttributes = zzAttrL[zzState]; int zzAttributes = zzAttrL[zzState];
if ((zzAttributes & 1) == 1) { if ((zzAttributes & 1) == 1) {
zzAction = zzState; zzAction = zzState;
zzMarkedPosL = zzCurrentPosL; zzMarkedPosL = zzCurrentPosL;
if ((zzAttributes & 8) == 8) { if ((zzAttributes & 8) == 8) {
break zzForAction; break zzForAction;
} }
} }
} }
@ -519,7 +525,7 @@ class Yylex {
// store back cached position // store back cached position
zzMarkedPos = zzMarkedPosL; zzMarkedPos = zzMarkedPosL;
switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
case 11: { case 11: {
sb.append(yytext()); sb.append(yytext());
@ -572,7 +578,8 @@ class Yylex {
case 33: case 33:
break; break;
case 1: { case 1: {
throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_CHAR, Character.valueOf(yycharat(0))); throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_CHAR,
Character.valueOf(yycharat(0)));
} }
case 34: case 34:
break; break;
@ -614,7 +621,7 @@ class Yylex {
case 24: { case 24: {
try { try {
int ch = Integer.parseInt(yytext().substring(2), 16); int ch = Integer.parseInt(yytext().substring(2), 16);
sb.append((char) ch); sb.append((char)ch);
} catch (Exception e) { } catch (Exception e) {
throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_EXCEPTION, e); throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_EXCEPTION, e);
} }

View File

@ -20,62 +20,62 @@
package com.alibaba.nacos.client.logger.json.parser; package com.alibaba.nacos.client.logger.json.parser;
/** /**
* @author FangYidong<fangyidong@yahoo.com.cn> * @author FangYidong<fangyidong @ yahoo.com.cn>
*/ */
public class Yytoken { public class Yytoken {
/** /**
* JSON primitive value: string,number,boolean,null * JSON primitive value: string,number,boolean,null
*/ */
public static final int TYPE_VALUE=0; public static final int TYPE_VALUE = 0;
public static final int TYPE_LEFT_BRACE=1; public static final int TYPE_LEFT_BRACE = 1;
public static final int TYPE_RIGHT_BRACE=2; public static final int TYPE_RIGHT_BRACE = 2;
public static final int TYPE_LEFT_SQUARE=3; public static final int TYPE_LEFT_SQUARE = 3;
public static final int TYPE_RIGHT_SQUARE=4; public static final int TYPE_RIGHT_SQUARE = 4;
public static final int TYPE_COMMA=5; public static final int TYPE_COMMA = 5;
public static final int TYPE_COLON=6; public static final int TYPE_COLON = 6;
/** /**
* end of file * end of file
*/ */
public static final int TYPE_EOF=-1; public static final int TYPE_EOF = -1;
public int type=0; public int type = 0;
public Object value=null; public Object value = null;
public Yytoken(int type,Object value){ public Yytoken(int type, Object value) {
this.type=type; this.type = type;
this.value=value; this.value = value;
} }
public String toString(){ public String toString() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
switch(type){ switch (type) {
case TYPE_VALUE: case TYPE_VALUE:
sb.append("VALUE(").append(value).append(")"); sb.append("VALUE(").append(value).append(")");
break; break;
case TYPE_LEFT_BRACE: case TYPE_LEFT_BRACE:
sb.append("LEFT BRACE({)"); sb.append("LEFT BRACE({)");
break; break;
case TYPE_RIGHT_BRACE: case TYPE_RIGHT_BRACE:
sb.append("RIGHT BRACE(})"); sb.append("RIGHT BRACE(})");
break; break;
case TYPE_LEFT_SQUARE: case TYPE_LEFT_SQUARE:
sb.append("LEFT SQUARE([)"); sb.append("LEFT SQUARE([)");
break; break;
case TYPE_RIGHT_SQUARE: case TYPE_RIGHT_SQUARE:
sb.append("RIGHT SQUARE(])"); sb.append("RIGHT SQUARE(])");
break; break;
case TYPE_COMMA: case TYPE_COMMA:
sb.append("COMMA(,)"); sb.append("COMMA(,)");
break; break;
case TYPE_COLON: case TYPE_COLON:
sb.append("COLON(:)"); sb.append("COLON(:)");
break; break;
case TYPE_EOF: case TYPE_EOF:
sb.append("END OF FILE"); sb.append("END OF FILE");
break; break;
default: default:
break; break;
} }
return sb.toString(); return sb.toString();
} }
} }

View File

@ -21,11 +21,10 @@ import com.alibaba.nacos.client.logger.support.LoggerHelper;
import com.alibaba.nacos.client.logger.support.LoggerSupport; import com.alibaba.nacos.client.logger.support.LoggerSupport;
import com.alibaba.nacos.client.logger.util.MessageUtil; import com.alibaba.nacos.client.logger.util.MessageUtil;
/** /**
* Log4j2Logger * Log4j2Logger
* @author Nacos
* *
* @author Nacos
*/ */
public class Log4j2Logger extends LoggerSupport implements Logger { public class Log4j2Logger extends LoggerSupport implements Logger {

View File

@ -24,8 +24,8 @@ import com.alibaba.nacos.client.logger.support.LogLog;
/** /**
* Log4j2Logger Factory * Log4j2Logger Factory
* @author Nacos
* *
* @author Nacos
*/ */
public class Log4j2LoggerFactory implements ILoggerFactory { public class Log4j2LoggerFactory implements ILoggerFactory {

View File

@ -17,14 +17,15 @@ package com.alibaba.nacos.client.logger.nop;
import com.alibaba.nacos.client.logger.Logger; import com.alibaba.nacos.client.logger.Logger;
import com.alibaba.nacos.client.logger.support.LoggerSupport; import com.alibaba.nacos.client.logger.support.LoggerSupport;
/** /**
* NopLogger * NopLogger
* @author Nacos
* *
* @author Nacos
*/ */
public class NopLogger extends LoggerSupport implements Logger { public class NopLogger extends LoggerSupport implements Logger {
public NopLogger(){ public NopLogger() {
super(null); super(null);
} }

View File

@ -17,10 +17,11 @@ package com.alibaba.nacos.client.logger.nop;
import com.alibaba.nacos.client.logger.Logger; import com.alibaba.nacos.client.logger.Logger;
import com.alibaba.nacos.client.logger.support.ILoggerFactory; import com.alibaba.nacos.client.logger.support.ILoggerFactory;
/** /**
* NopLogger Factory * NopLogger Factory
* @author Nacos
* *
* @author Nacos
*/ */
public class NopLoggerFactory implements ILoggerFactory { public class NopLoggerFactory implements ILoggerFactory {

View File

@ -24,8 +24,8 @@ import java.util.List;
/** /**
* AbstractActiveOption * AbstractActiveOption
* @author Nacos
* *
* @author Nacos
*/ */
public abstract class AbstractActiveOption implements ActivateOption { public abstract class AbstractActiveOption implements ActivateOption {
@ -53,7 +53,7 @@ public abstract class AbstractActiveOption implements ActivateOption {
for (Object[] arg : args) { for (Object[] arg : args) {
if (arg != null && arg.length == 3) { if (arg != null && arg.length == 3) {
try { try {
Method m = object.getClass().getMethod((String) arg[0], (Class<?>[]) arg[1]); Method m = object.getClass().getMethod((String)arg[0], (Class<?>[])arg[1]);
m.invoke(object, arg[2]); m.invoke(object, arg[2]);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
LogLog.info("Can't find method for " + object.getClass() + " " + arg[0] + " " + arg[2]); LogLog.info("Can't find method for " + object.getClass() + " " + arg[0] + " " + arg[2]);

View File

@ -140,8 +140,7 @@ public interface ActivateOption {
int maxBackupIndex); int maxBackupIndex);
/** /**
* 将当前logger对象的appender设置为异步Appender * 将当前logger对象的appender设置为异步Appender 注意此logger需要提前进行Appender的初始化
* 注意此logger需要提前进行Appender的初始化
* *
* @param queueSize 等待队列大小 * @param queueSize 等待队列大小
* @param discardingThreshold discardingThreshold该参数仅对logback实现有效log4j和log4j2无效 * @param discardingThreshold discardingThreshold该参数仅对logback实现有效log4j和log4j2无效
@ -150,11 +149,10 @@ public interface ActivateOption {
void activateAsync(int queueSize, int discardingThreshold); void activateAsync(int queueSize, int discardingThreshold);
/** /**
* 将当前logger对象的appender设置为异步Appender * 将当前logger对象的appender设置为异步Appender 注意此logger需要提前进行Appender的初始化
* 注意此logger需要提前进行Appender的初始化
* *
* @param args AsyncAppender配置参数请自行保证参数的正确性要求每个Object[]有3个元素第一个为set方法名第二个为方法类型数组第三个为对应的参数值 * @param args AsyncAppender配置参数请自行保证参数的正确性要求每个Object[]有3个元素第一个为set方法名第二个为方法类型数组第三个为对应的参数值 args.add(new
* args.add(new Object[] { "setBufferSize", new Class<?>[] { int.class }, queueSize }); * Object[] { "setBufferSize", new Class<?>[] { int.class }, queueSize });
* @since 0.2.3 * @since 0.2.3
*/ */
void activateAsync(List<Object[]> args); void activateAsync(List<Object[]> args);
@ -176,6 +174,7 @@ public interface ActivateOption {
/** /**
* 获取日志级别 * 获取日志级别
*
* @return level * @return level
*/ */
Level getLevel(); Level getLevel();
@ -189,6 +188,7 @@ public interface ActivateOption {
/** /**
* 获取所属的产品名 * 获取所属的产品名
*
* @return 所属的产品名 * @return 所属的产品名
*/ */
String getProductName(); String getProductName();

View File

@ -47,11 +47,12 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
public Log4j2ActivateOption(org.apache.logging.log4j.Logger logger) { public Log4j2ActivateOption(org.apache.logging.log4j.Logger logger) {
if (logger != null) { if (logger != null) {
if (logger instanceof org.apache.logging.log4j.core.Logger) { if (logger instanceof org.apache.logging.log4j.core.Logger) {
this.logger = (org.apache.logging.log4j.core.Logger) logger; this.logger = (org.apache.logging.log4j.core.Logger)logger;
configuration = this.logger.getContext().getConfiguration(); configuration = this.logger.getContext().getConfiguration();
} else { } else {
throw new RuntimeException("logger must instanceof org.apache.logging.log4j.core.Logger, " + logger.getClass().getName()); throw new RuntimeException(
"logger must instanceof org.apache.logging.log4j.core.Logger, " + logger.getClass().getName());
} }
} }
} }
@ -59,12 +60,13 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
@Override @Override
public void activateConsoleAppender(String target, String encoding) { public void activateConsoleAppender(String target, String encoding) {
org.apache.logging.log4j.core.Layout layout = org.apache.logging.log4j.core.layout.PatternLayout.newBuilder(). org.apache.logging.log4j.core.Layout layout = org.apache.logging.log4j.core.layout.PatternLayout.newBuilder().
withConfiguration(configuration) withConfiguration(configuration)
.withPattern(LoggerHelper.getPattern()) .withPattern(LoggerHelper.getPattern())
.withCharset(Charset.forName(encoding)) .withCharset(Charset.forName(encoding))
.build(); .build();
org.apache.logging.log4j.core.appender.ConsoleAppender appender = ConsoleAppender.createAppender(layout, null, org.apache.logging.log4j.core.appender.ConsoleAppender appender = ConsoleAppender.createAppender(layout, null,
ConsoleAppender.Target.valueOf(target.toUpperCase().replace(".", "_")), "LoggerApiConsoleAppender", false, false, true); ConsoleAppender.Target.valueOf(target.toUpperCase().replace(".", "_")), "LoggerApiConsoleAppender", false,
false, true);
appender.start(); appender.start();
removeAllAppenders(logger); removeAllAppenders(logger);
logger.addAppender(appender); logger.addAppender(appender);
@ -75,17 +77,17 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
@Override @Override
public void activateAppender(String productName, String file, String encoding) { public void activateAppender(String productName, String file, String encoding) {
org.apache.logging.log4j.core.appender.RollingFileAppender appender = RollingFileAppender.newBuilder() org.apache.logging.log4j.core.appender.RollingFileAppender appender = RollingFileAppender.newBuilder()
.withName(productName + "." + file.replace(File.separatorChar, '.') + ".Appender") .withName(productName + "." + file.replace(File.separatorChar, '.') + ".Appender")
.withFileName(LoggerHelper.getLogFileP(productName, file)) .withFileName(LoggerHelper.getLogFileP(productName, file))
.withAppend(true) .withAppend(true)
.withBufferedIo(true) .withBufferedIo(true)
.setConfiguration(configuration) .setConfiguration(configuration)
.withFilePattern(LoggerHelper.getLogFile(productName, file) + ".%d{yyyy-MM-dd}") .withFilePattern(LoggerHelper.getLogFile(productName, file) + ".%d{yyyy-MM-dd}")
.withLayout(buildLayout(encoding)) .withLayout(buildLayout(encoding))
.withCreateOnDemand(false) .withCreateOnDemand(false)
.withPolicy(TimeBasedTriggeringPolicy.createPolicy("1", "true")) .withPolicy(TimeBasedTriggeringPolicy.createPolicy("1", "true"))
.withStrategy(DefaultRolloverStrategy.createStrategy(null, null, "nomax", null, null, false, configuration)) .withStrategy(DefaultRolloverStrategy.createStrategy(null, null, "nomax", null, null, false, configuration))
.build(); .build();
appender.start(); appender.start();
removeAllAppenders(logger); removeAllAppenders(logger);
@ -100,7 +102,8 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
} }
@Override @Override
public void activateAsyncAppender(String productName, String file, String encoding, int queueSize, int discardingThreshold) { public void activateAsyncAppender(String productName, String file, String encoding, int queueSize,
int discardingThreshold) {
activateAppender(productName, file, encoding); activateAppender(productName, file, encoding);
activateAsync(queueSize, discardingThreshold); activateAsync(queueSize, discardingThreshold);
} }
@ -111,19 +114,21 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
} }
@Override @Override
public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size, String datePattern) { public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size,
String datePattern) {
org.apache.logging.log4j.core.appender.RollingFileAppender appender = RollingFileAppender.newBuilder() org.apache.logging.log4j.core.appender.RollingFileAppender appender = RollingFileAppender.newBuilder()
.withName(productName + "." + file.replace(File.separatorChar, '.') + ".Appender") .withName(productName + "." + file.replace(File.separatorChar, '.') + ".Appender")
.withFileName(LoggerHelper.getLogFileP(productName, file)) .withFileName(LoggerHelper.getLogFileP(productName, file))
.withAppend(true) .withAppend(true)
.withBufferedIo(true) .withBufferedIo(true)
.setConfiguration(configuration) .setConfiguration(configuration)
.withFilePattern(LoggerHelper.getLogFile(productName, file) + ".%d{" + datePattern + "}") .withFilePattern(LoggerHelper.getLogFile(productName, file) + ".%d{" + datePattern + "}")
.withLayout(buildLayout(encoding)) .withLayout(buildLayout(encoding))
.withCreateOnDemand(false) .withCreateOnDemand(false)
.withPolicy(CompositeTriggeringPolicy.createPolicy(TimeBasedTriggeringPolicy.createPolicy("1", "true"), SizeBasedTriggeringPolicy.createPolicy(size))) .withPolicy(CompositeTriggeringPolicy.createPolicy(TimeBasedTriggeringPolicy.createPolicy("1", "true"),
.withStrategy(DefaultRolloverStrategy.createStrategy(null, null, "nomax", null, null, false, configuration)) SizeBasedTriggeringPolicy.createPolicy(size)))
.build(); .withStrategy(DefaultRolloverStrategy.createStrategy(null, null, "nomax", null, null, false, configuration))
.build();
appender.start(); appender.start();
removeAllAppenders(logger); removeAllAppenders(logger);
@ -133,19 +138,22 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
} }
@Override @Override
public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size, String datePattern, int maxBackupIndex) { public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size,
String datePattern, int maxBackupIndex) {
org.apache.logging.log4j.core.appender.RollingFileAppender appender = RollingFileAppender.newBuilder() org.apache.logging.log4j.core.appender.RollingFileAppender appender = RollingFileAppender.newBuilder()
.withName(productName + "." + file.replace(File.separatorChar, '.') + ".Appender") .withName(productName + "." + file.replace(File.separatorChar, '.') + ".Appender")
.withFileName(LoggerHelper.getLogFileP(productName, file)) .withFileName(LoggerHelper.getLogFileP(productName, file))
.withAppend(true) .withAppend(true)
.withBufferedIo(true) .withBufferedIo(true)
.setConfiguration(configuration) .setConfiguration(configuration)
.withFilePattern(LoggerHelper.getLogFile(productName, file) + ".%d{" + datePattern + "}.%i") .withFilePattern(LoggerHelper.getLogFile(productName, file) + ".%d{" + datePattern + "}.%i")
.withLayout(buildLayout(encoding)) .withLayout(buildLayout(encoding))
.withCreateOnDemand(false) .withCreateOnDemand(false)
.withPolicy(CompositeTriggeringPolicy.createPolicy(TimeBasedTriggeringPolicy.createPolicy("1", "true"), SizeBasedTriggeringPolicy.createPolicy(size))) .withPolicy(CompositeTriggeringPolicy.createPolicy(TimeBasedTriggeringPolicy.createPolicy("1", "true"),
.withStrategy(DefaultRolloverStrategy.createStrategy(String.valueOf(maxBackupIndex), "1", "max", null, null, false, configuration)) SizeBasedTriggeringPolicy.createPolicy(size)))
.build(); .withStrategy(DefaultRolloverStrategy
.createStrategy(String.valueOf(maxBackupIndex), "1", "max", null, null, false, configuration))
.build();
appender.start(); appender.start();
removeAllAppenders(logger); removeAllAppenders(logger);
@ -155,19 +163,21 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
} }
@Override @Override
public void activateAppenderWithSizeRolling(String productName, String file, String encoding, String size, int maxBackupIndex) { public void activateAppenderWithSizeRolling(String productName, String file, String encoding, String size,
int maxBackupIndex) {
org.apache.logging.log4j.core.appender.RollingFileAppender appender = RollingFileAppender.newBuilder() org.apache.logging.log4j.core.appender.RollingFileAppender appender = RollingFileAppender.newBuilder()
.withName(productName + "." + file.replace(File.separatorChar, '.') + ".Appender") .withName(productName + "." + file.replace(File.separatorChar, '.') + ".Appender")
.withFileName(LoggerHelper.getLogFileP(productName, file)) .withFileName(LoggerHelper.getLogFileP(productName, file))
.withAppend(true) .withAppend(true)
.withBufferedIo(true) .withBufferedIo(true)
.setConfiguration(configuration) .setConfiguration(configuration)
.withFilePattern(LoggerHelper.getLogFile(productName, file) + ".%i") .withFilePattern(LoggerHelper.getLogFile(productName, file) + ".%i")
.withLayout(buildLayout(encoding)) .withLayout(buildLayout(encoding))
.withCreateOnDemand(false) .withCreateOnDemand(false)
.withPolicy(SizeBasedTriggeringPolicy.createPolicy(size)) .withPolicy(SizeBasedTriggeringPolicy.createPolicy(size))
.withStrategy(DefaultRolloverStrategy.createStrategy(String.valueOf(maxBackupIndex), "1", "max", null, null, false, configuration)) .withStrategy(DefaultRolloverStrategy
.build(); .createStrategy(String.valueOf(maxBackupIndex), "1", "max", null, null, false, configuration))
.build();
appender.start(); appender.start();
removeAllAppenders(logger); removeAllAppenders(logger);
@ -181,7 +191,7 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
List<Object[]> args = new ArrayList<Object[]>(); List<Object[]> args = new ArrayList<Object[]>();
if (queueSize != Integer.MIN_VALUE) { if (queueSize != Integer.MIN_VALUE) {
args.add(new Object[] { "setBufferSize", new Class<?>[] { int.class }, queueSize }); args.add(new Object[] {"setBufferSize", new Class<?>[] {int.class}, queueSize});
} }
activateAsync(args); activateAsync(args);
} }
@ -201,10 +211,10 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
} }
AsyncAppender.Builder builder = AsyncAppender.newBuilder() AsyncAppender.Builder builder = AsyncAppender.newBuilder()
.setName(productName + "." + logger.getName() + ".AsyncAppender") .setName(productName + "." + logger.getName() + ".AsyncAppender")
.setConfiguration(configuration) .setConfiguration(configuration)
.setAppenderRefs(refs) .setAppenderRefs(refs)
.setBlockingQueueFactory(ArrayBlockingQueueFactory.<LogEvent>createFactory()); .setBlockingQueueFactory(ArrayBlockingQueueFactory.<LogEvent>createFactory());
invokeMethod(builder, args); invokeMethod(builder, args);
@ -221,10 +231,10 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
public void activateAppender(Logger logger) { public void activateAppender(Logger logger) {
if (!(logger.getDelegate() instanceof org.apache.logging.log4j.core.Logger)) { if (!(logger.getDelegate() instanceof org.apache.logging.log4j.core.Logger)) {
throw new IllegalArgumentException("logger must be org.apache.logging.log4j.core.Logger, but it's " throw new IllegalArgumentException("logger must be org.apache.logging.log4j.core.Logger, but it's "
+ logger.getDelegate().getClass()); + logger.getDelegate().getClass());
} }
activateAppender(((org.apache.logging.log4j.core.Logger) logger.getDelegate())); activateAppender(((org.apache.logging.log4j.core.Logger)logger.getDelegate()));
setProductName(logger.getProductName()); setProductName(logger.getProductName());
} }
@ -244,7 +254,8 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
public void setLevel(Level level) { public void setLevel(Level level) {
this.level = level; this.level = level;
org.apache.logging.log4j.Level l = org.apache.logging.log4j.Level.toLevel(level.getName(), org.apache.logging.log4j.Level.ERROR); org.apache.logging.log4j.Level l = org.apache.logging.log4j.Level.toLevel(level.getName(),
org.apache.logging.log4j.Level.ERROR);
logger.setLevel(l); logger.setLevel(l);
logger.getContext().getConfiguration().getLoggerConfig(this.logger.getName()).setLevel(l); logger.getContext().getConfiguration().getLoggerConfig(this.logger.getName()).setLevel(l);
} }
@ -256,10 +267,10 @@ public class Log4j2ActivateOption extends AbstractActiveOption {
protected org.apache.logging.log4j.core.Layout buildLayout(String encoding) { protected org.apache.logging.log4j.core.Layout buildLayout(String encoding) {
org.apache.logging.log4j.core.Layout layout = org.apache.logging.log4j.core.layout.PatternLayout.newBuilder(). org.apache.logging.log4j.core.Layout layout = org.apache.logging.log4j.core.layout.PatternLayout.newBuilder().
withConfiguration(configuration) withConfiguration(configuration)
.withPattern(LoggerHelper.getPattern()) .withPattern(LoggerHelper.getPattern())
.withCharset(Charset.forName(encoding)) .withCharset(Charset.forName(encoding))
.build(); .build();
return layout; return layout;
} }

View File

@ -39,14 +39,14 @@ import com.alibaba.nacos.client.logger.support.LoggerHelper;
* *
* @author zhuyong 2014年3月20日 上午11:16:26 * @author zhuyong 2014年3月20日 上午11:16:26
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({"rawtypes", "unchecked"})
public class Logback918ActivateOption extends AbstractActiveOption { public class Logback918ActivateOption extends AbstractActiveOption {
private ch.qos.logback.classic.Logger logger; private ch.qos.logback.classic.Logger logger;
public Logback918ActivateOption(Object logger) { public Logback918ActivateOption(Object logger) {
if (logger instanceof ch.qos.logback.classic.Logger) { if (logger instanceof ch.qos.logback.classic.Logger) {
this.logger = (ch.qos.logback.classic.Logger) logger; this.logger = (ch.qos.logback.classic.Logger)logger;
} else { } else {
throw new IllegalArgumentException("logger must be instanceof ch.qos.logback.classic.Logger"); throw new IllegalArgumentException("logger must be instanceof ch.qos.logback.classic.Logger");
} }
@ -102,7 +102,7 @@ public class Logback918ActivateOption extends AbstractActiveOption {
@Override @Override
public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size) { public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size) {
ch.qos.logback.core.Appender appender = getLogbackDailyAndSizeRollingFileAppender(productName, file, encoding, ch.qos.logback.core.Appender appender = getLogbackDailyAndSizeRollingFileAppender(productName, file, encoding,
size); size);
logger.detachAndStopAllAppenders(); logger.detachAndStopAllAppenders();
logger.addAppender(appender); logger.addAppender(appender);
@ -146,11 +146,12 @@ public class Logback918ActivateOption extends AbstractActiveOption {
public void activateAppender(Logger logger) { public void activateAppender(Logger logger) {
if (!(logger.getDelegate() instanceof ch.qos.logback.classic.Logger)) { if (!(logger.getDelegate() instanceof ch.qos.logback.classic.Logger)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"logger must be ch.qos.logback.classic.Logger, but it's " + logger.getDelegate().getClass()); "logger must be ch.qos.logback.classic.Logger, but it's " + logger.getDelegate().getClass());
} }
this.logger.detachAndStopAllAppenders(); this.logger.detachAndStopAllAppenders();
Iterator<ch.qos.logback.core.Appender<ILoggingEvent>> iter = ((ch.qos.logback.classic.Logger) logger.getDelegate()).iteratorForAppenders(); Iterator<ch.qos.logback.core.Appender<ILoggingEvent>> iter = ((ch.qos.logback.classic.Logger)logger
.getDelegate()).iteratorForAppenders();
while (iter.hasNext()) { while (iter.hasNext()) {
ch.qos.logback.core.Appender<ILoggingEvent> appender = iter.next(); ch.qos.logback.core.Appender<ILoggingEvent> appender = iter.next();
this.logger.addAppender(appender); this.logger.addAppender(appender);
@ -161,7 +162,7 @@ public class Logback918ActivateOption extends AbstractActiveOption {
public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size, public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size,
String datePattern) { String datePattern) {
ch.qos.logback.core.Appender appender = getLogbackDailyAndSizeRollingFileAppender(productName, file, encoding, ch.qos.logback.core.Appender appender = getLogbackDailyAndSizeRollingFileAppender(productName, file, encoding,
size, datePattern, -1); size, datePattern, -1);
logger.detachAndStopAllAppenders(); logger.detachAndStopAllAppenders();
logger.addAppender(appender); logger.addAppender(appender);
@ -211,8 +212,8 @@ public class Logback918ActivateOption extends AbstractActiveOption {
public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size, public void activateAppenderWithTimeAndSizeRolling(String productName, String file, String encoding, String size,
String datePattern, int maxBackupIndex) { String datePattern, int maxBackupIndex) {
ch.qos.logback.core.Appender appender = getLogbackDailyAndSizeRollingFileAppender(productName, file, encoding, ch.qos.logback.core.Appender appender = getLogbackDailyAndSizeRollingFileAppender(productName, file, encoding,
size, datePattern, size, datePattern,
maxBackupIndex); maxBackupIndex);
logger.detachAndStopAllAppenders(); logger.detachAndStopAllAppenders();
logger.addAppender(appender); logger.addAppender(appender);
@ -223,7 +224,7 @@ public class Logback918ActivateOption extends AbstractActiveOption {
public void activateAppenderWithSizeRolling(String productName, String file, String encoding, String size, public void activateAppenderWithSizeRolling(String productName, String file, String encoding, String size,
int maxBackupIndex) { int maxBackupIndex) {
ch.qos.logback.core.Appender appender = getSizeRollingAppender(productName, file, encoding, size, ch.qos.logback.core.Appender appender = getSizeRollingAppender(productName, file, encoding, size,
maxBackupIndex); maxBackupIndex);
logger.detachAndStopAllAppenders(); logger.detachAndStopAllAppenders();
logger.addAppender(appender); logger.addAppender(appender);
@ -235,11 +236,11 @@ public class Logback918ActivateOption extends AbstractActiveOption {
List<Object[]> args = new ArrayList<Object[]>(); List<Object[]> args = new ArrayList<Object[]>();
if (queueSize != Integer.MIN_VALUE) { if (queueSize != Integer.MIN_VALUE) {
args.add(new Object[] { "setQueueSize", new Class<?>[] { int.class }, queueSize }); args.add(new Object[] {"setQueueSize", new Class<?>[] {int.class}, queueSize});
} }
if (discardingThreshold != Integer.MIN_VALUE) { if (discardingThreshold != Integer.MIN_VALUE) {
args.add(new Object[] { "setDiscardingThreshold", new Class<?>[] { int.class }, discardingThreshold }); args.add(new Object[] {"setDiscardingThreshold", new Class<?>[] {int.class}, discardingThreshold});
} }
activateAsync(args); activateAsync(args);

View File

@ -29,10 +29,10 @@ import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
/** /**
* ActivateOption的Logback 0.9.19及后续版本的实现 * ActivateOption的Logback 0.9.19及后续版本的实现
* *
* @author zhuyong 2014年3月20日 上午10:24:58 * @author zhuyong 2014年3月20日 上午10:24:58
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({"rawtypes", "unchecked"})
public class LogbackActivateOption extends Logback918ActivateOption { public class LogbackActivateOption extends Logback918ActivateOption {
public LogbackActivateOption(Object logger) { public LogbackActivateOption(Object logger) {

View File

@ -20,10 +20,11 @@ import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.LogbackException; import ch.qos.logback.core.LogbackException;
/** /**
* Logback Context Util * Logback Context Util
* @author Nacos
* *
* @author Nacos
*/ */
public class LogbackLoggerContextUtil { public class LogbackLoggerContextUtil {
@ -35,11 +36,11 @@ public class LogbackLoggerContextUtil {
if (!(lcObject instanceof LoggerContext)) { if (!(lcObject instanceof LoggerContext)) {
throw new LogbackException( throw new LogbackException(
"Expected LOGBACK binding with SLF4J, but another log system has taken the place: " "Expected LOGBACK binding with SLF4J, but another log system has taken the place: "
+ lcObject.getClass().getSimpleName()); + lcObject.getClass().getSimpleName());
} }
loggerContext = (LoggerContext) lcObject; loggerContext = (LoggerContext)lcObject;
} }
return loggerContext; return loggerContext;

View File

@ -41,7 +41,8 @@ public class Slf4jLog4j2AdapterActivateOption extends Log4j2ActivateOption {
super(null); super(null);
try { try {
org.apache.logging.log4j.core.Logger log4j2Logger = (org.apache.logging.log4j.core.Logger) loggerField.get(logger); org.apache.logging.log4j.core.Logger log4j2Logger = (org.apache.logging.log4j.core.Logger)loggerField.get(
logger);
super.logger = log4j2Logger; super.logger = log4j2Logger;
super.configuration = super.logger.getContext().getConfiguration(); super.configuration = super.logger.getContext().getConfiguration();
} catch (Exception e) { } catch (Exception e) {
@ -54,12 +55,13 @@ public class Slf4jLog4j2AdapterActivateOption extends Log4j2ActivateOption {
public void activateAppender(Logger logger) { public void activateAppender(Logger logger) {
if (!(logger.getDelegate() instanceof org.apache.logging.slf4j.Log4jLogger)) { if (!(logger.getDelegate() instanceof org.apache.logging.slf4j.Log4jLogger)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"logger must be org.apache.logging.slf4j.Log4jLogger, but it's " "logger must be org.apache.logging.slf4j.Log4jLogger, but it's "
+ logger.getDelegate().getClass()); + logger.getDelegate().getClass());
} }
try { try {
org.apache.logging.log4j.core.Logger log4j2Logger = (org.apache.logging.log4j.core.Logger) loggerField.get(logger.getDelegate()); org.apache.logging.log4j.core.Logger log4j2Logger = (org.apache.logging.log4j.core.Logger)loggerField.get(
logger.getDelegate());
super.activateAppender(log4j2Logger); super.activateAppender(log4j2Logger);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("activateAppender error, ", e); throw new RuntimeException("activateAppender error, ", e);

View File

@ -66,7 +66,7 @@ public class Slf4jLogger extends LoggerSupport implements Logger {
} }
try { try {
Class<ActivateOption> clazz = (Class<ActivateOption>) Class.forName(activateOptionClass); Class<ActivateOption> clazz = (Class<ActivateOption>)Class.forName(activateOptionClass);
Constructor<ActivateOption> c = clazz.getConstructor(Object.class); Constructor<ActivateOption> c = clazz.getConstructor(Object.class);
this.activateOption = c.newInstance(delegate); this.activateOption = c.newInstance(delegate);
} catch (Exception e) { } catch (Exception e) {

View File

@ -15,15 +15,15 @@
*/ */
package com.alibaba.nacos.client.logger.slf4j; package com.alibaba.nacos.client.logger.slf4j;
import com.alibaba.nacos.client.logger.Logger; import com.alibaba.nacos.client.logger.Logger;
import com.alibaba.nacos.client.logger.nop.NopLogger; import com.alibaba.nacos.client.logger.nop.NopLogger;
import com.alibaba.nacos.client.logger.support.ILoggerFactory; import com.alibaba.nacos.client.logger.support.ILoggerFactory;
import com.alibaba.nacos.client.logger.support.LogLog; import com.alibaba.nacos.client.logger.support.LogLog;
/** /**
* Slf4jLogger Factory * Slf4jLogger Factory
* @author Nacos
* *
* @author Nacos
*/ */
public class Slf4jLoggerFactory implements ILoggerFactory { public class Slf4jLoggerFactory implements ILoggerFactory {

View File

@ -27,7 +27,7 @@ public class AppenderInfo extends HashMap {
private static String file = "file"; private static String file = "file";
public String getName() { public String getName() {
return (String) get(AppenderInfo.name); return (String)get(AppenderInfo.name);
} }
public void setName(String name) { public void setName(String name) {

View File

@ -24,7 +24,7 @@ package com.alibaba.nacos.client.logger.support;
/** /**
* 兼容老的ErrorLog后续请使用{@link LoggerHelper} * 兼容老的ErrorLog后续请使用{@link LoggerHelper}
* *
* @author zhuyong 2014年7月1日 上午11:41:22 * @author zhuyong 2014年7月1日 上午11:41:22
*/ */
public class ErrorLog { public class ErrorLog {

View File

@ -19,26 +19,23 @@ import com.alibaba.nacos.client.logger.Logger;
/** /**
* logger factory interface * logger factory interface
*
* @author Nacos
* *
* @author Nacos
*/ */
public interface ILoggerFactory { public interface ILoggerFactory {
/** /**
* get logger * get logger
* *
* @param clazz * @param clazz class
* class * @return logger
* @return logger */
*/ Logger getLogger(Class<?> clazz);
Logger getLogger(Class<?> clazz);
/** /**
* get logger * get logger
* *
* @param name * @param name logger name
* logger name * @return logger
* @return logger */
*/ Logger getLogger(String name);
Logger getLogger(String name);
} }

View File

@ -33,10 +33,11 @@ package com.alibaba.nacos.client.logger.support;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.Calendar; import java.util.Calendar;
/** /**
* logger log * logger log
* @author Nacos
* *
* @author Nacos
*/ */
public class LogLog { public class LogLog {

View File

@ -60,7 +60,9 @@ public class LogbackHelper {
ILoggerFactory lc = org.slf4j.LoggerFactory.getILoggerFactory(); ILoggerFactory lc = org.slf4j.LoggerFactory.getILoggerFactory();
if (!(lc instanceof LoggerContext)) { if (!(lc instanceof LoggerContext)) {
LogLog.warn("expected logback binding with SLF4J, but another log system has taken the place: " + lcObject.getClass().getSimpleName()); LogLog.warn(
"expected logback binding with SLF4J, but another log system has taken the place: " + lcObject
.getClass().getSimpleName());
} else { } else {
lcObject = lc; lcObject = lc;
@ -77,6 +79,7 @@ public class LogbackHelper {
LogLog.error("failed to init LogbackHelper, " + t.getMessage()); LogLog.error("failed to init LogbackHelper, " + t.getMessage());
} }
} }
@SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL") @SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL")
public static Boolean setDepth(int depth) { public static Boolean setDepth(int depth) {
if (Logback) { if (Logback) {
@ -84,7 +87,7 @@ public class LogbackHelper {
depth = Integer.MAX_VALUE; depth = Integer.MAX_VALUE;
} }
try { try {
LoggerContext loggerContext = (LoggerContext) lcObject; LoggerContext loggerContext = (LoggerContext)lcObject;
List<Logger> loggers = loggerContext.getLoggerList(); List<Logger> loggers = loggerContext.getLoggerList();
for (ch.qos.logback.classic.Logger logger : loggers) { for (ch.qos.logback.classic.Logger logger : loggers) {
@ -100,12 +103,13 @@ public class LogbackHelper {
} }
return null; return null;
} }
@SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL") @SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL")
public static Boolean changeLevel(String name, String level) { public static Boolean changeLevel(String name, String level) {
if (Logback) { if (Logback) {
try { try {
Level l = Level.toLevel(level, Level.ERROR); Level l = Level.toLevel(level, Level.ERROR);
LoggerContext loggerContext = (LoggerContext) lcObject; LoggerContext loggerContext = (LoggerContext)lcObject;
Logger logger = loggerContext.exists(name); Logger logger = loggerContext.exists(name);
if (logger != null) { if (logger != null) {
@ -126,7 +130,7 @@ public class LogbackHelper {
Map<String, LoggerInfo> appenders = new HashMap<String, LoggerInfo>(10); Map<String, LoggerInfo> appenders = new HashMap<String, LoggerInfo>(10);
if (Logback) { if (Logback) {
LoggerContext loggerContext = (LoggerContext) lcObject; LoggerContext loggerContext = (LoggerContext)lcObject;
if (name != null && !"".equals(name.trim())) { if (name != null && !"".equals(name.trim())) {
Logger logger = loggerContext.exists(name); Logger logger = loggerContext.exists(name);
if (logger != null) { if (logger != null) {
@ -148,24 +152,24 @@ public class LogbackHelper {
} }
private static void doSetDepth(Iterator<Appender<ILoggingEvent>> iter, int depth) private static void doSetDepth(Iterator<Appender<ILoggingEvent>> iter, int depth)
throws IllegalAccessException { throws IllegalAccessException {
while (iter.hasNext()) { while (iter.hasNext()) {
Appender<ILoggingEvent> a = iter.next(); Appender<ILoggingEvent> a = iter.next();
if (a instanceof AsyncAppenderBase) { if (a instanceof AsyncAppenderBase) {
Iterator<Appender<ILoggingEvent>> aiter = ((AsyncAppenderBase) a).iteratorForAppenders(); Iterator<Appender<ILoggingEvent>> aiter = ((AsyncAppenderBase)a).iteratorForAppenders();
doSetDepth(aiter, depth); doSetDepth(aiter, depth);
} else if (a instanceof OutputStreamAppender) { } else if (a instanceof OutputStreamAppender) {
OutputStreamAppender oa = (OutputStreamAppender) a; OutputStreamAppender oa = (OutputStreamAppender)a;
Encoder e = oa.getEncoder(); Encoder e = oa.getEncoder();
Layout l = null; Layout l = null;
if (e instanceof PatternLayoutEncoder) { if (e instanceof PatternLayoutEncoder) {
l = ((PatternLayoutEncoder) e).getLayout(); l = ((PatternLayoutEncoder)e).getLayout();
} else if (e instanceof LayoutWrappingEncoder) { } else if (e instanceof LayoutWrappingEncoder) {
l = ((LayoutWrappingEncoder) e).getLayout(); l = ((LayoutWrappingEncoder)e).getLayout();
} }
if (l != null) { if (l != null) {
if (l instanceof PatternLayoutBase) { if (l instanceof PatternLayoutBase) {
Converter c = (Converter) f.get(l); Converter c = (Converter)f.get(l);
while (c != null) { while (c != null) {
if (c instanceof ThrowableProxyConverter) { if (c instanceof ThrowableProxyConverter) {
f1.set(c, depth); f1.set(c, depth);
@ -183,10 +187,10 @@ public class LogbackHelper {
LoggerInfo info = new LoggerInfo(logger.getName(), logger.isAdditive()); LoggerInfo info = new LoggerInfo(logger.getName(), logger.isAdditive());
Level level = logger.getLevel(), effectiveLevel = logger.getEffectiveLevel(); Level level = logger.getLevel(), effectiveLevel = logger.getEffectiveLevel();
if (level != null) { if (level != null) {
info.setLevel(level.toString()); info.setLevel(level.toString());
} }
if (effectiveLevel != null) { if (effectiveLevel != null) {
info.setEffectiveLevel(effectiveLevel.toString()); info.setEffectiveLevel(effectiveLevel.toString());
} }
List<AppenderInfo> result = doGetLoggerAppenders(logger.iteratorForAppenders()); List<AppenderInfo> result = doGetLoggerAppenders(logger.iteratorForAppenders());
@ -203,9 +207,9 @@ public class LogbackHelper {
info.setName(appender.getName()); info.setName(appender.getName());
info.setType(appender.getClass().getName()); info.setType(appender.getClass().getName());
if (appender instanceof FileAppender) { if (appender instanceof FileAppender) {
info.setFile(((FileAppender) appender).getFile()); info.setFile(((FileAppender)appender).getFile());
} else if (appender instanceof AsyncAppender) { } else if (appender instanceof AsyncAppender) {
AsyncAppender aa = (AsyncAppender) appender; AsyncAppender aa = (AsyncAppender)appender;
Iterator<Appender<ILoggingEvent>> iter = aa.iteratorForAppenders(); Iterator<Appender<ILoggingEvent>> iter = aa.iteratorForAppenders();
List<AppenderInfo> asyncs = doGetLoggerAppenders(iter); List<AppenderInfo> asyncs = doGetLoggerAppenders(iter);
// 标明异步appender // 标明异步appender
@ -216,7 +220,7 @@ public class LogbackHelper {
} }
info.withDetail("nestedNames", nestedNames); info.withDetail("nestedNames", nestedNames);
} else if (appender instanceof ConsoleAppender) { } else if (appender instanceof ConsoleAppender) {
info.withDetail("target", ((ConsoleAppender) appender).getTarget()); info.withDetail("target", ((ConsoleAppender)appender).getTarget());
} }
result.add(info); result.add(info);
} }

View File

@ -31,20 +31,20 @@ import com.alibaba.nacos.client.logger.Logger;
/** /**
* logger help * logger help
* @author Nacos
* *
* @author Nacos
*/ */
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule") @SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class LoggerHelper { public abstract class LoggerHelper {
private static final String MORE_URL_POSFIX = ".ERROR_CODE_MORE_URL"; private static final String MORE_URL_POSFIX = ".ERROR_CODE_MORE_URL";
private static final String DEFAULT_MORE_URL = "http://console.taobao.net/help/"; private static final String DEFAULT_MORE_URL = "http://console.taobao.net/help/";
private static String LOG_PATH = null; private static String LOG_PATH = null;
private static final String CONVERSION_PATTERN = "01 %d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n"; private static final String CONVERSION_PATTERN = "01 %d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n";
private static Map<String, Boolean> Product_Logger_Info; private static Map<String, Boolean> Product_Logger_Info;
private static Map<String, String> Product_Logger_Pattern; private static Map<String, String> Product_Logger_Pattern;
private static Map<String, ResourceBundle> Product_Resource_Bundle; private static Map<String, ResourceBundle> Product_Resource_Bundle;
@ -55,7 +55,7 @@ public abstract class LoggerHelper {
LOG_PATH = defaultPath + File.separator + "logs" + File.separator; LOG_PATH = defaultPath + File.separator + "logs" + File.separator;
} else { } else {
if (!new File(dpath).isAbsolute()) { if (!new File(dpath).isAbsolute()) {
// throw new RuntimeException("-DJM.LOG.PATH must be an absolute path."); // throw new RuntimeException("-DJM.LOG.PATH must be an absolute path.");
String defaultPath = System.getProperty("user.home"); String defaultPath = System.getProperty("user.home");
dpath = defaultPath + File.separator + dpath; dpath = defaultPath + File.separator + dpath;
} }
@ -83,15 +83,15 @@ public abstract class LoggerHelper {
/** /**
* <pre> * <pre>
* 获取中间件产品日志路径 * 获取中间件产品日志路径
* *
* 优先使用-DJM.LOG.PATH参数且必须是绝对路径 * 优先使用-DJM.LOG.PATH参数且必须是绝对路径
* 其次是{user.home}/logs/ * 其次是{user.home}/logs/
* *
* 比如hsf调用LoggerHelper.getLogFile("hsf", "hsf.log")则返回{user.home}/logs/hsf/hsf.log * 比如hsf调用LoggerHelper.getLogFile("hsf", "hsf.log")则返回{user.home}/logs/hsf/hsf.log
* </pre> * </pre>
* *
* @param productName 中间件产品名如hsf, tddl * @param productName 中间件产品名如hsf, tddl
* @param fileName 日志文件名如hsf.log如需要二级子目录可以传 subDir + File.separator + *.log * @param fileName 日志文件名如hsf.log如需要二级子目录可以传 subDir + File.separator + *.log
*/ */
public static String getLogFile(String productName, String fileName) { public static String getLogFile(String productName, String fileName) {
String file = LOG_PATH + productName + File.separator + fileName; String file = LOG_PATH + productName + File.separator + fileName;
@ -125,9 +125,9 @@ public abstract class LoggerHelper {
/** /**
* 设置特定中间件产品的日志格式注意这里的格式需要自己保证在 log4j/logback 下都兼容框架不做校验同时控制台输出仍会采用中间件的特定格式 * 设置特定中间件产品的日志格式注意这里的格式需要自己保证在 log4j/logback 下都兼容框架不做校验同时控制台输出仍会采用中间件的特定格式
* *
* @param productName 中间件产品名如hsf, tddl * @param productName 中间件产品名如hsf, tddl
* @param pattern 日志格式 * @param pattern 日志格式
*/ */
public static void setPattern(String productName, String pattern) { public static void setPattern(String productName, String pattern) {
Product_Logger_Pattern.put(productName, pattern); Product_Logger_Pattern.put(productName, pattern);
@ -137,7 +137,7 @@ public abstract class LoggerHelper {
* 设置产品的日志国际化properties文件 * 设置产品的日志国际化properties文件
* *
* @param productName 中间件产品名如hsf, tddl * @param productName 中间件产品名如hsf, tddl
* @param bundleName bundleName * @param bundleName bundleName
*/ */
public static void setResourceBundle(String productName, String bundleName) { public static void setResourceBundle(String productName, String bundleName) {
try { try {
@ -152,7 +152,7 @@ public abstract class LoggerHelper {
* 获取国际化的message如果找不到则返回原始的code * 获取国际化的message如果找不到则返回原始的code
* *
* @param productName 中间件产品名如hsf, tddl * @param productName 中间件产品名如hsf, tddl
* @param code code * @param code code
*/ */
public static String getResourceBundleString(String productName, String code) { public static String getResourceBundleString(String productName, String code) {
if (Product_Resource_Bundle.isEmpty() || code == null || productName == null) { if (Product_Resource_Bundle.isEmpty() || code == null || productName == null) {
@ -174,7 +174,7 @@ public abstract class LoggerHelper {
/** /**
* 获取统一格式的ErrorCode输出 * 获取统一格式的ErrorCode输出
* *
* @param errorCode * @param errorCode
*/ */
@Deprecated @Deprecated
@ -184,11 +184,11 @@ public abstract class LoggerHelper {
/** /**
* 根据productName获取统一格式的ErrorCode输出 * 根据productName获取统一格式的ErrorCode输出
* *
* @param productName HSF会根据 HSF.ErrorCodeMoreUrl System属性中获取 more url 前缀如http://console.taobao.net/jm/ * @param productName HSF会根据 HSF.ErrorCodeMoreUrl System属性中获取 more url 前缀如http://console.taobao.net/jm/
* @param errorCode 错误码如HSF-001 * @param errorCode 错误码如HSF-001
* @param errorType 错误类型 * @param errorType 错误类型
* @param message 出错异常信息 * @param message 出错异常信息
*/ */
public static String getErrorCodeStr(String productName, String errorCode, String errorType, String message) { public static String getErrorCodeStr(String productName, String errorCode, String errorType, String message) {
String moreUrl = DEFAULT_MORE_URL; String moreUrl = DEFAULT_MORE_URL;
@ -214,18 +214,17 @@ public abstract class LoggerHelper {
return sb.toString(); return sb.toString();
} }
@SuppressFBWarnings(value = { "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE" }) @SuppressFBWarnings(value = {"RV_RETURN_VALUE_IGNORED_BAD_PRACTICE"})
public static String getLogFileP(String productName, String fileName) { public static String getLogFileP(String productName, String fileName) {
String file = getLogFile(productName, fileName); String file = getLogFile(productName, fileName);
File logfile = new File(file); File logfile = new File(file);
logfile.getParentFile().mkdirs(); logfile.getParentFile().mkdirs();
return file; return file;
} }
/** /**
* When prudent is set to true, file appenders from multiple JVMs can safely * When prudent is set to true, file appenders from multiple JVMs can safely write to the same file.
* write to the same file. * <p>
*
* Only support by logback * Only support by logback
* *
* @param prudent * @param prudent
@ -235,14 +234,15 @@ public abstract class LoggerHelper {
if (logger != null && logger.getDelegate() != null) { if (logger != null && logger.getDelegate() != null) {
if (!(logger.getDelegate() instanceof ch.qos.logback.classic.Logger)) { if (!(logger.getDelegate() instanceof ch.qos.logback.classic.Logger)) {
throw new IllegalArgumentException("logger must be ch.qos.logback.classic.Logger, but it's " throw new IllegalArgumentException("logger must be ch.qos.logback.classic.Logger, but it's "
+ logger.getDelegate().getClass()); + logger.getDelegate().getClass());
} }
Iterator<Appender<ILoggingEvent>> iter = ((ch.qos.logback.classic.Logger) logger.getDelegate()).iteratorForAppenders(); Iterator<Appender<ILoggingEvent>> iter = ((ch.qos.logback.classic.Logger)logger.getDelegate())
.iteratorForAppenders();
while (iter.hasNext()) { while (iter.hasNext()) {
ch.qos.logback.core.Appender<ILoggingEvent> appender = iter.next(); ch.qos.logback.core.Appender<ILoggingEvent> appender = iter.next();
if (appender instanceof FileAppender) { if (appender instanceof FileAppender) {
((FileAppender) appender).setPrudent(prudent); ((FileAppender)appender).setPrudent(prudent);
} else { } else {
continue; continue;
} }

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