Merge pull request #5 from alibaba/master

sync the newest code
This commit is contained in:
jifengnan 2019-03-27 19:13:21 +08:00 committed by GitHub
commit 95009390e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
260 changed files with 12774 additions and 8853 deletions

View File

@ -1,3 +1,36 @@
## 1.0.0-RC2(Mar 22, 2019)
* [#923] Nacos 1.0.0 compatible with nacos-client 0.6.2
* [#938] Client beat processor task lost
* [#946] Change default server mode to AP
## 1.0.0-RC1(Mar 15, 2019)
* [#870] About Nacos's namespace and tenant design
* [#869] Client exception message is confusing
* [#866] BeatInfo scheduled property may have the memory visibility issue
* [#865] checksum value is not correct
* [#839] Refactor API URLs
* [#811] ApiCommands.updateIpPublish countDownLatch timeout issue
* [#809] Instance field 'valid' should be deprecated and replaced by 'healthy'
* [#803] Nacos front-end function regression plan and landing
* [#801] Nacos uses nignx as a best practice article for current limiting.
* [#757] The word 'domain' should be replaced by 'service'
* [#745] Support server running mode in CP, AP or mixed
* [#744] The exact status of server should be stored and controlled
* [#725] Will the nacos registry be how to do multi-environment deployment?
* [#677] Support ephemeral instances and persistent instances
* [#651] Remove old API entry 'APICommands'
* [#650] Refactor server list management to make it irrelevant to consistency protocol
* [#634] Add global push enable switch and data query enable switch
* [#629] Server data needs warm up before open traffic
* [#502] Registering ephemeral instance as well as persistent instances
* [#501] Health check mode confict when building muilt clusters whit nacos sync + nacos
* [#479] Metadata should be displayed and edited using standard property syntax
* [#327] Inform the ACM SDK of the RAM role name and access the configuration ? ?
* [#269] need to support service group in naming module
## 0.9.0(Feb 28, 2019)
* [#840] Nacos server adds startup mode to distinguish between config and naming.

View File

@ -143,6 +143,26 @@ These are only part of the companies using Nacos, for reference only. If you are
![云帐房](http://www.yunzhangfang.com/yzf-pc/img/logo.png)
![知氏教育](https://www.chyeth.com/622e88980a5d091eaa6449f82d48ca43.png)
![中化信息](http://www.sinochem.com/Portals/0/xinlogo.png)
![一点车](https://img.alicdn.com/tfs/TB1DXerNgDqK1RjSZSyXXaxEVXa-333-103.png)
![明传无线](https://img.alicdn.com/tfs/TB1VfOANgHqK1RjSZFPXXcwapXa-313-40.png)
![妙优车](https://img.alicdn.com/tfs/TB1lvCyNhTpK1RjSZFMXXbG_VXa-130-60.png)
![蜂巢](https://img.alicdn.com/tfs/TB1kY9qNgTqK1RjSZPhXXXfOFXa-120-50.png)
![华存数据](https://img.alicdn.com/tfs/TB1G.GBNbrpK1RjSZTEXXcWAVXa-234-65.png)
![数云](https://img.alicdn.com/tfs/TB1qsurNgDqK1RjSZSyXXaxEVXa-300-90.png)
![广通软件](https://img.alicdn.com/tfs/TB13aywNhTpK1RjSZR0XXbEwXXa-98-38.png)
![菜菜](https://img.alicdn.com/tfs/TB1xqmBNjTpK1RjSZKPXXa3UpXa-162-70.png)
![科蓝公司](https://img.alicdn.com/tfs/TB18DmINcfpK1RjSZFOXXa6nFXa-200-200.png)
![浩鲸](https://img.alicdn.com/tfs/TB15uqANXzqK1RjSZFoXXbfcXXa-188-86.png)
![未名天日语](https://img.alicdn.com/tfs/TB1mvmyNkvoK1RjSZPfXXXPKFXa-238-46.png)
![金联创](https://img.alicdn.com/tfs/TB1PSWsNmrqK1RjSZK9XXXyypXa-195-130.jpg)
![同窗链](https://img.alicdn.com/tfs/TB1k1qzNbvpK1RjSZFqXXcXUVXa-160-69.png)
![顺能](https://img.alicdn.com/tfs/TB1HdyvNmzqK1RjSZFLXXcn2XXa-143-143.jpg)
![百世快递](https://img.alicdn.com/tfs/TB1UdaGNgHqK1RjSZJnXXbNLpXa-277-62.png)
![汽车之家](https://img.alicdn.com/tfs/TB17OqENbrpK1RjSZTEXXcWAVXa-240-113.jpg)
![鲸打卡](https://img.alicdn.com/tfs/TB1q71ANkvoK1RjSZPfXXXPKFXa-257-104.png)
![时代光华](https://img.alicdn.com/tfs/TB1UzuyNhTpK1RjSZR0XXbEwXXa-201-86.jpg)
![康美](https://img.alicdn.com/tfs/TB19RCANgHqK1RjSZFPXXcwapXa-180-180.jpg)
![环球易购](https://img.alicdn.com/tfs/TB1iCGyNb2pK1RjSZFsXXaNlXXa-143-143.jpg)
![海格管家](https://img.alicdn.com/tfs/TB1FNq4EwHqK1RjSZFgXXa7JXXa-232-232.jpg)
![Nepxion](https://avatars0.githubusercontent.com/u/16344119?s=200&v=4)
![东莞最佳拍档](https://img.alicdn.com/tfs/TB11ugsDzTpK1RjSZKPXXa3UpXa-300-300.png)
@ -152,3 +172,4 @@ These are only part of the companies using Nacos, for reference only. If you are
![联合永道](https://img.alicdn.com/tfs/TB1CRAxDxYaK1RjSZFnXXa80pXa-190-190.jpg)
![明源云](https://img.alicdn.com/tfs/TB1.q14ErrpK1RjSZTEXXcWAVXa-219-219.jpg)

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.9.0</version>
<version>1.0.0-RC2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -24,6 +24,8 @@ public class PropertyKeyConst {
public final static String ENDPOINT = "endpoint";
public final static String ENDPOINT_PORT = "endpointPort";
public final static String NAMESPACE = "namespace";
public final static String ACCESS_KEY = "accessKey";
@ -39,7 +41,17 @@ public class PropertyKeyConst {
public final static String ENCODE = "encode";
public final static String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart";
public final static String NAMING_CLIENT_BEAT_THREAD_COUNT = "namingClientBeatThreadCount";
public final static String NAMING_POLLING_THREAD_COUNT = "namingPollingThreadCount";
public static class SystemEnv {
public static final String ALIBABA_ALIWARE_ENDPOINT_PORT = "ALIBABA_ALIWARE_ENDPOINT_PORT";
public static final String ALIBABA_ALIWARE_NAMESPACE = "ALIBABA_ALIWARE_NAMESPACE";
public static final String ALIBABA_ALIWARE_ENDPOINT_URL = "ALIBABA_ALIWARE_ENDPOINT_URL";
}
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.api;
/**
* Properties that are preferred to which in {@link PropertyKeyConst}
*
* @author pbting
* @date 2019-02-22 3:38 PM
*/
public interface SystemPropertyKeyConst {
String NAMING_SERVER_PORT = "nacos.naming.exposed.port";
String NAMING_WEB_CONTEXT = "nacos.naming.web.context";
String NACOS_NAMING_REQUEST_MODULE = "nacos.naming.request.module";
}

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.api.cmdb.pojo;
import java.util.Map;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public class Entity {

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.api.cmdb.pojo;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public class EntityEvent {

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.api.cmdb.pojo;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public enum EntityEventType {

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.api.cmdb.pojo;
import java.util.Set;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public class Label {

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.api.cmdb.pojo;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public enum PreservedEntityTypes {

View File

@ -26,7 +26,7 @@ import java.util.Set;
/**
* Service to visit CMDB store
*
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public interface CmdbService {

View File

@ -22,8 +22,6 @@ package com.alibaba.nacos.api.common;
*/
public class Constants {
public static final String CLIENT_VERSION_HEADER = "Client-Version";
public static final String CLIENT_VERSION = "3.0.0";
public static int DATA_IN_BODY_VERSION = 204;
@ -121,11 +119,13 @@ public class Constants {
public static final int NAMING_INSTANCE_ID_SEG_COUNT = 4;
public static final String NAMING_HTTP_HEADER_SPILIER = "\\|";
public static final String NAMING_DEFAULT_CLUSTER_NAME = "DEFAULT";
public static final String DEFAULT_CLUSTER_NAME = "DEFAULT";
public static final String REQUEST_PARAM_NAMESPACE_ID = "namespaceId";
public static final String REQUEST_PARAM_DEFAULT_NAMESPACE_ID = "public";
public static final String REQUEST_PARAM_SERVICE_NAME = "serviceName";
public static final String REQUEST_PARAM_GROUP = "group";
public static final String REQUEST_PARAM_DEFAULT_GROUP = "DEFAULT_GROUP";
public static final String DEFAULT_NAMESPACE_ID = "public";
public static final int WRITE_REDIRECT_CODE = 307;
public static final String SERVICE_INFO_SPLITER = "@@";
public static final String NULL_STRING = "null";
}

View File

@ -35,6 +35,7 @@ public class NacosException extends Exception {
}
public NacosException(int errCode, String errMsg) {
super(errMsg);
this.errCode = errCode;
this.errMsg = errMsg;
}

View File

@ -1,36 +1,34 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.api.naming;
/**
* Common parameters for service discovery
*
* @author nkorange
* @since 1.0.0
*/
public class CommonParams {
public static final String SERVICE_NAME = "serviceName";
public static final String CLUSTER_NAME = "clusterName";
public static final String NAMESPACE_ID = "namespaceId";
public static final String GROUP_NAME = "groupName";
{
"editor.tabSize": 2,
"editor.formatOnSave": true,
"[javascript]": {
"editor.formatOnSave": true,
"editor.formatOnPaste": false
},
"[javascriptreact]": {
"editor.formatOnSave": true,
"editor.formatOnPaste": false
},
"[typescript]": {
"editor.formatOnSave": true,
"editor.formatOnPaste": false
},
"[typescriptreact]": {
"editor.formatOnSave": true,
"editor.formatOnPaste": false
},
"[html]": {
"editor.formatOnSave": false
}
}

View File

@ -23,7 +23,7 @@ import com.alibaba.nacos.api.exception.NacosException;
/**
* Naming Factory
*
* @author dungu.zpf
* @author nkorange
*/
public class NamingFactory {

View File

@ -27,7 +27,7 @@ import java.util.List;
/**
* Naming Service
*
* @author dungu.zpf
* @author nkorange
*/
public interface NamingService {
@ -41,6 +41,17 @@ public interface NamingService {
*/
void registerInstance(String serviceName, String ip, int port) throws NacosException;
/**
* register a instance to service
*
* @param serviceName name of service
* @param groupName group of service
* @param ip instance ip
* @param port instance port
* @throws NacosException
*/
void registerInstance(String serviceName, String groupName, String ip, int port) throws NacosException;
/**
* register a instance to service with specified cluster name
*
@ -52,6 +63,18 @@ public interface NamingService {
*/
void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;
/**
* register a instance to service with specified cluster name
*
* @param serviceName name of service
* @param groupName group of service
* @param ip instance ip
* @param port instance port
* @param clusterName instance cluster name
* @throws NacosException
*/
void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException;
/**
* register a instance to service with specified instance properties
*
@ -61,6 +84,16 @@ public interface NamingService {
*/
void registerInstance(String serviceName, Instance instance) throws NacosException;
/**
* register a instance to service with specified instance properties
*
* @param serviceName name of service
* @param groupName group of service
* @param instance instance to register
* @throws NacosException
*/
void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException;
/**
* deregister instance from a service
*
@ -71,6 +104,17 @@ public interface NamingService {
*/
void deregisterInstance(String serviceName, String ip, int port) throws NacosException;
/**
* deregister instance from a service
*
* @param serviceName name of service
* @param groupName group of service
* @param ip instance ip
* @param port instance port
* @throws NacosException
*/
void deregisterInstance(String serviceName, String groupName, String ip, int port) throws NacosException;
/**
* deregister instance with specified cluster name from a service
*
@ -82,6 +126,18 @@ public interface NamingService {
*/
void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;
/**
* deregister instance with specified cluster name from a service
*
* @param serviceName name of service
* @param groupName group of service
* @param ip instance ip
* @param port instance port
* @param clusterName instance cluster name
* @throws NacosException
*/
void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException;
/**
* get all instances of a service
*
@ -91,6 +147,16 @@ public interface NamingService {
*/
List<Instance> getAllInstances(String serviceName) throws NacosException;
/**
* get all instances of a service
*
* @param serviceName name of service
* @param groupName group of service
* @return A list of instance
* @throws NacosException
*/
List<Instance> getAllInstances(String serviceName, String groupName) throws NacosException;
/**
* Get all instances of a service
*
@ -101,6 +167,17 @@ public interface NamingService {
*/
List<Instance> getAllInstances(String serviceName, boolean subscribe) throws NacosException;
/**
* Get all instances of a service
*
* @param serviceName name of service
* @param groupName group of service
* @param subscribe if subscribe the service
* @return A list of instance
* @throws NacosException
*/
List<Instance> getAllInstances(String serviceName, String groupName, boolean subscribe) throws NacosException;
/**
* Get all instances within specified clusters of a service
*
@ -111,6 +188,17 @@ public interface NamingService {
*/
List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException;
/**
* Get all instances within specified clusters of a service
*
* @param serviceName name of service
* @param groupName group of service
* @param clusters list of cluster
* @return A list of qualified instance
* @throws NacosException
*/
List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters) throws NacosException;
/**
* Get all instances within specified clusters of a service
*
@ -122,6 +210,18 @@ public interface NamingService {
*/
List<Instance> getAllInstances(String serviceName, List<String> clusters, boolean subscribe) throws NacosException;
/**
* Get all instances within specified clusters of a service
*
* @param serviceName name of service
* @param groupName group of service
* @param clusters list of cluster
* @param subscribe if subscribe the service
* @return A list of qualified instance
* @throws NacosException
*/
List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException;
/**
* Get qualified instances of service
*
@ -132,6 +232,17 @@ public interface NamingService {
*/
List<Instance> selectInstances(String serviceName, boolean healthy) throws NacosException;
/**
* Get qualified instances of service
*
* @param serviceName name of service
* @param groupName group of service
* @param healthy a flag to indicate returning healthy or unhealthy instances
* @return A qualified list of instance
* @throws NacosException
*/
List<Instance> selectInstances(String serviceName, String groupName, boolean healthy) throws NacosException;
/**
* Get qualified instances of service
*
@ -143,6 +254,18 @@ public interface NamingService {
*/
List<Instance> selectInstances(String serviceName, boolean healthy, boolean subscribe) throws NacosException;
/**
* Get qualified instances of service
*
* @param serviceName name of service
* @param groupName group of service
* @param healthy a flag to indicate returning healthy or unhealthy instances
* @param subscribe if subscribe the service
* @return A qualified list of instance
* @throws NacosException
*/
List<Instance> selectInstances(String serviceName, String groupName, boolean healthy, boolean subscribe) throws NacosException;
/**
* Get qualified instances within specified clusters of service
*
@ -154,6 +277,18 @@ public interface NamingService {
*/
List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy) throws NacosException;
/**
* Get qualified instances within specified clusters of service
*
* @param serviceName name of service
* @param groupName group of service
* @param clusters list of cluster
* @param healthy a flag to indicate returning healthy or unhealthy instances
* @return A qualified list of instance
* @throws NacosException
*/
List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy) throws NacosException;
/**
* Get qualified instances within specified clusters of service
*
@ -166,6 +301,19 @@ public interface NamingService {
*/
List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy, boolean subscribe) throws NacosException;
/**
* Get qualified instances within specified clusters of service
*
* @param serviceName name of service
* @param groupName group of service
* @param clusters list of cluster
* @param healthy a flag to indicate returning healthy or unhealthy instances
* @param subscribe if subscribe the service
* @return A qualified list of instance
* @throws NacosException
*/
List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy, boolean subscribe) throws NacosException;
/**
* Select one healthy instance of service using predefined load balance strategy
*
@ -175,6 +323,16 @@ public interface NamingService {
*/
Instance selectOneHealthyInstance(String serviceName) throws NacosException;
/**
* Select one healthy instance of service using predefined load balance strategy
*
* @param serviceName name of service
* @param groupName group of service
* @return qualified instance
* @throws NacosException
*/
Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException;
/**
* select one healthy instance of service using predefined load balance strategy
*
@ -185,6 +343,17 @@ public interface NamingService {
*/
Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException;
/**
* select one healthy instance of service using predefined load balance strategy
*
* @param serviceName name of service
* @param groupName group of service
* @param subscribe if subscribe the service
* @return qualified instance
* @throws NacosException
*/
Instance selectOneHealthyInstance(String serviceName, String groupName, boolean subscribe) throws NacosException;
/**
* Select one healthy instance of service using predefined load balance strategy
*
@ -195,6 +364,17 @@ public interface NamingService {
*/
Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException;
/**
* Select one healthy instance of service using predefined load balance strategy
*
* @param serviceName name of service
* @param groupName group of service
* @param clusters a list of clusters should the instance belongs to
* @return qualified instance
* @throws NacosException
*/
Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters) throws NacosException;
/**
* Select one healthy instance of service using predefined load balance strategy
*
@ -206,6 +386,18 @@ public interface NamingService {
*/
Instance selectOneHealthyInstance(String serviceName, List<String> clusters, boolean subscribe) throws NacosException;
/**
* Select one healthy instance of service using predefined load balance strategy
*
* @param serviceName name of service
* @param groupName group of service
* @param clusters a list of clusters should the instance belongs to
* @param subscribe if subscribe the service
* @return qualified instance
* @throws NacosException
*/
Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException;
/**
* Subscribe service to receive events of instances alteration
*
@ -216,7 +408,17 @@ public interface NamingService {
void subscribe(String serviceName, EventListener listener) throws NacosException;
/**
* subscribe service to receive events of instances alteration
* Subscribe service to receive events of instances alteration
*
* @param serviceName name of service
* @param groupName group of service
* @param listener event listener
* @throws NacosException
*/
void subscribe(String serviceName, String groupName, EventListener listener) throws NacosException;
/**
* Subscribe service to receive events of instances alteration
*
* @param serviceName name of service
* @param clusters list of cluster
@ -226,7 +428,18 @@ public interface NamingService {
void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;
/**
* unsubscribe event listener of service
* Subscribe service to receive events of instances alteration
*
* @param serviceName name of service
* @param groupName group of service
* @param clusters list of cluster
* @param listener event listener
* @throws NacosException
*/
void subscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException;
/**
* Unsubscribe event listener of service
*
* @param serviceName name of service
* @param listener event listener
@ -238,6 +451,16 @@ public interface NamingService {
* unsubscribe event listener of service
*
* @param serviceName name of service
* @param groupName group of service
* @param listener event listener
* @throws NacosException
*/
void unsubscribe(String serviceName, String groupName, EventListener listener) throws NacosException;
/**
* Unsubscribe event listener of service
*
* @param serviceName name of service
* @param clusters list of cluster
* @param listener event listener
* @throws NacosException
@ -245,7 +468,18 @@ public interface NamingService {
void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;
/**
* get all service names from server
* Unsubscribe event listener of service
*
* @param serviceName name of service
* @param groupName group of service
* @param clusters list of cluster
* @param listener event listener
* @throws NacosException
*/
void unsubscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException;
/**
* Get all service names from server
*
* @param pageNo page index
* @param pageSize page size
@ -255,7 +489,18 @@ public interface NamingService {
ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException;
/**
* Get all subscribed services of current client
* Get all service names from server
*
* @param pageNo page index
* @param pageSize page size
* @param groupName group name
* @return list of service names
* @throws NacosException
*/
ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName) throws NacosException;
/**
* Get all service names from server with selector
*
* @param pageNo page index
* @param pageSize page size
@ -266,6 +511,18 @@ public interface NamingService {
*/
ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException;
/**
* Get all service names from server with selector
*
* @param pageNo page index
* @param pageSize page size
* @param groupName group name
* @param selector selector to filter the resource
* @return list of service names
* @throws NacosException
*/
ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException;
/**
* Get all subscribed services of current client
*

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.api.naming.listener;
/**
* Event Interface
*
* @author dungu.zpf
* @author nkorange
*/
public interface Event {
}

View File

@ -22,7 +22,7 @@ import com.alibaba.nacos.api.naming.pojo.Instance;
/**
* Naming Event
*
* @author dungu.zpf
* @author nkorange
*/
public class NamingEvent implements Event {

View File

@ -25,7 +25,7 @@ import java.util.Map;
import java.util.Objects;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public abstract class AbstractHealthChecker implements Cloneable {
@ -47,6 +47,20 @@ public abstract class AbstractHealthChecker implements Cloneable {
*/
public abstract AbstractHealthChecker clone() throws CloneNotSupportedException;
public static class None extends AbstractHealthChecker {
public static final String TYPE = "NONE";
public None() {
this.setType(TYPE);
}
@Override
public AbstractHealthChecker clone() throws CloneNotSupportedException {
return new None();
}
}
public static class Http extends AbstractHealthChecker {
public static final String TYPE = "HTTP";

View File

@ -21,7 +21,7 @@ import java.util.Map;
/**
* Cluster
*
* @author dungu.zpf
* @author nkorange
*/
public class Cluster {

View File

@ -24,7 +24,7 @@ import java.util.Map;
/**
* Instance
*
* @author dungu.zpf
* @author nkorange
*/
public class Instance {
@ -51,11 +51,20 @@ public class Instance {
/**
* instance health status
*/
@JSONField(name = "valid")
private boolean healthy = true;
/**
* If instance is enabled to accept request
*/
private boolean enabled = true;
/**
* If instance is ephemeral
*
* @since 1.0.0
*/
private boolean ephemeral = true;
/**
* cluster information of instance
*/
@ -147,6 +156,14 @@ public class Instance {
this.enabled = enabled;
}
public boolean isEphemeral() {
return ephemeral;
}
public void setEphemeral(boolean ephemeral) {
this.ephemeral = ephemeral;
}
@Override
public String toString() {
return JSON.toJSONString(this);
@ -162,7 +179,7 @@ public class Instance {
return false;
}
Instance host = (Instance)obj;
Instance host = (Instance) obj;
return strEquals(toString(), host.toString());
}

View File

@ -22,7 +22,7 @@ import java.util.List;
/**
* ListView
*
* @author dungu.zpf
* @author nkorange
*/
public class ListView<T> {

View File

@ -15,18 +15,20 @@
*/
package com.alibaba.nacos.api.naming.pojo;
import com.alibaba.nacos.api.selector.AbstractSelector;
import java.util.HashMap;
import java.util.Map;
/**
* Service
* Service of Nacos
* <p>
* We introduce a 'service --> cluster --> instance' model, in which service stores a list of clusters,
* which contains a list of instances.
* <p>
* Typically we put some unique properties between instances to service level.
*
* @author dungu.zpf
* @author nkorange
*/
public class Service {
/**
* service name
*/
@ -40,25 +42,18 @@ public class Service {
/**
* application name of this service
*/
private String app;
private String appName;
/**
* Service group which is meant to classify services into different sets.
* Service group to classify services into different sets.
*/
private String group;
/**
* Health check mode.
*/
private String healthCheckMode;
/**
* Selector name of this service
*/
private AbstractSelector selector;
private String groupName;
private Map<String, String> metadata = new HashMap<String, String>();
public Service() {
}
public Service(String name) {
this.name = name;
}
@ -71,14 +66,6 @@ public class Service {
this.name = name;
}
public String getHealthCheckMode() {
return healthCheckMode;
}
public void setHealthCheckMode(String healthCheckMode) {
this.healthCheckMode = healthCheckMode;
}
public float getProtectThreshold() {
return protectThreshold;
}
@ -87,20 +74,20 @@ public class Service {
this.protectThreshold = protectThreshold;
}
public String getApp() {
return app;
public String getAppName() {
return appName;
}
public void setApp(String app) {
this.app = app;
public void setAppName(String appName) {
this.appName = appName;
}
public String getGroup() {
return group;
public String getGroupName() {
return groupName;
}
public void setGroup(String group) {
this.group = group;
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public Map<String, String> getMetadata() {
@ -114,12 +101,4 @@ public class Service {
public void addMetadata(String key, String value) {
this.metadata.put(key, value);
}
public AbstractSelector getSelector() {
return selector;
}
public void setSelector(AbstractSelector selector) {
this.selector = selector;
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.api.naming.pojo;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.nacos.api.common.Constants;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@ -26,7 +27,7 @@ import java.util.List;
/**
* ServiceInfo
*
* @author dungu.zpf
* @author nkorange
*/
public class ServiceInfo {
@ -34,9 +35,10 @@ public class ServiceInfo {
private String jsonFromServer = EMPTY;
public static final String SPLITER = "@@";
@JSONField(name = "dom")
private String name;
private String groupName;
private String clusters;
private long cacheMillis = 1000L;
@ -67,7 +69,7 @@ public class ServiceInfo {
int clusterIndex = 1;
int serviceNameIndex = 0;
String[] keys = key.split(SPLITER);
String[] keys = key.split(Constants.SERVICE_INFO_SPLITER);
if (keys.length >= maxIndex) {
this.name = keys[serviceNameIndex];
this.clusters = keys[clusterIndex];
@ -105,6 +107,14 @@ public class ServiceInfo {
this.name = name;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public void setLastRefTime(long lastRefTime) {
this.lastRefTime = lastRefTime;
}
@ -178,13 +188,16 @@ public class ServiceInfo {
@JSONField(serialize = false)
public static ServiceInfo fromKey(String key) {
ServiceInfo serviceInfo = new ServiceInfo();
if (key.contains(SPLITER)) {
serviceInfo.setName(key.split(SPLITER)[0]);
serviceInfo.setClusters(key.split(SPLITER)[1]);
return serviceInfo;
int maxSegCount = 3;
String[] segs = key.split(Constants.SERVICE_INFO_SPLITER);
if (segs.length == maxSegCount -1) {
serviceInfo.setGroupName(segs[0]);
serviceInfo.setName(segs[1]);
} else if (segs.length == maxSegCount) {
serviceInfo.setGroupName(segs[0]);
serviceInfo.setName(segs[1]);
serviceInfo.setClusters(segs[2]);
}
serviceInfo.setName(key);
return serviceInfo;
}
@ -192,7 +205,7 @@ public class ServiceInfo {
public static String getKey(String name, String clusters) {
if (!isEmpty(clusters)) {
return name + SPLITER + clusters;
return name + Constants.SERVICE_INFO_SPLITER + clusters;
}
return name;

View File

@ -0,0 +1,43 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.api.naming.utils;
import com.alibaba.nacos.api.common.Constants;
/**
* @author nkorange
* @since 1.0.0
*/
public class NamingUtils {
public static String getGroupedName(String serviceName, String groupName) {
return groupName + Constants.SERVICE_INFO_SPLITER + serviceName;
}
public static String getServiceName(String serviceNameWithGroup) {
if (!serviceNameWithGroup.contains(Constants.SERVICE_INFO_SPLITER)) {
return serviceNameWithGroup;
}
return serviceNameWithGroup.split(Constants.SERVICE_INFO_SPLITER)[1];
}
public static String getGroupName(String serviceNameWithGroup) {
if (!serviceNameWithGroup.contains(Constants.SERVICE_INFO_SPLITER)) {
return Constants.DEFAULT_GROUP;
}
return serviceNameWithGroup.split(Constants.SERVICE_INFO_SPLITER)[0];
}
}

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.api.selector;
/**
* Abstract selector that only contains a type
*
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public abstract class AbstractSelector {

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.api.selector;
/**
* The selector to filter resource with flexible expression.
*
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public class ExpressionSelector extends AbstractSelector {

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.api.selector;
/**
* The types of selector accepted by Nacos
*
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public enum SelectorType {

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.9.0</version>
<version>1.0.0-RC2</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -26,7 +26,7 @@
<packaging>jar</packaging>
<name>nacos-client ${project.version}</name>
<url>http://maven.apache.org</url>
<url>https://github.com/alibaba/nacos</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@ -34,6 +34,7 @@ import com.alibaba.nacos.client.config.utils.ParamUtils;
import com.alibaba.nacos.client.config.utils.TenantUtil;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.client.utils.TemplateUtils;
import org.slf4j.Logger;
import java.io.IOException;
@ -42,6 +43,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Callable;
/**
* Config Impl
@ -73,19 +75,33 @@ public class NacosConfigService implements ConfigService {
} else {
encode = encodeTmp.trim();
}
String namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE);
if (StringUtils.isBlank(namespaceTmp)) {
namespace = TenantUtil.getUserTenant();
properties.put(PropertyKeyConst.NAMESPACE, namespace);
} else {
namespace = namespaceTmp;
properties.put(PropertyKeyConst.NAMESPACE, namespace);
}
initNamespace(properties);
agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
agent.start();
worker = new ClientWorker(agent, configFilterChainManager);
}
private void initNamespace(Properties properties) {
String namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE);
namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, new Callable<String>() {
@Override
public String call() {
return TenantUtil.getUserTenant();
}
});
namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, new Callable<String>() {
@Override
public String call() {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
return StringUtils.isNotBlank(namespace) ? namespace : "";
}
});
namespace = namespaceTmp;
properties.put(PropertyKeyConst.NAMESPACE, namespace);
}
@Override
public String getConfig(String dataId, String group, long timeoutMs) throws NacosException {
return getConfigInner(namespace, dataId, group, timeoutMs);

View File

@ -24,6 +24,7 @@ import com.alibaba.nacos.client.config.impl.ServerListManager;
import com.alibaba.nacos.client.config.impl.SpasAdapter;
import com.alibaba.nacos.client.config.utils.IOUtils;
import com.alibaba.nacos.client.identify.STSConfig;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.client.utils.JSONUtils;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
@ -41,6 +42,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Callable;
/**
* Server Agent
@ -197,29 +199,29 @@ public class ServerHttpAgent implements HttpAgent {
public ServerHttpAgent(ServerListManager mgr, Properties properties) {
serverListMgr = mgr;
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;
}
init(properties);
}
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);
init(properties);
}
private void init(Properties properties) {
initEncode(properties);
initAkSk(properties);
}
private void initEncode(Properties properties) {
encode = TemplateUtils.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.ENCODE), new Callable<String>() {
@Override
public String call() throws Exception {
return Constants.ENCODE;
}
});
}
private void initAkSk(Properties properties) {
String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
if (StringUtils.isBlank(ak)) {
accessKey = SpasAdapter.getAk();
@ -273,8 +275,9 @@ public class ServerHttpAgent implements HttpAgent {
}
}
String stsResponse = getSTSResponse();
STSCredential stsCredentialTmp = (STSCredential)JSONUtils.deserializeObject(stsResponse,
new TypeReference<STSCredential>() {});
STSCredential stsCredentialTmp = (STSCredential) JSONUtils.deserializeObject(stsResponse,
new TypeReference<STSCredential>() {
});
sTSCredential = stsCredentialTmp;
LOGGER.info("[getSTSCredential] code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}", sTSCredential.getCode(),
sTSCredential.getAccessKeyId(), sTSCredential.getLastUpdated(), sTSCredential.getExpiration());
@ -291,7 +294,7 @@ public class ServerHttpAgent implements HttpAgent {
int respCode;
String response;
try {
conn = (HttpURLConnection)new URL(securityCredentialsUrl).openConnection();
conn = (HttpURLConnection) new URL(securityCredentialsUrl).openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
conn.setReadTimeout(1000);

View File

@ -20,22 +20,15 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.impl.EventDispatcher.ServerlistChangeEvent;
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.utils.IOUtils;
import com.alibaba.nacos.client.utils.EnvUtil;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.client.utils.StringUtils;
import com.alibaba.nacos.client.utils.*;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.slf4j.Logger;
import java.io.IOException;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Random;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
@ -93,6 +86,8 @@ public class ServerListManager {
public ServerListManager(String endpoint, String namespace) throws NacosException {
isFixed = false;
isStarted = false;
endpoint = initEndpoint(endpoint);
if (StringUtils.isBlank(endpoint)) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
}
@ -158,10 +153,8 @@ public class ServerListManager {
}
private void initParam(Properties properties) {
String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT);
if (!StringUtils.isBlank(endpointTmp)) {
endpoint = endpointTmp;
}
endpoint = initEndpoint(properties.getProperty(PropertyKeyConst.ENDPOINT));
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
if (!StringUtils.isBlank(contentPathTmp)) {
contentPath = contentPathTmp;
@ -172,6 +165,21 @@ public class ServerListManager {
}
}
private String initEndpoint(String endpointTmp) {
String endpointPortTmp = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT);
if (StringUtils.isNotBlank(endpointPortTmp)) {
endpointPort = Integer.parseInt(endpointPortTmp);
}
return TemplateUtils.stringBlankAndThenExecute(endpointTmp, new Callable<String>() {
@Override
public String call() {
String endpointUrl = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_URL);
return StringUtils.isNotBlank(endpointUrl) ? endpointUrl : "";
}
});
}
public synchronized void start() throws NacosException {
if (isStarted || isFixed) {

View File

@ -25,6 +25,8 @@ public class Constants {
public static final String SECRET_KEY = "secretKey";
public static final String TENANT_ID = "tenantId";
public static final String PROPERTIES_FILENAME = "spas.properties";
public static final String CREDENTIAL_PATH = "/home/admin/.spas_key/";
@ -37,10 +39,14 @@ public class Constants {
public static final String DOCKER_SECRET_KEY = "env_spas_secretKey";
public static final String DOCKER_TENANT_ID = "ebv_spas_tenantId";
public static final String ENV_ACCESS_KEY = "spas_accessKey";
public static final String ENV_SECRET_KEY = "spas_secretKey";
public static final String ENV_TENANT_ID = "tenant.id";
public static final String NO_APP_NAME = "";
}

View File

@ -19,11 +19,7 @@ import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.StringUtils;
import org.slf4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.net.URL;
import java.util.Properties;
import java.util.Timer;
@ -144,6 +140,7 @@ public class CredentialWatcher {
String accessKey = null;
String secretKey = null;
String tenantId = null;
if (propertiesIS == null) {
propertyPath = null;
accessKey = System.getenv(Constants.ENV_ACCESS_KEY);
@ -183,6 +180,9 @@ public class CredentialWatcher {
if (properties.containsKey(Constants.SECRET_KEY)) {
secretKey = properties.getProperty(Constants.SECRET_KEY);
}
if (properties.containsKey(Constants.TENANT_ID)) {
tenantId = properties.getProperty(Constants.TENANT_ID);
}
} else {
if (properties.containsKey(Constants.DOCKER_ACCESS_KEY)) {
accessKey = properties.getProperty(Constants.DOCKER_ACCESS_KEY);
@ -190,6 +190,10 @@ public class CredentialWatcher {
if (properties.containsKey(Constants.DOCKER_SECRET_KEY)) {
secretKey = properties.getProperty(Constants.DOCKER_SECRET_KEY);
}
if (properties.containsKey(Constants.DOCKER_TENANT_ID)) {
tenantId = properties.getProperty(Constants.DOCKER_TENANT_ID);
}
}
}
@ -200,7 +204,11 @@ public class CredentialWatcher {
secretKey = secretKey.trim();
}
Credentials credential = new Credentials(accessKey, secretKey);
if (tenantId != null) {
tenantId = tenantId.trim();
}
Credentials credential = new Credentials(accessKey, secretKey, tenantId);
if (!credential.valid()) {
SpasLogger.warn("[1] Credential file missing required property {} Credential file missing {} or {}",
appName, Constants.ACCESS_KEY, Constants.SECRET_KEY);

View File

@ -26,13 +26,16 @@ public class Credentials implements SpasCredential {
private volatile String secretKey;
public Credentials(String accessKey, String secretKey) {
private volatile String tenantId;
public Credentials(String accessKey, String secretKey, String tenantId) {
this.accessKey = accessKey;
this.secretKey = secretKey;
this.tenantId = tenantId;
}
public Credentials() {
this(null, null);
this(null, null, null);
}
public String getAccessKey() {
@ -51,16 +54,24 @@ public class Credentials implements SpasCredential {
this.secretKey = secretKey;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public boolean valid() {
return accessKey != null && !accessKey.isEmpty() && secretKey != null && !secretKey.isEmpty();
return accessKey != null && !accessKey.isEmpty() && secretKey != null
&& !secretKey.isEmpty();
}
public boolean identical(Credentials other) {
return this == other ||
(other != null &&
(accessKey == null && other.accessKey == null || accessKey != null && accessKey.equals(other.accessKey))
&&
(secretKey == null && other.secretKey == null || secretKey != null && secretKey.equals(
other.secretKey)));
return this == other || (other != null
&& (accessKey == null && other.accessKey == null
|| accessKey != null && accessKey.equals(other.accessKey))
&& (secretKey == null && other.secretKey == null
|| secretKey != null && secretKey.equals(other.secretKey)));
}
}

View File

@ -28,6 +28,16 @@ public abstract class AbstractNacosLogging {
private static final String NACOS_LOGGING_DEFAULT_CONFIG_ENABLED_PROPERTY = "nacos.logging.default.config.enabled";
private static final String NACOS_LOGGING_PATH_PROPERTY = "nacos.logging.path";
static {
String loggingPath = System.getProperty(NACOS_LOGGING_PATH_PROPERTY);
if (StringUtils.isBlank(loggingPath)) {
String userHome = System.getProperty("user.home");
System.setProperty(NACOS_LOGGING_PATH_PROPERTY, userHome + "/logs/nacos");
}
}
protected String getLocation(String defaultLocation) {
String location = System.getProperty(NACOS_LOGGING_CONFIG_PROPERTY);
if (StringUtils.isBlank(location)) {

View File

@ -26,16 +26,22 @@ import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
import org.apache.logging.log4j.core.lookup.Interpolator;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.util.PropertiesUtil;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.apache.logging.log4j.core.config.ConfigurationFactory.CONFIGURATION_FILE_PROPERTY;
/**
* Support for Log4j version 2.7 or higher
*
@ -52,6 +58,8 @@ public class Log4J2NacosLogging extends AbstractNacosLogging {
private static final String JSON_PARSER_CLASS_NAME = "com.fasterxml.jackson.databind.ObjectMapper";
private final StrSubstitutor strSubstitutor = new StrSubstitutor(new Interpolator());
private Set<String> locationList = new HashSet<String>();
public Log4J2NacosLogging() {
@ -63,9 +71,13 @@ public class Log4J2NacosLogging extends AbstractNacosLogging {
@Override
public void loadConfiguration() {
String config = findConfig(getCurrentlySupportedConfigLocations());
if (config != null) {
locationList.add(config);
if (locationList.isEmpty()) {
return;
}
List<String> configList = findConfig(getCurrentlySupportedConfigLocations());
if (configList != null) {
locationList.addAll(configList);
}
final List<AbstractConfiguration> configurations = new ArrayList<AbstractConfiguration>();
@ -112,22 +124,35 @@ public class Log4J2NacosLogging extends AbstractNacosLogging {
List<String> supportedConfigLocations = new ArrayList<String>();
if (ClassUtils.isPresent(YAML_PARSER_CLASS_NAME)) {
Collections.addAll(supportedConfigLocations, "log4j2.yaml", "log4j2.yml");
Collections.addAll(supportedConfigLocations, "log4j2.yaml", "log4j2.yml", "log4j2-test.yaml",
"log4j2-test.yml");
}
if (ClassUtils.isPresent(JSON_PARSER_CLASS_NAME)) {
Collections.addAll(supportedConfigLocations, "log4j2.json", "log4j2.jsn");
Collections.addAll(supportedConfigLocations, "log4j2.json", "log4j2.jsn", "log4j2-test.json",
"log4j2-test.jsn");
}
supportedConfigLocations.add("log4j2.xml");
supportedConfigLocations.add("log4j2-test.xml");
return supportedConfigLocations.toArray(new String[supportedConfigLocations.size()]);
}
private String findConfig(String[] locations) {
private List<String> findConfig(String[] locations) {
final String configLocationStr = this.strSubstitutor.replace(PropertiesUtil.getProperties()
.getStringProperty(CONFIGURATION_FILE_PROPERTY));
if (configLocationStr != null) {
return Arrays.asList(configLocationStr.split(","));
}
for (String location : locations) {
ClassLoader defaultClassLoader = ClassUtils.getDefaultClassLoader();
if (defaultClassLoader != null && defaultClassLoader.getResource(location) != null) {
return "classpath:" + location;
List<String> list = new ArrayList<String>();
list.add("classpath:" + location);
return list;
}
}
return null;

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.client.naming;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
@ -23,7 +24,9 @@ import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.client.identify.CredentialService;
import com.alibaba.nacos.client.naming.beat.BeatInfo;
import com.alibaba.nacos.client.naming.beat.BeatReactor;
import com.alibaba.nacos.client.naming.core.Balancer;
@ -33,6 +36,8 @@ import com.alibaba.nacos.client.naming.net.NamingProxy;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.TemplateUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.math.NumberUtils;
@ -40,13 +45,13 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Callable;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
public class NacosNamingService implements NamingService {
/**
* Each Naming instance should have different namespace.
*/
@ -68,97 +73,218 @@ public class NacosNamingService implements NamingService {
private NamingProxy serverProxy;
private void init() {
public NacosNamingService(String serverList) {
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverList);
namespace = System.getProperty(PropertyKeyConst.NAMESPACE);
init(properties);
}
if (StringUtils.isEmpty(namespace)) {
namespace = UtilAndComs.DEFAULT_NAMESPACE_ID;
public NacosNamingService(Properties properties) {
init(properties);
}
private void init(Properties properties) {
serverList = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
initNamespace(properties);
initEndpoint(properties);
initWebRootContext();
initCacheDir();
initLogName(properties);
eventDispatcher = new EventDispatcher();
serverProxy = new NamingProxy(namespace, endpoint, serverList);
serverProxy.setProperties(properties);
beatReactor = new BeatReactor(serverProxy, initClientBeatThreadCount(properties));
hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, isLoadCacheAtStart(properties), initPollingThreadCount(properties));
}
private int initClientBeatThreadCount(Properties properties) {
if (properties == null) {
return UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT;
}
int clientBeatThreadCount = NumberUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT),
UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT);
return clientBeatThreadCount;
}
private int initPollingThreadCount(Properties properties) {
if (properties == null) {
return UtilAndComs.DEFAULT_POLLING_THREAD_COUNT;
}
int pollingThreadCount = NumberUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_POLLING_THREAD_COUNT),
UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
return pollingThreadCount;
}
private boolean isLoadCacheAtStart(Properties properties) {
boolean loadCacheAtStart = false;
if (properties != null && StringUtils.isNotEmpty(properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START))) {
loadCacheAtStart = BooleanUtils.toBoolean(
properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START));
}
return loadCacheAtStart;
}
private void initLogName(Properties properties) {
logName = System.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME);
if (StringUtils.isEmpty(logName)) {
logName = "naming.log";
}
if (properties != null && StringUtils.isNotEmpty(properties.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME))) {
logName = properties.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME);
} else {
logName = "naming.log";
}
}
}
private void initCacheDir() {
cacheDir = System.getProperty("com.alibaba.nacos.naming.cache.dir");
if (StringUtils.isEmpty(cacheDir)) {
cacheDir = System.getProperty("user.home") + "/nacos/naming/" + namespace;
}
}
public NacosNamingService(String serverList) {
private void initEndpoint(Properties properties) {
if (properties == null) {
this.serverList = serverList;
init();
eventDispatcher = new EventDispatcher();
serverProxy = new NamingProxy(namespace, endpoint, serverList);
beatReactor = new BeatReactor(serverProxy);
hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir);
return;
}
String endpointUrl = TemplateUtils.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.ENDPOINT), new Callable<String>() {
@Override
public String call() {
return System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_URL);
}
});
if (com.alibaba.nacos.client.utils.StringUtils.isBlank(endpointUrl)) {
return;
}
String endpointPort = TemplateUtils.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.ENDPOINT_PORT), new Callable<String>() {
@Override
public String call() {
return System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_PORT);
}
});
endpointPort = TemplateUtils.stringEmptyAndThenExecute(endpointPort, new Callable<String>() {
@Override
public String call() {
return "8080";
}
});
endpoint = endpointUrl + ":" + endpointPort;
}
public NacosNamingService(Properties properties) {
private void initNamespace(Properties properties) {
String tmpNamespace = null;
init();
serverList = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
if (StringUtils.isNotEmpty(properties.getProperty(PropertyKeyConst.NAMESPACE))) {
namespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
if (properties != null) {
tmpNamespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
}
if (StringUtils.isNotEmpty(properties.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME))) {
logName = properties.getProperty(UtilAndComs.NACOS_NAMING_LOG_NAME);
}
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = System.getProperty(PropertyKeyConst.NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Property :" + namespace);
return namespace;
}
});
if (StringUtils.isNotEmpty(properties.getProperty(PropertyKeyConst.ENDPOINT))) {
endpoint = properties.getProperty(PropertyKeyConst.ENDPOINT) + ":" +
properties.getProperty("address.server.port", "8080");
}
cacheDir = System.getProperty("user.home") + "/nacos/naming/" + namespace;
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
LogUtils.NAMING_LOGGER.info("initializer namespace from System Environment :" + namespace);
return namespace;
}
});
boolean loadCacheAtStart = false;
if (StringUtils.isNotEmpty(properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START))) {
loadCacheAtStart = BooleanUtils.toBoolean(
properties.getProperty(PropertyKeyConst.NAMING_LOAD_CACHE_AT_START));
}
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
String namespace = CredentialService.getInstance().getCredential().getTenantId();
LogUtils.NAMING_LOGGER.info("initializer namespace from Credential Module " + namespace);
return namespace;
}
});
int clientBeatThreadCount = NumberUtils.toInt(
properties.getProperty(PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT),
UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT);
tmpNamespace = TemplateUtils.stringEmptyAndThenExecute(tmpNamespace, new Callable<String>() {
@Override
public String call() {
return UtilAndComs.DEFAULT_NAMESPACE_ID;
}
});
namespace = tmpNamespace;
}
int pollingThreadCount = NumberUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_POLLING_THREAD_COUNT),
UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
eventDispatcher = new EventDispatcher();
serverProxy = new NamingProxy(namespace, endpoint, serverList);
beatReactor = new BeatReactor(serverProxy, clientBeatThreadCount);
hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, loadCacheAtStart, pollingThreadCount);
private void initWebRootContext() {
// support the web context with ali-yun if the app deploy by EDAS
final String webContext = System.getProperty(SystemPropertyKeyConst.NAMING_WEB_CONTEXT);
TemplateUtils.stringNotEmptyAndThenExecute(webContext, new Runnable() {
@Override
public void run() {
UtilAndComs.WEB_CONTEXT = webContext.indexOf("/") > -1 ? webContext
: "/" + webContext;
UtilAndComs.NACOS_URL_BASE = UtilAndComs.WEB_CONTEXT + "/v1/ns";
UtilAndComs.NACOS_URL_INSTANCE = UtilAndComs.NACOS_URL_BASE + "/instance";
}
});
}
@Override
public void registerInstance(String serviceName, String ip, int port) throws NacosException {
registerInstance(serviceName, ip, port, Constants.NAMING_DEFAULT_CLUSTER_NAME);
registerInstance(serviceName, ip, port, Constants.DEFAULT_CLUSTER_NAME);
}
@Override
public void registerInstance(String serviceName, String groupName, String ip, int port) throws NacosException {
registerInstance(serviceName, groupName, ip, port, Constants.DEFAULT_CLUSTER_NAME);
}
@Override
public void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException {
registerInstance(serviceName, Constants.DEFAULT_GROUP, ip, port, clusterName);
}
@Override
public void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException {
Instance instance = new Instance();
instance.setIp(ip);
instance.setPort(port);
instance.setWeight(1.0);
instance.setClusterName(clusterName);
registerInstance(serviceName, instance);
registerInstance(serviceName, groupName, instance);
}
@Override
public void registerInstance(String serviceName, Instance instance) throws NacosException {
registerInstance(serviceName, Constants.DEFAULT_GROUP, instance);
}
@Override
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
BeatInfo beatInfo = new BeatInfo();
beatInfo.setServiceName(serviceName);
beatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName));
beatInfo.setIp(instance.getIp());
beatInfo.setPort(instance.getPort());
beatInfo.setCluster(instance.getClusterName());
@ -166,20 +292,30 @@ public class NacosNamingService implements NamingService {
beatInfo.setMetadata(instance.getMetadata());
beatInfo.setScheduled(false);
beatReactor.addBeatInfo(serviceName, beatInfo);
beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
serverProxy.registerService(serviceName, instance);
serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
}
@Override
public void deregisterInstance(String serviceName, String ip, int port) throws NacosException {
deregisterInstance(serviceName, ip, port, Constants.NAMING_DEFAULT_CLUSTER_NAME);
deregisterInstance(serviceName, ip, port, Constants.DEFAULT_CLUSTER_NAME);
}
@Override
public void deregisterInstance(String serviceName, String groupName, String ip, int port) throws NacosException {
deregisterInstance(serviceName, groupName, ip, port, Constants.DEFAULT_CLUSTER_NAME);
}
@Override
public void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException {
beatReactor.removeBeatInfo(serviceName, ip, port);
serverProxy.deregisterService(serviceName, ip, port, clusterName);
deregisterInstance(serviceName, Constants.DEFAULT_GROUP, ip, port, clusterName);
}
@Override
public void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException {
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), ip, port);
serverProxy.deregisterService(NamingUtils.getGroupedName(serviceName, groupName), ip, port, clusterName);
}
@Override
@ -187,25 +323,45 @@ public class NacosNamingService implements NamingService {
return getAllInstances(serviceName, new ArrayList<String>());
}
@Override
public List<Instance> getAllInstances(String serviceName, String groupName) throws NacosException {
return getAllInstances(serviceName, groupName, new ArrayList<String>());
}
@Override
public List<Instance> getAllInstances(String serviceName, boolean subscribe) throws NacosException {
return getAllInstances(serviceName, new ArrayList<String>(), subscribe);
}
@Override
public List<Instance> getAllInstances(String serviceName, String groupName, boolean subscribe) throws NacosException {
return getAllInstances(serviceName, groupName, new ArrayList<String>(), subscribe);
}
@Override
public List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException {
return getAllInstances(serviceName, clusters, true);
}
@Override
public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters) throws NacosException {
return getAllInstances(serviceName, groupName, clusters, true);
}
@Override
public List<Instance> getAllInstances(String serviceName, List<String> clusters, boolean subscribe)
throws NacosException {
return getAllInstances(serviceName, Constants.DEFAULT_GROUP, clusters, subscribe);
}
@Override
public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException {
ServiceInfo serviceInfo;
if (subscribe) {
serviceInfo = hostReactor.getServiceInfo(serviceName, StringUtils.join(clusters, ","));
serviceInfo = hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));
} else {
serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(serviceName, StringUtils.join(clusters, ","));
serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));
}
List<Instance> list;
if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
@ -219,26 +375,47 @@ public class NacosNamingService implements NamingService {
return selectInstances(serviceName, new ArrayList<String>(), healthy);
}
@Override
public List<Instance> selectInstances(String serviceName, String groupName, boolean healthy) throws NacosException {
return selectInstances(serviceName, groupName, healthy, true);
}
@Override
public List<Instance> selectInstances(String serviceName, boolean healthy, boolean subscribe)
throws NacosException {
return selectInstances(serviceName, new ArrayList<String>(), healthy, subscribe);
}
@Override
public List<Instance> selectInstances(String serviceName, String groupName, boolean healthy, boolean subscribe) throws NacosException {
return selectInstances(serviceName, groupName, new ArrayList<String>(), healthy, subscribe);
}
@Override
public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy)
throws NacosException {
return selectInstances(serviceName, clusters, healthy, true);
}
@Override
public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy) throws NacosException {
return selectInstances(serviceName, groupName, clusters, healthy, true);
}
@Override
public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy,
boolean subscribe) throws NacosException {
return selectInstances(serviceName, Constants.DEFAULT_GROUP, clusters, healthy, subscribe);
}
@Override
public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy, boolean subscribe) throws NacosException {
ServiceInfo serviceInfo;
if (subscribe) {
serviceInfo = hostReactor.getServiceInfo(serviceName, StringUtils.join(clusters, ","));
serviceInfo = hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));
} else {
serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(serviceName, StringUtils.join(clusters, ","));
serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));
}
return selectInstances(serviceInfo, healthy);
}
@ -248,60 +425,109 @@ public class NacosNamingService implements NamingService {
return selectOneHealthyInstance(serviceName, new ArrayList<String>());
}
@Override
public Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException {
return selectOneHealthyInstance(serviceName, groupName, true);
}
@Override
public Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException {
return selectOneHealthyInstance(serviceName, new ArrayList<String>(), subscribe);
}
@Override
public Instance selectOneHealthyInstance(String serviceName, String groupName, boolean subscribe) throws NacosException {
return selectOneHealthyInstance(serviceName, groupName, new ArrayList<String>(), subscribe);
}
@Override
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException {
return selectOneHealthyInstance(serviceName, clusters, true);
}
@Override
public Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters) throws NacosException {
return selectOneHealthyInstance(serviceName, groupName, clusters, true);
}
@Override
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters, boolean subscribe)
throws NacosException {
return selectOneHealthyInstance(serviceName, Constants.DEFAULT_GROUP, clusters, subscribe);
}
@Override
public Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException {
if (subscribe) {
return Balancer.RandomByWeight.selectHost(
hostReactor.getServiceInfo(serviceName, StringUtils.join(clusters, ",")));
hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ",")));
} else {
return Balancer.RandomByWeight.selectHost(
hostReactor.getServiceInfoDirectlyFromServer(serviceName, StringUtils.join(clusters, ",")));
hostReactor.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ",")));
}
}
@Override
public void subscribe(String service, EventListener listener) {
eventDispatcher.addListener(hostReactor.getServiceInfo(service, StringUtils.EMPTY), StringUtils.EMPTY,
listener);
public void subscribe(String serviceName, EventListener listener) throws NacosException {
subscribe(serviceName, new ArrayList<String>(), listener);
}
@Override
public void subscribe(String service, List<String> clusters, EventListener listener) {
eventDispatcher.addListener(hostReactor.getServiceInfo(service, StringUtils.join(clusters, ",")),
StringUtils.join(clusters, ","), listener);
public void subscribe(String serviceName, String groupName, EventListener listener) throws NacosException {
subscribe(serviceName, groupName, new ArrayList<String>(), listener);
}
@Override
public void unsubscribe(String service, EventListener listener) {
eventDispatcher.removeListener(service, StringUtils.EMPTY, listener);
public void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException {
subscribe(serviceName, Constants.DEFAULT_GROUP, clusters, listener);
}
@Override
public void unsubscribe(String service, List<String> clusters, EventListener listener) {
eventDispatcher.removeListener(service, StringUtils.join(clusters, ","), listener);
public void subscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException {
eventDispatcher.addListener(hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName),
StringUtils.join(clusters, ",")), StringUtils.join(clusters, ","), listener);
}
@Override
public void unsubscribe(String serviceName, EventListener listener) throws NacosException {
unsubscribe(serviceName, new ArrayList<String>(), listener);
}
@Override
public void unsubscribe(String serviceName, String groupName, EventListener listener) throws NacosException {
unsubscribe(serviceName, groupName, new ArrayList<String>(), listener);
}
@Override
public void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException {
unsubscribe(serviceName, Constants.DEFAULT_GROUP, clusters, listener);
}
@Override
public void unsubscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException {
eventDispatcher.removeListener(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","), listener);
}
@Override
public ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException {
return serverProxy.getServiceList(pageNo, pageSize);
return serverProxy.getServiceList(pageNo, pageSize, Constants.DEFAULT_GROUP);
}
@Override
public ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName) throws NacosException {
return getServicesOfServer(pageNo, pageSize, groupName, null);
}
@Override
public ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector)
throws NacosException {
return serverProxy.getServiceList(pageNo, pageSize, selector);
return getServicesOfServer(pageNo, pageSize, Constants.DEFAULT_GROUP, selector);
}
@Override
public ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException {
return serverProxy.getServiceList(pageNo, pageSize, groupName, selector);
}
@Override

View File

@ -34,7 +34,7 @@ import java.util.concurrent.*;
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class FailoverReactor {

View File

@ -20,7 +20,7 @@ import com.alibaba.fastjson.JSON;
import java.util.Map;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class BeatInfo {
@ -30,7 +30,7 @@ public class BeatInfo {
private String serviceName;
private String cluster;
private Map<String, String> metadata;
private boolean scheduled;
private volatile boolean scheduled;
@Override
public String toString() {

View File

@ -58,20 +58,21 @@ public class BeatReactor {
executorService.schedule(new BeatProcessor(), 0, TimeUnit.MILLISECONDS);
}
public void addBeatInfo(String dom, BeatInfo beatInfo) {
public void addBeatInfo(String serviceName, BeatInfo beatInfo) {
NAMING_LOGGER.info("[BEAT] adding beat: {} to beat map.", beatInfo);
dom2Beat.put(buildKey(dom, beatInfo.getIp(), beatInfo.getPort()), beatInfo);
dom2Beat.put(buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort()), beatInfo);
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
}
public void removeBeatInfo(String dom, String ip, int port) {
NAMING_LOGGER.info("[BEAT] removing beat: {}:{}:{} from beat map.", dom, ip, port);
dom2Beat.remove(buildKey(dom, ip, port));
public void removeBeatInfo(String serviceName, String ip, int port) {
NAMING_LOGGER.info("[BEAT] removing beat: {}:{}:{} from beat map.", serviceName, ip, port);
dom2Beat.remove(buildKey(serviceName, ip, port));
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
}
public String buildKey(String dom, String ip, int port) {
return dom + Constants.NAMING_INSTANCE_ID_SPLITTER + ip + Constants.NAMING_INSTANCE_ID_SPLITTER + port;
public String buildKey(String serviceName, String ip, int port) {
return serviceName + Constants.NAMING_INSTANCE_ID_SPLITTER
+ ip + Constants.NAMING_INSTANCE_ID_SPLITTER + port;
}
class BeatProcessor implements Runnable {

View File

@ -29,7 +29,7 @@ import java.nio.charset.CharsetDecoder;
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class ConcurrentDiskUtil {

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.client.naming.cache;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
@ -44,7 +45,6 @@ public class DiskCache {
makeSureCacheDirExists(dir);
File file = new File(dir, dom.getKeyEncoded());
if (!file.exists()) {
// add another !file.exists() to avoid conflicted creating-new-file from multi-instances
@ -93,8 +93,8 @@ public class DiskCache {
String fileName = URLDecoder.decode(file.getName(), "UTF-8");
if (!(fileName.endsWith(ServiceInfo.SPLITER + "meta") || fileName.endsWith(
ServiceInfo.SPLITER + "special-url"))) {
if (!(fileName.endsWith(Constants.SERVICE_INFO_SPLITER + "meta") || fileName.endsWith(
Constants.SERVICE_INFO_SPLITER + "special-url"))) {
ServiceInfo dom = new ServiceInfo(fileName);
List<Instance> ips = new ArrayList<Instance>();
dom.setHosts(ips);

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.client.naming.core;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class ProtectMode {

View File

@ -77,7 +77,7 @@ public class PushReceiver implements Runnable {
PushPacket pushPacket = JSON.parseObject(json, PushPacket.class);
String ack;
if ("dom".equals(pushPacket.type)) {
if ("dom".equals(pushPacket.type) || "service".equals(pushPacket.type)) {
hostReactor.processServiceJSON(pushPacket.data);
// send ack to server

View File

@ -15,6 +15,7 @@
*/
package com.alibaba.nacos.client.naming.net;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.naming.utils.IoUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.google.common.net.HttpHeaders;
@ -29,16 +30,22 @@ import java.net.URLEncoder;
import java.util.*;
import java.util.zip.GZIPInputStream;
import static com.alibaba.nacos.client.utils.LogUtils.*;
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class HttpClient {
public static final int TIME_OUT_MILLIS = Integer.getInteger("com.alibaba.nacos.client.naming.ctimeout", 50000);
public static final int CON_TIME_OUT_MILLIS = Integer.getInteger("com.alibaba.nacos.client.naming.ctimeout", 3000);
private static final boolean ENABLE_HTTPS = Boolean.getBoolean("com.alibaba.nacos.client.naming.tls.enable");
public static final int TIME_OUT_MILLIS = Integer
.getInteger("com.alibaba.nacos.client.naming.ctimeout", 50000);
public static final int CON_TIME_OUT_MILLIS = Integer
.getInteger("com.alibaba.nacos.client.naming.ctimeout", 3000);
private static final boolean ENABLE_HTTPS = Boolean
.getBoolean("com.alibaba.nacos.client.naming.tls.enable");
private static final String POST = "POST";
private static final String PUT = "PUT";
static {
// limit max redirection
@ -62,14 +69,23 @@ public class HttpClient {
HttpURLConnection conn = null;
try {
String encodedContent = encodingParams(paramValues, encoding);
url += (null == encodedContent) ? "" : ("?" + encodedContent);
url += (StringUtils.isEmpty(encodedContent)) ? "" : ("?" + encodedContent);
conn = (HttpURLConnection) new URL(url).openConnection();
setHeaders(conn, headers, encoding);
conn.setConnectTimeout(CON_TIME_OUT_MILLIS);
conn.setReadTimeout(TIME_OUT_MILLIS);
conn.setRequestMethod(method);
setHeaders(conn, headers, encoding);
conn.setDoOutput(true);
if (POST.equals(method) || PUT.equals(method)) {
// fix: apache http nio framework must set some content to request body
byte[] b = encodedContent.getBytes();
conn.setRequestProperty("Content-Length", String.valueOf(b.length));
conn.getOutputStream().write(b, 0, b.length);
conn.getOutputStream().flush();
conn.getOutputStream().close();
}
conn.connect();
NAMING_LOGGER.debug("Request from server: " + url);
return getResult(conn);
@ -77,7 +93,7 @@ public class HttpClient {
try {
if (conn != null) {
NAMING_LOGGER.warn("failed to request " + conn.getURL() + " from "
+ InetAddress.getByName(conn.getURL().getHost()).getHostAddress());
+ InetAddress.getByName(conn.getURL().getHost()).getHostAddress());
}
} catch (Exception e1) {
NAMING_LOGGER.error("[NA] failed to request ", e1);
@ -99,7 +115,8 @@ public class HttpClient {
InputStream inputStream;
if (HttpURLConnection.HTTP_OK == respCode
|| HttpURLConnection.HTTP_NOT_MODIFIED == respCode) {
|| HttpURLConnection.HTTP_NOT_MODIFIED == respCode
|| Constants.WRITE_REDIRECT_CODE == respCode) {
inputStream = conn.getInputStream();
} else {
inputStream = conn.getErrorStream();
@ -150,18 +167,18 @@ public class HttpClient {
}
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset="
+ encoding);
+ encoding);
conn.addRequestProperty("Accept-Charset", encoding);
}
private static String encodingParams(Map<String, String> params, String encoding)
throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
throws UnsupportedEncodingException {
if (null == params || params.isEmpty()) {
return null;
return "";
}
params.put("encoding", encoding);
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (StringUtils.isEmpty(entry.getValue())) {
@ -173,6 +190,9 @@ public class HttpClient {
sb.append("&");
}
if (sb.length() > 0) {
sb = sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}

View File

@ -18,46 +18,40 @@ package com.alibaba.nacos.client.naming.net;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.selector.AbstractSelector;
import com.alibaba.nacos.api.selector.ExpressionSelector;
import com.alibaba.nacos.api.selector.SelectorType;
import com.alibaba.nacos.client.config.impl.SpasAdapter;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.beat.BeatInfo;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.client.naming.utils.IoUtils;
import com.alibaba.nacos.client.naming.utils.NetUtils;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
import com.alibaba.nacos.client.naming.utils.*;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.common.util.HttpMethod;
import com.alibaba.nacos.common.util.UuidUtils;
import java.io.IOException;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.*;
import java.util.concurrent.*;
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class NamingProxy {
private static final int DEFAULT_SERVER_PORT = 8848;
private int serverPort = DEFAULT_SERVER_PORT;
private String namespaceId;
private String endpoint;
@ -72,7 +66,7 @@ public class NamingProxy {
private long vipSrvRefInterMillis = TimeUnit.SECONDS.toMillis(30);
private ScheduledExecutorService executorService;
private Properties properties;
public NamingProxy(String namespaceId, String endpoint, String serverList) {
@ -85,7 +79,15 @@ public class NamingProxy {
}
}
executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
initRefreshSrvIfNeed();
}
private void initRefreshSrvIfNeed() {
if (StringUtils.isEmpty(endpoint)) {
return;
}
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
@ -109,11 +111,7 @@ public class NamingProxy {
try {
String urlString = "http://" + endpoint + "/nacos/serverlist";
List<String> headers = Arrays.asList("Client-Version", UtilAndComs.VERSION,
"Accept-Encoding", "gzip,deflate,sdch",
"Connection", "Keep-Alive",
"RequestId", UuidUtils.generateUuid());
List<String> headers = builderHeaders();
HttpClient.HttpResult result = HttpClient.httpGet(urlString, headers, null, UtilAndComs.ENCODING);
if (HttpURLConnection.HTTP_OK != result.code) {
@ -167,37 +165,39 @@ public class NamingProxy {
}
}
public void registerService(String serviceName, Instance instance) throws NacosException {
public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {
NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}",
namespaceId, serviceName, instance);
final Map<String, String> params = new HashMap<String, String>(8);
params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
params.put("ip", instance.getIp());
params.put("port", String.valueOf(instance.getPort()));
params.put("weight", String.valueOf(instance.getWeight()));
params.put("enable", String.valueOf(instance.isEnabled()));
params.put("healthy", String.valueOf(instance.isHealthy()));
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
params.put("metadata", JSON.toJSONString(instance.getMetadata()));
params.put("serviceName", serviceName);
params.put("clusterName", instance.getClusterName());
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.POST);
}
public void deregisterService(String serviceName, String ip, int port, String cluster) throws NacosException {
public void deregisterService(String serviceName, String ip, int port, String clusterName) throws NacosException {
NAMING_LOGGER.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}:{}@{}",
namespaceId, serviceName, ip, port, cluster);
namespaceId, serviceName, ip, port, clusterName);
final Map<String, String> params = new HashMap<String, String>(8);
params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put("ip", ip);
params.put("port", String.valueOf(port));
params.put("serviceName", serviceName);
params.put("cluster", cluster);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.CLUSTER_NAME, clusterName);
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.DELETE);
}
@ -206,8 +206,8 @@ public class NamingProxy {
throws NacosException {
final Map<String, String> params = new HashMap<String, String>(8);
params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
params.put("serviceName", serviceName);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put("clusters", clusters);
params.put("udpPort", String.valueOf(udpPort));
params.put("clientIP", NetUtils.localIP());
@ -221,8 +221,8 @@ public class NamingProxy {
NAMING_LOGGER.info("[BEAT] {} sending beat to server: {}", namespaceId, beatInfo.toString());
Map<String, String> params = new HashMap<String, String>(4);
params.put("beat", JSON.toJSONString(beatInfo));
params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
params.put("serviceName", beatInfo.getServiceName());
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, beatInfo.getServiceName());
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/beat", params, HttpMethod.PUT);
JSONObject jsonObject = JSON.parseObject(result);
@ -238,31 +238,33 @@ public class NamingProxy {
public boolean serverHealthy() {
try {
reqAPI(UtilAndComs.NACOS_URL_BASE + "/api/hello", new HashMap<String, String>(2));
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/operator/metrics", new HashMap<String, String>(2));
JSONObject json = JSON.parseObject(result);
String serverStatus = json.getString("status");
return "UP".equals(serverStatus);
} catch (Exception e) {
return false;
}
return true;
}
public ListView<String> getServiceList(int pageNo, int pageSize) throws NacosException {
return getServiceList(pageNo, pageSize, null);
public ListView<String> getServiceList(int pageNo, int pageSize, String groupName) throws NacosException {
return getServiceList(pageNo, pageSize, groupName, null);
}
public ListView<String> getServiceList(int pageNo, int pageSize, AbstractSelector selector) throws NacosException {
public ListView<String> getServiceList(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException {
Map<String, String> params = new HashMap<String, String>(4);
params.put("pageNo", String.valueOf(pageNo));
params.put("pageSize", String.valueOf(pageSize));
params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, namespaceId);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.GROUP_NAME, groupName);
if (selector != null) {
switch (SelectorType.valueOf(selector.getType())) {
case none:
break;
case label:
ExpressionSelector expressionSelector = (ExpressionSelector)selector;
ExpressionSelector expressionSelector = (ExpressionSelector) selector;
params.put("selector", JSON.toJSONString(expressionSelector));
break;
default:
@ -309,16 +311,13 @@ public class NamingProxy {
throws NacosException {
long start = System.currentTimeMillis();
long end = 0;
List<String> headers = Arrays.asList("Client-Version", UtilAndComs.VERSION,
"Accept-Encoding", "gzip,deflate,sdch",
"Connection", "Keep-Alive",
"RequestId", UuidUtils.generateUuid());
checkSignature(params);
List<String> headers = builderHeaders();
String url;
if (!curServer.contains(UtilAndComs.SERVER_ADDR_IP_SPLITER)) {
curServer = curServer + UtilAndComs.SERVER_ADDR_IP_SPLITER + DEFAULT_SERVER_PORT;
curServer = curServer + UtilAndComs.SERVER_ADDR_IP_SPLITER + serverPort;
}
url = HttpClient.getPrefix() + curServer + api;
@ -337,10 +336,6 @@ public class NamingProxy {
return StringUtils.EMPTY;
}
NAMING_LOGGER.error("[CALL-SERVER] failed to req API:" + HttpClient.getPrefix() + curServer
+ api + ". code:"
+ result.code + " msg: " + result.content);
throw new NacosException(NacosException.SERVER_ERROR, "failed to req API:" + HttpClient.getPrefix() + curServer
+ api + ". code:"
+ result.code + " msg: " + result.content);
@ -352,12 +347,14 @@ public class NamingProxy {
public String reqAPI(String api, Map<String, String> params, List<String> servers, String method) {
params.put(Constants.REQUEST_PARAM_NAMESPACE_ID, getNamespaceId());
params.put(CommonParams.NAMESPACE_ID, getNamespaceId());
if (CollectionUtils.isEmpty(servers) && StringUtils.isEmpty(nacosDomain)) {
throw new IllegalArgumentException("no server available");
}
Exception exception = new Exception();
if (servers != null && !servers.isEmpty()) {
Random random = new Random(System.currentTimeMillis());
@ -367,30 +364,116 @@ public class NamingProxy {
String server = servers.get(index);
try {
return callServer(api, params, server, method);
} catch (NacosException e) {
exception = e;
NAMING_LOGGER.error("request {} failed.", server, e);
} catch (Exception e) {
NAMING_LOGGER.error("[NA] req api:" + api + " failed, server(" + server, e);
exception = e;
NAMING_LOGGER.error("request {} failed.", server, e);
}
index = (index + 1) % servers.size();
}
throw new IllegalStateException("failed to req API:" + api + " after all servers(" + servers + ") tried");
throw new IllegalStateException("failed to req API:" + api + " after all servers(" + servers + ") tried: "
+ exception.getMessage());
}
for (int i = 0; i < UtilAndComs.REQUEST_DOMAIN_RETRY_COUNT; i++) {
try {
return callServer(api, params, nacosDomain);
} catch (Exception e) {
exception = e;
NAMING_LOGGER.error("[NA] req api:" + api + " failed, server(" + nacosDomain, e);
}
}
throw new IllegalStateException("failed to req API:/api/" + api + " after all servers(" + servers + ") tried");
throw new IllegalStateException("failed to req API:/api/" + api + " after all servers(" + servers + ") tried: "
+ exception.getMessage());
}
private void checkSignature(Map<String, String> params) {
String ak = getAccessKey();
String sk = getSecretKey();
if (StringUtils.isEmpty(ak) && StringUtils.isEmpty(sk)) {
return;
}
try {
String app = System.getProperty("project.name");
String signData = getSignData(params.get("serviceName"));
String signature = SignUtil.sign(signData, sk);
params.put("signature", signature);
params.put("data", signData);
params.put("ak", ak);
params.put("app", app);
} catch (Exception e) {
e.printStackTrace();
}
}
public List<String> builderHeaders() {
List<String> headers = Arrays.asList("Client-Version", UtilAndComs.VERSION,
"User-Agent", UtilAndComs.VERSION,
"Accept-Encoding", "gzip,deflate,sdch",
"Connection", "Keep-Alive",
"RequestId", UuidUtils.generateUuid(), "Request-Module", "Naming");
return headers;
}
private static String getSignData(String serviceName) {
return StringUtils.isNotEmpty(serviceName)
? System.currentTimeMillis() + "@@" + serviceName
: String.valueOf(System.currentTimeMillis());
}
public String getAccessKey() {
if (properties == null) {
return SpasAdapter.getAk();
}
return TemplateUtils.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.ACCESS_KEY), new Callable<String>() {
@Override
public String call() {
return SpasAdapter.getAk();
}
});
}
public String getSecretKey() {
if (properties == null) {
return SpasAdapter.getSk();
}
return TemplateUtils.stringEmptyAndThenExecute(properties.getProperty(PropertyKeyConst.SECRET_KEY), new Callable<String>() {
@Override
public String call() throws Exception {
return SpasAdapter.getSk();
}
});
}
public void setProperties(Properties properties) {
this.properties = properties;
setServerPort(DEFAULT_SERVER_PORT);
}
public String getNamespaceId() {
return namespaceId;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
String sp = System.getProperty(SystemPropertyKeyConst.NAMING_SERVER_PORT);
if (com.alibaba.nacos.client.utils.StringUtils.isNotBlank(sp)) {
this.serverPort = Integer.parseInt(sp);
}
}
}

View File

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

View File

@ -20,7 +20,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class GenericPoller<T> implements Poller<T> {

View File

@ -23,14 +23,22 @@ import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class IoUtils {
static public String toString(InputStream input, String encoding) throws IOException {
return (null == encoding) ? toString(new InputStreamReader(input, "UTF-8"))
: toString(new InputStreamReader(input, encoding));
static public String toString(InputStream input, String encoding) {
try {
return (null == encoding) ? toString(new InputStreamReader(input, "UTF-8"))
: toString(new InputStreamReader(input, encoding));
} catch (Exception e) {
NAMING_LOGGER.error("NA", "read input failed.", e);
return StringUtils.EMPTY;
}
}
static public String toString(Reader reader) throws IOException {
@ -78,7 +86,7 @@ public class IoUtils {
}
static private BufferedReader toBufferedReader(Reader reader) {
return reader instanceof BufferedReader ? (BufferedReader)reader : new BufferedReader(
return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(
reader);
}

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.client.naming.utils;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class Pair<T> {

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.client.naming.utils;
import java.util.List;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public interface Poller<T> {
/**

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.naming.utils;
import com.alibaba.nacos.client.identify.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
/**
* @author pbting
* @date 2019-01-22 10:20 PM
*/
public class SignUtil {
public static final Charset UTF8 = Charset.forName("UTF-8");
public SignUtil() {
}
public static String sign(String data, String key) throws Exception {
try {
byte[] signature = sign(data.getBytes(UTF8), key.getBytes(UTF8),
SignUtil.SigningAlgorithm.HmacSHA1);
return new String(Base64.encodeBase64(signature));
} catch (Exception var3) {
throw new Exception(
"Unable to calculate a request signature: " + var3.getMessage(),
var3);
}
}
private static byte[] sign(byte[] data, byte[] key,
SignUtil.SigningAlgorithm algorithm) throws Exception {
try {
Mac mac = Mac.getInstance(algorithm.toString());
mac.init(new SecretKeySpec(key, algorithm.toString()));
return mac.doFinal(data);
} catch (Exception var4) {
throw new Exception(
"Unable to calculate a request signature: " + var4.getMessage(),
var4);
}
}
public enum SigningAlgorithm {
// Hmac SHA1 algorithm
HmacSHA1;
SigningAlgorithm() {
}
}
}

View File

@ -22,7 +22,7 @@ import java.util.Collection;
import java.util.Locale;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class StringUtils {
public static boolean isEmpty(String str) {

View File

@ -20,7 +20,13 @@ package com.alibaba.nacos.client.naming.utils;
*/
public class UtilAndComs {
public static final String VERSION = "Nacos-Java-Client:v0.2.1";
public static final String VERSION = "Nacos-Java-Client:v1.0.0";
public static String WEB_CONTEXT = "/nacos";
public static String NACOS_URL_BASE = WEB_CONTEXT + "/v1/ns";
public static String NACOS_URL_INSTANCE = NACOS_URL_BASE + "/instance";
public static final String ENCODING = "UTF-8";
@ -30,25 +36,21 @@ public class UtilAndComs {
public static final String FAILOVER_SWITCH = "00-00---000-VIPSRV_FAILOVER_SWITCH-000---00-00";
public static final String NACOS_URL_BASE = "/nacos/v1/ns";
public static final String NACOS_URL_INSTANCE = NACOS_URL_BASE + "/instance";
public static final String DEFAULT_NAMESPACE_ID = "public";
public static final int REQUEST_DOMAIN_RETRY_COUNT = 3;
public static final String DEFAULT_NAMING_ID = "default";
public static final String NACOS_NAMING_LOG_NAME = "com.alibaba.nacos.naming.log.filename";
public static final String NACOS_NAMING_LOG_LEVEL = "com.alibaba.nacos.naming.log.level";
public static final String SERVER_ADDR_IP_SPLITER = ":";
public static final int DEFAULT_CLIENT_BEAT_THREAD_COUNT = Runtime.getRuntime().availableProcessors() > 1 ?
Runtime.getRuntime().availableProcessors() / 2 : 1;
public static final int DEFAULT_CLIENT_BEAT_THREAD_COUNT = Runtime.getRuntime()
.availableProcessors() > 1 ? Runtime.getRuntime().availableProcessors() / 2
: 1;
public static final int DEFAULT_POLLING_THREAD_COUNT = Runtime.getRuntime().availableProcessors() > 1 ?
Runtime.getRuntime().availableProcessors() / 2 : 1;
public static final int DEFAULT_POLLING_THREAD_COUNT = Runtime.getRuntime()
.availableProcessors() > 1 ? Runtime.getRuntime().availableProcessors() / 2
: 1;
}

View File

@ -37,6 +37,11 @@ public class StringUtils {
return true;
}
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
public static boolean isNotEmpty(String str) {
return !StringUtils.isEmpty(str);
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.utils;
import java.util.concurrent.Callable;
/**
* @author pbting
* @date 2019-03-04 1:31 PM
*/
public class TemplateUtils {
public static final void stringNotEmptyAndThenExecute(String source, Runnable runnable) {
if (StringUtils.isNotEmpty(source)) {
try {
runnable.run();
} catch (Exception e) {
LogUtils.NAMING_LOGGER.error("string empty and then execute cause an exception.", e);
}
}
}
public static final String stringEmptyAndThenExecute(String source, Callable<String> callable) {
if (StringUtils.isEmpty(source)) {
try {
return callable.call();
} catch (Exception e) {
LogUtils.NAMING_LOGGER.error("string empty and then execute cause an exception.", e);
}
}
return source.trim();
}
public static final String stringBlankAndThenExecute(String source, Callable<String> callable) {
if (StringUtils.isBlank(source)) {
try {
return callable.call();
} catch (Exception e) {
LogUtils.NAMING_LOGGER.error("string empty and then execute cause an exception.", e);
}
}
return source.trim();
}
}

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<RollingFile name="CONFIG_LOG_FILE" fileName="${sys:user.home}/logs/nacos/config.log"
filePattern="${sys:user.home}/logs/nacos/config.log.%d{yyyy-MM-dd}.%i">
<RollingFile name="CONFIG_LOG_FILE" fileName="${sys:nacos.logging.path}/config.log"
filePattern="${sys:nacos.logging.path}/config.log.%d{yyyy-MM-dd}.%i">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n</Pattern>
</PatternLayout>
@ -15,8 +15,8 @@
<DefaultRolloverStrategy max="${sys:JM.LOG.RETAIN.COUNT:-7}"/>
</RollingFile>
<RollingFile name="NAMING_LOG_FILE" fileName="${sys:user.home}/logs/nacos/naming.log"
filePattern="${sys:user.home}/logs/nacos/naming.log.%d{yyyy-MM-dd}.%i">
<RollingFile name="NAMING_LOG_FILE" fileName="${sys:nacos.logging.path}/naming.log"
filePattern="${sys:nacos.logging.path}/naming.log.%d{yyyy-MM-dd}.%i">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n</Pattern>
</PatternLayout>

View File

@ -3,11 +3,11 @@
<contextName>nacos</contextName>
<appender name="CONFIG_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${user.home}/logs/nacos/config.log</file>
<file>${nacos.logging.path}/config.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${user.home}/logs/nacos/config.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
<maxHistory>${JM.LOG.RETAIN.COUNT:-7}</maxHistory>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${nacos.logging.path}/config.log.%i</fileNamePattern>
<maxIndex>${JM.LOG.RETAIN.COUNT:-7}</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
@ -20,11 +20,11 @@
</appender>
<appender name="NAMING_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${user.home}/logs/nacos/naming.log</file>
<file>${nacos.logging.path}/naming.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${user.home}/logs/nacos/naming.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
<maxHistory>${JM.LOG.RETAIN.COUNT:-7}</maxHistory>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${nacos.logging.path}/naming.log.%i</fileNamePattern>
<maxIndex>${JM.LOG.RETAIN.COUNT:-7}</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

View File

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

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId>
<version>0.9.0</version>
<version>1.0.0-RC2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -19,7 +19,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
@SpringBootApplication

View File

@ -27,7 +27,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
@RestController
@ -40,7 +40,7 @@ public class OperationController {
@Autowired
private CmdbProvider cmdbProvider;
@RequestMapping(value = "/updateSwitch", method = RequestMethod.POST)
@RequestMapping(value = "/switch", method = RequestMethod.PUT)
public String updateSwitch(HttpServletRequest request) throws Exception {
String entry = WebUtils.required(request, "entry");
@ -64,7 +64,7 @@ public class OperationController {
return "ok";
}
@RequestMapping(value = "/queryLabel", method = RequestMethod.GET)
@RequestMapping(value = "/label", method = RequestMethod.GET)
public String queryLabel(HttpServletRequest request) throws Exception {
String entry = WebUtils.required(request, "entry");
String label = WebUtils.required(request, "label");

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.cmdb.core;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public class CmdbManager {

View File

@ -19,7 +19,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
@Component

View File

@ -35,7 +35,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
@Component

View File

@ -21,7 +21,7 @@ import com.alibaba.nacos.api.cmdb.pojo.Entity;
import java.util.List;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public interface CmdbReader {

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.cmdb.service;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public interface CmdbWriter {

View File

@ -20,7 +20,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.7.0
*/
public class UtilsAndCommons {

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.9.0</version>
<version>1.0.0-RC2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.common.util;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
* @since 0.8.0
*/
public class HttpMethod {

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.common.util;
import java.util.UUID;
/**
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
public class UuidUtils {

View File

@ -17,7 +17,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.9.0</version>
<version>1.0.0-RC2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -16,21 +16,12 @@
package com.alibaba.nacos.config.server.service;
import com.alibaba.nacos.config.server.monitor.MetricsMonitor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.dao.DataAccessException;
@ -40,10 +31,19 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import static com.alibaba.nacos.core.utils.SystemUtils.STANDALONE_MODE;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.alibaba.nacos.config.server.service.PersistService.CONFIG_INFO4BETA_ROW_MAPPER;
import static com.alibaba.nacos.config.server.utils.LogUtil.defaultLog;
import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
import static com.alibaba.nacos.core.utils.SystemUtils.STANDALONE_MODE;
/**
* Base data source
@ -52,7 +52,11 @@ import static com.alibaba.nacos.config.server.utils.LogUtil.fatalLog;
*/
@Service("basicDataSourceService")
public class BasicDataSourceServiceImpl implements DataSourceService {
private static final String JDBC_DRIVER_NAME = "com.mysql.jdbc.Driver";
private static final Logger log = LoggerFactory.getLogger(BasicDataSourceServiceImpl.class);
private static final String DEFAULT_MYSQL_DRIVER = "com.mysql.jdbc.Driver";
private static final String MYSQL_HIGH_LEVEL_DRIVER = "com.mysql.cj.jdbc.Driver";
private static String JDBC_DRIVER_NAME;
/**
* JDBC执行超时时间, 单位秒
@ -76,9 +80,22 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
private volatile int masterIndex;
private static Pattern ipPattern = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
@Autowired
private Environment env;
static {
try {
Class.forName(MYSQL_HIGH_LEVEL_DRIVER);
JDBC_DRIVER_NAME = MYSQL_HIGH_LEVEL_DRIVER;
log.info("Use Mysql 8 as the driver");
} catch (ClassNotFoundException e) {
log.info("Use Mysql as the driver");
JDBC_DRIVER_NAME = DEFAULT_MYSQL_DRIVER;
}
}
@PostConstruct
public void init() {
queryTimeout = NumberUtils.toInt(System.getProperty("QUERYTIMEOUT"), 3);
@ -242,7 +259,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
if (ds == null) {
return StringUtils.EMPTY;
}
BasicDataSource bds = (BasicDataSource)ds;
BasicDataSource bds = (BasicDataSource) ds;
return bds.getUrl();
}
@ -282,6 +299,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
}
class SelectMasterTask implements Runnable {
@Override
public void run() {
defaultLog.info("check master db.");
@ -294,7 +312,8 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
testMasterJT.setQueryTimeout(queryTimeout);
try {
testMasterJT
.update("DELETE FROM config_info WHERE data_id='com.alibaba.nacos.testMasterDB'");
.update(
"DELETE FROM config_info WHERE data_id='com.alibaba.nacos.testMasterDB'");
if (jt.getDataSource() != ds) {
fatalLog.warn("[master-db] {}", ds.getUrl());
}
@ -317,6 +336,7 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
class CheckDBHealthTask implements Runnable {
@Override
public void run() {
defaultLog.info("check db health.");
@ -329,9 +349,11 @@ public class BasicDataSourceServiceImpl implements DataSourceService {
isHealthList.set(i, Boolean.TRUE);
} catch (DataAccessException e) {
if (i == masterIndex) {
fatalLog.error("[db-error] master db {} down.", getIpFromUrl(dataSourceList.get(i).getUrl()));
fatalLog.error("[db-error] master db {} down.",
getIpFromUrl(dataSourceList.get(i).getUrl()));
} else {
fatalLog.error("[db-error] slave db {} down.", getIpFromUrl(dataSourceList.get(i).getUrl()));
fatalLog.error("[db-error] slave db {} down.",
getIpFromUrl(dataSourceList.get(i).getUrl()));
}
isHealthList.set(i, Boolean.FALSE);

View File

@ -24,7 +24,7 @@ import javax.servlet.ServletContext;
/**
* Running config
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
* @author nkorange
*/
@Component
public class RunningConfigUtils implements ApplicationListener<WebServerInitializedEvent> {
@ -32,7 +32,7 @@ public class RunningConfigUtils implements ApplicationListener<WebServerInitiali
private static int serverPort;
private static String contextPath;
private static String clusterName = "serverlist";
@Autowired
@ -52,7 +52,7 @@ public class RunningConfigUtils implements ApplicationListener<WebServerInitiali
public static String getContextPath() {
return contextPath;
}
public static String getClusterName() {
return clusterName;
}
@ -64,5 +64,5 @@ public class RunningConfigUtils implements ApplicationListener<WebServerInitiali
public static void setContextPath(String contextPath) {
RunningConfigUtils.contextPath = contextPath;
}
}

View File

@ -6,7 +6,7 @@ CREATE TABLE config_info (
group_id varchar(128) NOT NULL,
tenant_id varchar(128) default '',
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
md5 varchar(32) DEFAULT NULL,
gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
@ -31,7 +31,7 @@ CREATE TABLE his_config_info (
group_id varchar(128) NOT NULL,
tenant_id varchar(128) default '',
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
md5 varchar(32) DEFAULT NULL,
gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000',
gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000',
@ -51,7 +51,7 @@ CREATE TABLE config_info_beta (
group_id varchar(128) NOT NULL,
tenant_id varchar(128) default '',
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
beta_ips varchar(1024),
md5 varchar(32) DEFAULT NULL,
gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
@ -68,7 +68,7 @@ CREATE TABLE config_info_tag (
tenant_id varchar(128) default '',
tag_id varchar(128) NOT NULL,
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
md5 varchar(32) DEFAULT NULL,
gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
@ -84,7 +84,7 @@ CREATE TABLE config_info_aggr (
tenant_id varchar(128) default '',
datum_id varchar(255) NOT NULL,
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
constraint configinfoaggr_id_key PRIMARY KEY (id),
constraint uk_configinfoaggr_datagrouptenantdatum UNIQUE (data_id,group_id,tenant_id,datum_id));
@ -158,7 +158,7 @@ CREATE TABLE tenant_capacity (
gmt_modified timestamp DEFAULT '2010-05-05 00:00:00',
constraint tenant_capacity_id_key PRIMARY KEY (id),
constraint uk_tenant_id UNIQUE (tenant_id));
CREATE TABLE tenant_info (
id bigint NOT NULL generated by default as identity,
kp varchar(128) NOT NULL,

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.9.0</version>
<version>1.0.0-RC2</version>
</parent>
<artifactId>nacos-console</artifactId>
<!--<packaging>war</packaging>-->

View File

@ -16,7 +16,7 @@
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.naming.web.ApiCommands;
import com.alibaba.nacos.naming.controllers.OperatorController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -38,10 +38,10 @@ public class HealthController {
private static final Logger logger = LoggerFactory.getLogger(HealthController.class);
private final PersistService persistService;
private final ApiCommands apiCommands;
private final OperatorController apiCommands;
@Autowired
public HealthController(PersistService persistService, ApiCommands apiCommands) {
public HealthController(PersistService persistService, OperatorController apiCommands) {
this.persistService = persistService;
this.apiCommands = apiCommands;
}
@ -98,7 +98,7 @@ public class HealthController {
private boolean isNamingReadiness(HttpServletRequest request) {
try {
apiCommands.hello(request);
apiCommands.metrics(request);
return true;
} catch (Exception e) {
logger.error("Naming health check fail.", e);

View File

@ -48,3 +48,27 @@ db.password=4b9622f3f70c7677835ac5a6719e7caf
#security.basic.enabled=false
#nacos.security.ignore.urls=/**
nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**
management.metrics.export.elastic.enabled=false
#management.metrics.export.elastic.host=http://localhost:9200
# metrics for influx
management.metrics.export.influx.enabled=false
#management.metrics.export.influx.db=springboot
#management.metrics.export.influx.uri=http://localhost:8086
#management.metrics.export.influx.auto-create-db=true
#management.metrics.export.influx.consistency=one
#management.metrics.export.influx.compressed=true
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D
# default current work dir
server.tomcat.basedir=
nacos.naming.distro.taskDispatchThreadCount=10
nacos.naming.distro.taskDispatchPeriod=200
nacos.naming.distro.batchSyncKeyCount=1000
nacos.naming.distro.initDataRatio=0.9
nacos.naming.distro.syncRetryDelay=5000
nacos.naming.data.warmup=false
nacos.naming.expireInstance=true

View File

@ -6,7 +6,7 @@ CREATE TABLE config_info (
group_id varchar(128) NOT NULL,
tenant_id varchar(128) default '',
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
md5 varchar(32) DEFAULT NULL,
gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
@ -31,7 +31,7 @@ CREATE TABLE his_config_info (
group_id varchar(128) NOT NULL,
tenant_id varchar(128) default '',
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
md5 varchar(32) DEFAULT NULL,
gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000',
gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000',
@ -51,7 +51,7 @@ CREATE TABLE config_info_beta (
group_id varchar(128) NOT NULL,
tenant_id varchar(128) default '',
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
beta_ips varchar(1024),
md5 varchar(32) DEFAULT NULL,
gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
@ -68,7 +68,7 @@ CREATE TABLE config_info_tag (
tenant_id varchar(128) default '',
tag_id varchar(128) NOT NULL,
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
md5 varchar(32) DEFAULT NULL,
gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
@ -84,7 +84,7 @@ CREATE TABLE config_info_aggr (
tenant_id varchar(128) default '',
datum_id varchar(255) NOT NULL,
app_name varchar(128),
content LONG VARCHAR NOT NULL,
content CLOB,
gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00',
constraint configinfoaggr_id_key PRIMARY KEY (id),
constraint uk_configinfoaggr_datagrouptenantdatum UNIQUE (data_id,group_id,tenant_id,datum_id));

View File

@ -9,3 +9,8 @@
# misc
.DS_Store
npm-debug.log*
# test
test/uirecorder.log
test/reports
test/screenshots/*

View File

@ -31,7 +31,7 @@ module.exports = {
path: path.resolve(__dirname, '../dist'),
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
alias: {
'@': resolve('src'),
utils: resolve('src/utils'),
@ -51,7 +51,7 @@ module.exports = {
include: [resolve('src')],
},
{
test: /\.(js|jsx)$/,
test: /\.(js|jsx|ts|tsx)$/,
include: [resolve('src')],
use: ['babel-loader'],
},

View File

@ -9,7 +9,6 @@
"eslint": "eslint --ext .js src/",
"eslint-fix": "eslint --ext .js --fix src/"
},
"private": true,
"husky": {
"hooks": {
"pre-commit": "lint-staged"

View File

@ -0,0 +1,111 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as React from 'react';
import { MONACO_OPTIONS } from './constant';
import './index.scss';
interface PropsType {
dispatch: (obj: Object) => void;
options: Object;
value: string;
language: string;
width: number;
height: number;
onChange: (value: string) => void;
}
interface StateType {}
class MonacoEditor extends React.Component<PropsType, StateType> {
static displayName = 'MonacoEditor';
private nodeRef: any = React.createRef();
public monacoEditor: any = null;
public state: StateType;
public props: PropsType;
constructor(props: PropsType) {
super(props);
}
componentWillReceiveProps(nextProps): void {
if (!this.monacoEditor) {
return;
}
const { value = '', language = 'js', width, height, options = {} } = this.props;
if (value !== nextProps.value) {
this.monacoEditor.setValue(nextProps.value || '');
}
if (language !== nextProps.language) {
this.monacoEditor.editor.setModelLanguage(this.monacoEditor.getModel(), nextProps.language);
}
if (this.monacoEditor && (width !== nextProps.width || height !== nextProps.height)) {
this.monacoEditor.layout();
}
if (this.monacoEditor && nextProps.options && options !== nextProps.options) {
this.monacoEditor.updateOptions({ ...MONACO_OPTIONS, ...nextProps.options });
}
}
componentDidMount(): void {
if (!window.monaco) {
window.importEditor &&
window.importEditor(() => {
this.initMoacoEditor();
});
} else {
this.initMoacoEditor();
}
}
componentWillUnmount(): void {
this.monacoEditor && this.monacoEditor.dispose();
this.nodeRef = null;
}
initMoacoEditor(): void {
const { options = {}, language = 'js', value = '' } = this.props;
try {
this.monacoEditor = window.monaco.editor.create(this.nodeRef && this.nodeRef.current, {
...MONACO_OPTIONS,
...options,
language,
value,
});
this.editorDidMount(this.monacoEditor);
} catch (error) {}
}
editorDidMount(editor: any) {
const { onChange } = this.props;
editor.onDidChangeModelContent(event => {
const value = editor.getValue();
typeof onChange === 'function' && onChange(value);
});
}
render(): HTMLElement {
const { width = '100%', height = 0 } = this.props;
const style = {
width,
height,
};
return <div ref={this.nodeRef} style={style} />;
}
}
export default MonacoEditor;

View File

@ -0,0 +1,27 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const MONACO_OPTIONS: Object = {
codeLens: true,
selectOnLineNumbers: true,
roundedSelection: false,
readOnly: false,
lineNumbersMinChars: true,
theme: 'vs-dark',
wordWrapColumn: 120,
folding: true,
showFoldingControls: 'always',
wordWrap: 'wordWrapColumn',
cursorStyle: 'line',
automaticLayout: true,
};

View File

@ -0,0 +1,12 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

View File

@ -0,0 +1,16 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import MonacoEditor from './MonacoEditor';
export default MonacoEditor;

View File

@ -390,7 +390,8 @@ class MainLayout extends React.Component {
refreshNav() {
const { navList } = this.state;
const { functionMode } = this.props;
const { location, history, functionMode } = this.props;
const [configUrl, serviceUrl] = ['/configurationManagement', '/serviceManagement'];
this.setState(
{
navList: navList.map(item => {
@ -411,6 +412,12 @@ class MainLayout extends React.Component {
},
() => this.setState({ navRow: this.nacosGetNav(navList) }, () => this.renderNav())
);
if (functionMode === 'config' && location.pathname === serviceUrl) {
history.push(configUrl);
}
if (functionMode === 'naming' && location.pathname === configUrl) {
history.push(serviceUrl);
}
}
componentWillReceiveProps() {
@ -440,7 +447,7 @@ class MainLayout extends React.Component {
) : (
<div
style={{ textIndent: 0, display: !version ? 'none' : 'block' }}
className={'product-nav-title'}
className="product-nav-title"
title={nacosName}
>
<span>{nacosName}</span>
@ -483,7 +490,12 @@ class MainLayout extends React.Component {
<div>{this.props.children}</div>
) : (
<div
style={{ height: 300, lineHeight: '300px', textAlign: 'center', fontSize: '18px' }}
style={{
height: 300,
lineHeight: 300,
textAlign: 'center',
fontSize: 18,
}}
>
{doesNotExist}
</div>

View File

@ -78,6 +78,7 @@ const I18N_CONF = {
query: 'Search',
pubNoData: 'No results found.',
columnServiceName: 'Service Name',
groupName: 'Group Name',
columnClusterCount: 'Cluster Count',
columnIpCount: 'Instance Count',
columnHealthyInstanceCount: 'Healthy Instance Count',
@ -105,31 +106,24 @@ const I18N_CONF = {
metadata: 'Metadata',
selector: 'Selector',
type: 'Type',
healthCheckPattern: 'Health check pattern',
groupName: 'Group Name',
protectThreshold: 'Protect Threshold',
serviceName: 'Service Name',
editService: 'Edit Service',
healthCheckPatternService: 'Service',
healthCheckPatternClient: 'Client',
healthCheckPatternNone: 'None',
},
EditServiceDialog: {
createService: 'Create Service',
updateService: 'Edit Service',
serviceName: 'Service Name',
metadata: 'Metadata',
groupName: 'Group Name',
type: 'Type',
typeLabel: 'Label',
typeNone: 'None',
selector: 'Selector',
protectThreshold: 'Protect Threshold',
healthCheckPattern: 'Health check pattern',
healthCheckPatternService: 'Service',
healthCheckPatternClient: 'Client',
healthCheckPatternNone: 'None',
serviceNameRequired: 'Please enter a service name',
protectThresholdRequired: 'Please enter a protect threshold',
healthCheckModeRequired: 'Please select health check pattern',
},
InstanceTable: {
operation: 'Operation',
@ -140,6 +134,7 @@ const I18N_CONF = {
editor: 'Edit',
offline: 'Offline',
online: 'Online',
ephemeral: 'Ephemeral',
},
EditInstanceDialog: {
port: 'Port',

View File

@ -78,6 +78,7 @@ const I18N_CONF = {
query: '查询',
pubNoData: '没有数据',
columnServiceName: '服务名',
groupName: '分组',
columnClusterCount: '集群数目',
columnIpCount: '实例数',
columnHealthyInstanceCount: '健康实例数',
@ -105,31 +106,24 @@ const I18N_CONF = {
metadata: '元数据',
selector: '表达式',
type: '服务路由类型',
healthCheckPattern: '健康检查模式',
groupName: '分组',
protectThreshold: '保护阈值',
serviceName: '服务名',
editService: '编辑服务',
healthCheckPatternService: '服务端',
healthCheckPatternClient: '客户端',
healthCheckPatternNone: '禁止',
},
EditServiceDialog: {
createService: '创建服务',
updateService: '更新服务',
serviceName: '服务名',
metadata: '元数据',
groupName: '分组',
type: '服务路由类型',
typeLabel: '标签',
typeNone: '默认',
selector: '表达式',
protectThreshold: '保护阈值',
healthCheckPattern: '健康检查模式',
healthCheckPatternService: '服务端',
healthCheckPatternClient: '客户端',
healthCheckPatternNone: '禁止',
serviceNameRequired: '请输入服务名',
protectThresholdRequired: '请输入保护阈值',
healthCheckModeRequired: '请选择健康检查模式',
},
InstanceTable: {
operation: '操作',
@ -140,6 +134,7 @@ const I18N_CONF = {
editor: '编辑',
offline: '下线',
online: '上线',
ephemeral: '临时实例',
},
EditInstanceDialog: {
port: '端口',

View File

@ -15,7 +15,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import { request } from '../../../globalLib';
import { Dialog, Form, Input, Switch, Select, Message, ConfigProvider } from '@alifd/next';
import { DIALOG_FORM_LAYOUT } from './constant';
import { DIALOG_FORM_LAYOUT, METADATA_SEPARATOR, METADATA_ENTER } from './constant';
import MonacoEditor from 'components/MonacoEditor';
import { replaceEnter, processMetaData } from 'utils/nacosutil';
@ConfigProvider.config
class EditClusterDialog extends React.Component {
@ -40,9 +42,7 @@ class EditClusterDialog extends React.Component {
show(_editCluster) {
let editCluster = _editCluster;
const { metadata = {} } = editCluster;
editCluster.metadataText = Object.keys(metadata)
.map(k => `${k}=${metadata[k]}`)
.join(',');
editCluster.metadataText = processMetaData(METADATA_ENTER)(metadata);
this.setState({
editCluster,
editClusterDialogVisible: true,
@ -69,7 +69,7 @@ class EditClusterDialog extends React.Component {
data: {
serviceName,
clusterName: name,
metadata: metadataText,
metadata: replaceEnter(METADATA_SEPARATOR)(metadataText),
checkPort: defaultCheckPort,
useInstancePort4Check: useIPPort4Check,
healthChecker: JSON.stringify(healthChecker),
@ -113,6 +113,7 @@ class EditClusterDialog extends React.Component {
return (
<Dialog
className="cluster-edit-dialog"
style={{ width: 600 }}
title={updateCluster}
visible={editClusterDialogVisible}
onOk={() => this.onConfirm()}
@ -128,6 +129,7 @@ class EditClusterDialog extends React.Component {
>
<Select.Option value="TCP">TCP</Select.Option>
<Select.Option value="HTTP">HTTP</Select.Option>
<Select.Option value="NONE">NONE</Select.Option>
</Select>
</Form.Item>
<Form.Item label={`${checkPort}:`}>
@ -143,37 +145,27 @@ class EditClusterDialog extends React.Component {
onChange={useIPPort4Check => this.onChangeCluster({ useIPPort4Check })}
/>
</Form.Item>
{type === 'HTTP' ? (
<div>
<div className="next-row next-form-item next-left next-medium">
<div className="next-col next-col-fixed-12 next-form-item-label">
<label>{`${checkPath}:`}</label>
</div>
<div className="next-col next-col-12 next-form-item-control">
<Input
className="in-text"
value={path}
onChange={path => healthCheckerChange({ path })}
/>
</div>
</div>
<div className="next-row next-form-item next-left next-medium">
<div className="next-col next-col-fixed-12 next-form-item-label">
<label>{`${checkHeaders}:`}</label>
</div>
<div className="next-col next-col-12 next-form-item-control">
<Input
className="in-text"
value={headers}
onChange={headers => healthCheckerChange({ headers })}
/>
</div>
</div>
</div>
) : null}
{type === 'HTTP' && [
<Form.Item label={`${checkPath}:`}>
<Input
className="in-text"
value={path}
onChange={path => healthCheckerChange({ path })}
/>
</Form.Item>,
<Form.Item label={`${checkHeaders}:`}>
<Input
className="in-text"
value={headers}
onChange={headers => healthCheckerChange({ headers })}
/>
</Form.Item>,
]}
<Form.Item label={`${locale.metadata}:`}>
<Input
className="in-text"
<MonacoEditor
language={'properties'}
width={'100%'}
height={200}
value={metadataText}
onChange={metadataText => this.onChangeCluster({ metadataText })}
/>

View File

@ -15,7 +15,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import { request } from '../../../globalLib';
import { Dialog, Form, Input, Switch, Message, ConfigProvider } from '@alifd/next';
import { DIALOG_FORM_LAYOUT } from './constant';
import { DIALOG_FORM_LAYOUT, METADATA_ENTER, METADATA_SEPARATOR } from './constant';
import MonacoEditor from 'components/MonacoEditor';
import { replaceEnter, processMetaData } from 'utils/nacosutil';
@ConfigProvider.config
class EditInstanceDialog extends React.Component {
@ -43,9 +45,7 @@ class EditInstanceDialog extends React.Component {
let editInstance = _editInstance;
const { metadata = {} } = editInstance;
if (Object.keys(metadata).length) {
editInstance.metadataText = Object.keys(metadata)
.map(k => `${k}=${metadata[k]}`)
.join(',');
editInstance.metadataText = processMetaData(METADATA_ENTER)(metadata);
}
this.setState({ editInstance, editInstanceDialogVisible: true });
}
@ -56,11 +56,20 @@ class EditInstanceDialog extends React.Component {
onConfirm() {
const { serviceName, clusterName, getInstanceList, openLoading, closeLoading } = this.props;
const { ip, port, weight, enabled, metadataText } = this.state.editInstance;
const { ip, port, ephemeral, weight, enabled, metadataText } = this.state.editInstance;
request({
method: 'PUT',
url: 'v1/ns/instance',
data: { serviceName, clusterName, ip, port, weight, enable: enabled, metadata: metadataText },
data: {
serviceName,
clusterName,
ip,
port,
ephemeral,
weight,
enable: enabled,
metadata: replaceEnter(METADATA_SEPARATOR)(metadataText),
},
dataType: 'text',
beforeSend: () => openLoading(),
success: res => {
@ -71,6 +80,7 @@ class EditInstanceDialog extends React.Component {
this.hide();
getInstanceList();
},
error: e => Message.error(e.responseText || 'error'),
complete: () => closeLoading(),
});
}
@ -89,6 +99,7 @@ class EditInstanceDialog extends React.Component {
<Dialog
className="instance-edit-dialog"
title={locale.updateInstance}
style={{ width: 600 }}
visible={editInstanceDialogVisible}
onOk={() => this.onConfirm()}
onCancel={() => this.hide()}
@ -115,8 +126,10 @@ class EditInstanceDialog extends React.Component {
/>
</Form.Item>
<Form.Item label={`${locale.metadata}:`}>
<Input
className="in-text"
<MonacoEditor
language={'properties'}
width={'100%'}
height={200}
value={editInstance.metadataText}
onChange={metadataText => this.onChangeCluster({ metadataText })}
/>

View File

@ -15,7 +15,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import { request } from '../../../globalLib';
import { Dialog, Form, Input, Select, Message, ConfigProvider } from '@alifd/next';
import { DIALOG_FORM_LAYOUT } from './constant';
import { DIALOG_FORM_LAYOUT, METADATA_SEPARATOR, METADATA_ENTER } from './constant';
import MonacoEditor from 'components/MonacoEditor';
import { replaceEnter, processMetaData } from 'utils/nacosutil';
@ConfigProvider.config
class EditServiceDialog extends React.Component {
@ -33,7 +35,7 @@ class EditServiceDialog extends React.Component {
isCreate: false,
editService: {},
editServiceDialogVisible: false,
errors: { name: {}, protectThreshold: {}, healthCheckMode: {} },
errors: { name: {}, protectThreshold: {} },
};
this.show = this.show.bind(this);
}
@ -42,9 +44,7 @@ class EditServiceDialog extends React.Component {
let editService = _editService;
const { metadata = {}, name } = editService;
if (Object.keys(metadata).length) {
editService.metadataText = Object.keys(metadata)
.map(k => `${k}=${metadata[k]}`)
.join(',');
editService.metadataText = processMetaData(METADATA_ENTER)(metadata);
}
this.setState({ editService, editServiceDialogVisible: true, isCreate: !name });
}
@ -59,7 +59,6 @@ class EditServiceDialog extends React.Component {
const helpMap = {
name: locale.serviceNameRequired,
protectThreshold: locale.protectThresholdRequired,
healthCheckMode: locale.healthCheckModeRequired,
};
if (field.protectThreshold === 0) {
field.protectThreshold = '0';
@ -77,16 +76,16 @@ class EditServiceDialog extends React.Component {
onConfirm() {
const { isCreate } = this.state;
const editService = Object.assign({}, this.state.editService);
const { name, protectThreshold, healthCheckMode, metadataText, selector } = editService;
if (!this.validator({ name, protectThreshold, healthCheckMode })) return;
const { name, protectThreshold, groupName, metadataText = '', selector } = editService;
if (!this.validator({ name, protectThreshold })) return;
request({
method: isCreate ? 'POST' : 'PUT',
url: 'v1/ns/service',
data: {
serviceName: name,
groupName: groupName || 'DEFAULT_GROUP',
protectThreshold,
healthCheckMode,
metadata: metadataText,
metadata: replaceEnter(METADATA_SEPARATOR)(metadataText),
selector: JSON.stringify(selector),
},
dataType: 'text',
@ -109,7 +108,7 @@ class EditServiceDialog extends React.Component {
}
onChangeCluster(changeVal) {
const resetKey = ['name', 'protectThreshold', 'healthCheckMode'];
const resetKey = ['name', 'protectThreshold'];
const { editService = {} } = this.state;
const errors = Object.assign({}, this.state.errors);
resetKey.forEach(key => {
@ -134,7 +133,7 @@ class EditServiceDialog extends React.Component {
const {
name,
protectThreshold,
healthCheckMode,
groupName,
metadataText,
selector = { type: 'none' },
} = editService;
@ -172,24 +171,19 @@ class EditServiceDialog extends React.Component {
onChange={protectThreshold => this.onChangeCluster({ protectThreshold })}
/>
</Form.Item>
<Form.Item
required
{...formItemLayout}
label={`${locale.healthCheckPattern}:`}
{...errors.healthCheckMode}
>
<Select
className="full-width"
defaultValue={healthCheckMode}
onChange={healthCheckMode => this.onChangeCluster({ healthCheckMode })}
>
<Select.Option value="server">{locale.healthCheckPatternService}</Select.Option>
<Select.Option value="client">{locale.healthCheckPatternClient}</Select.Option>
<Select.Option value="none">{locale.healthCheckPatternNone}</Select.Option>
</Select>
<Form.Item {...formItemLayout} label={`${locale.groupName}:`}>
<Input
defaultValue={groupName}
placeholder="DEFAULT_GROUP"
readOnly={!isCreate}
onChange={groupName => this.onChangeCluster({ groupName })}
/>
</Form.Item>
<Form.Item label={`${locale.metadata}:`} {...formItemLayout}>
<Input.TextArea
<MonacoEditor
language={'properties'}
width={'100%'}
height={200}
value={metadataText}
onChange={metadataText => this.onChangeCluster({ metadataText })}
/>

View File

@ -14,7 +14,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { request } from '../../../globalLib';
import { Button, ConfigProvider, Pagination, Table } from '@alifd/next';
import { Button, ConfigProvider, Message, Pagination, Table } from '@alifd/next';
import { HEALTHY_COLOR_MAPPING } from './constant';
import EditInstanceDialog from './EditInstanceDialog';
@ -56,12 +56,12 @@ class InstanceTable extends React.Component {
if (!clusterName) return;
const { pageSize, pageNum } = this.state;
request({
url: 'v1/ns/catalog/instanceList',
url: 'v1/ns/catalog/instances',
data: {
serviceName,
clusterName,
pgSize: pageSize,
startPg: pageNum,
pageSize,
pageNo: pageNum,
},
beforeSend: () => this.openLoading(),
success: instance => this.setState({ instance }),
@ -75,10 +75,8 @@ class InstanceTable extends React.Component {
switchState(index, record) {
const { instance } = this.state;
const { ip, port, weight, enabled, metadata } = record;
const { ip, port, ephemeral, weight, enabled, metadata } = record;
const { clusterName, serviceName } = this.props;
const newVal = Object.assign({}, instance);
newVal.list[index].enabled = !enabled;
request({
method: 'PUT',
url: 'v1/ns/instance',
@ -87,13 +85,19 @@ class InstanceTable extends React.Component {
clusterName,
ip,
port,
ephemeral,
weight,
enable: !enabled,
metadata: JSON.stringify(metadata),
},
dataType: 'text',
beforeSend: () => this.openLoading(),
success: () => this.setState({ instance: newVal }),
success: () => {
const newVal = Object.assign({}, instance);
newVal.list[index].enabled = !enabled;
this.setState({ instance: newVal });
},
error: e => Message.error(e.responseText || 'error'),
complete: () => this.closeLoading(),
});
}
@ -113,6 +117,12 @@ class InstanceTable extends React.Component {
<Table dataSource={instance.list} loading={loading} getRowProps={this.rowColor}>
<Table.Column width={138} title="IP" dataIndex="ip" />
<Table.Column width={100} title={locale.port} dataIndex="port" />
<Table.Column
width={100}
title={locale.ephemeral}
dataIndex="ephemeral"
cell={val => `${val}`}
/>
<Table.Column width={100} title={locale.weight} dataIndex="weight" />
<Table.Column
width={100}

View File

@ -14,11 +14,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import { request } from '@/globalLib';
import { Input, Button, Card, ConfigProvider, Form, Loading } from '@alifd/next';
import { Input, Button, Card, ConfigProvider, Form, Loading, Message } from '@alifd/next';
import EditServiceDialog from './EditServiceDialog';
import EditClusterDialog from './EditClusterDialog';
import InstanceTable from './InstanceTable';
import { getParameter } from 'utils/nacosutil';
import { getParameter, processMetaData } from 'utils/nacosutil';
import MonacoEditor from 'components/MonacoEditor';
import { MONACO_READONLY_OPTIONS, METADATA_ENTER } from './constant';
import './ServiceDetail.scss';
const FormItem = Form.Item;
@ -43,6 +45,7 @@ class ServiceDetail extends React.Component {
this.editClusterDialog = React.createRef();
this.state = {
serviceName: getParameter(props.location.search, 'name'),
groupName: getParameter(props.location.search, 'groupName'),
loading: false,
currentPage: 1,
clusters: [],
@ -62,11 +65,12 @@ class ServiceDetail extends React.Component {
}
getServiceDetail() {
const { serviceName } = this.state;
const { serviceName, groupName } = this.state;
request({
url: `v1/ns/catalog/serviceDetail?serviceName=${serviceName}`,
url: `v1/ns/catalog/service?serviceName=${serviceName}&groupName=${groupName}`,
beforeSend: () => this.openLoading(),
success: ({ clusters = [], service = {} }) => this.setState({ service, clusters }),
error: e => Message.error(e.responseText || 'error'),
complete: () => this.closeLoading(),
});
}
@ -91,14 +95,7 @@ class ServiceDetail extends React.Component {
const { locale = {} } = this.props;
const { serviceName, loading, service = {}, clusters } = this.state;
const { metadata = {}, selector = {} } = service;
const healthCheckMap = {
server: locale.healthCheckPatternService,
client: locale.healthCheckPatternClient,
none: locale.healthCheckPatternNone,
};
const metadataText = Object.keys(metadata)
.map(key => `${key}=${metadata[key]}`)
.join(',');
const metadataText = processMetaData(METADATA_ENTER)(metadata);
return (
<div className="main-container service-detail">
<Loading
@ -135,14 +132,20 @@ class ServiceDetail extends React.Component {
<FormItem label={`${locale.serviceName}:`}>
<Input value={service.name} readOnly />
</FormItem>
<FormItem label={`${locale.groupName}:`}>
<Input value={service.groupName} readOnly />
</FormItem>
<FormItem label={`${locale.protectThreshold}:`}>
<Input value={service.protectThreshold} readOnly />
</FormItem>
<FormItem label={`${locale.healthCheckPattern}:`}>
<Input value={healthCheckMap[service.healthCheckMode]} readOnly />
</FormItem>
<FormItem label={`${locale.metadata}:`}>
<Input value={metadataText} readOnly />
<MonacoEditor
language={'properties'}
width={'100%'}
height={200}
value={metadataText}
options={MONACO_READONLY_OPTIONS}
/>
</FormItem>
<FormItem label={`${locale.type}:`}>
<Input value={selector.type} readOnly />

View File

@ -12,11 +12,19 @@
*/
export const DIALOG_FORM_LAYOUT = {
labelCol: { fixedSpan: 12 },
wrapperCol: { span: 12 },
labelCol: { fixedSpan: 6 },
wrapperCol: { span: 18 },
};
export const HEALTHY_COLOR_MAPPING = {
true: 'green',
false: 'red',
};
export const MONACO_READONLY_OPTIONS = {
readOnly: true,
};
export const METADATA_SEPARATOR = ',';
export const METADATA_ENTER = '\r\n';

View File

@ -74,10 +74,15 @@ class ServiceList extends React.Component {
}
queryServiceList() {
const { currentPage, pageSize, keyword } = this.state;
const parameter = [`startPg=${currentPage}`, `pgSize=${pageSize}`, `keyword=${keyword}`];
const { currentPage, pageSize, keyword, withInstances = false } = this.state;
const parameter = [
`withInstances=${withInstances}`,
`pageNo=${currentPage}`,
`pageSize=${pageSize}`,
`keyword=${keyword}`,
];
request({
url: `v1/ns/catalog/serviceList?${parameter.join('&')}`,
url: `v1/ns/catalog/services?${parameter.join('&')}`,
beforeSend: () => this.openLoading(),
success: ({ count = 0, serviceList = [] } = {}) => {
this.setState({
@ -99,7 +104,7 @@ class ServiceList extends React.Component {
setTimeout(() => this.queryServiceList());
};
deleteService(serviceName) {
deleteService(service) {
const { locale = {} } = this.props;
const { prompt, promptDelete } = locale;
Dialog.confirm({
@ -108,7 +113,7 @@ class ServiceList extends React.Component {
onOk: () => {
request({
method: 'DELETE',
url: `v1/ns/service?serviceName=${serviceName}`,
url: `v1/ns/service?serviceName=${service.name}&groupName=${service.groupName}`,
dataType: 'text',
beforeSend: () => this.openLoading(),
success: res => {
@ -155,7 +160,7 @@ class ServiceList extends React.Component {
<div className="main-container service-management">
<Loading
shape="flower"
style={{ position: 'relative' }}
style={{ position: 'relative', width: '100%' }}
visible={this.state.loading}
tip="Loading..."
color="#333"
@ -181,6 +186,9 @@ class ServiceList extends React.Component {
style={{ width: 200 }}
value={keyword}
onChange={keyword => this.setState({ keyword })}
onPressEnter={() =>
this.setState({ currentPage: 1 }, () => this.queryServiceList())
}
/>
</FormItem>
<FormItem label="">
@ -204,12 +212,11 @@ class ServiceList extends React.Component {
<Col span="24" style={{ padding: 0 }}>
<Table
dataSource={this.state.dataSource}
fixedHeader
maxBodyHeight={530}
locale={{ empty: pubNoData }}
getRowProps={row => this.rowColor(row)}
>
<Column title={locale.columnServiceName} dataIndex="name" />
<Column title={locale.groupName} dataIndex="groupName" />
<Column title={locale.columnClusterCount} dataIndex="clusterCount" />
<Column title={locale.columnIpCount} dataIndex="ipCount" />
<Column
@ -224,7 +231,9 @@ class ServiceList extends React.Component {
<Button
type="normal"
onClick={() =>
this.props.history.push(`/serviceDetail?name=${record.name}`)
this.props.history.push(
`/serviceDetail?name=${record.name}&groupName=${record.groupName}`
)
}
>
{detail}
@ -232,7 +241,7 @@ class ServiceList extends React.Component {
<Button
style={{ marginLeft: 12 }}
type="normal"
onClick={() => this.deleteService(record.name)}
onClick={() => this.deleteService(record)}
>
{deleteAction}
</Button>

View File

@ -46,3 +46,31 @@ export const getParameter = (search, name) => {
const [, value = ''] = hit.split('=');
return value;
};
/**
* 将回车符和空格替换
* @param {*} separator 替换符
*/
export const replaceEnter = (separator = ',') => text => {
if (typeof text !== 'string') {
return text;
}
return text
.replace(/\r\n/g, separator)
.replace(/[\r\n]/g, separator)
.replace(/[\t\s]/g, '');
};
/**
* 处理metaData对象生成可显示对象
*/
export const processMetaData = (separator = ',') => (metadata = {}) => {
if (Object.prototype.toString.call(metadata) !== '[object Object]') {
return '';
}
return Object.keys(metadata)
.map(key => `${key}=${metadata[key]}`)
.join(separator);
};

View File

@ -0,0 +1,17 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
# Apply for all files
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

View File

@ -0,0 +1,9 @@
.DS_Store
.idea
node_modules
npm-debug.log
uirecorder.log
reports
screenshots/**/*.png
screenshots/**/*.html
screenshots/**/*.json

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