----初始化项目

This commit is contained in:
2025-09-19 20:49:14 +08:00
parent b345d2828d
commit df7765c400
2867 changed files with 359313 additions and 89 deletions

102
address/pom.xml Normal file
View File

@ -0,0 +1,102 @@
<?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>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos-address</artifactId>
<packaging>jar</packaging>
<name>nacos-address ${project.version}</name>
<url>https://nacos.io</url>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-naming</artifactId>
<exclusions>
<exclusion>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-cmdb</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<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>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>release-address</id>
<build>
<finalName>nacos-address</finalName>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.alibaba.nacos.address.AddressServer</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,35 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.address;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* support address server.
*
* @author nacos
* @since 1.1.0
*/
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
public class AddressServer {
public static void main(String[] args) {
SpringApplication.run(AddressServer.class, args);
}
}

View File

@ -0,0 +1,127 @@
/*
* 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.component;
import com.alibaba.nacos.address.constant.AddressServerConstants;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.common.utils.InternetAddressUtil;
import com.alibaba.nacos.common.utils.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 {
/**
* Generate product name.
*
* @param name name
* @return product
*/
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 service name
* @param clusterName cluster name
* @param ipArray array of ips
* @return instance list
*/
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.parseInt(ipAndPort[1]));
instance.setClusterName(clusterName);
instance.setServiceName(serviceName);
instance.setEphemeral(false);
instance.getMetadata().put("app", rawProductName);
instance.getMetadata().put("tenant", Constants.DEFAULT_NAMESPACE_ID);
instanceList.add(instance);
}
return instanceList;
}
private String[] generateIpAndPort(String ip) {
String[] result = InternetAddressUtil.splitIPPortStr(ip);
if (result.length != InternetAddressUtil.SPLIT_IP_PORT_RESULT_LENGTH) {
return new String[] {result[0], String.valueOf(AddressServerConstants.DEFAULT_SERVER_PORT)};
}
return result;
}
/**
* Generate response ips.
*
* @param instanceList an instance set will generate string response to client.
* @return the result of response to client
*/
public String generateResponseIps(List<com.alibaba.nacos.api.naming.pojo.Instance> instanceList) {
StringBuilder ips = new StringBuilder();
instanceList.forEach(instance -> {
ips.append(instance.getIp()).append(':').append(instance.getPort());
ips.append('\n');
});
return ips.toString();
}
/**
* Generate nacos service name.
*
* @param rawServiceName the raw service name will not contain the {@link Constants#DEFAULT_GROUP}.
* @return the nacos service name
*/
public String generateNacosServiceName(String rawServiceName) {
if (rawServiceName.contains(Constants.DEFAULT_GROUP)) {
return rawServiceName;
}
return Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + rawServiceName;
}
}

View File

