Merge pull request #5 from alibaba/develop

更新代码
This commit is contained in:
邪影oO 2019-07-09 10:45:41 +08:00 committed by GitHub
commit 3d65579094
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 1739 additions and 225 deletions

123
address/pom.xml Normal file
View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos-address</artifactId>
<packaging>jar</packaging>
<name>nacos-address ${project.version}</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-naming</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-cmdb</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.4</version>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>release-address</id>
<build>
<finalName>nacos-address</finalName>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.alibaba.nacos.address.AddressServer</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,33 @@
/*
* 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.address;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* support address server.
*
* @author nacos
* @since 1.1.0
*/
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
public class AddressServer {
public static void main(String[] args) {
SpringApplication.run(AddressServer.class, args);
}
}

View File

@ -0,0 +1,118 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address.component;
import com.alibaba.nacos.address.constant.AddressServerConstants;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.naming.core.Instance;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* will generator some result by the input parameter.
*
* @author pbting
* @date 2019-07-01 8:53 PM
* @since 1.1.0
*/
@Component
public class AddressServerGeneratorManager {
public String generateProductName(String name) {
if (StringUtils.isBlank(name) || AddressServerConstants.DEFAULT_PRODUCT.equals(name)) {
return AddressServerConstants.ALIWARE_NACOS_DEFAULT_PRODUCT_NAME;
}
return String.format(AddressServerConstants.ALIWARE_NACOS_PRODUCT_DOM_TEMPLATE, name);
}
/**
* Note: if the parameter inputted is empty then will return the empty list.
*
* @param serviceName
* @param clusterName
* @param ipArray
* @return
*/
public List<Instance> generateInstancesByIps(String serviceName, String rawProductName, String clusterName, String[] ipArray) {
if (StringUtils.isEmpty(serviceName)
|| StringUtils.isEmpty(clusterName)
|| ipArray == null || ipArray.length == 0) {
return Collections.emptyList();
}
List<Instance> instanceList = new ArrayList<>(ipArray.length);
for (String ip : ipArray) {
String[] ipAndPort = generateIpAndPort(ip);
Instance instance = new Instance();
instance.setIp(ipAndPort[0]);
instance.setPort(Integer.valueOf(ipAndPort[1]));
instance.setClusterName(clusterName);
instance.setServiceName(serviceName);
instance.setTenant(Constants.DEFAULT_NAMESPACE_ID);
instance.setApp(rawProductName);
instance.setEphemeral(false);
instanceList.add(instance);
}
return instanceList;
}
public String[] generateIpAndPort(String ip) {
int index = ip.indexOf(AddressServerConstants.IP_PORT_SEPARATOR);
if (index != -1) {
return new String[]{ip.substring(0, index), ip.substring(index + 1)};
}
return new String[]{ip, String.valueOf(AddressServerConstants.DEFAULT_SERVER_PORT)};
}
/**
* @param instanceList a instance set will generate string response to client.
* @return the result of response to client
*/
public String generateResponseIps(List<Instance> instanceList) {
StringBuilder ips = new StringBuilder();
instanceList.forEach(instance -> {
ips.append(instance.getIp() + ":" + instance.getPort());
ips.append("\n");
});
return ips.toString();
}
/**
* @param rawServiceName the raw service name will not contains the {@Constans.DEFAULT_GROUP}
* @return the nacos service name
*/
public String generateNacosServiceName(String rawServiceName) {
if (rawServiceName.indexOf(Constants.DEFAULT_GROUP) != -1) {
return rawServiceName;
}
return Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + rawServiceName;
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address.component;
import com.alibaba.nacos.address.constant.AddressServerConstants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
/**
* This class holds the IP list of the CAI's address service.
*
* @author deshao
* @date 2016/4/28 20:58
* @since 1.1.0
*/
@Component
public class AddressServerManager {
public String getRawProductName(String name) {
if (StringUtils.isBlank(name) || AddressServerConstants.DEFAULT_PRODUCT.equals(name)) {
return AddressServerConstants.DEFAULT_PRODUCT;
}
return name;
}
/**
* <p>
* if the name is empty then return the default {@UtilAndCommons#DEFAULT_CLUSTER_NAME},
* <p>
* or return the source name by input
*
* @param name
* @return
*/
public String getDefaultClusterNameIfEmpty(String name) {
if (StringUtils.isEmpty(name) || AddressServerConstants.DEFAULT_GET_CLUSTER.equals(name)) {
return AddressServerConstants.DEFAULT_GET_CLUSTER;
}
return name;
}
public String getRawClusterName(String name) {
return getDefaultClusterNameIfEmpty(name);
}
/**
* @param ips multi ip will separator by the ','
* @return
*/
public String[] splitIps(String ips) {
if (StringUtils.isBlank(ips)) {
return new String[0];
}
return ips.split(AddressServerConstants.MULTI_IPS_SEPARATOR);
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address.constant;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
/**
* Uniform constant parameter naming for address servers and default values for related parameters
*
* @author pbting
* @date 2019-06-17 7:23 PM
* @since 1.1.0
*/
public interface AddressServerConstants {
/**
* the default server port when create the Instance object.
*/
int DEFAULT_SERVER_PORT = 8848;
/**
* when post ips is not given the product,then use the default.
*/
String DEFAULT_PRODUCT = "nacos";
/**
* the separator between ip and port.
*/
String IP_PORT_SEPARATOR = ":";
/**
* the separator for {@Service#name} between raw service name and group
*/
String GROUP_SERVICE_NAME_SEP = "@@";
/**
* when post ips is not given the cluster,then use the default.
*/
String DEFAULT_GET_CLUSTER = "serverlist";
/**
* post multi ip will use the "," to separator
*/
String MULTI_IPS_SEPARATOR = ",";
/**
* the default product name when deploy nacos with naming and config
*/
String ALIWARE_NACOS_DEFAULT_PRODUCT_NAME = "nacos.as.default";
/**
* when the config and naming will separate deploy,then must specify product name by the client
*/
String ALIWARE_NACOS_PRODUCT_DOM_TEMPLATE = "nacos.as.%s";
/**
* the url for address server prefix
*/
String ADDRESS_SERVER_REQUEST_URL =
UtilsAndCommons.NACOS_SERVER_CONTEXT + UtilsAndCommons.NACOS_SERVER_VERSION + "/as";
}

View File

@ -0,0 +1,153 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address.controller;
import com.alibaba.nacos.address.component.AddressServerGeneratorManager;
import com.alibaba.nacos.address.component.AddressServerManager;
import com.alibaba.nacos.address.constant.AddressServerConstants;
import com.alibaba.nacos.address.misc.Loggers;
import com.alibaba.nacos.address.util.AddressServerParamCheckUtil;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
import com.alibaba.nacos.naming.core.Cluster;
import com.alibaba.nacos.naming.core.Instance;
import com.alibaba.nacos.naming.core.Service;
import com.alibaba.nacos.naming.core.ServiceManager;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author pbting
* @date 2019-06-10 9:59 AM
* @since 1.1.0
*/
@RestController
@RequestMapping({AddressServerConstants.ADDRESS_SERVER_REQUEST_URL + "/nodes"})
public class AddressServerClusterController {
@Autowired
private ServiceManager serviceManager;
@Autowired
private AddressServerManager addressServerManager;
@Autowired
private AddressServerGeneratorManager addressServerGeneratorManager;
/**
* @param product Ip list of products to be associated
* @param cluster Ip list of product cluster to be associated
* @param ips will post ip list.
* @return
*/
@RequestMapping(value = "", method = RequestMethod.POST)
public ResponseEntity postCluster(@RequestParam(required = false) String product,
@RequestParam(required = false) String cluster,
@RequestParam(name = "ips") String ips) {
//1. prepare the storage name for product and cluster
String productName = addressServerGeneratorManager.generateProductName(product);
String clusterName = addressServerManager.getDefaultClusterNameIfEmpty(cluster);
//2. prepare the response name for product and cluster to client
String rawProductName = addressServerManager.getRawProductName(product);
String rawClusterName = addressServerManager.getRawClusterName(cluster);
Loggers.addressLogger.info("put cluster node,the cluster name is " + cluster + "; the product name=" + product + "; the ip list=" + ips);
ResponseEntity responseEntity;
try {
String serviceName = addressServerGeneratorManager.generateNacosServiceName(productName);
Cluster clusterObj = new Cluster();
clusterObj.setName(clusterName);
clusterObj.setHealthChecker(new AbstractHealthChecker.None());
serviceManager.createServiceIfAbsent(Constants.DEFAULT_NAMESPACE_ID, serviceName, false, clusterObj);
String[] ipArray = addressServerManager.splitIps(ips);
String checkResult = AddressServerParamCheckUtil.checkIps(ipArray);
if (AddressServerParamCheckUtil.CHECK_OK.equals(checkResult)) {
List<Instance> instanceList = addressServerGeneratorManager.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray);
for (Instance instance : instanceList) {
serviceManager.registerInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, instance);
}
responseEntity = ResponseEntity.ok("product=" + rawProductName + ",cluster=" + rawClusterName + "; put success with size=" + instanceList.size());
} else {
responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(checkResult);
}
} catch (Exception e) {
responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
return responseEntity;
}
/**
* @param product Ip list of products to be associated
* @param cluster Ip list of product cluster to be associated
* @param ips will delete ips.
* @return
*/
@RequestMapping(value = "", method = RequestMethod.DELETE)
public ResponseEntity deleteCluster(@RequestParam(required = false) String product,
@RequestParam(required = false) String cluster,
@RequestParam String ips) {
//1. prepare the storage name for product and cluster
String productName = addressServerGeneratorManager.generateProductName(product);
String clusterName = addressServerManager.getDefaultClusterNameIfEmpty(cluster);
//2. prepare the response name for product and cluster to client
String rawProductName = addressServerManager.getRawProductName(product);
String rawClusterName = addressServerManager.getRawClusterName(cluster);
ResponseEntity responseEntity = ResponseEntity.status(HttpStatus.OK).body("product=" + rawProductName + ", cluster=" + rawClusterName + " delete success.");
try {
String serviceName = addressServerGeneratorManager.generateNacosServiceName(productName);
Service service = serviceManager.getService(Constants.DEFAULT_NAMESPACE_ID, serviceName);
if (service == null) {
responseEntity = ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + rawProductName + " not found.");
} else {
if (StringUtils.isBlank(ips)) {
// delete all ips from the cluster
responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body("ips must not be empty.");
} else {
// delete specified ip list
String[] ipArray = addressServerManager.splitIps(ips);
String checkResult = AddressServerParamCheckUtil.checkIps(ipArray);
if (AddressServerParamCheckUtil.CHECK_OK.equals(checkResult)) {
List<Instance> instanceList = addressServerGeneratorManager.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray);
serviceManager.removeInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, false, instanceList.toArray(new Instance[instanceList.size()]));
} else {
responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(checkResult);
}
}
}
} catch (Exception e) {
responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getCause());
}
return responseEntity;
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address.controller;
import com.alibaba.nacos.address.component.AddressServerGeneratorManager;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.naming.core.Cluster;
import com.alibaba.nacos.naming.core.Service;
import com.alibaba.nacos.naming.core.ServiceManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* @author pbting
* @date 2019-06-18 5:04 PM
* @since 1.1.0
*/
@RestController
public class ServerListController {
@Autowired
private ServiceManager serviceManager;
@Autowired
private AddressServerGeneratorManager addressServerBuilderManager;
/**
* @param product will get Ip list of that products to be associated
* @param cluster will get Ip list of that product cluster to be associated
* @return
*/
@RequestMapping(value = "/{product}/{cluster}", method = RequestMethod.GET)
public ResponseEntity getCluster(@PathVariable String product,
@PathVariable String cluster) {
String productName = addressServerBuilderManager.generateProductName(product);
String serviceName = addressServerBuilderManager.generateNacosServiceName(productName);
Service service = serviceManager.getService(Constants.DEFAULT_NAMESPACE_ID, serviceName);
if (service == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + product + " not found.");
}
if (!service.getClusterMap().containsKey(cluster)) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + product + ",cluster=" + cluster + " not found.");
}
Cluster clusterObj = service.getClusterMap().get(cluster);
return ResponseEntity.status(HttpStatus.OK).body(addressServerBuilderManager.generateResponseIps(clusterObj.allIPs(false)));
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address.misc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author pbting
* @date 2019-07-04 4:34 PM
*/
public class Loggers {
public static final Logger addressLogger = LoggerFactory.getLogger("com.alibaba.nacos.address.main");
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Provides a unified tool class for address server parameter verification
*
* @author pbting
* @date 2019-06-19 11:19 AM
* @since 1.1.0
*/
public class AddressServerParamCheckUtil {
public static final String CHECK_OK = "ok";
public static final String ILLEGAL_IP_PREFIX = "illegal ip: ";
private static final String IP_REGEX = "(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3}";
private static final Pattern IP_PATTERN = Pattern.compile(IP_REGEX);
public static String checkIps(String... ips) {
if (ips == null || ips.length == 0) {
return CHECK_OK;
}
// illegal response
StringBuilder illegalResponse = new StringBuilder();
for (String ip : ips) {
Matcher matcher = IP_PATTERN.matcher(ip);
if (matcher.matches()) {
continue;
}
illegalResponse.append(ip + ",");
}
if (illegalResponse.length() == 0) {
return CHECK_OK;
}
return ILLEGAL_IP_PREFIX + illegalResponse.substring(0, illegalResponse.length() - 1);
}
}

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<included>
<springProperty scope="context" name="logPath" source="nacos.logs.path" defaultValue="${user.home}/nacos/logs"/>
<property name="LOG_HOME" value="${logPath}"/>
<appender name="nacos-address"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/nacos-address.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/nacos-address.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
<maxFileSize>2GB</maxFileSize>
<MaxHistory>15</MaxHistory>
<totalSizeCap>7GB</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<Pattern>%date %level %msg%n%n</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<logger name="com.alibaba.nacos.address.main" additivity="false">
<level value="INFO"/>
<appender-ref ref="nacos-address"/>
</logger>
</included>

View File

@ -0,0 +1,2 @@
server.port=8080
server.servlet.context-path=/

View File

@ -0,0 +1,193 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address;
import org.junit.Test;
import java.util.HashMap;
/**
* @author pbting
* @date 2019-06-18 2:37 PM
*/
public class AddressServerControllerTests {
private static final String PRODUCT_NACOS = "nacos";
private static final String PRODUCT_CONFIG = "config";
private static final String PRODUCT_NAMING = "naming";
private static final String DEFAULT_URL_CLUSTER = "serverlist";
private static final String GET_SERVERLIST_URL_FORMART = "http://127.0.0.1:8080/%s/%s";
//-----------------product=nacos,cluster=DEFAULT -------------------//
/**
* test the default product and cluster
*/
@Test
public void postCluster() {
String ips = "127.0.0.100,127.0.0.102,127.0.0.104";
HashMap<String, String> params = new HashMap<>();
params.put("ips", ips);
String response = SimpleHttpTestUtils.doPost("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
@Test
public void getCluster() {
String getUrl = String.format(GET_SERVERLIST_URL_FORMART, PRODUCT_NACOS, DEFAULT_URL_CLUSTER);
String response = SimpleHttpTestUtils.doGet(getUrl, new HashMap<>(), "UTF-8");
System.err.println(response);
}
@Test
public void deleteCluster() {
HashMap<String, String> deleteIp = new HashMap<>();
deleteIp.put("ips", "127.0.0.104");
String response = SimpleHttpTestUtils.doDelete("http://127.0.0.1:8080/nacos/v1/as/nodes", deleteIp, "UTF-8");
System.err.println(response);
}
@Test
public void deleteClusterWithSpecIp() {
HashMap<String, String> params = new HashMap<>();
params.put("ips", "127.0.0.103");
String response = SimpleHttpTestUtils.doDelete("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
@Test
public void putCluster() {
String ips = "127.0.0.114";
HashMap<String, String> params = new HashMap<>();
params.put("ips", ips);
String response = SimpleHttpTestUtils.doPut("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
//-----------------product=config,cluster=cluster01 -------------------//
/**
* test with product
*/
@Test
public void postClusterWithProduct() {
String ips = "127.0.0.101,127.0.0.102,127.0.0.103";
HashMap<String, String> params = new HashMap<>();
params.put("ips", ips);
params.put("product", PRODUCT_CONFIG);
String response = SimpleHttpTestUtils.doPost("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
@Test
public void getClusterWithProduct() {
HashMap<String, String> params = new HashMap<>();
String getUrl = String.format(GET_SERVERLIST_URL_FORMART, PRODUCT_CONFIG, DEFAULT_URL_CLUSTER);
String response = SimpleHttpTestUtils.doGet(getUrl, params, "UTF-8");
System.err.println(response);
}
@Test
public void deleteClusterWithProduct() {
HashMap<String, String> params = new HashMap<>();
params.put("product", PRODUCT_CONFIG);
String response = SimpleHttpTestUtils.doDelete("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
@Test
public void deleteClusterWithProductAndIp() {
HashMap<String, String> params = new HashMap<>();
params.put("product", PRODUCT_CONFIG);
params.put("ips", "127.0.0.196");
String response = SimpleHttpTestUtils.doDelete("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
@Test
public void putClusterWithProduct() {
String ips = "127.0.0.196";
HashMap<String, String> params = new HashMap<>();
params.put("ips", ips);
params.put("product", PRODUCT_CONFIG);
String response = SimpleHttpTestUtils.doPut("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
//-----------------product=naming,cluster=cluster01 -------------------//
/**
* test with product and cluster
*/
@Test
public void postClusterWithProductAndCluster() {
String ips = "127.0.0.100,127.0.0.200,127.0.0.31";
HashMap<String, String> params = new HashMap<>();
params.put("ips", ips);
params.put("product", PRODUCT_NAMING);
params.put("cluster", "cluster01");
String response = SimpleHttpTestUtils.doPost("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
@Test
public void getClusterWithProductAndCluster() {
HashMap<String, String> params = new HashMap<>();
String getUrl = String.format(GET_SERVERLIST_URL_FORMART, PRODUCT_NAMING, "cluster01");
String response = SimpleHttpTestUtils.doGet(getUrl, params, "UTF-8");
System.err.println(response);
}
@Test
public void deleteClusterWithProductAndCluster() {
HashMap<String, String> params = new HashMap<>();
params.put("product", PRODUCT_NAMING);
params.put("cluster", "cluster01");
String response = SimpleHttpTestUtils.doDelete("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
@Test
public void deleteClusterWithProductAndClusterAndIp() {
HashMap<String, String> params = new HashMap<>();
params.put("product", PRODUCT_NAMING);
params.put("cluster", "cluster01");
params.put("ips", "127.0.0.200");
String response = SimpleHttpTestUtils.doDelete("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
@Test
public void putClusterWithProductAndCluster() {
String ips = "127.0.0.171";
HashMap<String, String> params = new HashMap<>();
params.put("ips", ips);
params.put("product", PRODUCT_NAMING);
params.put("cluster", "cluster01");
String response = SimpleHttpTestUtils.doPut("http://127.0.0.1:8080/nacos/v1/as/nodes", params, "UTF-8");
System.err.println(response);
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address;
import com.alibaba.nacos.address.util.AddressServerParamCheckUtil;
import org.junit.Test;
/**
* @author pbting
* @date 2019-06-19 11:31 AM
*/
public class ParamCheckUtilTests {
@Test
public void checkIps() {
String[] ips = {"127.0.0.1"};
System.out.println(AddressServerParamCheckUtil.checkIps(ips));
String[] illlegalIps = {"127.100.19", "127.0.0.1"};
System.err.println(AddressServerParamCheckUtil.checkIps(illlegalIps));
}
}

View File

@ -0,0 +1,182 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
/**
* @author pbting
* @date 2019-06-18 2:40 PM
*/
public class SimpleHttpTestUtils {
private static final String REQUEST_METHOD_DELETE = "DELETE";
private static final String REQUEST_METHOD_PUT = "PUT";
private static final String REQUEST_METHOD_POST = "POST";
private static final String REQUEST_METHOD_GET = "GET";
/**
* 连接超时
*/
private static int CONNECT_TIME_OUT = 2000;
/**
* 读取数据超时
*/
private static int READ_TIME_OUT = 2000;
/**
* 请求编码
*/
public static String REQUEST_ENCODING = "UTF-8";
/**
* 接收编码
*/
public static String RESPONSE_ENCODING = "UTF-8";
public static final short OK = 200;
public static final short Bad_Request = 400;
public static final short Internal_Server_Error = 500;
public static final short PARAM_ERROR_NO_ANALYSESOR = 1000;
/**
* <pre>
* 发送带参数的GET的HTTP请求
* </pre>
*
* @param reqUrl HTTP请求URL
* @param paramMap 参数映射表
* @return HTTP响应的字符串
*/
public static String doGet(String reqUrl, Map<String, String> paramMap, String recvEncoding) {
return doRequest(reqUrl, paramMap, REQUEST_METHOD_GET, recvEncoding);
}
/**
* <pre>
* 发送带参数的POST的HTTP请求
* </pre>
*
* @param reqUrl HTTP请求URL
* @param paramMap 参数映射表
* @return HTTP响应的字符串
*/
public static String doPost(String reqUrl, Map<String, String> paramMap, String recvEncoding) {
return doRequest(reqUrl, paramMap, REQUEST_METHOD_POST, recvEncoding);
}
/**
* <pre>
* 发送带参数的 PUT HTTP 请求
* </pre>
*
* @param reqUrl HTTP请求URL
* @param paramMap 参数映射表
* @return HTTP响应的字符串
*/
public static String doPut(String reqUrl, Map<String, String> paramMap, String recvEncoding) {
return doRequest(reqUrl, paramMap, REQUEST_METHOD_PUT, recvEncoding);
}
/**
* <pre>
* 发送带参数的 DELETE HTTP 请求
* </pre>
*
* @param reqUrl HTTP请求URL
* @param paramMap 参数映射表
* @return HTTP响应的字符串
*/
public static String doDelete(String reqUrl, Map<String, String> paramMap, String recvEncoding) {
return doRequest(reqUrl, paramMap, REQUEST_METHOD_DELETE, recvEncoding);
}
private static String doRequest(String reqUrl, Map<String, String> paramMap, String reqMethod, String recvEncoding) {
return doExecute(reqUrl, paramMap, reqMethod, recvEncoding);
}
private static String doExecute(String reqUrl, Map<String, String> paramMap, String reqMethod, String recvEncoding) {
HttpURLConnection urlCon = null;
String responseContent = null;
try {
StringBuilder params = new StringBuilder();
if (paramMap != null) {
for (Map.Entry<String, String> element : paramMap.entrySet()) {
params.append(element.getKey());
params.append("=");
params.append(URLEncoder.encode(element.getValue(), REQUEST_ENCODING));
params.append("&");
}
if (params.length() > 0) {
params = params.deleteCharAt(params.length() - 1);
}
if (params.length() > 0 &&
(REQUEST_METHOD_GET.equals(reqMethod) || REQUEST_METHOD_DELETE.equals(reqMethod))) {
reqUrl = reqUrl + "?" + params.toString();
}
}
URL url = new URL(reqUrl);
urlCon = (HttpURLConnection) url.openConnection();
urlCon.setRequestMethod(reqMethod);
urlCon.setConnectTimeout(CONNECT_TIME_OUT);
urlCon.setReadTimeout(READ_TIME_OUT);
urlCon.setDoOutput(true);
if (REQUEST_METHOD_POST.equals(reqMethod) || REQUEST_METHOD_PUT.equals(reqMethod)) {
byte[] b = params.toString().getBytes();
urlCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
urlCon.setRequestProperty("Content-Length", String.valueOf(b.length));
urlCon.getOutputStream().write(b, 0, b.length);
urlCon.getOutputStream().flush();
urlCon.getOutputStream().close();
}
InputStream in = urlCon.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(in, recvEncoding));
String tempLine = rd.readLine();
StringBuffer tempStr = new StringBuffer();
while (tempLine != null) {
tempStr.append(tempLine);
tempLine = rd.readLine();
}
responseContent = tempStr.toString();
rd.close();
in.close();
urlCon.getResponseMessage();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlCon != null) {
urlCon.disconnect();
}
}
return responseContent;
}
}

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -57,6 +57,15 @@ public @interface NacosConfigurationProperties {
*/
String dataId();
/**
* set config type is yaml
* this method is deprecated, we support you use {@link #type()} to set config type
*
* @return default value <code>false</code>
*/
@Deprecated
boolean yaml() default false;
/**
* config style
*

View File

@ -52,7 +52,7 @@ public abstract class AbstractHealthChecker implements Cloneable {
/**
* used to JsonAdapter
*/
public void jsonAdapterCallback(SerializeWriter writer){
public void jsonAdapterCallback(SerializeWriter writer) {
// do nothing
}
@ -147,7 +147,7 @@ public abstract class AbstractHealthChecker implements Cloneable {
return false;
}
Http other = (Http)obj;
Http other = (Http) obj;
if (!strEquals(type, other.getType())) {
return false;
@ -259,7 +259,7 @@ public abstract class AbstractHealthChecker implements Cloneable {
return false;
}
Mysql other = (Mysql)obj;
Mysql other = (Mysql) obj;
if (!strEquals(user, other.getUser())) {
return false;

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -34,12 +34,10 @@ import com.alibaba.nacos.client.config.impl.EventDispatcher.ServerlistChangeEven
import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult;
import com.alibaba.nacos.client.config.utils.IOUtils;
import com.alibaba.nacos.client.identify.Constants;
import com.alibaba.nacos.client.utils.*;
import org.slf4j.Logger;
import org.slf4j.Logger;
/**
* Serverlist Manager
@ -275,13 +273,23 @@ public class ServerListManager {
LOGGER.warn("[update-serverlist] current serverlist from address server is empty!!!");
return;
}
List<String> newServerAddrList = new ArrayList<String>();
for (String server : newList) {
if (server.startsWith(HTTP) || server.startsWith(HTTPS)) {
newServerAddrList.add(server);
} else {
newServerAddrList.add(HTTP + server);
}
}
/**
* no change
*/
if (newList.equals(serverUrls)) {
if (newServerAddrList.equals(serverUrls)) {
return;
}
serverUrls = new ArrayList<String>(newList);
serverUrls = new ArrayList<String>(newServerAddrList);
iterator = iterator();
currentServerAddr = iterator.next();

View File

@ -238,7 +238,9 @@ public class NacosNamingService implements NamingService {
@Override
public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), instance.getIp(), instance.getPort());
if (instance.isEphemeral()) {
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), instance.getIp(), instance.getPort());
}
serverProxy.deregisterService(NamingUtils.getGroupedName(serviceName, groupName), instance);
}

View File

@ -64,6 +64,9 @@ public class BeatReactor {
public void removeBeatInfo(String serviceName, String ip, int port) {
NAMING_LOGGER.info("[BEAT] removing beat: {}:{}:{} from beat map.", serviceName, ip, port);
BeatInfo beatInfo = dom2Beat.remove(buildKey(serviceName, ip, port));
if (beatInfo == null) {
return;
}
beatInfo.setStopped(true);
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
}
@ -83,10 +86,10 @@ public class BeatReactor {
@Override
public void run() {
long result = serverProxy.sendBeat(beatInfo);
if (beatInfo.isStopped()) {
return;
}
long result = serverProxy.sendBeat(beatInfo);
long nextTime = result > 0 ? result : beatInfo.getPeriod();
executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
}

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -17,7 +17,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.config.server.service;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@ -30,6 +31,9 @@ import static com.alibaba.nacos.core.utils.SystemUtils.STANDALONE_MODE;
@Component
public class DynamicDataSource implements ApplicationContextAware {
@Autowired
private PropertyUtil propertyUtil;
private ApplicationContext applicationContext;
@Override
@ -44,7 +48,7 @@ public class DynamicDataSource implements ApplicationContextAware {
public DataSourceService getDataSource() {
DataSourceService dataSourceService = null;
if (STANDALONE_MODE && !PropertyUtil.isStandaloneUseMysql()) {
if (STANDALONE_MODE && !propertyUtil.isStandaloneUseMysql()) {
dataSourceService = (DataSourceService)applicationContext.getBean("localDataSourceService");
} else {
dataSourceService = (DataSourceService)applicationContext.getBean("basicDataSourceService");

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
</parent>
<artifactId>nacos-console</artifactId>
<!--<packaging>war</packaging>-->
@ -84,37 +84,8 @@
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>nacos-server</finalName>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<configuration>
<mainClass>com.alibaba.nacos.Nacos</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
@ -131,4 +102,52 @@
</resource>
</resources>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.4</version>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>release-nacos</id>
<build>
<finalName>nacos-server</finalName>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<configuration>
<mainClass>com.alibaba.nacos.Nacos</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -43,6 +43,7 @@ import ServiceList from './pages/ServiceManagement/ServiceList';
import ServiceDetail from './pages/ServiceManagement/ServiceDetail';
import SubscriberList from './pages/ServiceManagement/SubscriberList';
import ClusterNodeList from './pages/ClusterManagement/ClusterNodeList';
import Welcome from './pages/Welcome/Welcome';
import reducers from './reducers';
import { changeLanguage } from './reducers/locale';
@ -70,7 +71,8 @@ const store = createStore(
);
const MENU = [
{ path: '/', exact: true, render: () => <Redirect to="/configurationManagement" /> },
{ path: '/', exact: true, render: () => <Redirect to="/welcome" /> },
{ path: '/welcome', component: Welcome },
{ path: '/namespace', component: Namespace },
{ path: '/newconfig', component: Newconfig },
{ path: '/configsync', component: Configsync },

View File

@ -257,7 +257,7 @@ const I18N_CONF = {
importSucc: '导入成功',
importAbort: '导入终止',
importSuccBegin: '导入成功,导入了',
importSuccEnd: '项配',
importSuccEnd: '项配',
importFail: '导入失败',
importDataValidationError: '未读取到合法数据请检查导入的数据文件',
metadataIllegal: '导入的元数据文件非法',
@ -266,24 +266,24 @@ const I18N_CONF = {
skipImport: '跳过',
overwriteImport: '覆盖',
importRemind: '文件上传后将直接导入配置请务必谨慎操作',
samePreparation: '相同配',
samePreparation: '相同配',
targetNamespace: '目标空间',
conflictConfig: '检测到冲突的配置项',
failureEntries: '失败的条目',
unprocessedEntries: '未处理的条目',
skippedEntries: '跳过的条目',
exportSelected: '导出选中的配',
exportSelected: '导出选中的配',
clone: '克隆',
exportSelectedAlertTitle: '导出',
exportSelectedAlertContent: '请选择要导出的配',
exportSelectedAlertTitle: '导出',
exportSelectedAlertContent: '请选择要导出的配',
cloneSucc: '克隆成功',
cloneAbort: '克隆终止',
cloneSuccBegin: '克隆成功,克隆了',
cloneSuccEnd: '项配',
cloneSuccEnd: '项配',
cloneFail: '克隆失败',
getNamespaceFailed: '获取命名空间失败',
startCloning: '开始克隆',
cloningConfiguration: '克隆配',
cloningConfiguration: '克隆配',
source: '源空间',
configurationNumber: '配置数量',
target: '目标空间',

View File

@ -37,6 +37,7 @@ import {
Grid,
ConfigProvider,
} from '@alifd/next';
import { resolve } from 'url';
const { Row, Col } = Grid;
@ -95,7 +96,18 @@ class ConfigEditor extends React.Component {
dataId: getParams('dataId').trim(),
group,
},
() => this.getConfig()
() =>
this.getConfig(true).then(res => {
if (!res) {
this.getConfig();
return;
}
this.setState({
isBeta: true,
tabActiveKey: 'beta',
betaPublishSuccess: true,
});
})
);
} else {
if (group) {
@ -154,14 +166,15 @@ class ConfigEditor extends React.Component {
openDiff(cbName) {
this.diffcb = cbName;
let leftvalue = this.monacoEditor.getValue();
let rightvalue = this.codeVal;
let rightvalue = this.codeVal || '';
leftvalue = leftvalue.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n');
rightvalue = rightvalue.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n');
this.diffEditorDialog.current.getInstance().openDialog(leftvalue, rightvalue);
}
clickTab(tabActiveKey) {
this.setState({ tabActiveKey }, () => this.getConfig(tabActiveKey === 'bata'));
console.log('tabActiveKey', tabActiveKey, tabActiveKey === 'beta');
this.setState({ tabActiveKey }, () => this.getConfig(tabActiveKey === 'beta'));
}
getCodeVal() {
@ -191,11 +204,13 @@ class ConfigEditor extends React.Component {
if (validateContent.validate({ content, type })) {
return this._publishConfig();
} else {
Dialog.confirm({
content: locale.codeValErrorPrompt,
onOk: () => this._publishConfig(),
return new Promise((resolve, reject) => {
Dialog.confirm({
content: locale.codeValErrorPrompt,
onOk: () => resolve(this._publishConfig()),
onCancel: () => resolve(false),
});
});
return false;
}
}
@ -226,7 +241,7 @@ class ConfigEditor extends React.Component {
if (isNewConfig) {
this.setState({ isNewConfig: false });
}
this.getConfig();
this.getConfig(beta);
}
return res;
});
@ -235,13 +250,11 @@ class ConfigEditor extends React.Component {
publishBeta() {
return this._publishConfig(true).then(res => {
if (res) {
this.setState(
{
betaPublishSuccess: true,
tabActiveKey: 'beta',
},
() => this.getConfig(true)
);
this.setState({
betaPublishSuccess: true,
tabActiveKey: 'beta',
});
return res;
}
});
}
@ -308,27 +321,31 @@ class ConfigEditor extends React.Component {
);
}
getConfig(beta = false) {
getConfig(beta = false, decide = false) {
const namespace = getParams('namespace');
const { dataId, group } = this.state.form;
return request
.get('v1/cs/configs', {
params: {
dataId,
group,
beta,
show: 'all',
namespaceId: namespace,
tenant: namespace,
},
})
.then(res => {
const { type, content, configTags } = res;
this.changeForm({ ...res, config_tags: configTags ? configTags.split(',') : [] });
this.initMoacoEditor(type, content);
this.codeVal = content;
return res;
});
const params = {
dataId,
group,
namespaceId: namespace,
tenant: namespace,
};
if (beta) {
params.beta = true;
}
if (!beta) {
params.show = 'all';
}
return request.get('v1/cs/configs', { params }).then(res => {
const form = beta ? res.data : res;
if (!form) return false;
const { type, content, configTags, betaIps } = form;
this.setState({ betaIps });
this.changeForm({ ...form, config_tags: configTags ? configTags.split(',') : [] });
this.initMoacoEditor(type, content);
this.codeVal = content;
return res;
});
}
validation() {
@ -458,6 +475,7 @@ class ConfigEditor extends React.Component {
<Input.TextArea
aria-label="TextArea"
placeholder="127.0.0.1,127.0.0.2"
value={betaIps}
onChange={betaIps => this.setState({ betaIps })}
/>
)}
@ -465,9 +483,10 @@ class ConfigEditor extends React.Component {
)}
<Form.Item label={locale.format}>
<Radio.Group
defaultValue="text"
value={form.type}
onChange={type => {
this.initMoacoEditor(type, '');
this.initMoacoEditor(type, form.content);
this.changeForm({ type });
}}
>
@ -521,7 +540,7 @@ class ConfigEditor extends React.Component {
<Button
size="large"
type="primary"
disabled={!betaIps}
disabled={!betaIps || betaPublishSuccess}
onClick={() => this.openDiff('publishBeta')}
>
{locale.release}
@ -543,22 +562,27 @@ class ConfigEditor extends React.Component {
<DiffEditorDialog
ref={this.diffEditorDialog}
publishConfig={() => {
this[this.diffcb]();
let title = locale.toedit;
if (isNewConfig) {
title = locale.newConfigEditor;
}
if (this.diffcb === 'publishBeta') {
title = locale.betaPublish;
}
if (this.diffcb === 'publish' && tabActiveKey === 'beta') {
title = locale.stopPublishBeta;
this.stopBeta();
}
this.successDialog.current.getInstance().openDialog({
title: <div>{title}</div>,
isok: true,
...form,
const res = this[this.diffcb]();
res.then(res => {
if (!res) {
return;
}
let title = locale.toedit;
if (isNewConfig) {
title = locale.newConfigEditor;
}
if (this.diffcb === 'publishBeta') {
title = locale.betaPublish;
}
if (this.diffcb === 'publish' && tabActiveKey === 'beta') {
title = locale.stopPublishBeta;
this.stopBeta();
}
this.successDialog.current.getInstance().openDialog({
title: <div>{title}</div>,
isok: true,
...form,
});
});
}}
/>

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.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
@connect(state => ({ ...state.base }))
class Welcome extends React.Component {
static propTypes = {
functionMode: PropTypes.string,
};
render() {
const { functionMode } = this.props;
return (
<div>
{functionMode !== '' && (
<Redirect
to={`/${functionMode === 'naming' ? 'serviceManagement' : 'configurationManagement'}`}
/>
)}
</div>
);
}
}
export default Welcome;

View File

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

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -19,8 +19,6 @@ package com.alibaba.nacos.core.utils;
import com.alibaba.nacos.common.util.IoUtils;
import com.sun.management.OperatingSystemMXBean;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.lang.management.ManagementFactory;
@ -38,12 +36,10 @@ import static org.apache.commons.lang3.CharEncoding.UTF_8;
*/
public class SystemUtils {
private static final Logger logger = LoggerFactory.getLogger(SystemUtils.class);
/**
* Standalone mode or not
*/
public static final boolean STANDALONE_MODE = Boolean.getBoolean(STANDALONE_MODE_PROPERTY_NAME);
public static final boolean STANDALONE_MODE = Boolean.getBoolean(STANDALONE_MODE_PROPERTY_NAME);
public static final String STANDALONE_MODE_ALONE = "standalone";
public static final String STANDALONE_MODE_CLUSTER = "cluster";
@ -83,7 +79,7 @@ public class SystemUtils {
public static List<String> getIPsBySystemEnv(String key) {
String env = getSystemEnv(key);
List<String> ips = new ArrayList<String>();
List<String> ips = new ArrayList<>();
if (StringUtils.isNotEmpty(env)) {
ips = Arrays.asList(env.split(","));
}

View File

@ -51,15 +51,18 @@ if [ -z "$JAVA_HOME" ]; then
fi
fi
export SERVER="nacos-server"
export MODE="cluster"
export FUNCTION_MODE="all"
while getopts ":m:f:" opt
while getopts ":m:f:s:" opt
do
case $opt in
m)
MODE=$OPTARG;;
f)
FUNCTION_MODE=$OPTARG;;
s)
SERVER=$OPTARG;;
?)
echo "Unknown parameter"
exit 1;;
@ -102,7 +105,7 @@ else
fi
JAVA_OPT="${JAVA_OPT} -Dnacos.home=${BASE_DIR}"
JAVA_OPT="${JAVA_OPT} -Dloader.path=${BASE_DIR}/plugins/health -jar ${BASE_DIR}/target/nacos-server.jar"
JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/target/${SERVER}.jar"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
JAVA_OPT="${JAVA_OPT} --spring.config.location=${CUSTOM_SEARCH_LOCATIONS}"
JAVA_OPT="${JAVA_OPT} --logging.config=${BASE_DIR}/conf/nacos-logback.xml"
@ -115,14 +118,16 @@ fi
echo "$JAVA ${JAVA_OPT}"
if [[ "${MODE}" == "standalone" ]]; then
echo "nacos is starting"
$JAVA ${JAVA_OPT} nacos.nacos
echo "nacos is starting with standalone"
else
if [ ! -f "${BASE_DIR}/logs/start.out" ]; then
touch "${BASE_DIR}/logs/start.out"
fi
echo "$JAVA ${JAVA_OPT}" > ${BASE_DIR}/logs/start.out 2>&1 &
nohup $JAVA ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
echo "nacos is startingyou can check the ${BASE_DIR}/logs/start.out"
echo "nacos is starting with cluster"
fi
# check the start.out log output file
if [ ! -f "${BASE_DIR}/logs/start.out" ]; then
touch "${BASE_DIR}/logs/start.out"
fi
# start
echo "$JAVA ${JAVA_OPT}" > ${BASE_DIR}/logs/start.out 2>&1 &
nohup $JAVA ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
echo "nacos is startingyou can check the ${BASE_DIR}/logs/start.out"

View File

@ -24,7 +24,7 @@
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>%date %level %msg%n%n</Pattern>
<charset>UTF-8</charset>
<charset>UTF-8</charset>
</encoder>
</appender>
@ -496,6 +496,28 @@
</encoder>
</appender>
<appender name="nacos-address"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/nacos-address.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/nacos-address.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
<maxFileSize>2GB</maxFileSize>
<MaxHistory>15</MaxHistory>
<totalSizeCap>7GB</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<Pattern>%date %level %msg%n%n</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<logger name="com.alibaba.nacos.address.main" additivity="false">
<level value="INFO"/>
<appender-ref ref="nacos-address"/>
</logger>
<logger name="com.alibaba.nacos.cmdb.main" additivity="false">
<level value="INFO"/>
<appender-ref ref="cmdb-main"/>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -99,6 +99,32 @@
<finalName>ans</finalName>
</build>
</profile>
<profile>
<id>release-address</id>
<build>
<finalName>nacos-address</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptors>
<descriptor>release-address.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>install</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>release-client</id>
<dependencies>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<assembly>
<id>server</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>dir</format>
<format>tar.gz</format>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>../</directory>
<includes>
<include>README.md</include>
</includes>
</fileSet>
<fileSet>
<includes>
<include>conf/cluster.conf.example</include>
<include>conf/nacos-logback.xml</include>
</includes>
</fileSet>
<fileSet>
<includes>
<include>bin/*</include>
</includes>
<fileMode>0755</fileMode>
</fileSet>
</fileSets>
<files>
<file>
<source>LICENSE-BIN</source>
<destName>LICENSE</destName>
</file>
<file>
<source>NOTICE-BIN</source>
<destName>NOTICE</destName>
</file>
<file>
<!--打好的jar包名称和放置目录-->
<source>../address/target/nacos-address.jar</source>
<outputDirectory>/target/</outputDirectory>
</file>
</files>
</assembly>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -237,7 +237,7 @@ public class ServerListManager {
}
//local site servers
List<String> allLocalSiteSrvs = new ArrayList<String>();
List<String> allLocalSiteSrvs = new ArrayList<>();
for (Server server : servers) {
if (server.getKey().endsWith(":0")) {
@ -277,7 +277,7 @@ public class ServerListManager {
// for every change disable healthy check for some while
if (switchDomain.isHealthCheckEnabled()) {
Loggers.SRV_LOG.info("[NACOS-DISTRO] healthy server list changed, " +
"disable health check for {} ms from now on, old: {}, new: {}", STABLE_PERIOD,
"disable health check for {} ms from now on, old: {}, new: {}", STABLE_PERIOD,
healthyServers, newHealthyList);
switchDomain.setHealthCheckEnabled(false);
@ -351,38 +351,38 @@ public class ServerListManager {
@Override
public void run() {
try {
List<Server> refreshedServers = refreshServerList();
List<Server> oldServers = servers;
try {
List<Server> refreshedServers = refreshServerList();
List<Server> oldServers = servers;
if (CollectionUtils.isEmpty(refreshedServers)) {
Loggers.RAFT.warn("refresh server list failed, ignore it.");
return;
}
boolean changed = false;
List<Server> newServers = (List<Server>) CollectionUtils.subtract(refreshedServers, oldServers);
if (CollectionUtils.isNotEmpty(newServers)) {
servers.addAll(newServers);
changed = true;
Loggers.RAFT.info("server list is updated, new: {} servers: {}", newServers.size(), newServers);
}
List<Server> deadServers = (List<Server>) CollectionUtils.subtract(oldServers, refreshedServers);
if (CollectionUtils.isNotEmpty(deadServers)) {
servers.removeAll(deadServers);
changed = true;
Loggers.RAFT.info("server list is updated, dead: {}, servers: {}", deadServers.size(), deadServers);
}
if (changed) {
notifyListeners();
}
} catch (Exception e) {
Loggers.RAFT.info("error while updating server list.", e);
if (CollectionUtils.isEmpty(refreshedServers)) {
Loggers.RAFT.warn("refresh server list failed, ignore it.");
return;
}
boolean changed = false;
List<Server> newServers = (List<Server>) CollectionUtils.subtract(refreshedServers, oldServers);
if (CollectionUtils.isNotEmpty(newServers)) {
servers.addAll(newServers);
changed = true;
Loggers.RAFT.info("server list is updated, new: {} servers: {}", newServers.size(), newServers);
}
List<Server> deadServers = (List<Server>) CollectionUtils.subtract(oldServers, refreshedServers);
if (CollectionUtils.isNotEmpty(deadServers)) {
servers.removeAll(deadServers);
changed = true;
Loggers.RAFT.info("server list is updated, dead: {}, servers: {}", deadServers.size(), deadServers);
}
if (changed) {
notifyListeners();
}
} catch (Exception e) {
Loggers.RAFT.info("error while updating server list.", e);
}
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.naming.consistency.persistent.raft;
import org.springframework.context.ApplicationEvent;
/**
* @author pbting
* @date 2019-07-01 8:46 PM
*/
public abstract class BaseRaftEvent extends ApplicationEvent {
private RaftPeer raftPeer;
public BaseRaftEvent(Object source, RaftPeer raftPeer) {
super(source);
this.raftPeer = raftPeer;
}
public RaftPeer getRaftPeer() {
return raftPeer;
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.naming.consistency.persistent.raft;
/**
* @author pbting
* @date 2019-07-01 8:25 PM
*/
public class LeaderElectFinishedEvent extends BaseRaftEvent {
public LeaderElectFinishedEvent(Object source, RaftPeer raftPeer) {
super(source, raftPeer);
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.naming.consistency.persistent.raft;
/**
* @author pbting
* @date 2019-07-01 8:45 PM
*/
public class MakeLeaderEvent extends BaseRaftEvent {
public MakeLeaderEvent(Object source, RaftPeer raftPeer) {
super(source, raftPeer);
}
}

View File

@ -397,7 +397,7 @@ public class RaftCore {
local.voteFor = local.ip;
local.state = RaftPeer.State.CANDIDATE;
Map<String, String> params = new HashMap<String, String>(1);
Map<String, String> params = new HashMap<>(1);
params.put("vote", JSON.toJSONString(local));
for (final String server : peers.allServersWithoutMySelf()) {
final String url = buildURL(server, API_VOTE);
@ -605,14 +605,14 @@ public class RaftCore {
peers.makeLeader(remote);
Map<String, Integer> receivedKeysMap = new HashMap<String, Integer>(datums.size());
Map<String, Integer> receivedKeysMap = new HashMap<>(datums.size());
for (Map.Entry<String, Datum> entry : datums.entrySet()) {
receivedKeysMap.put(entry.getKey(), 0);
}
// now check datums
List<String> batch = new ArrayList<String>();
List<String> batch = new ArrayList<>();
if (!switchDomain.isSendBeatOnly()) {
int processedCount = 0;
Loggers.RAFT.info("[RAFT] received beat with {} keys, RaftCore.datums' size is {}, remote server: {}, term: {}, local term: {}",
@ -745,7 +745,7 @@ public class RaftCore {
}
List<String> deadKeys = new ArrayList<String>();
List<String> deadKeys = new ArrayList<>();
for (Map.Entry<String, Integer> entry : receivedKeysMap.entrySet()) {
if (entry.getValue() == 0) {
deadKeys.add(entry.getKey());
@ -901,7 +901,7 @@ public class RaftCore {
private ConcurrentHashMap<String, String> services = new ConcurrentHashMap<>(10 * 1024);
private BlockingQueue<Pair> tasks = new LinkedBlockingQueue<Pair>(1024 * 1024);
private BlockingQueue<Pair> tasks = new LinkedBlockingQueue<>(1024 * 1024);
public void addTask(String datumKey, ApplyAction action) {

View File

@ -29,7 +29,10 @@ import com.ning.http.client.Response;
import org.apache.commons.collections.SortedBag;
import org.apache.commons.collections.bag.TreeBag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
@ -45,16 +48,18 @@ import static com.alibaba.nacos.core.utils.SystemUtils.STANDALONE_MODE;
*/
@Component
@DependsOn("serverListManager")
public class RaftPeerSet implements ServerChangeListener {
public class RaftPeerSet implements ServerChangeListener, ApplicationContextAware {
@Autowired
private ServerListManager serverListManager;
private ApplicationContext applicationContext;
private AtomicLong localTerm = new AtomicLong(0L);
private RaftPeer leader = null;
private Map<String, RaftPeer> peers = new HashMap<String, RaftPeer>();
private Map<String, RaftPeer> peers = new HashMap<>();
private Set<String> sites = new HashSet<>();
@ -64,6 +69,12 @@ public class RaftPeerSet implements ServerChangeListener {
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@PostConstruct
public void init() {
serverListManager.listen(this);
@ -153,6 +164,7 @@ public class RaftPeerSet implements ServerChangeListener {
if (!Objects.equals(leader, peer)) {
leader = peer;
applicationContext.publishEvent(new LeaderElectFinishedEvent(this, leader));
Loggers.RAFT.info("{} has become the LEADER", leader.ip);
}
}
@ -163,12 +175,13 @@ public class RaftPeerSet implements ServerChangeListener {
public RaftPeer makeLeader(RaftPeer candidate) {
if (!Objects.equals(leader, candidate)) {
leader = candidate;
applicationContext.publishEvent(new MakeLeaderEvent(this, leader));
Loggers.RAFT.info("{} has become the LEADER, local: {}, leader: {}",
leader.ip, JSON.toJSONString(local()), JSON.toJSONString(leader));
}
for (final RaftPeer peer : peers.values()) {
Map<String, String> params = new HashMap<String, String>(1);
Map<String, String> params = new HashMap<>(1);
if (!Objects.equals(peer, candidate) && peer.state == RaftPeer.State.LEADER) {
try {
String url = RaftCore.buildURL(peer.ip, RaftCore.API_GET_PEER);

View File

@ -21,9 +21,9 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.common.util.IoUtils;
import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.consistency.RecordListener;
import com.alibaba.nacos.naming.consistency.Datum;
import com.alibaba.nacos.naming.consistency.KeyBuilder;
import com.alibaba.nacos.naming.consistency.RecordListener;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftConsistencyServiceImpl;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftCore;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer;
@ -57,7 +57,8 @@ import java.util.Map;
* @since 1.0.0
*/
@RestController
@RequestMapping(UtilsAndCommons.NACOS_NAMING_CONTEXT + "/raft")
@RequestMapping({UtilsAndCommons.NACOS_NAMING_CONTEXT + "/raft",
UtilsAndCommons.NACOS_SERVER_CONTEXT + UtilsAndCommons.NACOS_NAMING_CONTEXT + "/raft"})
public class RaftController {
@Autowired

View File

@ -109,6 +109,7 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
return;
}
checkTask = new HealthCheckTask(this);
HealthCheckReactor.scheduleCheck(checkTask);
inited = true;
}
@ -129,14 +130,16 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
/**
* Replace the service for the current cluster.
* <p>Deprecated because the service shouldn't be replaced.
* <p> the service shouldn't be replaced. so if the service is not empty will nothing to do.
* (the service fields can be changed, but the service A shouldn't be replaced to service B).
* If the service of a cluster is required to replace, actually, a new cluster is required.
*
* @param service the new service
*/
@Deprecated
public void setService(Service service) {
if (this.service != null) {
return;
}
this.service = service;
}
@ -299,7 +302,7 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
mapa.put(o.getIp() + ":" + o.getPort(), o);
}
List<Instance> result = new ArrayList<Instance>();
List<Instance> result = new ArrayList<>();
for (Instance o : a) {
if (!mapa.containsKey(o.getIp() + ":" + o.getPort())) {

View File

@ -78,7 +78,7 @@ public class Service extends com.alibaba.nacos.api.naming.pojo.Service implement
*/
private long pushCacheMillis = 0L;
private Map<String, Cluster> clusterMap = new HashMap<String, Cluster>();
private Map<String, Cluster> clusterMap = new HashMap<>();
public Service() {
}

View File

@ -234,10 +234,10 @@ public class ServiceManager implements RecordListener<Service> {
List<RaftPeer> matchList = new ArrayList<>(raftPeerSet.allPeers());
List<RaftPeer> tempList = new ArrayList<>();
if(StringUtils.isNotBlank(keyword)) {
for(RaftPeer raftPeer: matchList) {
if (StringUtils.isNotBlank(keyword)) {
for (RaftPeer raftPeer : matchList) {
String ip = raftPeer.ip.split(":")[0];
if(keyword.equals(ip)) {
if (keyword.equals(ip)) {
tempList.add(raftPeer);
}
}
@ -388,6 +388,10 @@ public class ServiceManager implements RecordListener<Service> {
}
public void createEmptyService(String namespaceId, String serviceName, boolean local) throws NacosException {
createServiceIfAbsent(namespaceId, serviceName, local, null);
}
public void createServiceIfAbsent(String namespaceId, String serviceName, boolean local, Cluster cluster) throws NacosException {
Service service = getService(namespaceId, serviceName);
if (service == null) {
@ -399,6 +403,10 @@ public class ServiceManager implements RecordListener<Service> {
// now validate the service. if failed, exception will be thrown
service.setLastModifiedMillis(System.currentTimeMillis());
service.recalculateChecksum();
if (cluster != null) {
cluster.setService(service);
service.getClusterMap().put(cluster.getName(), cluster);
}
service.validate();
if (local) {
putService(service);

View File

@ -33,8 +33,7 @@ public class HealthCheckStatus {
public AtomicInteger checkOKCount = new AtomicInteger(0);
public long checkRT = -1L;
private static ConcurrentMap<String, HealthCheckStatus> statusMap =
new ConcurrentHashMap<String, HealthCheckStatus>();
private static ConcurrentMap<String, HealthCheckStatus> statusMap = new ConcurrentHashMap<>();
public static void reset(Instance instance) {
statusMap.put(buildKey(instance), new HealthCheckStatus());
@ -61,8 +60,8 @@ public class HealthCheckStatus {
String serviceName = instance.getServiceName();
String datumKey = instance.getDatumKey();
return serviceName + ":"
+ clusterName + ":"
+ datumKey;
+ clusterName + ":"
+ datumKey;
} catch (Throwable e) {
Loggers.SRV_LOG.error("[BUILD-KEY] Exception while set rt, ip {}, error: {}", instance.toJSON(), e);
}

View File

@ -135,12 +135,10 @@ public class TcpSuperSenseProcessor implements HealthCheckProcessor, Runnable {
taskQueue.add(beat);
MetricsMonitor.getTcpHealthCheckMonitor().incrementAndGet();
}
// selector.wakeup();
}
private void processTask() throws Exception {
Collection<Callable<Void>> tasks = new LinkedList<Callable<Void>>();
Collection<Callable<Void>> tasks = new LinkedList<>();
do {
Beat beat = taskQueue.poll(CONNECT_TIMEOUT_MS / 2, TimeUnit.MILLISECONDS);
if (beat == null) {
@ -345,7 +343,6 @@ public class TcpSuperSenseProcessor implements HealthCheckProcessor, Runnable {
try {
beat.finishCheck(false, false, beat.getTask().getCheckRTNormalized() * 2, "tcp:timeout");
key.cancel();
key.channel().close();
} catch (Exception ignore) {
@ -357,7 +354,7 @@ public class TcpSuperSenseProcessor implements HealthCheckProcessor, Runnable {
private class TaskProcessor implements Callable<Void> {
private static final int MAX_WAIT_TIME_MILLISECONDS = 500;
Beat beat = null;
Beat beat;
public TaskProcessor(Beat beat) {
this.beat = beat;

View File

@ -28,11 +28,9 @@ import java.util.concurrent.TimeUnit;
@Component
public class SwitchDomain implements Record, Cloneable {
private String name = UtilsAndCommons.SWITCH_DOMAIN_NAME;
private List<String> masters;
private Map<String, Integer> adWeightMap = new HashMap<String, Integer>();
private Map<String, Integer> adWeightMap = new HashMap<>();
private long defaultPushCacheMillis = TimeUnit.SECONDS.toMillis(10);
@ -42,8 +40,6 @@ public class SwitchDomain implements Record, Cloneable {
private float distroThreshold = 0.7F;
private String token = UtilsAndCommons.SUPER_TOKEN;
private boolean healthCheckEnabled = true;
private boolean distroEnabled = true;

15
pom.xml
View File

@ -21,7 +21,7 @@
<inceptionYear>2018</inceptionYear>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<packaging>pom</packaging>
<name>Alibaba NACOS ${project.version}</name>
@ -428,6 +428,7 @@
<module>config</module>
<module>core</module>
<module>naming</module>
<module>address</module>
<module>test</module>
<module>api</module>
<module>client</module>
@ -732,17 +733,5 @@
</dependencies>
</dependencyManagement>
<distributionManagement>
<snapshotRepository>
<!-- 这里的ID一定要在maven setting文件中存在于server下的ID -->
<id>sona</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>sona</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
</project>

View File

@ -9,7 +9,7 @@ Nacos的编码规范遵从于《阿里巴巴JAVA开发规约》。
## Guidelines
[Alibaba-Java-Coding-Guidelines](https://alibaba.github.io/Alibaba-Java-Coding-Guidelines/)
[阿里巴巴JAVA开发规约](https://github.com/alibaba/p3c/blob/master/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C%EF%BC%88%E8%AF%A6%E5%B0%BD%E7%89%88%EF%BC%89.pdf)
[阿里巴巴JAVA开发规约](https://github.com/alibaba/p3c/blob/master/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C%EF%BC%88%E5%8D%8E%E5%B1%B1%E7%89%88%EF%BC%89.pdf)
## IDE Plugin Installnot necessary

View File

@ -17,7 +17,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -385,6 +385,7 @@ public class ConfigAPI_ITCase {
final AtomicInteger count = new AtomicInteger(0);
final String content = "test-abc";
boolean result = iconfig.publishConfig(dataId, group, content);
Thread.sleep(TIME_OUT);
Assert.assertTrue(result);
Listener ml = new AbstractListener() {

View File

@ -159,7 +159,7 @@ public class DeregisterInstance_ITCase {
verifyInstanceList(instances, 2, serviceName);
instances = naming.getAllInstances(serviceName);
Assert.assertEquals(instances.size(), 2);
Assert.assertEquals(2, instances.size());
naming.deregisterInstance(serviceName, "127.0.0.1", TEST_PORT, "c1");
@ -167,15 +167,15 @@ public class DeregisterInstance_ITCase {
instances = naming.getAllInstances(serviceName);
Assert.assertEquals(instances.size(), 1);
Assert.assertEquals(1, instances.size());
instances = naming.getAllInstances(serviceName, Arrays.asList("c2"));
Assert.assertEquals(instances.size(), 1);
Assert.assertEquals(1, instances.size());
naming.deregisterInstance(serviceName,"127.0.0.2", TEST_PORT, "c2");
TimeUnit.SECONDS.sleep(5);
instances = naming.getAllInstances(serviceName);
Assert.assertEquals(instances.size(), 0);
Assert.assertEquals(0, instances.size());
}
public void verifyInstanceList(List<Instance> instances, int size, String serviceName) throws Exception {

View File

@ -56,6 +56,8 @@ public class NamingBase {
public static final int TEST_PORT = 8080;
public static final int TIME_OUT = 3000;
public static String randomDomainName() {
StringBuilder sb = new StringBuilder();
sb.append("jinhan");

View File

@ -30,13 +30,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Collections;
import java.util.List;
@ -169,7 +165,7 @@ public class Subscribe_ITCase extends RestAPI_ITCase {
Assert.assertTrue(verifyInstanceList(instances, naming.getAllInstances(serviceName)));
}
@Test
@Test(timeout = 20*TIME_OUT)
public void subscribeEmpty() throws Exception {
String serviceName = randomDomainName();