diff --git a/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/main/java/com/huawei/registry/interceptors/cloud3/x/ZookeeperInstanceSupplierInterceptor.java b/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/main/java/com/huawei/registry/interceptors/cloud3/x/ZookeeperInstanceSupplierInterceptor.java index d0dc54a696..3764b92c88 100644 --- a/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/main/java/com/huawei/registry/interceptors/cloud3/x/ZookeeperInstanceSupplierInterceptor.java +++ b/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/main/java/com/huawei/registry/interceptors/cloud3/x/ZookeeperInstanceSupplierInterceptor.java @@ -18,6 +18,7 @@ import com.huawei.registry.context.RegisterContext; import com.huawei.registry.support.InstanceInterceptorSupport; +import com.huawei.registry.utils.HostUtils; import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext; @@ -26,7 +27,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; /** @@ -56,7 +56,7 @@ private List getMergedInstances(ExecuteContext context) { // 全量服务实例 final Object allServiceInstances = context.getArguments()[0]; final List serviceInstances = filterDiscoveryServiceInstance( - (List) allServiceInstances); + (List) allServiceInstances); if (originServiceInstances instanceof List) { return convertAndMerge(serviceInstances, (List) originServiceInstances); } @@ -72,17 +72,23 @@ private List getMergedInstances(ExecuteContext context) { */ private List filterDiscoveryServiceInstance(List serviceInstances) { return serviceInstances.stream() - .filter(serviceInstance -> SERVICE_INSTANCE_CLASS_NAME.equals(serviceInstance.getClass().getName())) - .collect(Collectors.toList()); + .filter(serviceInstance -> SERVICE_INSTANCE_CLASS_NAME.equals(serviceInstance.getClass().getName())) + .collect(Collectors.toList()); } private List convertAndMerge(List microServiceInstances, - List originServiceInstances) { - List result = new ArrayList<>(microServiceInstances); + List originServiceInstances) { + List result = new ArrayList<>(); if (isOpenMigration() && RegisterContext.INSTANCE.isAvailable()) { result.addAll(originServiceInstances); } - return result.stream().distinct().filter(Objects::nonNull).collect(Collectors.toList()); + for (ServiceInstance microServiceInstance : microServiceInstances) { + result.removeIf(originServiceInstance -> + HostUtils.isSameInstance(originServiceInstance.getHost(), originServiceInstance.getPort(), + microServiceInstance.getHost(), microServiceInstance.getPort())); + result.add(microServiceInstance); + } + return result; } /** diff --git a/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/test/java/com/huawei/registry/interceptors/cloud3/x/ZookeeperInstanceSupplierInterceptorTest.java b/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/test/java/com/huawei/registry/interceptors/cloud3/x/ZookeeperInstanceSupplierInterceptorTest.java index 76c7e69939..7951d631fa 100644 --- a/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/test/java/com/huawei/registry/interceptors/cloud3/x/ZookeeperInstanceSupplierInterceptorTest.java +++ b/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/test/java/com/huawei/registry/interceptors/cloud3/x/ZookeeperInstanceSupplierInterceptorTest.java @@ -82,6 +82,16 @@ public void doAfter() throws NoSuchMethodException { Assert.assertTrue(result instanceof List); List instances = (List) result; assertEquals(instances.size(), (scInstances.size() + originInstances.size())); + + // 测试去重 + scInstances.clear(); + originInstances.clear(); + allInstances.clear(); + final ExecuteContext contextRepeat = interceptor.doAfter(buildContextRepeatedly()); + final Object resultRepeat = contextRepeat.getResult(); + Assert.assertTrue(resultRepeat instanceof List); + List instancesRepeat = (List) resultRepeat; + assertEquals(instancesRepeat.size(), (scInstances.size() + originInstances.size() - 1)); RegisterContext.INSTANCE.setAvailable(false); } @@ -102,6 +112,24 @@ private ExecuteContext buildContext() throws NoSuchMethodException { return context; } + private ExecuteContext buildContextRepeatedly() throws NoSuchMethodException { + scInstances.add(new DiscoveryServiceInstance(buildInstance(8001), serviceName)); + scInstances.add(new DiscoveryServiceInstance(buildInstance(8002), serviceName)); + scInstances.add(new DiscoveryServiceInstance(buildInstance(8003), serviceName)); + scInstances.add(new DiscoveryServiceInstance(buildInstance(8004), serviceName)); + scInstances.add(new DiscoveryServiceInstance(buildInstance(8005), serviceName)); + originInstances.add(new ZookeeperServiceInstance(serviceName, buildZkInstance(8005))); + originInstances.add(new ZookeeperServiceInstance(serviceName, buildZkInstance(8006))); + originInstances.add(new ZookeeperServiceInstance(serviceName, buildZkInstance(8007))); + originInstances.add(new ZookeeperServiceInstance(serviceName, buildZkInstance(8008))); + allInstances.addAll(originInstances); + allInstances.addAll(scInstances); + final ExecuteContext context = ExecuteContext.forMemberMethod(this, String.class.getDeclaredMethod("trim"), + new Object[]{allInstances}, null, null); + context.changeResult(originInstances); + return context; + } + /** * 构建实例 * @@ -111,9 +139,10 @@ private ExecuteContext buildContext() throws NoSuchMethodException { public org.apache.curator.x.discovery.ServiceInstance buildZkInstance(int port) { final org.apache.curator.x.discovery.ServiceInstance serviceInstance = Mockito .mock(org.apache.curator.x.discovery.ServiceInstance.class); + Mockito.when(serviceInstance.getSslPort()).thenReturn(port); Mockito.when(serviceInstance.getPort()).thenReturn(port); - Mockito.when(serviceInstance.getAddress()).thenReturn("localhost"); - Mockito.when(serviceInstance.buildUriSpec()).thenReturn("http://localhost:" + port); + Mockito.when(serviceInstance.getAddress()).thenReturn("127.0.0.1"); + Mockito.when(serviceInstance.buildUriSpec()).thenReturn("http://127.0.0.1:" + port); return serviceInstance; }