@ -0,0 +1,80 @@
/*
* 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.component;
import com.alibaba.nacos.address.constant.AddressServerConstants;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.common.utils.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)) {
return AddressServerConstants.DEFAULT_PRODUCT;
}
return name;
}
/**
* If the name is empty then return the default {@link UtilsAndCommons#DEFAULT_CLUSTER_NAME}, or return the source
* name by input.
*
* @param name name
* @return default cluster name
*/
public String getDefaultClusterNameIfEmpty(String name) {
if (StringUtils.isEmpty(name)) {
return AddressServerConstants.DEFAULT_GET_CLUSTER;
}
return name;
}
public String getRawClusterName(String name) {
return getDefaultClusterNameIfEmpty(name);
}
/**
* Split ips.
*
* @param ips multi ip will separator by the ','
* @return array of ip
*/
public String[] splitIps(String ips) {
if (StringUtils.isBlank(ips)) {
return new String[0];
}
return ips.split(AddressServerConstants.MULTI_IPS_SEPARATOR);
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 1999-2022 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.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
/**
* nacos web security configuration.
*
* @author onewe
*/
@Configuration
public class AddressServerSecurityConfiguration {
@Bean
@Order(99)
public SecurityFilterChain addressServerSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(
requestMatcherRegistry -> requestMatcherRegistry.mvcMatchers("/nacos/v1/as/**").authenticated()).csrf()
.disable().httpBasic();
return http.build();
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.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 for service name between raw service name and group.
*/
String GROUP_SERVICE_NAME_SEP = "@@";
/**
* when post ips is not given the cluster,then use the default.
*/
String DEFAULT_GET_CLUSTER = "serverlist";
/**
* post multi ip will use the "," to separator.
*/
String MULTI_IPS_SEPARATOR = ",";
/**
* the default product name when deploy nacos with naming and config.
*/
String ALIWARE_NACOS_DEFAULT_PRODUCT_NAME = "nacos.as.default";
/**
* when the config and naming will separate deploy,then must specify product name by the client.
*/
String ALIWARE_NACOS_PRODUCT_DOM_TEMPLATE = "nacos.as.%s";
/**
* the url for address server prefix.
*/
String ADDRESS_SERVER_REQUEST_URL =
UtilsAndCommons.NACOS_SERVER_CONTEXT + UtilsAndCommons.NACOS_SERVER_VERSION + "/as";
}

View File

@ -0,0 +1,221 @@
/*
* 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.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.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;
import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.common.utils.InternetAddressUtil;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.naming.core.ClusterOperator;
import com.alibaba.nacos.naming.core.InstanceOperator;
import com.alibaba.nacos.naming.core.v2.ServiceManager;
import com.alibaba.nacos.naming.core.v2.metadata.ClusterMetadata;
import com.alibaba.nacos.naming.core.v2.metadata.NamingMetadataManager;
import com.alibaba.nacos.naming.core.v2.metadata.ServiceMetadata;
import com.alibaba.nacos.naming.core.v2.pojo.Service;
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;
import java.util.Optional;
/**
* Address server cluster controller.
*
* @author pbting
* @since 1.1.0
*/
@RestController
@RequestMapping({AddressServerConstants.ADDRESS_SERVER_REQUEST_URL + "/nodes"})
public class AddressServerClusterController {
private final InstanceOperator instanceOperator;
private final NamingMetadataManager metadataManager;
private final ClusterOperator clusterOperator;
private final AddressServerManager addressServerManager;
private final AddressServerGeneratorManager addressServerGeneratorManager;
public AddressServerClusterController(InstanceOperator instanceOperator, NamingMetadataManager metadataManager,
ClusterOperator clusterOperator, AddressServerManager addressServerManager,
AddressServerGeneratorManager addressServerGeneratorManager) {
this.instanceOperator = instanceOperator;
this.metadataManager = metadataManager;
this.clusterOperator = clusterOperator;
this.addressServerManager = addressServerManager;
this.addressServerGeneratorManager = addressServerGeneratorManager;
}
/**
* Create new cluster.
*
* @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 result of create new cluster
*/
@RequestMapping(value = "", method = RequestMethod.POST)
public ResponseEntity<String> 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.ADDRESS_LOGGER.info("put cluster node,the cluster name is " + cluster + "; the product name=" + product
+ "; the ip list=" + ips);
ResponseEntity<String> responseEntity;
try {
String serviceName = addressServerGeneratorManager.generateNacosServiceName(productName);
Result result = registerCluster(serviceName, rawProductName, clusterName, ips);
if (InternetAddressUtil.checkOK(result.getCheckResult())) {
responseEntity = ResponseEntity
.ok("product=" + rawProductName + ",cluster=" + rawClusterName + "; put success with size="
+ result.getSize());
} else {
responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result.getCheckResult());
}
} catch (Exception e) {
responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
return responseEntity;
}
private Result registerCluster(String serviceName, String productName, String clusterName, String ips)
throws NacosException {
String serviceWithoutGroup = NamingUtils.getServiceName(serviceName);
String groupName = NamingUtils.getGroupName(serviceName);
Service service = Service.newService(Constants.DEFAULT_NAMESPACE_ID, groupName, serviceWithoutGroup, false);
service = ServiceManager.getInstance().getSingleton(service);
if (service.isEphemeral()) {
return new Result(
String.format("Service %s is ephemeral service, can't use as address server", serviceName), 0);
}
ServiceMetadata serviceMetadata = metadataManager.getServiceMetadata(service).orElse(new ServiceMetadata());
if (!serviceMetadata.getClusters().containsKey(clusterName)) {
ClusterMetadata metadata = new ClusterMetadata();
metadata.setHealthyCheckType(AbstractHealthChecker.None.TYPE);
metadata.setHealthChecker(new AbstractHealthChecker.None());
clusterOperator.updateClusterMetadata(Constants.DEFAULT_NAMESPACE_ID, serviceName, clusterName, metadata);
}
String[] ipArray = addressServerManager.splitIps(ips);
String checkResult = InternetAddressUtil.checkIPs(ipArray);
if (InternetAddressUtil.checkOK(checkResult)) {
List<Instance> instanceList = addressServerGeneratorManager
.generateInstancesByIps(serviceName, productName, clusterName, ipArray);
for (Instance instance : instanceList) {
instanceOperator.registerInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, instance);
}
}
return new Result(checkResult, ipArray.length);
}
/**
* Delete cluster.
*
* @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 delete result (the cluster information is return if success, exception information is return if fail)
*/
@RequestMapping(value = "", method = RequestMethod.DELETE)
public ResponseEntity<String> 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);
String serviceWithoutGroup = NamingUtils.getServiceName(serviceName);
String groupName = NamingUtils.getGroupName(serviceName);
Optional<com.alibaba.nacos.naming.core.v2.pojo.Service> service = com.alibaba.nacos.naming.core.v2.ServiceManager
.getInstance().getSingletonIfExist(Constants.DEFAULT_NAMESPACE_ID, groupName, serviceWithoutGroup);
if (!service.isPresent()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + rawProductName + " not found.");
}
if (StringUtils.isBlank(ips)) {
// delete all ips from the cluster
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("ips must not be empty.");
}
// delete specified ip list
String[] ipArray = addressServerManager.splitIps(ips);
String checkResult = InternetAddressUtil.checkIPs(ipArray);
if (InternetAddressUtil.checkOK(checkResult)) {
List<Instance> instanceList = addressServerGeneratorManager
.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray);
for (Instance each : instanceList) {
instanceOperator.removeInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, each);
}
} else {
responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(checkResult);
}
} catch (Exception e) {
responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getCause());
}
return responseEntity;
}
private class Result {
private final String checkResult;
private final int size;
public Result(String checkResult, int size) {
this.checkResult = checkResult;
this.size = size;
}
public String getCheckResult() {
return checkResult;
}
public int getSize() {
return size;
}
}
}

