Merge pull request #5707 from KomachiSion/feature_support_grpc_core

Merge codes from develop branch
This commit is contained in:
杨翊 SionYang 2021-05-14 12:56:06 +08:00 committed by GitHub
commit 04cc4da340
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 1728 additions and 425 deletions

View File

@ -1,16 +0,0 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[{package.json,.travis.yml}]
indent_size = 2

28
NOTICE
View File

@ -31,8 +31,30 @@ Also, please refer to each LICENSE.<component>.txt file, which is located in
the 'license' directory of the distribution file, for the license terms of the
components that this product depends on.
------
This product has a bundle Protocol Buffers
com.alibaba.nacos.common.utils.InetAddressValidator.java in this product is
copied from com.dynatrace.openkit.core.util.InetAddressValidator.java of openkit-java project.
https://github.com/Dynatrace/openkit-java
openkit-java
======================
Copyright 2018-2021 Dynatrace LLC
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.
------
This product has a bundle Protocol Buffers<72><73>
Protocol Buffers
=======================
Protocol Buffers for Go with Gadgets
@ -41,7 +63,7 @@ Copyright (c) 2013, The GoGo Authors. All rights reserved.
http://github.com/gogo/protobuf
------
This product has a bundle Istio
This product has a bundle Istio<EFBFBD><EFBFBD>
Istio
=======================
@ -57,4 +79,4 @@ This product has a bundle Istio
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.
limitations under the License.

View File

@ -36,11 +36,6 @@
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-naming</artifactId>

View File

