commit
3d65579094
123
address/pom.xml
Normal file
123
address/pom.xml
Normal 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>
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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";
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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)));
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
2
address/src/main/resources/application.properties
Normal file
2
address/src/main/resources/application.properties
Normal file
@ -0,0 +1,2 @@
|
||||
server.port=8080
|
||||
server.servlet.context-path=/
|
@ -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);
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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>
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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");
|
||||
|
@ -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>
|
||||
|
@ -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 },
|
||||
|
@ -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: '目标空间:',
|
||||
|
@ -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,
|
||||
});
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
@ -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;
|
@ -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;
|
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
@ -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>
|
||||
|
||||
|
@ -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(","));
|
||||
}
|
||||
|
@ -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 starting,you 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 starting,you can check the ${BASE_DIR}/logs/start.out"
|
||||
|
@ -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"/>
|
||||
|
@ -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>
|
||||
|
63
distribution/release-address.xml
Normal file
63
distribution/release-address.xml
Normal 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>
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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())) {
|
||||
|
@ -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() {
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
15
pom.xml
@ -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>
|
||||
|
||||
|
@ -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 Install(not necessary)
|
||||
|
@ -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>
|
||||
|
@ -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() {
|
||||
|
@ -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 {
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user