View File

@ -0,0 +1,91 @@
/*
* 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.controller;
import com.alibaba.nacos.address.component.AddressServerGeneratorManager;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.naming.core.v2.ServiceManager;
import com.alibaba.nacos.naming.core.v2.index.ServiceStorage;
import com.alibaba.nacos.naming.core.v2.metadata.ClusterMetadata;
import com.alibaba.nacos.naming.core.v2.metadata.NamingMetadataManager;
import com.alibaba.nacos.naming.core.v2.metadata.ServiceMetadata;
import com.alibaba.nacos.naming.core.v2.pojo.Service;
import com.alibaba.nacos.naming.utils.ServiceUtil;
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;
import java.util.Optional;
/**
* Server list controller.
*
* @author pbting
* @since 1.1.0
*/
@RestController
public class ServerListController {
private final AddressServerGeneratorManager addressServerBuilderManager;
private final NamingMetadataManager metadataManager;
private final ServiceStorage serviceStorage;
public ServerListController(AddressServerGeneratorManager addressServerBuilderManager,
NamingMetadataManager metadataManager, ServiceStorage serviceStorage) {
this.addressServerBuilderManager = addressServerBuilderManager;
this.metadataManager = metadataManager;
this.serviceStorage = serviceStorage;
}
/**
* Get cluster.
*
* @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 result of get
*/
@RequestMapping(value = "/{product}/{cluster}", method = RequestMethod.GET)
public ResponseEntity<String> getCluster(@PathVariable String product, @PathVariable String cluster) {
String productName = addressServerBuilderManager.generateProductName(product);
String serviceName = addressServerBuilderManager.generateNacosServiceName(productName);
String serviceWithoutGroup = NamingUtils.getServiceName(serviceName);
String groupName = NamingUtils.getGroupName(serviceName);
Optional<Service> service = ServiceManager.getInstance()
.getSingletonIfExist(Constants.DEFAULT_NAMESPACE_ID, groupName, serviceWithoutGroup);
if (!service.isPresent()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + product + " not found.");
}
ClusterMetadata metadata = metadataManager.getServiceMetadata(service.get()).orElse(new ServiceMetadata())
.getClusters().get(cluster);
if (null == metadata) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body("product=" + product + ",cluster=" + cluster + " not found.");
}
ServiceInfo serviceInfo = serviceStorage.getData(service.get());
serviceInfo = ServiceUtil.selectInstances(serviceInfo, cluster, false);
return ResponseEntity.status(HttpStatus.OK)
.body(addressServerBuilderManager.generateResponseIps(serviceInfo.getHosts()));
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.misc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Loggers holder.
*
* @author pbting
* @date 2019-07-04 4:34 PM
*/
public class Loggers {
public static final Logger ADDRESS_LOGGER = LoggerFactory.getLogger("com.alibaba.nacos.address.main");
}