@ -83,6 +83,8 @@ public class Constants {
public static final String GLOBAL_ADMIN = "globalAdmin";
public static final String USERNAME = "username";
public static final String TOKEN_REFRESH_WINDOW = "tokenRefreshWindow";
/**

View File

@ -113,21 +113,10 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>

View File

@ -0,0 +1,37 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.common;
/**
* config common constants.
*
* @author Nacos
*/
public class ConfigConstants {
public static final String TENANT = "tenant";
public static final String DATA_ID = "dataId";
public static final String GROUP = "group";
public static final String CONTENT = "content";
public static final String CONFIG_TYPE = "configType";
public static final String ENCRYPTED_DATA_KEY = "encryptedDataKey";
}

View File

@ -22,6 +22,11 @@ import com.alibaba.nacos.api.config.filter.IConfigRequest;
import java.util.HashMap;
import java.util.Map;
import static com.alibaba.nacos.client.config.common.ConfigConstants.CONTENT;
import static com.alibaba.nacos.client.config.common.ConfigConstants.DATA_ID;
import static com.alibaba.nacos.client.config.common.ConfigConstants.GROUP;
import static com.alibaba.nacos.client.config.common.ConfigConstants.TENANT;
/**
* Config Request.
*
@ -34,35 +39,35 @@ public class ConfigRequest implements IConfigRequest {
private final IConfigContext configContext = new ConfigContext();
public String getTenant() {
return (String) param.get("tenant");
return (String) param.get(TENANT);
}
public void setTenant(String tenant) {
param.put("tenant", tenant);
param.put(TENANT, tenant);
}
public String getDataId() {
return (String) param.get("dataId");
return (String) param.get(DATA_ID);
}
public void setDataId(String dataId) {
param.put("dataId", dataId);
param.put(DATA_ID, dataId);
}
public String getGroup() {
return (String) param.get("group");
return (String) param.get(GROUP);
}
public void setGroup(String group) {
param.put("group", group);
param.put(GROUP, group);
}
public String getContent() {
return (String) param.get("content");
return (String) param.get(CONTENT);
}
public void setContent(String content) {
param.put("content", content);
param.put(CONTENT, content);
}
public void getType() {

View File

@ -22,6 +22,13 @@ import com.alibaba.nacos.api.config.filter.IConfigResponse;
import java.util.HashMap;
import java.util.Map;
import static com.alibaba.nacos.client.config.common.ConfigConstants.CONFIG_TYPE;
import static com.alibaba.nacos.client.config.common.ConfigConstants.CONTENT;
import static com.alibaba.nacos.client.config.common.ConfigConstants.DATA_ID;
import static com.alibaba.nacos.client.config.common.ConfigConstants.ENCRYPTED_DATA_KEY;
import static com.alibaba.nacos.client.config.common.ConfigConstants.GROUP;
import static com.alibaba.nacos.client.config.common.ConfigConstants.TENANT;
/**
* Config Response.
*
@ -34,51 +41,51 @@ public class ConfigResponse implements IConfigResponse {
private final IConfigContext configContext = new ConfigContext();
public String getTenant() {
return (String) param.get("tenant");
return (String) param.get(TENANT);
}
public void setTenant(String tenant) {
param.put("tenant", tenant);
param.put(TENANT, tenant);
}
public String getDataId() {
return (String) param.get("dataId");
return (String) param.get(DATA_ID);
}
public void setDataId(String dataId) {
param.put("dataId", dataId);
param.put(DATA_ID, dataId);
}
public String getGroup() {
return (String) param.get("group");
return (String) param.get(GROUP);
}
public void setGroup(String group) {
param.put("group", group);
param.put(GROUP, group);
}
public String getContent() {
return (String) param.get("content");
return (String) param.get(CONTENT);
}
public void setContent(String content) {
param.put("content", content);
param.put(CONTENT, content);
}
public String getConfigType() {
return (String) param.get("configType");
return (String) param.get(CONFIG_TYPE);
}
public void setConfigType(String configType) {
param.put("configType", configType);
param.put(CONFIG_TYPE, configType);
}
public String getEncryptedDataKey() {
return (String) param.get("encryptedDataKey");
return (String) param.get(ENCRYPTED_DATA_KEY);
}
public void setEncryptedDataKey(String encryptedDataKey) {
param.put("encryptedDataKey", encryptedDataKey);
param.put(ENCRYPTED_DATA_KEY, encryptedDataKey);
}
@Override

View File

@ -48,7 +48,9 @@ public class ParamUtil {
private static String appName;
private static final String DEFAULT_SERVER_PORT;
private static final String DEFAULT_SERVER_PORT = "8848";
private static String serverPort;
private static String clientVersion = "unknown";
@ -56,22 +58,38 @@ public class ParamUtil {
private static double perTaskConfigSize = 3000;
private static final String NACOS_CLIENT_APP_KEY = "nacos.client.appKey";
private static final String BLANK_STR = "";
private static final String NACOS_CLIENT_CONTEXTPATH_KEY = "nacos.client.contextPath";
private static final String DEFAULT_NACOS_CLIENT_CONTEXTPATH = "nacos";
private static final String NACOS_SERVER_PORT_KEY = "nacos.server.port";
private static final String NACOS_CONNECT_TIMEOUT_KEY = "NACOS.CONNECT.TIMEOUT";
private static final String DEFAULT_NACOS_CONNECT_TIMEOUT = "1000";
private static final String PER_TASK_CONFIG_SIZE_KEY = "PER_TASK_CONFIG_SIZE";
private static final String DEFAULT_PER_TASK_CONFIG_SIZE_KEY = "3000";
static {
// 客户端身份信息
appKey = System.getProperty("nacos.client.appKey", "");
// Client identity information
appKey = System.getProperty(NACOS_CLIENT_APP_KEY, BLANK_STR);
defaultContextPath = System.getProperty("nacos.client.contextPath", "nacos");
defaultContextPath = System.getProperty(NACOS_CLIENT_CONTEXTPATH_KEY, DEFAULT_NACOS_CLIENT_CONTEXTPATH);
appName = AppNameUtils.getAppName();
String defaultServerPortTmp = "8848";
DEFAULT_SERVER_PORT = System.getProperty("nacos.server.port", defaultServerPortTmp);
LOGGER.info("[settings] [req-serv] nacos-server port:{}", DEFAULT_SERVER_PORT);
serverPort = System.getProperty(NACOS_SERVER_PORT_KEY, DEFAULT_SERVER_PORT);
LOGGER.info("[settings] [req-serv] nacos-server port:{}", serverPort);
String tmp = "1000";
try {
tmp = System.getProperty("NACOS.CONNECT.TIMEOUT", "1000");
tmp = System.getProperty(NACOS_CONNECT_TIMEOUT_KEY, DEFAULT_NACOS_CONNECT_TIMEOUT);
connectTimeout = Integer.parseInt(tmp);
} catch (NumberFormatException e) {
final String msg = "[http-client] invalid connect timeout:" + tmp;
@ -83,7 +101,8 @@ public class ParamUtil {
clientVersion = VersionUtils.version;
try {
perTaskConfigSize = Double.valueOf(System.getProperty("PER_TASK_CONFIG_SIZE", "3000"));
perTaskConfigSize = Double
.valueOf(System.getProperty(PER_TASK_CONFIG_SIZE_KEY, DEFAULT_PER_TASK_CONFIG_SIZE_KEY));
LOGGER.info("PER_TASK_CONFIG_SIZE: {}", perTaskConfigSize);
} catch (Throwable t) {
LOGGER.error("[PER_TASK_CONFIG_SIZE] PER_TASK_CONFIG_SIZE invalid", t);
@ -139,7 +158,7 @@ public class ParamUtil {
}
public static String getDefaultServerPort() {
return DEFAULT_SERVER_PORT;
return serverPort;
}
public static String getDefaultNodesPath() {
@ -188,7 +207,7 @@ public class ParamUtil {
* @return end point rule
*/
public static String parsingEndpointRule(String endpointUrl) {
// 配置文件中输入的话 ENV 中的优先
// If entered in the configuration file, the priority in ENV will be given priority.
if (endpointUrl == null || !PATTERN.matcher(endpointUrl).find()) {
// skip retrieve from system property and retrieve directly from system env
String endpointUrlSource = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_ENDPOINT_URL);

View File

@ -0,0 +1,39 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.filter.impl;
import com.alibaba.nacos.api.exception.NacosException;
import org.junit.Assert;
import org.junit.Test;
public class ConfigFilterChainTest {
@Test
public void testConfigFilterChain() {
ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager(null);
configFilterChainManager.addFilter(new DemoFilter1());
configFilterChainManager.addFilter(new DemoFilter2());
ConfigRequest configRequest = new ConfigRequest();
try {
configFilterChainManager.doFilter(configRequest, null);
Assert.assertEquals(DemoFilter1.class.getName(), configRequest.getParameter("filter1"));
Assert.assertEquals(DemoFilter2.class.getName(), configRequest.getParameter("filter2"));
} catch (NacosException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.filter.impl;
import com.alibaba.nacos.api.config.filter.IConfigFilter;
import com.alibaba.nacos.api.config.filter.IConfigFilterChain;
import com.alibaba.nacos.api.config.filter.IConfigRequest;
import com.alibaba.nacos.api.config.filter.IConfigResponse;
import com.alibaba.nacos.api.config.filter.IFilterConfig;
import com.alibaba.nacos.api.exception.NacosException;
import java.util.Properties;
public class DemoFilter1 implements IConfigFilter {
private static final String DEFAULT_NAME = DemoFilter1.class.getName();
@Override
public void init(IFilterConfig filterConfig) {
}
@Override
public void init(Properties properties) {
}
@Override
public void doFilter(IConfigRequest request, IConfigResponse response, IConfigFilterChain filterChain)
throws NacosException {
request.putParameter("filter1", DEFAULT_NAME);
filterChain.doFilter(request, response);
}
@Override
public int getOrder() {
return 0;
}
@Override
public String getFilterName() {
return DEFAULT_NAME;
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.client.config.filter.impl;
import com.alibaba.nacos.api.config.filter.IConfigFilter;
import com.alibaba.nacos.api.config.filter.IConfigFilterChain;
import com.alibaba.nacos.api.config.filter.IConfigRequest;
import com.alibaba.nacos.api.config.filter.IConfigResponse;
import com.alibaba.nacos.api.config.filter.IFilterConfig;
import com.alibaba.nacos.api.exception.NacosException;
import java.util.Properties;
public class DemoFilter2 implements IConfigFilter {
private static final String DEFAULT_NAME = DemoFilter2.class.getName();
@Override
public void init(IFilterConfig filterConfig) {
}
@Override
public void init(Properties properties) {
}
@Override
public void doFilter(IConfigRequest request, IConfigResponse response, IConfigFilterChain filterChain)
throws NacosException {
request.putParameter("filter2", DEFAULT_NAME);
filterChain.doFilter(request, response);
}
@Override
public int getOrder() {
return 0;
}
@Override
public String getFilterName() {
return DEFAULT_NAME;
}
}

View File

@ -39,12 +39,6 @@
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-core</artifactId>

View File

@ -65,13 +65,6 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -119,7 +119,7 @@ public class DefaultPublisher extends Thread implements EventPublisher {
UPDATER.compareAndSet(this, lastEventSequence, Math.max(lastEventSequence, event.sequence()));
}
} catch (Throwable ex) {
LOGGER.error("Event listener exception : {}", ex);
LOGGER.error("Event listener exception : ", ex);
}
}

View File

@ -16,8 +16,6 @@
package com.alibaba.nacos.common.utils;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -47,14 +45,15 @@ public class IPUtil {
private static final String LOCAL_HOST_IP_V6 = "[::1]";
private static Pattern ipv4Pattern = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
private static final int IPV4_ADDRESS_LENGTH = 4;
private static final int IPV6_ADDRESS_LENGTH = 16;
private static final String CHECK_OK = "ok";
private static final Pattern DOMAIN_PATTERN = Pattern.compile("[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?");
private static final String IPV4_TUPLE = "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])";
private static final Pattern IPV4_PATTERN = Pattern
.compile("(?<!\\d)" + IPV4_TUPLE + "\\." + IPV4_TUPLE + "\\." + IPV4_TUPLE + "\\." + IPV4_TUPLE + "(?!\\d)");
/**
* get localhost ip.
* @return java.lang.String
@ -73,7 +72,7 @@ public class IPUtil {
* @return boolean
*/
public static boolean isIPv4(String addr) {
return ipv4Pattern.matcher(addr).matches();
return InetAddressValidator.isIPv4Address(addr);
}
/**
@ -83,11 +82,7 @@ public class IPUtil {
* @return boolean
*/
public static boolean isIPv6(String addr) {
try {
return InetAddress.getByName(addr).getAddress().length == IPV6_ADDRESS_LENGTH;
} catch (UnknownHostException e) {
return false;
}
return InetAddressValidator.isIPv6Address(removeBrackets(addr));
}
/**
@ -139,6 +134,9 @@ public class IPUtil {
throw new IllegalArgumentException("The IP address(\"" + str
+ "\") is incorrect. If it is an IPv6 address, please use [] to enclose the IP part!");
}
if (!isIPv4(serverAddrArr[0]) && !DOMAIN_PATTERN.matcher(serverAddrArr[0]).matches()) {
throw new IllegalArgumentException("The IPv4 or Domain address(\"" + serverAddrArr[0] + "\") is incorrect.");
}
}
return serverAddrArr;
}
@ -159,7 +157,7 @@ public class IPUtil {
result = "";
}
} else {
Matcher m = ipv4Pattern.matcher(str);
Matcher m = IPV4_PATTERN.matcher(str);
if (m.find()) {
result = m.group();
}
@ -204,4 +202,17 @@ public class IPUtil {
return CHECK_OK.equals(checkIPsResult);
}
/**
* remove brackets "[]".
*
* @param str is ipv6 address
* @return
*/
public static String removeBrackets(String str) {
if (StringUtils.isBlank(str)) {
return "";
}
return str.replaceAll("[\\[\\]]", "");
}
}

View File

@ -0,0 +1,199 @@
/**
* Copyright 2018-2021 Dynatrace LLC
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.common.utils;
import java.util.regex.Pattern;
/**
* ipv4 ipv6 check util.
*
* @author Dynatrace LLC
*/
@SuppressWarnings({"checkstyle:AbbreviationAsWordInName", "PMD.ClassNamingShouldBeCamelRule"})
public class InetAddressValidator {
private static final String PERCENT = "%";
private static final String DOUBLE_COLON = "::";
private static final String DOUBLE_COLON_FFFF = "::ffff:";
private static final String FE80 = "fe80:";
private static final int ZERO = 0;
private static final int SEVEN = 7;
private static final int FIVE = 5;
private static final Pattern IPV4_PATTERN = Pattern
.compile("^" + "(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)" + "(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}" + "$");
private static final Pattern IPV6_STD_PATTERN = Pattern
.compile("^" + "(?:[0-9a-fA-F]{1,4}:){7}" + "[0-9a-fA-F]{1,4}" + "$");
private static final Pattern IPV6_HEX_COMPRESSED_PATTERN = Pattern
.compile("^" + "(" + "(?:[0-9A-Fa-f]{1,4}" + "(?::[0-9A-Fa-f]{1,4})*)?" + ")" + "::"
+ "(" + "(?:[0-9A-Fa-f]{1,4}" + "(?::[0-9A-Fa-f]{1,4})*)?" + ")" + "$");
private static final Pattern IPV6_MIXED_COMPRESSED_REGEX = Pattern.compile(
"^" + "(" + "(?:[0-9A-Fa-f]{1,4}" + "(?::[0-9A-Fa-f]{1,4})*)?" + ")" + "::" + "(" + "(?:[0-9A-Fa-f]{1,4}:"
+ "(?:[0-9A-Fa-f]{1,4}:)*)?" + ")" + "$");
private static final Pattern IPV6_MIXED_UNCOMPRESSED_REGEX = Pattern
.compile("^" + "(?:[0-9a-fA-F]{1,4}:){6}" + "$");
/**
* Check if <code>input</code> is a valid IPv4 address.
* The format is 'xxx.xxx.xxx.xxx'. Four blocks of integer numbers ranging from 0 to 255
* are required. Letters are not allowed.
*
* @param input ip-address to check
* @return true if <code>input</code> is in correct IPv4 notation.
*/
public static boolean isIPv4Address(final String input) {
return IPV4_PATTERN.matcher(input).matches();
}
/**
* Check if the given address is a valid IPv6 address in the standard format
* The format is 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'. Eight blocks of hexadecimal digits
* are required.
*
* @param input ip-address to check
* @return true if <code>input</code> is in correct IPv6 notation.
*/
public static boolean isIPv6StdAddress(final String input) {
return IPV6_STD_PATTERN.matcher(input).matches();
}
/**
* Check if the given address is a valid IPv6 address in the hex-compressed notation
* The format is 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'. If all digits in a block are '0'
* the block can be left empty.
*
* @param input ip-address to check
* @return true if <code>input</code> is in correct IPv6 (hex-compressed) notation.
*/
public static boolean isIPv6HexCompressedAddress(final String input) {
return IPV6_HEX_COMPRESSED_PATTERN.matcher(input).matches();
}
/**
* Check if <code>input</code> is a IPv6 address.
* Possible notations for valid IPv6 are:
* - Standard IPv6 address
* - Hex-compressed IPv6 address
* - Link-local IPv6 address
* - IPv4-mapped-to-IPV6 address
* - IPv6 mixed address
*
* @param input ip-address to check
* @return true if <code>input</code> is in correct IPv6 notation.
*/
public static boolean isIPv6Address(final String input) {
return isIPv6StdAddress(input) || isIPv6HexCompressedAddress(input) || isLinkLocalIPv6WithZoneIndex(input)
|| isIPv6IPv4MappedAddress(input) || isIPv6MixedAddress(input);
}
/**
* Check if the given address is a valid IPv6 address in the mixed-standard or mixed-compressed notation.
* IPV6 Mixed mode consists of two parts, the first 96 bits (up to 6 blocks of 4 hex digits) are IPv6
* the IPV6 part can be either compressed or uncompressed
* the second block is a full IPv4 address
* e.g. '0:0:0:0:0:0:172.12.55.18'
*
* @param input ip-address to check
* @return true if <code>input</code> is in correct IPv6 (mixed-standard or mixed-compressed) notation.
*/
public static boolean isIPv6MixedAddress(final String input) {
int splitIndex = input.lastIndexOf(':');
if (splitIndex == -1) {
return false;
}
//the last part is a ipv4 address
boolean ipv4PartValid = isIPv4Address(input.substring(splitIndex + 1));
String ipV6Part = input.substring(ZERO, splitIndex + 1);
if (DOUBLE_COLON.equals(ipV6Part)) {
return ipv4PartValid;
}
boolean ipV6UncompressedDetected = IPV6_MIXED_UNCOMPRESSED_REGEX.matcher(ipV6Part).matches();
boolean ipV6CompressedDetected = IPV6_MIXED_COMPRESSED_REGEX.matcher(ipV6Part).matches();
return ipv4PartValid && (ipV6UncompressedDetected || ipV6CompressedDetected);
}
/**
* Check if <code>input</code> is an IPv4 address mapped into a IPv6 address. These are
* starting with "::ffff:" followed by the IPv4 address in a dot-seperated notation.
* The format is '::ffff:d.d.d.d'
*
* @param input ip-address to check
* @return true if <code>input</code> is in correct IPv6 notation containing an IPv4 address
*/
public static boolean isIPv6IPv4MappedAddress(final String input) {
if (input.length() > SEVEN && input.substring(ZERO, SEVEN).equalsIgnoreCase(DOUBLE_COLON_FFFF)) {
String lowerPart = input.substring(SEVEN);
return isIPv4Address(lowerPart);
}
return false;
}
/**
* Check if <code>input</code> is a link local IPv6 address starting with "fe80:" and containing
* a zone index with "%xxx". The zone index will not be checked.
*
* @param input ip-address to check
* @return true if address part of <code>input</code> is in correct IPv6 notation.
*/
public static boolean isLinkLocalIPv6WithZoneIndex(String input) {
if (input.length() > FIVE && input.substring(ZERO, FIVE).equalsIgnoreCase(FE80)) {
int lastIndex = input.lastIndexOf(PERCENT);
if (lastIndex > ZERO && lastIndex < (input.length() - 1)) {
String ipPart = input.substring(ZERO, lastIndex);
return isIPv6StdAddress(ipPart) || isIPv6HexCompressedAddress(ipPart);
}
}
return false;
}
/**
* Check if <code>input</code> is a valid IPv4 or IPv6 address.
*
* @param ipAddress ip-address to check
* @return <code>true</code> if <code>ipAddress</code> is a valid ip-address
*/
public static boolean isValidIP(String ipAddress) {
if (ipAddress == null || ipAddress.length() == 0) {
return false;
}
return isIPv4Address(ipAddress) || isIPv6Address(ipAddress);
}
/**
* get to ipv4 pattern.
*
* @return
*/
public static Pattern getIpv4Pattern() {
return IPV4_PATTERN;
}
}

View File

@ -71,6 +71,18 @@ public class IPUtilTest {
Assert.assertEquals("", IPUtil.getIPFromString(
"jdbc:mysql://666.288.333.444:3306/nacos_config_test?characterEncoding=utf8&connectTimeout=1000"
+ "&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"));
Assert.assertEquals("", IPUtil.getIPFromString(
"jdbc:mysql://292.168.1.1:3306/nacos_config_test?characterEncoding=utf8&connectTimeout=1000"
+ "&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"));
Assert.assertEquals("", IPUtil.getIPFromString(
"jdbc:mysql://29.168.1.288:3306/nacos_config_test?characterEncoding=utf8&connectTimeout=1000"
+ "&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"));
Assert.assertEquals("", IPUtil.getIPFromString(
"jdbc:mysql://29.168.288.28:3306/nacos_config_test?characterEncoding=utf8&connectTimeout=1000"
+ "&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"));
Assert.assertEquals("", IPUtil.getIPFromString(
"jdbc:mysql://29.288.28.28:3306/nacos_config_test?characterEncoding=utf8&connectTimeout=1000"
+ "&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"));
}
@Test

View File

@ -36,11 +36,6 @@
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

View File

@ -45,6 +45,12 @@ public class CapacityController {
private final CapacityService capacityService;
private static final int STATUS200 = 200;
private static final int STATUS400 = 400;
private static final int STATUS500 = 500;
@Autowired
public CapacityController(CapacityService capacityService) {
this.capacityService = capacityService;
@ -55,25 +61,25 @@ public class CapacityController {
@RequestParam(required = false) String tenant) {
if (group == null && tenant == null) {
RestResult<Capacity> restResult = new RestResult<Capacity>();
response.setStatus(400);
restResult.setCode(400);
restResult.setMessage("参数group和tenant不能同时为空");
response.setStatus(STATUS400);
restResult.setCode(STATUS400);
restResult.setMessage("The parameter group and tenant cannot be empty at the same time");
return restResult;
}
if (group == null && StringUtils.isBlank(tenant)) {
RestResult<Capacity> restResult = new RestResult<Capacity>();
response.setStatus(400);
restResult.setCode(400);
restResult.setMessage("tenant不能为空字符串");
response.setStatus(STATUS400);
restResult.setCode(STATUS400);
restResult.setMessage("tenant cannot be an empty string");
return restResult;
}
RestResult<Capacity> restResult = new RestResult<Capacity>();
try {
response.setStatus(200);
restResult.setCode(200);
response.setStatus(STATUS200);
restResult.setCode(STATUS200);
Capacity capacity = capacityService.getCapacityWithDefault(group, tenant);
if (capacity == null) {
LOGGER.warn("[getCapacity] capacity不存在,需初始化 group: {}, tenant: {}", group, tenant);
LOGGER.warn("[getCapacity] capacity not existneed init group: {}, tenant: {}", group, tenant);
capacityService.initCapacity(group, tenant);
capacity = capacityService.getCapacityWithDefault(group, tenant);
}
@ -82,8 +88,8 @@ public class CapacityController {
}
} catch (Exception e) {
LOGGER.error("[getCapacity] ", e);
response.setStatus(500);
restResult.setCode(500);
response.setStatus(STATUS500);
restResult.setCode(STATUS500);
restResult.setMessage(e.getMessage());
}
return restResult;
@ -100,14 +106,15 @@ public class CapacityController {
if (StringUtils.isBlank(group) && StringUtils.isBlank(tenant)) {
capacityService.initAllCapacity();
RestResult<Boolean> restResult = new RestResult<Boolean>();
setFailResult(response, restResult, 400);
restResult.setMessage("参数group和tenant不能同时为空");
setFailResult(response, restResult, STATUS400);
restResult.setMessage("The parameter group and tenant cannot be empty at the same time");
return restResult;
}
if (quota == null && maxSize == null && maxAggrCount == null && maxAggrSize == null) {
RestResult<Boolean> restResult = new RestResult<Boolean>();
setFailResult(response, restResult, 400);
restResult.setMessage("参数quota、maxSize、maxAggrCount、maxAggrSize不能同时为空");
setFailResult(response, restResult, STATUS400);
restResult.setMessage(
"The parameters quota, maxSize, maxAggrCount, maxAggrSize cannot be empty at the same time");
return restResult;
}
String targetFieldName;
@ -121,8 +128,8 @@ public class CapacityController {
}
RestResult<Boolean> restResult = new RestResult<Boolean>();
if (StringUtils.isBlank(targetFieldValue)) {
setFailResult(response, restResult, 400);
restResult.setMessage(String.format("参数%s为空", targetFieldName));
setFailResult(response, restResult, STATUS400);
restResult.setMessage(String.format("parameter %s is empty.", targetFieldName));
return restResult;
}
try {
@ -130,15 +137,19 @@ public class CapacityController {
.insertOrUpdateCapacity(group, tenant, quota, maxSize, maxAggrCount, maxAggrSize);
if (insertOrUpdateResult) {
setSuccessResult(response, restResult);
restResult.setMessage(String.format("成功更新%s为%s的容量信息配置", targetFieldName, targetFieldValue));
restResult.setMessage(
String.format("successfully updated the capacity information configuration of %s to %s",
targetFieldName, targetFieldValue));
return restResult;
}
setFailResult(response, restResult, 500);
restResult.setMessage(String.format("%s为%s的容量信息配置更新失败", targetFieldName, targetFieldValue));
setFailResult(response, restResult, STATUS500);
restResult.setMessage(
String.format("failed updated the capacity information configuration of %s to %s", targetFieldName,
targetFieldValue));
return restResult;
} catch (Exception e) {
LOGGER.error("[updateCapacity] ", e);
setFailResult(response, restResult, 500);
setFailResult(response, restResult, STATUS500);
restResult.setMessage(e.getMessage());
return restResult;
}
@ -151,8 +162,8 @@ public class CapacityController {
}
private void setSuccessResult(HttpServletResponse response, RestResult<Boolean> restResult) {
response.setStatus(200);
restResult.setCode(200);
response.setStatus(STATUS200);
restResult.setCode(STATUS200);
restResult.setData(true);
}
}

View File

@ -400,27 +400,31 @@ public class LongPollingService {
getRetainIps().put(ClientLongPolling.this.ip, System.currentTimeMillis());
// Delete subscriber's relations.
allSubs.remove(ClientLongPolling.this);
boolean removeFlag = allSubs.remove(ClientLongPolling.this);
if (isFixedPolling()) {
LogUtil.CLIENT_LOG
.info("{}|{}|{}|{}|{}|{}", (System.currentTimeMillis() - createTime), "fix",
RequestUtil.getRemoteIp((HttpServletRequest) asyncContext.getRequest()),
"polling", clientMd5Map.size(), probeRequestSize);
List<String> changedGroups = MD5Util
.compareMd5((HttpServletRequest) asyncContext.getRequest(),
(HttpServletResponse) asyncContext.getResponse(), clientMd5Map);
if (changedGroups.size() > 0) {
sendResponse(changedGroups);
if (removeFlag) {
if (isFixedPolling()) {
LogUtil.CLIENT_LOG
.info("{}|{}|{}|{}|{}|{}", (System.currentTimeMillis() - createTime), "fix",
RequestUtil.getRemoteIp((HttpServletRequest) asyncContext.getRequest()),
"polling", clientMd5Map.size(), probeRequestSize);
List<String> changedGroups = MD5Util
.compareMd5((HttpServletRequest) asyncContext.getRequest(),
(HttpServletResponse) asyncContext.getResponse(), clientMd5Map);
if (changedGroups.size() > 0) {
sendResponse(changedGroups);
} else {
sendResponse(null);
}
} else {
LogUtil.CLIENT_LOG
.info("{}|{}|{}|{}|{}|{}", (System.currentTimeMillis() - createTime), "timeout",
RequestUtil.getRemoteIp((HttpServletRequest) asyncContext.getRequest()),
"polling", clientMd5Map.size(), probeRequestSize);
sendResponse(null);
}
} else {
LogUtil.CLIENT_LOG
.info("{}|{}|{}|{}|{}|{}", (System.currentTimeMillis() - createTime), "timeout",
RequestUtil.getRemoteIp((HttpServletRequest) asyncContext.getRequest()),
"polling", clientMd5Map.size(), probeRequestSize);
sendResponse(null);
LogUtil.DEFAULT_LOG.warn("client subsciber's relations delete fail.");
}
} catch (Throwable t) {
LogUtil.DEFAULT_LOG.error("long polling error:" + t.getMessage(), t.getCause());

View File

@ -16,21 +16,12 @@
package com.alibaba.nacos.config.server.service.notify;
import com.alibaba.nacos.common.executor.ExecutorFactory;
import com.alibaba.nacos.common.executor.NameThreadFactory;
import com.alibaba.nacos.common.task.NacosTask;
import com.alibaba.nacos.config.server.utils.LogUtil;
import com.alibaba.nacos.core.cluster.Member;
import com.alibaba.nacos.core.cluster.ServerMemberManager;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
@ -39,6 +30,7 @@ import java.util.concurrent.TimeUnit;
* @author Nacos
*/
public class NotifySingleService {
private static final Logger LOGGER = LogUtil.FATAL_LOG;
static class NotifyTaskProcessorWrapper extends NotifyTaskProcessor {
@ -84,7 +76,7 @@ public class NotifySingleService {
.error("[notify-exception] target:{} dataid:{} group:{} ts:{}", target, getDataId(), getGroup(),
getLastModified());
LogUtil.NOTIFY_LOG.debug("[notify-exception] target:{} dataid:{} group:{} ts:{}",
new Object[] {target, getDataId(), getGroup(), getLastModified()}, e);
target, getDataId(), getGroup(), getLastModified(), e);
}
if (!this.isSuccess) {
@ -100,59 +92,4 @@ public class NotifySingleService {
}
}
}
@Autowired
public NotifySingleService(ServerMemberManager memberManager) {
this.memberManager = memberManager;
setupNotifyExecutors();
}
/**
* When the system is started or when the cluster is expanded or offline: single-threaded setupNotifyExecutors
* executors use ConcurrentHashMap to ensure visibility.
*/
private void setupNotifyExecutors() {
Collection<Member> clusterIps = memberManager.allMembers();
for (Member member : clusterIps) {
final String address = member.getAddress();
/*
* Fixed number of threads, unbounded queue
* (based on assumption: thread pool throughput is good,
* there will be no continuous task accumulation,
* there is occasional instantaneous pressure)
*/
Executor executor = ExecutorFactory.newSingleScheduledExecutorService(
new NameThreadFactory("com.alibaba.nacos.config.NotifySingleServiceThread-" + address));
if (null == executors.putIfAbsent(address, executor)) {
LOGGER.warn("[notify-thread-pool] setup thread target ip {} ok.", address);
}
}
for (Map.Entry<String, Executor> entry : executors.entrySet()) {
String target = entry.getKey();
// The cluster node goes offline
if (!clusterIps.contains(target)) {
ThreadPoolExecutor executor = (ThreadPoolExecutor) entry.getValue();
executor.shutdown();
executors.remove(target);
LOGGER.warn("[notify-thread-pool] tear down thread target ip {} ok.", target);
}
}
}
private static final Logger LOGGER = LogUtil.FATAL_LOG;
private ServerMemberManager memberManager;
private ConcurrentHashMap<String, Executor> executors = new ConcurrentHashMap<String, Executor>();
public ConcurrentHashMap<String, Executor> getExecutors() {
return executors;
}
}

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.utils;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.auth.model.User;
import org.apache.commons.lang3.StringUtils;
@ -90,7 +91,8 @@ public class RequestUtil {
*/
public static String getSrcUserName(HttpServletRequest request) {
User user = getUser(request);
return user == null ? null : user.getUserName();
// If auth is disabled, get username from parameters by agreed key
return user == null ? request.getParameter(Constants.USERNAME) : user.getUserName();
}
}

View File

@ -497,13 +497,13 @@ const request = (function(_global) {
try {
token = JSON.parse(localStorage.token);
} catch (e) {
console.log('Token Erro', localStorage.token, e);
console.log('Token Error', localStorage.token, e);
goLogin();
}
const { accessToken = '' } = token;
const { accessToken = '', username = '' } = token;
const [url, paramsStr = ''] = config.url.split('?');
const params = paramsStr.split('&');
params.push(`accessToken=${accessToken}`);
params.push(`accessToken=${accessToken}&username=${username}`);
return $.ajax(
Object.assign({}, config, {

View File

@ -244,6 +244,7 @@ const I18N_CONF = {
home: 'Application:',
actionType: 'Action Type:',
operator: 'Operator:',
sourceIp: 'Source IP',
configureContent: 'Configuration Content:',
back: 'Back',
},
@ -252,6 +253,7 @@ const I18N_CONF = {
viewDetails1: 'view details',
},
ConfigurationManagement: {
exportBtn: 'Export',
questionnaire2: 'questionnaire',
ad:
'a ACM front-end monitoring questionnaire, the time limit to receive Ali cloud voucher details shoved stamp: the',
@ -539,6 +541,7 @@ const I18N_CONF = {
rollbackDelete: 'Delete',
update: 'Update',
insert: 'Insert',
additionalRollbackMessage: 'This operation will delete the below config!',
},
UserManagement: {
userManagement: 'User Management',

View File

@ -244,6 +244,7 @@ const I18N_CONF = {
actionType: '操作类型:',
configureContent: '配置内容:',
operator: '操作人:',
sourceIp: '来源 IP:',
back: '返回',
},
DashboardCard: {
@ -251,6 +252,7 @@ const I18N_CONF = {
viewDetails1: '查看详情',
},
ConfigurationManagement: {
exportBtn: '导出',
questionnaire2: '问卷调查',
ad: ' ACM 前端监控调查问卷限时领取阿里云代金券\t 详情猛戳',
noLongerDisplay4: '不再显示',
@ -535,6 +537,7 @@ const I18N_CONF = {
rollbackDelete: '删除',
update: '更新',
insert: '插入',
additionalRollbackMessage: '此操作将删除以下配置',
},
UserManagement: {
userManagement: '用户管理',

View File

@ -92,7 +92,11 @@ class PermissionsManagement extends React.Component {
<>
<RegionGroup left={locale.privilegeManagement} />
<div className="filter-panel">
<Button type="primary" onClick={() => this.setState({ createPermissionVisible: true })}>
<Button
type="primary"
onClick={() => this.setState({ createPermissionVisible: true })}
style={{ marginRight: 20 }}
>
{locale.addPermission}
</Button>
<Button type="secondary" onClick={() => this.getPermissions()}>

View File

@ -72,7 +72,11 @@ class RolesManagement extends React.Component {
<>
<RegionGroup left={locale.roleManagement} />
<div className="filter-panel">
<Button type="primary" onClick={() => this.setState({ createRoleVisible: true })}>
<Button
type="primary"
onClick={() => this.setState({ createRoleVisible: true })}
style={{ marginRight: 20 }}
>
{locale.bindingRoles}
</Button>
<Button type="secondary" onClick={() => this.getRoles()}>

View File

@ -74,7 +74,11 @@ class UserManagement extends React.Component {
<>
<RegionGroup left={locale.userManagement} />
<div className="filter-panel">
<Button type="primary" onClick={() => this.setState({ createUserVisible: true })}>
<Button
type="primary"
onClick={() => this.setState({ createUserVisible: true })}
style={{ marginRight: 20 }}
>
{locale.createUser}
</Button>
<Button type="secondary" onClick={() => this.getUsers()}>

View File

@ -86,7 +86,7 @@ class ConfigRollback extends React.Component {
self.field.setValue('dataId', data.dataId);
self.field.setValue('content', data.content);
self.field.setValue('appName', data.appName);
self.field.setValue('opType', self.typeMapName[data.opType.trim()]);
self.field.setValue('opType', data.opType.trim());
self.opType = data.opType; // 当前回滚类型I:插入,D:删除,U:'更新'
self.field.setValue('group', data.group);
self.field.setValue('md5', data.md5);
@ -111,15 +111,17 @@ class ConfigRollback extends React.Component {
const { locale = {} } = this.props;
const self = this;
let type = 'post';
let additionalMsg = '';
if (this.opType.trim() === 'I') {
type = 'delete';
additionalMsg = locale.additionalRollbackMessage;
}
Dialog.confirm({
title: locale.rollBack,
content: (
<div style={{ marginTop: '-20px' }}>
<div style={{ marginTop: '-20px', maxWidth: '500px' }}>
<h3>
{locale.determine} {locale.followingConfiguration}
{locale.determine} {locale.followingConfiguration} {additionalMsg}
</h3>
<p>
<span style={{ color: '#999', marginRight: 5 }}>Data ID:</span>
@ -166,6 +168,18 @@ class ConfigRollback extends React.Component {
});
}
getOpType(type, locale) {
if (type) {
const typeMap = {
U: locale.update,
I: locale.insert,
D: locale.deleteAction,
};
return typeMap[type];
}
return '';
}
render() {
const { locale = {} } = this.props;
const { init } = this.field;
@ -177,6 +191,7 @@ class ConfigRollback extends React.Component {
span: 18,
},
};
const { getOpType } = this;
return (
<div style={{ padding: 10 }}>
<h1>{locale.configurationRollback}</h1>
@ -198,7 +213,7 @@ class ConfigRollback extends React.Component {
</FormItem>
</div>
<FormItem label={locale.actionType} required {...formItemLayout}>
<Input htmlType="text" readOnly {...init('opType')} />
<Input htmlType="text" readOnly value={getOpType(init('opType').value, locale)} />
</FormItem>
<FormItem label="MD5:" required {...formItemLayout}>
<Input htmlType="text" readOnly {...init('md5')} />

View File

@ -33,6 +33,8 @@ import {
Table,
Upload,
Message,
MenuButton,
Box,
} from '@alifd/next';
import BatchHandle from 'components/BatchHandle';
import RegionGroup from 'components/RegionGroup';
@ -46,6 +48,7 @@ import { getConfigs } from '../../../reducers/configuration';
import './index.scss';
import { LANGUAGE_KEY, GLOBAL_PAGE_SIZE_LIST } from '../../../constants';
const { Item } = MenuButton;
const { Panel } = Collapse;
const configsTableSelected = new Map();
@connect(
@ -515,7 +518,7 @@ class ConfigurationManagement extends React.Component {
exportData() {
const { group, appName, dataId, openUri } = this;
const { accessToken = '' } = JSON.parse(localStorage.token || '{}');
const { accessToken = '', username = '' } = JSON.parse(localStorage.token || '{}');
openUri('v1/cs/configs', {
export: 'true',
tenant: getParams('namespace'),
@ -524,12 +527,13 @@ class ConfigurationManagement extends React.Component {
dataId,
ids: '',
accessToken,
username,
});
}
exportDataNew() {
const { group, appName, dataId, openUri } = this;
const { accessToken = '' } = JSON.parse(localStorage.token || '{}');
const { accessToken = '', username = '' } = JSON.parse(localStorage.token || '{}');
openUri('v1/cs/configs', {
exportV2: 'true',
tenant: getParams('namespace'),
@ -538,13 +542,14 @@ class ConfigurationManagement extends React.Component {
dataId,
ids: '',
accessToken,
username,
});
}
exportSelectedData(newVersion) {
const ids = [];
const { locale = {} } = this.props;
const { accessToken = '' } = JSON.parse(localStorage.token || '{}');
const { accessToken = '', username = '' } = JSON.parse(localStorage.token || '{}');
if (!configsTableSelected.size) {
Dialog.alert({
title: locale.exportSelectedAlertTitle,
@ -561,6 +566,7 @@ class ConfigurationManagement extends React.Component {
appName: '',
ids: ids.join(','),
accessToken,
username,
});
} else {
this.openUri('v1/cs/configs', {
@ -570,6 +576,7 @@ class ConfigurationManagement extends React.Component {
appName: '',
ids: ids.join(','),
accessToken,
username,
});
}
}
@ -956,12 +963,12 @@ class ConfigurationManagement extends React.Component {
console.log(e);
goLogin();
}
const { accessToken = '' } = token;
const { accessToken = '', username = '' } = token;
const uploadProps = {
accept: 'application/zip',
action: `v1/cs/configs?import=true&namespace=${getParams(
'namespace'
)}&accessToken=${accessToken}`,
)}&accessToken=${accessToken}&username=${username}`,
headers: Object.assign({}, {}, { accessToken }),
data: {
policy: self.field.getValue('sameConfigPolicy'),
@ -1163,42 +1170,24 @@ class ConfigurationManagement extends React.Component {
style={
this.inApp
? { display: 'none' }
: { verticalAlign: 'middle', marginTop: 0, marginLeft: 10 }
: { verticalAlign: 'middle', marginTop: 0, marginLeft: 0 }
}
>
<div
style={{ color: '#33cde5', fontSize: 12, cursor: 'pointer' }}
onClick={this.changeAdvancedQuery}
>
<span style={{ marginRight: 5, lineHeight: '28px' }}>
{locale.advancedQuery9}
</span>
<Icon
type={this.state.isAdvancedQuery ? 'arrow-up-filling' : 'arrow-down-filling'}
size={'xs'}
/>
</div>
</Form.Item>
<Form.Item label={''}>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.exportData.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsExport'}
>
{locale.export}
</Button>
</Form.Item>
<Form.Item label={''}>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.exportDataNew.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsExport'}
>
{locale.newExport}
<Button onClick={this.changeAdvancedQuery}>
{this.state.isAdvancedQuery ? (
<>
{locale.advancedQuery9}
<Icon type="arrow-up" size="xs" style={{ marginLeft: '5px' }} />
</>
) : (
<>
{locale.advancedQuery9}
<Icon type="arrow-down" size="xs" style={{ marginLeft: '5px' }} />
</>
)}
</Button>
</Form.Item>
<Form.Item label={''}>
<Button
type={'primary'}
@ -1287,16 +1276,7 @@ class ConfigurationManagement extends React.Component {
locaid: 'configsDelete',
onClick: () => this.multipleSelectionDeletion(),
},
{
text: locale.exportSelected,
locaid: 'configsExport',
onClick: () => this.exportSelectedData(false),
},
{
text: locale.newExportSelected,
locaid: 'configsExport',
onClick: () => this.exportSelectedData(true),
},
{
text: locale.clone,
locaid: 'configsDelete',
@ -1313,6 +1293,38 @@ class ConfigurationManagement extends React.Component {
{item.text}
</Button>
))}
<MenuButton
type="primary"
label={locale.exportBtn}
popupStyle={{ minWidth: 150 }}
>
{[
{
text: locale.export,
locaid: 'exportData',
onClick: () => this.exportData(this),
},
{
text: locale.newExport,
locaid: 'exportDataNew',
onClick: () => this.exportDataNew(this),
},
{
text: locale.exportSelected,
locaid: 'configsExport',
onClick: () => this.exportSelectedData(false),
},
{
text: locale.newExportSelected,
locaid: 'configsExport',
onClick: () => this.exportSelectedData(true),
},
].map((item, index) => (
<Item key={item.text} style={{ minWidth: 150 }} onClick={item.onClick}>
{item.text}
</Item>
))}
</MenuButton>
</div>
<Pagination
style={{ float: 'right' }}

View File

@ -60,11 +60,6 @@ class HistoryDetail extends React.Component {
getDataDetail() {
const { locale = {} } = this.props;
const self = this;
const typeMap = {
U: locale.update,
I: locale.insert,
D: locale.deleteAction,
};
request({
url: `v1/cs/history?dataId=${this.dataId}&group=${this.group}&nid=${this.nid}`,
success(result) {
@ -74,8 +69,9 @@ class HistoryDetail extends React.Component {
self.field.setValue('content', data.content);
self.field.setValue('appName', self.inApp ? self.edasAppName : data.appName);
self.field.setValue('envs', self.serverId);
self.field.setValue('srcUser', self.srcUser);
self.field.setValue('opType', typeMap[data.opType.trim()]);
self.field.setValue('srcUser', data.srcUser);
self.field.setValue('srcIp', data.srcIp);
self.field.setValue('opType', data.opType.trim());
self.field.setValue('group', data.group);
self.field.setValue('md5', data.md5);
}
@ -85,10 +81,22 @@ class HistoryDetail extends React.Component {
goList() {
this.props.history.push(
`/historyRollback?serverId=${this.serverId}&group=${this.group}&dataId=${this.dataId}&namespace=${this.tenant}`
`/historyRollback?serverId=${this.serverId}&historyGroup=${this.group}&historyDataId=${this.dataId}&namespace=${this.tenant}`
);
}
getOpType(type, locale) {
if (type) {
const typeMap = {
U: locale.update,
I: locale.insert,
D: locale.deleteAction,
};
return typeMap[type];
}
return '';
}
render() {
const { locale = {} } = this.props;
const { init } = this.field;
@ -100,6 +108,7 @@ class HistoryDetail extends React.Component {
span: 18,
},
};
const { getOpType } = this;
return (
<div style={{ padding: 10 }}>
<h1>{locale.historyDetails}</h1>
@ -123,8 +132,11 @@ class HistoryDetail extends React.Component {
<Form.Item label={locale.operator} required {...formItemLayout}>
<Input htmlType="text" readOnly {...init('srcUser')} />
</Form.Item>
<Form.Item label={locale.sourceIp} required {...formItemLayout}>
<Input htmlType="text" readOnly {...init('srcIp')} />
</Form.Item>
<Form.Item label={locale.actionType} required {...formItemLayout}>
<Input htmlType="text" readOnly {...init('opType')} />
<Input htmlType="text" readOnly value={getOpType(init('opType').value, locale)} />
</Form.Item>
<Form.Item label="MD5:" required {...formItemLayout}>
<Input htmlType="text" readOnly {...init('md5')} />

View File

@ -203,6 +203,10 @@ class ListeningToQuery extends React.Component {
dataSource={selectDataSource}
style={{ width: 200 }}
{...this.init('type')}
onChange={value => {
this.field.setValue('type', value);
this.queryTrackQuery();
}}
/>
</FormItem>
<FormItem

View File

@ -47,8 +47,9 @@ const request = () => {
console.log(e);
goLogin();
}
const { accessToken = '' } = token;
const { accessToken = '', username = '' } = token;
config.params.accessToken = accessToken;
config.params.username = username;
config.headers = Object.assign({}, headers, { accessToken });
}
if (data && isPlainObject(data) && ['post', 'put'].includes(method)) {

View File

@ -66,12 +66,6 @@
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</dependency>
<!-- log -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>

View File

@ -211,26 +211,26 @@ public class UserController {
response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, NacosAuthConfig.TOKEN_PREFIX + user.getToken());
ObjectNode result = JacksonUtils.createEmptyJsonNode();
// JSONObject result = new JSONObject();
result.put(Constants.ACCESS_TOKEN, user.getToken());
result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds());
result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
result.put(Constants.USERNAME, user.getUserName());
return result;
}
// 通过用户名和密码创建一个 Authentication 认证对象实现类为 UsernamePasswordAuthenticationToken
// create Authentication class through username and password, the implement class is UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,
password);
RestResult<String> rr = new RestResult<String>();
try {
//通过 AuthenticationManager默认实现为ProviderManager的authenticate方法验证 Authentication 对象
// use the method authenticate of AuthenticationManager(default implement is ProviderManager) to valid Authentication
Authentication authentication = authenticationManager.authenticate(authenticationToken);
// Authentication 绑定到 SecurityContext
// bind SecurityContext to Authentication
SecurityContextHolder.getContext().setAuthentication(authentication);
//生成Token
// generate Token
String token = jwtTokenManager.createToken(authentication);
//将Token写入到Http头部
// write Token to Http header
response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, "Bearer " + token);
rr.setCode(200);
rr.setData("Bearer " + token);

View File

@ -364,7 +364,7 @@
* 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.
*/.next-pagination-size-selector{position:static!important}.configuration-table{margin-bottom:20px}.next-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;top:0;margin:-1px}.next-switch:after[dir=rtl]{content:" ";transition:all .1s linear;transform-origin:right center}.next-switch-medium[dir=rtl]:after,.next-switch-small[dir=rtl]:after{right:100%;transform:translateX(100%)}.next-switch-on[dir=rtl]>.next-switch-children{right:10px;left:auto;color:#fff}.next-switch-on[disabled][dir=rtl]:after{left:0;right:100%;box-shadow:1px 1px 3px 0 rgba(0,0,0,.12)}.next-switch-on.next-switch-small[dir=rtl]>.next-switch-children{right:6px;left:auto}.next-switch-off[dir=rtl]:after{right:0;transform:translateX(0);box-shadow:-1px 0 3px 0 rgba(0,0,0,.12)}.next-switch-off[dir=rtl]>.next-switch-children{left:10px;right:auto}.next-switch-off.next-switch-small[dir=rtl]>.next-switch-children{left:5px;right:auto}.next-switch{outline:none;text-align:left;transition:all .1s linear;overflow:hidden;cursor:pointer;user-select:none}.next-switch,.next-switch *,.next-switch :after,.next-switch :before{box-sizing:border-box}.next-switch:after{content:" ";transition:all .1s linear;transform-origin:left center}.next-switch-medium{width:56px;height:26px;border-radius:20px}.next-switch-medium:after{border:1px solid transparent;position:absolute;left:100%;transform:translateX(-100%);width:24px;height:24px;border-radius:20px;box-sizing:border-box}.next-switch-medium>.next-switch-children{font-size:12px;height:24px;line-height:24px}.next-switch-small{position:relative;display:inline-block;width:44px;height:22px}.next-switch-small,.next-switch-small:after{border:1px solid transparent;border-radius:20px}.next-switch-small:after{position:absolute;left:100%;transform:translateX(-100%);width:20px;height:20px;box-sizing:border-box}.next-switch-small>.next-switch-children{font-size:12px;position:absolute;height:20px;line-height:20px}.next-switch-on{background-color:#5584ff}.next-switch-on:after{box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#fff;border-color:transparent}.next-switch-on>.next-switch-children{left:10px}.next-switch-on:focus,.next-switch-on:hover{background-color:#3e71f7}.next-switch-on:focus:after,.next-switch-on:hover:after{background-color:#fff}.next-switch-on.next-switch-small>.next-switch-children{left:6px}.next-switch-on[disabled]{background-color:#ebecf0;cursor:not-allowed}.next-switch-on[disabled]:after{right:0;box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#f7f8fa;border-color:#e6e7eb}.next-switch-on[disabled]>.next-switch-children{color:#ccc}.next-switch-off{background-color:#fff;border-color:#c4c6cf}.next-switch-off:focus,.next-switch-off:hover{background-color:#f2f3f7;border-color:#c4c6cf}.next-switch-off:after{left:0;transform:translateX(0);box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#fff;border-color:transparent}.next-switch-off:after:focus,.next-switch-off:after:hover{background-color:#fff}.next-switch-off>.next-switch-children{right:10px;color:#999}.next-switch-off[disabled]{background-color:#f7f8fa;cursor:not-allowed}.next-switch-off[disabled]:after{box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#f7f8fa;border-color:#e6e7eb}.next-switch-off[disabled]>.next-switch-children{color:#c4c6cf}.next-switch-off.next-switch-small>.next-switch-children{right:5px}
*/.next-pagination-size-selector{position:static!important}.configuration-table{margin-bottom:20px}.next-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;top:0;margin:-1px}.next-switch:after[dir=rtl]{content:" ";transition:all .1s linear;transform-origin:right center}.next-switch-medium[dir=rtl]:after,.next-switch-small[dir=rtl]:after{right:100%;transform:translateX(100%)}.next-switch-on[dir=rtl]>.next-switch-children{right:10px;left:auto;color:#fff}.next-switch-on[disabled][dir=rtl]:after{left:0;right:100%;box-shadow:1px 1px 3px 0 rgba(0,0,0,.12)}.next-switch-on.next-switch-small[dir=rtl]>.next-switch-children{right:6px;left:auto}.next-switch-off[dir=rtl]:after{right:0;transform:translateX(0);box-shadow:-1px 0 3px 0 rgba(0,0,0,.12)}.next-switch-off[dir=rtl]>.next-switch-children{left:10px;right:auto}.next-switch-off.next-switch-small[dir=rtl]>.next-switch-children{left:5px;right:auto}.next-switch{outline:none;text-align:left;transition:all .1s linear;overflow:hidden;cursor:pointer}.next-switch,.next-switch *,.next-switch :after,.next-switch :before{box-sizing:border-box}.next-switch:after{content:" ";transition:all .1s linear;transform-origin:left center}.next-switch-medium{width:56px;height:26px;border-radius:20px}.next-switch-medium:after{border:1px solid transparent;position:absolute;left:100%;transform:translateX(-100%);width:24px;height:24px;border-radius:20px;box-sizing:border-box}.next-switch-medium>.next-switch-children{font-size:12px;height:24px;line-height:24px}.next-switch-small{position:relative;display:inline-block;width:44px;height:22px}.next-switch-small,.next-switch-small:after{border:1px solid transparent;border-radius:20px}.next-switch-small:after{position:absolute;left:100%;transform:translateX(-100%);width:20px;height:20px;box-sizing:border-box}.next-switch-small>.next-switch-children{font-size:12px;position:absolute;height:20px;line-height:20px}.next-switch-on{background-color:#5584ff}.next-switch-on:after{box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#fff;border-color:transparent}.next-switch-on>.next-switch-children{left:10px}.next-switch-on:focus,.next-switch-on:hover{background-color:#3e71f7}.next-switch-on:focus:after,.next-switch-on:hover:after{background-color:#fff}.next-switch-on.next-switch-small>.next-switch-children{left:6px}.next-switch-on[disabled]{background-color:#ebecf0;cursor:not-allowed}.next-switch-on[disabled]:after{right:0;box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#f7f8fa;border-color:#e6e7eb}.next-switch-on[disabled]>.next-switch-children{color:#ccc}.next-switch-off{background-color:#fff;border-color:#c4c6cf}.next-switch-off:focus,.next-switch-off:hover{background-color:#f2f3f7;border-color:#c4c6cf}.next-switch-off:after{left:0;transform:translateX(0);box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#fff;border-color:transparent}.next-switch-off:after:focus,.next-switch-off:after:hover{background-color:#fff}.next-switch-off>.next-switch-children{right:10px;color:#999}.next-switch-off[disabled]{background-color:#f7f8fa;cursor:not-allowed}.next-switch-off[disabled]:after{box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#f7f8fa;border-color:#e6e7eb}.next-switch-off[disabled]>.next-switch-children{color:#c4c6cf}.next-switch-off.next-switch-small>.next-switch-children{right:5px}
/*!
* Copyright 1999-2018 Alibaba Group Holding Ltd.

File diff suppressed because one or more lines are too long

View File

@ -105,12 +105,6 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>

View File

@ -46,4 +46,17 @@ public abstract class AbstractMemberLookup implements MemberLookup {
public void destroy() throws NacosException {
}
@Override
public void start() throws NacosException {
if (start.compareAndSet(false, true)) {
doStart();
}
}
/**
* subclass can override this method if need.
* @throws NacosException NacosException
*/
protected abstract void doStart() throws NacosException;
}

View File

@ -67,12 +67,10 @@ public class AddressServerMemberLookup extends AbstractMemberLookup {
private volatile boolean shutdown = false;
@Override
public void start() throws NacosException {
if (start.compareAndSet(false, true)) {
this.maxFailCount = Integer.parseInt(EnvUtil.getProperty("maxHealthCheckFailCount", "12"));
initAddressSys();
run();
}
public void doStart() throws NacosException {
this.maxFailCount = Integer.parseInt(EnvUtil.getProperty("maxHealthCheckFailCount", "12"));
initAddressSys();
run();
}
@Override

View File

@ -51,17 +51,15 @@ public class FileConfigMemberLookup extends AbstractMemberLookup {
};
@Override
public void start() throws NacosException {
if (start.compareAndSet(false, true)) {
readClusterConfFromDisk();
// Use the inotify mechanism to monitor file changes and automatically
// trigger the reading of cluster.conf
try {
WatchFileCenter.registerWatcher(EnvUtil.getConfPath(), watcher);
} catch (Throwable e) {
Loggers.CLUSTER.error("An exception occurred in the launch file monitor : {}", e.getMessage());
}
public void doStart() throws NacosException {
readClusterConfFromDisk();
// Use the inotify mechanism to monitor file changes and automatically
// trigger the reading of cluster.conf
try {
WatchFileCenter.registerWatcher(EnvUtil.getConfPath(), watcher);
} catch (Throwable e) {
Loggers.CLUSTER.error("An exception occurred in the launch file monitor : {}", e.getMessage());
}
}

View File

@ -31,11 +31,9 @@ import java.util.Collections;
public class StandaloneMemberLookup extends AbstractMemberLookup {
@Override
public void start() {
if (start.compareAndSet(false, true)) {
String url = InetUtils.getSelfIP() + ":" + EnvUtil.getPort();
afterLookup(MemberUtil.readServerConf(Collections.singletonList(url)));
}
public void doStart() {
String url = InetUtils.getSelfIP() + ":" + EnvUtil.getPort();
afterLookup(MemberUtil.readServerConf(Collections.singletonList(url)));
}
@Override

View File

@ -36,6 +36,9 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;
import static com.alibaba.nacos.common.constant.HttpHeaderConsts.ACCEPT_ENCODING;
import static com.alibaba.nacos.common.http.param.MediaType.APPLICATION_JSON;
/**
* web utils.
*
@ -43,6 +46,14 @@ import java.util.function.Function;
*/
public class WebUtils {
private static final String ENCODING_KEY = "encoding";
private static final String COMMA = ",";
private static final String SEMI = ";";
private static final String TMP_SUFFIX = ".tmp";
/**
* get target value from parameterMap, if not found will throw {@link IllegalArgumentException}.
*
@ -55,7 +66,7 @@ public class WebUtils {
if (StringUtils.isEmpty(value)) {
throw new IllegalArgumentException("Param '" + key + "' is required.");
}
String encoding = req.getParameter("encoding");
String encoding = req.getParameter(ENCODING_KEY);
return resolveValue(value, encoding);
}
@ -75,7 +86,7 @@ public class WebUtils {
if (StringUtils.isBlank(value)) {
return defaultValue;
}
String encoding = req.getParameter("encoding");
String encoding = req.getParameter(ENCODING_KEY);
return resolveValue(value, encoding);
}
@ -131,9 +142,9 @@ public class WebUtils {
* @return accept encode
*/
public static String getAcceptEncoding(HttpServletRequest req) {
String encode = StringUtils.defaultIfEmpty(req.getHeader("Accept-Charset"), StandardCharsets.UTF_8.name());
encode = encode.contains(",") ? encode.substring(0, encode.indexOf(",")) : encode;
return encode.contains(";") ? encode.substring(0, encode.indexOf(";")) : encode;
String encode = StringUtils.defaultIfEmpty(req.getHeader(ACCEPT_ENCODING), StandardCharsets.UTF_8.name());
encode = encode.contains(COMMA) ? encode.substring(0, encode.indexOf(COMMA)) : encode;
return encode.contains(SEMI) ? encode.substring(0, encode.indexOf(SEMI)) : encode;
}
/**
@ -162,7 +173,7 @@ public class WebUtils {
*/
public static void response(HttpServletResponse response, String body, int code) throws IOException {
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType("application/json;charset=UTF-8");
response.setContentType(APPLICATION_JSON);
response.getWriter().write(body);
response.setStatus(code);
}
@ -183,7 +194,7 @@ public class WebUtils {
}
File tmpFile = null;
try {
tmpFile = DiskUtils.createTmpFile(multipartFile.getName(), ".tmp");
tmpFile = DiskUtils.createTmpFile(multipartFile.getName(), TMP_SUFFIX);
multipartFile.transferTo(tmpFile);
consumer.accept(tmpFile);
} catch (Throwable ex) {

View File

@ -0,0 +1,141 @@
/*
* 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.core.cluster.lookup;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.Query;
import com.alibaba.nacos.core.cluster.ServerMemberManager;
import com.alibaba.nacos.core.utils.Loggers;
import com.alibaba.nacos.sys.env.EnvUtil;
import junit.framework.TestCase;
import org.apache.commons.lang3.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.util.ReflectionTestUtils;
import java.lang.reflect.Type;
import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class AddressServerMemberLookupTest extends TestCase {
@Mock
private NacosRestTemplate restTemplate;
@Mock
private ServerMemberManager memberManager;
@Mock
private HttpRestResult<String> result;
private AddressServerMemberLookup addressServerMemberLookup;
private String addressUrl;
private String envIdUrl;
private String addressServerUrl;
private String addressPort;
private String domainName;
@Mock
private ConfigurableEnvironment environment;
@Before
public void setUp() throws Exception {
EnvUtil.setEnvironment(environment);
when(environment.getProperty("maxHealthCheckFailCount", "12")).thenReturn("12");
when(environment.getProperty("nacos.core.address-server.retry", Integer.class, 5)).thenReturn(5);
when(environment.getProperty("address.server.domain", "jmenv.tbsite.net")).thenReturn("jmenv.tbsite.net");
when(environment.getProperty("address.server.port", "8080")).thenReturn("8080");
when(environment.getProperty("address.server.domain", "jmenv.tbsite.net")).thenReturn("jmenv.tbsite.net");
when(environment.getProperty(eq("address.server.url"), any(String.class))).thenReturn("/nacos/serverlist");
initAddressSys();
when(restTemplate.<String>get(eq(addressServerUrl), any(Header.EMPTY.getClass()), any(Query.EMPTY.getClass()), any(Type.class)))
.thenReturn(result);
addressServerMemberLookup = new AddressServerMemberLookup();
ReflectionTestUtils.setField(addressServerMemberLookup, "restTemplate", restTemplate);
when(result.ok()).thenReturn(true);
when(result.getData()).thenReturn("1.1.1.1:8848");
addressServerMemberLookup.start();
}
@After
public void tearDown() throws NacosException {
addressServerMemberLookup.destroy();
}
@Test
public void testMemberChange() throws Exception {
addressServerMemberLookup.injectMemberManager(memberManager);
verify(restTemplate).get(eq(addressServerUrl), any(Header.EMPTY.getClass()), any(Query.EMPTY.getClass()), any(Type.class));
}
@Test
public void testInfo() {
Map<String, Object> infos = addressServerMemberLookup.info();
assertEquals(4, infos.size());
assertTrue(infos.containsKey("addressServerHealth"));
assertTrue(infos.containsKey("addressServerUrl"));
assertTrue(infos.containsKey("envIdUrl"));
assertTrue(infos.containsKey("addressServerFailCount"));
assertEquals(addressServerUrl, infos.get("addressServerUrl"));
assertEquals(envIdUrl, infos.get("envIdUrl"));
}
private void initAddressSys() {
String envDomainName = System.getenv("address_server_domain");
if (StringUtils.isBlank(envDomainName)) {
domainName = EnvUtil.getProperty("address.server.domain", "jmenv.tbsite.net");
} else {
domainName = envDomainName;
}
String envAddressPort = System.getenv("address_server_port");
if (StringUtils.isBlank(envAddressPort)) {
addressPort = EnvUtil.getProperty("address.server.port", "8080");
} else {
addressPort = envAddressPort;
}
String envAddressUrl = System.getenv("address_server_url");
if (StringUtils.isBlank(envAddressUrl)) {
addressUrl = EnvUtil.getProperty("address.server.url", EnvUtil.getContextPath() + "/" + "serverlist");
} else {
addressUrl = envAddressUrl;
}
addressServerUrl = "http://" + domainName + ":" + addressPort + addressUrl;
envIdUrl = "http://" + domainName + ":" + addressPort + "/env";
Loggers.CORE.info("ServerListService address-server port:" + addressPort);
Loggers.CORE.info("ADDRESS_SERVER_URL:" + addressServerUrl);
}
}

View File

@ -0,0 +1,101 @@
/*
* 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.core.cluster.lookup;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.core.cluster.MemberLookup;
import com.alibaba.nacos.core.cluster.ServerMemberManager;
import com.alibaba.nacos.sys.env.EnvUtil;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.env.StandardEnvironment;
import javax.servlet.ServletContext;
import java.io.File;
import java.util.Objects;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class LookupFactoryTest extends TestCase {
@Mock
private ServletContext servletContext;
private static final String LOOKUP_MODE_TYPE = "nacos.core.member.lookup.type";
private ServerMemberManager memberManager;
private MemberLookup memberLookup;
@Before
public void setUp() throws Exception {
when(servletContext.getContextPath()).thenReturn("");
EnvUtil.setEnvironment(new StandardEnvironment());
memberManager = new ServerMemberManager(servletContext);
}
@Test
public void testCreateLookUp() throws NacosException {
memberLookup = LookupFactory.createLookUp(memberManager);
if (EnvUtil.getStandaloneMode()) {
assertEquals(memberLookup.getClass(), StandaloneMemberLookup.class);
} else {
String lookupType = EnvUtil.getProperty(LOOKUP_MODE_TYPE);
if (StringUtils.isNotBlank(lookupType)) {
LookupFactory.LookupType type = LookupFactory.LookupType.sourceOf(lookupType);
if (Objects.nonNull(type)) {
if (LookupFactory.LookupType.FILE_CONFIG.equals(type)) {
assertEquals(memberLookup.getClass(), FileConfigMemberLookup.class);
}
if (LookupFactory.LookupType.ADDRESS_SERVER.equals(type)) {
assertEquals(memberLookup.getClass(), AddressServerMemberLookup.class);
}
} else {
File file = new File(EnvUtil.getClusterConfFilePath());
if (file.exists() || StringUtils.isNotBlank(EnvUtil.getMemberList())) {
assertEquals(memberLookup.getClass(), FileConfigMemberLookup.class);
} else {
assertEquals(memberLookup.getClass(), AddressServerMemberLookup.class);
}
}
} else {
File file = new File(EnvUtil.getClusterConfFilePath());
if (file.exists() || StringUtils.isNotBlank(EnvUtil.getMemberList())) {
assertEquals(memberLookup.getClass(), FileConfigMemberLookup.class);
} else {
assertEquals(memberLookup.getClass(), AddressServerMemberLookup.class);
}
}
}
}
@Test
public void testSwitchLookup() throws NacosException {
String name1 = "file";
MemberLookup memberLookup = LookupFactory.switchLookup(name1, memberManager);
assertEquals(memberLookup.getClass(), FileConfigMemberLookup.class);
String name2 = "address-server";
memberLookup = LookupFactory.switchLookup(name2, memberManager);
assertEquals(memberLookup.getClass(), AddressServerMemberLookup.class);
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.core.distributed.distro;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
public class DistroConfigTest extends TestCase {
private DistroConfig distroConfig;
private long syncDelayMillis = 2000;
private long syncRetryDelayMillis = 4000;
private long verifyIntervalMillis = 6000;
private long loadDataRetryDelayMillis = 80000;
@Before
public void setUp() {
distroConfig = DistroConfig.getInstance();
}
@Test
public void testSetSyncDelayMillis() {
distroConfig.setSyncDelayMillis(syncDelayMillis);
assertEquals(syncDelayMillis, distroConfig.getSyncDelayMillis());
}
@Test
public void testSetSyncRetryDelayMillis() {
distroConfig.setSyncRetryDelayMillis(syncRetryDelayMillis);
assertEquals(syncRetryDelayMillis, distroConfig.getSyncRetryDelayMillis());
}
@Test
public void testSetVerifyIntervalMillis() {
distroConfig.setVerifyIntervalMillis(verifyIntervalMillis);
assertEquals(verifyIntervalMillis, distroConfig.getVerifyIntervalMillis());
}
public void testSetLoadDataRetryDelayMillis() {
distroConfig.setLoadDataRetryDelayMillis(loadDataRetryDelayMillis);
assertEquals(loadDataRetryDelayMillis, distroConfig.getLoadDataRetryDelayMillis());
}
}

View File

@ -0,0 +1,85 @@
/*
* 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.core.distributed.distro.component;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class DistroComponentHolderTest extends TestCase {
private final String type = "com.alibaba.nacos.naming.iplist.";
private DistroComponentHolder componentHolder;
@Mock
private DistroDataStorage distroDataStorage;
@Mock
private DistroTransportAgent distroTransportAgent;
@Mock
private DistroFailedTaskHandler distroFailedTaskHandler;
@Mock
private DistroDataProcessor distroDataProcessor;
@Before
public void setUp() {
componentHolder = new DistroComponentHolder();
componentHolder.registerDataStorage(type, distroDataStorage);
componentHolder.registerTransportAgent(type, distroTransportAgent);
componentHolder.registerFailedTaskHandler(type, distroFailedTaskHandler);
when(distroDataProcessor.processType()).thenReturn(type);
componentHolder.registerDataProcessor(distroDataProcessor);
}
@Test
public void testFindTransportAgent() {
DistroTransportAgent distroTransportAgent = componentHolder.findTransportAgent(type);
assertEquals(this.distroTransportAgent, distroTransportAgent);
}
@Test
public void testFindDataStorage() {
DistroDataStorage distroDataStorage = componentHolder.findDataStorage(type);
assertEquals(this.distroDataStorage, distroDataStorage);
}
@Test
public void testGetDataStorageTypes() {
componentHolder.getDataStorageTypes();
}
@Test
public void testFindFailedTaskHandler() {
DistroFailedTaskHandler distroFailedTaskHandler = componentHolder.findFailedTaskHandler(type);
assertEquals(this.distroFailedTaskHandler, distroFailedTaskHandler);
}
@Test
public void testFindDataProcessor() {
DistroDataProcessor distroDataProcessor = componentHolder.findDataProcessor(type);
assertEquals(this.distroDataProcessor, distroDataProcessor);
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.core.distributed.distro.entity;
import com.alibaba.nacos.consistency.DataOperation;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
public class DistroDataTest extends TestCase {
private DistroData distroData;
private DistroKey distroKey;
private final String type = "com.alibaba.nacos.naming.iplist.";
private int contentSize = 10;
private final byte[] content = new byte[contentSize];
@Before
public void setUp() {
distroKey = new DistroKey("checksum", type);
distroData = new DistroData(distroKey, content);
distroData.setType(DataOperation.VERIFY);
}
@Test
public void testGetters() {
assertEquals(distroKey, distroData.getDistroKey());
assertEquals(content, distroData.getContent());
assertEquals(DataOperation.VERIFY, distroData.getType());
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.core.distributed.distro.entity;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class DistroKeyTest {
private final String type = "com.alibaba.nacos.naming.iplist.";
private final String resourceKey = "checksum";
private final String targetServer = "1.1.1.1";
private DistroKey distroKey1;
private DistroKey distroKey2;
@Before
public void setUp() {
distroKey1 = new DistroKey(resourceKey, type, targetServer);
distroKey2 = new DistroKey();
distroKey2.setResourceKey(resourceKey);
distroKey2.setResourceType(type);
distroKey2.setTargetServer(targetServer);
}
@Test
public void testGetters() {
Assert.assertEquals(distroKey2.getResourceKey(), resourceKey);
Assert.assertEquals(distroKey2.getResourceType(), type);
Assert.assertEquals(distroKey2.getTargetServer(), targetServer);
}
@Test
public void testEquals() {
Assert.assertEquals(distroKey1, distroKey2);
}
}

View File

@ -0,0 +1,106 @@
/*
* 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.core.distributed.distro.task.load;
import com.alibaba.nacos.core.cluster.Member;
import com.alibaba.nacos.core.cluster.ServerMemberManager;
import com.alibaba.nacos.core.distributed.distro.DistroConfig;
import com.alibaba.nacos.core.distributed.distro.component.DistroCallback;
import com.alibaba.nacos.core.distributed.distro.component.DistroComponentHolder;
import com.alibaba.nacos.core.distributed.distro.component.DistroDataProcessor;
import com.alibaba.nacos.core.distributed.distro.component.DistroDataStorage;
import com.alibaba.nacos.core.distributed.distro.component.DistroFailedTaskHandler;
import com.alibaba.nacos.core.distributed.distro.component.DistroTransportAgent;
import com.alibaba.nacos.core.distributed.distro.entity.DistroData;
import com.alibaba.nacos.sys.env.EnvUtil;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class DistroLoadDataTaskTest extends TestCase {
private final String type = "com.alibaba.nacos.naming.iplist.";
private DistroComponentHolder componentHolder;
@Mock
private DistroDataStorage distroDataStorage;
@Mock
private DistroTransportAgent distroTransportAgent;
@Mock
private DistroFailedTaskHandler distroFailedTaskHandler;
@Mock
private DistroDataProcessor distroDataProcessor;
@Mock
private DistroData distroData;
private DistroLoadDataTask distroLoadDataTask;
@Mock
private ServerMemberManager memberManager;
@Mock
private DistroConfig distroConfig;
@Mock
private DistroCallback loadCallback;
@Before
public void setUp() throws Exception {
EnvUtil.setEnvironment(new StandardEnvironment());
memberManager = new ServerMemberManager(new MockServletContext());
Member member1 = Member.builder().ip("2.2.2.2").port(8848).build();
Member member2 = Member.builder().ip("1.1.1.1").port(8848).build();
memberManager.update(member1);
memberManager.update(member2);
componentHolder = new DistroComponentHolder();
componentHolder.registerDataStorage(type, distroDataStorage);
componentHolder.registerTransportAgent(type, distroTransportAgent);
componentHolder.registerFailedTaskHandler(type, distroFailedTaskHandler);
when(distroDataProcessor.processType()).thenReturn(type);
componentHolder.registerDataProcessor(distroDataProcessor);
when(distroTransportAgent.getDatumSnapshot(any(String.class))).thenReturn(distroData);
when(distroDataProcessor.processSnapshot(distroData)).thenReturn(true);
distroLoadDataTask = new DistroLoadDataTask(memberManager, componentHolder, distroConfig, loadCallback);
}
@Test
public void testRun() {
distroLoadDataTask.run();
Map<String, Boolean> loadCompletedMap = (Map<String, Boolean>) ReflectionTestUtils.getField(distroLoadDataTask, "loadCompletedMap");
assertNotNull(loadCompletedMap);
assertTrue(loadCompletedMap.containsKey(type));
verify(distroTransportAgent).getDatumSnapshot(any(String.class));
}
}

View File

@ -38,11 +38,6 @@
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-common</artifactId>

View File

@ -30,11 +30,6 @@
<url>http://nacos.io</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-api</artifactId>

View File

@ -40,11 +40,6 @@
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-core</artifactId>

View File

@ -82,15 +82,13 @@ public class ClientBeatProcessor implements BeatProcessor {
Loggers.EVT_LOG.debug("[CLIENT-BEAT] refresh beat: {}", rsInfo.toString());
}
instance.setLastBeat(System.currentTimeMillis());
if (!instance.isMarked()) {
if (!instance.isHealthy()) {
instance.setHealthy(true);
Loggers.EVT_LOG
.info("service: {} {POS} {IP-ENABLED} valid: {}:{}@{}, region: {}, msg: client beat ok",
cluster.getService().getName(), ip, port, cluster.getName(),
UtilsAndCommons.LOCALHOST_SITE);
getPushService().serviceChanged(service);
}
if (!instance.isMarked() && !instance.isHealthy()) {
instance.setHealthy(true);
Loggers.EVT_LOG
.info("service: {} {POS} {IP-ENABLED} valid: {}:{}@{}, region: {}, msg: client beat ok",
cluster.getService().getName(), ip, port, cluster.getName(),
UtilsAndCommons.LOCALHOST_SITE);
getPushService().serviceChanged(service);
}
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.naming.consistency.ephemeral.distro;
import com.alibaba.nacos.naming.consistency.Datum;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Map;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class DataStoreTest extends TestCase {
private DataStore dataStore;
private String key;
@Mock
private Datum datum;
@Mock
private Map<String, Datum> dataMap;
@Before
public void setUp() {
dataStore = new DataStore();
key = "tmp_key";
ReflectionTestUtils.setField(dataStore, "dataMap", dataMap);
}
@Test
public void testPut() {
dataStore.put(key, datum);
verify(dataMap).put(key, datum);
}
@Test
public void testRemove() {
dataStore.remove(key);
verify(dataMap).remove(key);
}
@Test
public void testKeys() {
dataStore.keys();
verify(dataMap).keySet();
}
@Test
public void testGet() {
dataStore.get(key);
verify(dataMap).get(key);
}
@Test
public void testContains() {
dataStore.contains(key);
verify(dataMap).containsKey(key);
}
}

View File

@ -29,15 +29,44 @@ import org.junit.Test;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.mock.web.MockServletContext;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
public class ClusterVersionJudgementTest {
private ServerMemberManager manager;
private String[] ipList;
private final int ipCount = 3;
private final String ip1 = "1.1.1.1";
private final String ip2 = "2.2.2.2";
private final String ip3 = "3.3.3.3";
private final int defalutPort = 80;
private final String newVersion = "1.4.0";
private final String oldVersion = "1.3.0";
private List<Member> members;
private Map<String, Object> newVersionMeta;
private Map<String, Object> oldVersionMeta;
private ClusterVersionJudgement judgement;
public ClusterVersionJudgementTest() {
}
@BeforeClass
public static void beforeClass() {
EnvUtil.setEnvironment(new MockEnvironment());
@ -46,6 +75,19 @@ public class ClusterVersionJudgementTest {
@Before
public void beforeMethod() throws Exception {
manager = new ServerMemberManager(new MockServletContext());
newVersionMeta = new HashMap<>(4);
newVersionMeta.put(MemberMetaDataConstants.VERSION, newVersion);
oldVersionMeta = new HashMap<>(4);
oldVersionMeta.put(MemberMetaDataConstants.VERSION, oldVersion);
ipList = new String[ipCount];
ipList[0] = ip1;
ipList[1] = ip2;
ipList[2] = ip3;
members = new LinkedList<>();
members.add(Member.builder().ip(ipList[0]).port(defalutPort).state(NodeState.UP).build());
members.add(Member.builder().ip(ipList[1]).port(defalutPort).state(NodeState.UP).build());
members.add(Member.builder().ip(ipList[2]).port(defalutPort).state(NodeState.UP).build());
manager.memberJoin(members);
}
@After
@ -59,49 +101,49 @@ public class ClusterVersionJudgementTest {
*/
@Test
public void testAllMemberIsNewVersion() {
Map<String, String> metadataInfo = new HashMap<>(4);
metadataInfo.put(MemberMetaDataConstants.VERSION, "1.4.0");
Collection<Member> members = Arrays
.asList(Member.builder().ip("1.1.1.1").port(80).state(NodeState.UP).extendInfo(metadataInfo).build(),
Member.builder().ip("2.2.2.2").port(80).state(NodeState.UP).extendInfo(metadataInfo).build(),
Member.builder().ip("3.3.3.3").port(80).state(NodeState.UP).extendInfo(metadataInfo).build());
manager.memberJoin(members);
ClusterVersionJudgement judgement = new ClusterVersionJudgement(manager);
Collection<Member> allMembers = manager.allMembers();
allMembers.forEach(member -> member.setExtendInfo(newVersionMeta));
judgement = new ClusterVersionJudgement(manager);
judgement.judge();
Assert.assertTrue(judgement.allMemberIsNewVersion());
}
@Test
public void testPartMemberIsNewVersion() {
Map<String, String> metadataInfo = new HashMap<>(4);
metadataInfo.put(MemberMetaDataConstants.VERSION, "1.4.0");
Collection<Member> members = Arrays
.asList(Member.builder().ip("1.1.1.1").port(80).state(NodeState.UP).extendInfo(metadataInfo).build(),
Member.builder().ip("2.2.2.2").port(80).state(NodeState.UP).extendInfo(metadataInfo).build(),
Member.builder().ip("3.3.3.3").port(80).state(NodeState.UP).build());
manager.memberJoin(members);
ClusterVersionJudgement judgement = new ClusterVersionJudgement(manager);
Collection<Member> allMembers = manager.allMembers();
AtomicInteger count = new AtomicInteger();
allMembers.forEach(member -> {
if (count.get() == 0) {
member.setExtendInfo(oldVersionMeta);
} else {
count.incrementAndGet();
member.setExtendInfo(newVersionMeta);
}
});
judgement = new ClusterVersionJudgement(manager);
judgement.judge();
Assert.assertFalse(judgement.allMemberIsNewVersion());
}
@Test
public void testPartMemberUpdateToNewVersion() {
Map<String, String> metadataInfo = new HashMap<>(4);
metadataInfo.put(MemberMetaDataConstants.VERSION, "1.4.0");
Collection<Member> members = Arrays
.asList(Member.builder().ip("1.1.1.1").port(80).state(NodeState.UP).extendInfo(metadataInfo).build(),
Member.builder().ip("2.2.2.2").port(80).state(NodeState.UP).extendInfo(metadataInfo).build(),
Member.builder().ip("3.3.3.3").port(80).state(NodeState.UP).build());
manager.memberJoin(members);
ClusterVersionJudgement judgement = new ClusterVersionJudgement(manager);
// Firstly, make a cluster with a part of new version servers.
Collection<Member> allMembers = manager.allMembers();
AtomicInteger count = new AtomicInteger();
allMembers.forEach(member -> {
if (count.get() == 0) {
member.setExtendInfo(oldVersionMeta);
} else {
count.incrementAndGet();
member.setExtendInfo(newVersionMeta);
}
});
judgement = new ClusterVersionJudgement(manager);
judgement.judge();
Assert.assertFalse(judgement.allMemberIsNewVersion());
// update 3.3.3.3:80 version to 1.4.0
manager.update(Member.builder().ip("3.3.3.3").port(80).state(NodeState.UP).extendInfo(metadataInfo).build());
judgement.registerObserver(Assert::assertTrue, 0);
// Secondly, make all in the cluster to be new version servers.
allMembers.forEach(member -> member.setExtendInfo(newVersionMeta));
judgement = new ClusterVersionJudgement(manager);
judgement.judge();
Assert.assertTrue(judgement.allMemberIsNewVersion());
}

View File

@ -0,0 +1,87 @@
/*
* 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.naming.consistency.persistent.impl;
import com.alibaba.nacos.core.exception.KvStorageException;
import com.alibaba.nacos.core.storage.kv.FileKvStorage;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.lang.reflect.Field;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class NamingKvStorageTest extends TestCase {
private NamingKvStorage namingKvStorage;
@Mock
private FileKvStorage baseDirStorageMock;
private final byte[] key = "fileName_test".getBytes();
private final String str = "str_test";
@Before
public void setUp() throws Exception {
super.setUp();
namingKvStorage = new NamingKvStorage("baseDir_test");
Field baseDirStorageField = NamingKvStorage.class.getDeclaredField("baseDirStorage");
baseDirStorageField.setAccessible(true);
baseDirStorageField.set(namingKvStorage, baseDirStorageMock);
when(baseDirStorageMock.get(key)).thenReturn(null);
}
@Test
public void testGet() throws KvStorageException {
namingKvStorage.get(key);
verify(baseDirStorageMock).get(key);
}
@Test
public void testPut() throws KvStorageException {
byte[] value = "value_test".getBytes();
namingKvStorage.put(key, value);
verify(baseDirStorageMock).put(key, value);
}
@Test
public void testDelete() throws KvStorageException {
namingKvStorage.delete(key);
verify(baseDirStorageMock).delete(key);
}
@Test
public void testDoSnapshot() throws KvStorageException {
namingKvStorage.doSnapshot(str);
verify(baseDirStorageMock).doSnapshot(str);
}
@Test
public void testSnapshotLoad() throws KvStorageException {
namingKvStorage.snapshotLoad(str);
verify(baseDirStorageMock).snapshotLoad(str);
}
}

View File

@ -22,7 +22,6 @@ import com.alibaba.nacos.core.distributed.raft.RaftConfig;
import com.alibaba.nacos.core.distributed.raft.utils.RaftExecutor;
import com.alibaba.nacos.core.storage.kv.KvStorage;
import com.alibaba.nacos.sys.env.EnvUtil;
import com.alibaba.nacos.sys.utils.DiskUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@ -38,6 +37,9 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
@RunWith(MockitoJUnitRunner.class)
public class NamingSnapshotOperationTest {
@ -49,21 +51,23 @@ public class NamingSnapshotOperationTest {
@Mock
private KvStorage storage;
private final String tmpDir = Paths.get(EnvUtil.getNacosTmpDir(), "rocks_test").toString();
private final String snapshotDir = Paths.get(EnvUtil.getNacosTmpDir(), "rocks_snapshot_test").toString();
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private boolean isSnapshoted = false;
@Before
public void init() {
DiskUtils.deleteQuietly(Paths.get(EnvUtil.getNacosTmpDir()));
public void init() throws Exception {
doAnswer(invocationOnMock -> {
isSnapshoted = true;
return null;
}).when(storage).doSnapshot(any(String.class));
}
@After
public void after() {
storage.shutdown();
DiskUtils.deleteQuietly(Paths.get(EnvUtil.getNacosTmpDir()));
}
@Test
@ -78,6 +82,7 @@ public class NamingSnapshotOperationTest {
latch.countDown();
});
latch.await(10, TimeUnit.SECONDS);
Assert.assertTrue(isSnapshoted);
Assert.assertTrue(result.get());
final Reader reader = new Reader(snapshotDir, writer.listFiles());

View File

@ -0,0 +1,82 @@
/*
* 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.naming.core;
import com.alibaba.nacos.core.cluster.Member;
import com.alibaba.nacos.core.cluster.ServerMemberManager;
import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.sys.env.EnvUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.env.StandardEnvironment;
import java.util.HashSet;
import java.util.concurrent.ConcurrentSkipListMap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(MockitoJUnitRunner.class)
public class DistroMapperTest {
private DistroMapper distroMapper;
@Mock
private ServerMemberManager memberManager;
private SwitchDomain switchDomain;
private String serviceName = "com.taobao.service";
private String ip1 = "1.1.1.1";
private String ip2 = "2.2.2.2";
private String ip3 = "3.3.3.3";
private String ip4 = "4.4.4.4";
private int port = 8848;
@Before
public void setUp() {
ConcurrentSkipListMap<String, Member> serverList = new ConcurrentSkipListMap<>();
EnvUtil.setEnvironment(new StandardEnvironment());
serverList.put(ip1, Member.builder().ip(ip1).port(port).build());
serverList.put(ip2, Member.builder().ip(ip2).port(port).build());
serverList.put(ip3, Member.builder().ip(ip3).port(port).build());
EnvUtil.setLocalAddress(ip4);
serverList.put(EnvUtil.getLocalAddress(), Member.builder().ip(EnvUtil.getLocalAddress()).port(port).build());
HashSet<Member> set = new HashSet<>(serverList.values());
switchDomain = new SwitchDomain();
distroMapper = new DistroMapper(memberManager, switchDomain);
}
@Test
public void testResponsible() {
assertTrue(distroMapper.responsible(serviceName));
}
@Test
public void testMapSrv() {
String server = distroMapper.mapSrv(serviceName);
assertEquals(server, ip4);
}
}

View File

@ -58,12 +58,6 @@
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>

View File

@ -29,13 +29,13 @@ import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import static com.alibaba.nacos.sys.env.Constants.IP_ADDRESS;
import static com.alibaba.nacos.sys.env.Constants.NACOS_SERVER_IP;
@ -62,6 +62,9 @@ public class InetUtils {
private static final List<String> IGNORED_INTERFACES = new ArrayList<String>();
private static Pattern domainPattern = Pattern
.compile("[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?");
static {
NotifyCenter.registerToSharePublisher(IPChangeEvent.class);
@ -92,8 +95,7 @@ public class InetUtils {
preferHostnameOverIP = Boolean.getBoolean(SYSTEM_PREFER_HOSTNAME_OVER_IP);
if (!preferHostnameOverIP) {
preferHostnameOverIP = Boolean
.parseBoolean(EnvUtil.getProperty(PREFER_HOSTNAME_OVER_IP));
preferHostnameOverIP = Boolean.parseBoolean(EnvUtil.getProperty(PREFER_HOSTNAME_OVER_IP));
}
if (preferHostnameOverIP) {
@ -157,7 +159,7 @@ public class InetUtils {
} else {
continue;
}
if (!ignoreInterface(ifc.getDisplayName())) {
for (Enumeration<InetAddress> addrs = ifc.getInetAddresses(); addrs.hasMoreElements(); ) {
InetAddress address = addrs.nextElement();
@ -220,18 +222,16 @@ public class InetUtils {
}
/**
* juege str is right domain.
* juege str is right domain.Check only rule
*
* @param str nacosIP
* @return nacosIP is domain
*/
public static boolean isDomain(String str) {
InetSocketAddress address = new InetSocketAddress(str, 0);
boolean unResolved = address.isUnresolved();
if (unResolved) {
LOG.warn("the domain: '" + str + "' can not be resolved");
if (StringUtils.isBlank(str)) {
return false;
}
return !unResolved;
return domainPattern.matcher(str).matches();
}
/**

View File

@ -92,12 +92,6 @@
<artifactId>nacos-address</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
@ -110,12 +104,6 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.keran213539</groupId>
<artifactId>commonOkHttp</artifactId>