commit
95009390e5
33
CHANGELOG.md
33
CHANGELOG.md
@ -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.
|
||||
|
21
README.md
21
README.md
@ -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)
|
||||
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ public class NacosException extends Exception {
|
||||
}
|
||||
|
||||
public NacosException(int errCode, String errMsg) {
|
||||
super(errMsg);
|
||||
this.errCode = errCode;
|
||||
this.errMsg = errMsg;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ import com.alibaba.nacos.api.exception.NacosException;
|
||||
/**
|
||||
* Naming Factory
|
||||
*
|
||||
* @author dungu.zpf
|
||||
* @author nkorange
|
||||
*/
|
||||
public class NamingFactory {
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -18,7 +18,7 @@ package com.alibaba.nacos.api.naming.listener;
|
||||
/**
|
||||
* Event Interface
|
||||
*
|
||||
* @author dungu.zpf
|
||||
* @author nkorange
|
||||
*/
|
||||
public interface Event {
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
/**
|
||||
* Naming Event
|
||||
*
|
||||
* @author dungu.zpf
|
||||
* @author nkorange
|
||||
*/
|
||||
public class NamingEvent implements Event {
|
||||
|
||||
|
@ -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";
|
||||
|
||||
|
@ -21,7 +21,7 @@ import java.util.Map;
|
||||
/**
|
||||
* Cluster
|
||||
*
|
||||
* @author dungu.zpf
|
||||
* @author nkorange
|
||||
*/
|
||||
public class Cluster {
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import java.util.List;
|
||||
/**
|
||||
* ListView
|
||||
*
|
||||
* @author dungu.zpf
|
||||
* @author nkorange
|
||||
*/
|
||||
public class ListView<T> {
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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 = "";
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
||||
|
@ -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> {
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
||||
|
@ -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> {
|
||||
/**
|
||||
|
@ -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() {
|
||||
}
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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>-->
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -9,3 +9,8 @@
|
||||
# misc
|
||||
.DS_Store
|
||||
npm-debug.log*
|
||||
|
||||
# test
|
||||
test/uirecorder.log
|
||||
test/reports
|
||||
test/screenshots/*
|
@ -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'],
|
||||
},
|
||||
|
@ -9,7 +9,6 @@
|
||||
"eslint": "eslint --ext .js src/",
|
||||
"eslint-fix": "eslint --ext .js --fix src/"
|
||||
},
|
||||
"private": true,
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
|
@ -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;
|
@ -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,
|
||||
};
|
@ -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.
|
||||
*/
|
@ -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;
|
@ -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>
|
||||
|
@ -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',
|
||||
|
@ -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: '端口',
|
||||
|
@ -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 })}
|
||||
/>
|
||||
|
@ -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 })}
|
||||
/>
|
||||
|
@ -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 })}
|
||||
/>
|
||||
|
@ -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}
|
||||
|
@ -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 />
|
||||
|
@ -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';
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
|
9
console/src/main/resources/static/console-fe/test/.gitignore
vendored
Normal file
9
console/src/main/resources/static/console-fe/test/.gitignore
vendored
Normal 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
Loading…
Reference in New Issue
Block a user