View File

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

View File

@ -0,0 +1,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.
#

View File

@ -0,0 +1,17 @@
#
# 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.
#
server.port=8080
server.servlet.context-path=/

View File

@ -0,0 +1,110 @@
/*
* 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.component;
import com.alibaba.nacos.address.constant.AddressServerConstants;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class AddressServerGeneratorManagerTest {
@Test
public void testGenerateProductName() {
AddressServerGeneratorManager manager = new AddressServerGeneratorManager();
final String blankName = manager.generateProductName("");
Assert.assertEquals(AddressServerConstants.ALIWARE_NACOS_DEFAULT_PRODUCT_NAME, blankName);
final String defaultName = manager.generateProductName(AddressServerConstants.DEFAULT_PRODUCT);
Assert.assertEquals(AddressServerConstants.ALIWARE_NACOS_DEFAULT_PRODUCT_NAME, defaultName);
final String testName = manager.generateProductName("test");
Assert.assertEquals("nacos.as.test", testName);
}
@Test
public void testGenerateInstancesByIps() {
AddressServerGeneratorManager manager = new AddressServerGeneratorManager();
final List<Instance> empty = manager.generateInstancesByIps(null, null, null, null);
Assert.assertNotNull(empty);
Assert.assertTrue(empty.isEmpty());
String[] ipArray = new String[]{"192.168.3.1:8848", "192.168.3.2:8848", "192.168.3.3:8848"};
final List<Instance> instanceList = manager.generateInstancesByIps("DEFAULT_GROUP@@nacos.as.test", "test", "test",
ipArray);
Assert.assertNotNull(instanceList);
Assert.assertFalse(instanceList.isEmpty());
Assert.assertEquals(3, instanceList.size());
final Instance instance1 = instanceList.get(0);
Assert.assertEquals("192.168.3.1", instance1.getIp());
final Instance instance2 = instanceList.get(1);
Assert.assertEquals("192.168.3.2", instance2.getIp());
final Instance instance3 = instanceList.get(2);
Assert.assertEquals("192.168.3.3", instance3.getIp());
}
@Test
public void testGenerateResponseIps() {
final List<com.alibaba.nacos.api.naming.pojo.Instance> instanceList = new ArrayList<>();
Instance instance1 = new Instance();
instance1.setIp("192.168.3.1");
instance1.setPort(8848);
Instance instance2 = new Instance();
instance2.setIp("192.168.3.2");
instance2.setPort(8848);
Instance instance3 = new Instance();
instance3.setIp("192.168.3.3");
instance3.setPort(8848);
instanceList.add(instance1);
instanceList.add(instance2);
instanceList.add(instance3);
AddressServerGeneratorManager manager = new AddressServerGeneratorManager();
final String ipListStr = manager.generateResponseIps(instanceList);
StringBuilder expectStr = new StringBuilder();
final StringBuilder ret = expectStr
.append("192.168.3.1:8848").append('\n')
.append("192.168.3.2:8848").append('\n')
.append("192.168.3.3:8848").append('\n');
Assert.assertEquals(ret.toString(), ipListStr);
}
@Test
public void testGenerateNacosServiceName() {
AddressServerGeneratorManager manager = new AddressServerGeneratorManager();
final String containDefault = manager.generateNacosServiceName("DEFAULT_GROUP@@test");
Assert.assertEquals("DEFAULT_GROUP@@test", containDefault);
final String product = manager.generateNacosServiceName("product");
Assert.assertEquals("DEFAULT_GROUP@@product", product);
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.component;
import com.alibaba.nacos.address.constant.AddressServerConstants;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class AddressServerManagerTests {
private static final AddressServerManager ADDRESS_SERVER_MANAGER = new AddressServerManager();
@Test
public void getRawProductName() {
assertEquals(AddressServerConstants.DEFAULT_PRODUCT, ADDRESS_SERVER_MANAGER.getRawProductName(""));
assertEquals(AddressServerConstants.DEFAULT_PRODUCT,
ADDRESS_SERVER_MANAGER.getRawProductName(AddressServerConstants.DEFAULT_PRODUCT));
assertEquals("otherProduct", ADDRESS_SERVER_MANAGER.getRawProductName("otherProduct"));
}
@Test
public void getDefaultClusterNameIfEmpty() {
assertEquals(AddressServerConstants.DEFAULT_GET_CLUSTER, ADDRESS_SERVER_MANAGER.getDefaultClusterNameIfEmpty(""));
assertEquals(AddressServerConstants.DEFAULT_GET_CLUSTER,
ADDRESS_SERVER_MANAGER.getDefaultClusterNameIfEmpty(AddressServerConstants.DEFAULT_GET_CLUSTER));
assertEquals("otherServerList", ADDRESS_SERVER_MANAGER.getDefaultClusterNameIfEmpty("otherServerList"));
}
@Test
public void testGetRawClusterName() {
assertEquals("serverList", ADDRESS_SERVER_MANAGER.getRawClusterName("serverList"));
assertEquals(AddressServerConstants.DEFAULT_GET_CLUSTER, ADDRESS_SERVER_MANAGER.getRawClusterName(""));
}
@Test
public void testSplitIps() {
final String[] emptyArr = ADDRESS_SERVER_MANAGER.splitIps("");
assertEquals(0, emptyArr.length);
final String[] one = ADDRESS_SERVER_MANAGER.splitIps("192.168.1.12:8848");
assertEquals(1, one.length);
assertEquals("192.168.1.12:8848", one[0]);
final String[] two = ADDRESS_SERVER_MANAGER.splitIps("192.168.1.12:8848,192.268.3.33:8848");
assertEquals(2, two.length);
assertEquals("192.168.1.12:8848", two[0]);
assertEquals("192.268.3.33:8848", two[1]);
}
}

View File

@ -0,0 +1,137 @@
/*
* 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.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.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.naming.core.ClusterOperator;
import com.alibaba.nacos.naming.core.InstanceOperator;
import com.alibaba.nacos.naming.core.v2.ServiceManager;
import com.alibaba.nacos.naming.core.v2.metadata.NamingMetadataManager;
import com.alibaba.nacos.naming.core.v2.pojo.Service;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(MockitoJUnitRunner.class)
public class AddressServerClusterControllerTest {
@Mock
private InstanceOperator instanceOperator;
@Mock
private NamingMetadataManager metadataManager;
@Mock
private ClusterOperator clusterOperator;
private MockMvc mockMvc;
@Before
public void before() {
mockMvc = MockMvcBuilders.standaloneSetup(
new AddressServerClusterController(instanceOperator, metadataManager, clusterOperator,
new AddressServerManager(), new AddressServerGeneratorManager())).build();
Service service = Service
.newService(Constants.DEFAULT_NAMESPACE_ID, Constants.DEFAULT_GROUP, "nacos.as.default", false);
ServiceManager.getInstance().getSingleton(service);
}
@After
public void tearDown() {
Service service = Service
.newService(Constants.DEFAULT_NAMESPACE_ID, Constants.DEFAULT_GROUP, "nacos.as.default", false);
ServiceManager.getInstance().removeSingleton(service);
}
@Test
public void testPostCluster() throws Exception {
mockMvc.perform(post("/nacos/v1/as/nodes").param("product", "default").param("cluster", "serverList")
.param("ips", "192.168.3.1,192.168.3.2")).andExpect(status().isOk());
}
@Test
public void testPostClusterWithErrorIps() throws Exception {
mockMvc.perform(post("/nacos/v1/as/nodes").param("product", "default").param("cluster", "serverList")
.param("ips", "192.168.1")).andExpect(status().isBadRequest());
}
@Test
public void testPostClusterThrowException() throws Exception {
Mockito.doThrow(new NacosException(500, "create service error")).when(clusterOperator)
.updateClusterMetadata(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), Mockito.eq(
Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"),
Mockito.eq("serverList"), Mockito.any());
mockMvc.perform(post("/nacos/v1/as/nodes").param("product", "default").param("cluster", "serverList")
.param("ips", "192.168.1")).andExpect(status().isInternalServerError());
}
@Test
public void testDeleteCluster() throws Exception {
mockMvc.perform(delete("/nacos/v1/as/nodes").param("product", "default").param("cluster", "serverList")
.param("ips", "192.168.3.1,192.168.3.2")).andExpect(status().isOk());
}
@Test
public void testDeleteClusterCannotFindService() throws Exception {
tearDown();
mockMvc.perform(delete("/nacos/v1/as/nodes").param("product", "default").param("cluster", "serverList")
.param("ips", "192.168.3.1,192.168.3.2")).andExpect(status().isNotFound());
}
@Test
public void testDeleteClusterEmptyIps() throws Exception {
mockMvc.perform(delete("/nacos/v1/as/nodes").param("product", "default").param("cluster", "serverList")
.param("ips", "")).andExpect(status().isBadRequest());
}
@Test
public void testDeleteClusterErrorIps() throws Exception {
mockMvc.perform(delete("/nacos/v1/as/nodes").param("product", "default").param("cluster", "serverList")
.param("ips", "192.168.1")).andExpect(status().isBadRequest());
}
@Test
public void testDeleteClusterThrowException() throws Exception {
Mockito.doThrow(new NacosException(500, "remove service error")).when(instanceOperator)
.removeInstance(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), Mockito.eq(
Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"),
Mockito.any());
mockMvc.perform(delete("/nacos/v1/as/nodes").param("product", "default").param("cluster", "serverList")
.param("ips", "192.168.3.1,192.168.3.2")).andExpect(status().isInternalServerError());
}
}

View File

@ -0,0 +1,102 @@
/*
* 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.controller;
import com.alibaba.nacos.address.component.AddressServerGeneratorManager;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.naming.core.v2.ServiceManager;
import com.alibaba.nacos.naming.core.v2.index.ServiceStorage;
import com.alibaba.nacos.naming.core.v2.metadata.ClusterMetadata;
import com.alibaba.nacos.naming.core.v2.metadata.NamingMetadataManager;
import com.alibaba.nacos.naming.core.v2.metadata.ServiceMetadata;
import com.alibaba.nacos.naming.core.v2.pojo.Service;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(MockitoJUnitRunner.class)
public class ServerListControllerTest {
@Mock
private NamingMetadataManager metadataManager;
@Mock
private ServiceStorage serviceStorage;
private Service service;
private MockMvc mockMvc;
@Before
public void before() {
this.mockMvc = MockMvcBuilders.standaloneSetup(
new ServerListController(new AddressServerGeneratorManager(), metadataManager, serviceStorage)).build();
service = Service
.newService(Constants.DEFAULT_NAMESPACE_ID, Constants.DEFAULT_GROUP, "nacos.as.default", false);
ServiceManager.getInstance().getSingleton(service);
}
@After
public void tearDown() {
ServiceManager.getInstance().removeSingleton(service);
}
@Test
public void testGetCluster() throws Exception {
final Service service = Service
.newService(Constants.DEFAULT_NAMESPACE_ID, Constants.DEFAULT_GROUP, "nacos.as.default", false);
ServiceMetadata serviceMetadata = new ServiceMetadata();
serviceMetadata.getClusters().put("serverList", new ClusterMetadata());
when(metadataManager.getServiceMetadata(service)).thenReturn(Optional.of(serviceMetadata));
List<Instance> list = new ArrayList<>(2);
list.add(new Instance());
list.add(new Instance());
ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.setHosts(list);
when(serviceStorage.getData(service)).thenReturn(serviceInfo);
mockMvc.perform(get("/nacos/serverList")).andExpect(status().isOk());
}
@Test
public void testGetClusterCannotFindService() throws Exception {
tearDown();
mockMvc.perform(get("/default/serverList")).andExpect(status().isNotFound());
}
@Test
public void testGetClusterCannotFindCluster() throws Exception {
mockMvc.perform(get("/nacos/serverList")).andExpect(status().isNotFound());
}
}