From 9afdd430bb33f8f9a82e39639190a9a4664aa0ae Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Mon, 22 Mar 2021 09:53:50 +0800 Subject: [PATCH 01/18] add ut for package c.a.nacos.client.naming.beat (#5156) --- .../alibaba/nacos/client/BeatReactorTest.java | 68 ---- .../client/naming/beat/BeatInfoTest.java | 89 +++++ .../client/naming/beat/BeatReactorTest.java | 313 ++++++++++++++++++ 3 files changed, 402 insertions(+), 68 deletions(-) delete mode 100644 client/src/test/java/com/alibaba/nacos/client/BeatReactorTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/beat/BeatInfoTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/beat/BeatReactorTest.java diff --git a/client/src/test/java/com/alibaba/nacos/client/BeatReactorTest.java b/client/src/test/java/com/alibaba/nacos/client/BeatReactorTest.java deleted file mode 100644 index 9da690595..000000000 --- a/client/src/test/java/com/alibaba/nacos/client/BeatReactorTest.java +++ /dev/null @@ -1,68 +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.client; - -import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.client.naming.beat.BeatInfo; -import com.alibaba.nacos.client.naming.beat.BeatReactor; -import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.concurrent.ScheduledThreadPoolExecutor; - -@RunWith(MockitoJUnitRunner.class) -public class BeatReactorTest { - - @Mock - private NamingHttpClientProxy namingHttpClientProxy; - - @Test - public void test() throws NoSuchFieldException, IllegalAccessException, InterruptedException, NacosException { - BeatInfo beatInfo = new BeatInfo(); - beatInfo.setServiceName("test"); - beatInfo.setIp("11.11.11.11"); - beatInfo.setPort(1234); - beatInfo.setCluster("clusterName"); - beatInfo.setWeight(1); - beatInfo.setMetadata(new HashMap()); - beatInfo.setScheduled(false); - beatInfo.setPeriod(1000L); - - BeatReactor beatReactor = new BeatReactor(namingHttpClientProxy); - beatReactor.addBeatInfo("testService", beatInfo); - - Assert.assertEquals(1, getActiveThread(beatReactor)); - Thread.sleep(1100L); - beatReactor.removeBeatInfo("testService", beatInfo.getIp(), beatInfo.getPort()); - Thread.sleep(3100L); - Assert.assertEquals(0, getActiveThread(beatReactor)); - } - - private int getActiveThread(BeatReactor beatReactor) throws NoSuchFieldException, IllegalAccessException { - Field field = BeatReactor.class.getDeclaredField("executorService"); - field.setAccessible(true); - ScheduledThreadPoolExecutor scheduledExecutorService = (ScheduledThreadPoolExecutor) field.get(beatReactor); - return scheduledExecutorService.getQueue().size(); - } - -} diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/beat/BeatInfoTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/beat/BeatInfoTest.java new file mode 100644 index 000000000..923a76ab9 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/beat/BeatInfoTest.java @@ -0,0 +1,89 @@ +/* + * + * 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.client.naming.beat; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class BeatInfoTest { + + @Test + public void testGetterAndSetter() { + BeatInfo info = new BeatInfo(); + + String ip = "1.1.1.1"; + info.setIp(ip); + int port = 10000; + info.setPort(port); + + double weight = 1.0; + info.setWeight(weight); + String serviceName = "serviceName"; + info.setServiceName(serviceName); + String cluster = "cluster1"; + info.setCluster(cluster); + Map meta = new HashMap<>(); + meta.put("a", "b"); + info.setMetadata(meta); + long period = 100; + info.setPeriod(period); + info.setScheduled(true); + info.setStopped(true); + + Assert.assertEquals(ip, info.getIp()); + Assert.assertEquals(port, info.getPort()); + Assert.assertEquals(weight, info.getWeight(), 0.1); + Assert.assertEquals(serviceName, info.getServiceName()); + Assert.assertEquals(meta, info.getMetadata()); + Assert.assertEquals(period, info.getPeriod()); + Assert.assertTrue(info.isScheduled()); + Assert.assertTrue(info.isStopped()); + } + + @Test + public void testToString() { + BeatInfo info = new BeatInfo(); + + String ip = "1.1.1.1"; + info.setIp(ip); + int port = 10000; + info.setPort(port); + + double weight = 1.0; + info.setWeight(weight); + String serviceName = "serviceName"; + info.setServiceName(serviceName); + String cluster = "cluster1"; + info.setCluster(cluster); + Map meta = new HashMap<>(); + meta.put("a", "b"); + info.setMetadata(meta); + long period = 100; + info.setPeriod(period); + info.setScheduled(true); + info.setStopped(true); + String expect = "BeatInfo{port=10000, ip='1.1.1.1', " + "weight=1.0, serviceName='serviceName'," + + " cluster='cluster1', metadata={a=b}," + " scheduled=true, period=100, stopped=true}"; + Assert.assertEquals(expect, info.toString()); + } + +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/beat/BeatReactorTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/beat/BeatReactorTest.java new file mode 100644 index 000000000..357f10c3d --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/beat/BeatReactorTest.java @@ -0,0 +1,313 @@ +/* + * + * 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.client.naming.beat; + +import com.alibaba.nacos.api.PropertyKeyConst; +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.utils.NamingUtils; +import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class BeatReactorTest { + + @Test + public void testConstruct() throws NoSuchFieldException, IllegalAccessException { + Properties properties = new Properties(); + String threadSize = "10"; + properties.put(PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT, threadSize); + + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + BeatReactor beatReactor = new BeatReactor(proxy, properties); + Field field = BeatReactor.class.getDeclaredField("executorService"); + field.setAccessible(true); + ScheduledThreadPoolExecutor scheduledExecutorService = (ScheduledThreadPoolExecutor) field.get(beatReactor); + Assert.assertEquals(Integer.valueOf(threadSize).intValue(), scheduledExecutorService.getCorePoolSize()); + + } + + @Test + public void testAddBeatInfo() throws NacosException, InterruptedException { + BeatInfo beatInfo = new BeatInfo(); + beatInfo.setServiceName("test"); + beatInfo.setIp("11.11.11.11"); + beatInfo.setPort(1234); + beatInfo.setCluster("clusterName"); + beatInfo.setWeight(1); + beatInfo.setMetadata(new HashMap()); + beatInfo.setScheduled(false); + beatInfo.setPeriod(10L); + + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + BeatReactor beatReactor = new BeatReactor(proxy); + String serviceName = "serviceName1"; + + beatReactor.addBeatInfo(serviceName, beatInfo); + TimeUnit.MILLISECONDS.sleep(15); + Mockito.verify(proxy, Mockito.times(1)).sendBeat(beatInfo, false); + + } + + @Test + public void testRemoveBeatInfo() throws InterruptedException, NacosException { + BeatInfo beatInfo = new BeatInfo(); + beatInfo.setServiceName("test"); + String ip = "11.11.11.11"; + beatInfo.setIp(ip); + int port = 1234; + beatInfo.setPort(port); + beatInfo.setCluster("clusterName"); + beatInfo.setWeight(1); + beatInfo.setMetadata(new HashMap()); + beatInfo.setScheduled(false); + beatInfo.setPeriod(10L); + + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + BeatReactor beatReactor = new BeatReactor(proxy); + String serviceName = "serviceName1"; + + beatReactor.addBeatInfo(serviceName, beatInfo); + TimeUnit.MILLISECONDS.sleep(15); + Mockito.verify(proxy, Mockito.times(1)).sendBeat(beatInfo, false); + beatReactor.removeBeatInfo(serviceName, ip, port); + Assert.assertTrue(beatInfo.isStopped()); + Mockito.verify(proxy, Mockito.times(1)).sendBeat(beatInfo, false); + TimeUnit.MILLISECONDS.sleep(10); + + } + + @Test + public void testBuildBeatInfo1() { + String ip = "11.11.11.11"; + int port = 1234; + double weight = 1.0; + String serviceName = "service@@group1"; + String clusterName = "cluster1"; + + Map meta = new HashMap<>(); + Instance instance = new Instance(); + instance.setServiceName(serviceName); + instance.setIp(ip); + instance.setPort(port); + instance.setWeight(weight); + instance.setMetadata(meta); + instance.setClusterName(clusterName); + + BeatInfo expectInfo = new BeatInfo(); + expectInfo.setServiceName(serviceName); + expectInfo.setIp(ip); + expectInfo.setPort(port); + expectInfo.setCluster(clusterName); + expectInfo.setWeight(weight); + expectInfo.setMetadata(meta); + expectInfo.setScheduled(false); + expectInfo.setPeriod(Constants.DEFAULT_HEART_BEAT_INTERVAL); + + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + BeatReactor beatReactor = new BeatReactor(proxy); + assertBeatInfoEquals(expectInfo, beatReactor.buildBeatInfo(instance)); + } + + @Test + public void testBuildBeatInfo2() { + String ip = "11.11.11.11"; + int port = 1234; + double weight = 1.0; + String serviceName = "service"; + String clusterName = "cluster1"; + + Map meta = new HashMap<>(); + Instance instance = new Instance(); + instance.setServiceName(serviceName); + instance.setIp(ip); + instance.setPort(port); + instance.setWeight(weight); + instance.setMetadata(meta); + instance.setClusterName(clusterName); + + String groupedService = "group1@@service"; + + BeatInfo expectInfo = new BeatInfo(); + expectInfo.setServiceName(groupedService); + expectInfo.setIp(ip); + expectInfo.setPort(port); + expectInfo.setCluster(clusterName); + expectInfo.setWeight(weight); + expectInfo.setMetadata(meta); + expectInfo.setScheduled(false); + expectInfo.setPeriod(Constants.DEFAULT_HEART_BEAT_INTERVAL); + + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + BeatReactor beatReactor = new BeatReactor(proxy); + assertBeatInfoEquals(expectInfo, beatReactor.buildBeatInfo(groupedService, instance)); + } + + void assertBeatInfoEquals(BeatInfo expect, BeatInfo actual) { + Assert.assertEquals(expect.getCluster(), actual.getCluster()); + Assert.assertEquals(expect.getIp(), actual.getIp()); + Assert.assertEquals(expect.getMetadata(), actual.getMetadata()); + Assert.assertEquals(expect.getPeriod(), actual.getPeriod()); + Assert.assertEquals(expect.getPort(), actual.getPort()); + Assert.assertEquals(expect.getServiceName(), actual.getServiceName()); + Assert.assertEquals(expect.getWeight(), actual.getWeight(), 0.1); + Assert.assertEquals(expect.isStopped(), actual.isStopped()); + Assert.assertEquals(expect.isScheduled(), actual.isScheduled()); + } + + @Test + public void testBuildKey() { + String ip = "11.11.11.11"; + int port = 1234; + String serviceName = "serviceName1"; + + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + BeatReactor beatReactor = new BeatReactor(proxy); + Assert.assertEquals( + serviceName + Constants.NAMING_INSTANCE_ID_SPLITTER + ip + Constants.NAMING_INSTANCE_ID_SPLITTER + port, + beatReactor.buildKey(serviceName, ip, port)); + } + + @Test + public void testShutdown() throws NacosException, NoSuchFieldException, IllegalAccessException { + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + BeatReactor beatReactor = new BeatReactor(proxy); + Field field = BeatReactor.class.getDeclaredField("executorService"); + field.setAccessible(true); + ScheduledThreadPoolExecutor scheduledExecutorService = (ScheduledThreadPoolExecutor) field.get(beatReactor); + + Assert.assertFalse(scheduledExecutorService.isShutdown()); + beatReactor.shutdown(); + Assert.assertTrue(scheduledExecutorService.isShutdown()); + } + + @Test + public void testLightBeatFromResponse() throws InterruptedException, NacosException, JsonProcessingException { + BeatInfo beatInfo = new BeatInfo(); + beatInfo.setServiceName("test"); + beatInfo.setIp("11.11.11.11"); + beatInfo.setPort(1234); + beatInfo.setCluster("clusterName"); + beatInfo.setWeight(1); + beatInfo.setMetadata(new HashMap()); + beatInfo.setScheduled(false); + beatInfo.setPeriod(10L); + + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + String jsonString = "{\"lightBeatEnabled\":true,\"clientBeatInterval\":10}"; + ObjectMapper mapper = new ObjectMapper(); + JsonNode actualObj = mapper.readTree(jsonString); + + Mockito.when(proxy.sendBeat(beatInfo, false)).thenReturn(actualObj); + BeatReactor beatReactor = new BeatReactor(proxy); + String serviceName = "serviceName1"; + + beatReactor.addBeatInfo(serviceName, beatInfo); + TimeUnit.MILLISECONDS.sleep(12); + Mockito.verify(proxy, Mockito.times(1)).sendBeat(beatInfo, false); + TimeUnit.MILLISECONDS.sleep(12); + Mockito.verify(proxy, Mockito.times(1)).sendBeat(beatInfo, false); + Mockito.verify(proxy, Mockito.times(1)).sendBeat(beatInfo, true); + + } + + @Test + public void testIntervalFromResponse() throws JsonProcessingException, NacosException, InterruptedException { + BeatInfo beatInfo = new BeatInfo(); + beatInfo.setServiceName("test"); + beatInfo.setIp("11.11.11.11"); + beatInfo.setPort(1234); + beatInfo.setCluster("clusterName"); + beatInfo.setWeight(1); + beatInfo.setMetadata(new HashMap()); + beatInfo.setScheduled(false); + beatInfo.setPeriod(10L); + + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + String jsonString = "{\"clientBeatInterval\":20}"; + ObjectMapper mapper = new ObjectMapper(); + JsonNode actualObj = mapper.readTree(jsonString); + + Mockito.when(proxy.sendBeat(beatInfo, false)).thenReturn(actualObj); + BeatReactor beatReactor = new BeatReactor(proxy); + String serviceName = "serviceName1"; + + beatReactor.addBeatInfo(serviceName, beatInfo); + TimeUnit.MILLISECONDS.sleep(12); + Mockito.verify(proxy, Mockito.times(1)).sendBeat(beatInfo, false); + TimeUnit.MILLISECONDS.sleep(20); + Mockito.verify(proxy, Mockito.times(2)).sendBeat(beatInfo, false); + + } + + @Test + public void testNotFoundFromResponse() throws JsonProcessingException, NacosException, InterruptedException { + BeatInfo beatInfo = new BeatInfo(); + beatInfo.setServiceName("test"); + beatInfo.setIp("11.11.11.11"); + beatInfo.setPort(1234); + beatInfo.setCluster("clusterName"); + beatInfo.setWeight(1); + beatInfo.setMetadata(new HashMap()); + beatInfo.setScheduled(false); + beatInfo.setPeriod(10L); + + NamingHttpClientProxy proxy = Mockito.mock(NamingHttpClientProxy.class); + String jsonString = "{\"clientBeatInterval\":10,\"code\":20404}"; + ObjectMapper mapper = new ObjectMapper(); + JsonNode actualObj = mapper.readTree(jsonString); + + Mockito.when(proxy.sendBeat(beatInfo, false)).thenReturn(actualObj); + + Mockito.when(proxy.sendBeat(beatInfo, false)).thenReturn(actualObj); + BeatReactor beatReactor = new BeatReactor(proxy); + String serviceName = "serviceName1"; + + beatReactor.addBeatInfo(serviceName, beatInfo); + TimeUnit.MILLISECONDS.sleep(11); + Mockito.verify(proxy, Mockito.times(1)).sendBeat(beatInfo, false); + + Instance instance = new Instance(); + instance.setPort(beatInfo.getPort()); + instance.setIp(beatInfo.getIp()); + instance.setWeight(beatInfo.getWeight()); + instance.setMetadata(beatInfo.getMetadata()); + instance.setClusterName(beatInfo.getCluster()); + instance.setServiceName(beatInfo.getServiceName()); + instance.setInstanceId(null); + instance.setEphemeral(true); + + Mockito.verify(proxy, Mockito.times(1)) + .registerService(beatInfo.getServiceName(), NamingUtils.getGroupName(beatInfo.getServiceName()), + instance); + } + +} \ No newline at end of file From dee919ace96407140d9bc34a3b493092c9bcde03 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Mon, 22 Mar 2021 09:54:27 +0800 Subject: [PATCH 02/18] add ut for package c.a.nacos.client.naming.backups (#5157) --- .../naming/backups/FailoverReactorTest.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/backups/FailoverReactorTest.java diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/backups/FailoverReactorTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/backups/FailoverReactorTest.java new file mode 100644 index 000000000..993b85b1f --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/backups/FailoverReactorTest.java @@ -0,0 +1,77 @@ +/* + * 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.client.naming.backups; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.pojo.ServiceInfo; +import com.alibaba.nacos.client.naming.cache.ServiceInfoHolder; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import java.lang.reflect.Field; +import java.util.Date; +import java.util.HashMap; +import java.util.concurrent.ScheduledExecutorService; + +public class FailoverReactorTest { + + @Test + public void testInit() throws NacosException, NoSuchFieldException, IllegalAccessException { + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + Mockito.when(holder.getServiceInfoMap()).thenReturn(new HashMap<>()); + FailoverReactor failoverReactor = new FailoverReactor(holder, "/tmp"); + Field executorService = FailoverReactor.class.getDeclaredField("executorService"); + executorService.setAccessible(true); + ScheduledExecutorService o = (ScheduledExecutorService) executorService.get(failoverReactor); + Assert.assertFalse(o.isShutdown()); + failoverReactor.shutdown(); + Assert.assertTrue(o.isShutdown()); + } + + @Test + public void testAddDay() throws NacosException { + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + Mockito.when(holder.getServiceInfoMap()).thenReturn(new HashMap<>()); + FailoverReactor failoverReactor = new FailoverReactor(holder, "/tmp"); + Date date = new Date(); + Date actual = failoverReactor.addDay(date, 1); + Assert.assertEquals(date.getTime() + 24 * 60 * 60 * 1000, actual.getTime()); + failoverReactor.shutdown(); + } + + @Test + public void testIsFailoverSwitch() throws NacosException { + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + Mockito.when(holder.getServiceInfoMap()).thenReturn(new HashMap<>()); + FailoverReactor failoverReactor = new FailoverReactor(holder, "/tmp"); + Assert.assertFalse(failoverReactor.isFailoverSwitch()); + failoverReactor.shutdown(); + + } + + @Test + public void testGetService() throws NacosException { + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + Mockito.when(holder.getServiceInfoMap()).thenReturn(new HashMap<>()); + FailoverReactor failoverReactor = new FailoverReactor(holder, "/tmp"); + ServiceInfo info = failoverReactor.getService("aa@@bb"); + Assert.assertEquals(new ServiceInfo("aa@@bb").toString(), info.toString()); + failoverReactor.shutdown(); + + } +} \ No newline at end of file From 2798aa90a19c4c047b62423b18cb2479e79f3d55 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Tue, 23 Mar 2021 09:23:47 +0800 Subject: [PATCH 03/18] add ut for c.a.nacos.client.naming.cache in nacos 2.0 (#5165) --- .../naming/cache/ConcurrentDiskUtilTest.java | 60 +++++++ .../client/naming/cache/DiskCacheTest.java | 9 +- .../naming/cache/ServiceInfoHolderTest.java | 151 ++++++++++++++++++ 3 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/cache/ConcurrentDiskUtilTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/cache/ServiceInfoHolderTest.java diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/cache/ConcurrentDiskUtilTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/cache/ConcurrentDiskUtilTest.java new file mode 100644 index 000000000..17c9c0245 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/cache/ConcurrentDiskUtilTest.java @@ -0,0 +1,60 @@ +/* + * + * 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.client.naming.cache; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +public class ConcurrentDiskUtilTest { + + @Test + public void testReadAndWrite() throws IOException { + File tempFile = File.createTempFile("aaa", "bbb"); + String fileName = tempFile.getAbsolutePath(); + String content = "hello"; + String charset = "UTF-8"; + ConcurrentDiskUtil.writeFileContent(fileName, content, charset); + String actualContent = ConcurrentDiskUtil.getFileContent(fileName, charset); + Assert.assertEquals(content, actualContent); + } + + @Test + public void testReadAndWrite2() throws IOException { + File tempFile = File.createTempFile("aaa", "bbb"); + String content = "hello"; + String charset = "UTF-8"; + ConcurrentDiskUtil.writeFileContent(tempFile, content, charset); + String actualContent = ConcurrentDiskUtil.getFileContent(tempFile, charset); + Assert.assertEquals(content, actualContent); + } + + @Test + public void testByteBufferToString() throws IOException { + String msg = "test buff to string"; + ByteBuffer buff = ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8)); + String actual = ConcurrentDiskUtil.byteBufferToString(buff, "UTF-8"); + Assert.assertEquals(msg, actual); + + } +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/cache/DiskCacheTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/cache/DiskCacheTest.java index acd059be4..c3e3087f1 100644 --- a/client/src/test/java/com/alibaba/nacos/client/naming/cache/DiskCacheTest.java +++ b/client/src/test/java/com/alibaba/nacos/client/naming/cache/DiskCacheTest.java @@ -19,6 +19,7 @@ package com.alibaba.nacos.client.naming.cache; import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.ServiceInfo; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -39,7 +40,7 @@ public class DiskCacheTest { private Instance instance; @Before - public void setUp() throws Exception { + public void setUp() { System.out.println(CACHE_DIR); serviceInfo = new ServiceInfo("G@@testName", "testClusters"); instance = new Instance(); @@ -94,4 +95,10 @@ public class DiskCacheTest { assertEquals(actual.getPort(), expected.getPort()); assertEquals(actual.getMetadata(), expected.getMetadata()); } + + @Test + public void testGetLineSeparator() { + String lineSeparator = DiskCache.getLineSeparator(); + Assert.assertTrue(lineSeparator.length() > 0); + } } diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/cache/ServiceInfoHolderTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/cache/ServiceInfoHolderTest.java new file mode 100644 index 000000000..7d02749a6 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/cache/ServiceInfoHolderTest.java @@ -0,0 +1,151 @@ +/* + * + * 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.client.naming.cache; + +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.alibaba.nacos.api.naming.pojo.ServiceInfo; +import com.alibaba.nacos.client.naming.backups.FailoverReactor; +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.ScheduledExecutorService; + +public class ServiceInfoHolderTest { + + @Test + public void testGetServiceInfoMap() { + Properties prop = new Properties(); + ServiceInfoHolder holder = new ServiceInfoHolder("aa", prop); + Assert.assertEquals(0, holder.getServiceInfoMap().size()); + + } + + @Test + public void testProcessServiceInfo() { + ServiceInfo info = new ServiceInfo("a@@b@@c"); + Instance instance1 = createInstance("1.1.1.1", 1); + Instance instance2 = createInstance("1.1.1.2", 2); + List hosts = new ArrayList<>(); + hosts.add(instance1); + hosts.add(instance2); + info.setHosts(hosts); + + Properties prop = new Properties(); + ServiceInfoHolder holder = new ServiceInfoHolder("aa", prop); + + ServiceInfo actual1 = holder.processServiceInfo(info); + Assert.assertEquals(info, actual1); + + Instance newInstance1 = createInstance("1.1.1.1", 1); + newInstance1.setWeight(2.0); + Instance instance3 = createInstance("1.1.1.3", 3); + List hosts2 = new ArrayList<>(); + hosts2.add(newInstance1); + hosts2.add(instance3); + ServiceInfo info2 = new ServiceInfo("a@@b@@c"); + info2.setHosts(hosts2); + + ServiceInfo actual2 = holder.processServiceInfo(info2); + Assert.assertEquals(info2, actual2); + } + + private Instance createInstance(String ip, int port) { + Instance instance = new Instance(); + instance.setIp(ip); + instance.setPort(port); + return instance; + } + + @Test + public void testProcessServiceInfo2() { + Properties prop = new Properties(); + ServiceInfoHolder holder = new ServiceInfoHolder("aa", prop); + String json = "{\"groupName\":\"a\",\"name\":\"b\",\"clusters\":\"c\"}"; + + ServiceInfo actual = holder.processServiceInfo(json); + ServiceInfo expect = new ServiceInfo("a@@b@@c"); + expect.setJsonFromServer(json); + Assert.assertEquals(expect.getKey(), actual.getKey()); + } + + @Test + public void testProcessServiceInfoWithPushEmpty() { + ServiceInfo oldInfo = new ServiceInfo("a@@b@@c"); + Instance instance1 = createInstance("1.1.1.1", 1); + Instance instance2 = createInstance("1.1.1.2", 2); + List hosts = new ArrayList<>(); + hosts.add(instance1); + hosts.add(instance2); + oldInfo.setHosts(hosts); + + Properties prop = new Properties(); + prop.setProperty(PropertyKeyConst.NAMING_PUSH_EMPTY_PROTECTION, "true"); + ServiceInfoHolder holder = new ServiceInfoHolder("aa", prop); + holder.processServiceInfo(oldInfo); + + ServiceInfo newInfo = new ServiceInfo("a@@b@@c"); + + final ServiceInfo actual = holder.processServiceInfo(newInfo); + + Assert.assertEquals(oldInfo.getKey(), actual.getKey()); + Assert.assertEquals(2, actual.getHosts().size()); + } + + @Test + public void testGetServiceInfo() { + ServiceInfo info = new ServiceInfo("a@@b@@c"); + Instance instance1 = createInstance("1.1.1.1", 1); + List hosts = new ArrayList<>(); + hosts.add(instance1); + info.setHosts(hosts); + + Properties prop = new Properties(); + ServiceInfoHolder holder = new ServiceInfoHolder("aa", prop); + + ServiceInfo expect = holder.processServiceInfo(info); + String serviceName = "b"; + String groupName = "a"; + String clusters = "c"; + ServiceInfo actual = holder.getServiceInfo(serviceName, groupName, clusters); + Assert.assertEquals(expect.getKey(), actual.getKey()); + Assert.assertEquals(expect.getHosts().size(), actual.getHosts().size()); + Assert.assertEquals(expect.getHosts().get(0), actual.getHosts().get(0)); + } + + @Test + public void testShutdown() throws NacosException, NoSuchFieldException, IllegalAccessException { + Properties prop = new Properties(); + ServiceInfoHolder holder = new ServiceInfoHolder("aa", prop); + Field field = ServiceInfoHolder.class.getDeclaredField("failoverReactor"); + field.setAccessible(true); + FailoverReactor reactor = (FailoverReactor) field.get(holder); + Field executorService = FailoverReactor.class.getDeclaredField("executorService"); + executorService.setAccessible(true); + ScheduledExecutorService pool = (ScheduledExecutorService) executorService.get(reactor); + Assert.assertFalse(pool.isShutdown()); + holder.shutdown(); + Assert.assertTrue(pool.isShutdown()); + } +} \ No newline at end of file From a9a795c97d335f95fb6ce20072fb3c3c7158aa82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E7=BF=8A=20SionYang?= <263976490@qq.com> Date: Tue, 23 Mar 2021 10:53:56 +0800 Subject: [PATCH 04/18] Fix IT start error problem. (#5168) --- .../java/com/alibaba/nacos/test/AppTest.java | 49 ------------------- .../java/com/alibaba/nacos/test/BaseTest.java | 39 --------------- .../common/NacosAsyncRestTemplate_ITCase.java | 2 +- .../test/common/NacosRestTemplate_ITCase.java | 2 +- ...NacosRestTemplate_Interceptors_ITCase.java | 2 +- .../test/core/auth/ConfigAuth_ITCase.java | 2 +- .../test/core/auth/NamingAuth_ITCase.java | 2 +- .../test/core/auth/Permission_ITCase.java | 2 +- .../nacos/test/core/auth/Role_ITCase.java | 2 +- .../nacos/test/core/auth/User_ITCase.java | 2 +- .../core/cluster/MemberLookup_ITCase.java | 4 +- .../naming/AutoDeregisterInstance_ITCase.java | 2 +- .../test/naming/CPInstancesAPI_ITCase.java | 2 +- .../nacos/test/naming/ClientBeat_ITCase.java | 2 +- .../nacos/test/naming/Cmdb_ITCase.java | 2 +- .../naming/DeregisterInstance_ITCase.java | 2 +- .../nacos/test/naming/MultiTenant_ITCase.java | 2 +- .../MultiTenant_InstanceAPI_ITCase.java | 2 +- .../naming/NamingHttpClientProxy_ITCase.java | 2 +- .../naming/NamingMaintainService_ITCase.java | 6 +-- .../test/naming/RegisterInstance_ITCase.java | 2 +- .../nacos/test/naming/RestAPI_ITCase.java | 2 +- .../test/naming/SelectInstances_ITCase.java | 2 +- .../SelectOneHealthyInstance_ITCase.java | 2 +- .../test/naming/ServiceListTest_ITCase.java | 2 +- .../test/naming/SubscribeCluster_ITCase.java | 2 +- .../nacos/test/naming/Subscribe_ITCase.java | 2 +- .../nacos/test/naming/Unsubscribe_ITCase.java | 2 +- test/src/test/resources/logback-test.xml | 2 - 29 files changed, 27 insertions(+), 121 deletions(-) delete mode 100644 test/src/test/java/com/alibaba/nacos/test/AppTest.java delete mode 100644 test/src/test/java/com/alibaba/nacos/test/BaseTest.java diff --git a/test/src/test/java/com/alibaba/nacos/test/AppTest.java b/test/src/test/java/com/alibaba/nacos/test/AppTest.java deleted file mode 100644 index 891ae7131..000000000 --- a/test/src/test/java/com/alibaba/nacos/test/AppTest.java +++ /dev/null @@ -1,49 +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.test; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Unit test for simple App. - */ -public class AppTest - extends TestCase { - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest(String testName) { - super(testName); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() { - return new TestSuite(AppTest.class); - } - - /** - * Rigourous Test :-) - */ - public void testApp() { - assertTrue(true); - } -} diff --git a/test/src/test/java/com/alibaba/nacos/test/BaseTest.java b/test/src/test/java/com/alibaba/nacos/test/BaseTest.java deleted file mode 100644 index b88465e03..000000000 --- a/test/src/test/java/com/alibaba/nacos/test/BaseTest.java +++ /dev/null @@ -1,39 +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.test; - -import com.alibaba.nacos.common.utils.JacksonUtils; -import com.alibaba.nacos.naming.healthcheck.RsInfo; -import org.junit.Test; - -/** - * @author liaochuntao - * @author yangyi - * - * @deprecated It seems no necessary for super test class, will be removed. - */ -@Deprecated -public class BaseTest { - - @Test - public void test_rs_json() { - String json = "{\"cluster\":\"DEFAULT\",\"ip\":\"127.0.0.1\",\"metadata\":{},\"port\":60000,\"scheduled\":true,\"serviceName\":\"DEFAULT_GROUP@@jinhan9J7ye.Vj6hx.net\",\"weight\":1.0}"; - RsInfo client = JacksonUtils.toObj(json, RsInfo.class); - System.out.println(client); - } - -} diff --git a/test/src/test/java/com/alibaba/nacos/test/common/NacosAsyncRestTemplate_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/common/NacosAsyncRestTemplate_ITCase.java index 2e5ad7aaa..8455ac6a0 100644 --- a/test/src/test/java/com/alibaba/nacos/test/common/NacosAsyncRestTemplate_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/common/NacosAsyncRestTemplate_ITCase.java @@ -48,7 +48,7 @@ import java.util.Map; @FixMethodOrder(MethodSorters.JVM) @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = { - "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class NacosAsyncRestTemplate_ITCase { @LocalServerPort diff --git a/test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_ITCase.java index 8990a80ae..176497820 100644 --- a/test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_ITCase.java @@ -47,7 +47,7 @@ import java.util.Map; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = { - "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @FixMethodOrder(MethodSorters.JVM) public class NacosRestTemplate_ITCase { diff --git a/test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_Interceptors_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_Interceptors_ITCase.java index ff220110d..e2e501814 100644 --- a/test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_Interceptors_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/common/NacosRestTemplate_Interceptors_ITCase.java @@ -51,7 +51,7 @@ import java.util.Map; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = { - "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @FixMethodOrder(MethodSorters.JVM) public class NacosRestTemplate_Interceptors_ITCase { diff --git a/test/src/test/java/com/alibaba/nacos/test/core/auth/ConfigAuth_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/core/auth/ConfigAuth_ITCase.java index 54c8ee672..0b06d45d8 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/auth/ConfigAuth_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/auth/ConfigAuth_ITCase.java @@ -45,7 +45,7 @@ import static org.junit.Assert.fail; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class ConfigAuth_ITCase extends AuthBase { @LocalServerPort diff --git a/test/src/test/java/com/alibaba/nacos/test/core/auth/NamingAuth_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/core/auth/NamingAuth_ITCase.java index 707feea32..6df5c5231 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/auth/NamingAuth_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/auth/NamingAuth_ITCase.java @@ -43,7 +43,7 @@ import static org.junit.Assert.fail; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class NamingAuth_ITCase extends AuthBase { @LocalServerPort diff --git a/test/src/test/java/com/alibaba/nacos/test/core/auth/Permission_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/core/auth/Permission_ITCase.java index dbad58fe2..bca4fdf8d 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/auth/Permission_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/auth/Permission_ITCase.java @@ -44,7 +44,7 @@ import java.util.concurrent.TimeUnit; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class Permission_ITCase extends HttpClient4Test { @LocalServerPort diff --git a/test/src/test/java/com/alibaba/nacos/test/core/auth/Role_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/core/auth/Role_ITCase.java index bffa89207..03d411187 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/auth/Role_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/auth/Role_ITCase.java @@ -44,7 +44,7 @@ import java.util.concurrent.TimeUnit; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class Role_ITCase extends HttpClient4Test { @LocalServerPort diff --git a/test/src/test/java/com/alibaba/nacos/test/core/auth/User_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/core/auth/User_ITCase.java index 137a31d85..fd5917e61 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/auth/User_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/auth/User_ITCase.java @@ -46,7 +46,7 @@ import java.util.concurrent.TimeUnit; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class User_ITCase extends HttpClient4Test { @LocalServerPort diff --git a/test/src/test/java/com/alibaba/nacos/test/core/cluster/MemberLookup_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/core/cluster/MemberLookup_ITCase.java index 66cd2121f..c4549ba75 100644 --- a/test/src/test/java/com/alibaba/nacos/test/core/cluster/MemberLookup_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/core/cluster/MemberLookup_ITCase.java @@ -25,10 +25,8 @@ import com.alibaba.nacos.core.cluster.lookup.LookupFactory; import com.alibaba.nacos.core.cluster.MemberLookup; import com.alibaba.nacos.core.cluster.lookup.StandaloneMemberLookup; import com.alibaba.nacos.sys.env.EnvUtil; -import com.alibaba.nacos.sys.utils.ApplicationUtils; import com.alibaba.nacos.sys.utils.DiskUtils; import com.alibaba.nacos.sys.utils.InetUtils; -import com.alibaba.nacos.test.BaseTest; import org.apache.commons.lang3.StringUtils; import org.junit.After; import org.junit.Assert; @@ -49,7 +47,7 @@ import java.util.Map; * @author liaochuntao */ @FixMethodOrder(value = MethodSorters.NAME_ASCENDING) -public class MemberLookup_ITCase extends BaseTest { +public class MemberLookup_ITCase { static final String path = Paths.get(System.getProperty("user.home"), "/member_look") .toString(); diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/AutoDeregisterInstance_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/AutoDeregisterInstance_ITCase.java index 451630959..f8c285283 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/AutoDeregisterInstance_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/AutoDeregisterInstance_ITCase.java @@ -50,7 +50,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.randomDomainName; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = { - "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class AutoDeregisterInstance_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java index 674493b96..9aa2cec06 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java @@ -55,7 +55,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.*; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class CPInstancesAPI_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/ClientBeat_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/ClientBeat_ITCase.java index 6e5cefe02..cf0c4a8d1 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/ClientBeat_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/ClientBeat_ITCase.java @@ -40,7 +40,7 @@ import java.util.concurrent.TimeUnit; @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class ClientBeat_ITCase extends NamingBase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/Cmdb_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/Cmdb_ITCase.java index 11c37f47e..c087aa4fb 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/Cmdb_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/Cmdb_ITCase.java @@ -49,7 +49,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.*; @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @Ignore public class Cmdb_ITCase { diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/DeregisterInstance_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/DeregisterInstance_ITCase.java index ac74ed1c1..415ed71fb 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/DeregisterInstance_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/DeregisterInstance_ITCase.java @@ -45,7 +45,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.randomDomainName; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class DeregisterInstance_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_ITCase.java index 1d4178bf8..209ea0b78 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_ITCase.java @@ -48,7 +48,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.*; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class MultiTenant_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_InstanceAPI_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_InstanceAPI_ITCase.java index 504304d3c..b90c49a90 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_InstanceAPI_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/MultiTenant_InstanceAPI_ITCase.java @@ -60,7 +60,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.randomDomainName; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = { - "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class MultiTenant_InstanceAPI_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/NamingHttpClientProxy_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/NamingHttpClientProxy_ITCase.java index b7aa0e0f8..2d5eb1aa5 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/NamingHttpClientProxy_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/NamingHttpClientProxy_ITCase.java @@ -45,7 +45,7 @@ import java.util.concurrent.TimeUnit; @RunWith(SpringRunner.class) @SpringBootTest(classes = NamingApp.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class NamingHttpClientProxy_ITCase { @LocalServerPort private int port; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/NamingMaintainService_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/NamingMaintainService_ITCase.java index d59dd9e59..42ee83208 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/NamingMaintainService_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/NamingMaintainService_ITCase.java @@ -27,8 +27,6 @@ import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.Service; import com.alibaba.nacos.api.selector.ExpressionSelector; import com.alibaba.nacos.api.selector.NoneSelector; -import com.alibaba.nacos.sys.utils.ApplicationUtils; -import com.alibaba.nacos.test.BaseTest; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -51,8 +49,8 @@ import static com.alibaba.nacos.test.naming.NamingBase.randomDomainName; **/ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class NamingMaintainService_ITCase extends BaseTest { + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class NamingMaintainService_ITCase { private NamingMaintainService namingMaintainService; private NamingService namingService; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/RegisterInstance_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/RegisterInstance_ITCase.java index f5a672456..5c4cef38d 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/RegisterInstance_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/RegisterInstance_ITCase.java @@ -46,7 +46,7 @@ import java.util.concurrent.TimeUnit; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = { - "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + "server.servlet.context-path=/nacos"}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class RegisterInstance_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/RestAPI_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/RestAPI_ITCase.java index 48d0ff0bd..eee831b54 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/RestAPI_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/RestAPI_ITCase.java @@ -35,7 +35,7 @@ import java.net.URL; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class RestAPI_ITCase extends NamingBase { @LocalServerPort diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/SelectInstances_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/SelectInstances_ITCase.java index 4b78ef75f..a30759341 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/SelectInstances_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/SelectInstances_ITCase.java @@ -47,7 +47,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.*; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class SelectInstances_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/SelectOneHealthyInstance_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/SelectOneHealthyInstance_ITCase.java index 16104ebf0..b93a4566c 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/SelectOneHealthyInstance_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/SelectOneHealthyInstance_ITCase.java @@ -42,7 +42,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.*; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class SelectOneHealthyInstance_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/ServiceListTest_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/ServiceListTest_ITCase.java index 4a58b3fed..a3ae63157 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/ServiceListTest_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/ServiceListTest_ITCase.java @@ -45,7 +45,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.randomDomainName; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class ServiceListTest_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/SubscribeCluster_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/SubscribeCluster_ITCase.java index 86c13f809..fbd913ed5 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/SubscribeCluster_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/SubscribeCluster_ITCase.java @@ -46,7 +46,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.*; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class SubscribeCluster_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/Subscribe_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/Subscribe_ITCase.java index 77b9be11f..4767f3434 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/Subscribe_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/Subscribe_ITCase.java @@ -48,7 +48,7 @@ import java.util.concurrent.TimeUnit; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class Subscribe_ITCase extends RestAPI_ITCase { private NamingService naming; diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/Unsubscribe_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/Unsubscribe_ITCase.java index a04c200d7..2de35457e 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/Unsubscribe_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/Unsubscribe_ITCase.java @@ -45,7 +45,7 @@ import static com.alibaba.nacos.test.naming.NamingBase.*; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos"}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class Unsubscribe_ITCase { private NamingService naming; diff --git a/test/src/test/resources/logback-test.xml b/test/src/test/resources/logback-test.xml index a765fe871..1461c7d0c 100644 --- a/test/src/test/resources/logback-test.xml +++ b/test/src/test/resources/logback-test.xml @@ -17,8 +17,6 @@ - - From 141e531c5221e410d7afcbc56e8aff79bddaaa65 Mon Sep 17 00:00:00 2001 From: Gagharv Date: Thu, 25 Mar 2021 09:46:01 +0800 Subject: [PATCH 05/18] Just delete unnecessary code, which may cause members to lose state, such as `supportRemoteConnection`. (#5176) When the node list is changed, ClusterRpcClientProxy#refresh is judged as a member leave. --- .../com/alibaba/nacos/core/cluster/ServerMemberManager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/main/java/com/alibaba/nacos/core/cluster/ServerMemberManager.java b/core/src/main/java/com/alibaba/nacos/core/cluster/ServerMemberManager.java index 5160effc7..788a406dc 100644 --- a/core/src/main/java/com/alibaba/nacos/core/cluster/ServerMemberManager.java +++ b/core/src/main/java/com/alibaba/nacos/core/cluster/ServerMemberManager.java @@ -360,8 +360,6 @@ public class ServerMemberManager implements ApplicationListener Date: Thu, 25 Mar 2021 09:48:00 +0800 Subject: [PATCH 06/18] [ISSUE #5169] Fix instance beat run only by responsible server. (#5179) * [ISSUE #5169] DISTRO filter support `beat` parameter For old version clients. * [ISSUE #5169] Only responsible server need to check instance heartbeats --- ...stanceBeatCheckResponsibleInterceptor.java | 40 +++++++++++++++++++ .../heartbeat/InstanceBeatCheckTask.java | 8 ++-- .../naming/web/DistroIpPortTagGenerator.java | 17 ++++++++ ...eck.heartbeat.AbstractBeatCheckInterceptor | 1 + 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 naming/src/main/java/com/alibaba/nacos/naming/healthcheck/heartbeat/InstanceBeatCheckResponsibleInterceptor.java diff --git a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/heartbeat/InstanceBeatCheckResponsibleInterceptor.java b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/heartbeat/InstanceBeatCheckResponsibleInterceptor.java new file mode 100644 index 000000000..7e2d385a0 --- /dev/null +++ b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/heartbeat/InstanceBeatCheckResponsibleInterceptor.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1999-2021 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.healthcheck.heartbeat; + +import com.alibaba.nacos.naming.core.DistroMapper; +import com.alibaba.nacos.sys.utils.ApplicationUtils; + +/** + * Instance responsibility check interceptor. + * + * @author gengtuo.ygt + * on 2021/3/24 + */ +public class InstanceBeatCheckResponsibleInterceptor extends AbstractBeatCheckInterceptor { + + @Override + public boolean intercept(InstanceBeatCheckTask object) { + return !ApplicationUtils.getBean(DistroMapper.class).responsible(object.getClient().getResponsibleId()); + } + + @Override + public int order() { + return Integer.MIN_VALUE + 2; + } + +} diff --git a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/heartbeat/InstanceBeatCheckTask.java b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/heartbeat/InstanceBeatCheckTask.java index d8f9dd158..66c5b28c5 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/heartbeat/InstanceBeatCheckTask.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/heartbeat/InstanceBeatCheckTask.java @@ -17,7 +17,7 @@ package com.alibaba.nacos.naming.healthcheck.heartbeat; import com.alibaba.nacos.common.spi.NacosServiceLoader; -import com.alibaba.nacos.naming.core.v2.client.Client; +import com.alibaba.nacos.naming.core.v2.client.impl.IpPortBasedClient; import com.alibaba.nacos.naming.core.v2.pojo.HealthCheckInstancePublishInfo; import com.alibaba.nacos.naming.core.v2.pojo.Service; import com.alibaba.nacos.naming.interceptor.Interceptable; @@ -34,7 +34,7 @@ public class InstanceBeatCheckTask implements Interceptable { private static final List CHECKERS = new LinkedList<>(); - private final Client client; + private final IpPortBasedClient client; private final Service service; @@ -46,7 +46,7 @@ public class InstanceBeatCheckTask implements Interceptable { CHECKERS.addAll(NacosServiceLoader.load(InstanceBeatChecker.class)); } - public InstanceBeatCheckTask(Client client, Service service, HealthCheckInstancePublishInfo instancePublishInfo) { + public InstanceBeatCheckTask(IpPortBasedClient client, Service service, HealthCheckInstancePublishInfo instancePublishInfo) { this.client = client; this.service = service; this.instancePublishInfo = instancePublishInfo; @@ -63,7 +63,7 @@ public class InstanceBeatCheckTask implements Interceptable { public void afterIntercept() { } - public Client getClient() { + public IpPortBasedClient getClient() { return client; } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/web/DistroIpPortTagGenerator.java b/naming/src/main/java/com/alibaba/nacos/naming/web/DistroIpPortTagGenerator.java index 3f93924ea..5bf4b216e 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/web/DistroIpPortTagGenerator.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/web/DistroIpPortTagGenerator.java @@ -16,9 +16,12 @@ package com.alibaba.nacos.naming.web; +import com.alibaba.nacos.api.exception.runtime.NacosDeserializationException; import com.alibaba.nacos.common.utils.IPUtil; +import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.core.utils.ReuseHttpServletRequest; +import com.alibaba.nacos.naming.healthcheck.RsInfo; /** * Distro IP and port tag generator. @@ -27,6 +30,8 @@ import com.alibaba.nacos.core.utils.ReuseHttpServletRequest; */ public class DistroIpPortTagGenerator implements DistroTagGenerator { + private static final String PARAMETER_BEAT = "beat"; + private static final String PARAMETER_IP = "ip"; private static final String PARAMETER_PORT = "port"; @@ -35,6 +40,18 @@ public class DistroIpPortTagGenerator implements DistroTagGenerator { public String getResponsibleTag(ReuseHttpServletRequest request) { String ip = request.getParameter(PARAMETER_IP); String port = request.getParameter(PARAMETER_PORT); + if (StringUtils.isBlank(ip)) { + // some old version clients using beat parameter + String beatStr = request.getParameter(PARAMETER_BEAT); + if (StringUtils.isNotBlank(beatStr)) { + try { + RsInfo rsInfo = JacksonUtils.toObj(beatStr, RsInfo.class); + ip = rsInfo.getIp(); + port = String.valueOf(rsInfo.getPort()); + } catch (NacosDeserializationException ignored) { + } + } + } if (StringUtils.isNotBlank(ip)) { ip = ip.trim(); } diff --git a/naming/src/main/resources/META-INF/services/com.alibaba.nacos.naming.healthcheck.heartbeat.AbstractBeatCheckInterceptor b/naming/src/main/resources/META-INF/services/com.alibaba.nacos.naming.healthcheck.heartbeat.AbstractBeatCheckInterceptor index 50ef3ca2b..f236b0548 100644 --- a/naming/src/main/resources/META-INF/services/com.alibaba.nacos.naming.healthcheck.heartbeat.AbstractBeatCheckInterceptor +++ b/naming/src/main/resources/META-INF/services/com.alibaba.nacos.naming.healthcheck.heartbeat.AbstractBeatCheckInterceptor @@ -16,3 +16,4 @@ com.alibaba.nacos.naming.healthcheck.heartbeat.ServiceEnableBeatCheckInterceptor com.alibaba.nacos.naming.healthcheck.heartbeat.InstanceEnableBeatCheckInterceptor +com.alibaba.nacos.naming.healthcheck.heartbeat.InstanceBeatCheckResponsibleInterceptor From 46c9a96ec5822581f934f424f0645667940fa9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E7=BF=8A=20SionYang?= <263976490@qq.com> Date: Fri, 26 Mar 2021 09:36:20 +0800 Subject: [PATCH 07/18] Fix #5178, Fix NPE when init server list failed. (#5188) --- .../client/naming/core/ServerListManager.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/core/ServerListManager.java b/client/src/main/java/com/alibaba/nacos/client/naming/core/ServerListManager.java index f4b22d7e2..ea96e5b53 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/core/ServerListManager.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/core/ServerListManager.java @@ -60,9 +60,9 @@ public class ServerListManager implements ServerListFactory, Closeable { private final AtomicInteger currentIndex = new AtomicInteger(); - private List serversFromEndpoint = new ArrayList(); + private final List serverList = new ArrayList<>(); - private List serverList = new ArrayList(); + private List serversFromEndpoint = new ArrayList<>(); private ScheduledExecutorService refreshServerListExecutor; @@ -85,12 +85,9 @@ public class ServerListManager implements ServerListFactory, Closeable { this.serversFromEndpoint = getServerListFromEndpoint(); refreshServerListExecutor = new ScheduledThreadPoolExecutor(1, new NameThreadFactory("com.alibaba.nacos.client.naming.server.list.refresher")); - refreshServerListExecutor.scheduleWithFixedDelay(new Runnable() { - @Override - public void run() { - refreshServerListIfNeed(); - } - }, 0, refreshServerListInternal, TimeUnit.MILLISECONDS); + refreshServerListExecutor + .scheduleWithFixedDelay(this::refreshServerListIfNeed, 0, refreshServerListInternal, + TimeUnit.MILLISECONDS); } else { String serverListFromProps = properties.getProperty(PropertyKeyConst.SERVER_ADDR); if (StringUtils.isNotEmpty(serverListFromProps)) { @@ -138,7 +135,7 @@ public class ServerListManager implements ServerListFactory, Closeable { if (CollectionUtils.isEmpty(list)) { throw new Exception("Can not acquire Nacos list"); } - if (!CollectionUtils.isEqualCollection(list, serversFromEndpoint)) { + if (null == serversFromEndpoint || !CollectionUtils.isEqualCollection(list, serversFromEndpoint)) { NAMING_LOGGER.info("[SERVER-LIST] server list is updated: " + list); } serversFromEndpoint = list; @@ -156,6 +153,7 @@ public class ServerListManager implements ServerListFactory, Closeable { return nacosDomain; } + @Override public List getServerList() { return serverList.isEmpty() ? serversFromEndpoint : serverList; } From d5b9b908a00aea0d3e60d27383d10dbb48246d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=99=93=E5=8F=8C=20Li=20Xiao=20Shuang?= <644968328@qq.com> Date: Fri, 26 Mar 2021 10:01:06 +0800 Subject: [PATCH 08/18] [ISSUE #5096] Add unit tests to package com.alibaba.nacos.naming.healthcheck in nacos 2.0 (#5170) * add unit test for healthcheck * add newline * delete javadoc * add Licensed * add verify * normalize --- .../healthcheck/v2/HealthCheckTaskV2Test.java | 110 +++++++++++ ...ersistentHealthStatusSynchronizerTest.java | 55 ++++++ .../v2/processor/HealthCheckCommonV2Test.java | 118 ++++++++++++ .../HealthCheckProcessorV2DelegateTest.java | 94 +++++++++ .../HttpHealthCheckProcessorTest.java | 179 ++++++++++++++++++ 5 files changed, 556 insertions(+) create mode 100644 naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/HealthCheckTaskV2Test.java create mode 100644 naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/PersistentHealthStatusSynchronizerTest.java create mode 100644 naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HealthCheckCommonV2Test.java create mode 100644 naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HealthCheckProcessorV2DelegateTest.java create mode 100644 naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HttpHealthCheckProcessorTest.java diff --git a/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/HealthCheckTaskV2Test.java b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/HealthCheckTaskV2Test.java new file mode 100644 index 000000000..275a13040 --- /dev/null +++ b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/HealthCheckTaskV2Test.java @@ -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.naming.healthcheck.v2; + +import com.alibaba.nacos.naming.core.v2.client.impl.IpPortBasedClient; +import com.alibaba.nacos.naming.core.v2.metadata.NamingMetadataManager; +import com.alibaba.nacos.naming.core.v2.pojo.Service; +import com.alibaba.nacos.naming.misc.SwitchDomain; +import com.alibaba.nacos.sys.utils.ApplicationUtils; +import org.junit.Assert; +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 java.util.Collections; +import java.util.List; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class HealthCheckTaskV2Test { + + private HealthCheckTaskV2 healthCheckTaskV2; + + @Mock + private IpPortBasedClient ipPortBasedClient; + + @Mock + private ConfigurableApplicationContext context; + + @Mock + private SwitchDomain switchDomain; + + @Mock + private Service service; + + @Before + public void setUp() { + ApplicationUtils.injectContext(context); + when(ApplicationUtils.getBean(SwitchDomain.class)).thenReturn(switchDomain); + when(switchDomain.getTcpHealthParams()).thenReturn(new SwitchDomain.TcpHealthParams()); + when(ApplicationUtils.getBean(NamingMetadataManager.class)).thenReturn(new NamingMetadataManager()); + healthCheckTaskV2 = new HealthCheckTaskV2(ipPortBasedClient); + } + + @Test + public void testDoHealthCheck() { + when(ipPortBasedClient.getAllPublishedService()).thenReturn(returnService()); + + healthCheckTaskV2.setCheckRtWorst(1); + healthCheckTaskV2.setCheckRtLastLast(1); + Assert.assertEquals(1, healthCheckTaskV2.getCheckRtWorst()); + Assert.assertEquals(1, healthCheckTaskV2.getCheckRtLastLast()); + + healthCheckTaskV2.run(); + healthCheckTaskV2.passIntercept(); + healthCheckTaskV2.doHealthCheck(); + + verify(ipPortBasedClient, times(3)).getAllPublishedService(); + verify(switchDomain, times(3)).isHealthCheckEnabled(service.getGroupedServiceName()); + } + + private List returnService() { + return Collections.singletonList(service); + } + + @Test + public void testGetClient() { + Assert.assertNotNull(healthCheckTaskV2.getClient()); + } + + @Test + public void testGetAndSet() { + healthCheckTaskV2.setCheckRtBest(1); + healthCheckTaskV2.setCheckRtNormalized(1); + healthCheckTaskV2.setCheckRtLast(1); + healthCheckTaskV2.setCancelled(true); + healthCheckTaskV2.setStartTime(1615796485783L); + + Assert.assertEquals(1, healthCheckTaskV2.getCheckRtBest()); + Assert.assertEquals(1, healthCheckTaskV2.getCheckRtNormalized()); + Assert.assertEquals(1, healthCheckTaskV2.getCheckRtLast()); + Assert.assertTrue(healthCheckTaskV2.isCancelled()); + Assert.assertEquals(1615796485783L, healthCheckTaskV2.getStartTime()); + } + + @Test + public void testAfterIntercept() { + healthCheckTaskV2.afterIntercept(); + } +} diff --git a/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/PersistentHealthStatusSynchronizerTest.java b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/PersistentHealthStatusSynchronizerTest.java new file mode 100644 index 000000000..c67dee8ec --- /dev/null +++ b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/PersistentHealthStatusSynchronizerTest.java @@ -0,0 +1,55 @@ +/* + * 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.healthcheck.v2; + +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.alibaba.nacos.naming.core.v2.client.Client; +import com.alibaba.nacos.naming.core.v2.pojo.InstancePublishInfo; +import com.alibaba.nacos.naming.core.v2.pojo.Service; +import com.alibaba.nacos.naming.core.v2.service.impl.PersistentClientOperationServiceImpl; +import com.alibaba.nacos.naming.utils.InstanceUtil; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class PersistentHealthStatusSynchronizerTest { + + @Mock + private PersistentClientOperationServiceImpl persistentClientOperationService; + + @Mock + private Client client; + + @Test + public void testInstanceHealthStatusChange() { + Service service = Service.newService("public", "DEFAULT", "nacos", true); + InstancePublishInfo instancePublishInfo = new InstancePublishInfo("127.0.0.1", 8080); + PersistentHealthStatusSynchronizer persistentHealthStatusSynchronizer = new PersistentHealthStatusSynchronizer( + persistentClientOperationService); + persistentHealthStatusSynchronizer.instanceHealthStatusChange(true, client, service, instancePublishInfo); + + Instance updateInstance = InstanceUtil.parseToApiInstance(service, instancePublishInfo); + updateInstance.setHealthy(true); + + verify(client).getClientId(); + verify(persistentClientOperationService).registerInstance(service, updateInstance, client.getClientId()); + } +} diff --git a/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HealthCheckCommonV2Test.java b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HealthCheckCommonV2Test.java new file mode 100644 index 000000000..2f339560f --- /dev/null +++ b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HealthCheckCommonV2Test.java @@ -0,0 +1,118 @@ +/* + * 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.healthcheck.v2.processor; + +import com.alibaba.nacos.naming.core.v2.client.impl.IpPortBasedClient; +import com.alibaba.nacos.naming.core.v2.pojo.HealthCheckInstancePublishInfo; +import com.alibaba.nacos.naming.core.v2.pojo.Service; +import com.alibaba.nacos.naming.healthcheck.v2.HealthCheckTaskV2; +import com.alibaba.nacos.naming.misc.SwitchDomain; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.concurrent.atomic.AtomicInteger; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class HealthCheckCommonV2Test { + + @Mock + private SwitchDomain.HealthParams healthParams; + + @Mock + private HealthCheckTaskV2 healthCheckTaskV2; + + @Mock + private Service service; + + @Mock + private IpPortBasedClient ipPortBasedClient; + + @Mock + private HealthCheckInstancePublishInfo healthCheckInstancePublishInfo; + + private HealthCheckCommonV2 healthCheckCommonV2; + + @Before + public void setUp() { + healthCheckCommonV2 = new HealthCheckCommonV2(); + when(healthCheckTaskV2.getClient()).thenReturn(ipPortBasedClient); + when(ipPortBasedClient.getInstancePublishInfo(service)).thenReturn(healthCheckInstancePublishInfo); + when(healthCheckInstancePublishInfo.getFailCount()).thenReturn(new AtomicInteger()); + } + + @Test + public void testReEvaluateCheckRT() { + healthCheckCommonV2.reEvaluateCheckRT(1, healthCheckTaskV2, healthParams); + + verify(healthParams, times(2)).getMax(); + verify(healthParams, times(1)).getMin(); + verify(healthParams, times(2)).getFactor(); + + verify(healthCheckTaskV2).getCheckRtWorst(); + verify(healthCheckTaskV2).getCheckRtBest(); + verify(healthCheckTaskV2).getCheckRtNormalized(); + } + + @Test + public void testCheckOk() { + healthCheckCommonV2.checkOk(healthCheckTaskV2, service, "test checkOk"); + + verify(healthCheckTaskV2).getClient(); + verify(service).getGroupedServiceName(); + verify(ipPortBasedClient).getInstancePublishInfo(service); + verify(healthCheckInstancePublishInfo).isHealthy(); + verify(healthCheckInstancePublishInfo).getCluster(); + verify(healthCheckInstancePublishInfo).resetFailCount(); + verify(healthCheckInstancePublishInfo).finishCheck(); + + } + + @Test + public void testCheckFail() { + when(healthCheckInstancePublishInfo.isHealthy()).thenReturn(true); + healthCheckCommonV2.checkFail(healthCheckTaskV2, service, "test checkFail"); + + verify(healthCheckTaskV2).getClient(); + verify(service).getGroupedServiceName(); + verify(ipPortBasedClient).getInstancePublishInfo(service); + verify(healthCheckInstancePublishInfo).isHealthy(); + verify(healthCheckInstancePublishInfo).getCluster(); + verify(healthCheckInstancePublishInfo).resetOkCount(); + verify(healthCheckInstancePublishInfo).finishCheck(); + } + + @Test + public void testCheckFailNow() { + when(healthCheckInstancePublishInfo.isHealthy()).thenReturn(true); + healthCheckCommonV2.checkFailNow(healthCheckTaskV2, service, "test checkFailNow"); + + verify(healthCheckTaskV2).getClient(); + verify(service).getGroupedServiceName(); + verify(ipPortBasedClient).getInstancePublishInfo(service); + verify(healthCheckInstancePublishInfo).isHealthy(); + verify(healthCheckInstancePublishInfo).getCluster(); + verify(healthCheckInstancePublishInfo).resetOkCount(); + verify(healthCheckInstancePublishInfo).finishCheck(); + } +} diff --git a/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HealthCheckProcessorV2DelegateTest.java b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HealthCheckProcessorV2DelegateTest.java new file mode 100644 index 000000000..af1b75c77 --- /dev/null +++ b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HealthCheckProcessorV2DelegateTest.java @@ -0,0 +1,94 @@ +/* + * 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.healthcheck.v2.processor; + +import com.alibaba.nacos.api.naming.pojo.healthcheck.HealthCheckType; +import com.alibaba.nacos.naming.core.v2.client.impl.IpPortBasedClient; +import com.alibaba.nacos.naming.core.v2.metadata.ClusterMetadata; +import com.alibaba.nacos.naming.core.v2.pojo.Service; +import com.alibaba.nacos.naming.healthcheck.extend.HealthCheckExtendProvider; +import com.alibaba.nacos.naming.healthcheck.v2.HealthCheckTaskV2; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class HealthCheckProcessorV2DelegateTest { + + @Mock + private HealthCheckExtendProvider healthCheckExtendProvider; + + @Mock + private HealthCheckTaskV2 healthCheckTaskV2; + + @Mock + private Service service; + + @Mock + private ClusterMetadata clusterMetadata; + + private HealthCheckProcessorV2Delegate healthCheckProcessorV2Delegate; + + @Before + public void setUp() { + healthCheckProcessorV2Delegate = new HealthCheckProcessorV2Delegate(healthCheckExtendProvider); + verify(healthCheckExtendProvider).init(); + } + + @Test + public void testAddProcessor() throws NoSuchFieldException, IllegalAccessException { + List list = new ArrayList<>(); + list.add(new TcpHealthCheckProcessor(null, null)); + healthCheckProcessorV2Delegate.addProcessor(list); + + Class healthCheckProcessorV2DelegateClass = HealthCheckProcessorV2Delegate.class; + Field field = healthCheckProcessorV2DelegateClass.getDeclaredField("healthCheckProcessorMap"); + field.setAccessible(true); + Map map = (Map) field + .get(healthCheckProcessorV2Delegate); + HealthCheckProcessorV2 healthCheckProcessorV2 = map.get(HealthCheckType.TCP.name()); + Assert.assertNotNull(healthCheckProcessorV2); + } + + @Test + public void testProcess() throws NoSuchFieldException, IllegalAccessException { + testAddProcessor(); + when(clusterMetadata.getHealthyCheckType()).thenReturn(HealthCheckType.TCP.name()); + when(healthCheckTaskV2.getClient()).thenReturn(new IpPortBasedClient("127.0.0.1:80#true", true)); + + healthCheckProcessorV2Delegate.process(healthCheckTaskV2, service, clusterMetadata); + + verify(clusterMetadata).getHealthyCheckType(); + verify(healthCheckTaskV2).getClient(); + } + + @Test + public void testGetType() { + Assert.assertNull(healthCheckProcessorV2Delegate.getType()); + } +} diff --git a/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HttpHealthCheckProcessorTest.java b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HttpHealthCheckProcessorTest.java new file mode 100644 index 000000000..edfc97112 --- /dev/null +++ b/naming/src/test/java/com/alibaba/nacos/naming/healthcheck/v2/processor/HttpHealthCheckProcessorTest.java @@ -0,0 +1,179 @@ +/* + * 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.healthcheck.v2.processor; + +import com.alibaba.nacos.api.naming.pojo.healthcheck.HealthCheckType; +import com.alibaba.nacos.common.model.RestResult; +import com.alibaba.nacos.naming.core.v2.client.impl.IpPortBasedClient; +import com.alibaba.nacos.naming.core.v2.metadata.ClusterMetadata; +import com.alibaba.nacos.naming.core.v2.pojo.HealthCheckInstancePublishInfo; +import com.alibaba.nacos.naming.core.v2.pojo.Service; +import com.alibaba.nacos.naming.healthcheck.v2.HealthCheckTaskV2; +import com.alibaba.nacos.naming.misc.SwitchDomain; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class HttpHealthCheckProcessorTest { + + @Mock + private HealthCheckCommonV2 healthCheckCommon; + + @Mock + private SwitchDomain switchDomain; + + @Mock + private HealthCheckTaskV2 healthCheckTaskV2; + + @Mock + private Service service; + + @Mock + private ClusterMetadata clusterMetadata; + + @Mock + private IpPortBasedClient ipPortBasedClient; + + @Mock + private HealthCheckInstancePublishInfo healthCheckInstancePublishInfo; + + @Mock + private RestResult restResult; + + @Mock + private ConnectException connectException; + + private HttpHealthCheckProcessor httpHealthCheckProcessor; + + @Before + public void setUp() { + when(switchDomain.getHttpHealthParams()).thenReturn(new SwitchDomain.HttpHealthParams()); + when(healthCheckTaskV2.getClient()).thenReturn(ipPortBasedClient); + when(ipPortBasedClient.getInstancePublishInfo(service)).thenReturn(healthCheckInstancePublishInfo); + httpHealthCheckProcessor = new HttpHealthCheckProcessor(healthCheckCommon, switchDomain); + } + + @Test + public void testProcess() { + httpHealthCheckProcessor.process(healthCheckTaskV2, service, clusterMetadata); + + verify(healthCheckTaskV2).getClient(); + verify(healthCheckInstancePublishInfo).tryStartCheck(); + } + + @Test + public void testGetType() { + Assert.assertEquals(httpHealthCheckProcessor.getType(), HealthCheckType.HTTP.name()); + } + + @Test + public void testConstructor() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + Class healthCheckProcessorClass = HttpHealthCheckProcessor.class; + Class[] classes = healthCheckProcessorClass.getDeclaredClasses(); + Class aClass = Arrays.stream(classes).findFirst().get(); + Constructor constructor = aClass + .getConstructor(HttpHealthCheckProcessor.class, HealthCheckInstancePublishInfo.class, + HealthCheckTaskV2.class, Service.class); + Object objects = constructor + .newInstance(httpHealthCheckProcessor, healthCheckInstancePublishInfo, healthCheckTaskV2, service); + + Assert.assertNotNull(objects); + } + + @Test + public void testOnReceive() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + Class healthCheckProcessorClass = HttpHealthCheckProcessor.class; + Class[] classes = healthCheckProcessorClass.getDeclaredClasses(); + Class aClass = Arrays.stream(classes).findFirst().get(); + Constructor constructor = aClass + .getConstructor(HttpHealthCheckProcessor.class, HealthCheckInstancePublishInfo.class, + HealthCheckTaskV2.class, Service.class); + Object objects = constructor + .newInstance(httpHealthCheckProcessor, healthCheckInstancePublishInfo, healthCheckTaskV2, service); + List codeList = Stream + .of(HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_UNAVAILABLE, HttpURLConnection.HTTP_NOT_FOUND) + .collect(Collectors.toList()); + for (Integer code : codeList) { + when(restResult.getCode()).thenReturn(code); + Method onReceive = aClass.getMethod("onReceive", RestResult.class); + onReceive.invoke(objects, restResult); + + //verify + this.verifyCall(code); + } + } + + private void verifyCall(int code) { + switch (code) { + case HttpURLConnection.HTTP_OK: + verify(healthCheckCommon).checkOk(healthCheckTaskV2, service, "http:" + restResult.getCode()); + break; + case HttpURLConnection.HTTP_UNAVAILABLE: + verify(healthCheckCommon).checkFail(healthCheckTaskV2, service, "http:" + restResult.getCode()); + verify(healthCheckCommon) + .reEvaluateCheckRT(healthCheckTaskV2.getCheckRtNormalized() * 2, healthCheckTaskV2, + switchDomain.getHttpHealthParams()); + break; + case HttpURLConnection.HTTP_NOT_FOUND: + verify(healthCheckCommon).checkFailNow(healthCheckTaskV2, service, "http:" + restResult.getCode()); + verify(healthCheckCommon) + .reEvaluateCheckRT(switchDomain.getHttpHealthParams().getMax(), healthCheckTaskV2, + switchDomain.getHttpHealthParams()); + break; + default: + } + } + + @Test + public void testOnError() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + Class healthCheckProcessorClass = HttpHealthCheckProcessor.class; + Class[] classes = healthCheckProcessorClass.getDeclaredClasses(); + Class aClass = Arrays.stream(classes).findFirst().get(); + Constructor constructor = aClass + .getConstructor(HttpHealthCheckProcessor.class, HealthCheckInstancePublishInfo.class, + HealthCheckTaskV2.class, Service.class); + Object objects = constructor + .newInstance(httpHealthCheckProcessor, healthCheckInstancePublishInfo, healthCheckTaskV2, service); + Method onReceive = aClass.getMethod("onError", Throwable.class); + onReceive.invoke(objects, connectException); + + verify(healthCheckCommon) + .checkFailNow(healthCheckTaskV2, service, "http:unable2connect:" + connectException.getMessage()); + verify(healthCheckCommon).reEvaluateCheckRT(switchDomain.getHttpHealthParams().getMax(), healthCheckTaskV2, + switchDomain.getHttpHealthParams()); + } +} From 9cdfd9599d23d68bd3a4785ae109e175f58526e5 Mon Sep 17 00:00:00 2001 From: "mai.jh" Date: Fri, 26 Mar 2021 13:52:56 +0800 Subject: [PATCH 09/18] [ISSUE-#5182] Remove ConfigController#removeRequestContext method. (#5201) * fix #5182, After some discussion, 2.0 adopted a long connection approach and decided to remove RemoveRequest Context * fix #5182, After some discussion, 2.0 adopted a long connection approach and decided to remove RemoveRequest Context * Removing invalid import --- .../server/controller/ConfigController.java | 47 ------------------- 1 file changed, 47 deletions(-) diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java index fad3d184f..9adfd5ecf 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java @@ -48,11 +48,8 @@ import com.alibaba.nacos.config.server.utils.RequestUtil; import com.alibaba.nacos.config.server.utils.TimeUtils; import com.alibaba.nacos.config.server.utils.ZipUtils; import com.alibaba.nacos.sys.utils.InetUtils; -import org.apache.catalina.connector.Request; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; -import org.apache.tomcat.util.buf.ByteChunk; -import org.apache.tomcat.util.http.Parameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -73,14 +70,12 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.lang.reflect.Field; import java.net.URLDecoder; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -300,46 +295,6 @@ public class ConfigController { return rr; } - private void removeRequestContext(HttpServletRequest request) { - try { - - request.removeAttribute("body"); - - Map parameterMap = request.getParameterMap(); - Field locked = parameterMap.getClass().getDeclaredField("locked"); - locked.setAccessible(true); - locked.set(parameterMap, false); - parameterMap.remove(Constants.PROBE_MODIFY_REQUEST); - - Field inneRequestFiled = request.getClass().getDeclaredField("request"); - inneRequestFiled.setAccessible(true); - Request innerRequest = (Request) inneRequestFiled.get(request); - - Field coyoteRequest = innerRequest.getClass().getDeclaredField("coyoteRequest"); - coyoteRequest.setAccessible(true); - org.apache.coyote.Request coyotoRequest = (org.apache.coyote.Request) coyoteRequest.get(innerRequest); - Parameters parameters = coyotoRequest.getParameters(); - Field hashMapField = parameters.getClass().getDeclaredField("paramHashValues"); - hashMapField.setAccessible(true); - LinkedHashMap hashMaps = (LinkedHashMap) hashMapField.get(parameters); - hashMaps.remove(Constants.PROBE_MODIFY_REQUEST); - - Field tmpNameField = parameters.getClass().getDeclaredField("tmpName"); - tmpNameField.setAccessible(true); - ByteChunk tmpName = (ByteChunk) tmpNameField.get(parameters); - byte[] bytemp = new byte[0]; - tmpName.setBytes(bytemp, 0, 0); - - Field tmpValueField = parameters.getClass().getDeclaredField("tmpValue"); - tmpValueField.setAccessible(true); - ByteChunk tmpValue = (ByteChunk) tmpValueField.get(parameters); - tmpValue.setBytes(bytemp, 0, 0); - - } catch (Exception e) { - LOGGER.warn("remove listen request param error", e); - } - } - /** * The client listens for configuration changes. */ @@ -349,8 +304,6 @@ public class ConfigController { throws ServletException, IOException { request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true); - //remove large listen context , reduce request content to optimize cms gc. - removeRequestContext(request); String probeModify = request.getParameter("Listening-Configs"); if (StringUtils.isBlank(probeModify)) { LOGGER.warn("invalid probeModify is blank"); From ebc64d204279a15ad9fdf7cfbfe7baa854505625 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Mon, 29 Mar 2021 10:48:06 +0800 Subject: [PATCH 10/18] add ut for c.a.nacos.client.naming.event in nacos 2.0 (#5192) --- .../event/InstancesChangeEventTest.java | 44 ++++++++ .../event/InstancesChangeNotifierTest.java | 101 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/event/InstancesChangeEventTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/event/InstancesChangeNotifierTest.java diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/event/InstancesChangeEventTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/event/InstancesChangeEventTest.java new file mode 100644 index 000000000..c4c6d78cb --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/event/InstancesChangeEventTest.java @@ -0,0 +1,44 @@ +/* + * 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.client.naming.event; + +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 InstancesChangeEventTest { + + @Test + public void testGetServiceName() { + String serviceName = "a"; + String groupName = "b"; + String clusters = "c"; + List hosts = new ArrayList<>(); + Instance ins = new Instance(); + hosts.add(ins); + InstancesChangeEvent event = new InstancesChangeEvent(serviceName, groupName, clusters, hosts); + Assert.assertEquals(serviceName, event.getServiceName()); + Assert.assertEquals(clusters, event.getClusters()); + Assert.assertEquals(groupName, event.getGroupName()); + List hosts1 = event.getHosts(); + Assert.assertEquals(hosts.size(), hosts1.size()); + Assert.assertEquals(hosts.get(0), hosts1.get(0)); + } +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/event/InstancesChangeNotifierTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/event/InstancesChangeNotifierTest.java new file mode 100644 index 000000000..bf7319b34 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/event/InstancesChangeNotifierTest.java @@ -0,0 +1,101 @@ +/* + * 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.client.naming.event; + +import com.alibaba.nacos.api.naming.listener.EventListener; +import com.alibaba.nacos.api.naming.pojo.ServiceInfo; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; + +public class InstancesChangeNotifierTest { + + @Test + public void testRegisterListener() { + String group = "a"; + String name = "b"; + String clusters = "c"; + InstancesChangeNotifier instancesChangeNotifier = new InstancesChangeNotifier(); + EventListener listener = Mockito.mock(EventListener.class); + instancesChangeNotifier.registerListener(group, name, clusters, listener); + List subscribeServices = instancesChangeNotifier.getSubscribeServices(); + Assert.assertEquals(1, subscribeServices.size()); + Assert.assertEquals(group, subscribeServices.get(0).getGroupName()); + Assert.assertEquals(name, subscribeServices.get(0).getName()); + Assert.assertEquals(clusters, subscribeServices.get(0).getClusters()); + + } + + @Test + public void testDeregisterListener() { + String group = "a"; + String name = "b"; + String clusters = "c"; + InstancesChangeNotifier instancesChangeNotifier = new InstancesChangeNotifier(); + EventListener listener = Mockito.mock(EventListener.class); + instancesChangeNotifier.registerListener(group, name, clusters, listener); + List subscribeServices = instancesChangeNotifier.getSubscribeServices(); + Assert.assertEquals(1, subscribeServices.size()); + + instancesChangeNotifier.deregisterListener(group, name, clusters, listener); + + List subscribeServices2 = instancesChangeNotifier.getSubscribeServices(); + Assert.assertEquals(1, subscribeServices2.size()); + } + + @Test + public void testIsSubscribed() { + String group = "a"; + String name = "b"; + String clusters = "c"; + InstancesChangeNotifier instancesChangeNotifier = new InstancesChangeNotifier(); + EventListener listener = Mockito.mock(EventListener.class); + Assert.assertFalse(instancesChangeNotifier.isSubscribed(group, name, clusters)); + + instancesChangeNotifier.registerListener(group, name, clusters, listener); + Assert.assertTrue(instancesChangeNotifier.isSubscribed(group, name, clusters)); + } + + @Test + public void testOnEvent() { + String group = "a"; + String name = "b"; + String clusters = "c"; + InstancesChangeNotifier instancesChangeNotifier = new InstancesChangeNotifier(); + EventListener listener = Mockito.mock(EventListener.class); + + instancesChangeNotifier.registerListener(group, name, clusters, listener); + InstancesChangeEvent event1 = Mockito.mock(InstancesChangeEvent.class); + Mockito.when(event1.getClusters()).thenReturn(clusters); + Mockito.when(event1.getGroupName()).thenReturn(group); + Mockito.when(event1.getServiceName()).thenReturn(name); + + instancesChangeNotifier.onEvent(event1); + Mockito.verify(listener, times(1)).onEvent(any()); + } + + @Test + public void testSubscribeType() { + InstancesChangeNotifier instancesChangeNotifier = new InstancesChangeNotifier(); + Assert.assertEquals(InstancesChangeEvent.class, instancesChangeNotifier.subscribeType()); + } +} \ No newline at end of file From 7cab70e8895ab121ad72dca141970b9cba377aba Mon Sep 17 00:00:00 2001 From: JackSun-Developer Date: Mon, 29 Mar 2021 10:51:04 +0800 Subject: [PATCH 11/18] [#5171] Too much Integration Tests in package com.alibaba.nacos.test.naming cannot pass, could you fix them? (#5224) --- .../naming/AutoDeregisterInstance_ITCase.java | 25 ++++++----- .../test/naming/CPInstancesAPI_ITCase.java | 19 ++++++--- .../nacos/test/naming/ClientBeat_ITCase.java | 6 +-- .../naming/DeregisterInstance_ITCase.java | 41 ++++--------------- .../test/naming/RegisterInstance_ITCase.java | 10 +---- 5 files changed, 40 insertions(+), 61 deletions(-) diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/AutoDeregisterInstance_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/AutoDeregisterInstance_ITCase.java index f8c285283..c136b028a 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/AutoDeregisterInstance_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/AutoDeregisterInstance_ITCase.java @@ -29,6 +29,7 @@ import com.alibaba.nacos.sys.env.EnvUtil; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; @@ -89,6 +90,7 @@ public class AutoDeregisterInstance_ITCase { * @throws Exception */ @Test + @Ignore("Nacos 2.0 does not support HTTP beat check any more, it uses gRPC instead.") public void autoDregDomClustersTest() throws Exception { String serviceName = randomDomainName(); @@ -100,7 +102,7 @@ public class AutoDeregisterInstance_ITCase { List instances; instances = naming.getAllInstances(serviceName); - Assert.assertEquals(2, instances.size()); + Assert.assertEquals(1, instances.size()); NacosNamingService namingServiceImpl = (NacosNamingService) naming; @@ -126,6 +128,7 @@ public class AutoDeregisterInstance_ITCase { * @throws Exception */ @Test + @Ignore("Nacos 2.0 does not support HTTP beat check any more, it uses gRPC instead.") public void autoDregDomTest() throws Exception { String serviceName = randomDomainName(); @@ -137,7 +140,7 @@ public class AutoDeregisterInstance_ITCase { List instances; instances = naming.getAllInstances(serviceName); - Assert.assertEquals(2, instances.size()); + Assert.assertEquals(1, instances.size()); NacosNamingService namingServiceImpl = (NacosNamingService) naming; @@ -158,19 +161,19 @@ public class AutoDeregisterInstance_ITCase { * @throws Exception */ @Test + @Ignore("Nacos 2.0 does not support HTTP beat check any more, it uses gRPC instead.") public void autoRegDomTest() throws Exception { String serviceName = randomDomainName(); naming.registerInstance(serviceName, "127.0.0.1", TEST_PORT); - naming.registerInstance(serviceName, "127.0.0.2", TEST_PORT); TimeUnit.SECONDS.sleep(5); List instances; instances = naming.getAllInstances(serviceName); - Assert.assertEquals(2, instances.size()); + Assert.assertEquals(1, instances.size()); NacosNamingService namingServiceImpl = (NacosNamingService) naming; @@ -178,11 +181,11 @@ public class AutoDeregisterInstance_ITCase { .removeBeatInfo(Constants.DEFAULT_GROUP + Constants.SERVICE_INFO_SPLITER + serviceName, "127.0.0.1", TEST_PORT); - verifyInstanceList(instances, 1, serviceName); + verifyInstanceList(instances, 0, serviceName); instances = naming.getAllInstances(serviceName); - Assert.assertEquals(1, instances.size()); + Assert.assertEquals(0, instances.size()); BeatInfo beatInfo = new BeatInfo(); beatInfo.setServiceName(Constants.DEFAULT_GROUP + Constants.SERVICE_INFO_SPLITER + serviceName); beatInfo.setIp("127.0.0.1"); @@ -191,11 +194,11 @@ public class AutoDeregisterInstance_ITCase { NamingTestUtils.getBeatReactorByReflection(namingServiceImpl) .addBeatInfo(Constants.DEFAULT_GROUP + Constants.SERVICE_INFO_SPLITER + serviceName, beatInfo); - verifyInstanceList(instances, 2, serviceName); + verifyInstanceList(instances, 1, serviceName); instances = naming.getAllInstances(serviceName); - Assert.assertEquals(2, instances.size()); + Assert.assertEquals(1, instances.size()); } /** @@ -204,19 +207,19 @@ public class AutoDeregisterInstance_ITCase { * @throws Exception */ @Test + @Ignore("Nacos 2.0 does not support HTTP beat check any more, it uses gRPC instead.") public void autoRegDomClustersTest() throws Exception { String serviceName = randomDomainName(); naming.registerInstance(serviceName, "127.0.0.1", TEST_PORT, "c1"); - naming.registerInstance(serviceName, "127.0.0.2", TEST_PORT, "c2"); TimeUnit.SECONDS.sleep(5); List instances; instances = naming.getAllInstances(serviceName); - Assert.assertEquals(2, instances.size()); + Assert.assertEquals(1, instances.size()); NacosNamingService namingServiceImpl = (NacosNamingService) naming; @@ -242,7 +245,7 @@ public class AutoDeregisterInstance_ITCase { instances = naming.getAllInstances(serviceName); - Assert.assertEquals(2, instances.size()); + Assert.assertEquals(1, instances.size()); instances = naming.getAllInstances(serviceName, Arrays.asList("c2")); Assert.assertEquals(1, instances.size()); diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java index 9aa2cec06..12966a9e0 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/CPInstancesAPI_ITCase.java @@ -130,7 +130,8 @@ public class CPInstancesAPI_ITCase { instance.setIp("11.11.11.11"); instance.setPort(80); naming1.registerInstance(serviceName, TEST_GROUP_1, instance); - + TimeUnit.SECONDS.sleep(3L); + naming1.deregisterInstance(serviceName, TEST_GROUP_1, instance); namingServiceDelete(serviceName, TEST_NAMESPACE_1, TEST_GROUP_1); } @@ -175,11 +176,11 @@ public class CPInstancesAPI_ITCase { * @ExpectResult : */ @Test - public void deleteService_hasInstace() throws Exception { + public void deleteService_hasInstace() { String serviceName = NamingBase.randomDomainName(); namingServiceCreate(serviceName, TEST_NAMESPACE_1); - ResponseEntity response = request(NamingBase.NAMING_CONTROLLER_PATH + "/instance", + ResponseEntity registerResponse = request(NamingBase.NAMING_CONTROLLER_PATH + "/instance", Params.newParams() .appendParam("serviceName", serviceName) .appendParam("ip", "11.11.11.11") @@ -188,8 +189,16 @@ public class CPInstancesAPI_ITCase { .done(), String.class, HttpMethod.POST); - Assert.assertTrue(response.getStatusCode().is2xxSuccessful()); - namingServiceDelete(serviceName, TEST_NAMESPACE_1); + Assert.assertTrue(registerResponse.getStatusCode().is2xxSuccessful()); + + ResponseEntity deleteServiceResponse = request(NamingBase.NAMING_CONTROLLER_PATH + "/service", + Params.newParams() + .appendParam("serviceName", serviceName) + .appendParam("namespaceId", TEST_NAMESPACE_1) + .done(), + String.class, + HttpMethod.DELETE); + Assert.assertTrue(deleteServiceResponse.getStatusCode().is4xxClientError()); } /** diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/ClientBeat_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/ClientBeat_ITCase.java index cf0c4a8d1..6e8e345c2 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/ClientBeat_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/ClientBeat_ITCase.java @@ -81,7 +81,7 @@ public class ClientBeat_ITCase extends NamingBase { TimeUnit.SECONDS.sleep(2L); List list = naming.getAllInstances(serviceName); - Assert.assertEquals(2, list.size()); + Assert.assertEquals(1, list.size()); for (Instance instance1 : list) { Assert.assertEquals("1.2.3.4", instance1.getIp()); Assert.assertTrue(instance1.getPort() == 80 || instance1.getPort() == 81); @@ -95,7 +95,7 @@ public class ClientBeat_ITCase extends NamingBase { TimeUnit.SECONDS.sleep(35L); list = naming.getAllInstances(serviceName); - Assert.assertEquals(2, list.size()); + Assert.assertEquals(1, list.size()); for (Instance instance1 : list) { Assert.assertEquals("1.2.3.4", instance1.getIp()); Assert.assertTrue(instance1.getPort() == 80 || instance1.getPort() == 81); @@ -120,7 +120,7 @@ public class ClientBeat_ITCase extends NamingBase { TimeUnit.SECONDS.sleep(35L); list = naming.getAllInstances(serviceName); - Assert.assertEquals(2, list.size()); + Assert.assertEquals(1, list.size()); for (Instance instance1 : list) { Assert.assertEquals("1.2.3.4", instance1.getIp()); Assert.assertTrue(instance1.getPort() == 80 || instance1.getPort() == 81); diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/DeregisterInstance_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/DeregisterInstance_ITCase.java index 415ed71fb..4bb49a532 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/DeregisterInstance_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/DeregisterInstance_ITCase.java @@ -87,13 +87,12 @@ public class DeregisterInstance_ITCase { String serviceName = randomDomainName(); System.out.println(serviceName); naming.registerInstance(serviceName, "127.0.0.1", TEST_PORT); - naming.registerInstance(serviceName, "127.0.0.2", TEST_PORT); List instances = naming.getAllInstances(serviceName); - verifyInstanceList(instances, 2, serviceName); + verifyInstanceList(instances, 1, serviceName); instances = naming.getAllInstances(serviceName); - Assert.assertEquals(2, instances.size()); + Assert.assertEquals(1, instances.size()); naming.deregisterInstance(serviceName, "127.0.0.1", TEST_PORT); @@ -101,15 +100,7 @@ public class DeregisterInstance_ITCase { instances = naming.getAllInstances(serviceName); - Assert.assertEquals(instances.size(), 1); - Assert.assertEquals(instances.get(0).getIp(), "127.0.0.2"); - - naming.deregisterInstance(serviceName, "127.0.0.2", TEST_PORT); - - TimeUnit.SECONDS.sleep(3); - - instances = naming.getAllInstances(serviceName); - Assert.assertEquals(0, instances.size()); + Assert.assertEquals(instances.size(), 0); } /** @@ -124,14 +115,13 @@ public class DeregisterInstance_ITCase { System.out.println(serviceName); naming.registerInstance(serviceName, "127.0.0.1", TEST_PORT, "c1"); - naming.registerInstance(serviceName, "127.0.0.2", TEST_PORT, "c2"); List instances; instances = naming.getAllInstances(serviceName); - verifyInstanceList(instances, 2, serviceName); + verifyInstanceList(instances, 1, serviceName); instances = naming.getAllInstances(serviceName); - Assert.assertEquals(instances.size(), 2); + Assert.assertEquals(1, instances.size()); naming.deregisterInstance(serviceName, "127.0.0.1", TEST_PORT, "c1"); @@ -139,12 +129,7 @@ public class DeregisterInstance_ITCase { instances = naming.getAllInstances(serviceName); - Assert.assertEquals(1, instances.size()); - - instances = naming.getAllInstances(serviceName, Arrays.asList("c2")); - Assert.assertEquals(instances.size(), 1); - - instances = naming.getAllInstances(serviceName, Arrays.asList("c1")); + Assert.assertEquals(0, instances.size()); } @@ -161,14 +146,12 @@ public class DeregisterInstance_ITCase { String serviceName = randomDomainName(); naming.registerInstance(serviceName, "127.0.0.1", TEST_PORT, "c1"); - naming.registerInstance(serviceName, "127.0.0.2", TEST_PORT, "c2"); List instances; instances = naming.getAllInstances(serviceName); - verifyInstanceList(instances, 2, serviceName); + verifyInstanceList(instances, 1, serviceName); - instances = naming.getAllInstances(serviceName); - Assert.assertEquals(2, instances.size()); + Assert.assertEquals(1, instances.size()); naming.deregisterInstance(serviceName, "127.0.0.1", TEST_PORT, "c1"); @@ -176,14 +159,6 @@ public class DeregisterInstance_ITCase { instances = naming.getAllInstances(serviceName); - Assert.assertEquals(1, instances.size()); - - instances = naming.getAllInstances(serviceName, Arrays.asList("c2")); - Assert.assertEquals(1, instances.size()); - - naming.deregisterInstance(serviceName,"127.0.0.2", TEST_PORT, "c2"); - TimeUnit.SECONDS.sleep(5); - instances = naming.getAllInstances(serviceName); Assert.assertEquals(0, instances.size()); } diff --git a/test/src/test/java/com/alibaba/nacos/test/naming/RegisterInstance_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/naming/RegisterInstance_ITCase.java index 5c4cef38d..3b85800f5 100644 --- a/test/src/test/java/com/alibaba/nacos/test/naming/RegisterInstance_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/naming/RegisterInstance_ITCase.java @@ -95,7 +95,7 @@ public class RegisterInstance_ITCase { naming.registerInstance(serviceName, "127.0.0.2", 80, "c2"); List instances = naming.getAllInstances(serviceName); - Assert.assertEquals(2, instances.size()); + Assert.assertEquals(1, instances.size()); } /** @@ -114,8 +114,6 @@ public class RegisterInstance_ITCase { List instances = naming.getAllInstances(serviceName); Assert.assertEquals(1, instances.size()); - Assert.assertTrue(instances.get(0).getInstanceId().contains(serviceName)); - //Assert.assertEquals(instances.get(0).getService().getName(), serviceName); Assert.assertEquals(instances.get(0).getIp(), NamingBase.TEST_IP_4_DOM_1); Assert.assertEquals(instances.get(0).getPort(), NamingBase.TEST_PORT); } @@ -139,20 +137,14 @@ public class RegisterInstance_ITCase { List instances = naming.getAllInstances(serviceName); Assert.assertEquals(1, instances.size()); - Assert.assertTrue(instances.get(0).getInstanceId().contains(serviceName)); - //Assert.assertEquals(instances2.get(0).getService().getName(), serviceName); Assert.assertEquals(instances.get(0).getIp(), NamingBase.TEST_IP_4_DOM_1); Assert.assertEquals(instances.get(0).getPort(), NamingBase.TEST_PORT); - //Assert.assertEquals(instances.get(0).getCluster().getName(), TEST_NEW_CLUSTER_4_DOM_1); List instances2 = naming.getAllInstances(serviceName, Arrays.asList(NamingBase.TEST_NEW_CLUSTER_4_DOM_1)); Assert.assertEquals(instances2.size(), 1); - Assert.assertTrue(instances2.get(0).getInstanceId().contains(serviceName)); - //Assert.assertEquals(instances2.get(0).getService().getName(), serviceName); Assert.assertEquals(instances2.get(0).getIp(), NamingBase.TEST_IP_4_DOM_1); Assert.assertEquals(instances2.get(0).getPort(), NamingBase.TEST_PORT); - //Assert.assertEquals(instances2.get(0).getCluster().getName(), TEST_NEW_CLUSTER_4_DOM_1); } /** From 1969f00aa52aa4c6d6355b064146a2a8865d4de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E7=BF=8A=20SionYang?= <263976490@qq.com> Date: Mon, 29 Mar 2021 15:31:25 +0800 Subject: [PATCH 12/18] Fix #5204, Fix query error when pageNo is larger than service number. (#5228) --- .../main/java/com/alibaba/nacos/naming/utils/ServiceUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/naming/src/main/java/com/alibaba/nacos/naming/utils/ServiceUtil.java b/naming/src/main/java/com/alibaba/nacos/naming/utils/ServiceUtil.java index ffeba1570..94407cedd 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/utils/ServiceUtil.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/utils/ServiceUtil.java @@ -30,6 +30,7 @@ import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -158,7 +159,7 @@ public class ServiceUtil { start = 0; } if (start >= result.size()) { - return result; + return Collections.emptyList(); } int end = start + pageSize; if (end > result.size()) { From a6a254a1c0bcc7c0e90cc80683e32fbd2ffdfa54 Mon Sep 17 00:00:00 2001 From: "nov.lzf" Date: Mon, 29 Mar 2021 21:31:06 +0800 Subject: [PATCH 13/18] fix thread pool (#5233) * fix thread pool * fix log --- .../nacos/common/remote/client/RpcClient.java | 2 +- .../nacos/common/remote/client/grpc/GrpcClient.java | 10 +++++++--- .../common/remote/client/grpc/GrpcConnection.java | 2 +- .../remote/grpc/GrpcBiStreamRequestAcceptor.java | 13 +++++++++++-- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/common/src/main/java/com/alibaba/nacos/common/remote/client/RpcClient.java b/common/src/main/java/com/alibaba/nacos/common/remote/client/RpcClient.java index 1676caa7c..93e3d8d78 100644 --- a/common/src/main/java/com/alibaba/nacos/common/remote/client/RpcClient.java +++ b/common/src/main/java/com/alibaba/nacos/common/remote/client/RpcClient.java @@ -561,7 +561,7 @@ public abstract class RpcClient implements Closeable { } } catch (Exception e) { - LoggerUtils.printIfWarnEnabled(LOGGER, "[{}] Fail to re connect to server ,error is ", name, e); + LoggerUtils.printIfWarnEnabled(LOGGER, "[{}] Fail to re connect to server ,error is {}", name, e); } } diff --git a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java index f35579fd6..3aa58c682 100644 --- a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java +++ b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java @@ -42,7 +42,7 @@ import io.grpc.stub.StreamObserver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -245,10 +245,14 @@ public abstract class GrpcClient extends RpcClient { public Connection connectToServer(ServerInfo serverInfo) { try { if (grpcExecutor == null) { - grpcExecutor = new ThreadPoolExecutor(0, Runtime.getRuntime().availableProcessors() * 8, 10L, - TimeUnit.SECONDS, new SynchronousQueue(), + + grpcExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 8, + Runtime.getRuntime().availableProcessors() * 8, 10L, TimeUnit.SECONDS, + new LinkedBlockingQueue<>(1000), new ThreadFactoryBuilder().setDaemon(true).setNameFormat("nacos-grpc-client-executor-%d") .build()); + grpcExecutor.allowCoreThreadTimeOut(true); + } RequestGrpc.RequestFutureStub newChannelStubTemp = createNewChannelStub(serverInfo.getServerIp(), serverInfo.getServerPort() + rpcPortOffset()); diff --git a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcConnection.java b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcConnection.java index 1f9d24a3a..4e4cc3120 100644 --- a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcConnection.java +++ b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcConnection.java @@ -157,7 +157,7 @@ public class GrpcConnection extends Connection { requestCallBack.onException(throwable); } } - }, this.executor); + }, requestCallBack.getExecutor() != null ? requestCallBack.getExecutor() : this.executor); // set timeout future. ListenableFuture payloadListenableFuture = Futures .withTimeout(requestFuture, requestCallBack.getTimeout(), TimeUnit.MILLISECONDS, diff --git a/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcBiStreamRequestAcceptor.java b/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcBiStreamRequestAcceptor.java index e93d36405..3621e64ef 100644 --- a/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcBiStreamRequestAcceptor.java +++ b/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcBiStreamRequestAcceptor.java @@ -169,7 +169,11 @@ public class GrpcBiStreamRequestAcceptor extends BiRequestStreamGrpc.BiRequestSt //client close the stream. return; } else { - serverCallStreamObserver.onCompleted(); + try { + serverCallStreamObserver.onCompleted(); + } catch (Throwable throwable) { + //ignore + } } } @@ -186,7 +190,12 @@ public class GrpcBiStreamRequestAcceptor extends BiRequestStreamGrpc.BiRequestSt //client close the stream. return; } else { - serverCallStreamObserver.onCompleted(); + try { + serverCallStreamObserver.onCompleted(); + } catch (Throwable throwable) { + //ignore + } + } } } From 712774f31b45896e5882cadfdad55ccb542b63c2 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Tue, 30 Mar 2021 10:15:06 +0800 Subject: [PATCH 14/18] remove unused utils; use threadlocalrandom from jdk since 1.7 (#5231) --- .../nacos/client/naming/utils/Chooser.java | 1 + .../nacos/client/naming/utils/JvmRandom.java | 223 -------------- .../client/naming/utils/RandomUtils.java | 171 ----------- .../naming/utils/ThreadLocalRandom.java | 279 ------------------ 4 files changed, 1 insertion(+), 673 deletions(-) delete mode 100644 client/src/main/java/com/alibaba/nacos/client/naming/utils/JvmRandom.java delete mode 100644 client/src/main/java/com/alibaba/nacos/client/naming/utils/RandomUtils.java delete mode 100644 client/src/main/java/com/alibaba/nacos/client/naming/utils/ThreadLocalRandom.java diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/utils/Chooser.java b/client/src/main/java/com/alibaba/nacos/client/naming/utils/Chooser.java index 4e618e2d5..fbacb48f2 100644 --- a/client/src/main/java/com/alibaba/nacos/client/naming/utils/Chooser.java +++ b/client/src/main/java/com/alibaba/nacos/client/naming/utils/Chooser.java @@ -19,6 +19,7 @@ package com.alibaba.nacos.client.naming.utils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.ThreadLocalRandom; /** * Chooser. diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/utils/JvmRandom.java b/client/src/main/java/com/alibaba/nacos/client/naming/utils/JvmRandom.java deleted file mode 100644 index 67bc82954..000000000 --- a/client/src/main/java/com/alibaba/nacos/client/naming/utils/JvmRandom.java +++ /dev/null @@ -1,223 +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.client.naming.utils; - -import java.util.Random; - -/** - *

JVMRandom is a wrapper that supports all possible Random methods via the {@link - * java.lang.Math#random()} method and its system-wide {@link Random} object.

- *

- * It does this to allow for a Random class in which the seed is shared between all members of the class - a better name - * would have been SharedSeedRandom.

- *

- * N.B. the current implementation overrides the methods {@link Random#nextInt(int)} and {@link - * Random#nextLong()} to produce positive numbers ranging from 0 (inclusive) to MAX_VALUE (exclusive). - *

- * @author unknown - * @version $Id: JVMRandom.java 911986 2010-02-19 21:19:05Z niallp $ - * @since 2.0 - */ -public final class JvmRandom extends Random { - - /** - * Required for serialization support. - * - * @see java.io.Serializable - */ - private static final long serialVersionUID = 1L; - - private static final Random SHARED_RANDOM = new Random(); - - /** - * Ensures that only the parent constructor can call reseed. - */ - private boolean constructed = false; - - /** - * Constructs a new instance. - */ - public JvmRandom() { - this.constructed = true; - } - - /** - * Unsupported in 2.0. - * - * @param seed ignored - * @throws UnsupportedOperationException unsupported operation exception - */ - @Override - public synchronized void setSeed(long seed) { - if (this.constructed) { - throw new UnsupportedOperationException(); - } - } - - /** - * Unsupported in 2.0. - * - * @return Nothing, this method always throws an UnsupportedOperationException. - * @throws UnsupportedOperationException unsupported operation exception - */ - @Override - public synchronized double nextGaussian() { - throw new UnsupportedOperationException(); - } - - /** - * Unsupported in 2.0. - * - * @param byteArray ignored - * @throws UnsupportedOperationException unsupported operation exception - */ - @Override - public void nextBytes(byte[] byteArray) { - throw new UnsupportedOperationException(); - } - - /** - *

Returns the next pseudorandom, uniformly distributed int value from the Math.random() sequence.

Identical - * to nextInt(Integer.MAX_VALUE)

N.B. All values are >= 0.

- * - * @return the random int - */ - @Override - public int nextInt() { - return nextInt(Integer.MAX_VALUE); - } - - /** - *

Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified - * value (exclusive), from the Math.random() sequence.

- * - * @param n the specified exclusive max-value - * @return the random int - * @throws IllegalArgumentException when n <= 0 - */ - @Override - public int nextInt(int n) { - return SHARED_RANDOM.nextInt(n); - } - - /** - *

Returns the next pseudorandom, uniformly distributed long value from the Math.random() sequence.

- * Identical - * to nextLong(Long.MAX_VALUE)

N.B. All values are >= 0.

- * - * @return the random long - */ - @Override - public long nextLong() { - return nextLong(Long.MAX_VALUE); - } - - /** - *

Returns a pseudorandom, uniformly distributed long value between 0 (inclusive) and the specified - * value (exclusive), from the Math.random() sequence.

- * - * @param n the specified exclusive max-value - * @return the random long - * @throws IllegalArgumentException when n <= 0 - */ - public static long nextLong(long n) { - if (n <= 0) { - throw new IllegalArgumentException("Upper bound for nextInt must be positive"); - } - // Code adapted from Harmony Random#nextInt(int) - // n is power of 2 - if ((n & -n) == n) { - // dropping lower order bits improves behaviour for low values of n - return next63bits() >> 63 - bitsRequired(n - 1); - } - // Not a power of two - long val; - long bits; - // reject some values to improve distribution - do { - bits = next63bits(); - val = bits % n; - } while (bits - val + (n - 1) < 0); - return val; - } - - /** - *

Returns the next pseudorandom, uniformly distributed boolean value from the Math.random() sequence.

- * - * @return the random boolean - */ - @Override - public boolean nextBoolean() { - return SHARED_RANDOM.nextBoolean(); - } - - /** - *

Returns the next pseudorandom, uniformly distributed float value between 0.0 and - * 1.0 - * from the Math.random() sequence.

- * - * @return the random float - */ - @Override - public float nextFloat() { - return SHARED_RANDOM.nextFloat(); - } - - /** - *

Synonymous to the Math.random() call.

- * - * @return the random double - */ - @Override - public double nextDouble() { - return SHARED_RANDOM.nextDouble(); - } - - /** - * Get the next unsigned random long. - * - * @return unsigned random long - */ - private static long next63bits() { - // drop the sign bit to leave 63 random bits - return SHARED_RANDOM.nextLong() & 0x7fffffffffffffffL; - } - - /** - * Count the number of bits required to represent a long number. - * - * @param num long number - * @return number of bits required - */ - private static int bitsRequired(long num) { - // Derived from Hacker's Delight, Figure 5-9 - long y = num; - int n = 0; - while (true) { - // 64 = number of bits in a long - if (num < 0) { - return 64 - n; - } - if (y == 0) { - return n; - } - n++; - num = num << 1; - y = y >> 1; - } - } -} diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/utils/RandomUtils.java b/client/src/main/java/com/alibaba/nacos/client/naming/utils/RandomUtils.java deleted file mode 100644 index f991d41a0..000000000 --- a/client/src/main/java/com/alibaba/nacos/client/naming/utils/RandomUtils.java +++ /dev/null @@ -1,171 +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.client.naming.utils; - -import java.util.Random; - -/** - * RandomUtils is a wrapper that supports all possible {@link java.util.Random} methods via the {@link - * java.lang.Math#random()} method and its system-wide Random object. - * - * @author Gary D. Gregory - * @version $Id: RandomUtils.java 906320 2010-02-04 01:41:10Z sebb $ - * @since 2.0 - */ -public class RandomUtils { - - /** - * An instance of {@link JvmRandom}. - */ - private static final Random JVM_RANDOM = new JvmRandom(); - - // should be possible for JVM_RANDOM? - // public static void nextBytes(byte[]) { - // public synchronized double nextGaussian(); - // } - - /** - *

Returns the next pseudorandom, uniformly distributed int value from the Math.random() sequence.

N.B. - * All values are >= 0. - * - * @return the random int - */ - public static int nextInt() { - return nextInt(JVM_RANDOM); - } - - /** - *

Returns the next pseudorandom, uniformly distributed int value from the given random - * sequence.

- * - * @param random the Random sequence generator. - * @return the random int - */ - public static int nextInt(Random random) { - return random.nextInt(); - } - - /** - *

Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified - * value (exclusive), from the Math.random() sequence.

- * - * @param n the specified exclusive max-value - * @return the random int - */ - public static int nextInt(int n) { - return nextInt(JVM_RANDOM, n); - } - - /** - *

Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified - * value (exclusive), from the given Random sequence.

- * - * @param random the Random sequence generator. - * @param n the specified exclusive max-value - * @return the random int - */ - public static int nextInt(Random random, int n) { - // check this cannot return 'n' - return random.nextInt(n); - } - - /** - *

Returns the next pseudorandom, uniformly distributed long value from the Math.random() sequence.

N.B. - * All values are >= 0. - * - * @return the random long - */ - public static long nextLong() { - return nextLong(JVM_RANDOM); - } - - /** - *

Returns the next pseudorandom, uniformly distributed long value from the given Random sequence.

- * - * @param random the Random sequence generator. - * @return the random long - */ - public static long nextLong(Random random) { - return random.nextLong(); - } - - /** - *

Returns the next pseudorandom, uniformly distributed boolean value from the Math.random() sequence.

- * - * @return the random boolean - */ - public static boolean nextBoolean() { - return nextBoolean(JVM_RANDOM); - } - - /** - *

Returns the next pseudorandom, uniformly distributed boolean value from the given random sequence.

- * - * @param random the Random sequence generator. - * @return the random boolean - */ - public static boolean nextBoolean(Random random) { - return random.nextBoolean(); - } - - /** - *

Returns the next pseudorandom, uniformly distributed float value between 0.0 and - * 1.0 - * from the Math.random() sequence.

- * - * @return the random float - */ - public static float nextFloat() { - return nextFloat(JVM_RANDOM); - } - - /** - *

Returns the next pseudorandom, uniformly distributed float value between 0.0 and - * 1.0 - * from the given Random sequence.

- * - * @param random the Random sequence generator. - * @return the random float - */ - public static float nextFloat(Random random) { - return random.nextFloat(); - } - - /** - *

Returns the next pseudorandom, uniformly distributed float value between 0.0 and - * 1.0 - * from the Math.random() sequence.

- * - * @return the random double - */ - public static double nextDouble() { - return nextDouble(JVM_RANDOM); - } - - /** - *

Returns the next pseudorandom, uniformly distributed float value between 0.0 and - * 1.0 - * from the given Random sequence.

- * - * @param random the Random sequence generator. - * @return the random double - */ - public static double nextDouble(Random random) { - return random.nextDouble(); - } - -} diff --git a/client/src/main/java/com/alibaba/nacos/client/naming/utils/ThreadLocalRandom.java b/client/src/main/java/com/alibaba/nacos/client/naming/utils/ThreadLocalRandom.java deleted file mode 100644 index ff280d00f..000000000 --- a/client/src/main/java/com/alibaba/nacos/client/naming/utils/ThreadLocalRandom.java +++ /dev/null @@ -1,279 +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.client.naming.utils; - -import java.security.SecureRandom; -import java.util.Random; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -/** - * A random number generator isolated to the current thread. Like the global {@link java.util.Random} generator used by - * the {@link java.lang.Math} class, a {@code ThreadLocalRandom} is initialized with an internally generated seed that - * may not otherwise be modified. When applicable, use of {@code ThreadLocalRandom} rather than shared {@code Random} - * objects in concurrent programs will typically encounter much less overhead and contention. Use of {@code - * ThreadLocalRandom} is particularly appropriate when multiple tasks (for example, each a {@link - * io.netty.util.internal.chmv8.ForkJoinTask}) use random numbers in parallel in thread pools. - *

- * Usages of this class should typically be of the form: {@code ThreadLocalRandom.current().nextX(...)} (where {@code X} - * is {@code Int}, {@code Long}, etc). When all usages are of this form, it is never possible to accidently share a - * {@code ThreadLocalRandom} across multiple threads. - *

- *

- * This class also provides additional commonly used bounded random generation methods. - *

- * //since 1.7 //author Doug Lea - */ -@SuppressWarnings("all") -public class ThreadLocalRandom extends Random { - - private static final AtomicLong seedUniquifier = new AtomicLong(); - - private static volatile long initialSeedUniquifier; - - public static void setInitialSeedUniquifier(long initialSeedUniquifier) { - ThreadLocalRandom.initialSeedUniquifier = initialSeedUniquifier; - } - - public static synchronized long getInitialSeedUniquifier() { - // Use the value set via the setter. - long initialSeedUniquifier = ThreadLocalRandom.initialSeedUniquifier; - // Otherwise, generate one. - if (initialSeedUniquifier == 0) { - // Try to generate a real random number from /dev/random. - // Get from a different thread to avoid blocking indefinitely on a machine without much entrophy. - final BlockingQueue queue = new LinkedBlockingQueue(); - Thread generatorThread = new Thread("initialSeedUniquifierGenerator") { - @Override - public void run() { - SecureRandom random = new SecureRandom(); // Get the real random seed from /dev/random - queue.add(random.nextLong()); - } - }; - generatorThread.start(); - - // Get the random seed from the thread with timeout. - final long timeoutSeconds = 3; - final long deadLine = System.nanoTime() + TimeUnit.SECONDS.toNanos(timeoutSeconds); - for (; ; ) { - long waitTime = deadLine - System.nanoTime(); - if (waitTime <= 0) { - break; - } - - try { - Long result = queue.poll(waitTime, TimeUnit.NANOSECONDS); - if (result != null) { - initialSeedUniquifier = result; - break; - } - } catch (InterruptedException ignore) { - // Ignore - } - } - - // Just in case the initialSeedUniquifier is zero or some other constant - initialSeedUniquifier ^= 0x3255ecdc33bae119L; // just a meaningless random number - initialSeedUniquifier ^= Long.reverse(System.nanoTime()); - - ThreadLocalRandom.initialSeedUniquifier = initialSeedUniquifier; - } - - return initialSeedUniquifier; - } - - private static long newSeed() { - for (; ; ) { - final long current = seedUniquifier.get(); - final long actualCurrent = current != 0 ? current : getInitialSeedUniquifier(); - - // L'Ecuyer, "Tables of Linear Congruential Generators of Different Sizes and Good Lattice Structure", 1999 - final long next = actualCurrent * 181783497276652981L; - - if (seedUniquifier.compareAndSet(current, next)) { - return next ^ System.nanoTime(); - } - } - } - - // same constants as Random, but must be redeclared because private - private static final long multiplier = 0x5DEECE66DL; - - private static final long addend = 0xBL; - - private static final long mask = (1L << 48) - 1; - - /** - * The random seed. We can't use super.seed. - */ - private long rnd; - - /** - * Initialization flag to permit calls to setSeed to succeed only while executing the Random constructor. We can't - * allow others since it would cause setting seed in one part of a program to unintentionally impact other usages by - * the thread. - */ - boolean initialized = false; - - // Padding to help avoid memory contention among seed updates in - // different TLRs in the common case that they are located near - // each other. - private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; - - /** - * Constructor called only by localRandom.initialValue. - */ - ThreadLocalRandom() { - super(newSeed()); - initialized = true; - } - - /** - * The actual ThreadLocal - */ - private static final ThreadLocal localRandom = new ThreadLocal() { - @Override - protected ThreadLocalRandom initialValue() { - return new ThreadLocalRandom(); - } - }; - - /** - * Returns the current thread's {@code ThreadLocalRandom}. - * - * @return the current thread's {@code ThreadLocalRandom} - */ - public static ThreadLocalRandom current() { - return localRandom.get(); - } - - /** - * Throws {@code UnsupportedOperationException}. Setting seeds in this generator is not supported. - * - * @throws UnsupportedOperationException always - */ - @Override - public void setSeed(long seed) { - if (initialized) { - throw new UnsupportedOperationException(); - } - rnd = (seed ^ multiplier) & mask; - } - - @Override - protected int next(int bits) { - rnd = (rnd * multiplier + addend) & mask; - return (int) (rnd >>> (48 - bits)); - } - - /** - * Returns a pseudorandom, uniformly distributed value between the given least value (inclusive) and bound - * (exclusive). - * - * @param least the least value returned - * @param bound the upper bound (exclusive) - * @return the next value - * @throws IllegalArgumentException if least greater than or equal to bound - */ - public int nextInt(int least, int bound) { - if (least >= bound) { - throw new IllegalArgumentException(); - } - return nextInt(bound - least) + least; - } - - /** - * Returns a pseudorandom, uniformly distributed value between 0 (inclusive) and the specified value (exclusive). - * - * @param n the bound on the random number to be returned. Must be positive. - * @return the next value - * @throws IllegalArgumentException if n is not positive - */ - public long nextLong(long n) { - if (n <= 0) { - throw new IllegalArgumentException("n must be positive"); - } - - // Divide n by two until small enough for nextInt. On each - // iteration (at most 31 of them but usually much less), - // randomly choose both whether to include high bit in result - // (offset) and whether to continue with the lower vs upper - // half (which makes a difference only if odd). - long offset = 0; - while (n >= Integer.MAX_VALUE) { - int bits = next(2); - long half = n >>> 1; - long nextn = ((bits & 2) == 0) ? half : n - half; - if ((bits & 1) == 0) { - offset += n - nextn; - } - n = nextn; - } - return offset + nextInt((int) n); - } - - /** - * Returns a pseudorandom, uniformly distributed value between the given least value (inclusive) and bound - * (exclusive). - * - * @param least the least value returned - * @param bound the upper bound (exclusive) - * @return the next value - * @throws IllegalArgumentException if least greater than or equal to bound - */ - public long nextLong(long least, long bound) { - if (least >= bound) { - throw new IllegalArgumentException(); - } - return nextLong(bound - least) + least; - } - - /** - * Returns a pseudorandom, uniformly distributed {@code double} value between 0 (inclusive) and the specified value - * (exclusive). - * - * @param n the bound on the random number to be returned. Must be positive. - * @return the next value - * @throws IllegalArgumentException if n is not positive - */ - public double nextDouble(double n) { - if (n <= 0) { - throw new IllegalArgumentException("n must be positive"); - } - return nextDouble() * n; - } - - /** - * Returns a pseudorandom, uniformly distributed value between the given least value (inclusive) and bound - * (exclusive). - * - * @param least the least value returned - * @param bound the upper bound (exclusive) - * @return the next value - * @throws IllegalArgumentException if least greater than or equal to bound - */ - public double nextDouble(double least, double bound) { - if (least >= bound) { - throw new IllegalArgumentException(); - } - return nextDouble() * (bound - least) + least; - } - - private static final long serialVersionUID = -5851777807851030925L; -} From 85c7d4e518319baf334136d146614944aa13fdb3 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Tue, 30 Mar 2021 10:16:09 +0800 Subject: [PATCH 15/18] add ut for c.a.nacos.client.naming.utils in nacos 2.0 (#5230) --- .../naming/utils/CollectionUtilsTest.java | 63 ++++++++++ .../naming/utils/GenericPollerTest.java | 44 +++++++ .../client/naming/utils/InitUtilsTest.java | 119 ++++++++++++++++++ .../naming/utils/NamingHttpUtilTest.java | 38 ++++++ .../nacos/client/naming/utils/PairTest.java | 32 +++++ .../client/naming/utils/SignUtilTest.java | 29 +++++ 6 files changed, 325 insertions(+) create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/utils/CollectionUtilsTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/utils/GenericPollerTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/utils/InitUtilsTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/utils/NamingHttpUtilTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/utils/PairTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/utils/SignUtilTest.java diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/utils/CollectionUtilsTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/utils/CollectionUtilsTest.java new file mode 100644 index 000000000..efe7531b7 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/utils/CollectionUtilsTest.java @@ -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.client.naming.utils; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class CollectionUtilsTest { + + @Test + public void testSubtract() { + List subtract = (List) CollectionUtils + .subtract(Arrays.asList("a", "b"), Arrays.asList("b", "c")); + Assert.assertEquals(1, subtract.size()); + Assert.assertEquals("a", subtract.get(0)); + } + + @Test + public void testGetCardinalityMap() { + List list1 = Arrays.asList("2", "2", "3"); + Map map1 = CollectionUtils.getCardinalityMap(list1); + Assert.assertEquals(2, map1.size()); + Assert.assertEquals(2, map1.get("2").intValue()); + Assert.assertEquals(1, map1.get("3").intValue()); + + } + + @Test + public void testIsEqualCollection() { + List list1 = Arrays.asList("2", "2", "3"); + List list2 = Arrays.asList("3", "2", "2"); + List list3 = Arrays.asList("3", "2", "3"); + Assert.assertTrue(CollectionUtils.isEqualCollection(list1, list2)); + Assert.assertFalse(CollectionUtils.isEqualCollection(list1, list3)); + + } + + @Test + public void testIsEmpty() { + Assert.assertTrue(CollectionUtils.isEmpty(null)); + Assert.assertTrue(CollectionUtils.isEmpty(new ArrayList())); + Assert.assertFalse(CollectionUtils.isEmpty(Arrays.asList("aa"))); + } +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/utils/GenericPollerTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/utils/GenericPollerTest.java new file mode 100644 index 000000000..b081427fb --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/utils/GenericPollerTest.java @@ -0,0 +1,44 @@ +/* + * 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.client.naming.utils; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; + +public class GenericPollerTest { + + @Test + public void testNext() { + String item1 = "item1"; + String item2 = "item2"; + GenericPoller poller = new GenericPoller<>(Arrays.asList(item1, item2)); + Assert.assertEquals(item1, poller.next()); + Assert.assertEquals(item2, poller.next()); + Assert.assertEquals(item1, poller.next()); + } + + @Test + public void testRefresh() { + String item1 = "item1"; + String item2 = "item2"; + GenericPoller poller = new GenericPoller<>(Arrays.asList(item1, item2)); + Poller poller1 = poller.refresh(Arrays.asList(item2)); + Assert.assertEquals(item2, poller1.next()); + } +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/utils/InitUtilsTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/utils/InitUtilsTest.java new file mode 100644 index 000000000..e3267391e --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/utils/InitUtilsTest.java @@ -0,0 +1,119 @@ +/* + * 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.client.naming.utils; + +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.SystemPropertyKeyConst; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Properties; + +public class InitUtilsTest { + + @Test + public void testInitWebRootContext() { + String ctx = "/aaa"; + Properties properties = new Properties(); + properties.put(PropertyKeyConst.CONTEXT_PATH, ctx); + InitUtils.initWebRootContext(properties); + Assert.assertEquals(ctx, UtilAndComs.webContext); + Assert.assertEquals(ctx + "/v1/ns", UtilAndComs.nacosUrlBase); + Assert.assertEquals(ctx + "/v1/ns/instance", UtilAndComs.nacosUrlInstance); + } + + /** + * current namespace priority 1. system.Properties 2. user.Properties 3. default value + */ + @Test + public void testInitNamespaceForNamingDefault() { + //DEFAULT + Properties prop = new Properties(); + String ns = InitUtils.initNamespaceForNaming(prop); + Assert.assertEquals("public", ns); + } + + @Test + public void testInitNamespaceForNamingFromProp() { + Properties prop = new Properties(); + String expect = "ns1"; + prop.put(PropertyKeyConst.NAMESPACE, expect); + String ns = InitUtils.initNamespaceForNaming(prop); + Assert.assertEquals(expect, ns); + } + + @Test + public void testInitNamespaceForNamingFromSystem() { + try { + String expect1 = "ns1"; + System.setProperty(PropertyKeyConst.NAMESPACE, expect1); + Properties prop = new Properties(); + prop.put(PropertyKeyConst.NAMESPACE, "cccccc"); + String ns = InitUtils.initNamespaceForNaming(prop); + Assert.assertEquals(expect1, ns); + } finally { + System.clearProperty(PropertyKeyConst.NAMESPACE); + } + } + + /** + * 1. System.property tenant.id 2. System.property ans.namespace 2. System.env ALIBABA_ALIWARE_NAMESPACE + */ + @Test + public void testInitNamespaceForNamingFromCloud() { + try { + String expect1 = "ns1"; + System.setProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING, " true"); + System.setProperty(SystemPropertyKeyConst.ANS_NAMESPACE, expect1); + Properties prop = new Properties(); + prop.put(PropertyKeyConst.NAMESPACE, "cccccc"); + String ns = InitUtils.initNamespaceForNaming(prop); + Assert.assertEquals(expect1, ns); + } finally { + System.clearProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING); + System.clearProperty(SystemPropertyKeyConst.ANS_NAMESPACE); + + } + } + + @Test + public void testInitEndpoint() { + Properties prop = new Properties(); + String endpoint = "1.1.1.1"; + String endpointPort = "1234"; + prop.put(PropertyKeyConst.ENDPOINT, endpoint); + prop.put(PropertyKeyConst.ENDPOINT_PORT, endpointPort); + String actual = InitUtils.initEndpoint(prop); + Assert.assertEquals(endpoint + ":" + endpointPort, actual); + } + + @Test + public void testInitEndpointAns() { + try { + System.setProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE, "true"); + Properties prop = new Properties(); + String endpoint = "${key:test.com}"; + prop.put(PropertyKeyConst.ENDPOINT, endpoint); + String actual = InitUtils.initEndpoint(prop); + //defaultEndpointPort is "8080"; + Assert.assertEquals("test.com:8080", actual); + } finally { + System.clearProperty(PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE); + } + } + +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/utils/NamingHttpUtilTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/utils/NamingHttpUtilTest.java new file mode 100644 index 000000000..eda626ba4 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/utils/NamingHttpUtilTest.java @@ -0,0 +1,38 @@ +/* + * 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.client.naming.utils; + +import com.alibaba.nacos.common.constant.HttpHeaderConsts; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.utils.VersionUtils; +import org.junit.Assert; +import org.junit.Test; + +public class NamingHttpUtilTest { + + @Test + public void testBuilderHeader() { + Header header = NamingHttpUtil.builderHeader(); + Assert.assertNotNull(header); + Assert.assertEquals(header.getValue(HttpHeaderConsts.CLIENT_VERSION_HEADER), VersionUtils.version); + Assert.assertEquals(header.getValue(HttpHeaderConsts.USER_AGENT_HEADER), VersionUtils.getFullClientVersion()); + Assert.assertEquals(header.getValue(HttpHeaderConsts.ACCEPT_ENCODING), "gzip,deflate,sdch"); + Assert.assertEquals(header.getValue(HttpHeaderConsts.CONNECTION), "Keep-Alive"); + Assert.assertNotNull(header.getValue(HttpHeaderConsts.REQUEST_ID)); + Assert.assertEquals(header.getValue(HttpHeaderConsts.REQUEST_MODULE), "Naming"); + } +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/utils/PairTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/utils/PairTest.java new file mode 100644 index 000000000..bbdf66b5d --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/utils/PairTest.java @@ -0,0 +1,32 @@ +/* + * 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.client.naming.utils; + +import org.junit.Assert; +import org.junit.Test; + +public class PairTest { + + @Test + public void testItem() { + String item = "aa"; + double weight = 1.0; + Pair pair = new Pair<>(item, weight); + Assert.assertEquals(weight, pair.weight(), 0.01); + Assert.assertEquals(item, pair.item()); + } +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/utils/SignUtilTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/utils/SignUtilTest.java new file mode 100644 index 000000000..3e6637cf0 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/utils/SignUtilTest.java @@ -0,0 +1,29 @@ +/* + * 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.client.naming.utils; + +import org.junit.Assert; +import org.junit.Test; + +public class SignUtilTest { + + @Test + public void testSign() throws Exception { + String actual = SignUtil.sign("aaa", "b"); + Assert.assertEquals("DxyaKScrqL26yXYOuHXE3OwfQ0Y=", actual); + } +} \ No newline at end of file From 51d57e083ca0f8b2ca7a049938dce511ea2ada28 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Tue, 30 Mar 2021 10:16:46 +0800 Subject: [PATCH 16/18] upgrade mockito from 2.4 to 3.8 (#5226) --- address/pom.xml | 10 ---------- pom.xml | 9 ++++++++- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/address/pom.xml b/address/pom.xml index 5247f1252..0b01afd36 100644 --- a/address/pom.xml +++ b/address/pom.xml @@ -51,16 +51,6 @@ - - org.mockito - mockito-all - test - - - org.hamcrest - hamcrest-all - test - diff --git a/pom.xml b/pom.xml index f3a45533f..d21ef06ff 100644 --- a/pom.xml +++ b/pom.xml @@ -162,6 +162,7 @@ 4.0.63 0.9.11 1.10.19 + 3.8.0 1.3 0.5.0 9.0.40 @@ -1029,6 +1030,12 @@ ${mockito-all.version} + + org.mockito + mockito-core + ${mockito-core.version} + + org.hamcrest hamcrest-all @@ -1066,6 +1073,6 @@ https://oss.sonatype.org/service/local/staging/deploy/maven2/ - + From 975985ecc4a3934170a97e0b1dd3dddb73fb9210 Mon Sep 17 00:00:00 2001 From: "shalk(xiao kun)" Date: Tue, 30 Mar 2021 10:17:56 +0800 Subject: [PATCH 17/18] [ISSUE #5151] add ut for package c.a.nacos.client.naming.core (#5193) * add ut for package c.a.nacos.client.naming.core * fix * fix shutdown * fix import --- .../client/naming/core/BalancerTest.java | 69 ++++++++ .../client/naming/core/ProtectModeTest.java | 37 +++++ .../client/naming/core/PushReceiverTest.java | 153 ++++++++++++++++++ .../naming/core/ServerListManagerTest.java | 100 ++++++++++++ .../core/ServiceInfoUpdateServiceTest.java | 80 +++++++++ 5 files changed, 439 insertions(+) create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/core/BalancerTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/core/ProtectModeTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/core/PushReceiverTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/core/ServerListManagerTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/naming/core/ServiceInfoUpdateServiceTest.java diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/core/BalancerTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/core/BalancerTest.java new file mode 100644 index 000000000..cc2801d2e --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/core/BalancerTest.java @@ -0,0 +1,69 @@ +/* + * 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.client.naming.core; + +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.alibaba.nacos.api.naming.pojo.ServiceInfo; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.ArrayList; +import java.util.List; + +public class BalancerTest { + + @Rule + public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void testGetHostByRandomWeightNull() { + Assert.assertNull(Balancer.getHostByRandomWeight(null)); + Assert.assertNull(Balancer.getHostByRandomWeight(new ArrayList<>())); + } + + @Test + public void testGetHostByRandomWeight() { + List list = new ArrayList<>(); + Instance instance1 = new Instance(); + list.add(instance1); + final Instance actual = Balancer.getHostByRandomWeight(list); + Assert.assertEquals(instance1, actual); + } + + @Test + public void testSelectHost() { + List hosts = new ArrayList<>(); + Instance instance1 = new Instance(); + hosts.add(instance1); + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.setHosts(hosts); + + final Instance actual = Balancer.RandomByWeight.selectHost(serviceInfo); + Assert.assertEquals(instance1, actual); + } + + @Test + public void testSelectHostEmpty() { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("no host to srv for serviceInfo: null"); + ServiceInfo serviceInfo = new ServiceInfo(); + + Balancer.RandomByWeight.selectHost(serviceInfo); + } +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/core/ProtectModeTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/core/ProtectModeTest.java new file mode 100644 index 000000000..3954d84c8 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/core/ProtectModeTest.java @@ -0,0 +1,37 @@ +/* + * 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.client.naming.core; + +import org.junit.Assert; +import org.junit.Test; + +public class ProtectModeTest { + + @Test + public void testProtectThresholdDefault() { + final ProtectMode protectMode = new ProtectMode(); + Assert.assertEquals(0.8f, protectMode.getProtectThreshold(), 0.01f); + } + + @Test + public void testSetProtectThreshold() { + final ProtectMode protectMode = new ProtectMode(); + float expect = 0.7f; + protectMode.setProtectThreshold(expect); + Assert.assertEquals(expect, protectMode.getProtectThreshold(), 0.01f); + } +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/core/PushReceiverTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/core/PushReceiverTest.java new file mode 100644 index 000000000..91997a73b --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/core/PushReceiverTest.java @@ -0,0 +1,153 @@ +/* + * 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.client.naming.core; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.naming.cache.ServiceInfoHolder; +import com.alibaba.nacos.common.utils.IoUtils; +import com.alibaba.nacos.common.utils.JacksonUtils; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +public class PushReceiverTest { + + @Test + public void testTestRunDomAndService() throws InterruptedException, IOException { + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + final PushReceiver pushReceiver = new PushReceiver(holder); + final ExecutorService executorService = Executors.newFixedThreadPool(1); + executorService.submit(new Runnable() { + @Override + public void run() { + pushReceiver.run(); + } + }); + TimeUnit.MILLISECONDS.sleep(10); + + PushReceiver.PushPacket pack1 = new PushReceiver.PushPacket(); + pack1.type = "dom"; + pack1.data = "pack1"; + pack1.lastRefTime = 1; + final String res1 = udpClientRun(pack1, pushReceiver); + Assert.assertEquals("{\"type\": \"push-ack\", \"lastRefTime\":\"1\", \"data\":\"\"}", res1); + verify(holder, times(1)).processServiceInfo(pack1.data); + + PushReceiver.PushPacket pack2 = new PushReceiver.PushPacket(); + pack2.type = "service"; + pack2.data = "pack2"; + pack2.lastRefTime = 2; + final String res2 = udpClientRun(pack2, pushReceiver); + Assert.assertEquals("{\"type\": \"push-ack\", \"lastRefTime\":\"2\", \"data\":\"\"}", res2); + verify(holder, times(1)).processServiceInfo(pack2.data); + + } + + private String udpClientRun(PushReceiver.PushPacket pack, PushReceiver pushReceiver) throws IOException { + final int udpPort = pushReceiver.getUdpPort(); + String json = JacksonUtils.toJson(pack); + final byte[] bytes = IoUtils.tryCompress(json, "UTF-8"); + final DatagramSocket datagramSocket = new DatagramSocket(); + datagramSocket.send(new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"), udpPort)); + byte[] buffer = new byte[20480]; + final DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length); + datagramSocket.receive(datagramPacket); + final byte[] data = datagramPacket.getData(); + String res = new String(data, StandardCharsets.UTF_8); + return res.trim(); + } + + @Test + public void testTestRunWithDump() throws InterruptedException, IOException { + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + final PushReceiver pushReceiver = new PushReceiver(holder); + final ExecutorService executorService = Executors.newFixedThreadPool(1); + executorService.submit(new Runnable() { + @Override + public void run() { + pushReceiver.run(); + } + }); + TimeUnit.MILLISECONDS.sleep(10); + + PushReceiver.PushPacket pack1 = new PushReceiver.PushPacket(); + pack1.type = "dump"; + pack1.data = "pack1"; + pack1.lastRefTime = 1; + final String res1 = udpClientRun(pack1, pushReceiver); + Assert.assertEquals("{\"type\": \"dump-ack\", \"lastRefTime\": \"1\", \"data\":\"{}\"}", res1); + verify(holder, times(1)).getServiceInfoMap(); + + } + + @Test + public void testTestRunWithUnknown() throws InterruptedException, IOException { + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + final PushReceiver pushReceiver = new PushReceiver(holder); + final ExecutorService executorService = Executors.newFixedThreadPool(1); + executorService.submit(new Runnable() { + @Override + public void run() { + pushReceiver.run(); + } + }); + TimeUnit.MILLISECONDS.sleep(10); + + PushReceiver.PushPacket pack1 = new PushReceiver.PushPacket(); + pack1.type = "unknown"; + pack1.data = "pack1"; + pack1.lastRefTime = 1; + final String res1 = udpClientRun(pack1, pushReceiver); + Assert.assertEquals("{\"type\": \"unknown-ack\", \"lastRefTime\":\"1\", \"data\":\"\"}", res1); + } + + @Test + public void testShutdown() throws NacosException, NoSuchFieldException, IllegalAccessException { + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + final PushReceiver pushReceiver = new PushReceiver(holder); + + pushReceiver.shutdown(); + + final Field closed = PushReceiver.class.getDeclaredField("closed"); + closed.setAccessible(true); + final boolean o = (boolean) closed.get(pushReceiver); + Assert.assertTrue(o); + + } + + @Test + public void testGetUdpPort() { + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + final PushReceiver pushReceiver = new PushReceiver(holder); + final int udpPort = pushReceiver.getUdpPort(); + System.out.println("udpPort = " + udpPort); + Assert.assertTrue(udpPort > 0); + } +} \ No newline at end of file diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/core/ServerListManagerTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/core/ServerListManagerTest.java new file mode 100644 index 000000000..02a8a89c3 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/core/ServerListManagerTest.java @@ -0,0 +1,100 @@ +/* + * 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.client.naming.core; + +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import static org.mockito.ArgumentMatchers.any; + +public class ServerListManagerTest { + + @Test + public void testConstructWithAddr() { + Properties properties = new Properties(); + properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848,127.0.0.1:8849"); + final ServerListManager serverListManager = new ServerListManager(properties); + final List serverList = serverListManager.getServerList(); + Assert.assertEquals(2, serverList.size()); + Assert.assertEquals("127.0.0.1:8848", serverList.get(0)); + Assert.assertEquals("127.0.0.1:8849", serverList.get(1)); + } + + @Ignore + @Test + public void testConstructWithEndpoint() throws Exception { + Properties properties = new Properties(); + properties.put(PropertyKeyConst.ENDPOINT, "127.0.0.1"); + final ServerListManager serverListManager = new ServerListManager(properties); + NacosRestTemplate mock = Mockito.mock(NacosRestTemplate.class); + + HttpRestResult a = new HttpRestResult(); + a.setData("127.0.0.1:8848"); + a.setCode(200); + Mockito.when(mock.get(any(), any(), any(), any())).thenReturn(a); + + final Field nacosRestTemplate = ServerListManager.class.getDeclaredField("nacosRestTemplate"); + nacosRestTemplate.setAccessible(true); + nacosRestTemplate.set(serverListManager, mock); + TimeUnit.SECONDS.sleep(31); + final List serverList = serverListManager.getServerList(); + Assert.assertEquals(1, serverList.size()); + Assert.assertEquals("127.0.0.1:8848", serverList.get(0)); + } + + @Test + public void testIsDomain() throws IOException { + Properties properties = new Properties(); + properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848"); + final ServerListManager serverListManager = new ServerListManager(properties); + Assert.assertTrue(serverListManager.isDomain()); + Assert.assertEquals("127.0.0.1:8848", serverListManager.getNacosDomain()); + } + + @Test + public void testGetCurrentServer() { + Properties properties = new Properties(); + properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848"); + final ServerListManager serverListManager = new ServerListManager(properties); + Assert.assertEquals("127.0.0.1:8848", serverListManager.getCurrentServer()); + Assert.assertEquals("127.0.0.1:8848", serverListManager.genNextServer()); + } + + @Test + public void testShutdown() { + Properties properties = new Properties(); + properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848"); + final ServerListManager serverListManager = new ServerListManager(properties); + try { + serverListManager.shutdown(); + } catch (Exception e) { + Assert.fail(); + } + } + +} diff --git a/client/src/test/java/com/alibaba/nacos/client/naming/core/ServiceInfoUpdateServiceTest.java b/client/src/test/java/com/alibaba/nacos/client/naming/core/ServiceInfoUpdateServiceTest.java new file mode 100644 index 000000000..0a9f44605 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/naming/core/ServiceInfoUpdateServiceTest.java @@ -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.client.naming.core; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.pojo.ServiceInfo; +import com.alibaba.nacos.client.naming.cache.ServiceInfoHolder; +import com.alibaba.nacos.client.naming.event.InstancesChangeNotifier; +import com.alibaba.nacos.client.naming.remote.NamingClientProxy; +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +public class ServiceInfoUpdateServiceTest { + + @Test + public void testScheduleUpdateIfAbsent() throws InterruptedException, NacosException { + String serviceName = "aa"; + String group = "bb"; + String clusters = "cc"; + ServiceInfo info = new ServiceInfo(); + info.setName(serviceName); + info.setGroupName(group); + info.setClusters(clusters); + info.setLastRefTime(System.currentTimeMillis()); + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + NamingClientProxy proxy = Mockito.mock(NamingClientProxy.class); + Mockito.when(proxy.queryInstancesOfService(serviceName, group, clusters, 0, false)).thenReturn(info); + + InstancesChangeNotifier notifyer = Mockito.mock(InstancesChangeNotifier.class); + Properties prop = new Properties(); + final ServiceInfoUpdateService serviceInfoUpdateService = new ServiceInfoUpdateService(prop, holder, proxy, + notifyer); + + serviceInfoUpdateService.scheduleUpdateIfAbsent("aa", "bb", "cc"); + TimeUnit.SECONDS.sleep(2); + Mockito.verify(proxy).queryInstancesOfService(serviceName, group, clusters, 0, false); + } + + @Test + public void testStopUpdateIfContain() throws NacosException { + String serviceName = "aa"; + String group = "bb"; + String clusters = "cc"; + ServiceInfo info = new ServiceInfo(); + info.setName(serviceName); + info.setGroupName(group); + info.setClusters(clusters); + info.setLastRefTime(System.currentTimeMillis()); + NamingClientProxy proxy = Mockito.mock(NamingClientProxy.class); + Mockito.when(proxy.queryInstancesOfService(serviceName, group, clusters, 0, false)).thenReturn(info); + + InstancesChangeNotifier notifyer = Mockito.mock(InstancesChangeNotifier.class); + Properties prop = new Properties(); + ServiceInfoHolder holder = Mockito.mock(ServiceInfoHolder.class); + + final ServiceInfoUpdateService serviceInfoUpdateService = new ServiceInfoUpdateService(prop, holder, proxy, + notifyer); + serviceInfoUpdateService.scheduleUpdateIfAbsent(serviceName, group, clusters); + + serviceInfoUpdateService.stopUpdateIfContain(serviceName, group, clusters); + serviceInfoUpdateService.shutdown(); + } +} \ No newline at end of file From d146e057c4627674073fd9cf3b384d56fd4a2d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E7=BF=8A=20SionYang?= <263976490@qq.com> Date: Tue, 30 Mar 2021 16:27:41 +0800 Subject: [PATCH 18/18] Fix ThreadPool usage problem and add some monitor for distro (#5237) --- .../common/remote/client/grpc/GrpcClient.java | 2 +- .../core/remote/grpc/GrpcClusterServer.java | 3 ++ .../nacos/core/utils/GlobalExecutor.java | 10 ++-- .../alibaba/nacos/core/utils/RemoteUtils.java | 20 ++++++- .../distro/v2/DistroClientTransportAgent.java | 20 +++++-- .../naming/monitor/NamingTpsMonitor.java | 54 +++++++++++++++++++ .../nacos/naming/monitor/TpsMonitorItem.java | 32 ++++++++++- .../naming/push/v2/task/PushExecuteTask.java | 2 +- 8 files changed, 130 insertions(+), 13 deletions(-) diff --git a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java index 3aa58c682..c5eae03c5 100644 --- a/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java +++ b/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java @@ -248,7 +248,7 @@ public abstract class GrpcClient extends RpcClient { grpcExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 8, Runtime.getRuntime().availableProcessors() * 8, 10L, TimeUnit.SECONDS, - new LinkedBlockingQueue<>(1000), + new LinkedBlockingQueue<>(10000), new ThreadFactoryBuilder().setDaemon(true).setNameFormat("nacos-grpc-client-executor-%d") .build()); grpcExecutor.allowCoreThreadTimeOut(true); diff --git a/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcClusterServer.java b/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcClusterServer.java index 5aa5aa5d0..c37cb0d88 100644 --- a/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcClusterServer.java +++ b/core/src/main/java/com/alibaba/nacos/core/remote/grpc/GrpcClusterServer.java @@ -39,6 +39,9 @@ public class GrpcClusterServer extends BaseGrpcServer { @Override public ThreadPoolExecutor getRpcExecutor() { + if (!GlobalExecutor.clusterRpcExecutor.allowsCoreThreadTimeOut()) { + GlobalExecutor.clusterRpcExecutor.allowCoreThreadTimeOut(true); + } return GlobalExecutor.clusterRpcExecutor; } } diff --git a/core/src/main/java/com/alibaba/nacos/core/utils/GlobalExecutor.java b/core/src/main/java/com/alibaba/nacos/core/utils/GlobalExecutor.java index 81ddc9c57..3efd9384f 100644 --- a/core/src/main/java/com/alibaba/nacos/core/utils/GlobalExecutor.java +++ b/core/src/main/java/com/alibaba/nacos/core/utils/GlobalExecutor.java @@ -20,8 +20,8 @@ import com.alibaba.nacos.common.executor.ExecutorFactory; import com.alibaba.nacos.common.executor.NameThreadFactory; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -43,15 +43,15 @@ public class GlobalExecutor { new NameThreadFactory("com.alibaba.nacos.core.protocal.distro")); public static final ThreadPoolExecutor sdkRpcExecutor = new ThreadPoolExecutor( - Runtime.getRuntime().availableProcessors(), + Runtime.getRuntime().availableProcessors() * RemoteUtils.getRemoteExecutorTimesOfProcessors(), Runtime.getRuntime().availableProcessors() * RemoteUtils.getRemoteExecutorTimesOfProcessors(), 60L, - TimeUnit.SECONDS, new SynchronousQueue(), + TimeUnit.SECONDS, new LinkedBlockingQueue<>(RemoteUtils.getRemoteExecutorQueueSize()), new ThreadFactoryBuilder().setDaemon(true).setNameFormat("nacos-grpc-executor-%d").build()); public static final ThreadPoolExecutor clusterRpcExecutor = new ThreadPoolExecutor( - Runtime.getRuntime().availableProcessors(), + Runtime.getRuntime().availableProcessors() * RemoteUtils.getRemoteExecutorTimesOfProcessors(), Runtime.getRuntime().availableProcessors() * RemoteUtils.getRemoteExecutorTimesOfProcessors(), 60L, - TimeUnit.SECONDS, new SynchronousQueue(), + TimeUnit.SECONDS, new LinkedBlockingQueue<>(RemoteUtils.getRemoteExecutorQueueSize()), new ThreadFactoryBuilder().setDaemon(true).setNameFormat("nacos-cluster-grpc-executor-%d").build()); public static void runWithoutThread(Runnable runnable) { diff --git a/core/src/main/java/com/alibaba/nacos/core/utils/RemoteUtils.java b/core/src/main/java/com/alibaba/nacos/core/utils/RemoteUtils.java index e0760e608..5ffcd0f58 100644 --- a/core/src/main/java/com/alibaba/nacos/core/utils/RemoteUtils.java +++ b/core/src/main/java/com/alibaba/nacos/core/utils/RemoteUtils.java @@ -28,7 +28,15 @@ public class RemoteUtils { public static final float LOADER_FACTOR = 0.1f; - private static final int REMOTE_EXECUTOR_TIMES_OF_PROCESSORS = 64; + /** + * Default remote execute times for CPU count of task processors. + */ + private static final int REMOTE_EXECUTOR_TIMES_OF_PROCESSORS = 1 << 4; + + /** + * Default remote execute queue size: 16384. + */ + private static final int REMOTE_EXECUTOR_QUEUE_SIZE = 1 << 14; /** * get remote executors thread times of processors,default is 64. see the usage of this method for detail. @@ -44,4 +52,14 @@ public class RemoteUtils { return REMOTE_EXECUTOR_TIMES_OF_PROCESSORS; } } + + public static int getRemoteExecutorQueueSize() { + String queueSizeString = System.getProperty("remote.executor.queue.size"); + if (NumberUtil.isDigits(queueSizeString)) { + Integer size = Integer.valueOf(queueSizeString); + return size > 0 ? size : REMOTE_EXECUTOR_QUEUE_SIZE; + } else { + return REMOTE_EXECUTOR_QUEUE_SIZE; + } + } } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/distro/v2/DistroClientTransportAgent.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/distro/v2/DistroClientTransportAgent.java index f673b525a..d331c4b00 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/distro/v2/DistroClientTransportAgent.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/distro/v2/DistroClientTransportAgent.java @@ -36,6 +36,7 @@ import com.alibaba.nacos.naming.cluster.remote.response.DistroDataResponse; import com.alibaba.nacos.naming.core.v2.event.client.ClientEvent; import com.alibaba.nacos.naming.misc.GlobalExecutor; import com.alibaba.nacos.naming.misc.Loggers; +import com.alibaba.nacos.naming.monitor.NamingTpsMonitor; import java.util.concurrent.Executor; @@ -89,7 +90,7 @@ public class DistroClientTransportAgent implements DistroTransportAgent { DistroDataRequest request = new DistroDataRequest(data, data.getType()); Member member = memberManager.find(targetServer); try { - clusterRpcClientProxy.asyncRequest(member, request, new DistroRpcCallbackWrapper(callback)); + clusterRpcClientProxy.asyncRequest(member, request, new DistroRpcCallbackWrapper(callback, member)); } catch (NacosException nacosException) { callback.onFailed(nacosException); } @@ -126,7 +127,7 @@ public class DistroClientTransportAgent implements DistroTransportAgent { Member member = memberManager.find(targetServer); try { DistroVerifyCallbackWrapper wrapper = new DistroVerifyCallbackWrapper(targetServer, - verifyData.getDistroKey().getResourceKey(), callback); + verifyData.getDistroKey().getResourceKey(), callback, member); clusterRpcClientProxy.asyncRequest(member, request, wrapper); } catch (NacosException nacosException) { callback.onFailed(nacosException); @@ -199,8 +200,11 @@ public class DistroClientTransportAgent implements DistroTransportAgent { private final DistroCallback distroCallback; - public DistroRpcCallbackWrapper(DistroCallback distroCallback) { + private final Member member; + + public DistroRpcCallbackWrapper(DistroCallback distroCallback, Member member) { this.distroCallback = distroCallback; + this.member = member; } @Override @@ -217,8 +221,10 @@ public class DistroClientTransportAgent implements DistroTransportAgent { @Override public void onResponse(Response response) { if (checkResponse(response)) { + NamingTpsMonitor.distroSyncSuccess(member.getAddress(), member.getIp()); distroCallback.onSuccess(); } else { + NamingTpsMonitor.distroSyncFail(member.getAddress(), member.getIp()); distroCallback.onFailed(null); } } @@ -236,11 +242,15 @@ public class DistroClientTransportAgent implements DistroTransportAgent { private final String clientId; private final DistroCallback distroCallback; + + private final Member member; - private DistroVerifyCallbackWrapper(String targetServer, String clientId, DistroCallback distroCallback) { + private DistroVerifyCallbackWrapper(String targetServer, String clientId, DistroCallback distroCallback, + Member member) { this.targetServer = targetServer; this.clientId = clientId; this.distroCallback = distroCallback; + this.member = member; } @Override @@ -257,10 +267,12 @@ public class DistroClientTransportAgent implements DistroTransportAgent { @Override public void onResponse(Response response) { if (checkResponse(response)) { + NamingTpsMonitor.distroVerifySuccess(member.getAddress(), member.getIp()); distroCallback.onSuccess(); } else { Loggers.DISTRO.info("Target {} verify client {} failed, sync new client", targetServer, clientId); NotifyCenter.publishEvent(new ClientEvent.ClientVerifyFailedEvent(clientId, targetServer)); + NamingTpsMonitor.distroVerifyFail(member.getAddress(), member.getIp()); distroCallback.onFailed(null); } } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/monitor/NamingTpsMonitor.java b/naming/src/main/java/com/alibaba/nacos/naming/monitor/NamingTpsMonitor.java index adab499c5..b447475ec 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/monitor/NamingTpsMonitor.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/monitor/NamingTpsMonitor.java @@ -34,6 +34,7 @@ public class NamingTpsMonitor { private NamingTpsMonitor() { this.tpsMonitorManager = ApplicationUtils.getBean(TpsMonitorManager.class); registerPushMonitorPoint(); + registerDistroMonitorPoint(); } private void registerPushMonitorPoint() { @@ -45,6 +46,15 @@ public class NamingTpsMonitor { tpsMonitorManager.registerTpsControlPoint(new TpsMonitorPoint(TpsMonitorItem.NAMING_UDP_PUSH_FAIL.name())); } + private void registerDistroMonitorPoint() { + tpsMonitorManager.registerTpsControlPoint(new TpsMonitorPoint(TpsMonitorItem.NAMING_DISTRO_SYNC.name())); + tpsMonitorManager.registerTpsControlPoint(new TpsMonitorPoint(TpsMonitorItem.NAMING_DISTRO_SYNC_SUCCESS.name())); + tpsMonitorManager.registerTpsControlPoint(new TpsMonitorPoint(TpsMonitorItem.NAMING_DISTRO_SYNC_FAIL.name())); + tpsMonitorManager.registerTpsControlPoint(new TpsMonitorPoint(TpsMonitorItem.NAMING_DISTRO_VERIFY.name())); + tpsMonitorManager.registerTpsControlPoint(new TpsMonitorPoint(TpsMonitorItem.NAMING_DISTRO_VERIFY_SUCCESS.name())); + tpsMonitorManager.registerTpsControlPoint(new TpsMonitorPoint(TpsMonitorItem.NAMING_DISTRO_VERIFY_FAIL.name())); + } + public static NamingTpsMonitor getInstance() { return INSTANCE; } @@ -92,4 +102,48 @@ public class NamingTpsMonitor { INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_UDP_PUSH.name(), clientId, clientIp); INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_UDP_PUSH_FAIL.name(), clientId, clientIp); } + + /** + * Apply distro sync success. + * + * @param clientId client id + * @param clientIp client ip + */ + public static void distroSyncSuccess(String clientId, String clientIp) { + INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_DISTRO_SYNC.name(), clientId, clientIp); + INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_DISTRO_SYNC_SUCCESS.name(), clientId, clientIp); + } + + /** + * Apply distro sync fail. + * + * @param clientId client id + * @param clientIp client ip + */ + public static void distroSyncFail(String clientId, String clientIp) { + INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_DISTRO_SYNC.name(), clientId, clientIp); + INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_DISTRO_SYNC_FAIL.name(), clientId, clientIp); + } + + /** + * Apply distro verify success. + * + * @param clientId client id + * @param clientIp client ip + */ + public static void distroVerifySuccess(String clientId, String clientIp) { + INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_DISTRO_VERIFY.name(), clientId, clientIp); + INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_DISTRO_VERIFY_SUCCESS.name(), clientId, clientIp); + } + + /** + * Apply distro verify fail. + * + * @param clientId client id + * @param clientIp client ip + */ + public static void distroVerifyFail(String clientId, String clientIp) { + INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_DISTRO_VERIFY.name(), clientId, clientIp); + INSTANCE.tpsMonitorManager.applyTpsForClientIp(TpsMonitorItem.NAMING_DISTRO_VERIFY_FAIL.name(), clientId, clientIp); + } } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/monitor/TpsMonitorItem.java b/naming/src/main/java/com/alibaba/nacos/naming/monitor/TpsMonitorItem.java index bef40bc78..c07fe21e9 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/monitor/TpsMonitorItem.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/monitor/TpsMonitorItem.java @@ -51,5 +51,35 @@ public enum TpsMonitorItem { /** * Naming udp fail push. */ - NAMING_UDP_PUSH_FAIL; + NAMING_UDP_PUSH_FAIL, + + /** + * Naming rpc distro sync total count. + */ + NAMING_DISTRO_SYNC, + + /** + * Naming rpc distro sync success count. + */ + NAMING_DISTRO_SYNC_SUCCESS, + + /** + * Naming rpc distro sync fail count. + */ + NAMING_DISTRO_SYNC_FAIL, + + /** + * Naming rpc distro verify fail count. + */ + NAMING_DISTRO_VERIFY, + + /** + * Naming rpc distro verify fail count. + */ + NAMING_DISTRO_VERIFY_SUCCESS, + + /** + * Naming rpc distro verify fail count. + */ + NAMING_DISTRO_VERIFY_FAIL, } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/push/v2/task/PushExecuteTask.java b/naming/src/main/java/com/alibaba/nacos/naming/push/v2/task/PushExecuteTask.java index 6569cc4f2..eb32275d2 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/push/v2/task/PushExecuteTask.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/push/v2/task/PushExecuteTask.java @@ -106,7 +106,7 @@ public class PushExecuteTask extends AbstractExecuteTask { @Override public long getTimeout() { // TODO timeout should can be config - return 3000L; + return 5000L; } @Override