From e64858606441b2be7ec44eff8a434c2b30b80c78 Mon Sep 17 00:00:00 2001 From: KomachiSion Date: Mon, 29 Aug 2022 14:31:49 +0800 Subject: [PATCH] Remove ServiceManager usage part3 and remove ServiceManager.java --- .../AddressServerGeneratorManager.java | 2 +- .../AddressServerClusterController.java | 106 ++- .../controller/ServerListController.java | 47 +- .../AddressServerGeneratorManagerTest.java | 2 +- .../AddressServerClusterControllerTest.java | 136 ++- .../controller/ServerListControllerTest.java | 90 +- .../nacos/naming/core/ServiceManager.java | 843 ------------------ .../nacos/naming/core/ClusterTest.java | 183 ---- 8 files changed, 209 insertions(+), 1200 deletions(-) delete mode 100644 naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java delete mode 100644 naming/src/test/java/com/alibaba/nacos/naming/core/ClusterTest.java diff --git a/address/src/main/java/com/alibaba/nacos/address/component/AddressServerGeneratorManager.java b/address/src/main/java/com/alibaba/nacos/address/component/AddressServerGeneratorManager.java index 7e7584e60..62761e770 100644 --- a/address/src/main/java/com/alibaba/nacos/address/component/AddressServerGeneratorManager.java +++ b/address/src/main/java/com/alibaba/nacos/address/component/AddressServerGeneratorManager.java @@ -99,7 +99,7 @@ public class AddressServerGeneratorManager { * @param instanceList a instance set will generate string response to client. * @return the result of response to client */ - public String generateResponseIps(List instanceList) { + public String generateResponseIps(List instanceList) { StringBuilder ips = new StringBuilder(); instanceList.forEach(instance -> { diff --git a/address/src/main/java/com/alibaba/nacos/address/controller/AddressServerClusterController.java b/address/src/main/java/com/alibaba/nacos/address/controller/AddressServerClusterController.java index 6ec2425d4..9cd136080 100644 --- a/address/src/main/java/com/alibaba/nacos/address/controller/AddressServerClusterController.java +++ b/address/src/main/java/com/alibaba/nacos/address/controller/AddressServerClusterController.java @@ -21,13 +21,19 @@ 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.healthcheck.AbstractHealthChecker; +import com.alibaba.nacos.api.naming.utils.NamingUtils; import com.alibaba.nacos.common.utils.InternetAddressUtil; -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 com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.naming.core.ClusterOperator; +import com.alibaba.nacos.naming.core.Instance; +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; @@ -36,6 +42,7 @@ 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. @@ -47,15 +54,22 @@ import java.util.List; @RequestMapping({AddressServerConstants.ADDRESS_SERVER_REQUEST_URL + "/nodes"}) public class AddressServerClusterController { - private final ServiceManager serviceManager; + private final InstanceOperator instanceOperator; + + private final NamingMetadataManager metadataManager; + + private final ClusterOperator clusterOperator; private final AddressServerManager addressServerManager; private final AddressServerGeneratorManager addressServerGeneratorManager; - public AddressServerClusterController(ServiceManager serviceManager, AddressServerManager addressServerManager, + public AddressServerClusterController(InstanceOperator instanceOperator, NamingMetadataManager metadataManager, + ClusterOperator clusterOperator, AddressServerManager addressServerManager, AddressServerGeneratorManager addressServerGeneratorManager) { - this.serviceManager = serviceManager; + this.instanceOperator = instanceOperator; + this.metadataManager = metadataManager; + this.clusterOperator = clusterOperator; this.addressServerManager = addressServerManager; this.addressServerGeneratorManager = addressServerGeneratorManager; } @@ -86,23 +100,13 @@ public class AddressServerClusterController { 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 = InternetAddressUtil.checkIPs(ipArray); - if (InternetAddressUtil.checkOK(checkResult)) { - List instanceList = addressServerGeneratorManager - .generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray); - for (Instance instance : instanceList) { - serviceManager.registerInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, instance); - } + Result result = registerCluster(serviceName, rawProductName, clusterName, ips); + if (InternetAddressUtil.checkOK(result.getCheckResult())) { responseEntity = ResponseEntity .ok("product=" + rawProductName + ",cluster=" + rawClusterName + "; put success with size=" - + instanceList.size()); + + result.getSize()); } else { - responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(checkResult); + responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result.getCheckResult()); } } catch (Exception e) { responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); @@ -111,6 +115,35 @@ public class AddressServerClusterController { 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 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. * @@ -134,9 +167,12 @@ public class AddressServerClusterController { try { String serviceName = addressServerGeneratorManager.generateNacosServiceName(productName); - Service service = serviceManager.getService(Constants.DEFAULT_NAMESPACE_ID, serviceName); + String serviceWithoutGroup = NamingUtils.getServiceName(serviceName); + String groupName = NamingUtils.getGroupName(serviceName); + Optional service = com.alibaba.nacos.naming.core.v2.ServiceManager + .getInstance().getSingletonIfExist(Constants.DEFAULT_NAMESPACE_ID, groupName, serviceWithoutGroup); - if (service == null) { + if (!service.isPresent()) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + rawProductName + " not found."); } if (StringUtils.isBlank(ips)) { @@ -149,8 +185,9 @@ public class AddressServerClusterController { if (InternetAddressUtil.checkOK(checkResult)) { List instanceList = addressServerGeneratorManager .generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray); - serviceManager.removeInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, false, - instanceList.toArray(new Instance[0])); + for (Instance each : instanceList) { + instanceOperator.removeInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, each); + } } else { responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(checkResult); } @@ -162,4 +199,23 @@ public class AddressServerClusterController { 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; + } + } } diff --git a/address/src/main/java/com/alibaba/nacos/address/controller/ServerListController.java b/address/src/main/java/com/alibaba/nacos/address/controller/ServerListController.java index 0fc03b0fd..21dd8bbb0 100644 --- a/address/src/main/java/com/alibaba/nacos/address/controller/ServerListController.java +++ b/address/src/main/java/com/alibaba/nacos/address/controller/ServerListController.java @@ -18,9 +18,15 @@ 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 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; @@ -28,6 +34,8 @@ 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. * @@ -37,14 +45,17 @@ import org.springframework.web.bind.annotation.RestController; @RestController public class ServerListController { - private final ServiceManager serviceManager; - private final AddressServerGeneratorManager addressServerBuilderManager; - public ServerListController(ServiceManager serviceManager, - AddressServerGeneratorManager addressServerBuilderManager) { - this.serviceManager = serviceManager; + 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; } /** @@ -59,20 +70,22 @@ public class ServerListController { String productName = addressServerBuilderManager.generateProductName(product); String serviceName = addressServerBuilderManager.generateNacosServiceName(productName); - Service service = serviceManager.getService(Constants.DEFAULT_NAMESPACE_ID, serviceName); - if (service == null) { - + String serviceWithoutGroup = NamingUtils.getServiceName(serviceName); + String groupName = NamingUtils.getGroupName(serviceName); + Optional service = ServiceManager.getInstance() + .getSingletonIfExist(Constants.DEFAULT_NAMESPACE_ID, groupName, serviceWithoutGroup); + if (!service.isPresent()) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + product + " not found."); } - - if (!service.getClusterMap().containsKey(cluster)) { - + 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."); } - - Cluster clusterObj = service.getClusterMap().get(cluster); + ServiceInfo serviceInfo = serviceStorage.getData(service.get()); + serviceInfo = ServiceUtil.selectInstances(serviceInfo, cluster, false); return ResponseEntity.status(HttpStatus.OK) - .body(addressServerBuilderManager.generateResponseIps(clusterObj.allIPs(false))); + .body(addressServerBuilderManager.generateResponseIps(serviceInfo.getHosts())); } } diff --git a/address/src/test/java/com/alibaba/nacos/address/component/AddressServerGeneratorManagerTest.java b/address/src/test/java/com/alibaba/nacos/address/component/AddressServerGeneratorManagerTest.java index 0f42249bf..de4bdc4a6 100644 --- a/address/src/test/java/com/alibaba/nacos/address/component/AddressServerGeneratorManagerTest.java +++ b/address/src/test/java/com/alibaba/nacos/address/component/AddressServerGeneratorManagerTest.java @@ -67,7 +67,7 @@ public class AddressServerGeneratorManagerTest { @Test public void testGenerateResponseIps() { - final List instanceList = new ArrayList<>(); + final List instanceList = new ArrayList<>(); Instance instance1 = new Instance(); instance1.setIp("192.168.3.1"); instance1.setPort(8848); diff --git a/address/src/test/java/com/alibaba/nacos/address/controller/AddressServerClusterControllerTest.java b/address/src/test/java/com/alibaba/nacos/address/controller/AddressServerClusterControllerTest.java index 366ef5008..aa7f8eddb 100644 --- a/address/src/test/java/com/alibaba/nacos/address/controller/AddressServerClusterControllerTest.java +++ b/address/src/test/java/com/alibaba/nacos/address/controller/AddressServerClusterControllerTest.java @@ -21,8 +21,12 @@ 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.Service; -import com.alibaba.nacos.naming.core.ServiceManager; +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; @@ -40,124 +44,94 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. public class AddressServerClusterControllerTest { @Mock - private ServiceManager serviceManager; + private InstanceOperator instanceOperator; + + @Mock + private NamingMetadataManager metadataManager; + + @Mock + private ClusterOperator clusterOperator; private MockMvc mockMvc; @Before public void before() { - mockMvc = MockMvcBuilders.standaloneSetup(new AddressServerClusterController(serviceManager, new AddressServerManager(), - new AddressServerGeneratorManager())).build(); + 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()); - + 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()); + 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(serviceManager) - .createServiceIfAbsent(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), Mockito.eq( - Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"), - Mockito.eq(false), Mockito.any()); - - mockMvc.perform(post("/nacos/v1/as/nodes") - .param("product", "default") - .param("cluster", "serverList") - .param("ips", "192.168.1")) - .andExpect(status().isInternalServerError()); + + 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 { - - Mockito.when(serviceManager.getService(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), - Mockito.eq(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"))) - .thenReturn(new Service(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default")); - - 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()); - + 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 { - - 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()); + 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 { - - Mockito.when(serviceManager.getService(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), - Mockito.eq(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"))) - .thenReturn(new Service(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default")); - - mockMvc.perform(delete("/nacos/v1/as/nodes") - .param("product", "default") - .param("cluster", "serverList") - .param("ips", "") - ).andExpect(status().isBadRequest()); + mockMvc.perform(delete("/nacos/v1/as/nodes").param("product", "default").param("cluster", "serverList") + .param("ips", "")).andExpect(status().isBadRequest()); } @Test public void testDeleteClusterErrorIps() throws Exception { - - Mockito.when(serviceManager.getService(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), - Mockito.eq(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"))) - .thenReturn(new Service(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default")); - - mockMvc.perform(delete("/nacos/v1/as/nodes") - .param("product", "default") - .param("cluster", "serverList") - .param("ips", "192.168.1") - ).andExpect(status().isBadRequest()); + 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.when(serviceManager.getService(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), - Mockito.eq(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"))) - .thenReturn(new Service(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default")); - - Mockito.doThrow(new NacosException(500, "remove service error")) - .when(serviceManager) - .removeInstance(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), - Mockito.eq(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"), - Mockito.eq(false), + 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()); + + 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()); } - + } diff --git a/address/src/test/java/com/alibaba/nacos/address/controller/ServerListControllerTest.java b/address/src/test/java/com/alibaba/nacos/address/controller/ServerListControllerTest.java index 43fbaa9fd..44c27b3db 100644 --- a/address/src/test/java/com/alibaba/nacos/address/controller/ServerListControllerTest.java +++ b/address/src/test/java/com/alibaba/nacos/address/controller/ServerListControllerTest.java @@ -17,25 +17,29 @@ package com.alibaba.nacos.address.controller; import com.alibaba.nacos.address.component.AddressServerGeneratorManager; -import com.alibaba.nacos.address.constant.AddressServerConstants; import com.alibaba.nacos.api.common.Constants; -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 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.Mockito; 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.HashMap; 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; @@ -43,68 +47,56 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. public class ServerListControllerTest { @Mock - private ServiceManager serviceManager; + private NamingMetadataManager metadataManager; + + @Mock + private ServiceStorage serviceStorage; + + private Service service; private MockMvc mockMvc; @Before public void before() { - this.mockMvc = MockMvcBuilders - .standaloneSetup(new ServerListController(serviceManager, new AddressServerGeneratorManager())) - .build(); + 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 = new Service( - Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"); - - Cluster cluster = new Cluster(); - cluster.setName("serverList"); - cluster.setService(service); - - final HashMap clusterMap = new HashMap<>(1); - clusterMap.put("serverList", cluster); - service.setClusterMap(clusterMap); + 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 list = new ArrayList<>(2); - list.add(new Instance("192.168.3.1", 8848)); - list.add(new Instance("192.168.3.2", 8848)); - cluster.updateIps(list, false); - - Mockito.when(serviceManager.getService(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), - Mockito.eq(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"))) - .thenReturn(service); - - mockMvc.perform(get("/nacos/serverList")) - .andExpect(status().isOk()); - + 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 { - - mockMvc.perform(get("/default/serverList")) - .andExpect(status().isNotFound()); + tearDown(); + mockMvc.perform(get("/default/serverList")).andExpect(status().isNotFound()); } @Test public void testGetClusterCannotFindCluster() throws Exception { - - final Service service = new Service( - Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"); - - final HashMap clusterMap = new HashMap<>(1); - service.setClusterMap(clusterMap); - - Mockito.when(serviceManager.getService(Mockito.eq(Constants.DEFAULT_NAMESPACE_ID), - Mockito.eq(Constants.DEFAULT_GROUP + AddressServerConstants.GROUP_SERVICE_NAME_SEP + "nacos.as.default"))) - .thenReturn(service); - - mockMvc.perform(get("/nacos/serverList")) - .andExpect(status().isNotFound()); + mockMvc.perform(get("/nacos/serverList")).andExpect(status().isNotFound()); } } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java b/naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java deleted file mode 100644 index 2f170eb25..000000000 --- a/naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java +++ /dev/null @@ -1,843 +0,0 @@ -/* - * Copyright 1999-2018 Alibaba Group Holding Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.nacos.naming.core; - -import com.alibaba.nacos.api.common.Constants; -import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.api.naming.utils.NamingUtils; -import com.alibaba.nacos.common.utils.CollectionUtils; -import com.alibaba.nacos.common.utils.InternetAddressUtil; -import com.alibaba.nacos.common.utils.JacksonUtils; -import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.core.cluster.ServerMemberManager; -import com.alibaba.nacos.naming.consistency.ConsistencyService; -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.misc.Loggers; -import com.alibaba.nacos.naming.misc.SwitchDomain; -import com.alibaba.nacos.naming.misc.UtilsAndCommons; -import com.alibaba.nacos.naming.push.UdpPushService; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.StringJoiner; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.stream.Collectors; - -import static com.alibaba.nacos.naming.misc.UtilsAndCommons.UPDATE_INSTANCE_METADATA_ACTION_REMOVE; -import static com.alibaba.nacos.naming.misc.UtilsAndCommons.UPDATE_INSTANCE_METADATA_ACTION_UPDATE; - -/** - * Core manager storing all services in Nacos. - * - * @author nkorange - */ -@Component -public class ServiceManager implements RecordListener { - - /** - * Map(namespace, Map(group::serviceName, Service)). - */ - private final Map> serviceMap = new ConcurrentHashMap<>(); - - @Resource(name = "consistencyDelegate") - private ConsistencyService consistencyService; - - private final SwitchDomain switchDomain; - - private final DistroMapper distroMapper; - - private final ServerMemberManager memberManager; - - private final UdpPushService pushService; - - public ServiceManager(SwitchDomain switchDomain, DistroMapper distroMapper, ServerMemberManager memberManager, - UdpPushService pushService) { - this.switchDomain = switchDomain; - this.distroMapper = distroMapper; - this.memberManager = memberManager; - this.pushService = pushService; - } - - /** - * Init service maneger. - */ - @PostConstruct - public void init() { - try { - Loggers.SRV_LOG.info("listen for service meta change"); - consistencyService.listen(KeyBuilder.SERVICE_META_KEY_PREFIX, this); - } catch (NacosException e) { - Loggers.SRV_LOG.error("listen for service meta change failed!"); - } - } - - public Map chooseServiceMap(String namespaceId) { - return serviceMap.get(namespaceId); - } - - @Override - public boolean interests(String key) { - return KeyBuilder.matchServiceMetaKey(key) && !KeyBuilder.matchSwitchKey(key); - } - - @Override - public boolean matchUnlistenKey(String key) { - return KeyBuilder.matchServiceMetaKey(key) && !KeyBuilder.matchSwitchKey(key); - } - - @Override - public void onChange(String key, Service service) throws Exception { - try { - if (service == null) { - Loggers.SRV_LOG.warn("received empty push from raft, key: {}", key); - return; - } - - if (StringUtils.isBlank(service.getNamespaceId())) { - service.setNamespaceId(Constants.DEFAULT_NAMESPACE_ID); - } - - Loggers.RAFT.info("[RAFT-NOTIFIER] datum is changed, key: {}, value: {}", key, service); - - Service oldDom = getService(service.getNamespaceId(), service.getName()); - - if (oldDom != null) { - oldDom.update(service); - // re-listen to handle the situation when the underlying listener is removed: - consistencyService - .listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), true), - oldDom); - consistencyService - .listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), false), - oldDom); - } else { - putServiceAndInit(service); - } - } catch (Throwable e) { - Loggers.SRV_LOG.error("[NACOS-SERVICE] error while processing service update", e); - } - } - - @Override - public void onDelete(String key) throws Exception { - String namespace = KeyBuilder.getNamespace(key); - String name = KeyBuilder.getServiceName(key); - Service service = chooseServiceMap(namespace).get(name); - Loggers.RAFT.info("[RAFT-NOTIFIER] datum is deleted, key: {}", key); - - if (service != null) { - cleanupService(namespace, name, service); - } - - chooseServiceMap(namespace).remove(name); - } - - public Set getAllServiceNames(String namespaceId) { - return serviceMap.get(namespaceId).keySet(); - } - - public Map> getAllServiceNames() { - - Map> namesMap = new HashMap<>(16); - for (String namespaceId : serviceMap.keySet()) { - namesMap.put(namespaceId, serviceMap.get(namespaceId).keySet()); - } - return namesMap; - } - - public Set getAllNamespaces() { - return serviceMap.keySet(); - } - - public List getAllServiceNameList(String namespaceId) { - if (chooseServiceMap(namespaceId) == null) { - return new ArrayList<>(); - } - return new ArrayList<>(chooseServiceMap(namespaceId).keySet()); - } - - public Map> getResponsibleServices() { - Map> result = new HashMap<>(16); - for (String namespaceId : serviceMap.keySet()) { - result.put(namespaceId, new HashSet<>()); - for (Map.Entry entry : serviceMap.get(namespaceId).entrySet()) { - Service service = entry.getValue(); - if (distroMapper.responsible(entry.getKey())) { - result.get(namespaceId).add(service); - } - } - } - return result; - } - - public int getResponsibleServiceCount() { - int serviceCount = 0; - for (String namespaceId : serviceMap.keySet()) { - for (Map.Entry entry : serviceMap.get(namespaceId).entrySet()) { - if (distroMapper.responsible(entry.getKey())) { - serviceCount++; - } - } - } - return serviceCount; - } - - public int getResponsibleInstanceCount() { - Map> responsibleServices = getResponsibleServices(); - int count = 0; - for (String namespaceId : responsibleServices.keySet()) { - for (Service service : responsibleServices.get(namespaceId)) { - count += service.allIPs().size(); - } - } - - return count; - } - - /** - * Fast remove service. - * - *

Remove service bu async. - * - * @param namespaceId namespace - * @param serviceName service name - * @throws NacosException exception - */ - public void easyRemoveService(String namespaceId, String serviceName) throws NacosException { - - Service service = getService(namespaceId, serviceName); - if (service == null) { - throw new NacosException(NacosException.INVALID_PARAM, - "specified service not exist, serviceName : " + serviceName); - } - - consistencyService.remove(KeyBuilder.buildServiceMetaKey(namespaceId, serviceName)); - } - - public void addOrReplaceService(Service service) throws NacosException { - consistencyService.put(KeyBuilder.buildServiceMetaKey(service.getNamespaceId(), service.getName()), service); - } - - public void createEmptyService(String namespaceId, String serviceName, boolean local) throws NacosException { - createServiceIfAbsent(namespaceId, serviceName, local, null); - } - - /** - * Create service if not exist. - * - * @param namespaceId namespace - * @param serviceName service name - * @param local whether create service by local - * @param cluster cluster - * @throws NacosException nacos exception - */ - public void createServiceIfAbsent(String namespaceId, String serviceName, boolean local, Cluster cluster) - throws NacosException { - Service service = getService(namespaceId, serviceName); - //return if service already exists - if (service != null) { - return; - } - - Loggers.SRV_LOG.info("creating empty service {}:{}", namespaceId, serviceName); - service = new Service(); - service.setName(serviceName); - service.setNamespaceId(namespaceId); - service.setGroupName(NamingUtils.getGroupName(serviceName)); - // 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(); - - putServiceAndInit(service); - if (!local) { - addOrReplaceService(service); - } - } - - /** - * Register an instance to a service in AP mode. - * - *

This method creates service or cluster silently if they don't exist. - * - * @param namespaceId id of namespace - * @param serviceName service name - * @param instance instance to register - * @throws Exception any error occurred in the process - */ - public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException { - - NamingUtils.checkInstanceIsLegal(instance); - - createEmptyService(namespaceId, serviceName, instance.isEphemeral()); - - Service service = getService(namespaceId, serviceName); - - checkServiceIsNull(service, namespaceId, serviceName); - - addInstance(namespaceId, serviceName, instance.isEphemeral(), instance); - } - - /** - * Update instance to service. - * - * @param namespaceId namespace - * @param serviceName service name - * @param instance instance - * @throws NacosException nacos exception - */ - public void updateInstance(String namespaceId, String serviceName, Instance instance) throws NacosException { - - Service service = getService(namespaceId, serviceName); - - checkServiceIsNull(service, namespaceId, serviceName); - - if (!service.allIPs().contains(instance)) { - throw new NacosException(NacosException.INVALID_PARAM, "instance not exist: " + instance); - } - - addInstance(namespaceId, serviceName, instance.isEphemeral(), instance); - } - - /** - * Update instance's metadata. - * - * @param namespaceId namespace - * @param serviceName service name - * @param action update or remove - * @param ips need update instances - * @param metadata target metadata - * @return update succeed instances - * @throws NacosException nacos exception - */ - public List updateMetadata(String namespaceId, String serviceName, boolean isEphemeral, String action, - boolean all, List ips, Map metadata) throws NacosException { - - Service service = getService(namespaceId, serviceName); - - checkServiceIsNull(service, namespaceId, serviceName); - - List locatedInstance = getLocatedInstance(namespaceId, serviceName, isEphemeral, all, ips); - - if (CollectionUtils.isEmpty(locatedInstance)) { - throw new NacosException(NacosException.INVALID_PARAM, "not locate instances, input instances: " + ips); - } - - if (UPDATE_INSTANCE_METADATA_ACTION_UPDATE.equals(action)) { - locatedInstance.forEach(ele -> ele.getMetadata().putAll(metadata)); - } else if (UPDATE_INSTANCE_METADATA_ACTION_REMOVE.equals(action)) { - Set removeKeys = metadata.keySet(); - for (String removeKey : removeKeys) { - locatedInstance.forEach(ele -> ele.getMetadata().remove(removeKey)); - } - } - Instance[] instances = new Instance[locatedInstance.size()]; - locatedInstance.toArray(instances); - - addInstance(namespaceId, serviceName, isEphemeral, instances); - - return locatedInstance; - } - - /** - * Check if the service is null. - * - * @param service service - * @param namespaceId namespace - * @param serviceName service name - * @throws NacosException nacos exception - */ - public void checkServiceIsNull(Service service, String namespaceId, String serviceName) throws NacosException { - if (service == null) { - throw new NacosException(NacosException.INVALID_PARAM, - "service not found, namespace: " + namespaceId + ", serviceName: " + serviceName); - } - } - - /** - * Locate consistency's datum by all or instances provided. - * - * @param namespaceId namespace - * @param serviceName serviceName - * @param isEphemeral isEphemeral - * @param all get from consistencyService directly - * @param waitLocateInstance instances provided - * @return located instances - * @throws NacosException nacos exception - */ - public List getLocatedInstance(String namespaceId, String serviceName, boolean isEphemeral, boolean all, - List waitLocateInstance) throws NacosException { - List locatedInstance; - - //need the newest data from consistencyService - Datum datum = consistencyService.get(KeyBuilder.buildInstanceListKey(namespaceId, serviceName, isEphemeral)); - if (datum == null) { - throw new NacosException(NacosException.NOT_FOUND, - "instances from consistencyService not exist, namespace: " + namespaceId + ", service: " - + serviceName + ", ephemeral: " + isEphemeral); - } - - if (all) { - locatedInstance = ((Instances) datum.value).getInstanceList(); - } else { - locatedInstance = new ArrayList<>(); - for (Instance instance : waitLocateInstance) { - Instance located = locateInstance(((Instances) datum.value).getInstanceList(), instance); - if (located == null) { - continue; - } - locatedInstance.add(located); - } - } - - return locatedInstance; - } - - private Instance locateInstance(List sources, Instance target) { - if (CollectionUtils.isEmpty(sources)) { - return null; - } - - for (Instance element : sources) { - //also need clusterName equals, the same instance maybe exist in two cluster. - if (Objects.equals(element, target) && Objects.equals(element.getClusterName(), target.getClusterName())) { - return element; - } - } - return null; - } - - /** - * Add instance to service. - * - * @param namespaceId namespace - * @param serviceName service name - * @param ephemeral whether instance is ephemeral - * @param ips instances - * @throws NacosException nacos exception - */ - public void addInstance(String namespaceId, String serviceName, boolean ephemeral, Instance... ips) - throws NacosException { - - String key = KeyBuilder.buildInstanceListKey(namespaceId, serviceName, ephemeral); - - Service service = getService(namespaceId, serviceName); - - synchronized (service) { - List instanceList = addIpAddresses(service, ephemeral, ips); - - Instances instances = new Instances(); - instances.setInstanceList(instanceList); - - consistencyService.put(key, instances); - } - } - - /** - * Remove instance from service. - * - * @param namespaceId namespace - * @param serviceName service name - * @param ephemeral whether instance is ephemeral - * @param ips instances - * @throws NacosException nacos exception - */ - public void removeInstance(String namespaceId, String serviceName, boolean ephemeral, Instance... ips) - throws NacosException { - Service service = getService(namespaceId, serviceName); - - synchronized (service) { - removeInstance(namespaceId, serviceName, ephemeral, service, ips); - } - } - - private void removeInstance(String namespaceId, String serviceName, boolean ephemeral, Service service, - Instance... ips) throws NacosException { - - String key = KeyBuilder.buildInstanceListKey(namespaceId, serviceName, ephemeral); - - List instanceList = substractIpAddresses(service, ephemeral, ips); - - Instances instances = new Instances(); - instances.setInstanceList(instanceList); - - consistencyService.put(key, instances); - } - - public Instance getInstance(String namespaceId, String serviceName, String cluster, String ip, int port) { - Service service = getService(namespaceId, serviceName); - if (service == null) { - return null; - } - - List clusters = new ArrayList<>(); - clusters.add(cluster); - - List ips = service.allIPs(clusters); - if (ips == null || ips.isEmpty()) { - return null; - } - - for (Instance instance : ips) { - if (instance.getIp().equals(ip) && instance.getPort() == port) { - return instance; - } - } - - return null; - } - - /** - * Compare and get new instance list. - * - * @param service service - * @param action {@link UtilsAndCommons#UPDATE_INSTANCE_ACTION_REMOVE} or {@link UtilsAndCommons#UPDATE_INSTANCE_ACTION_ADD} - * @param ephemeral whether instance is ephemeral - * @param ips instances - * @return instance list after operation - * @throws NacosException nacos exception - */ - public List updateIpAddresses(Service service, String action, boolean ephemeral, Instance... ips) - throws NacosException { - - Datum datum = consistencyService - .get(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), ephemeral)); - - List currentIPs = service.allIPs(ephemeral); - Map currentInstances = new HashMap<>(currentIPs.size()); - Set currentInstanceIds = CollectionUtils.set(); - - for (Instance instance : currentIPs) { - currentInstances.put(instance.toIpAddr(), instance); - currentInstanceIds.add(instance.getInstanceId()); - } - - Map instanceMap; - if (datum != null && null != datum.value) { - instanceMap = setValid(((Instances) datum.value).getInstanceList(), currentInstances); - } else { - instanceMap = new HashMap<>(ips.length); - } - - for (Instance instance : ips) { - if (!service.getClusterMap().containsKey(instance.getClusterName())) { - Cluster cluster = new Cluster(instance.getClusterName(), service); - cluster.init(); - service.getClusterMap().put(instance.getClusterName(), cluster); - Loggers.SRV_LOG - .warn("cluster: {} not found, ip: {}, will create new cluster with default configuration.", - instance.getClusterName(), instance.toJson()); - } - - if (UtilsAndCommons.UPDATE_INSTANCE_ACTION_REMOVE.equals(action)) { - instanceMap.remove(instance.getDatumKey()); - } else { - Instance oldInstance = instanceMap.get(instance.getDatumKey()); - if (oldInstance != null) { - instance.setInstanceId(oldInstance.getInstanceId()); - } else { - instance.setInstanceId(instance.generateInstanceId(currentInstanceIds)); - } - instanceMap.put(instance.getDatumKey(), instance); - } - - } - - if (instanceMap.size() <= 0 && UtilsAndCommons.UPDATE_INSTANCE_ACTION_ADD.equals(action)) { - throw new IllegalArgumentException( - "ip list can not be empty, service: " + service.getName() + ", ip list: " + JacksonUtils - .toJson(instanceMap.values())); - } - - return new ArrayList<>(instanceMap.values()); - } - - private List substractIpAddresses(Service service, boolean ephemeral, Instance... ips) - throws NacosException { - return updateIpAddresses(service, UtilsAndCommons.UPDATE_INSTANCE_ACTION_REMOVE, ephemeral, ips); - } - - private List addIpAddresses(Service service, boolean ephemeral, Instance... ips) throws NacosException { - return updateIpAddresses(service, UtilsAndCommons.UPDATE_INSTANCE_ACTION_ADD, ephemeral, ips); - } - - private Map setValid(List oldInstances, Map map) { - - Map instanceMap = new HashMap<>(oldInstances.size()); - for (Instance instance : oldInstances) { - Instance instance1 = map.get(instance.toIpAddr()); - if (instance1 != null) { - instance.setHealthy(instance1.isHealthy()); - instance.setLastBeat(instance1.getLastBeat()); - } - instanceMap.put(instance.getDatumKey(), instance); - } - return instanceMap; - } - - public Service getService(String namespaceId, String serviceName) { - Map service = this.serviceMap.get(namespaceId); - if (service == null) { - return null; - } - return service.get(serviceName); - } - - public boolean containService(String namespaceId, String serviceName) { - return getService(namespaceId, serviceName) != null; - } - - /** - * Put service into manager. - * - * @param service service - */ - public void putService(Service service) { - if (!serviceMap.containsKey(service.getNamespaceId())) { - serviceMap.putIfAbsent(service.getNamespaceId(), new ConcurrentSkipListMap<>()); - } - serviceMap.get(service.getNamespaceId()).putIfAbsent(service.getName(), service); - } - - private void putServiceAndInit(Service service) throws NacosException { - putService(service); - service = getService(service.getNamespaceId(), service.getName()); - service.init(); - consistencyService - .listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), true), service); - consistencyService - .listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), false), service); - Loggers.SRV_LOG.info("[NEW-SERVICE] {}", service.toJson()); - } - - /** - * Search services. - * - * @param namespaceId namespace - * @param regex search regex - * @return list of service which searched - */ - public List searchServices(String namespaceId, String regex) { - List result = new ArrayList<>(); - for (Map.Entry entry : chooseServiceMap(namespaceId).entrySet()) { - Service service = entry.getValue(); - String key = service.getName() + ":" + service.getOwners().toString(); - if (key.matches(regex)) { - result.add(service); - } - } - - return result; - } - - public int getServiceCount() { - int serviceCount = 0; - for (String namespaceId : serviceMap.keySet()) { - serviceCount += serviceMap.get(namespaceId).size(); - } - return serviceCount; - } - - public int getInstanceCount() { - int total = 0; - for (String namespaceId : serviceMap.keySet()) { - for (Service service : serviceMap.get(namespaceId).values()) { - total += service.allIPs().size(); - } - } - return total; - } - - public int getPagedService(String namespaceId, int startPage, int pageSize, String param, String containedInstance, - List serviceList, boolean hasIpCount) { - - List matchList; - - if (chooseServiceMap(namespaceId) == null) { - return 0; - } - - if (StringUtils.isNotBlank(param)) { - StringJoiner regex = new StringJoiner(Constants.SERVICE_INFO_SPLITER); - for (String s : param.split(Constants.SERVICE_INFO_SPLITER, Constants.SERVICE_INFO_SPLIT_COUNT)) { - regex.add(StringUtils.isBlank(s) ? Constants.ANY_PATTERN - : Constants.ANY_PATTERN + s + Constants.ANY_PATTERN); - } - matchList = searchServices(namespaceId, regex.toString()); - } else { - matchList = new ArrayList<>(chooseServiceMap(namespaceId).values()); - } - - if (!CollectionUtils.isEmpty(matchList) && hasIpCount) { - matchList = matchList.stream().filter(s -> !CollectionUtils.isEmpty(s.allIPs())) - .collect(Collectors.toList()); - } - - if (StringUtils.isNotBlank(containedInstance)) { - - boolean contained; - for (int i = 0; i < matchList.size(); i++) { - Service service = matchList.get(i); - contained = false; - List instances = service.allIPs(); - for (Instance instance : instances) { - if (InternetAddressUtil.containsPort(containedInstance)) { - if (StringUtils - .equals(instance.getIp() + InternetAddressUtil.IP_PORT_SPLITER + instance.getPort(), - containedInstance)) { - contained = true; - break; - } - } else { - if (StringUtils.equals(instance.getIp(), containedInstance)) { - contained = true; - break; - } - } - } - if (!contained) { - matchList.remove(i); - i--; - } - } - } - - if (pageSize >= matchList.size()) { - serviceList.addAll(matchList); - return matchList.size(); - } - - for (int i = 0; i < matchList.size(); i++) { - if (i < startPage * pageSize) { - continue; - } - - serviceList.add(matchList.get(i)); - - if (serviceList.size() >= pageSize) { - break; - } - } - - return matchList.size(); - } - - /** - * Shut down service manager v1.x. - * - * @throws NacosException nacos exception during shutdown - */ - public void shutdown() throws NacosException { - try { - long start = System.nanoTime(); - Loggers.SRV_LOG - .info("Start to destroy ALL services. namespaces: {}, services: {}", serviceMap.keySet().size(), - getServiceCount()); - for (Iterator>> iterator = serviceMap.entrySet().iterator(); - iterator.hasNext(); ) { - Map.Entry> entry = iterator.next(); - destroyAllService(entry.getKey(), entry.getValue()); - iterator.remove(); - } - Loggers.SRV_LOG.info(String.format("Successfully destroy ALL services. costs %.2fms", - ((float) (System.nanoTime() - start)) * 1e-6)); - } catch (Exception e) { - throw new NacosException(NacosException.SERVER_ERROR, "shutdown serviceManager failed", e); - } - } - - private void destroyAllService(String namespace, Map serviceMap) throws Exception { - for (Iterator> iterator = serviceMap.entrySet().iterator(); iterator.hasNext(); ) { - Map.Entry entry = iterator.next(); - Service service = entry.getValue(); - String name = service.getName(); - cleanupService(namespace, name, service); - iterator.remove(); - } - } - - private void cleanupService(String namespace, String name, Service service) throws Exception { - service.destroy(); - String ephemeralInstanceListKey = KeyBuilder.buildInstanceListKey(namespace, name, true); - String persistInstanceListKey = KeyBuilder.buildInstanceListKey(namespace, name, false); - String serviceMetaKey = KeyBuilder.buildServiceMetaKey(namespace, name); - consistencyService.remove(ephemeralInstanceListKey); - consistencyService.remove(persistInstanceListKey); - consistencyService.remove(serviceMetaKey); - - // remove listeners of key to avoid mem leak - consistencyService.unListen(ephemeralInstanceListKey, service); - consistencyService.unListen(persistInstanceListKey, service); - consistencyService.unListen(serviceMetaKey, service); - Loggers.SRV_LOG.info("[DEAD-SERVICE] {}", service.toJson()); - } - - private static class ServiceKey { - - private String namespaceId; - - private String serviceName; - - private String serverIP; - - private String checksum; - - public String getChecksum() { - return checksum; - } - - public String getServerIP() { - return serverIP; - } - - public String getServiceName() { - return serviceName; - } - - public String getNamespaceId() { - return namespaceId; - } - - public ServiceKey(String namespaceId, String serviceName, String serverIP, String checksum) { - this.namespaceId = namespaceId; - this.serviceName = serviceName; - this.serverIP = serverIP; - this.checksum = checksum; - } - - @Override - public String toString() { - return JacksonUtils.toJson(this); - } - } -} diff --git a/naming/src/test/java/com/alibaba/nacos/naming/core/ClusterTest.java b/naming/src/test/java/com/alibaba/nacos/naming/core/ClusterTest.java deleted file mode 100644 index c769c49fd..000000000 --- a/naming/src/test/java/com/alibaba/nacos/naming/core/ClusterTest.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 1999-2018 Alibaba Group Holding Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.nacos.naming.core; - -import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Http; -import com.alibaba.nacos.common.utils.JacksonUtils; -import com.alibaba.nacos.sys.env.EnvUtil; -import com.alibaba.nacos.sys.utils.ApplicationUtils; -import com.alibaba.nacos.naming.misc.SwitchDomain; -import com.alibaba.nacos.naming.misc.SwitchDomain.TcpHealthParams; - -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.context.ConfigurableApplicationContext; -import org.springframework.mock.env.MockEnvironment; - -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class ClusterTest { - - private Cluster cluster; - - @Mock - private ConfigurableApplicationContext context; - - @Mock - private SwitchDomain switchDomain; - - @Before - public void before() { - EnvUtil.setEnvironment(new MockEnvironment()); - ApplicationUtils.injectContext(context); - when(context.getBean(SwitchDomain.class)).thenReturn(switchDomain); - when(switchDomain.getTcpHealthParams()).thenReturn(new TcpHealthParams()); - Service service = new Service(); - service.setName("nacos.service.1"); - - cluster = new Cluster("nacos-cluster-1", service); - cluster.setDefCkport(80); - cluster.setDefIPPort(8080); - cluster.init(); - } - - @After - public void tearDown() { - cluster.destroy(); - } - - @Test - public void updateCluster() { - Service service = new Service(); - service.setName("nacos.service.2"); - - Cluster newCluster = new Cluster("nacos-cluster-1", service); - newCluster.setDefCkport(8888); - newCluster.setDefIPPort(9999); - Http healthCheckConfig = new Http(); - healthCheckConfig.setPath("/nacos-path-1"); - healthCheckConfig.setExpectedResponseCode(500); - healthCheckConfig.setHeaders("Client-Version:nacos-test-1"); - newCluster.setHealthChecker(healthCheckConfig); - - cluster.update(newCluster); - - assertEquals(8888, cluster.getDefCkport()); - assertEquals(9999, cluster.getDefIPPort()); - assertTrue(cluster.getHealthChecker() instanceof Http); - Http httpHealthCheck = (Http) (cluster.getHealthChecker()); - assertEquals("/nacos-path-1", httpHealthCheck.getPath()); - assertEquals(500, httpHealthCheck.getExpectedResponseCode()); - assertEquals("Client-Version:nacos-test-1", httpHealthCheck.getHeaders()); - } - - @Test - public void updateIps() { - - Instance instance1 = new Instance(); - instance1.setIp("1.1.1.1"); - instance1.setPort(1234); - - Instance instance2 = new Instance(); - instance2.setIp("1.1.1.1"); - instance2.setPort(2345); - - List list = new ArrayList<>(); - list.add(instance1); - list.add(instance2); - - cluster.updateIps(list, false); - - List ips = cluster.allIPs(); - assertNotNull(ips); - assertEquals(2, ips.size()); - assertEquals("1.1.1.1", ips.get(0).getIp()); - assertEquals(1234, ips.get(0).getPort()); - assertEquals("1.1.1.1", ips.get(1).getIp()); - assertEquals(2345, ips.get(1).getPort()); - } - - @Test - public void testValidate() { - Service service = new Service("nacos.service.2"); - cluster = new Cluster("nacos-cluster-1", service); - cluster.validate(); - } - - @Test(expected = IllegalArgumentException.class) - public void testValidateClusterNameNull() { - Service service = new Service("nacos.service.2"); - cluster = new Cluster(null, service); - cluster.validate(); - } - - @Test(expected = IllegalArgumentException.class) - public void testValidateServiceNull() { - cluster = new Cluster("nacos-cluster-1", null); - cluster.validate(); - } - - @Test - public void testSerialize() throws Exception { - String actual = JacksonUtils.toJson(cluster); - System.out.println(actual); - assertTrue(actual.contains("\"defaultPort\":80")); - assertTrue(actual.contains("\"defIPPort\":8080")); - assertTrue(actual.contains("\"healthChecker\":{\"type\":\"TCP\"}")); - assertTrue(actual.contains("\"metadata\":{}")); - assertTrue(actual.contains("\"defCkport\":80")); - assertTrue(actual.contains("\"name\":\"nacos-cluster-1\"")); - assertTrue(actual.contains("\"defaultCheckPort\":80")); - assertTrue(actual.contains("\"serviceName\":\"nacos.service.1\"")); - assertTrue(actual.contains("\"useIPPort4Check\":true")); - assertTrue(actual.contains("\"sitegroup\":\"\"")); - assertTrue(actual.contains("\"empty\":true")); - assertFalse(actual.contains("\"service\"")); - - } - - @Test - @SuppressWarnings("checkstyle:linelength") - public void testDeserialize() throws Exception { - String example = "{\"defCkport\":80,\"defIPPort\":8080,\"defaultCheckPort\":80,\"defaultPort\":80,\"empty\":true,\"healthChecker\":{\"type\":\"TCP\"},\"metadata\":{},\"name\":\"nacos-cluster-1\",\"serviceName\":\"nacos.service.1\",\"sitegroup\":\"\",\"useIPPort4Check\":true}"; - Cluster actual = JacksonUtils.toObj(example, Cluster.class); - assertEquals(80, actual.getDefCkport()); - assertEquals(8080, actual.getDefIPPort()); - assertEquals(80, actual.getDefaultCheckPort()); - assertEquals(80, actual.getDefaultPort()); - assertTrue(actual.isEmpty()); - assertTrue(actual.getMetadata().isEmpty()); - assertTrue(actual.isUseIPPort4Check()); - assertEquals("nacos-cluster-1", actual.getName()); - assertEquals("nacos.service.1", actual.getServiceName()); - assertEquals("", actual.getSitegroup()); - assertNull(actual.getHealthCheckTask()); - } -}